ReviewOS

stacks/stx

feat(native): support shared component design tokens and essential layout utilities

#2090
Closed glennmichael123 opened this 9 days ago ·
9 days ago

Problem

Shared component templates compile with missing native style translations, so common controls do not retain their intended spacing, shape, and presentation.

Audited at v0.2.546, commit 0013ce66e3.

Reproduced evidence

Compiling actual shared-library components reports unknown-class diagnostics for:

  • Button: rounded-control, shadow-md, transition-all, duration-200.
  • TextInput/Select: rounded-control, px-control-x, py-control-y, text-control, ring utilities, shadow-sm.
  • Card: rounded-panel.
  • Drawer/Tooltip: positioning, stacking, overflow, shadow, and transition utilities.

Not every browser utility needs a literal native equivalent: cursor styles and hover-specific behavior may need deliberate alternatives. The functional layout and theme tokens are the first priority.

Sources:

Requested change

Inventory utilities used by shared components and prioritize design-token sizing, spacing, radii, borders/rings, shadows, and essential overlay positioning. Define explicit fallbacks or diagnostics where the host cannot represent a feature. Include runtime-computed classes, not only static markup.

Acceptance

  • Representative shared controls retain expected spacing and shape.
  • Theme/density tokens and appearance changes work across targets.
  • Dynamic class/style updates are covered.
  • Unsupported meaningful styles remain visible in diagnostics.
  • Validate representative screens with maintained native hosts; IR assertions alone do not establish visual parity.

Priority

Fifth in the portability audit sequence. Token support can be developed in parallel with behavioral fixes; overlay styling should follow the presentation contract. The audit verified compiler diagnostics, not pixel-level device output.

9 days ago

Progress pushed to main: ce9b402 translates shared shape/density defaults directly from theme-tokens.ts (including directional corners and density line heights). Unknown directional radius names now remain diagnostics instead of silently becoming 4px. Commits 6a381ac and 4e395bc fix reactive style replacement: removing a bound key restores authored defaults, class changes remove stale properties, and hidden nodes stay hidden.

Maintained tests compile actual shared Button/Card/TextInput/Select sources and exercise light/dark changes, computed classes, inline overrides, and clearing styles in development and minified bundles. Browser tests also cover restoration of authored values and CSS priorities. Local validation: 3,654 tests passed; typecheck, targeted lint, full build, and installed-package smoke all passed. Source is post-v0.2.583; no new release was cut. CI for the pushed batch is pending.

This issue remains OPEN. App theme/CSS-variable overrides, ring behavior, remaining native style normalization (including reactive CSS-text input), and maintained-host visual validation are not complete. The new runtime/IR tests are not a substitute for device-level visual validation.

9 days ago

Progress pushed to main: 90deaba6bb and 2e40d0831c share inline-style normalization between compiled HTML and reactive native bindings. CSS strings now work at runtime; numeric lengths normalize consistently; malformed/non-finite numeric values and unsupported properties are reported instead of passed through to native fields. Clearing a binding restores authored/class styles, including while hidden or changing appearance. Font weights retain the string representation required by the IR.

Regression coverage: packages/stx/test/native/inline-style.test.ts and reactive-inline-style.test.ts, including actual compiled dev/minified bundles. The runtime tests failed against the old CSS-string behavior before integration.

Validation at d4f3062c6d: full CI test command (bun test packages examples --max-concurrency=1) passed with 16,344 pass / 1 skip / 0 fail; typecheck, format check, build and installed-package smoke passed; lint had 0 errors (existing warnings remain). This also fixes the earlier overlay batch CI return-type failure in d4f3062c6d. New remote CI is pending.

Version: post-v0.2.583 source, not yet released. Keeping this issue open: custom theme/CSS-variable transport, rings or explicit host fallbacks, and maintained-host visual validation remain. These tests verify compiler/runtime behavior, not pixel-level device parity. Craft code was not modified.

9 days ago

Pushed two further styling fixes to main: a40627a reports unsupported runtime-computed classes and variants in JavaScriptCore, preserves authored names (including dark variants), and avoids repeating an unchanged warning on every update. 224069c translates numeric x/y offsets into native transforms, including negative/arbitrary lengths, dark-axis overrides, and removal/inline override behavior. The actual shared Switch regression now verifies thumb offsets across toggle and remount.

