@rezi-ui/core 0.1.0-alpha.33 → 0.1.0-alpha.35

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 (169) hide show
  1. package/dist/animation/interpolate.d.ts +5 -0
  2. package/dist/animation/interpolate.d.ts.map +1 -1
  3. package/dist/animation/interpolate.js +30 -0
  4. package/dist/animation/interpolate.js.map +1 -1
  5. package/dist/animation/timeline.d.ts.map +1 -1
  6. package/dist/animation/timeline.js +1 -3
  7. package/dist/animation/timeline.js.map +1 -1
  8. package/dist/animation/types.d.ts +17 -0
  9. package/dist/animation/types.d.ts.map +1 -1
  10. package/dist/app/createApp.d.ts +1 -0
  11. package/dist/app/createApp.d.ts.map +1 -1
  12. package/dist/app/createApp.js +137 -30
  13. package/dist/app/createApp.js.map +1 -1
  14. package/dist/app/types.d.ts +2 -0
  15. package/dist/app/types.d.ts.map +1 -1
  16. package/dist/app/widgetRenderer/animationTracks.d.ts +43 -2
  17. package/dist/app/widgetRenderer/animationTracks.d.ts.map +1 -1
  18. package/dist/app/widgetRenderer/animationTracks.js +83 -3
  19. package/dist/app/widgetRenderer/animationTracks.js.map +1 -1
  20. package/dist/app/widgetRenderer/cursorBreadcrumbs.d.ts +1 -1
  21. package/dist/app/widgetRenderer/cursorBreadcrumbs.d.ts.map +1 -1
  22. package/dist/app/widgetRenderer/cursorBreadcrumbs.js +5 -2
  23. package/dist/app/widgetRenderer/cursorBreadcrumbs.js.map +1 -1
  24. package/dist/app/widgetRenderer/damageTracking.d.ts +1 -0
  25. package/dist/app/widgetRenderer/damageTracking.d.ts.map +1 -1
  26. package/dist/app/widgetRenderer/damageTracking.js +2 -0
  27. package/dist/app/widgetRenderer/damageTracking.js.map +1 -1
  28. package/dist/app/widgetRenderer/mouseRouting.d.ts.map +1 -1
  29. package/dist/app/widgetRenderer/mouseRouting.js +4 -2
  30. package/dist/app/widgetRenderer/mouseRouting.js.map +1 -1
  31. package/dist/app/widgetRenderer/submitFramePipeline.d.ts.map +1 -1
  32. package/dist/app/widgetRenderer/submitFramePipeline.js +277 -0
  33. package/dist/app/widgetRenderer/submitFramePipeline.js.map +1 -1
  34. package/dist/app/widgetRenderer.d.ts +15 -2
  35. package/dist/app/widgetRenderer.d.ts.map +1 -1
  36. package/dist/app/widgetRenderer.js +161 -59
  37. package/dist/app/widgetRenderer.js.map +1 -1
  38. package/dist/index.d.ts +7 -4
  39. package/dist/index.d.ts.map +1 -1
  40. package/dist/index.js +4 -2
  41. package/dist/index.js.map +1 -1
  42. package/dist/layout/constraints.d.ts +15 -2
  43. package/dist/layout/constraints.d.ts.map +1 -1
  44. package/dist/layout/constraints.js +94 -4
  45. package/dist/layout/constraints.js.map +1 -1
  46. package/dist/layout/engine/distributeInteger.d.ts +9 -0
  47. package/dist/layout/engine/distributeInteger.d.ts.map +1 -0
  48. package/dist/layout/engine/distributeInteger.js +62 -0
  49. package/dist/layout/engine/distributeInteger.js.map +1 -0
  50. package/dist/layout/engine/flex.d.ts +14 -0
  51. package/dist/layout/engine/flex.d.ts.map +1 -1
  52. package/dist/layout/engine/flex.js +144 -1
  53. package/dist/layout/engine/flex.js.map +1 -1
  54. package/dist/layout/engine/guards.d.ts +8 -0
  55. package/dist/layout/engine/guards.d.ts.map +1 -1
  56. package/dist/layout/engine/guards.js +6 -0
  57. package/dist/layout/engine/guards.js.map +1 -1
  58. package/dist/layout/engine/intrinsic.d.ts +8 -0
  59. package/dist/layout/engine/intrinsic.d.ts.map +1 -0
  60. package/dist/layout/engine/intrinsic.js +383 -0
  61. package/dist/layout/engine/intrinsic.js.map +1 -0
  62. package/dist/layout/engine/layoutEngine.d.ts.map +1 -1
  63. package/dist/layout/engine/layoutEngine.js +78 -2
  64. package/dist/layout/engine/layoutEngine.js.map +1 -1
  65. package/dist/layout/kinds/box.d.ts +1 -1
  66. package/dist/layout/kinds/box.d.ts.map +1 -1
  67. package/dist/layout/kinds/box.js +48 -8
  68. package/dist/layout/kinds/box.js.map +1 -1
  69. package/dist/layout/kinds/grid.d.ts.map +1 -1
  70. package/dist/layout/kinds/grid.js +230 -29
  71. package/dist/layout/kinds/grid.js.map +1 -1
  72. package/dist/layout/kinds/leaf.d.ts.map +1 -1
  73. package/dist/layout/kinds/leaf.js +7 -2
  74. package/dist/layout/kinds/leaf.js.map +1 -1
  75. package/dist/layout/kinds/overlays.d.ts.map +1 -1
  76. package/dist/layout/kinds/overlays.js +28 -8
  77. package/dist/layout/kinds/overlays.js.map +1 -1
  78. package/dist/layout/kinds/stack.d.ts.map +1 -1
  79. package/dist/layout/kinds/stack.js +606 -218
  80. package/dist/layout/kinds/stack.js.map +1 -1
  81. package/dist/layout/responsive.d.ts +13 -1
  82. package/dist/layout/responsive.d.ts.map +1 -1
  83. package/dist/layout/responsive.js +60 -1
  84. package/dist/layout/responsive.js.map +1 -1
  85. package/dist/layout/textMeasure.d.ts +15 -0
  86. package/dist/layout/textMeasure.d.ts.map +1 -1
  87. package/dist/layout/textMeasure.js +116 -0
  88. package/dist/layout/textMeasure.js.map +1 -1
  89. package/dist/layout/types.d.ts +24 -0
  90. package/dist/layout/types.d.ts.map +1 -1
  91. package/dist/layout/validateProps.d.ts +14 -0
  92. package/dist/layout/validateProps.d.ts.map +1 -1
  93. package/dist/layout/validateProps.js +121 -1
  94. package/dist/layout/validateProps.js.map +1 -1
  95. package/dist/renderer/renderToDrawlist/renderTree.d.ts.map +1 -1
  96. package/dist/renderer/renderToDrawlist/renderTree.js +32 -2
  97. package/dist/renderer/renderToDrawlist/renderTree.js.map +1 -1
  98. package/dist/renderer/renderToDrawlist/themeTokens.d.ts +2 -15
  99. package/dist/renderer/renderToDrawlist/themeTokens.d.ts.map +1 -1
  100. package/dist/renderer/renderToDrawlist/themeTokens.js +2 -74
  101. package/dist/renderer/renderToDrawlist/themeTokens.js.map +1 -1
  102. package/dist/renderer/renderToDrawlist/widgets/basic.d.ts.map +1 -1
  103. package/dist/renderer/renderToDrawlist/widgets/basic.js +23 -2
  104. package/dist/renderer/renderToDrawlist/widgets/basic.js.map +1 -1
  105. package/dist/renderer/renderToDrawlist/widgets/collections.d.ts.map +1 -1
  106. package/dist/renderer/renderToDrawlist/widgets/collections.js +56 -4
  107. package/dist/renderer/renderToDrawlist/widgets/collections.js.map +1 -1
  108. package/dist/renderer/renderToDrawlist/widgets/navigation.d.ts +2 -1
  109. package/dist/renderer/renderToDrawlist/widgets/navigation.d.ts.map +1 -1
  110. package/dist/renderer/renderToDrawlist/widgets/navigation.js +171 -3
  111. package/dist/renderer/renderToDrawlist/widgets/navigation.js.map +1 -1
  112. package/dist/renderer/renderToDrawlist/widgets/overlays.d.ts.map +1 -1
  113. package/dist/renderer/renderToDrawlist/widgets/overlays.js +84 -26
  114. package/dist/renderer/renderToDrawlist/widgets/overlays.js.map +1 -1
  115. package/dist/renderer/renderToDrawlist/widgets/renderTextWidgets.d.ts.map +1 -1
  116. package/dist/renderer/renderToDrawlist/widgets/renderTextWidgets.js +64 -1
  117. package/dist/renderer/renderToDrawlist/widgets/renderTextWidgets.js.map +1 -1
  118. package/dist/runtime/commit.d.ts +17 -1
  119. package/dist/runtime/commit.d.ts.map +1 -1
  120. package/dist/runtime/commit.js +291 -121
  121. package/dist/runtime/commit.js.map +1 -1
  122. package/dist/runtime/router/types.d.ts +1 -0
  123. package/dist/runtime/router/types.d.ts.map +1 -1
  124. package/dist/runtime/router/virtualList.d.ts.map +1 -1
  125. package/dist/runtime/router/virtualList.js +4 -2
  126. package/dist/runtime/router/virtualList.js.map +1 -1
  127. package/dist/theme/blend.d.ts +6 -0
  128. package/dist/theme/blend.d.ts.map +1 -0
  129. package/dist/theme/blend.js +15 -0
  130. package/dist/theme/blend.js.map +1 -0
  131. package/dist/theme/extract.d.ts +8 -0
  132. package/dist/theme/extract.d.ts.map +1 -0
  133. package/dist/theme/extract.js +71 -0
  134. package/dist/theme/extract.js.map +1 -0
  135. package/dist/ui/designTokens.d.ts +3 -2
  136. package/dist/ui/designTokens.d.ts.map +1 -1
  137. package/dist/ui/designTokens.js +12 -1
  138. package/dist/ui/designTokens.js.map +1 -1
  139. package/dist/ui/index.d.ts +1 -1
  140. package/dist/ui/index.d.ts.map +1 -1
  141. package/dist/ui/index.js +1 -1
  142. package/dist/ui/index.js.map +1 -1
  143. package/dist/ui/recipes.d.ts +154 -1
  144. package/dist/ui/recipes.d.ts.map +1 -1
  145. package/dist/ui/recipes.js +520 -12
  146. package/dist/ui/recipes.js.map +1 -1
  147. package/dist/widgets/composition.d.ts +8 -2
  148. package/dist/widgets/composition.d.ts.map +1 -1
  149. package/dist/widgets/composition.js +3 -2
  150. package/dist/widgets/composition.js.map +1 -1
  151. package/dist/widgets/hooks/animation.d.ts +41 -0
  152. package/dist/widgets/hooks/animation.d.ts.map +1 -1
  153. package/dist/widgets/hooks/animation.js +549 -96
  154. package/dist/widgets/hooks/animation.js.map +1 -1
  155. package/dist/widgets/protocol.d.ts.map +1 -1
  156. package/dist/widgets/protocol.js +1 -0
  157. package/dist/widgets/protocol.js.map +1 -1
  158. package/dist/widgets/splitPane.d.ts.map +1 -1
  159. package/dist/widgets/splitPane.js +17 -6
  160. package/dist/widgets/splitPane.js.map +1 -1
  161. package/dist/widgets/tests/protocol.test.js +1 -0
  162. package/dist/widgets/tests/protocol.test.js.map +1 -1
  163. package/dist/widgets/types.d.ts +95 -2
  164. package/dist/widgets/types.d.ts.map +1 -1
  165. package/dist/widgets/ui.d.ts +3 -0
  166. package/dist/widgets/ui.d.ts.map +1 -1
  167. package/dist/widgets/ui.js +6 -1
  168. package/dist/widgets/ui.js.map +1 -1
  169. package/package.json +2 -2
