@typecad/ui 1.0.0-alpha.12 → 1.0.0-alpha.13

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (113) hide show
  1. package/assets/fonts/dejavu/DejaVuSans-Bold.ttf +0 -0
  2. package/assets/fonts/dejavu/DejaVuSans-ExtraLight.ttf +0 -0
  3. package/assets/fonts/dejavu/DejaVuSans-Oblique.ttf +0 -0
  4. package/assets/fonts/dejavu/DejaVuSans.ttf +0 -0
  5. package/assets/fonts/dejavu/DejaVuSansMono-Bold.ttf +0 -0
  6. package/assets/fonts/dejavu/DejaVuSansMono.ttf +0 -0
  7. package/assets/fonts/dejavu/LICENSE +187 -0
  8. package/assets/fonts/dejavu/README.md +49 -0
  9. package/dist/engine-index.js +2 -0
  10. package/dist/preview/build-program.d.ts +7 -1
  11. package/dist/preview/build-program.js +94 -15
  12. package/dist/preview/host-gfx.d.ts +3 -0
  13. package/dist/preview/host-gfx.js +30 -3
  14. package/dist/preview/host-ui-runtime.d.ts +115 -0
  15. package/dist/preview/host-ui-runtime.js +928 -46
  16. package/dist/ui-engine/block-layout.js +25 -11
  17. package/dist/ui-engine/color.d.ts +6 -0
  18. package/dist/ui-engine/color.js +80 -2
  19. package/dist/ui-engine/compat-report.d.ts +8 -0
  20. package/dist/ui-engine/compat-report.js +124 -0
  21. package/dist/ui-engine/css-imports.d.ts +4 -0
  22. package/dist/ui-engine/css-imports.js +70 -0
  23. package/dist/ui-engine/css-parser.js +58 -14
  24. package/dist/ui-engine/default-font.d.ts +25 -0
  25. package/dist/ui-engine/default-font.js +80 -0
  26. package/dist/ui-engine/font-assets.d.ts +2 -2
  27. package/dist/ui-engine/font-assets.js +22 -5
  28. package/dist/ui-engine/html-parser.d.ts +4 -0
  29. package/dist/ui-engine/html-parser.js +241 -26
  30. package/dist/ui-engine/image-assets.d.ts +8 -1
  31. package/dist/ui-engine/image-assets.js +35 -2
  32. package/dist/ui-engine/image-decode.d.ts +22 -0
  33. package/dist/ui-engine/image-decode.js +194 -0
  34. package/dist/ui-engine/inline-parser.js +1 -1
  35. package/dist/ui-engine/layout-engine.d.ts +19 -0
  36. package/dist/ui-engine/layout-engine.js +59 -3
  37. package/dist/ui-engine/model.d.ts +18 -0
  38. package/dist/ui-engine/model.js +75 -7
  39. package/dist/ui-engine/runtime-header/blend-bodies.js +29 -9
  40. package/dist/ui-engine/runtime-header/canvas-helpers.js +3 -0
  41. package/dist/ui-engine/runtime-header/canvas-scrollbar.js +115 -111
  42. package/dist/ui-engine/runtime-header/cuttlefish-gfx.js +21 -0
  43. package/dist/ui-engine/runtime-header/dirty-scroll-mutators.js +182 -179
  44. package/dist/ui-engine/runtime-header/forward-decls.js +215 -167
  45. package/dist/ui-engine/runtime-header/init-press-input.js +138 -135
  46. package/dist/ui-engine/runtime-header/keyboard.js +682 -380
  47. package/dist/ui-engine/runtime-header/node-draw-body.js +1656 -1386
  48. package/dist/ui-engine/runtime-header/paint-order-coords.js +259 -214
  49. package/dist/ui-engine/runtime-header/paint-rects-repair.js +736 -568
  50. package/dist/ui-engine/runtime-header/scroll-physics.js +25 -1
  51. package/dist/ui-engine/runtime-header/state-bindings-nav.js +9 -0
  52. package/dist/ui-engine/runtime-header/structs.js +228 -216
  53. package/dist/ui-engine/runtime-header/text-rendering.js +888 -770
  54. package/dist/ui-engine/runtime-header/tick/bindings-phase.js +118 -116
  55. package/dist/ui-engine/runtime-header/tick/dirty-draw-phase.js +897 -633
  56. package/dist/ui-engine/runtime-header/tick/scroll-canvas-phase.js +24 -25
  57. package/dist/ui-engine/runtime-header/touch-keyboard-fwd.js +78 -23
  58. package/dist/ui-engine/runtime-header/types-defines.js +110 -93
  59. package/dist/ui-engine/shadcn-kit.d.ts +1 -0
  60. package/dist/ui-engine/shadcn-kit.js +502 -0
  61. package/dist/ui-engine/style-resolver.d.ts +4 -0
  62. package/dist/ui-engine/style-resolver.js +58 -6
  63. package/dist/ui-engine/transpile-ui.js +12 -5
  64. package/dist/ui-engine/ua-stylesheet.d.ts +22 -1
  65. package/dist/ui-engine/ua-stylesheet.js +119 -32
  66. package/dist/ui-engine/ui-lowering.js +37 -3
  67. package/dist/ui-engine/ui-registry.js +32 -4
  68. package/dist/ui-engine/yoga-layout.js +57 -52
  69. package/package.json +9 -3
  70. package/src/engine-index.ts +53 -51
  71. package/src/preview/build-program.ts +810 -734
  72. package/src/preview/host-gfx.ts +30 -3
  73. package/src/preview/host-ui-runtime.ts +4133 -3289
  74. package/src/ui-engine/block-layout.ts +24 -11
  75. package/src/ui-engine/color.ts +77 -2
  76. package/src/ui-engine/compat-report.ts +139 -0
  77. package/src/ui-engine/css-imports.ts +69 -0
  78. package/src/ui-engine/css-parser.ts +64 -15
  79. package/src/ui-engine/default-font.ts +95 -0
  80. package/src/ui-engine/font-assets.ts +545 -525
  81. package/src/ui-engine/html-parser.ts +615 -397
  82. package/src/ui-engine/image-assets.ts +37 -2
  83. package/src/ui-engine/image-decode.ts +244 -0
  84. package/src/ui-engine/inline-parser.ts +1 -1
  85. package/src/ui-engine/layout-engine.ts +61 -3
  86. package/src/ui-engine/model.ts +1317 -1230
  87. package/src/ui-engine/runtime-header/blend-bodies.ts +29 -9
  88. package/src/ui-engine/runtime-header/canvas-helpers.ts +3 -0
  89. package/src/ui-engine/runtime-header/canvas-scrollbar.ts +121 -117
  90. package/src/ui-engine/runtime-header/cuttlefish-gfx.ts +21 -0
  91. package/src/ui-engine/runtime-header/dirty-scroll-mutators.ts +188 -185
  92. package/src/ui-engine/runtime-header/forward-decls.ts +227 -179
  93. package/src/ui-engine/runtime-header/init-press-input.ts +144 -141
  94. package/src/ui-engine/runtime-header/keyboard.ts +689 -386
  95. package/src/ui-engine/runtime-header/node-draw-body.ts +1681 -1411
  96. package/src/ui-engine/runtime-header/paint-order-coords.ts +265 -220
  97. package/src/ui-engine/runtime-header/paint-rects-repair.ts +742 -574
  98. package/src/ui-engine/runtime-header/scroll-physics.ts +25 -1
  99. package/src/ui-engine/runtime-header/state-bindings-nav.ts +9 -0
  100. package/src/ui-engine/runtime-header/structs.ts +234 -222
  101. package/src/ui-engine/runtime-header/text-rendering.ts +894 -776
  102. package/src/ui-engine/runtime-header/tick/bindings-phase.ts +124 -122
  103. package/src/ui-engine/runtime-header/tick/dirty-draw-phase.ts +902 -638
  104. package/src/ui-engine/runtime-header/tick/scroll-canvas-phase.ts +30 -31
  105. package/src/ui-engine/runtime-header/touch-keyboard-fwd.ts +78 -23
  106. package/src/ui-engine/runtime-header/types-defines.ts +116 -99
  107. package/src/ui-engine/shadcn-kit.ts +503 -0
  108. package/src/ui-engine/style-resolver.ts +471 -416
  109. package/src/ui-engine/transpile-ui.ts +12 -5
  110. package/src/ui-engine/ua-stylesheet.ts +137 -31
  111. package/src/ui-engine/ui-lowering.ts +486 -452
  112. package/src/ui-engine/ui-registry.ts +556 -524
  113. package/src/ui-engine/yoga-layout.ts +307 -309