Validation: 523 native tests passed; the complete workspace suite at aad48bb passed 16,378 tests, with 1 skip and 0 failures. Typecheck, targeted lint, and formatting checks passed. aad48bb also fixes the test listener leak responsible for the preceding CI failure; new remote CI is pending.

Version: source-only and unreleased; package version remains 0.2.583. No Craft files changed. No simulator/device visual validation was performed. Keeping this issue open for custom theme transport, remaining meaningful styling gaps, and maintained-host visual verification.

9 days ago

Progress on main through f92746f (unreleased; package version remains 0.2.583): shared semantic colors, shape and density utilities now consume inherited inline variables, including reactive overrides and restoring defaults. Document-level variables in rendered style blocks now reach native IR and the shared runtime, with appearance variants, specificity, source order and !important handling. Transparent html/body/main wrappers retain variable scopes without adding layout views. Regression coverage includes initial dark appearance, changes after mounting, hidden/reinserted branches, new loop rows, parent aliases and local overrides. Maintained tests: 559 passed / 0 failed across the native suite plus exported-return-type guard after rebasing the grid-row changes; typecheck, lint and formatting passed. This also fixes the two missing return annotations that failed CI on the previous batch. New-tip CI still needs confirmation. Keeping this issue open: scoped stylesheet rules, cascade layers and external stylesheet loading remain unsupported; rings and maintained iOS/Android visual validation remain outstanding. These are JS/compiler tests, not simulator or device pixel-parity evidence.

9 days ago

Pushed e7c673a (unreleased after v0.2.605): explicit CSS flex containers now receive the CSS default row direction instead of falling through to native column defaults. Covers flex/inline-flex classes and inline display:flex/display:inline-flex. Defaults apply after authored class/inline/reactive/appearance layers, so an inline display declaration does not override a lower-layer flex-col. Plain native views retain their existing host defaults.

Five new regressions failed before the fix. Tests cover static translation, actual shared Checkbox/Switch containers, normal/minified bundles, appearance changes, direction overrides, removal and remount. Native suite plus exported-return-types guard: 623 passed, zero failed; typecheck and lint passed. No Craft source changes and no claim of device visual parity. Keeping the broader issue open.

9 days ago

Pushed 6171d72 (unreleased after v0.2.605): native border translation now supports numeric/arbitrary px/rem widths, individual sides, and x/y axes. It rejects malformed, negative, context-dependent and non-finite lengths rather than forwarding invalid numbers; color utilities retain their separate interpretation.

Regression coverage: border-width.test.ts plus actual shared-control attribute tests. Covers runtime appearance changes, inline overrides, clearing obsolete edge widths, and restoring each shared control to its unmodified styling. Baseline regressions failed before the fix. Current native suite plus exported-return-types guard: 630 passed, zero failed; lint/typecheck passed. Device visual validation remains outstanding; issue stays open.

9 days ago

Added a runnable same-source validation screen in 2558b57: examples/shared-controls.stx explicitly imports the actual shared Button/Card/TextInput/Checkbox/Switch templates. The accompanying test/native/shared-controls-example.test.ts verifies source dependencies and exercises editing, toggling, density changes, appearance and remount in browser/native harnesses with normal/minified builds. docs/guide/native.md gives the bundle command and device-validation checklist. This is unreleased after v0.2.605, not a claim of device visual parity; maintained-host execution remains outstanding.

9 days ago

Pushed ddcfab4, with documentation/audit in e7e3d8d. Version: unreleased source after v0.2.634; no release cut in this batch.

Native TextInput now tracks host onFocus/onBlur and applies supported focus: style layers, including semantic colors, dark:focus:/focus:dark:, reactive replacement and inline priority. Blur, disabling, hiding and removal clear focused styling; remount starts unfocused. Authored listeners share the existing event multiplexer. Normal/minified tests use the actual shared TextInput and cover overrides, updates/removal, teardown and late-added focus classes. The keyed-row regression still dispatches the retained focus handler after reordering; its assertion now accepts the handler in createNode as well as updateNode.