@@ -1,10 +1,15 @@
1
1
  /**
2
2
  * packages/core/src/animation/interpolate.ts — Primitive interpolation helpers.
3
3
  */
4
+ import type { Rgb } from "../widgets/style.js";
4
5
  /** Clamp a number into [0, 1]. */
5
6
  export declare function clamp01(value: number): number;
6
7
  /** Clamp an animation duration to a safe, non-negative integer in milliseconds. */
7
8
  export declare function normalizeDurationMs(durationMs: number | undefined, fallbackMs: number): number;
8
9
  /** Linear interpolation between two numeric values. */
9
10
  export declare function interpolateNumber(from: number, to: number, t: number): number;
11
+ /** Linear interpolation between two RGB colors. */
12
+ export declare function interpolateRgb(from: Rgb, to: Rgb, t: number): Rgb;
13
+ /** Generate `steps` RGB samples between two colors (inclusive endpoints). */
14
+ export declare function interpolateRgbArray(from: Rgb, to: Rgb, steps: number): readonly Rgb[];
10
15
  //# sourceMappingURL=interpolate.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"interpolate.d.ts","sourceRoot":"","sources":["../../src/animation/interpolate.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,kCAAkC;AAClC,wBAAgB,OAAO,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAK7C;AAED,mFAAmF;AACnF,wBAAgB,mBAAmB,CAAC,UAAU,EAAE,MAAM,GAAG,SAAS,EAAE,UAAU,EAAE,MAAM,GAAG,MAAM,CAI9F;AAED,uDAAuD;AACvD,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,CAE7E"}