@@ -1,122 +1,124 @@
1
- // Slice of the C++ runtime header (original source lines 3930-4026).
2
- // ui_tick signature + opening, caret blink re-mark, bindings/list-bindings/input-bindings. Contains ui_tick opening.
3
- // See docs/superpowers/specs/2026-07-12-split-runtime-header-design.md.
4
- export function emitTickBindingsPhase(): string {
5
- return `
6
- static inline void ui_tick(uint16_t deltaMs) {
7
- // Touch poll — runs if touch is configured (defined by the emit layer)
8
- ui_poll_touch();
9
- // Allocate the retained framebuffer before transitions run. Geometry repair
10
- // must clear old animation footprints into RAM, not directly onto the panel.
11
- (void)ui_get_framebuffer();
12
- // ⓪' Poll GPIO inputs
13
- ui_poll_inputs();
14
- #if defined(UI_HIDE_OSK)
15
- // Advance the caret blink phase for the active input (desktop target).
16
- __ui_kb_blink++;
17
- // Re-mark the edited input dirty every ~16 ticks so the blink repainting
18
- // keeps cycling even when no other state changes (otherwise the caret
19
- // freezes once the typed-text dirty clears).
20
- if (__ui_kb_visible && __ui_kb_target >= 0 && (__ui_kb_blink & 0x10)) {
21
- ui_mark_dirty(static_cast<uint16_t>(__ui_kb_target));
22
- }
23
- #endif
24
- // ⓪ Evaluate bindings: call each binding's fn, compare to the node's
25
- // current property value, mark dirty if changed.
26
- for (uint16_t i = 0; i < __ui_binding_count; i++) {
27
- if (__ui_bindings[i].prop == PROP_TEXT && __ui_bindings[i].textFn) {
28
- // Text callbacks are necessarily evaluated to detect changes (the callback
29
- // may format a signal or read external state), but avoid a stack-sized old
30
- // copy: compare the generated value against the node buffer after writing.
31
- // The callback contract is fill-style and must be deterministic for the same
32
- // inputs; the temporary buffer keeps a change from destroying the old text.
33
- uint16_t n = __ui_bindings[i].node;
34
- if (n >= __ui_node_count) continue;
35
- char nextBuf[UI_TEXT_BUF + 1];
36
- nextBuf[0] = '\\0';
37
- __ui_bindings[i].textFn(nextBuf, UI_TEXT_BUF + 1);
38
- nextBuf[UI_TEXT_BUF] = '\\0';
39
- if (strcmp(nextBuf, __ui_nodes[n].textBuffer) != 0) {
40
- strncpy(__ui_nodes[n].textBuffer, nextBuf, UI_TEXT_BUF);
41
- __ui_nodes[n].textBuffer[UI_TEXT_BUF] = '\\0';
42
- ui_invalidate_text_layout_cache(n);
43
- ui_mark_dirty(n);
44
- }
45
- } else if (__ui_bindings[i].fn) {
46
- // Color/numeric binding
47
- uint32_t newVal = __ui_bindings[i].fn();
48
- if (__ui_bindings[i].prop == PROP_VISIBLE) {
49
- uint8_t nextVisible = newVal ? 1 : 0;
50
- if (nextVisible != __ui_nodes[__ui_bindings[i].node].visible) {
51
- ui_set_visible(__ui_bindings[i].node, nextVisible);
52
- }
53
- continue;
54
- }
55
- if (__ui_bindings[i].prop == PROP_VALUE) {
56
- // Numeric value binding: drive a progress/range node's value live.
57
- uint16_t n = __ui_bindings[i].node;
58
- int16_t v = static_cast<int16_t>(__ui_bindings[i].fn());
59
- if (v != __ui_nodes[n].value) {
60
- __ui_nodes[n].value = v;
61
- ui_mark_dirty(n);
62
- }
63
- continue;
64
- }
65
- // Cache numeric binding results. The first sample establishes the baseline;
66
- // subsequent identical values return immediately without touching node state.
67
- if (__ui_bindings[i].initialized && newVal == __ui_bindings[i].lastValue) continue;
68
- __ui_bindings[i].lastValue = newVal;
69
- __ui_bindings[i].initialized = 1;
70
- uint32_t* target = (__ui_bindings[i].prop == PROP_BG) ? &__ui_nodes[__ui_bindings[i].node].bg
71
- : (__ui_bindings[i].prop == PROP_FG) ? &__ui_nodes[__ui_bindings[i].node].fg
72
- : (__ui_bindings[i].prop == PROP_BORDER_COLOR) ? &__ui_nodes[__ui_bindings[i].node].borderColor
73
- : &__ui_nodes[__ui_bindings[i].node].bg;
74
- if (newVal != *target) {
75
- *target = newVal;
76
- // When a background binding writes a new color, ensure hasBg is set
77
- // so the draw dispatch actually fills (the node may have started
78
- // transparent but now has a runtime-assigned background).
79
- if (__ui_bindings[i].prop == PROP_BG) __ui_nodes[__ui_bindings[i].node].hasBg = 1;
80
- ui_mark_dirty(__ui_bindings[i].node);
81
- }
82
- }
83
- }
84
- // ⓪b Evaluate list bindings (on-node): refresh item count, recompute content
85
- // height, and advance any in-flight settle animation (bounce-back / edge-snap).
86
- // Also note whether any active-screen node is settling (feeds scroll-motion
87
- // gating below without a second full-node scan).
88
- uint8_t settlingOnActiveScreen = 0;
89
- for (uint16_t i = 0; i < __ui_node_count; i++) {
90
- if (__ui_nodes[i].virtualized && __ui_nodes[i].listCountFn) {
91
- uint16_t ih = __ui_nodes[i].listItemHeight > 0 ? __ui_nodes[i].listItemHeight : 24;
92
- // Keep the callback result as the list's invalidation token. The callback
93
- // is still evaluated because it is the public list-count source, but an
94
- // unchanged token avoids layout/dirty work and preserves the retained
95
- // viewport canvas.
96
- uint16_t newCount = __ui_nodes[i].listCountFn();
97
- if (newCount != __ui_nodes[i].listCount) {
98
- __ui_nodes[i].listCount = newCount;
99
- __ui_nodes[i].contentHeight = static_cast<int16_t>(static_cast<uint32_t>(newCount) * ih);
100
- __ui_nodes[i].lastPaintedScrollY = __ui_nodes[i].scrollY - (__ui_nodes[i].box.h > 0 ? __ui_nodes[i].box.h : 1);
101
- ui_mark_dirty(i);
102
- }
103
- }
104
- if (__ui_nodes[i].settling) {
105
- if (__ui_nodes[i].screenId == __ui_active_screen) settlingOnActiveScreen = 1;
106
- ui_scroll_advance_settle(i, deltaMs);
107
- }
108
- }
109
- // ⓪c Evaluate input bindings (two-way): if a bound <input>'s textBuffer
110
- // changed since last tick (e.g. the user typed via the on-screen keyboard),
111
- // fire the author's callback with the new text.
112
- for (uint16_t i = 0; i < __ui_input_binding_count; i++) {
113
- if (!__ui_input_bindings[i].cb) continue;
114
- uint16_t n = __ui_input_bindings[i].node;
115
- if (n >= __ui_node_count) continue;
116
- const char* cur = __ui_nodes[n].textBuffer;
117
- if (strcmp(cur, __ui_input_bindings[i].lastSeen) != 0) {
118
- strncpy(__ui_input_bindings[i].lastSeen, cur, UI_TEXT_BUF);
119
- __ui_input_bindings[i].lastSeen[UI_TEXT_BUF] = '\\0';
120
- __ui_input_bindings[i].cb(cur);
121
- }`;
122
- }
1
+ // Slice of the C++ runtime header (original source lines 3930-4026).
2
+ // ui_tick signature + opening, caret blink re-mark, bindings/list-bindings/input-bindings. Contains ui_tick opening.
3
+ // See docs/superpowers/specs/2026-07-12-split-runtime-header-design.md.
4
+ export function emitTickBindingsPhase(): string {
5
+ return `
6
+ static inline void ui_tick(uint16_t deltaMs) {
7
+ // Touch poll — runs if touch is configured (defined by the emit layer)
8
+ ui_poll_touch();
9
+ // <drawer> slide animation (device parity with the preview's applyDrawers).
10
+ ui_drawer_tick(deltaMs);
11
+ // Allocate the retained framebuffer before transitions run. Geometry repair
12
+ // must clear old animation footprints into RAM, not directly onto the panel.
13
+ (void)ui_get_framebuffer();
14
+ // ⓪' Poll GPIO inputs
15
+ ui_poll_inputs();
16
+ #if defined(UI_HIDE_OSK)
17
+ // Advance the caret blink phase for the active input (desktop target).
18
+ __ui_kb_blink++;
19
+ // Re-mark the edited input dirty every ~16 ticks so the blink repainting
20
+ // keeps cycling even when no other state changes (otherwise the caret
21
+ // freezes once the typed-text dirty clears).
22
+ if (__ui_kb_visible && __ui_kb_target >= 0 && (__ui_kb_blink & 0x10)) {
23
+ ui_mark_dirty(static_cast<uint16_t>(__ui_kb_target));
24
+ }
25
+ #endif
26
+ // Evaluate bindings: call each binding's fn, compare to the node's
27
+ // current property value, mark dirty if changed.
28
+ for (uint16_t i = 0; i < __ui_binding_count; i++) {
29
+ if (__ui_bindings[i].prop == PROP_TEXT && __ui_bindings[i].textFn) {
30
+ // Text callbacks are necessarily evaluated to detect changes (the callback
31
+ // may format a signal or read external state), but avoid a stack-sized old
32
+ // copy: compare the generated value against the node buffer after writing.
33
+ // The callback contract is fill-style and must be deterministic for the same
34
+ // inputs; the temporary buffer keeps a change from destroying the old text.
35
+ uint16_t n = __ui_bindings[i].node;
36
+ if (n >= __ui_node_count) continue;
37
+ char nextBuf[UI_TEXT_BUF + 1];
38
+ nextBuf[0] = '\\0';
39
+ __ui_bindings[i].textFn(nextBuf, UI_TEXT_BUF + 1);
40
+ nextBuf[UI_TEXT_BUF] = '\\0';
41
+ if (strcmp(nextBuf, __ui_nodes[n].textBuffer) != 0) {
42
+ strncpy(__ui_nodes[n].textBuffer, nextBuf, UI_TEXT_BUF);
43
+ __ui_nodes[n].textBuffer[UI_TEXT_BUF] = '\\0';
44
+ ui_invalidate_text_layout_cache(n);
45
+ ui_mark_dirty(n);
46
+ }
47
+ } else if (__ui_bindings[i].fn) {
48
+ // Color/numeric binding
49
+ uint32_t newVal = __ui_bindings[i].fn();
50
+ if (__ui_bindings[i].prop == PROP_VISIBLE) {
51
+ uint8_t nextVisible = newVal ? 1 : 0;
52
+ if (nextVisible != __ui_nodes[__ui_bindings[i].node].visible) {
53
+ ui_set_visible(__ui_bindings[i].node, nextVisible);
54
+ }
55
+ continue;
56
+ }
57
+ if (__ui_bindings[i].prop == PROP_VALUE) {
58
+ // Numeric value binding: drive a progress/range node's value live.
59
+ uint16_t n = __ui_bindings[i].node;
60
+ int16_t v = static_cast<int16_t>(__ui_bindings[i].fn());
61
+ if (v != __ui_nodes[n].value) {
62
+ __ui_nodes[n].value = v;
63
+ ui_mark_dirty(n);
64
+ }
65
+ continue;
66
+ }
67
+ // Cache numeric binding results. The first sample establishes the baseline;
68
+ // subsequent identical values return immediately without touching node state.
69
+ if (__ui_bindings[i].initialized && newVal == __ui_bindings[i].lastValue) continue;
70
+ __ui_bindings[i].lastValue = newVal;
71
+ __ui_bindings[i].initialized = 1;
72
+ uint32_t* target = (__ui_bindings[i].prop == PROP_BG) ? &__ui_nodes[__ui_bindings[i].node].bg
73
+ : (__ui_bindings[i].prop == PROP_FG) ? &__ui_nodes[__ui_bindings[i].node].fg
74
+ : (__ui_bindings[i].prop == PROP_BORDER_COLOR) ? &__ui_nodes[__ui_bindings[i].node].borderColor
75
+ : &__ui_nodes[__ui_bindings[i].node].bg;
76
+ if (newVal != *target) {
77
+ *target = newVal;
78
+ // When a background binding writes a new color, ensure hasBg is set
79
+ // so the draw dispatch actually fills (the node may have started
80
+ // transparent but now has a runtime-assigned background).
81
+ if (__ui_bindings[i].prop == PROP_BG) __ui_nodes[__ui_bindings[i].node].hasBg = 1;
82
+ ui_mark_dirty(__ui_bindings[i].node);
83
+ }
84
+ }
85
+ }
86
+ // ⓪b Evaluate list bindings (on-node): refresh item count, recompute content
87
+ // height, and advance any in-flight settle animation (bounce-back / edge-snap).
88
+ // Also note whether any active-screen node is settling (feeds scroll-motion
89
+ // gating below without a second full-node scan).
90
+ uint8_t settlingOnActiveScreen = 0;
91
+ for (uint16_t i = 0; i < __ui_node_count; i++) {
92
+ if (__ui_nodes[i].virtualized && __ui_nodes[i].listCountFn) {
93
+ uint16_t ih = __ui_nodes[i].listItemHeight > 0 ? __ui_nodes[i].listItemHeight : 24;
94
+ // Keep the callback result as the list's invalidation token. The callback
95
+ // is still evaluated because it is the public list-count source, but an
96
+ // unchanged token avoids layout/dirty work and preserves the retained
97
+ // viewport canvas.
98
+ uint16_t newCount = __ui_nodes[i].listCountFn();
99
+ if (newCount != __ui_nodes[i].listCount) {
100
+ __ui_nodes[i].listCount = newCount;
101
+ __ui_nodes[i].contentHeight = static_cast<int16_t>(static_cast<uint32_t>(newCount) * ih);
102
+ __ui_nodes[i].lastPaintedScrollY = __ui_nodes[i].scrollY - (__ui_nodes[i].box.h > 0 ? __ui_nodes[i].box.h : 1);
103
+ ui_mark_dirty(i);
104
+ }
105
+ }
106
+ if (__ui_nodes[i].settling) {
107
+ if (__ui_nodes[i].screenId == __ui_active_screen) settlingOnActiveScreen = 1;
108
+ ui_scroll_advance_settle(i, deltaMs);
109
+ }
110
+ }
111
+ // ⓪c Evaluate input bindings (two-way): if a bound <input>'s textBuffer
112
+ // changed since last tick (e.g. the user typed via the on-screen keyboard),
113
+ // fire the author's callback with the new text.
114
+ for (uint16_t i = 0; i < __ui_input_binding_count; i++) {
115
+ if (!__ui_input_bindings[i].cb) continue;
116
+ uint16_t n = __ui_input_bindings[i].node;
117
+ if (n >= __ui_node_count) continue;
118
+ const char* cur = __ui_nodes[n].textBuffer;
119
+ if (strcmp(cur, __ui_input_bindings[i].lastSeen) != 0) {
120
+ strncpy(__ui_input_bindings[i].lastSeen, cur, UI_TEXT_BUF);
121
+ __ui_input_bindings[i].lastSeen[UI_TEXT_BUF] = '\\0';
122
+ __ui_input_bindings[i].cb(cur);
123
+ }`;
124
+ }