Feat/zpl fc clock#93
Merged
Merged
Conversation
Adds round-trip support for ZPL's `^FC` directive that lets a single
`^FD` payload reference printer-RTC values inline. ZPL ground form:
^XA
^FO50,50^A0N,30,30^FDDate %d/%m/%Y at %H:%M^FS
^XZ
Prints "Date 24/05/2026 at 09:07" using the printer's clock. The
`%`, `{`, `#` chars before a token letter are the dispatch chars set
via `^FC<date>,<time>,<tertiary>` (defaults).
Stored in our model as `«clock:T»` markers in `props.content` —
same `«…»` bracket family as the `«name»` variable markers from the
^FE feature, dispatched at resolve time by the `clock:` prefix.
Three layers:
- lib/fcTemplate.ts: clock primitives (extract/resolve/tokens-to-
markers / markers-to-tokens / pickClockChars). Tokens supported:
Y / y / m / d / H / M / S / j. Julian day uses month-length
summation so DST-spring-forward days don't round down by one.
`markersToTokens` takes just the date char (firmware treats all
three clock chars as the same RTC). `tokensToMarkers` guards
against empty clock chars so malformed callers don't collapse
to a `[]` char-class that silently matches nothing.
- parser: tracks ^FC clock chars, scans ^FD for clock-char + token
letter sequences, converts to `«clock:T»` markers after the ^FE
FN-embed pass. Both ^FE embedChar and ^FC clockChars reset on
every ^XA so multi-label streams don't leak format-scoped state.
- generator: single tree walk collects both ^FE-template and ^FC-
clock payloads, picks safe delimiter chars, emits ^FC only when
≠ defaults, leaves markers literal when no safe triple exists
(same fail-safe as ^FE).
applyBindingToObject accepts an optional `now: Date` — lazy
allocation inside the clock branch so plain-text fields don't pay
for an unused Date construction. applyBindingToTree evaluates once
per tree pass and reuses across all leaves.
Schema-mode leaves `«clock:T»` markers literal (same intent as
`«name»` placeholders: show structure, not data).
28 new unit tests (fcTemplate primitives + parser/generator
roundtrip + binding integration with fixed `now` + DST Julian-day
edge cases + multi-label state-reset).
Extend the existing variable-insert dropdown to also list ^FC clock tokens (year/month/day/hour/minute/second/julian-day) below the variables section. Picking a token splices its `«clock:T»` marker into the input at the cursor, same insert flow as the variable markers. Replace the single-line `<input>` with an auto-growing `<textarea>` (2-8 rows) layered over a colour-mirror that highlights `«…»` markers in their type-specific colour — accent for variable markers, cyan for clock markers, default for literal text. Mirror geometry tracks the textarea exactly (shared CSS + scrollHeight- based sizing) so the highlight stays aligned at every grow step. Cursor + selection come from the native textarea; the mirror is purely visual and aria-hidden so screen readers see only the textarea value. Picker consumes the canonical CLOCK_TOKEN_LABELS list from lib/fcTemplate so the UI stays in lock-step with the resolver — a new token added to TOKEN_FORMATTERS forces a matching CLOCK_TOKEN_ LABELS row (TS narrowing), which in turn forces a locale-key add. Trigger button declares `aria-haspopup="menu"` + `aria-expanded`, floats absolute in the top-right corner of the textarea so the field keeps the full panel width. Locale: 8 new flat keys on t.app (clockYear4 / clockYear2 / clockMonth / clockDay / clockHour24 / clockMinute / clockSecond / clockJulianDay) across all 32 locales. Atomic-delete (Backspace removes a whole marker), marker right- click context menu, expand-to-modal editor, and ^FB-specific UX revamp are tracked in the project_ticket_template_editor_ux memory note for a follow-up PR.
There was a problem hiding this comment.
Code Review
This pull request implements support for the ZPL ^FC (Field Clock) command, enabling the use of dynamic date and time tokens within labels. The implementation includes a new fcTemplate utility for tokenizing and resolving clock markers, updates to the ZPL parser and generator to handle clock delimiters, and an overhaul of the TemplateContentInput component to support multi-line editing with syntax highlighting. Review feedback identified a usability issue where overflow-y-hidden prevents scrolling in the editor when content exceeds the maximum row limit and suggested refactoring hardcoded color values into theme constants for improved maintainability.
… colour Address gemini's PR #93 findings: - overflow-y-hidden meant content past MAX_ROWS was unreachable (no scroll, no expand). Switch to overflow-y-auto with the scrollbar visually hidden so wheel/keyboard scrolling still works and the mirror layer stays pixel-aligned (a visible scrollbar would shift the textarea's text origin and break the highlight). - Hardcoded `#67c8e0` clock-marker colour replaced with a themed --color-info CSS var. Light + dark palettes get distinct values so the clock highlight stays readable on both. Picker dropdown consumes the same token via `text-info`.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
No description provided.