@askrjs/askr 0.0.21 → 0.0.24

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 (294) hide show
  1. package/LICENSE +201 -201
  2. package/README.md +160 -46
  3. package/dist/_virtual/___vite-browser-external.js +1 -0
  4. package/dist/_virtual/__vite-browser-external.js +1 -0
  5. package/dist/_virtual/_commonjsHelpers.js +1 -0
  6. package/dist/_virtual/main.js +1 -0
  7. package/dist/_virtual/preload-helper.js +1 -0
  8. package/dist/{benchmark.d.ts → bench/benchmark-entry.d.ts} +3 -3
  9. package/dist/bench/benchmark-entry.d.ts.map +1 -0
  10. package/dist/benchmark.js +1 -1
  11. package/dist/boot/index.d.ts +70 -0
  12. package/dist/boot/index.d.ts.map +1 -0
  13. package/dist/boot/index.js +2 -0
  14. package/dist/common/component.d.ts +16 -0
  15. package/dist/common/component.d.ts.map +1 -0
  16. package/dist/common/errors.d.ts +53 -0
  17. package/dist/common/errors.d.ts.map +1 -0
  18. package/dist/common/index.d.ts +14 -0
  19. package/dist/common/index.d.ts.map +1 -0
  20. package/dist/common/jsx.d.ts +17 -0
  21. package/dist/common/jsx.d.ts.map +1 -0
  22. package/dist/common/jsx.js +1 -0
  23. package/dist/{jsx-CPjsGyEg.d.ts → common/props.d.ts} +6 -18
  24. package/dist/common/props.d.ts.map +1 -0
  25. package/dist/{router-DaGtH1Sq.d.ts → common/router.d.ts} +10 -7
  26. package/dist/common/router.d.ts.map +1 -0
  27. package/dist/common/ssr-errors.d.ts +8 -0
  28. package/dist/common/ssr-errors.d.ts.map +1 -0
  29. package/dist/common/ssr-errors.js +1 -0
  30. package/dist/common/ssr.d.ts +17 -0
  31. package/dist/common/ssr.d.ts.map +1 -0
  32. package/dist/common/vnode.d.ts +17 -0
  33. package/dist/common/vnode.d.ts.map +1 -0
  34. package/dist/common/vnode.js +1 -0
  35. package/dist/components/link.d.ts +56 -0
  36. package/dist/components/link.d.ts.map +1 -0
  37. package/dist/components/link.js +1 -0
  38. package/dist/dev/invariant.d.ts +83 -0
  39. package/dist/dev/invariant.d.ts.map +1 -0
  40. package/dist/dev/invariant.js +2 -0
  41. package/dist/dev/logger.d.ts +13 -0
  42. package/dist/dev/logger.d.ts.map +1 -0
  43. package/dist/dev/logger.js +1 -0
  44. package/dist/dev/vite-plugin-askr.d.ts +18 -0
  45. package/dist/dev/vite-plugin-askr.d.ts.map +1 -0
  46. package/dist/dev/warnings.d.ts +5 -0
  47. package/dist/dev/warnings.d.ts.map +1 -0
  48. package/dist/for/for.d.ts +16 -0
  49. package/dist/for/for.d.ts.map +1 -0
  50. package/dist/for/for.js +1 -0
  51. package/dist/for/index.d.ts +2 -63
  52. package/dist/for/index.d.ts.map +1 -0
  53. package/dist/for/index.js +1 -1
  54. package/dist/foundations/core.d.ts +23 -0
  55. package/dist/foundations/core.d.ts.map +1 -0
  56. package/dist/foundations/core.js +1 -0
  57. package/dist/foundations/index.d.ts +3 -669
  58. package/dist/foundations/index.d.ts.map +1 -0
  59. package/dist/foundations/index.js +1 -1
  60. package/dist/foundations/interactions/dismissable.d.ts +58 -0
  61. package/dist/foundations/interactions/dismissable.d.ts.map +1 -0
  62. package/dist/foundations/interactions/dismissable.js +1 -0
  63. package/dist/foundations/interactions/focusable.d.ts +16 -0
  64. package/dist/foundations/interactions/focusable.d.ts.map +1 -0
  65. package/dist/foundations/interactions/focusable.js +1 -0
  66. package/dist/foundations/interactions/hoverable.d.ts +19 -0
  67. package/dist/foundations/interactions/hoverable.d.ts.map +1 -0
  68. package/dist/foundations/interactions/hoverable.js +1 -0
  69. package/dist/foundations/interactions/index.d.ts +5 -0
  70. package/dist/foundations/interactions/index.d.ts.map +1 -0
  71. package/dist/foundations/interactions/interaction-policy.d.ts +96 -0
  72. package/dist/foundations/interactions/interaction-policy.d.ts.map +1 -0
  73. package/dist/foundations/interactions/interaction-policy.js +1 -0
  74. package/dist/foundations/interactions/pressable.d.ts +54 -0
  75. package/dist/foundations/interactions/pressable.d.ts.map +1 -0
  76. package/dist/foundations/interactions/pressable.js +1 -0
  77. package/dist/foundations/interactions/roving-focus.d.ts +117 -0
  78. package/dist/foundations/interactions/roving-focus.d.ts.map +1 -0
  79. package/dist/foundations/interactions/roving-focus.js +1 -0
  80. package/dist/foundations/state/controllable.d.ts +53 -0
  81. package/dist/foundations/state/controllable.d.ts.map +1 -0
  82. package/dist/foundations/state/controllable.js +1 -0
  83. package/dist/foundations/state/index.d.ts +2 -0
  84. package/dist/foundations/state/index.d.ts.map +1 -0
  85. package/dist/foundations/structures/collection.d.ts +67 -0
  86. package/dist/foundations/structures/collection.d.ts.map +1 -0
  87. package/dist/foundations/structures/collection.js +1 -0
  88. package/dist/foundations/structures/index.d.ts +5 -0
  89. package/dist/foundations/structures/index.d.ts.map +1 -0
  90. package/dist/foundations/structures/layer.d.ts +102 -0
  91. package/dist/foundations/structures/layer.d.ts.map +1 -0
  92. package/dist/foundations/structures/layer.js +1 -0
  93. package/dist/{layout-BINPv-nz.d.ts → foundations/structures/layout.d.ts} +3 -4
  94. package/dist/foundations/structures/layout.d.ts.map +1 -0
  95. package/dist/foundations/structures/layout.js +1 -0
  96. package/dist/foundations/structures/portal.d.ts +33 -0
  97. package/dist/foundations/structures/portal.d.ts.map +1 -0
  98. package/dist/foundations/structures/portal.js +1 -0
  99. package/dist/foundations/structures/presence.d.ts +30 -0
  100. package/dist/foundations/structures/presence.d.ts.map +1 -0
  101. package/dist/foundations/structures/presence.js +1 -0
  102. package/dist/foundations/structures/slot.d.ts +31 -0
  103. package/dist/foundations/structures/slot.d.ts.map +1 -0
  104. package/dist/foundations/structures/slot.js +1 -0
  105. package/dist/foundations/structures.d.ts +14 -0
  106. package/dist/foundations/structures.d.ts.map +1 -0
  107. package/dist/foundations/structures.js +1 -0
  108. package/dist/foundations/utilities/aria.d.ts +13 -0
  109. package/dist/foundations/utilities/aria.d.ts.map +1 -0
  110. package/dist/foundations/utilities/aria.js +1 -0
  111. package/dist/foundations/utilities/compose-handlers.d.ts +34 -0
  112. package/dist/foundations/utilities/compose-handlers.d.ts.map +1 -0
  113. package/dist/foundations/utilities/compose-handlers.js +1 -0
  114. package/dist/foundations/utilities/compose-ref.d.ts +24 -0
  115. package/dist/foundations/utilities/compose-ref.d.ts.map +1 -0
  116. package/dist/foundations/utilities/compose-ref.js +1 -0
  117. package/dist/foundations/utilities/event-types.d.ts +17 -0
  118. package/dist/foundations/utilities/event-types.d.ts.map +1 -0
  119. package/dist/foundations/utilities/index.d.ts +7 -0
  120. package/dist/foundations/utilities/index.d.ts.map +1 -0
  121. package/dist/foundations/utilities/merge-props.d.ts +2 -0
  122. package/dist/foundations/utilities/merge-props.d.ts.map +1 -0
  123. package/dist/foundations/utilities/merge-props.js +1 -0
  124. package/dist/foundations/utilities/use-id.d.ts +29 -0
  125. package/dist/foundations/utilities/use-id.d.ts.map +1 -0
  126. package/dist/foundations/utilities/use-id.js +1 -0
  127. package/dist/fx/fx.d.ts +30 -0
  128. package/dist/fx/fx.d.ts.map +1 -0
  129. package/dist/fx/fx.js +1 -0
  130. package/dist/fx/index.d.ts +5 -184
  131. package/dist/fx/index.d.ts.map +1 -0
  132. package/dist/fx/index.js +1 -1
  133. package/dist/fx/noop.d.ts +12 -0
  134. package/dist/fx/noop.d.ts.map +1 -0
  135. package/dist/fx/noop.js +1 -0
  136. package/dist/fx/timing.d.ts +155 -0
  137. package/dist/fx/timing.d.ts.map +1 -0
  138. package/dist/fx/timing.js +1 -0
  139. package/dist/index.d.ts +18 -37
  140. package/dist/index.d.ts.map +1 -0
  141. package/dist/index.js +1 -1
  142. package/dist/jsx/index.d.ts +4 -0
  143. package/dist/jsx/index.d.ts.map +1 -0
  144. package/dist/jsx/index.js +1 -0
  145. package/dist/jsx/jsx-dev-runtime.d.ts +4 -0
  146. package/dist/jsx/jsx-dev-runtime.d.ts.map +1 -0
  147. package/dist/jsx/jsx-runtime.d.ts +10 -0
  148. package/dist/jsx/jsx-runtime.d.ts.map +1 -0
  149. package/dist/{types-BTT0Fc9S.d.ts → jsx/types.d.ts} +6 -3
  150. package/dist/jsx/types.d.ts.map +1 -0
  151. package/dist/jsx/types.js +1 -0
  152. package/dist/jsx/utils.d.ts +4 -0
  153. package/dist/jsx/utils.d.ts.map +1 -0
  154. package/dist/jsx/utils.js +1 -0
  155. package/dist/jsx-dev-runtime.js +1 -1
  156. package/dist/jsx-runtime.js +1 -1
  157. package/dist/node_modules/esbuild/lib/main.js +65 -0
  158. package/dist/renderer/cleanup.d.ts +25 -0
  159. package/dist/renderer/cleanup.d.ts.map +1 -0
  160. package/dist/renderer/cleanup.js +1 -0
  161. package/dist/renderer/dom.d.ts +44 -0
  162. package/dist/renderer/dom.d.ts.map +1 -0
  163. package/dist/renderer/dom.js +1 -0
  164. package/dist/renderer/evaluate.d.ts +4 -0
  165. package/dist/renderer/evaluate.d.ts.map +1 -0
  166. package/dist/renderer/evaluate.js +1 -0
  167. package/dist/renderer/fastpath.d.ts +7 -0
  168. package/dist/renderer/fastpath.d.ts.map +1 -0
  169. package/dist/renderer/fastpath.js +1 -0
  170. package/dist/renderer/index.d.ts +6 -0
  171. package/dist/renderer/index.d.ts.map +1 -0
  172. package/dist/renderer/index.js +1 -0
  173. package/dist/renderer/keyed.d.ts +23 -0
  174. package/dist/renderer/keyed.d.ts.map +1 -0
  175. package/dist/renderer/keyed.js +1 -0
  176. package/dist/renderer/reconcile.d.ts +88 -0
  177. package/dist/renderer/reconcile.d.ts.map +1 -0
  178. package/dist/renderer/reconcile.js +1 -0
  179. package/dist/renderer/types.d.ts +3 -0
  180. package/dist/renderer/types.d.ts.map +1 -0
  181. package/dist/renderer/types.js +1 -0
  182. package/dist/renderer/utils.d.ts +63 -0
  183. package/dist/renderer/utils.d.ts.map +1 -0
  184. package/dist/renderer/utils.js +1 -0
  185. package/dist/resources/index.d.ts +7 -22
  186. package/dist/resources/index.d.ts.map +1 -0
  187. package/dist/resources/index.js +1 -1
  188. package/dist/router/index.d.ts +8 -87
  189. package/dist/router/index.d.ts.map +1 -0
  190. package/dist/router/index.js +1 -1
  191. package/dist/router/match.d.ts +22 -0
  192. package/dist/router/match.d.ts.map +1 -0
  193. package/dist/router/match.js +1 -0
  194. package/dist/router/navigate.d.ts +20 -0
  195. package/dist/router/navigate.d.ts.map +1 -0
  196. package/dist/router/navigate.js +1 -0
  197. package/dist/router/route.d.ts +52 -0
  198. package/dist/router/route.d.ts.map +1 -0
  199. package/dist/router/route.js +1 -0
  200. package/dist/runtime/component.d.ts +123 -0
  201. package/dist/runtime/component.d.ts.map +1 -0
  202. package/dist/runtime/component.js +1 -0
  203. package/dist/runtime/context.d.ts +80 -0
  204. package/dist/runtime/context.d.ts.map +1 -0
  205. package/dist/runtime/context.js +1 -0
  206. package/dist/runtime/derive.d.ts +7 -0
  207. package/dist/runtime/derive.d.ts.map +1 -0
  208. package/dist/runtime/derive.js +1 -0
  209. package/dist/runtime/dev-namespace.d.ts +31 -0
  210. package/dist/runtime/dev-namespace.d.ts.map +1 -0
  211. package/dist/runtime/dev-namespace.js +1 -0
  212. package/dist/runtime/events.d.ts +52 -0
  213. package/dist/runtime/events.d.ts.map +1 -0
  214. package/dist/runtime/events.js +1 -0
  215. package/dist/runtime/execution-model.d.ts +4 -0
  216. package/dist/runtime/execution-model.d.ts.map +1 -0
  217. package/dist/runtime/execution-model.js +1 -0
  218. package/dist/runtime/fastlane.d.ts +27 -0
  219. package/dist/runtime/fastlane.d.ts.map +1 -0
  220. package/dist/runtime/fastlane.js +1 -0
  221. package/dist/runtime/for.d.ts +52 -0
  222. package/dist/runtime/for.d.ts.map +1 -0
  223. package/dist/runtime/for.js +1 -0
  224. package/dist/runtime/hydration.d.ts +25 -0
  225. package/dist/runtime/hydration.d.ts.map +1 -0
  226. package/dist/runtime/operations.d.ts +39 -0
  227. package/dist/runtime/operations.d.ts.map +1 -0
  228. package/dist/runtime/operations.js +1 -0
  229. package/dist/runtime/resource-cell.d.ts +35 -0
  230. package/dist/runtime/resource-cell.d.ts.map +1 -0
  231. package/dist/runtime/resource-cell.js +1 -0
  232. package/dist/runtime/scheduler.d.ts +48 -0
  233. package/dist/runtime/scheduler.d.ts.map +1 -0
  234. package/dist/runtime/scheduler.js +1 -0
  235. package/dist/runtime/snapshot.d.ts +25 -0
  236. package/dist/runtime/snapshot.d.ts.map +1 -0
  237. package/dist/runtime/ssr-bridge.d.ts +10 -0
  238. package/dist/runtime/ssr-bridge.d.ts.map +1 -0
  239. package/dist/runtime/ssr-bridge.js +1 -0
  240. package/dist/runtime/state.d.ts +56 -0
  241. package/dist/runtime/state.d.ts.map +1 -0
  242. package/dist/runtime/state.js +1 -0
  243. package/dist/ssr/attrs.d.ts +26 -0
  244. package/dist/ssr/attrs.d.ts.map +1 -0
  245. package/dist/ssr/attrs.js +1 -0
  246. package/dist/ssr/context.d.ts +47 -0
  247. package/dist/ssr/context.d.ts.map +1 -0
  248. package/dist/ssr/context.js +1 -0
  249. package/dist/ssr/create-ssr.d.ts +19 -0
  250. package/dist/ssr/create-ssr.d.ts.map +1 -0
  251. package/dist/ssr/errors.d.ts +6 -0
  252. package/dist/ssr/errors.d.ts.map +1 -0
  253. package/dist/ssr/errors.js +1 -0
  254. package/dist/ssr/escape.d.ts +38 -0
  255. package/dist/ssr/escape.d.ts.map +1 -0
  256. package/dist/ssr/escape.js +1 -0
  257. package/dist/ssr/index.d.ts +18 -94
  258. package/dist/ssr/index.d.ts.map +1 -0
  259. package/dist/ssr/index.js +1 -1
  260. package/dist/ssr/render-keys.d.ts +39 -0
  261. package/dist/ssr/render-keys.d.ts.map +1 -0
  262. package/dist/ssr/render-keys.js +1 -0
  263. package/dist/ssr/sink.d.ts +23 -0
  264. package/dist/ssr/sink.d.ts.map +1 -0
  265. package/dist/ssr/sink.js +1 -0
  266. package/dist/ssr/stream-render.d.ts +7 -0
  267. package/dist/ssr/stream-render.d.ts.map +1 -0
  268. package/dist/ssr/stream-render.js +1 -0
  269. package/dist/ssr/types.d.ts +21 -0
  270. package/dist/ssr/types.d.ts.map +1 -0
  271. package/dist/vite/index.js +3 -1
  272. package/package.json +11 -10
  273. package/dist/chunk-37RC6ZT3.js +0 -1
  274. package/dist/chunk-3L6PFAJ3.js +0 -1
  275. package/dist/chunk-47D5SNYH.js +0 -1
  276. package/dist/chunk-4RTKQ7SC.js +0 -1
  277. package/dist/chunk-5PLQPS3O.js +0 -1
  278. package/dist/chunk-62D2TNHX.js +0 -1
  279. package/dist/chunk-BP2CKUO6.js +0 -1
  280. package/dist/chunk-D2JSJKCW.js +0 -1
  281. package/dist/chunk-EQ5S5GU4.js +0 -1
  282. package/dist/chunk-HGMOQ3I7.js +0 -1
  283. package/dist/chunk-HZKAD5DE.js +0 -1
  284. package/dist/chunk-ILZCMHZM.js +0 -2
  285. package/dist/chunk-NL44ANML.js +0 -2
  286. package/dist/chunk-YRY4OLQF.js +0 -1
  287. package/dist/component-AJMg1Gmv.d.ts +0 -177
  288. package/dist/jsx-dev-runtime.d.ts +0 -7
  289. package/dist/jsx-runtime.d.ts +0 -14
  290. package/dist/logger-NGZDJLVS.js +0 -1
  291. package/dist/main-EPE35NMW.js +0 -65
  292. package/dist/navigate-4VAVLF3A.js +0 -1
  293. package/dist/route-IVG3V65Y.js +0 -1
  294. package/dist/vite/index.d.ts +0 -17