1
+ {"version":3,"file":"interpolate.d.ts","sourceRoot":"","sources":["../../src/animation/interpolate.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,qBAAqB,CAAC;AAE/C,kCAAkC;AAClC,wBAAgB,OAAO,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAK7C;AAED,mFAAmF;AACnF,wBAAgB,mBAAmB,CAAC,UAAU,EAAE,MAAM,GAAG,SAAS,EAAE,UAAU,EAAE,MAAM,GAAG,MAAM,CAI9F;AAED,uDAAuD;AACvD,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,CAE7E;AASD,mDAAmD;AACnD,wBAAgB,cAAc,CAAC,IAAI,EAAE,GAAG,EAAE,EAAE,EAAE,GAAG,EAAE,CAAC,EAAE,MAAM,GAAG,GAAG,CAMjE;AAED,6EAA6E;AAC7E,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,GAAG,EAAE,EAAE,EAAE,GAAG,EAAE,KAAK,EAAE,MAAM,GAAG,SAAS,GAAG,EAAE,CASrF"}
@@ -23,4 +23,34 @@ export function normalizeDurationMs(durationMs, fallbackMs) {
23
23
  export function interpolateNumber(from, to, t) {
24
24
  return from + (to - from) * clamp01(t);
25
25
  }
26
+ function clampRgbChannel(channel) {
27
+ if (!Number.isFinite(channel))
28
+ return 0;
29
+ if (channel <= 0)
30
+ return 0;
31
+ if (channel >= 255)
32
+ return 255;
33
+ return Math.round(channel);
34
+ }
35
+ /** Linear interpolation between two RGB colors. */
36
+ export function interpolateRgb(from, to, t) {
37
+ return Object.freeze({
38
+ r: clampRgbChannel(interpolateNumber(from.r, to.r, t)),
39
+ g: clampRgbChannel(interpolateNumber(from.g, to.g, t)),
40
+ b: clampRgbChannel(interpolateNumber(from.b, to.b, t)),
41
+ });
42
+ }
43
+ /** Generate `steps` RGB samples between two colors (inclusive endpoints). */
44
+ export function interpolateRgbArray(from, to, steps) {
45
+ const count = Math.max(0, Math.trunc(steps));
46
+ if (count <= 0)
47
+ return Object.freeze([]);
48
+ if (count === 1)
49
+ return Object.freeze([interpolateRgb(from, to, 0)]);
50
+ const samples = new Array(count);
51
+ for (let i = 0; i < count; i++) {
52
+ samples[i] = interpolateRgb(from, to, i / (count - 1));
53
+ }
54
+ return Object.freeze(samples);
55
+ }
26
56
  //# sourceMappingURL=interpolate.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"interpolate.js","sourceRoot":"","sources":["../../src/animation/interpolate.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,kCAAkC;AAClC,MAAM,UAAU,OAAO,CAAC,KAAa;IACnC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC;QAAE,OAAO,CAAC,CAAC;IACtC,IAAI,KAAK,IAAI,CAAC;QAAE,OAAO,CAAC,CAAC;IACzB,IAAI,KAAK,IAAI,CAAC;QAAE,OAAO,CAAC,CAAC;IACzB,OAAO,KAAK,CAAC;AACf,CAAC;AAED,mFAAmF;AACnF,MAAM,UAAU,mBAAmB,CAAC,UAA8B,EAAE,UAAkB;IACpF,IAAI,UAAU,KAAK,SAAS;QAAE,OAAO,UAAU,CAAC;IAChD,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,UAAU,CAAC;QAAE,OAAO,UAAU,CAAC;IACpD,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC,CAAC;AAC7C,CAAC;AAED,uDAAuD;AACvD,MAAM,UAAU,iBAAiB,CAAC,IAAY,EAAE,EAAU,EAAE,CAAS;IACnE,OAAO,IAAI,GAAG,CAAC,EAAE,GAAG,IAAI,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;AACzC,CAAC"}
1
+ {"version":3,"file":"interpolate.js","sourceRoot":"","sources":["../../src/animation/interpolate.ts"],"names":[],"mappings":"AAAA;;GAEG;AAIH,kCAAkC;AAClC,MAAM,UAAU,OAAO,CAAC,KAAa;IACnC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC;QAAE,OAAO,CAAC,CAAC;IACtC,IAAI,KAAK,IAAI,CAAC;QAAE,OAAO,CAAC,CAAC;IACzB,IAAI,KAAK,IAAI,CAAC;QAAE,OAAO,CAAC,CAAC;IACzB,OAAO,KAAK,CAAC;AACf,CAAC;AAED,mFAAmF;AACnF,MAAM,UAAU,mBAAmB,CAAC,UAA8B,EAAE,UAAkB;IACpF,IAAI,UAAU,KAAK,SAAS;QAAE,OAAO,UAAU,CAAC;IAChD,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,UAAU,CAAC;QAAE,OAAO,UAAU,CAAC;IACpD,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC,CAAC;AAC7C,CAAC;AAED,uDAAuD;AACvD,MAAM,UAAU,iBAAiB,CAAC,IAAY,EAAE,EAAU,EAAE,CAAS;IACnE,OAAO,IAAI,GAAG,CAAC,EAAE,GAAG,IAAI,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;AACzC,CAAC;AAED,SAAS,eAAe,CAAC,OAAe;IACtC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC;QAAE,OAAO,CAAC,CAAC;IACxC,IAAI,OAAO,IAAI,CAAC;QAAE,OAAO,CAAC,CAAC;IAC3B,IAAI,OAAO,IAAI,GAAG;QAAE,OAAO,GAAG,CAAC;IAC/B,OAAO,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;AAC7B,CAAC;AAED,mDAAmD;AACnD,MAAM,UAAU,cAAc,CAAC,IAAS,EAAE,EAAO,EAAE,CAAS;IAC1D,OAAO,MAAM,CAAC,MAAM,CAAC;QACnB,CAAC,EAAE,eAAe,CAAC,iBAAiB,CAAC,IAAI,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;QACtD,CAAC,EAAE,eAAe,CAAC,iBAAiB,CAAC,IAAI,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;QACtD,CAAC,EAAE,eAAe,CAAC,iBAAiB,CAAC,IAAI,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;KACvD,CAAC,CAAC;AACL,CAAC;AAED,6EAA6E;AAC7E,MAAM,UAAU,mBAAmB,CAAC,IAAS,EAAE,EAAO,EAAE,KAAa;IACnE,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC;IAC7C,IAAI,KAAK,IAAI,CAAC;QAAE,OAAO,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;IACzC,IAAI,KAAK,KAAK,CAAC;QAAE,OAAO,MAAM,CAAC,MAAM,CAAC,CAAC,cAAc,CAAC,IAAI,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;IACrE,MAAM,OAAO,GAAU,IAAI,KAAK,CAAC,KAAK,CAAC,CAAC;IACxC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,EAAE,CAAC,EAAE,EAAE,CAAC;QAC/B,OAAO,CAAC,CAAC,CAAC,GAAG,cAAc,CAAC,IAAI,EAAE,EAAE,EAAE,CAAC,GAAG,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC;IACzD,CAAC;IACD,OAAO,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;AAChC,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"timeline.d.ts","sourceRoot":"","sources":["../../src/animation/timeline.ts"],"names":[],"mappings":"AAAA;;GAEG;AAIH,OAAO,KAAK,EAAE,cAAc,EAAE,WAAW,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAEhF,KAAK,eAAe,GAAG,QAAQ,CAAC;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,MAAM,CAAC;IACX,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,cAAc,CAAC;CACxB,CAAC,CAAC;AAEH,MAAM,MAAM,kBAAkB,GAAG,QAAQ,CAAC;IACxC,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,SAAS,eAAe,EAAE,CAAC;IACrC,eAAe,EAAE,MAAM,CAAC;CACzB,CAAC,CAAC;AAEH,MAAM,MAAM,cAAc,GAAG,QAAQ,CAAC;IACpC,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,OAAO,CAAC;CACf,CAAC,CAAC;AAgBH,wBAAgB,iBAAiB,CAC/B,SAAS,EAAE,SAAS,gBAAgB,EAAE,EACtC,QAAQ,GAAE,QAAQ,CAAC;IAAE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,WAAW,CAAA;CAAE,CAAM,GACnE,kBAAkB,CA4CpB;AAED,wBAAgB,cAAc,CAC5B,QAAQ,EAAE,kBAAkB,EAC5B,SAAS,EAAE,MAAM,EACjB,IAAI,EAAE,OAAO,GACZ,cAAc,CAwChB"}
1
+ {"version":3,"file":"timeline.d.ts","sourceRoot":"","sources":["../../src/animation/timeline.ts"],"names":[],"mappings":"AAAA;;GAEG;AAIH,OAAO,KAAK,EAAE,cAAc,EAAE,WAAW,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAEhF,KAAK,eAAe,GAAG,QAAQ,CAAC;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,MAAM,CAAC;IACX,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,cAAc,CAAC;CACxB,CAAC,CAAC;AAEH,MAAM,MAAM,kBAAkB,GAAG,QAAQ,CAAC;IACxC,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,SAAS,eAAe,EAAE,CAAC;IACrC,eAAe,EAAE,MAAM,CAAC;CACzB,CAAC,CAAC;AAEH,MAAM,MAAM,cAAc,GAAG,QAAQ,CAAC;IACpC,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,OAAO,CAAC;CACf,CAAC,CAAC;AAgBH,wBAAgB,iBAAiB,CAC/B,SAAS,EAAE,SAAS,gBAAgB,EAAE,EACtC,QAAQ,GAAE,QAAQ,CAAC;IAAE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,WAAW,CAAA;CAAE,CAAM,GACnE,kBAAkB,CA4CpB;AAED,wBAAgB,cAAc,CAC5B,QAAQ,EAAE,kBAAkB,EAC5B,SAAS,EAAE,MAAM,EACjB,IAAI,EAAE,OAAO,GACZ,cAAc,CAsChB"}
@@ -64,9 +64,7 @@ export function sampleSequence(sequence, elapsedMs, loop) {
64
64
  done: true,
65
65
  });
66
66
  }
67
- const normalizedElapsedMs = loop
68
- ? ((Math.max(0, elapsedMs) % total) + total) % total
69
- : Math.max(0, elapsedMs);
67
+ const normalizedElapsedMs = loop ? ((elapsedMs % total) + total) % total : Math.max(0, elapsedMs);
70
68
  let cursor = 0;
71
69
  for (let i = 0; i < sequence.segments.length; i++) {
72
70
  const seg = sequence.segments[i];
@@ -1 +1 @@
1
- {"version":3,"file":"timeline.js","sourceRoot":"","sources":["../../src/animation/timeline.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"timeline.js","sourceRoot":"","sources":["../../src/animation/timeline.ts"],"names":[],"mappings":"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"}
@@ -10,17 +10,32 @@ export type EasingFunction = (t: number) => number;
10
10
  export type EasingName = "linear" | "easeInQuad" | "easeOutQuad" | "easeInOutQuad" | "easeInCubic" | "easeOutCubic" | "easeInOutCubic" | "easeInExpo" | "easeOutExpo" | "easeInOutExpo" | "easeInBack" | "easeOutBack" | "easeInOutBack" | "easeOutBounce" | "easeInBounce";
11
11
  /** Easing value accepted by transition APIs. */
12
12
  export type EasingInput = EasingName | EasingFunction;
13
+ /** Playback controls for time-based animation hooks. */
14
+ export type PlaybackControl = Readonly<{
15
+ /** Freeze animation at the current sampled value. */
16
+ paused?: boolean;
17
+ /** Run animation time backwards. */
18
+ reversed?: boolean;
19
+ /** Playback rate multiplier. */
20
+ rate?: number;
21
+ }>;
13
22
  /** Time-based interpolation configuration. */
14
23
  export type TransitionConfig = Readonly<{
24
+ /** Delay before animation starts in milliseconds. */
25
+ delay?: number;
15
26
  /** Transition duration in milliseconds. */
16
27
  duration?: number;
17
28
  /** Easing curve name or custom easing function. */
18
29
  easing?: EasingInput;
30
+ /** Optional playback controls for pause/reverse/rate. */
31
+ playback?: PlaybackControl;
19
32
  /** Called when the transition reaches the target value. */
20
33
  onComplete?: () => void;
21
34
  }>;
22
35
  /** Spring simulation configuration. */
23
36
  export type SpringConfig = Readonly<{
37
+ /** Delay before spring simulation starts in milliseconds. */
38
+ delay?: number;
24
39
  /** Hooke spring constant. Larger values snap faster. */
25
40
  stiffness?: number;
26
41
  /** Velocity damping factor. Larger values reduce oscillation. */
@@ -60,6 +75,8 @@ export type SequenceConfig = Readonly<{
60
75
  duration?: number;
61
76
  /** Default easing for segments without per-keyframe easing. */
62
77
  easing?: EasingInput;
78
+ /** Optional playback controls for pause/reverse/rate. */
79
+ playback?: PlaybackControl;
63
80
  /** Loop sequence timeline when it reaches the end. */
64
81
  loop?: boolean;
65
82
  /** Called when the sequence reaches the final keyframe (when not looping). */
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/animation/types.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,8CAA8C;AAC9C,MAAM,MAAM,cAAc,GAAG,CAAC,CAAC,EAAE,MAAM,KAAK,MAAM,CAAC;AAEnD,+DAA+D;AAC/D,MAAM,MAAM,UAAU,GAClB,QAAQ,GACR,YAAY,GACZ,aAAa,GACb,eAAe,GACf,aAAa,GACb,cAAc,GACd,gBAAgB,GAChB,YAAY,GACZ,aAAa,GACb,eAAe,GACf,YAAY,GACZ,aAAa,GACb,eAAe,GACf,eAAe,GACf,cAAc,CAAC;AAEnB,gDAAgD;AAChD,MAAM,MAAM,WAAW,GAAG,UAAU,GAAG,cAAc,CAAC;AAEtD,8CAA8C;AAC9C,MAAM,MAAM,gBAAgB,GAAG,QAAQ,CAAC;IACtC,2CAA2C;IAC3C,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,mDAAmD;IACnD,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,2DAA2D;IAC3D,UAAU,CAAC,EAAE,MAAM,IAAI,CAAC;CACzB,CAAC,CAAC;AAEH,uCAAuC;AACvC,MAAM,MAAM,YAAY,GAAG,QAAQ,CAAC;IAClC,wDAAwD;IACxD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,iEAAiE;IACjE,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,iDAAiD;IACjD,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,uCAAuC;IACvC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,uCAAuC;IACvC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,gDAAgD;IAChD,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,8CAA8C;IAC9C,UAAU,CAAC,EAAE,MAAM,IAAI,CAAC;CACzB,CAAC,CAAC;AAEH,+DAA+D;AAC/D,MAAM,MAAM,sBAAsB,GAAG,QAAQ,CAAC;IAC5C,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;CACpB,CAAC,CAAC;AAEH,iDAAiD;AACjD,MAAM,MAAM,gBAAgB,GACxB,MAAM,GACN,QAAQ,CAAC;IACP,8BAA8B;IAC9B,KAAK,EAAE,MAAM,CAAC;IACd,kDAAkD;IAClD,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,wDAAwD;IACxD,MAAM,CAAC,EAAE,WAAW,CAAC;CACtB,CAAC,CAAC;AAEP,uCAAuC;AACvC,MAAM,MAAM,cAAc,GAAG,QAAQ,CAAC;IACpC,oDAAoD;IACpD,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,+DAA+D;IAC/D,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,sDAAsD;IACtD,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,8EAA8E;IAC9E,UAAU,CAAC,EAAE,MAAM,IAAI,CAAC;CACzB,CAAC,CAAC;AAEH,8CAA8C;AAC9C,MAAM,MAAM,aAAa,GAAG,QAAQ,CAAC;IACnC,qDAAqD;IACrD,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,8CAA8C;IAC9C,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,0DAA0D;IAC1D,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,sDAAsD;IACtD,UAAU,CAAC,EAAE,MAAM,IAAI,CAAC;CACzB,CAAC,CAAC"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/animation/types.ts"],"names":[],"mappings":"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"}
@@ -39,6 +39,7 @@ type ResolvedAppConfig = Readonly<{
39
39
  drawlistReuseOutputBuffer: boolean;
40
40
  drawlistEncodedStringCacheCap: number;
41
41
  maxFramesInFlight: number;
42
+ themeTransitionFrames: number;
42
43
  internal_onRender?: ((metrics: AppRenderMetrics) => void) | undefined;
43
44
  internal_onLayout?: ((snapshot: AppLayoutSnapshot) => void) | undefined;
44
45
  }>;
@@ -1 +1 @@
1
- {"version":3,"file":"createApp.d.ts","sourceRoot":"","sources":["../../src/app/createApp.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAGH,OAAO,EAOL,KAAK,cAAc,EACpB,MAAM,eAAe,CAAC;AAoBvB,OAAO,EACL,KAAK,8BAA8B,EAEpC,MAAM,yBAAyB,CAAC;AAMjC,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAQ1D,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAC/C,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAe1D,OAAO,KAAK,EACV,GAAG,EACH,SAAS,EACT,iBAAiB,EACjB,gBAAgB,EAKjB,MAAM,YAAY,CAAC;AAQpB,oDAAoD;AACpD,KAAK,iBAAiB,GAAG,QAAQ,CAAC;IAChC,MAAM,EAAE,MAAM,CAAC;IACf,aAAa,EAAE,MAAM,CAAC;IACtB,gBAAgB,EAAE,MAAM,CAAC;IACzB,WAAW,EAAE,MAAM,CAAC;IACpB,oBAAoB,EAAE,8BAA8B,CAAC;IACrD,WAAW,EAAE,OAAO,CAAC;IACrB,sBAAsB,EAAE,OAAO,CAAC;IAChC,yBAAyB,EAAE,OAAO,CAAC;IACnC,6BAA6B,EAAE,MAAM,CAAC;IACtC,iBAAiB,EAAE,MAAM,CAAC;IAC1B,iBAAiB,CAAC,EAAE,CAAC,CAAC,OAAO,EAAE,gBAAgB,KAAK,IAAI,CAAC,GAAG,SAAS,CAAC;IACtE,iBAAiB,CAAC,EAAE,CAAC,CAAC,QAAQ,EAAE,iBAAiB,KAAK,IAAI,CAAC,GAAG,SAAS,CAAC;CACzE,CAAC,CAAC;AA0BH,eAAO,MAAM,uCAAuC,4BAA4B,CAAC;AACjF,eAAO,MAAM,gDAAgD,oCAAoC,CAAC;AAuIlG,qEAAqE;AACrE,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,SAAS,GAAG,SAAS,GAAG,iBAAiB,CA0DjF;AAuKD,KAAK,oBAAoB,GAAG,QAAQ,CAAC;IACnC,OAAO,EAAE,cAAc,CAAC;IACxB,MAAM,CAAC,EAAE,SAAS,CAAC;IACnB,KAAK,CAAC,EAAE,KAAK,GAAG,eAAe,CAAC;CACjC,CAAC,CAAC;AAEH,KAAK,qBAAqB,CAAC,CAAC,IAAI,oBAAoB,GAClD,QAAQ,CAAC;IACP,YAAY,EAAE,CAAC,CAAC;IAChB,MAAM,CAAC,EAAE,SAAS,eAAe,CAAC,CAAC,CAAC,EAAE,CAAC;IACvC,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,oBAAoB,CAAC,EAAE,MAAM,CAAC;CAC/B,CAAC,CAAC;AAEL,KAAK,0BAA0B,GAAG,oBAAoB,GACpD,QAAQ,CAAC;IACP,MAAM,EAAE,SAAS,eAAe,CAAC,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC,EAAE,CAAC;IAC1D,YAAY,EAAE,MAAM,CAAC;IACrB,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;IACrC,oBAAoB,CAAC,EAAE,MAAM,CAAC;CAC/B,CAAC,CAAC;AAEL;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,SAAS,CAAC,IAAI,EAAE,0BAA0B,GAAG,GAAG,CAAC,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC,CAAC;AACxF,wBAAgB,SAAS,CAAC,CAAC,EAAE,IAAI,EAAE,qBAAqB,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC"}
1
+ {"version":3,"file":"createApp.d.ts","sourceRoot":"","sources":["../../src/app/createApp.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAGH,OAAO,EAOL,KAAK,cAAc,EACpB,MAAM,eAAe,CAAC;AAoBvB,OAAO,EACL,KAAK,8BAA8B,EAEpC,MAAM,yBAAyB,CAAC;AAMjC,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAS1D,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAC/C,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAe1D,OAAO,KAAK,EACV,GAAG,EACH,SAAS,EACT,iBAAiB,EACjB,gBAAgB,EAKjB,MAAM,YAAY,CAAC;AAQpB,oDAAoD;AACpD,KAAK,iBAAiB,GAAG,QAAQ,CAAC;IAChC,MAAM,EAAE,MAAM,CAAC;IACf,aAAa,EAAE,MAAM,CAAC;IACtB,gBAAgB,EAAE,MAAM,CAAC;IACzB,WAAW,EAAE,MAAM,CAAC;IACpB,oBAAoB,EAAE,8BAA8B,CAAC;IACrD,WAAW,EAAE,OAAO,CAAC;IACrB,sBAAsB,EAAE,OAAO,CAAC;IAChC,yBAAyB,EAAE,OAAO,CAAC;IACnC,6BAA6B,EAAE,MAAM,CAAC;IACtC,iBAAiB,EAAE,MAAM,CAAC;IAC1B,qBAAqB,EAAE,MAAM,CAAC;IAC9B,iBAAiB,CAAC,EAAE,CAAC,CAAC,OAAO,EAAE,gBAAgB,KAAK,IAAI,CAAC,GAAG,SAAS,CAAC;IACtE,iBAAiB,CAAC,EAAE,CAAC,CAAC,QAAQ,EAAE,iBAAiB,KAAK,IAAI,CAAC,GAAG,SAAS,CAAC;CACzE,CAAC,CAAC;AA2BH,eAAO,MAAM,uCAAuC,4BAA4B,CAAC;AACjF,eAAO,MAAM,gDAAgD,oCAAoC,CAAC;AAuIlG,qEAAqE;AACrE,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,SAAS,GAAG,SAAS,GAAG,iBAAiB,CA+DjF;AA4LD,KAAK,oBAAoB,GAAG,QAAQ,CAAC;IACnC,OAAO,EAAE,cAAc,CAAC;IACxB,MAAM,CAAC,EAAE,SAAS,CAAC;IACnB,KAAK,CAAC,EAAE,KAAK,GAAG,eAAe,CAAC;CACjC,CAAC,CAAC;AAEH,KAAK,qBAAqB,CAAC,CAAC,IAAI,oBAAoB,GAClD,QAAQ,CAAC;IACP,YAAY,EAAE,CAAC,CAAC;IAChB,MAAM,CAAC,EAAE,SAAS,eAAe,CAAC,CAAC,CAAC,EAAE,CAAC;IACvC,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,oBAAoB,CAAC,EAAE,MAAM,CAAC;CAC/B,CAAC,CAAC;AAEL,KAAK,0BAA0B,GAAG,oBAAoB,GACpD,QAAQ,CAAC;IACP,MAAM,EAAE,SAAS,eAAe,CAAC,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC,EAAE,CAAC;IAC1D,YAAY,EAAE,MAAM,CAAC;IACrB,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;IACrC,oBAAoB,CAAC,EAAE,MAAM,CAAC;CAC/B,CAAC,CAAC;AAkCL;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,SAAS,CAAC,IAAI,EAAE,0BAA0B,GAAG,GAAG,CAAC,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC,CAAC;AACxF,wBAAgB,SAAS,CAAC,CAAC,EAAE,IAAI,EAAE,qBAAqB,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC"}
@@ -30,6 +30,7 @@ import { PERF_ENABLED, perfMarkEnd, perfMarkStart, perfNow, perfRecord } from ".
30
30
  import { parseEventBatchV1 } from "../protocol/zrev_v1.js";
31
31
  import { createRouterIntegration } from "../router/integration.js";
32
32
  import { DEFAULT_TERMINAL_PROFILE, terminalProfileFromCaps, } from "../terminalProfile.js";
33
+ import { blendRgb } from "../theme/blend.js";
33
34
  import { defaultTheme } from "../theme/defaultTheme.js";
34
35
  import { coerceToLegacyTheme } from "../theme/interop.js";
35
36
  import { ui } from "../widgets/ui.js";
@@ -51,6 +52,7 @@ const DEFAULT_CONFIG = Object.freeze({
51
52
  drawlistReuseOutputBuffer: true,
52
53
  drawlistEncodedStringCacheCap: 131072,
53
54
  maxFramesInFlight: 1,
55
+ themeTransitionFrames: 0,
54
56
  internal_onRender: undefined,
55
57
  internal_onLayout: undefined,
56
58
  });
@@ -197,6 +199,9 @@ export function resolveAppConfig(config) {
197
199
  const maxFramesInFlight = config.maxFramesInFlight === undefined
198
200
  ? DEFAULT_CONFIG.maxFramesInFlight
199
201
  : Math.min(4, Math.max(1, requirePositiveInt("maxFramesInFlight", config.maxFramesInFlight)));
202
+ const themeTransitionFrames = config.themeTransitionFrames === undefined
203
+ ? DEFAULT_CONFIG.themeTransitionFrames
204
+ : requireNonNegativeInt("themeTransitionFrames", config.themeTransitionFrames);
200
205
  const internal_onRender = typeof config.internal_onRender === "function" ? config.internal_onRender : undefined;
201
206
  const internal_onLayout = typeof config.internal_onLayout === "function" ? config.internal_onLayout : undefined;
202
207
  return Object.freeze({
@@ -210,6 +215,7 @@ export function resolveAppConfig(config) {
210
215
  drawlistReuseOutputBuffer,
211
216
  drawlistEncodedStringCacheCap,
212
217
  maxFramesInFlight,
218
+ themeTransitionFrames,
213
219
  internal_onRender,
214
220
  internal_onLayout,
215
221
  });
@@ -316,6 +322,52 @@ function codepointToKeyCode(codepoint) {
316
322
  }
317
323
  return null;
318
324
  }
325
+ /**
326
+ * Convert text control characters into Ctrl+key key codes.
327
+ *
328
+ * Terminals without kitty/CSI-u often emit Ctrl+letter as text bytes:
329
+ * 0x01-0x1A for Ctrl+A..Ctrl+Z, and 0x1C-0x1F for Ctrl+\..Ctrl+_.
330
+ * We intentionally exclude 0x09 (Tab), 0x0D (Enter), and 0x1B (Escape)
331
+ * because they have dedicated key semantics in the engine.
332
+ */
333
+ function codepointToCtrlKeyCode(codepoint) {
334
+ if (codepoint === 9 || codepoint === 13) {
335
+ return null;
336
+ }
337
+ if (codepoint >= 1 && codepoint <= 26) {
338
+ return codepoint + 64;
339
+ }
340
+ if (codepoint >= 28 && codepoint <= 31) {
341
+ return codepoint + 64;
342
+ }
343
+ return null;
344
+ }
345
+ function blendThemeColors(from, to, t) {
346
+ const clampedT = Math.max(0, Math.min(1, t));
347
+ if (clampedT <= 0)
348
+ return from;
349
+ if (clampedT >= 1)
350
+ return to;
351
+ const colors = {};
352
+ const keys = new Set([...Object.keys(from.colors), ...Object.keys(to.colors)]);
353
+ for (const key of keys) {
354
+ const fromColor = from.colors[key];
355
+ const toColor = to.colors[key];
356
+ if (fromColor && toColor) {
357
+ colors[key] = blendRgb(fromColor, toColor, clampedT);
358
+ }
359
+ else if (toColor) {
360
+ colors[key] = toColor;
361
+ }
362
+ else if (fromColor) {
363
+ colors[key] = fromColor;
364
+ }
365
+ }
366
+ return Object.freeze({
367
+ colors: Object.freeze(colors),
368
+ spacing: to.spacing,
369
+ });
370
+ }
319
371
  export function createApp(opts) {
320
372
  const backend = opts.backend;
321
373
  const config = resolveAppConfig(opts.config);
@@ -338,6 +390,7 @@ export function createApp(opts) {
338
390
  invalidProps(`config.fpsCap=${String(config.fpsCap)} must match backend fpsCap=${String(backendFpsCap)}. Fix: align fpsCap between app config and backend, or prefer createNodeApp({ config }) for Node/Bun apps to keep them aligned automatically.`);
339
391
  }
340
392
  let theme = coerceToLegacyTheme(opts.theme ?? defaultTheme);
393
+ let themeTransition = null;
341
394
  let terminalProfile = DEFAULT_TERMINAL_PROFILE;
342
395
  const sm = new AppStateMachine();
343
396
  const routes = opts.routes;
@@ -433,6 +486,43 @@ export function createApp(opts) {
433
486
  return;
434
487
  scheduler.enqueue({ kind: "renderRequest" });
435
488
  }
489
+ function beginThemeTransition(nextTheme) {
490
+ if (config.themeTransitionFrames <= 0 || sm.state !== "Running" || mode !== "widget") {
491
+ theme = nextTheme;
492
+ themeTransition = null;
493
+ return;
494
+ }
495
+ themeTransition = Object.freeze({
496
+ from: theme,
497
+ to: nextTheme,
498
+ frame: 0,
499
+ totalFrames: config.themeTransitionFrames,
500
+ });
501
+ }
502
+ function advanceThemeTransitionFrame() {
503
+ const active = themeTransition;
504
+ if (!active)
505
+ return;
506
+ const nextFrame = active.frame + 1;
507
+ if (nextFrame >= active.totalFrames) {
508
+ theme = active.to;
509
+ themeTransition = null;
510
+ return;
511
+ }
512
+ theme = blendThemeColors(active.from, active.to, nextFrame / active.totalFrames);
513
+ themeTransition = Object.freeze({
514
+ ...active,
515
+ frame: nextFrame,
516
+ });
517
+ }
518
+ function scheduleThemeTransitionContinuation() {
519
+ if (!themeTransition || sm.state !== "Running")
520
+ return;
521
+ // Theme-aware composite widgets resolve recipe styles during commit, so
522
+ // transition frames must invalidate view/commit, not only render.
523
+ markDirty(DIRTY_VIEW, false);
524
+ scheduler.enqueue({ kind: "renderRequest" });
525
+ }
436
526
  function requestRenderFromRenderer() {
437
527
  markDirty(DIRTY_RENDER);
438
528
  }
@@ -880,33 +970,42 @@ export function createApp(opts) {
880
970
  }
881
971
  }
882
972
  }
883
- // Also route text events through keybinding system for single-character bindings
884
- if (ev.kind === "text" && !widgetRenderer.hasActiveOverlay()) {
885
- const keyCode = codepointToKeyCode(ev.codepoint);
886
- if (keyCode !== null) {
887
- // Create a synthetic key event for keybinding matching
888
- const syntheticKeyEvent = {
889
- kind: "key",
890
- action: "down",
891
- key: keyCode,
892
- mods: 0, // Text events have no modifiers
893
- timeMs: ev.timeMs,
894
- };
895
- const keyCtx = Object.freeze({
896
- state: committedState,
897
- update: app.update,
898
- focusedId: widgetRenderer.getFocusedId(),
899
- });
900
- const routeInputState = keybindingState;
901
- const keyResult = routeKeyEvent(routeInputState, syntheticKeyEvent, keyCtx);
902
- applyRoutedKeybindingState(routeInputState, keyResult.nextState);
903
- if (keyResult.handlerError !== undefined) {
904
- enqueueFatal("ZRUI_USER_CODE_THROW", `keybinding handler threw: ${describeThrown(keyResult.handlerError)}`);
905
- return;
906
- }
907
- if (keyResult.consumed) {
908
- noteBreadcrumbConsumptionPath("keybindings");
909
- continue; // Skip default widget routing
973
+ // Also route text events through keybinding system for single-character bindings.
974
+ // Printable text is guarded during overlays, but Ctrl+text control chars are not.
975
+ if (ev.kind === "text") {
976
+ const ctrlKeyCode = codepointToCtrlKeyCode(ev.codepoint);
977
+ const shouldRouteCtrlText = ctrlKeyCode !== null;
978
+ const shouldRoutePrintableText = !shouldRouteCtrlText && !widgetRenderer.hasActiveOverlay();
979
+ if (shouldRouteCtrlText || shouldRoutePrintableText) {
980
+ const keyCode = shouldRouteCtrlText
981
+ ? ctrlKeyCode
982
+ : codepointToKeyCode(ev.codepoint);
983
+ const mods = shouldRouteCtrlText ? ZR_MOD_CTRL : 0;
984
+ if (keyCode !== null) {
985
+ // Create a synthetic key event for keybinding matching
986
+ const syntheticKeyEvent = {
987
+ kind: "key",
988
+ action: "down",
989
+ key: keyCode,
990
+ mods,
991
+ timeMs: ev.timeMs,
992
+ };
993
+ const keyCtx = Object.freeze({
994
+ state: committedState,
995
+ update: app.update,
996
+ focusedId: widgetRenderer.getFocusedId(),
997
+ });
998
+ const routeInputState = keybindingState;
999
+ const keyResult = routeKeyEvent(routeInputState, syntheticKeyEvent, keyCtx);
1000
+ applyRoutedKeybindingState(routeInputState, keyResult.nextState);
1001
+ if (keyResult.handlerError !== undefined) {
1002
+ enqueueFatal("ZRUI_USER_CODE_THROW", `keybinding handler threw: ${describeThrown(keyResult.handlerError)}`);
1003
+ return;
1004
+ }
1005
+ if (keyResult.consumed) {
1006
+ noteBreadcrumbConsumptionPath("keybindings");
1007
+ continue; // Skip default widget routing
1008
+ }
910
1009
  }
911
1010
  }
912
1011
  }
@@ -1130,6 +1229,7 @@ export function createApp(opts) {
1130
1229
  checkLayoutStability: (pendingDirtyFlags & DIRTY_LAYOUT) === 0 && (pendingDirtyFlags & DIRTY_VIEW) !== 0,
1131
1230
  nowMs: frameNowMs,
1132
1231
  };
1232
+ advanceThemeTransitionFrame();
1133
1233
  const resilientView = (state) => {
1134
1234
  if (topLevelViewError !== null) {
1135
1235
  return buildTopLevelViewErrorScreen(topLevelViewError);
@@ -1179,6 +1279,7 @@ export function createApp(opts) {
1179
1279
  if (plan.commit)
1180
1280
  consumedDirtyFlags |= DIRTY_VIEW;
1181
1281
  clearConsumedDirtyFlags(consumedDirtyFlags, dirtyVersionStart);
1282
+ scheduleThemeTransitionContinuation();
1182
1283
  }
1183
1284
  function drainIgnored(items) {
1184
1285
  for (const it of items) {
@@ -1381,10 +1482,14 @@ export function createApp(opts) {
1381
1482
  if (inRender)
1382
1483
  throwCode("ZRUI_UPDATE_DURING_RENDER", updateDuringRenderDetail("setTheme"));
1383
1484
  const nextTheme = coerceToLegacyTheme(next);
1384
- if (nextTheme === theme)
1485
+ if (nextTheme === themeTransition?.to)
1385
1486
  return;
1386
- theme = nextTheme;
1387
- requestRenderFromRenderer();
1487
+ if (nextTheme === theme) {
1488
+ themeTransition = null;
1489
+ return;
1490
+ }
1491
+ beginThemeTransition(nextTheme);
1492
+ requestViewFromRenderer();
1388
1493
  },
1389
1494
  debugLayout(enabled) {
1390
1495
  assertOperational("debugLayout");
@@ -1538,6 +1643,7 @@ export function createApp(opts) {
1538
1643
  }
1539
1644
  return p.then(() => {
1540
1645
  lifecycleBusy = null;
1646
+ themeTransition = null;
1541
1647
  sm.toStopped();
1542
1648
  settleActiveRun?.();
1543
1649
  }, (e) => {
@@ -1553,6 +1659,7 @@ export function createApp(opts) {
1553
1659
  if (st0 === "Disposed")
1554
1660
  return;
1555
1661
  pollToken++;
1662
+ themeTransition = null;
1556
1663
  try {
1557
1664
  sm.dispose();
1558
1665
  }