Rings are deliberately NOT approximated with borders or shadows. Read-only inspection of the maintained Craft templates found text-field focus/blur events but no independent ring/inset/offset drawing fields. Ring classes, focus-visible modality and focus styles on non-text controls remain diagnostic. focus-within is additional STX work, not included here. Craft code was not modified.

Verification: 2,516 passed / 0 failed across 189 native/component test files; typecheck, changed-file lint and formatting passed. New remote CI is pending. No simulator/device visual parity claim. Keeping the broader issue open for remaining style work and host/device validation.

9 days ago

Pushed the remaining ancestor-focus batch in 179f808 and c16fa8d. Version: unreleased source after v0.2.634; no release cut.

Supported focus-within: styles now follow host-reported text-input focus through the logical ancestry, including actual shared Card/TextInput composition. Dark variants, reactive classes, inline overrides, blur/disable, overlapping focus/blur delivery, subtree hiding/removal/remount, reparenting and cloning are covered. Late focus events while an ancestor is hidden do not restore focused styling. Inserting/removing unfocused subtrees does not trigger an ancestor style walk.

Tests: focus-within-translation.test.ts and focus-within-runtime.test.ts. Combined native/component suite: 2,521 passed / 0 failed across 191 files; the final ancestor-walk optimization additionally passed 23 focused/lifecycle tests. Typecheck, changed-file lint and formatting passed. New remote CI is pending.

Limits remain explicit in docs/guide/native.md and docs/proposals/native-component-resolution-audit.md: this tracks text-input focus events, not keyboard/accessibility focus on non-text controls. Rings/inset/offsets and focus-visible remain diagnosed, with no border/shadow approximation. No Craft code changed and no device visual/accessibility certification claimed. Keeping the broader issue open for host capabilities, other styling gaps and maintained-device validation.

5 days ago

Closing the design-token/essential-layout feature after maintained-host acceptance, rather than IR-only evidence. Acceptance batch 7b3749e82e, documentation d321e4fd8d, integrated main tip 77d8cd6702.

The same checked-in fixture imports actual shared Button, TextInput and Card sources. It passes a real browser check and four iOS/Android normal/minified protocol cases: computed spacing/radii, live appearance/panel-color changes, density updates and retained input/Card identity. The maintained iOS suite passes 2/2 in light and 2/2 in dark, zero failures/skips. It measures actual Card content insets at 24/8/24 points through density changes and verifies keyboard/value retention while the shared Button updates state and typing continues. Retained screenshots were inspected in both appearances for legible shared content and the authored panel colors.

Unsupported meaningful features remain explicit diagnostics, including rings/inset/offset and unavailable focus modes; they are not silently replaced with border/shadow approximations. This meets the issue's supported-feature/fallback boundary, not a claim that all browser CSS has a native equivalent. No Craft source was changed. Android device drawing, assistive-technology navigation and broader Image/component migration remain scoped in #2091.

Version status: the supported token machinery already existed; this acceptance batch is unreleased source after v0.2.746, and no additional release was cut. Integrated-tip CI is queued: https://github.com/stacksjs/stx/actions/runs/40915422118 . Exact host/STX provenance and replay commands are in docs/proposals/shared-controls-device-validation.md.

5 days ago

Publication follow-up: STX / @stacksjs/components / bun-plugin-stx v0.2.747 is published and npm latest, release commit 239d660dd833bf3ecefe89836a0252e16c8568fe. Public archive checksums verify, and all 7 fresh-install consumer checks pass. All five release-commit CI jobs are green: https://github.com/stacksjs/stx/actions/runs/40918690528 . The release gate passed 17,437 tests, zero failures (48 existing skips).

The same-source design-token/controls acceptance batch documented above is now part of this release's source history; the token engine itself was already implemented. The patch also ships the final native DialogPanel layout fix. No additional CSS-equivalence, Android-device or assistive-technology certification is implied by publication. Image migration remains tracked in #2091 / craft-native/craft#427. Remaining peripheral package publication is still running; no Craft code changed.

Sign in to comment on this issue.