@@ -0,0 +1,58 @@
1
+ /**
2
+ * dismissable
3
+ *
4
+ * THE dismissal primitive. Handles Escape key and outside interactions.
5
+ *
6
+ * INVARIANTS:
7
+ * 1. Returns props that compose via mergeProps (no factories)
8
+ * 2. Disabled state respected exactly once, here
9
+ * 3. No side effects - pure props generation
10
+ * 4. Outside detection requires explicit node reference
11
+ * 5. This is the ONLY dismissal primitive - do not create alternatives
12
+ *
13
+ * DESIGN:
14
+ * - Returns standard event handler props (onKeyDown, onPointerDownCapture)
15
+ * - Composable via mergeProps with other foundations
16
+ * - Caller provides node reference for outside detection
17
+ * - Single onDismiss callback for all dismiss triggers
18
+ *
19
+ * PIT OF SUCCESS:
20
+ * ✓ Can't accidentally bypass (only way to get dismiss behavior)
21
+ * ✓ Can't duplicate (disabled checked once)
22
+ * ✓ Composes via mergeProps (standard props)
23
+ * ✓ Wrong usage is hard (no factories to misuse)
24
+ *
25
+ * USAGE:
26
+ * const props = dismissable({
27
+ * node: elementRef,
28
+ * disabled: false,
29
+ * onDismiss: () => close()
30
+ * });
31
+ *
32
+ * <div ref={elementRef} {...props}>Content</div>
33
+ *
34
+ * MISUSE EXAMPLE (PREVENTED):
35
+ * ❌ Can't forget to check disabled - checked inside dismissable
36
+ * ❌ Can't create custom escape handler - this is the only one
37
+ * ❌ Can't bypass via direct event listeners - mergeProps composes correctly
38
+ */
39
+ export interface DismissableOptions {
40
+ /**
41
+ * Reference to the element for outside click detection
42
+ */
43
+ node?: Node | null;
44
+ /**
45
+ * Whether dismiss is disabled
46
+ */
47
+ disabled?: boolean;
48
+ /**
49
+ * Called when dismiss is triggered (Escape or outside click)
50
+ */
51
+ onDismiss?: (trigger: 'escape' | 'outside') => void;
52
+ }
53
+ import type { KeyboardLikeEvent, PointerLikeEvent } from '../utilities/event-types';
54
+ export declare function dismissable({ node, disabled, onDismiss }: DismissableOptions): {
55
+ onKeyDown: (e: KeyboardLikeEvent) => void;
56
+ onPointerDownCapture: (e: PointerLikeEvent) => void;
57
+ };
58
+ //# sourceMappingURL=dismissable.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dismissable.d.ts","sourceRoot":"","sources":["../../../src/foundations/interactions/dismissable.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqCG;AAEH,MAAM,WAAW,kBAAkB;IACjC;;OAEG;IACH,IAAI,CAAC,EAAE,IAAI,GAAG,IAAI,CAAC;IAEnB;;OAEG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;IAEnB;;OAEG;IACH,SAAS,CAAC,EAAE,CAAC,OAAO,EAAE,QAAQ,GAAG,SAAS,KAAK,IAAI,CAAC;CACrD;AAED,OAAO,KAAK,EACV,iBAAiB,EACjB,gBAAgB,EACjB,MAAM,0BAA0B,CAAC;AAElC,wBAAgB,WAAW,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,SAAS,EAAE,EAAE,kBAAkB;mBACjD,iBAAiB;8BASN,gBAAgB;EAoBtD"}
@@ -0,0 +1 @@
1
+ function u({node:t,disabled:e,onDismiss:r}){function i(n){e||n.key==="Escape"&&(n.preventDefault?.(),n.stopPropagation?.(),r?.("escape"))}function a(n){if(e)return;const o=n.target;o instanceof Node&&t&&(t.contains(o)||r?.("outside"))}return{onKeyDown:i,onPointerDownCapture:a}}export{u as dismissable};
@@ -0,0 +1,16 @@
1
+ /**
2
+ * focusable
3
+ *
4
+ * Normalize focus-related props for hosts.
5
+ * - No DOM manipulation here; returns props that the runtime may attach.
6
+ */
7
+ export interface FocusableOptions {
8
+ disabled?: boolean;
9
+ tabIndex?: number | undefined;
10
+ }
11
+ export interface FocusableResult {
12
+ tabIndex?: number;
13
+ 'aria-disabled'?: 'true';
14
+ }
15
+ export declare function focusable({ disabled, tabIndex, }: FocusableOptions): FocusableResult;
16
+ //# sourceMappingURL=focusable.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"focusable.d.ts","sourceRoot":"","sources":["../../../src/foundations/interactions/focusable.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CAC/B;AAED,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED,wBAAgB,SAAS,CAAC,EACxB,QAAQ,EACR,QAAQ,GACT,EAAE,gBAAgB,GAAG,eAAe,CAKpC"}
@@ -0,0 +1 @@
1
+ import{ariaDisabled as i}from"../utilities/aria.js";function a({disabled:o,tabIndex:r}){return{tabIndex:o?-1:r===void 0?0:r,...i(o)}}export{a as focusable};
@@ -0,0 +1,19 @@
1
+ /**
2
+ * hoverable
3
+ *
4
+ * Produces props for pointer enter/leave handling. Pure and deterministic.
5
+ */
6
+ export interface HoverableOptions {
7
+ disabled?: boolean;
8
+ onEnter?: (e: HoverEvent) => void;
9
+ onLeave?: (e: HoverEvent) => void;
10
+ }
11
+ import type { DefaultPreventable, PropagationStoppable } from '../utilities/event-types';
12
+ type HoverEvent = DefaultPreventable & PropagationStoppable;
13
+ export interface HoverableResult {
14
+ onPointerEnter?: (e: HoverEvent) => void;
15
+ onPointerLeave?: (e: HoverEvent) => void;
16
+ }
17
+ export declare function hoverable({ disabled, onEnter, onLeave, }: HoverableOptions): HoverableResult;
18
+ export {};
19
+ //# sourceMappingURL=hoverable.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hoverable.d.ts","sourceRoot":"","sources":["../../../src/foundations/interactions/hoverable.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,OAAO,CAAC,EAAE,CAAC,CAAC,EAAE,UAAU,KAAK,IAAI,CAAC;IAClC,OAAO,CAAC,EAAE,CAAC,CAAC,EAAE,UAAU,KAAK,IAAI,CAAC;CACnC;AAED,OAAO,KAAK,EACV,kBAAkB,EAClB,oBAAoB,EACrB,MAAM,0BAA0B,CAAC;AAElC,KAAK,UAAU,GAAG,kBAAkB,GAAG,oBAAoB,CAAC;AAE5D,MAAM,WAAW,eAAe;IAC9B,cAAc,CAAC,EAAE,CAAC,CAAC,EAAE,UAAU,KAAK,IAAI,CAAC;IACzC,cAAc,CAAC,EAAE,CAAC,CAAC,EAAE,UAAU,KAAK,IAAI,CAAC;CAC1C;AAED,wBAAgB,SAAS,CAAC,EACxB,QAAQ,EACR,OAAO,EACP,OAAO,GACR,EAAE,gBAAgB,GAAG,eAAe,CAapC"}
@@ -0,0 +1 @@
1
+ function t({disabled:e,onEnter:n,onLeave:r}){return{onPointerEnter:e?void 0:o=>{n?.(o)},onPointerLeave:e?void 0:o=>{r?.(o)}}}export{t as hoverable};
@@ -0,0 +1,5 @@
1
+ export * from './pressable';
2
+ export * from './focusable';
3
+ export * from './hoverable';
4
+ export * from './dismissable';
5
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/foundations/interactions/index.ts"],"names":[],"mappings":"AAAA,cAAc,aAAa,CAAC;AAC5B,cAAc,aAAa,CAAC;AAC5B,cAAc,aAAa,CAAC;AAC5B,cAAc,eAAe,CAAC"}
@@ -0,0 +1,96 @@
1
+ /**
2
+ * INTERACTION POLICY (FRAMEWORK LAW)
3
+ *
4
+ * This is THE ONLY way to create interactive elements. Components MUST NOT
5
+ * implement interaction logic directly.
6
+ *
7
+ * INVARIANTS (ENFORCED):
8
+ * 1. "Press" is the semantic. Click/touch/Enter/Space are implementation details.
9
+ * 2. Disabled is enforced exactly once, here. Components may not check disabled.
10
+ * 3. Keyboard handling is automatic. Components may not add onKeyDown for activation.
11
+ * 4. Native elements opt out of polyfills, not semantics.
12
+ * 5. asChild may replace the host element, not interaction behavior.
13
+ * 6. This policy is the SINGLE SOURCE OF TRUTH for interactive behavior.
14
+ *
15
+ * DESIGN:
16
+ * - Single public function: applyInteractionPolicy
17
+ * - Returns props that compose via mergeProps
18
+ * - Delegates to pressable for mechanics
19
+ * - Enforces disabled once and only once
20
+ * - No configuration beyond disabled and native element type
21
+ *
22
+ * PIT OF SUCCESS:
23
+ * ✓ Can't bypass policy (only way to get interaction behavior)
24
+ * ✓ Can't duplicate disabled checks (enforced once, here)
25
+ * ✓ Can't write custom keyboard handlers for buttons (policy owns it)
26
+ * ✓ Composes via mergeProps (standard props)
27
+ * ✓ Wrong usage is impossible (no escape hatch)
28
+ *
29
+ * USAGE:
30
+ * function Button({ onPress, disabled }) {
31
+ * const interaction = applyInteractionPolicy({
32
+ * isNative: true,
33
+ * disabled,
34
+ * onPress
35
+ * });
36
+ *
37
+ * return <button {...interaction}>Click me</button>;
38
+ * }
39
+ *
40
+ * MISUSE EXAMPLE (PREVENTED):
41
+ * ❌ Button checking disabled again:
42
+ * function Button({ disabled, onPress }) {
43
+ * if (disabled) return; // NO! Policy handles this
44
+ * const interaction = applyInteractionPolicy(...);
45
+ * }
46
+ *
47
+ * ❌ Custom keyboard handler:
48
+ * function Button({ onPress }) {
49
+ * const interaction = applyInteractionPolicy(...);
50
+ * return <button {...interaction} onKeyDown={...}>; // NO! Policy owns this
51
+ * }
52
+ *
53
+ * ❌ Direct event handler:
54
+ * <button onClick={onPress}>; // NO! Use applyInteractionPolicy
55
+ */
56
+ import { Ref } from '../utilities/compose-ref';
57
+ export interface InteractionPolicyInput {
58
+ /** Whether the host element is a native interactive element (button, a, etc) */
59
+ isNative: boolean;
60
+ /** Disabled state - checked ONLY here, never in components */
61
+ disabled: boolean;
62
+ /** User-provided press handler - semantic action, not DOM event */
63
+ onPress?: (e: Event) => void;
64
+ /** Optional ref to compose */
65
+ ref?: Ref<unknown>;
66
+ }
67
+ /**
68
+ * THE interaction policy. Components MUST use this, NEVER implement
69
+ * interaction logic directly.
70
+ */
71
+ export declare function applyInteractionPolicy({ isNative, disabled, onPress, ref, }: InteractionPolicyInput): {
72
+ disabled: true | undefined;
73
+ onClick: (e: Event) => void;
74
+ ref: Ref<unknown>;
75
+ } | {
76
+ 'aria-disabled': true | undefined;
77
+ tabIndex: number;
78
+ ref: Ref<unknown>;
79
+ onClick: (e: import("../utilities").DefaultPreventable & import("../utilities").PropagationStoppable) => void;
80
+ disabled?: true;
81
+ role?: "button";
82
+ onKeyDown?: (e: import("../utilities").KeyboardLikeEvent) => void;
83
+ onKeyUp?: (e: import("../utilities").KeyboardLikeEvent) => void;
84
+ };
85
+ /**
86
+ * Merge rule for Slot / asChild
87
+ *
88
+ * Precedence:
89
+ * policy → user → child
90
+ *
91
+ * Event handlers are composed (policy first).
92
+ * Refs are always composed.
93
+ * Policy props MUST take precedence to enforce invariants.
94
+ */
95
+ export declare function mergeInteractionProps(childProps: Record<string, unknown>, policyProps: Record<string, unknown>, userProps?: Record<string, unknown>): Record<string, unknown>;
96
+ //# sourceMappingURL=interaction-policy.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"interaction-policy.d.ts","sourceRoot":"","sources":["../../../src/foundations/interactions/interaction-policy.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsDG;AAIH,OAAO,EAAe,GAAG,EAAE,MAAM,0BAA0B,CAAC;AAG5D,MAAM,WAAW,sBAAsB;IACrC,gFAAgF;IAChF,QAAQ,EAAE,OAAO,CAAC;IAClB,8DAA8D;IAC9D,QAAQ,EAAE,OAAO,CAAC;IAClB,mEAAmE;IACnE,OAAO,CAAC,EAAE,CAAC,CAAC,EAAE,KAAK,KAAK,IAAI,CAAC;IAC7B,8BAA8B;IAC9B,GAAG,CAAC,EAAE,GAAG,CAAC,OAAO,CAAC,CAAC;CACpB;AAED;;;GAGG;AACH,wBAAgB,sBAAsB,CAAC,EACrC,QAAQ,EACR,QAAQ,EACR,OAAO,EACP,GAAG,GACJ,EAAE,sBAAsB;;iBAcN,KAAK;;;;;;;;;;;EAkBvB;AAED;;;;;;;;;GASG;AACH,wBAAgB,qBAAqB,CACnC,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACnC,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACpC,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,2BAiCpC"}
@@ -0,0 +1 @@
1
+ import{pressable as v}from"./pressable.js";import{composeHandlers as p}from"../utilities/compose-handlers.js";import{composeRefs as H}from"../utilities/compose-ref.js";import{mergeProps as d}from"../utilities/merge-props.js";function y({isNative:r,disabled:n,onPress:e,ref:t}){function f(o){if(n){o.preventDefault?.();return}e?.(o)}if(r)return{disabled:n||void 0,onClick:o=>f(o),ref:t};const c=v({disabled:n,isNativeButton:!1,onPress:o=>f(o)});return{...c,"aria-disabled":n||void 0,tabIndex:n?-1:c.tabIndex??0,ref:t}}function g(r,n,e){let t=d(r,n);e&&(t=d(t,e));for(const i in t){if(!i.startsWith("on"))continue;const s=n?.[i],m=e?.[i],u=r?.[i];if(s||m||u){const a=l=>typeof l=="function"?l:void 0;t[i]=p(a(s),p(a(m),a(u)))}}const f=r?.ref,c=e?.ref,o=n?.ref;return t.ref=H(f,c,o),t}export{y as applyInteractionPolicy,g as mergeInteractionProps};
@@ -0,0 +1,54 @@
1
+ /**
2
+ * pressable
3
+ *
4
+ * Interaction helper that produces VNode props for 'press' semantics.
5
+ * - Pure and deterministic: no DOM construction or mutation here
6
+ * - The runtime owns event attachment and scheduling
7
+ * - This helper returns plain props (handlers) intended to be attached by the runtime
8
+ *
9
+ * Behaviour:
10
+ * - For native buttons: only an `onClick` prop is provided (no ARIA or keyboard shims)
11
+ * - For non-button elements: add `role="button"` and `tabIndex` and keyboard handlers
12
+ * - Activation: `Enter` activates on keydown, `Space` activates on keyup (matches native button)
13
+ * - Disabled: handlers short-circuit and `aria-disabled` is set for all hosts
14
+ *
15
+ * POLICY DECISIONS (LOCKED):
16
+ *
17
+ * 1. Activation Timing (Platform Parity)
18
+ * - Enter fires on keydown (immediate response)
19
+ * - Space fires on keyup (allows cancel by moving focus, matches native)
20
+ * - Space keydown prevents scroll (matches native button behavior)
21
+ *
22
+ * 2. Disabled Enforcement Strategy
23
+ * - Native buttons: Use HTML `disabled` attribute (platform-enforced non-interactivity)
24
+ * AND `aria-disabled` (consistent a11y signaling)
25
+ * - Non-native: Use `tabIndex=-1` (removes from tab order)
26
+ * AND `aria-disabled` (signals disabled state to AT)
27
+ * - Click handler short-circuits as defense-in-depth (prevents leaked focus issues)
28
+ *
29
+ * 3. Key Repeat Behavior
30
+ * - Held Enter/Space will fire onPress repeatedly (matches native button)
31
+ * - No debouncing or repeat prevention (platform parity)
32
+ */
33
+ export interface PressableOptions {
34
+ disabled?: boolean;
35
+ onPress?: (e: PressEvent) => void;
36
+ /**
37
+ * Whether the host is a native button. Defaults to false.
38
+ */
39
+ isNativeButton?: boolean;
40
+ }
41
+ import type { DefaultPreventable, KeyboardLikeEvent, PropagationStoppable } from '../utilities/event-types';
42
+ type PressEvent = DefaultPreventable & PropagationStoppable;
43
+ export interface PressableResult {
44
+ onClick: (e: PressEvent) => void;
45
+ disabled?: true;
46
+ role?: 'button';
47
+ tabIndex?: number;
48
+ onKeyDown?: (e: KeyboardLikeEvent) => void;
49
+ onKeyUp?: (e: KeyboardLikeEvent) => void;
50
+ 'aria-disabled'?: 'true';
51
+ }
52
+ export declare function pressable({ disabled, onPress, isNativeButton, }: PressableOptions): PressableResult;
53
+ export {};
54
+ //# sourceMappingURL=pressable.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pressable.d.ts","sourceRoot":"","sources":["../../../src/foundations/interactions/pressable.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AAEH,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,OAAO,CAAC,EAAE,CAAC,CAAC,EAAE,UAAU,KAAK,IAAI,CAAC;IAClC;;OAEG;IACH,cAAc,CAAC,EAAE,OAAO,CAAC;CAC1B;AAED,OAAO,KAAK,EACV,kBAAkB,EAClB,iBAAiB,EACjB,oBAAoB,EACrB,MAAM,0BAA0B,CAAC;AAGlC,KAAK,UAAU,GAAG,kBAAkB,GAAG,oBAAoB,CAAC;AAE5D,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,CAAC,CAAC,EAAE,UAAU,KAAK,IAAI,CAAC;IACjC,QAAQ,CAAC,EAAE,IAAI,CAAC;IAChB,IAAI,CAAC,EAAE,QAAQ,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,CAAC,CAAC,EAAE,iBAAiB,KAAK,IAAI,CAAC;IAC3C,OAAO,CAAC,EAAE,CAAC,CAAC,EAAE,iBAAiB,KAAK,IAAI,CAAC;IACzC,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED,wBAAgB,SAAS,CAAC,EACxB,QAAQ,EACR,OAAO,EACP,cAAsB,GACvB,EAAE,gBAAgB,GAAG,eAAe,CAwDpC"}
@@ -0,0 +1 @@
1
+ import{ariaDisabled as o}from"../utilities/aria.js";function u({disabled:n,onPress:e,isNativeButton:f=!1}){const r={onClick:t=>{if(n){t.preventDefault?.(),t.stopPropagation?.();return}e?.(t)}};return f?(n&&(r.disabled=!0,Object.assign(r,o(n))),r):(r.role="button",r.tabIndex=n?-1:0,r.onKeyDown=t=>{if(n){t.preventDefault?.(),t.stopPropagation?.();return}if(t.key==="Enter"){t.preventDefault?.(),e?.(t);return}t.key===" "&&t.preventDefault?.()},r.onKeyUp=t=>{if(n){t.preventDefault?.(),t.stopPropagation?.();return}t.key===" "&&(t.preventDefault?.(),e?.(t))},n&&Object.assign(r,o(n)),r)}export{u as pressable};
@@ -0,0 +1,117 @@
1
+ /**
2
+ * rovingFocus
3
+ *
4
+ * Single tab stop navigation with arrow-key control.
5
+ *
6
+ * INVARIANTS:
7
+ * 1. Only one item in the group is reachable via Tab (single tab stop)
8
+ * 2. Arrow keys move focus within the group
9
+ * 3. Orientation determines which arrow keys are active
10
+ * 4. Looping is opt-in
11
+ * 5. Disabled items are skipped
12
+ * 6. Returns props objects, never factories (composes via mergeProps)
13
+ *
14
+ * DESIGN:
15
+ * - Container gets onKeyDown for arrow navigation
16
+ * - Each item gets tabIndex based on current selection
17
+ * - Navigation logic is pure - caller controls focus application
18
+ * - Disabled check happens per-item via predicate
19
+ *
20
+ * PIT OF SUCCESS:
21
+ * ✓ Can't accidentally break tab order (tabIndex assigned correctly)
22
+ * ✓ Can't duplicate navigation logic (single source)
23
+ * ✓ Composes via mergeProps (all standard props)
24
+ * ✓ Type-safe - invalid indices caught at call site
25
+ *
26
+ * USAGE:
27
+ * const nav = rovingFocus({
28
+ * currentIndex: 0,
29
+ * itemCount: 3,
30
+ * orientation: 'horizontal',
31
+ * onNavigate: setIndex
32
+ * });
33
+ *
34
+ * <div {...nav.container}>
35
+ * <button {...nav.item(0)}>First</button>
36
+ * <button {...nav.item(1)}>Second</button>
37
+ * </div>
38
+ *
39
+ * MISUSE EXAMPLE (PREVENTED):
40
+ * ❌ Can't forget to set tabIndex - returned in item props
41
+ * ❌ Can't create conflicting arrow handlers - mergeProps composes
42
+ * ❌ Can't skip disabled items incorrectly - logic is internal
43
+ */
44
+ import type { KeyboardLikeEvent } from '../utilities/event-types';
45
+ export type Orientation = 'horizontal' | 'vertical' | 'both';
46
+ export interface RovingFocusOptions {
47
+ /**
48
+ * Current focused index
49
+ */
50
+ currentIndex: number;
51
+ /**
52
+ * Total number of items
53
+ */
54
+ itemCount: number;
55
+ /**
56
+ * Navigation orientation
57
+ * - horizontal: ArrowLeft/ArrowRight
58
+ * - vertical: ArrowUp/ArrowDown
59
+ * - both: all arrow keys
60
+ */
61
+ orientation?: Orientation;
62
+ /**
63
+ * Whether to loop when reaching the end
64
+ */
65
+ loop?: boolean;
66
+ /**
67
+ * Callback when navigation occurs
68
+ */
69
+ onNavigate?: (index: number) => void;
70
+ /**
71
+ * Optional disabled state check per index
72
+ */
73
+ isDisabled?: (index: number) => boolean;
74
+ }
75
+ export interface RovingFocusResult {
76
+ /**
77
+ * Props for the container element (composes via mergeProps)
78
+ */
79
+ container: {
80
+ onKeyDown: (e: KeyboardLikeEvent) => void;
81
+ };
82
+ /**
83
+ * Generate props for an item at the given index (composes via mergeProps)
84
+ */
85
+ item: (index: number) => {
86
+ tabIndex: number;
87
+ 'data-roving-index': number;
88
+ };
89
+ }
90
+ export declare function rovingFocus(options: RovingFocusOptions): RovingFocusResult;
91
+ /**
92
+ * USAGE EXAMPLE:
93
+ *
94
+ * function Menu() {
95
+ * const [focusIndex, setFocusIndex] = state(0);
96
+ * const items = ['File', 'Edit', 'View'];
97
+ *
98
+ * const navigation = rovingFocus({
99
+ * currentIndex: focusIndex(),
100
+ * itemCount: items.length,
101
+ * orientation: 'horizontal',
102
+ * loop: true,
103
+ * onNavigate: setFocusIndex,
104
+ * });
105
+ *
106
+ * return (
107
+ * <div {...navigation.container}>
108
+ * {items.map((label, index) => (
109
+ * <button {...navigation.item(index)}>
110
+ * {label}
111
+ * </button>
112
+ * ))}
113
+ * </div>
114
+ * );
115
+ * }
116
+ */
117
+ //# sourceMappingURL=roving-focus.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"roving-focus.d.ts","sourceRoot":"","sources":["../../../src/foundations/interactions/roving-focus.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA0CG;AAEH,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAElE,MAAM,MAAM,WAAW,GAAG,YAAY,GAAG,UAAU,GAAG,MAAM,CAAC;AAE7D,MAAM,WAAW,kBAAkB;IACjC;;OAEG;IACH,YAAY,EAAE,MAAM,CAAC;IAErB;;OAEG;IACH,SAAS,EAAE,MAAM,CAAC;IAElB;;;;;OAKG;IACH,WAAW,CAAC,EAAE,WAAW,CAAC;IAE1B;;OAEG;IACH,IAAI,CAAC,EAAE,OAAO,CAAC;IAEf;;OAEG;IACH,UAAU,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAErC;;OAEG;IACH,UAAU,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC;CACzC;AAED,MAAM,WAAW,iBAAiB;IAChC;;OAEG;IACH,SAAS,EAAE;QACT,SAAS,EAAE,CAAC,CAAC,EAAE,iBAAiB,KAAK,IAAI,CAAC;KAC3C,CAAC;IAEF;;OAEG;IACH,IAAI,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK;QACvB,QAAQ,EAAE,MAAM,CAAC;QACjB,mBAAmB,EAAE,MAAM,CAAC;KAC7B,CAAC;CACH;AAED,wBAAgB,WAAW,CAAC,OAAO,EAAE,kBAAkB,GAAG,iBAAiB,CAkE1E;AAED;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG"}
@@ -0,0 +1 @@
1
+ function v(u){const{currentIndex:r,itemCount:e,orientation:o="horizontal",loop:d=!1,onNavigate:l,isDisabled:c}=u;function f(t,i){let n=t+i;if(d)n<0&&(n=e-1),n>=e&&(n=0);else if(n<0||n>=e)return;return c?.(n)?n===t?void 0:f(n,i):n}function s(t){const{key:i}=t;let n;if((o==="horizontal"||o==="both")&&(i==="ArrowRight"&&(n=1),i==="ArrowLeft"&&(n=-1)),(o==="vertical"||o==="both")&&(i==="ArrowDown"&&(n=1),i==="ArrowUp"&&(n=-1)),n===void 0)return;const a=f(r,n);a!==void 0&&(t.preventDefault?.(),t.stopPropagation?.(),l?.(a))}return{container:{onKeyDown:s},item:t=>({tabIndex:t===r?0:-1,"data-roving-index":t})}}export{v as rovingFocus};
@@ -0,0 +1,53 @@
1
+ /**
2
+ * controllable
3
+ *
4
+ * Small utilities for controlled vs uncontrolled components. These helpers are
5
+ * intentionally minimal and do not manage state themselves; they help component
6
+ * implementations make correct decisions about when to call `onChange` vs
7
+ * update internal state.
8
+ *
9
+ * POLICY DECISIONS (LOCKED):
10
+ *
11
+ * 1. Controlled Detection
12
+ * A value is "controlled" if it is not `undefined`.
13
+ * This matches React conventions and is SSR-safe.
14
+ *
15
+ * 2. onChange Timing
16
+ * - Controlled mode: onChange called immediately, no internal update
17
+ * - Uncontrolled mode: internal state updated first, then onChange called
18
+ * This ensures onChange sees the new value in both modes.
19
+ *
20
+ * 3. Value Equality
21
+ * controllableState uses Object.is() to prevent unnecessary onChange calls.
22
+ * This is intentional — strict equality, no deep comparison.
23
+ */
24
+ import { type State } from '../../runtime/state';
25
+ export declare function isControlled<T>(value: T | undefined): value is T;
26
+ export declare function resolveControllable<T>(value: T | undefined, defaultValue: T): {
27
+ value: T;
28
+ isControlled: boolean;
29
+ };
30
+ export declare function makeControllable<T>(options: {
31
+ value: T | undefined;
32
+ defaultValue: T;
33
+ onChange?: (next: T) => void;
34
+ setInternal?: (next: T) => void;
35
+ }): {
36
+ set: (next: T) => void;
37
+ isControlled: boolean;
38
+ };
39
+ export type ControllableState<T> = State<T> & {
40
+ isControlled: boolean;
41
+ };
42
+ /**
43
+ * controllableState
44
+ *
45
+ * Hook-like primitive that mirrors `state()` semantics while supporting
46
+ * controlled/uncontrolled behavior.
47
+ */
48
+ export declare function controllableState<T>(options: {
49
+ value: T | undefined;
50
+ defaultValue: T;
51
+ onChange?: (next: T) => void;
52
+ }): ControllableState<T>;
53
+ //# sourceMappingURL=controllable.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"controllable.d.ts","sourceRoot":"","sources":["../../../src/foundations/state/controllable.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAEH,OAAO,EAAS,KAAK,KAAK,EAAE,MAAM,qBAAqB,CAAC;AAExD,wBAAgB,YAAY,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,GAAG,SAAS,GAAG,KAAK,IAAI,CAAC,CAEhE;AAED,wBAAgB,mBAAmB,CAAC,CAAC,EACnC,KAAK,EAAE,CAAC,GAAG,SAAS,EACpB,YAAY,EAAE,CAAC,GACd;IAAE,KAAK,EAAE,CAAC,CAAC;IAAC,YAAY,EAAE,OAAO,CAAA;CAAE,CAMrC;AAED,wBAAgB,gBAAgB,CAAC,CAAC,EAAE,OAAO,EAAE;IAC3C,KAAK,EAAE,CAAC,GAAG,SAAS,CAAC;IACrB,YAAY,EAAE,CAAC,CAAC;IAChB,QAAQ,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,IAAI,CAAC;IAC7B,WAAW,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,IAAI,CAAC;CACjC;gBAIoB,CAAC;;EAUrB;AAED,MAAM,MAAM,iBAAiB,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC,GAAG;IAAE,YAAY,EAAE,OAAO,CAAA;CAAE,CAAC;AAExE;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,CAAC,EAAE,OAAO,EAAE;IAC5C,KAAK,EAAE,CAAC,GAAG,SAAS,CAAC;IACrB,YAAY,EAAE,CAAC,CAAC;IAChB,QAAQ,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,IAAI,CAAC;CAC9B,GAAG,iBAAiB,CAAC,CAAC,CAAC,CA4BvB"}
@@ -0,0 +1 @@
1
+ import{state as s}from"../../runtime/state.js";function c(n){return n!==void 0}function a(n,t){const e=c(n);return{value:e?n:t,isControlled:e}}function C(n){const{value:t,defaultValue:e,onChange:o,setInternal:l}=n,{isControlled:r}=a(t,e);function u(i){r||l?.(i),o?.(i)}return{set:u,isControlled:r}}function d(n){const t=s(n.defaultValue),e=n.value!==void 0;function o(){return e?n.value:t()}return o.set=l=>{const r=o(),u=typeof l=="function"?l(r):l;if(!Object.is(r,u)){if(e){n.onChange?.(u);return}t.set(l),n.onChange?.(u)}},o.isControlled=e,o}export{d as controllableState,c as isControlled,C as makeControllable,a as resolveControllable};
@@ -0,0 +1,2 @@
1
+ export * from './controllable';
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/foundations/state/index.ts"],"names":[],"mappings":"AAAA,cAAc,gBAAgB,CAAC"}
@@ -0,0 +1,67 @@
1
+ /**
2
+ * createCollection
3
+ *
4
+ * Ordered descendant registry for coordinating items without DOM queries.
5
+ *
6
+ * INVARIANTS:
7
+ * 1. Registration order determines item order (no DOM queries)
8
+ * 2. Stable ordering across renders (insertion order preserved)
9
+ * 3. Each item may have metadata (type-safe, user-defined)
10
+ * 4. No implicit global state (explicit collection instances)
11
+ * 5. No automatic cleanup (caller controls lifecycle)
12
+ *
13
+ * DESIGN:
14
+ * - Returns a registry API ({ register, items, clear })
15
+ * - Items are stored in insertion order
16
+ * - Registration returns an unregister function
17
+ * - No side effects on registration (pure data structure)
18
+ *
19
+ * USAGE:
20
+ * const collection = createCollection<HTMLElement, { disabled: boolean }>();
21
+ * const unregister = collection.register(element, { disabled: false });
22
+ * const allItems = collection.items();
23
+ * unregister();
24
+ */
25
+ export type CollectionItem<TNode, TMetadata = unknown> = {
26
+ node: TNode;
27
+ metadata: TMetadata;
28
+ };
29
+ export interface Collection<TNode, TMetadata = unknown> {
30
+ /**
31
+ * Register a node with optional metadata.
32
+ * Returns an unregister function.
33
+ */
34
+ register(node: TNode, metadata: TMetadata): () => void;
35
+ /**
36
+ * Get all registered items in insertion order.
37
+ */
38
+ items(): ReadonlyArray<CollectionItem<TNode, TMetadata>>;
39
+ /**
40
+ * Clear all registered items.
41
+ */
42
+ clear(): void;
43
+ /**
44
+ * Get the count of registered items.
45
+ */
46
+ size(): number;
47
+ }
48
+ export declare function createCollection<TNode, TMetadata = unknown>(): Collection<TNode, TMetadata>;
49
+ /**
50
+ * USAGE EXAMPLE:
51
+ *
52
+ * // Create a collection for menu items
53
+ * const menuItems = createCollection<HTMLElement, { disabled: boolean }>();
54
+ *
55
+ * // Register items
56
+ * const unregister1 = menuItems.register(element1, { disabled: false });
57
+ * const unregister2 = menuItems.register(element2, { disabled: true });
58
+ *
59
+ * // Query items
60
+ * const allItems = menuItems.items();
61
+ * const enabledItems = allItems.filter(item => !item.metadata.disabled);
62
+ *
63
+ * // Cleanup
64
+ * unregister1();
65
+ * unregister2();
66
+ */
67
+ //# sourceMappingURL=collection.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"collection.d.ts","sourceRoot":"","sources":["../../../src/foundations/structures/collection.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAEH,MAAM,MAAM,cAAc,CAAC,KAAK,EAAE,SAAS,GAAG,OAAO,IAAI;IACvD,IAAI,EAAE,KAAK,CAAC;IACZ,QAAQ,EAAE,SAAS,CAAC;CACrB,CAAC;AAEF,MAAM,WAAW,UAAU,CAAC,KAAK,EAAE,SAAS,GAAG,OAAO;IACpD;;;OAGG;IACH,QAAQ,CAAC,IAAI,EAAE,KAAK,EAAE,QAAQ,EAAE,SAAS,GAAG,MAAM,IAAI,CAAC;IAEvD;;OAEG;IACH,KAAK,IAAI,aAAa,CAAC,cAAc,CAAC,KAAK,EAAE,SAAS,CAAC,CAAC,CAAC;IAEzD;;OAEG;IACH,KAAK,IAAI,IAAI,CAAC;IAEd;;OAEG;IACH,IAAI,IAAI,MAAM,CAAC;CAChB;AAED,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,SAAS,GAAG,OAAO,KAAK,UAAU,CACxE,KAAK,EACL,SAAS,CACV,CA8BA;AAED;;;;;;;;;;;;;;;;;GAiBG"}
@@ -0,0 +1 @@
1
+ function s(){const e=new Map;function r(t,u){const o={node:t,metadata:u};return e.set(t,o),()=>{e.delete(t)}}function n(){return Array.from(e.values())}function i(){e.clear()}function c(){return e.size}return{register:r,items:n,clear:i,size:c}}export{s as createCollection};
@@ -0,0 +1,5 @@
1
+ export * from './layout';
2
+ export * from './slot';
3
+ export * from './portal';
4
+ export * from './presence';
5
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/foundations/structures/index.ts"],"names":[],"mappings":"AAAA,cAAc,UAAU,CAAC;AACzB,cAAc,QAAQ,CAAC;AACvB,cAAc,UAAU,CAAC;AACzB,cAAc,YAAY,CAAC"}