foldkit-primitives 0.15.4 → 0.16.0

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 (422) hide show
  1. package/dist/device/fullscreen.d.ts +28 -0
  2. package/dist/device/fullscreen.d.ts.map +1 -0
  3. package/dist/device/fullscreen.js +69 -0
  4. package/dist/device/fullscreen.js.map +1 -0
  5. package/dist/device/geolocation.d.ts +56 -0
  6. package/dist/device/geolocation.d.ts.map +1 -0
  7. package/dist/device/geolocation.js +87 -0
  8. package/dist/device/geolocation.js.map +1 -0
  9. package/dist/device/index.d.ts +5 -0
  10. package/dist/device/index.js +6 -0
  11. package/dist/device/media-devices.d.ts +88 -0
  12. package/dist/device/media-devices.d.ts.map +1 -0
  13. package/dist/device/media-devices.js +117 -0
  14. package/dist/device/media-devices.js.map +1 -0
  15. package/dist/device/media-stream.d.ts +93 -0
  16. package/dist/device/media-stream.d.ts.map +1 -0
  17. package/dist/device/media-stream.js +106 -0
  18. package/dist/device/media-stream.js.map +1 -0
  19. package/dist/device/permissions.d.ts +106 -0
  20. package/dist/device/permissions.d.ts.map +1 -0
  21. package/dist/device/permissions.js +143 -0
  22. package/dist/device/permissions.js.map +1 -0
  23. package/dist/dom/autofocus.d.ts +15 -0
  24. package/dist/dom/autofocus.d.ts.map +1 -0
  25. package/dist/dom/autofocus.js +22 -0
  26. package/dist/dom/autofocus.js.map +1 -0
  27. package/dist/dom/clipboard.d.ts +30 -0
  28. package/dist/dom/clipboard.d.ts.map +1 -0
  29. package/dist/dom/clipboard.js +50 -0
  30. package/dist/dom/clipboard.js.map +1 -0
  31. package/dist/dom/editable-text.d.ts +72 -0
  32. package/dist/dom/editable-text.d.ts.map +1 -0
  33. package/dist/dom/editable-text.js +232 -0
  34. package/dist/dom/editable-text.js.map +1 -0
  35. package/dist/dom/fluid-hover.d.ts +93 -0
  36. package/dist/dom/fluid-hover.d.ts.map +1 -0
  37. package/dist/dom/fluid-hover.js +294 -0
  38. package/dist/dom/fluid-hover.js.map +1 -0
  39. package/dist/dom/focus-scope.d.ts +21 -0
  40. package/dist/dom/focus-scope.d.ts.map +1 -0
  41. package/dist/dom/focus-scope.js +93 -0
  42. package/dist/dom/focus-scope.js.map +1 -0
  43. package/dist/dom/follow-tab-stop.d.ts +11 -0
  44. package/dist/dom/follow-tab-stop.d.ts.map +1 -0
  45. package/dist/dom/follow-tab-stop.js +54 -0
  46. package/dist/dom/follow-tab-stop.js.map +1 -0
  47. package/dist/dom/image-decode.d.ts +27 -0
  48. package/dist/dom/image-decode.d.ts.map +1 -0
  49. package/dist/dom/image-decode.js +50 -0
  50. package/dist/dom/image-decode.js.map +1 -0
  51. package/dist/dom/index.d.ts +24 -0
  52. package/dist/dom/index.js +25 -0
  53. package/dist/dom/input-mask.d.ts +35 -0
  54. package/dist/dom/input-mask.d.ts.map +1 -0
  55. package/dist/dom/input-mask.js +90 -0
  56. package/dist/dom/input-mask.js.map +1 -0
  57. package/dist/dom/keep-in-view.d.ts +16 -0
  58. package/dist/dom/keep-in-view.d.ts.map +1 -0
  59. package/dist/dom/keep-in-view.js +38 -0
  60. package/dist/dom/keep-in-view.js.map +1 -0
  61. package/dist/dom/keyboard-inset.d.ts +29 -0
  62. package/dist/dom/keyboard-inset.d.ts.map +1 -0
  63. package/dist/dom/keyboard-inset.js +45 -0
  64. package/dist/dom/keyboard-inset.js.map +1 -0
  65. package/dist/dom/layers.d.ts +6 -0
  66. package/dist/dom/layers.d.ts.map +1 -0
  67. package/dist/dom/layers.js +35 -0
  68. package/dist/dom/layers.js.map +1 -0
  69. package/dist/dom/measure.d.ts +42 -0
  70. package/dist/dom/measure.d.ts.map +1 -0
  71. package/dist/dom/measure.js +123 -0
  72. package/dist/dom/measure.js.map +1 -0
  73. package/dist/dom/move.d.ts +45 -0
  74. package/dist/dom/move.d.ts.map +1 -0
  75. package/dist/dom/move.js +96 -0
  76. package/dist/dom/move.js.map +1 -0
  77. package/dist/dom/pointed-links.d.ts +13 -0
  78. package/dist/dom/pointed-links.d.ts.map +1 -0
  79. package/dist/dom/pointed-links.js +59 -0
  80. package/dist/dom/pointed-links.js.map +1 -0
  81. package/dist/dom/pointer-drag.d.ts +132 -0
  82. package/dist/dom/pointer-drag.d.ts.map +1 -0
  83. package/dist/dom/pointer-drag.js +307 -0
  84. package/dist/dom/pointer-drag.js.map +1 -0
  85. package/dist/dom/pointer-position.d.ts +133 -0
  86. package/dist/dom/pointer-position.d.ts.map +1 -0
  87. package/dist/dom/pointer-position.js +173 -0
  88. package/dist/dom/pointer-position.js.map +1 -0
  89. package/dist/dom/script-loader.d.ts +12 -0
  90. package/dist/dom/script-loader.d.ts.map +1 -0
  91. package/dist/dom/script-loader.js +54 -0
  92. package/dist/dom/script-loader.js.map +1 -0
  93. package/dist/dom/scroll-bars.d.ts +52 -0
  94. package/dist/dom/scroll-bars.d.ts.map +1 -0
  95. package/dist/dom/scroll-bars.js +259 -0
  96. package/dist/dom/scroll-bars.js.map +1 -0
  97. package/dist/dom/scroll-settle.d.ts +33 -0
  98. package/dist/dom/scroll-settle.d.ts.map +1 -0
  99. package/dist/dom/scroll-settle.js +84 -0
  100. package/dist/dom/scroll-settle.js.map +1 -0
  101. package/dist/dom/scroll.d.ts +21 -0
  102. package/dist/dom/scroll.d.ts.map +1 -0
  103. package/dist/dom/scroll.js +141 -0
  104. package/dist/dom/scroll.js.map +1 -0
  105. package/dist/dom/share.d.ts +19 -0
  106. package/dist/dom/share.d.ts.map +1 -0
  107. package/dist/dom/share.js +41 -0
  108. package/dist/dom/share.js.map +1 -0
  109. package/dist/dom/swipe.d.ts +121 -0
  110. package/dist/dom/swipe.d.ts.map +1 -0
  111. package/dist/dom/swipe.js +291 -0
  112. package/dist/dom/swipe.js.map +1 -0
  113. package/dist/dom/targets.d.ts +45 -0
  114. package/dist/dom/targets.d.ts.map +1 -0
  115. package/dist/dom/targets.js +70 -0
  116. package/dist/dom/targets.js.map +1 -0
  117. package/dist/dom/track-box.d.ts +61 -0
  118. package/dist/dom/track-box.d.ts.map +1 -0
  119. package/dist/dom/track-box.js +131 -0
  120. package/dist/dom/track-box.js.map +1 -0
  121. package/dist/events/active-element.d.ts +15 -0
  122. package/dist/events/active-element.d.ts.map +1 -0
  123. package/dist/events/active-element.js +33 -0
  124. package/dist/events/active-element.js.map +1 -0
  125. package/dist/events/hotkeys.d.ts +22 -0
  126. package/dist/events/hotkeys.d.ts.map +1 -0
  127. package/dist/events/hotkeys.js +56 -0
  128. package/dist/events/hotkeys.js.map +1 -0
  129. package/dist/events/idle.d.ts +29 -0
  130. package/dist/events/idle.d.ts.map +1 -0
  131. package/dist/events/idle.js +51 -0
  132. package/dist/events/idle.js.map +1 -0
  133. package/dist/events/index.d.ts +9 -0
  134. package/dist/events/index.js +10 -0
  135. package/dist/{input-modality-l7InESYh.d.mts → events/input-modality.d.ts} +9 -10
  136. package/dist/events/input-modality.d.ts.map +1 -0
  137. package/dist/{input-modality-XwQOFLip.mjs → events/input-modality.js} +2 -2
  138. package/dist/events/input-modality.js.map +1 -0
  139. package/dist/events/keyboard.d.ts +30 -0
  140. package/dist/events/keyboard.d.ts.map +1 -0
  141. package/dist/events/keyboard.js +55 -0
  142. package/dist/events/keyboard.js.map +1 -0
  143. package/dist/events/pointer.d.ts +15 -0
  144. package/dist/events/pointer.d.ts.map +1 -0
  145. package/dist/events/pointer.js +28 -0
  146. package/dist/events/pointer.js.map +1 -0
  147. package/dist/events/scroll.d.ts +16 -0
  148. package/dist/events/scroll.d.ts.map +1 -0
  149. package/dist/events/scroll.js +29 -0
  150. package/dist/events/scroll.js.map +1 -0
  151. package/dist/events/visibility.d.ts +25 -0
  152. package/dist/events/visibility.d.ts.map +1 -0
  153. package/dist/events/visibility.js +28 -0
  154. package/dist/events/visibility.js.map +1 -0
  155. package/dist/events/window-size.d.ts +30 -0
  156. package/dist/events/window-size.d.ts.map +1 -0
  157. package/dist/events/window-size.js +63 -0
  158. package/dist/events/window-size.js.map +1 -0
  159. package/dist/index.d.ts +9 -0
  160. package/dist/index.js +10 -0
  161. package/dist/interaction/bundle-behavior.d.ts +37 -0
  162. package/dist/interaction/bundle-behavior.d.ts.map +1 -0
  163. package/dist/interaction/bundle-behavior.js +34 -0
  164. package/dist/interaction/bundle-behavior.js.map +1 -0
  165. package/dist/interaction/dismiss-layer.d.ts +100 -0
  166. package/dist/interaction/dismiss-layer.d.ts.map +1 -0
  167. package/dist/interaction/dismiss-layer.js +140 -0
  168. package/dist/interaction/dismiss-layer.js.map +1 -0
  169. package/dist/interaction/editable-text.d.ts +13 -0
  170. package/dist/interaction/editable-text.d.ts.map +1 -0
  171. package/dist/interaction/editable-text.js +17 -0
  172. package/dist/interaction/editable-text.js.map +1 -0
  173. package/dist/interaction/focus-scope.d.ts +21 -0
  174. package/dist/interaction/focus-scope.d.ts.map +1 -0
  175. package/dist/interaction/focus-scope.js +25 -0
  176. package/dist/interaction/focus-scope.js.map +1 -0
  177. package/dist/interaction/focus-visible.d.ts +9 -0
  178. package/dist/interaction/focus-visible.d.ts.map +1 -0
  179. package/dist/interaction/focus-visible.js +10 -0
  180. package/dist/interaction/focus-visible.js.map +1 -0
  181. package/dist/interaction/grid-navigation.d.ts +73 -0
  182. package/dist/interaction/grid-navigation.d.ts.map +1 -0
  183. package/dist/interaction/grid-navigation.js +137 -0
  184. package/dist/interaction/grid-navigation.js.map +1 -0
  185. package/dist/interaction/index.d.ts +21 -0
  186. package/dist/interaction/index.js +21 -0
  187. package/dist/interaction/layers.d.ts +12 -0
  188. package/dist/interaction/layers.d.ts.map +1 -0
  189. package/dist/interaction/layers.js +14 -0
  190. package/dist/interaction/layers.js.map +1 -0
  191. package/dist/interaction/list-navigation.d.ts +105 -0
  192. package/dist/interaction/list-navigation.d.ts.map +1 -0
  193. package/dist/interaction/list-navigation.js +168 -0
  194. package/dist/interaction/list-navigation.js.map +1 -0
  195. package/dist/interaction/live-announce.d.ts +70 -0
  196. package/dist/interaction/live-announce.d.ts.map +1 -0
  197. package/dist/interaction/live-announce.js +115 -0
  198. package/dist/interaction/live-announce.js.map +1 -0
  199. package/dist/interaction/long-press.d.ts +102 -0
  200. package/dist/interaction/long-press.d.ts.map +1 -0
  201. package/dist/interaction/long-press.js +115 -0
  202. package/dist/interaction/long-press.js.map +1 -0
  203. package/dist/interaction/move.d.ts +10 -0
  204. package/dist/interaction/move.d.ts.map +1 -0
  205. package/dist/interaction/move.js +17 -0
  206. package/dist/interaction/move.js.map +1 -0
  207. package/dist/interaction/overlay.d.ts +45 -0
  208. package/dist/interaction/overlay.d.ts.map +1 -0
  209. package/dist/interaction/overlay.js +57 -0
  210. package/dist/interaction/overlay.js.map +1 -0
  211. package/dist/interaction/placing.d.ts +86 -0
  212. package/dist/interaction/placing.d.ts.map +1 -0
  213. package/dist/interaction/placing.js +239 -0
  214. package/dist/interaction/placing.js.map +1 -0
  215. package/dist/interaction/pointer-drag.d.ts +23 -0
  216. package/dist/interaction/pointer-drag.d.ts.map +1 -0
  217. package/dist/interaction/pointer-drag.js +21 -0
  218. package/dist/interaction/pointer-drag.js.map +1 -0
  219. package/dist/interaction/press.d.ts +152 -0
  220. package/dist/interaction/press.d.ts.map +1 -0
  221. package/dist/interaction/press.js +229 -0
  222. package/dist/interaction/press.js.map +1 -0
  223. package/dist/interaction/roving-tabindex.d.ts +85 -0
  224. package/dist/interaction/roving-tabindex.d.ts.map +1 -0
  225. package/dist/interaction/roving-tabindex.js +142 -0
  226. package/dist/interaction/roving-tabindex.js.map +1 -0
  227. package/dist/interaction/selection.d.ts +72 -0
  228. package/dist/interaction/selection.d.ts.map +1 -0
  229. package/dist/interaction/selection.js +129 -0
  230. package/dist/interaction/selection.js.map +1 -0
  231. package/dist/interaction/targets.d.ts +15 -0
  232. package/dist/interaction/targets.d.ts.map +1 -0
  233. package/dist/interaction/targets.js +20 -0
  234. package/dist/interaction/targets.js.map +1 -0
  235. package/dist/interaction/tree-navigation.d.ts +111 -0
  236. package/dist/interaction/tree-navigation.d.ts.map +1 -0
  237. package/dist/interaction/tree-navigation.js +207 -0
  238. package/dist/interaction/tree-navigation.js.map +1 -0
  239. package/dist/interaction/typeahead.d.ts +73 -0
  240. package/dist/interaction/typeahead.d.ts.map +1 -0
  241. package/dist/interaction/typeahead.js +113 -0
  242. package/dist/interaction/typeahead.js.map +1 -0
  243. package/dist/internal.d.ts +16 -0
  244. package/dist/internal.d.ts.map +1 -0
  245. package/dist/{internal-C4gHodLc.mjs → internal.js} +7 -5
  246. package/dist/internal.js.map +1 -0
  247. package/dist/media/breakpoints.d.ts +37 -0
  248. package/dist/media/breakpoints.d.ts.map +1 -0
  249. package/dist/media/breakpoints.js +64 -0
  250. package/dist/media/breakpoints.js.map +1 -0
  251. package/dist/media/index.d.ts +3 -0
  252. package/dist/media/index.js +4 -0
  253. package/dist/media/mediaquery.d.ts +40 -0
  254. package/dist/media/mediaquery.d.ts.map +1 -0
  255. package/dist/media/mediaquery.js +42 -0
  256. package/dist/media/mediaquery.js.map +1 -0
  257. package/dist/media/platform.d.ts +30 -0
  258. package/dist/media/platform.d.ts.map +1 -0
  259. package/dist/media/platform.js +50 -0
  260. package/dist/media/platform.js.map +1 -0
  261. package/dist/motion/index.d.ts +5 -0
  262. package/dist/motion/index.js +5 -0
  263. package/dist/motion/motion.d.ts +16 -0
  264. package/dist/motion/motion.d.ts.map +1 -0
  265. package/dist/motion/motion.js +25 -0
  266. package/dist/motion/motion.js.map +1 -0
  267. package/dist/motion/presence.d.ts +37 -0
  268. package/dist/motion/presence.d.ts.map +1 -0
  269. package/dist/motion/presence.js +65 -0
  270. package/dist/motion/presence.js.map +1 -0
  271. package/dist/motion/spring.d.ts +50 -0
  272. package/dist/motion/spring.d.ts.map +1 -0
  273. package/dist/motion/spring.js +92 -0
  274. package/dist/motion/spring.js.map +1 -0
  275. package/dist/motion/tween.d.ts +44 -0
  276. package/dist/motion/tween.d.ts.map +1 -0
  277. package/dist/motion/tween.js +65 -0
  278. package/dist/motion/tween.js.map +1 -0
  279. package/dist/net/broadcast.d.ts +39 -0
  280. package/dist/net/broadcast.d.ts.map +1 -0
  281. package/dist/net/broadcast.js +73 -0
  282. package/dist/net/broadcast.js.map +1 -0
  283. package/dist/net/index.d.ts +5 -0
  284. package/dist/net/index.js +6 -0
  285. package/dist/net/online.d.ts +24 -0
  286. package/dist/net/online.d.ts.map +1 -0
  287. package/dist/net/online.js +26 -0
  288. package/dist/net/online.js.map +1 -0
  289. package/dist/net/sharedHost.d.ts +64 -0
  290. package/dist/net/sharedHost.d.ts.map +1 -0
  291. package/dist/net/sharedHost.js +124 -0
  292. package/dist/net/sharedHost.js.map +1 -0
  293. package/dist/net/sse.d.ts +115 -0
  294. package/dist/net/sse.d.ts.map +1 -0
  295. package/dist/net/sse.js +138 -0
  296. package/dist/net/sse.js.map +1 -0
  297. package/dist/net/websocket.d.ts +172 -0
  298. package/dist/net/websocket.d.ts.map +1 -0
  299. package/dist/net/websocket.js +199 -0
  300. package/dist/net/websocket.js.map +1 -0
  301. package/dist/observers/bounds.d.ts +24 -0
  302. package/dist/observers/bounds.d.ts.map +1 -0
  303. package/dist/observers/bounds.js +51 -0
  304. package/dist/observers/bounds.js.map +1 -0
  305. package/dist/observers/index.d.ts +4 -0
  306. package/dist/observers/index.js +5 -0
  307. package/dist/observers/intersection.d.ts +18 -0
  308. package/dist/observers/intersection.d.ts.map +1 -0
  309. package/dist/observers/intersection.js +33 -0
  310. package/dist/observers/intersection.js.map +1 -0
  311. package/dist/observers/mutation.d.ts +25 -0
  312. package/dist/observers/mutation.d.ts.map +1 -0
  313. package/dist/observers/mutation.js +53 -0
  314. package/dist/observers/mutation.js.map +1 -0
  315. package/dist/observers/resize.d.ts +18 -0
  316. package/dist/observers/resize.d.ts.map +1 -0
  317. package/dist/observers/resize.js +33 -0
  318. package/dist/observers/resize.js.map +1 -0
  319. package/dist/state/history.d.ts +115 -0
  320. package/dist/state/history.d.ts.map +1 -0
  321. package/dist/state/history.js +167 -0
  322. package/dist/state/history.js.map +1 -0
  323. package/dist/state/index.d.ts +6 -0
  324. package/dist/state/index.js +7 -0
  325. package/dist/state/locale.d.ts +27 -0
  326. package/dist/state/locale.d.ts.map +1 -0
  327. package/dist/state/locale.js +25 -0
  328. package/dist/state/locale.js.map +1 -0
  329. package/dist/state/pagination.d.ts +53 -0
  330. package/dist/state/pagination.d.ts.map +1 -0
  331. package/dist/state/pagination.js +72 -0
  332. package/dist/state/pagination.js.map +1 -0
  333. package/dist/state/range.d.ts +9 -0
  334. package/dist/state/range.d.ts.map +1 -0
  335. package/dist/state/range.js +18 -0
  336. package/dist/state/range.js.map +1 -0
  337. package/dist/state/selection.d.ts +47 -0
  338. package/dist/state/selection.d.ts.map +1 -0
  339. package/dist/state/selection.js +39 -0
  340. package/dist/state/selection.js.map +1 -0
  341. package/dist/state/virtual.d.ts +201 -0
  342. package/dist/state/virtual.d.ts.map +1 -0
  343. package/dist/state/{index.mjs → virtual.js} +10 -306
  344. package/dist/state/virtual.js.map +1 -0
  345. package/dist/time/debounce.d.ts +43 -0
  346. package/dist/time/debounce.d.ts.map +1 -0
  347. package/dist/time/debounce.js +65 -0
  348. package/dist/time/debounce.js.map +1 -0
  349. package/dist/time/index.d.ts +6 -0
  350. package/dist/time/index.js +7 -0
  351. package/dist/time/interval.d.ts +37 -0
  352. package/dist/time/interval.d.ts.map +1 -0
  353. package/dist/time/interval.js +52 -0
  354. package/dist/time/interval.js.map +1 -0
  355. package/dist/time/relative.d.ts +8 -0
  356. package/dist/time/relative.d.ts.map +1 -0
  357. package/dist/time/relative.js +27 -0
  358. package/dist/time/relative.js.map +1 -0
  359. package/dist/time/throttle.d.ts +38 -0
  360. package/dist/time/throttle.d.ts.map +1 -0
  361. package/dist/time/throttle.js +39 -0
  362. package/dist/time/throttle.js.map +1 -0
  363. package/dist/time/ticks.d.ts +21 -0
  364. package/dist/time/ticks.d.ts.map +1 -0
  365. package/dist/time/ticks.js +30 -0
  366. package/dist/time/ticks.js.map +1 -0
  367. package/dist/time/timer.d.ts +32 -0
  368. package/dist/time/timer.d.ts.map +1 -0
  369. package/dist/time/timer.js +50 -0
  370. package/dist/time/timer.js.map +1 -0
  371. package/package.json +31 -31
  372. package/dist/device/index.d.mts +0 -335
  373. package/dist/device/index.d.mts.map +0 -1
  374. package/dist/device/index.mjs +0 -493
  375. package/dist/device/index.mjs.map +0 -1
  376. package/dist/dom/index.d.mts +0 -714
  377. package/dist/dom/index.d.mts.map +0 -1
  378. package/dist/dom/index.mjs +0 -1840
  379. package/dist/dom/index.mjs.map +0 -1
  380. package/dist/editable-text-Bg7vil7h.d.mts +0 -307
  381. package/dist/editable-text-Bg7vil7h.d.mts.map +0 -1
  382. package/dist/events/index.d.mts +0 -168
  383. package/dist/events/index.d.mts.map +0 -1
  384. package/dist/events/index.mjs +0 -307
  385. package/dist/events/index.mjs.map +0 -1
  386. package/dist/follow-tab-stop-DM5EI4Ci.mjs +0 -856
  387. package/dist/follow-tab-stop-DM5EI4Ci.mjs.map +0 -1
  388. package/dist/index-Bomdwb7e.d.mts +0 -142
  389. package/dist/index-Bomdwb7e.d.mts.map +0 -1
  390. package/dist/index.d.mts +0 -12
  391. package/dist/index.mjs +0 -12
  392. package/dist/input-modality-XwQOFLip.mjs.map +0 -1
  393. package/dist/input-modality-l7InESYh.d.mts.map +0 -1
  394. package/dist/interaction/index.d.mts +0 -1193
  395. package/dist/interaction/index.d.mts.map +0 -1
  396. package/dist/interaction/index.mjs +0 -1992
  397. package/dist/interaction/index.mjs.map +0 -1
  398. package/dist/internal-C4gHodLc.mjs.map +0 -1
  399. package/dist/media/index.d.mts +0 -103
  400. package/dist/media/index.d.mts.map +0 -1
  401. package/dist/media/index.mjs +0 -146
  402. package/dist/media/index.mjs.map +0 -1
  403. package/dist/motion/index.d.mts +0 -2
  404. package/dist/motion/index.mjs +0 -1
  405. package/dist/motion-BmlJCjn6.mjs +0 -236
  406. package/dist/motion-BmlJCjn6.mjs.map +0 -1
  407. package/dist/net/index.d.mts +0 -338
  408. package/dist/net/index.d.mts.map +0 -1
  409. package/dist/net/index.mjs +0 -530
  410. package/dist/net/index.mjs.map +0 -1
  411. package/dist/observers/index.d.mts +0 -76
  412. package/dist/observers/index.d.mts.map +0 -1
  413. package/dist/observers/index.mjs +0 -155
  414. package/dist/observers/index.mjs.map +0 -1
  415. package/dist/rolldown-runtime-D8jQpDG7.mjs +0 -12
  416. package/dist/state/index.d.mts +0 -432
  417. package/dist/state/index.d.mts.map +0 -1
  418. package/dist/state/index.mjs.map +0 -1
  419. package/dist/time/index.d.mts +0 -167
  420. package/dist/time/index.d.mts.map +0 -1
  421. package/dist/time/index.mjs +0 -236
  422. package/dist/time/index.mjs.map +0 -1
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dismiss-layer.js","names":[],"sources":["../../src/interaction/dismiss-layer.ts"],"sourcesContent":["/**\n * Dismissable layers: Escape closes the topmost open layer, a pointer press\n * outside closes the layers it is outside of. One Bundle, placed once, owns\n * the document listeners; each layer's Behavior marks its container (and its\n * trigger) with data attributes. The stack is the DOM order of the marked\n * elements at the moment of the event, so a layer opening or closing needs no\n * registration. A press inside a parent layer is outside its children, so the\n * parent stays and the children go; a press on a layer's trigger counts as\n * inside it, so a trigger never dismisses and reopens in one click. What a\n * dismissal does is the placement's `onOut`.\n */\nimport { Effect, Queue, Schema, Stream } from 'effect'\nimport type { HtmlBuilder } from 'foldkit/html'\nimport { defineMessageUnion } from 'foldkit/message'\nimport * as Subscription from 'foldkit/subscription'\nimport type * as Update from 'foldkit/update'\nimport { Bundle, type Declared } from 'foldkit-bundle'\nimport { Behavior, Capability } from 'foldkit-mixins'\n\nexport const LAYER_ATTRIBUTE = 'data-foldkit-plus-layer'\nexport const TRIGGER_ATTRIBUTE = 'data-foldkit-plus-layer-trigger'\nconst OUTSIDE_ATTRIBUTE = 'data-foldkit-plus-layer-outside'\nconst ESCAPE_ATTRIBUTE = 'data-foldkit-plus-layer-escape'\n\n/** An open layer as the document showed it: bottom to top is DOM order. */\nexport const Layer = Schema.Struct({\n id: Schema.String,\n /** Dismiss on a press outside it. */\n outside: Schema.Boolean,\n /** Dismiss on Escape when topmost. */\n escape: Schema.Boolean,\n})\nexport type Layer = typeof Layer.Type\n\nexport const Model = Schema.Struct({\n /** The open layers at the last event, bottom to top. */\n layers: Schema.Array(Layer),\n})\nexport type Model = typeof Model.Type\n\nexport const Message = defineMessageUnion({\n /** A pointer went down; `inside` are the layers whose element or trigger was on the event's path. */\n PressedAt: { layers: Schema.Array(Layer), inside: Schema.Array(Schema.String) },\n PressedEscape: { layers: Schema.Array(Layer) },\n})\nexport type Message = typeof Message.Type\n\nexport const Dismiss = Schema.TaggedStruct('Dismiss', { ids: Schema.Array(Schema.String) })\nexport type Dismiss = typeof Dismiss.Type\n\n/** Which layers a press inside `inside` dismisses: every layer above the topmost one hit, or all when none was. */\nexport const toDismiss = (\n layers: ReadonlyArray<Layer>,\n inside: ReadonlyArray<string>,\n): ReadonlyArray<string> => {\n let topmostHit = -1\n layers.forEach((layer, index) => {\n if (inside.includes(layer.id)) topmostHit = index\n })\n return layers\n .slice(topmostHit + 1)\n .filter(layer => layer.outside)\n .map(layer => layer.id)\n}\n\ntype Return = Update.ReturnWithOutMessage<Model, Message, Dismiss>\n\nconst sameLayers = (a: ReadonlyArray<Layer>, b: ReadonlyArray<Layer>): boolean =>\n a.length === b.length &&\n a.every(\n (layer, index) =>\n layer.id === b[index]!.id &&\n layer.outside === b[index]!.outside &&\n layer.escape === b[index]!.escape,\n )\n\nexport const bundle = Bundle.make('DismissLayer', {\n Model,\n Message,\n init: () => ({ model: { layers: [] } }),\n update: (model, message): Return => {\n // Every press in the document reports the layers, which are usually the\n // ones already held: keep the Model, or each click re-renders the page.\n const next = sameLayers(model.layers, message.layers) ? model : { layers: message.layers }\n return Message.match<Return>(message, {\n PressedAt: ({ layers, inside }) => {\n const ids = toDismiss(layers, inside)\n return ids.length === 0\n ? { model: next }\n : { model: next, outMessage: Dismiss.make({ ids }) }\n },\n PressedEscape: ({ layers }) => {\n const top = layers[layers.length - 1]\n return top !== undefined && top.escape\n ? { model: next, outMessage: Dismiss.make({ ids: [top.id] }) }\n : { model: next }\n },\n })\n },\n subscriptions: () =>\n Subscription.make<Model, Message>()(() => ({\n document: Subscription.persistentEntry(documentEvents()),\n })),\n})\n\nconst openLayers = (root: ParentNode): ReadonlyArray<Layer> =>\n Array.from(root.querySelectorAll(`[${LAYER_ATTRIBUTE}]`)).map(element => ({\n id: element.getAttribute(LAYER_ATTRIBUTE) ?? '',\n outside: element.getAttribute(OUTSIDE_ATTRIBUTE) !== 'false',\n escape: element.getAttribute(ESCAPE_ATTRIBUTE) !== 'false',\n }))\n\n/** The layer ids whose element or trigger is on the event's composed path. */\nexport const layersOnPath = (path: ReadonlyArray<EventTarget>): ReadonlyArray<string> => {\n const ids: Array<string> = []\n for (const target of path) {\n if (!(target instanceof Element)) continue\n const id = target.getAttribute(LAYER_ATTRIBUTE) ?? target.getAttribute(TRIGGER_ATTRIBUTE)\n if (id !== null && !ids.includes(id)) ids.push(id)\n }\n return ids\n}\n\n/**\n * The facts are read inside the listener, not after: `composedPath()` is\n * empty once dispatch has finished, and the open layers must be the ones the\n * press saw, not the ones a later render left.\n */\nconst documentEvents = (): Stream.Stream<Message> => {\n if (typeof document === 'undefined') return Stream.empty\n return Stream.callback<Message>(queue =>\n Effect.acquireRelease(\n Effect.sync(() => {\n const onPointerDown = (event: Event) =>\n Queue.offerUnsafe(\n queue,\n Message.PressedAt({\n layers: openLayers(document),\n inside: layersOnPath(event.composedPath()),\n }),\n )\n const onKeyDown = (event: Event) => {\n if ((event as KeyboardEvent).key !== 'Escape') return\n Queue.offerUnsafe(queue, Message.PressedEscape({ layers: openLayers(document) }))\n }\n document.addEventListener('pointerdown', onPointerDown, { capture: true })\n document.addEventListener('keydown', onKeyDown, { capture: true })\n return { onPointerDown, onKeyDown }\n }),\n ({ onPointerDown, onKeyDown }) =>\n Effect.sync(() => {\n document.removeEventListener('pointerdown', onPointerDown, { capture: true })\n document.removeEventListener('keydown', onKeyDown, { capture: true })\n }),\n ),\n )\n}\n\nexport interface BehaviorOptions<Input, Slots> {\n /** The layer's root, rendered only while the layer is open. */\n readonly layer: keyof Slots & string\n /** The element that opens the layer, so a press on it is inside. */\n readonly trigger?: keyof Slots & string\n readonly id: (input: Input) => string\n /** Dismiss on a press outside. Default `true`. */\n readonly outsidePress?: boolean\n /** Dismiss on Escape when topmost. Default `true`. */\n readonly escape?: boolean\n}\n\n/**\n * Marks the layer's container and trigger for the placed stack. The layer\n * takes part only while its element is rendered, so an `open` flag in the\n * parent Model is the whole lifecycle. Not for an element with `popover`,\n * which the browser dismisses itself.\n */\nexport const behavior =\n <Field extends string>(_declared: Declared<typeof bundle, Field>) =>\n <Slots>(slots: Slots) =>\n <Input, ParentMessage>(\n options: BehaviorOptions<Input, Slots>,\n ): Behavior.NamedBehavior<Slots, Input, ParentMessage> =>\n Behavior.forSlots(slots)<Input, ParentMessage>(\n {\n [options.layer]: Behavior.slot({\n requires: { capability: Capability.Container },\n attributes: ({\n input,\n h,\n }: {\n readonly input: Input\n readonly h: HtmlBuilder<ParentMessage>\n }) => [\n h.Attribute(LAYER_ATTRIBUTE, options.id(input)),\n ...(options.outsidePress === false ? [h.Attribute(OUTSIDE_ATTRIBUTE, 'false')] : []),\n ...(options.escape === false ? [h.Attribute(ESCAPE_ATTRIBUTE, 'false')] : []),\n ],\n }),\n ...(options.trigger === undefined\n ? {}\n : {\n [options.trigger]: Behavior.slot({\n requires: { capability: Capability.Interactive },\n attributes: ({\n input,\n h,\n }: {\n readonly input: Input\n readonly h: HtmlBuilder<ParentMessage>\n }) => [h.Attribute(TRIGGER_ATTRIBUTE, options.id(input))],\n }),\n }),\n // Keyed by values the caller chose; `forSlots` checks the keys exist.\n } as unknown as Behavior.BehaviorSpec<Slots, Input, ParentMessage>,\n { name: 'DismissLayer' },\n )\n"],"mappings":"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"}
@@ -0,0 +1,13 @@
1
+ import { EditAsked, EditableText as mount, TextCancelled, TextCommitted, TextEdited, TextFact, TextFact as TextFact$1, textOf } from "../dom/editable-text.js";
2
+ import { Behavior } from "foldkit-mixins";
3
+ export interface BehaviorOptions<Slots, ParentMessage> {
4
+ /** The slot holding the fields. */
5
+ readonly container: keyof Slots & string;
6
+ /** The attribute that marks a field, holding its name. */
7
+ readonly attribute: string;
8
+ /** Turns each fact into the view's Message. */
9
+ readonly toMessage: (fact: TextFact$1) => ParentMessage;
10
+ }
11
+ export declare const behavior: <Slots>(slots: Slots) => <Input, ParentMessage>(options: BehaviorOptions<Slots, ParentMessage>) => Behavior.NamedBehavior<Slots, Input, ParentMessage>;
12
+ export { EditAsked, TextCancelled, TextCommitted, TextEdited, type TextFact, mount, textOf };
13
+ //# sourceMappingURL=editable-text.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"editable-text.d.ts","names":["TextFact"],"sources":["../../src/interaction/editable-text.ts"],"mappings":";;iBAoBiB,gBAAgB,OAAO;;WAE7B,iBAAiB;;WAEjB;;WAEA,YAAY,MAAMA,eAAa;;qBAG7B,WACV,OAAK,OAAS,WACd,OAAO,eAAa,SACV,gBAAgB,OAAO,mBAC/B,SAAS,cAAc,OAAO,OAAO"}
@@ -0,0 +1,17 @@
1
+ import * as Mount from "foldkit/mount";
2
+ import { EditAsked, EditableText, EditableText as mount, TextCancelled, TextCommitted, TextEdited, textOf } from "../dom/editable-text.js";
3
+ import { Behavior, Capability } from "foldkit-mixins";
4
+ // src/interaction/editable-text.ts
5
+ /**
6
+ * `EditableText` as a Behavior: attaches the `foldkit-primitives/dom` Mount to
7
+ * a container slot and maps what it reports into the view's Messages. No
8
+ * Bundle: the text typed is a fact, and what it changes is the parent's
9
+ * `update`.
10
+ */
11
+ const behavior = (slots) => (options) => Behavior.forSlots(slots)({ [options.container]: Behavior.slot({
12
+ requires: { capability: Capability.Container },
13
+ mount: () => Mount.mapMessage(EditableText({ attribute: options.attribute }), options.toMessage)
14
+ }) }, { name: "EditableText" });
15
+ export { EditAsked, TextCancelled, TextCommitted, TextEdited, behavior, mount, textOf };
16
+
17
+ //# sourceMappingURL=editable-text.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"editable-text.js","names":["EditableTextMount"],"sources":["../../src/interaction/editable-text.ts"],"sourcesContent":["/**\n * `EditableText` as a Behavior: attaches the `foldkit-primitives/dom` Mount to\n * a container slot and maps what it reports into the view's Messages. No\n * Bundle: the text typed is a fact, and what it changes is the parent's\n * `update`.\n */\nimport * as Mount from 'foldkit/mount'\nimport { Behavior, Capability } from 'foldkit-mixins'\nimport { EditableText as EditableTextMount, type TextFact } from '../dom/editable-text.js'\n\nexport {\n EditAsked,\n EditableText as mount,\n TextCancelled,\n TextCommitted,\n TextEdited,\n textOf,\n type TextFact,\n} from '../dom/editable-text.js'\n\nexport interface BehaviorOptions<Slots, ParentMessage> {\n /** The slot holding the fields. */\n readonly container: keyof Slots & string\n /** The attribute that marks a field, holding its name. */\n readonly attribute: string\n /** Turns each fact into the view's Message. */\n readonly toMessage: (fact: TextFact) => ParentMessage\n}\n\nexport const behavior =\n <Slots>(slots: Slots) =>\n <Input, ParentMessage>(\n options: BehaviorOptions<Slots, ParentMessage>,\n ): Behavior.NamedBehavior<Slots, Input, ParentMessage> =>\n Behavior.forSlots(slots)<Input, ParentMessage>(\n {\n [options.container]: Behavior.slot({\n requires: { capability: Capability.Container },\n mount: () =>\n Mount.mapMessage(\n EditableTextMount({ attribute: options.attribute }),\n options.toMessage,\n ),\n }),\n // Keyed by a value the caller chose; `forSlots` checks the key exists.\n } as unknown as Behavior.BehaviorSpec<Slots, Input, ParentMessage>,\n { name: 'EditableText' },\n )\n"],"mappings":";;;;;;;;;;AA6BA,MAAa,YACH,WAEN,YAEA,SAAS,SAAS,KAAK,CAAC,CACtB,GACG,QAAQ,YAAY,SAAS,KAAK;CACjC,UAAU,EAAE,YAAY,WAAW,UAAU;CAC7C,aACE,MAAM,WACJA,aAAkB,EAAE,WAAW,QAAQ,UAAU,CAAC,GAClD,QAAQ,SACV;AACJ,CAAC,EAEH,GACA,EAAE,MAAM,eAAe,CACzB"}
@@ -0,0 +1,21 @@
1
+ import { FocusScope as mount, tabbableWithin } from "../dom/focus-scope.js";
2
+ import { Behavior } from "foldkit-mixins";
3
+ export interface BehaviorOptions<Slots> {
4
+ readonly container: keyof Slots & string;
5
+ /** Keep Tab, Shift+Tab, and a stray focus inside. Default `true`. */
6
+ readonly contain?: boolean;
7
+ /** Give focus back to what had it when the container unmounts. Default `true`. */
8
+ readonly restore?: boolean;
9
+ /** A selector inside the container to focus first. */
10
+ readonly initialFocus?: string;
11
+ }
12
+ /**
13
+ * On insert the container focuses `initialFocus`, else its first tabbable
14
+ * descendant, else itself; with `contain`, Tab and Shift+Tab wrap inside and
15
+ * focus that lands outside comes back to the first tabbable; on unmount, with
16
+ * `restore`, focus returns to the element that had it. A dialog that is not
17
+ * a native `<dialog>`, a menu, or a command palette takes this.
18
+ */
19
+ export declare const behavior: <Slots>(slots: Slots) => <Input, ParentMessage>(options: BehaviorOptions<Slots>) => Behavior.NamedBehavior<Slots, Input, ParentMessage>;
20
+ export { mount, tabbableWithin };
21
+ //# sourceMappingURL=focus-scope.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"focus-scope.d.ts","names":[],"sources":["../../src/interaction/focus-scope.ts"],"mappings":";;iBASiB,gBAAgB;WACtB,iBAAiB;;WAEjB;;WAEA;;WAEA;;;;;;;;;qBAUE,WACV,OAAK,OAAS,WACd,OAAO,eAAa,SACV,gBAAgB,WACxB,SAAS,cAAc,OAAO,OAAO"}
@@ -0,0 +1,25 @@
1
+ import { FocusScope, FocusScope as mount, tabbableWithin } from "../dom/focus-scope.js";
2
+ import { Behavior, Capability } from "foldkit-mixins";
3
+ // src/interaction/focus-scope.ts
4
+ /**
5
+ * `FocusScope` as a Behavior: attaches the `foldkit-primitives/dom` Mount to a
6
+ * container slot. No Bundle, because which element has focus is a DOM fact.
7
+ */
8
+ /**
9
+ * On insert the container focuses `initialFocus`, else its first tabbable
10
+ * descendant, else itself; with `contain`, Tab and Shift+Tab wrap inside and
11
+ * focus that lands outside comes back to the first tabbable; on unmount, with
12
+ * `restore`, focus returns to the element that had it. A dialog that is not
13
+ * a native `<dialog>`, a menu, or a command palette takes this.
14
+ */
15
+ const behavior = (slots) => (options) => Behavior.forSlots(slots)({ [options.container]: Behavior.slot({
16
+ requires: { capability: Capability.Container },
17
+ mount: () => FocusScope({
18
+ contain: options.contain ?? true,
19
+ restore: options.restore ?? true,
20
+ initialFocus: options.initialFocus ?? null
21
+ })
22
+ }) }, { name: "FocusScope" });
23
+ export { behavior, mount, tabbableWithin };
24
+
25
+ //# sourceMappingURL=focus-scope.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"focus-scope.js","names":["FocusScopeMount"],"sources":["../../src/interaction/focus-scope.ts"],"sourcesContent":["/**\n * `FocusScope` as a Behavior: attaches the `foldkit-primitives/dom` Mount to a\n * container slot. No Bundle, because which element has focus is a DOM fact.\n */\nimport { Behavior, Capability } from 'foldkit-mixins'\nimport { FocusScope as FocusScopeMount } from '../dom/focus-scope.js'\n\nexport { FocusScope as mount, tabbableWithin } from '../dom/focus-scope.js'\n\nexport interface BehaviorOptions<Slots> {\n readonly container: keyof Slots & string\n /** Keep Tab, Shift+Tab, and a stray focus inside. Default `true`. */\n readonly contain?: boolean\n /** Give focus back to what had it when the container unmounts. Default `true`. */\n readonly restore?: boolean\n /** A selector inside the container to focus first. */\n readonly initialFocus?: string\n}\n\n/**\n * On insert the container focuses `initialFocus`, else its first tabbable\n * descendant, else itself; with `contain`, Tab and Shift+Tab wrap inside and\n * focus that lands outside comes back to the first tabbable; on unmount, with\n * `restore`, focus returns to the element that had it. A dialog that is not\n * a native `<dialog>`, a menu, or a command palette takes this.\n */\nexport const behavior =\n <Slots>(slots: Slots) =>\n <Input, ParentMessage>(\n options: BehaviorOptions<Slots>,\n ): Behavior.NamedBehavior<Slots, Input, ParentMessage> =>\n Behavior.forSlots(slots)<Input, ParentMessage>(\n {\n [options.container]: Behavior.slot({\n requires: { capability: Capability.Container },\n mount: () =>\n FocusScopeMount({\n contain: options.contain ?? true,\n restore: options.restore ?? true,\n initialFocus: options.initialFocus ?? null,\n }),\n }),\n // Keyed by a value the caller chose; `forSlots` checks the key exists.\n } as unknown as Behavior.BehaviorSpec<Slots, Input, ParentMessage>,\n { name: 'FocusScope' },\n )\n"],"mappings":";;;;;;;;;;;;;;AA0BA,MAAa,YACH,WAEN,YAEA,SAAS,SAAS,KAAK,CAAC,CACtB,GACG,QAAQ,YAAY,SAAS,KAAK;CACjC,UAAU,EAAE,YAAY,WAAW,UAAU;CAC7C,aACEA,WAAgB;EACd,SAAS,QAAQ,WAAW;EAC5B,SAAS,QAAQ,WAAW;EAC5B,cAAc,QAAQ,gBAAgB;CACxC,CAAC;AACL,CAAC,EAEH,GACA,EAAE,MAAM,aAAa,CACvB"}
@@ -0,0 +1,9 @@
1
+ import { Declared } from "foldkit-bundle";
2
+ import { InputModality, InputModality as bundle, InputModalityModel, InputModalityModel as Model, Modality, modalityOfKey } from "../events/input-modality.js";
3
+ import { Behavior } from "foldkit-mixins";
4
+ export interface BehaviorOptions<Slots> {
5
+ readonly target: keyof Slots & string;
6
+ }
7
+ export declare const behavior: <Field extends string>(declared: Declared<typeof InputModality, Field>) => <Slots>(slots: Slots) => <Input extends { readonly [K in Field]: InputModalityModel; }, ParentMessage>(options: BehaviorOptions<Slots>) => Behavior.NamedBehavior<Slots, Input, ParentMessage>;
8
+ export { Modality, type Model, bundle, modalityOfKey };
9
+ //# sourceMappingURL=focus-visible.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"focus-visible.d.ts","names":[],"sources":["../../src/interaction/focus-visible.ts"],"mappings":";;;iBAeiB,gBAAgB;WACtB,cAAc;;qBAGZ,WACV,sBAAoB,UAAY,gBAAgB,eAAe,YAC/D,OAAK,OAAS,WACd,0BAA0B,KAAK,QAAQ,uBAAsB,eAAa,SAChE,gBAAgB,WACxB,SAAS,cAAc,OAAO,OAAO"}
@@ -0,0 +1,10 @@
1
+ import { InputModality as bundle, Modality, modalityOfKey } from "../events/input-modality.js";
2
+ import { Behavior, Capability } from "foldkit-mixins";
3
+ // src/interaction/focus-visible.ts
4
+ const behavior = (declared) => (slots) => (options) => Behavior.forSlots(slots)({ [options.target]: Behavior.slot({
5
+ requires: { capability: Capability.Focusable },
6
+ attributes: ({ input, h }) => input[declared.field].modality === "keyboard" ? [h.DataAttribute("focus-visible", "true")] : []
7
+ }) }, { name: "FocusVisible" });
8
+ export { Modality, behavior, bundle, modalityOfKey };
9
+
10
+ //# sourceMappingURL=focus-visible.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"focus-visible.js","names":[],"sources":["../../src/interaction/focus-visible.ts"],"sourcesContent":["/**\n * `FocusVisible` as a Behavior over a placed `InputModality`: the target gets\n * `data-focus-visible` while the page is being driven by keyboard, so a\n * stylesheet can show a ring with `[data-focus-visible]:focus` and hide it\n * for pointer users. CSS `:focus-visible` does this without any of it; this\n * is for a design system that must decide in the Model.\n */\nimport type { HtmlBuilder } from 'foldkit/html'\nimport type { Declared } from 'foldkit-bundle'\nimport { Behavior, Capability } from 'foldkit-mixins'\nimport { InputModality, type InputModalityModel } from '../events/input-modality.js'\n\nexport { InputModality as bundle, Modality, modalityOfKey } from '../events/input-modality.js'\nexport type { InputModalityModel as Model } from '../events/input-modality.js'\n\nexport interface BehaviorOptions<Slots> {\n readonly target: keyof Slots & string\n}\n\nexport const behavior =\n <Field extends string>(declared: Declared<typeof InputModality, Field>) =>\n <Slots>(slots: Slots) =>\n <Input extends { readonly [K in Field]: InputModalityModel }, ParentMessage>(\n options: BehaviorOptions<Slots>,\n ): Behavior.NamedBehavior<Slots, Input, ParentMessage> =>\n Behavior.forSlots(slots)<Input, ParentMessage>(\n {\n [options.target]: Behavior.slot({\n requires: { capability: Capability.Focusable },\n attributes: ({\n input,\n h,\n }: {\n readonly input: Input\n readonly h: HtmlBuilder<ParentMessage>\n }) =>\n input[declared.field].modality === 'keyboard'\n ? [h.DataAttribute('focus-visible', 'true')]\n : [],\n }),\n // Keyed by a value the caller chose; `forSlots` checks the key exists.\n } as unknown as Behavior.BehaviorSpec<Slots, Input, ParentMessage>,\n { name: 'FocusVisible' },\n )\n"],"mappings":";;;AAmBA,MAAa,YACY,cACf,WAEN,YAEA,SAAS,SAAS,KAAK,CAAC,CACtB,GACG,QAAQ,SAAS,SAAS,KAAK;CAC9B,UAAU,EAAE,YAAY,WAAW,UAAU;CAC7C,aAAa,EACX,OACA,QAKA,MAAM,SAAS,MAAM,CAAC,aAAa,aAC/B,CAAC,EAAE,cAAc,iBAAiB,MAAM,CAAC,IACzC,CAAC;AACT,CAAC,EAEH,GACA,EAAE,MAAM,eAAe,CACzB"}
@@ -0,0 +1,73 @@
1
+ import { Schema } from "effect";
2
+ import { Bundle, Declared } from "foldkit-bundle";
3
+ import { Behavior, Behaviors } from "foldkit-mixins";
4
+ import * as RovingTabindex from "./roving-tabindex.js";
5
+ import { KeyboardModifiers } from "foldkit/html";
6
+ export declare const Model: Schema.Struct<{
7
+ /** The current cell's id, or `null` before any cell has been focused. */
8
+ readonly current: Schema.NullOr<Schema.String>;
9
+ }>;
10
+ export type Model = typeof Model.Type;
11
+ export declare const Message: import("foldkit/message").MessageUnion<{
12
+ /** A cell became current: the user focused it, or a key moved there. */
13
+ readonly Focused: {
14
+ id: Schema.String;
15
+ };
16
+ }>;
17
+ export type Message = typeof Message.Type;
18
+ export declare const Args: Schema.Struct<{
19
+ /** Cells per row; the last row may be short. */
20
+ readonly columns: Schema.Number;
21
+ /** Left and right continue into the previous and next row; up and down
22
+ * continue into the previous and next column. Off, they stop at the edge. */
23
+ readonly wrap: Schema.Boolean;
24
+ /** Keep DOM focus on the container and point at the current cell with
25
+ * `aria-activedescendant` instead of moving focus. */
26
+ readonly virtual: Schema.Boolean;
27
+ }>;
28
+ export type Args = typeof Args.Type;
29
+ export declare const bundle: Bundle.Bundle<"GridNavigation", {
30
+ readonly columns: number;
31
+ readonly wrap: boolean;
32
+ readonly virtual: boolean;
33
+ }, {
34
+ readonly current: string | null;
35
+ }, {
36
+ readonly _tag: "Focused";
37
+ readonly id: string;
38
+ }, never, never, never, void, {}, {}>;
39
+ export interface MoveOptions {
40
+ readonly columns: number;
41
+ readonly wrap: boolean;
42
+ readonly direction: RovingTabindex.Direction;
43
+ }
44
+ /**
45
+ * The index the key moves to from `current` over a grid of `count` cells in
46
+ * rows of `columns`, skipping cells not in `enabled`, or `undefined` when the
47
+ * key is not a grid key. Left and right step within the row, and across rows
48
+ * under `wrap`; up and down step within the column, and across columns under
49
+ * `wrap`. Home and End are the row's first and last enabled cell; with Ctrl
50
+ * they are the grid's. At an edge without `wrap` the key is consumed and
51
+ * `current` is returned. From `-1` (nothing current) a forward key lands on
52
+ * the first enabled cell and a backward key on the last. Under `rtl`, left
53
+ * and right swap.
54
+ */
55
+ export declare const move: (enabled: ReadonlyArray<number>, count: number, current: number, key: string, modifiers: KeyboardModifiers, options: MoveOptions) => number | undefined;
56
+ export interface BehaviorOptions<Input, Slots> {
57
+ /** The slot that receives the arrow keys. */
58
+ readonly container: keyof Slots & string;
59
+ /** The slot rendered once per cell; must carry the cell's id (see `Behaviors.Collection`). */
60
+ readonly item: keyof Slots & string;
61
+ readonly items: (input: Input) => Behaviors.Collection.Items<unknown>;
62
+ /** Default `'ltr'`; return `'rtl'` to swap left and right. */
63
+ readonly direction?: (input: Input) => RovingTabindex.Direction;
64
+ }
65
+ /**
66
+ * Wires a placed `GridNavigation` to the slots exactly as `RovingTabindex`
67
+ * does, with `move` above deciding the cell: the container's arrows, Home and
68
+ * End focus the next cell (synchronously, then dispatch) or, under `virtual`,
69
+ * only dispatch and point with `aria-activedescendant`; each cell gets
70
+ * `tabindex` 0 or -1 and reports `Focused` when focused.
71
+ */
72
+ export declare const behavior: <Field extends string>(declared: Declared<typeof bundle, Field>, args: Args) => <Slots>(slots: Slots) => <Input extends { readonly [K in Field]: Model; }, ParentMessage>(options: BehaviorOptions<Input, Slots>) => Behavior.NamedBehavior<Slots, Input, ParentMessage>;
73
+ //# sourceMappingURL=grid-navigation.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"grid-navigation.d.ts","names":[],"sources":["../../src/interaction/grid-navigation.ts"],"mappings":";;;;;qBAiBa,OAAK,OAAA;;;;YAIN,eAAe,MAAM;qBAEpB,mCAAO;;;IAEP,IAAE,OAAA;;;YAEH,iBAAiB,QAAQ;qBAExB,MAAI,OAAA;;;;;;;;;;YAUL,cAAc,KAAK;qBAElB,QAAM,OAAA;;;;;;;;;;iBAUF;WACN;WACA;WACA,WAAW,eAAe;;;;;;;;;;;;;qBAcxB,OAAI,SACN,uBAAqB,eACjB,iBACE,aACJ,WACA,mBAAiB,SACnB;iBAyDM,gBAAgB,OAAO;;WAE7B,iBAAiB;;WAEjB,YAAY;WACZ,QAAQ,OAAO,UAAU,UAAU,WAAW;;WAE9C,aAAa,OAAO,UAAU,eAAe;;;;;;;;;qBAU3C,WACV,sBAAoB,UAAY,gBAAgB,QAAQ,QAAM,MAAQ,UACtE,OAAK,OAAS,WACd,0BAA0B,KAAK,QAAQ,UAAS,eAAa,SACnD,gBAAgB,OAAO,WAC/B,SAAS,cAAc,OAAO,OAAO"}
@@ -0,0 +1,137 @@
1
+ import { Option, Schema } from "effect";
2
+ import { defineMessageUnion } from "foldkit/message";
3
+ import { Bundle } from "foldkit-bundle";
4
+ import { perInput } from "../internal.js";
5
+ import { Behavior, Capability } from "foldkit-mixins";
6
+ import * as RovingTabindex from "./roving-tabindex.js";
7
+ // src/interaction/grid-navigation.ts
8
+ /**
9
+ * Two-dimensional arrow keys over a set of items laid out in rows of
10
+ * `columns` (a calendar grid, a color swatch picker, an emoji palette). The
11
+ * Model slice is the current item's id, as with `RovingTabindex`, so a
12
+ * reorder keeps the same item current. Which cell a key lands on is the pure
13
+ * `move`; the Behavior wires it to a container slot and a per-item slot and
14
+ * shares `RovingTabindex`'s item attributes, so the two are interchangeable
15
+ * on a view.
16
+ */
17
+ const Model = Schema.Struct({
18
+ /** The current cell's id, or `null` before any cell has been focused. */
19
+ current: Schema.NullOr(Schema.String) });
20
+ const Message = defineMessageUnion({
21
+ /** A cell became current: the user focused it, or a key moved there. */
22
+ Focused: { id: Schema.String } });
23
+ const Args = Schema.Struct({
24
+ /** Cells per row; the last row may be short. */
25
+ columns: Schema.Number.pipe(Schema.check(Schema.isGreaterThanOrEqualTo(1))),
26
+ /** Left and right continue into the previous and next row; up and down
27
+ * continue into the previous and next column. Off, they stop at the edge. */
28
+ wrap: Schema.Boolean,
29
+ /** Keep DOM focus on the container and point at the current cell with
30
+ * `aria-activedescendant` instead of moving focus. */
31
+ virtual: Schema.Boolean
32
+ });
33
+ const bundle = Bundle.make("GridNavigation", {
34
+ Model,
35
+ Message,
36
+ args: Args,
37
+ init: () => ({ model: { current: null } }),
38
+ update: (model, message) => model.current === message.id ? { model } : { model: { current: message.id } }
39
+ });
40
+ /**
41
+ * The index the key moves to from `current` over a grid of `count` cells in
42
+ * rows of `columns`, skipping cells not in `enabled`, or `undefined` when the
43
+ * key is not a grid key. Left and right step within the row, and across rows
44
+ * under `wrap`; up and down step within the column, and across columns under
45
+ * `wrap`. Home and End are the row's first and last enabled cell; with Ctrl
46
+ * they are the grid's. At an edge without `wrap` the key is consumed and
47
+ * `current` is returned. From `-1` (nothing current) a forward key lands on
48
+ * the first enabled cell and a backward key on the last. Under `rtl`, left
49
+ * and right swap.
50
+ */
51
+ const move = (enabled, count, current, key, modifiers, options) => {
52
+ if (enabled.length === 0 || modifiers.altKey || modifiers.metaKey) return void 0;
53
+ const first = enabled[0];
54
+ const last = enabled[enabled.length - 1];
55
+ const isEnabled = (index) => enabled.includes(index);
56
+ const { columns } = options;
57
+ const row = (index) => Math.floor(index / columns);
58
+ if (key === "Home" || key === "End") {
59
+ if (modifiers.ctrlKey || current === -1) return key === "Home" ? first : last;
60
+ const inRow = enabled.filter((index) => row(index) === row(current));
61
+ return key === "Home" ? inRow[0] ?? current : inRow[inRow.length - 1] ?? current;
62
+ }
63
+ if (modifiers.ctrlKey) return void 0;
64
+ const forwardKey = options.direction === "rtl" ? "ArrowLeft" : "ArrowRight";
65
+ const backwardKey = options.direction === "rtl" ? "ArrowRight" : "ArrowLeft";
66
+ const axis = key === forwardKey || key === backwardKey ? "row" : key === "ArrowDown" || key === "ArrowUp" ? "column" : void 0;
67
+ if (axis === void 0) return void 0;
68
+ const step = key === forwardKey || key === "ArrowDown" ? 1 : -1;
69
+ if (current === -1) return step === 1 ? first : last;
70
+ if (axis === "row") {
71
+ for (let index = current + step; index >= 0 && index < count; index += step) {
72
+ if (!options.wrap && row(index) !== row(current)) return current;
73
+ if (isEnabled(index)) return index;
74
+ }
75
+ return current;
76
+ }
77
+ const column = current % columns;
78
+ for (let index = current + step * columns;; index += step * columns) {
79
+ if (index < 0 || index >= count) {
80
+ if (!options.wrap) return current;
81
+ const nextColumn = column + step;
82
+ if (nextColumn < 0 || nextColumn >= columns) return current;
83
+ const start = step === 1 ? nextColumn : nextColumn + columns * Math.floor((count - 1 - nextColumn) / columns);
84
+ for (let next = start; next >= 0 && next < count; next += step * columns) if (isEnabled(next)) return next;
85
+ return current;
86
+ }
87
+ if (isEnabled(index)) return index;
88
+ }
89
+ };
90
+ /**
91
+ * Wires a placed `GridNavigation` to the slots exactly as `RovingTabindex`
92
+ * does, with `move` above deciding the cell: the container's arrows, Home and
93
+ * End focus the next cell (synchronously, then dispatch) or, under `virtual`,
94
+ * only dispatch and point with `aria-activedescendant`; each cell gets
95
+ * `tabindex` 0 or -1 and reports `Focused` when focused.
96
+ */
97
+ const behavior = (declared, args) => (slots) => (options) => {
98
+ const wrap = (id) => declared.wrapper.make(Message.Focused({ id }));
99
+ const slice = (input) => input[declared.field];
100
+ const itemsOf = perInput(options.items);
101
+ return Behavior.forSlots(slots)({
102
+ [options.container]: Behavior.slot({
103
+ requires: { capability: Capability.Interactive },
104
+ attributes: ({ input, h }) => {
105
+ const items = itemsOf(input);
106
+ const current = slice(input).current;
107
+ const from = current === null ? -1 : items.indexOf(current);
108
+ const direction = options.direction?.(input) ?? "ltr";
109
+ const stop = RovingTabindex.tabStop(items, current);
110
+ const stopId = stop === -1 ? void 0 : items.ids[stop];
111
+ const target = (key, modifiers) => {
112
+ const next = move(items.enabled, items.size, from, key, modifiers, {
113
+ columns: args.columns,
114
+ wrap: args.wrap,
115
+ direction
116
+ });
117
+ return next === void 0 ? void 0 : items.ids[next];
118
+ };
119
+ if (args.virtual) return [h.OnKeyDownPreventDefault((key, modifiers) => Option.map(Option.fromNullishOr(target(key, modifiers)), wrap)), ...stopId === void 0 ? [] : [h.AriaActiveDescendant(stopId)]];
120
+ return [h.OnKeyDownFocus((key, modifiers) => Option.map(Option.fromNullishOr(target(key, modifiers)), (id) => ({
121
+ focusSelector: RovingTabindex.idSelector(id),
122
+ message: wrap(id)
123
+ })))];
124
+ }
125
+ }),
126
+ [options.item]: Behavior.slot({
127
+ requires: { capability: Capability.Focusable },
128
+ attributes: ({ input, h, item }) => {
129
+ if (item === void 0) return [];
130
+ return RovingTabindex.itemAttributes(h, itemsOf(input), slice(input).current, item, args.virtual, wrap);
131
+ }
132
+ })
133
+ }, { name: "GridNavigation" });
134
+ };
135
+ export { Args, Message, Model, behavior, bundle, move };
136
+
137
+ //# sourceMappingURL=grid-navigation.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"grid-navigation.js","names":[],"sources":["../../src/interaction/grid-navigation.ts"],"sourcesContent":["/**\n * Two-dimensional arrow keys over a set of items laid out in rows of\n * `columns` (a calendar grid, a color swatch picker, an emoji palette). The\n * Model slice is the current item's id, as with `RovingTabindex`, so a\n * reorder keeps the same item current. Which cell a key lands on is the pure\n * `move`; the Behavior wires it to a container slot and a per-item slot and\n * shares `RovingTabindex`'s item attributes, so the two are interchangeable\n * on a view.\n */\nimport { Option, Schema } from 'effect'\nimport type { HtmlBuilder, KeyboardModifiers } from 'foldkit/html'\nimport { defineMessageUnion } from 'foldkit/message'\nimport { Bundle, type Declared } from 'foldkit-bundle'\nimport { Behavior, Behaviors, Capability, type SlotItem } from 'foldkit-mixins'\nimport * as RovingTabindex from './roving-tabindex.js'\nimport { perInput } from '../internal.js'\n\nexport const Model = Schema.Struct({\n /** The current cell's id, or `null` before any cell has been focused. */\n current: Schema.NullOr(Schema.String),\n})\nexport type Model = typeof Model.Type\n\nexport const Message = defineMessageUnion({\n /** A cell became current: the user focused it, or a key moved there. */\n Focused: { id: Schema.String },\n})\nexport type Message = typeof Message.Type\n\nexport const Args = Schema.Struct({\n /** Cells per row; the last row may be short. */\n columns: Schema.Number.pipe(Schema.check(Schema.isGreaterThanOrEqualTo(1))),\n /** Left and right continue into the previous and next row; up and down\n * continue into the previous and next column. Off, they stop at the edge. */\n wrap: Schema.Boolean,\n /** Keep DOM focus on the container and point at the current cell with\n * `aria-activedescendant` instead of moving focus. */\n virtual: Schema.Boolean,\n})\nexport type Args = typeof Args.Type\n\nexport const bundle = Bundle.make('GridNavigation', {\n Model,\n Message,\n args: Args,\n init: () => ({ model: { current: null } }),\n // Moving focus by key dispatches `Focused`, and the cell's `OnFocus` reports it again.\n update: (model, message) =>\n model.current === message.id ? { model } : { model: { current: message.id } },\n})\n\nexport interface MoveOptions {\n readonly columns: number\n readonly wrap: boolean\n readonly direction: RovingTabindex.Direction\n}\n\n/**\n * The index the key moves to from `current` over a grid of `count` cells in\n * rows of `columns`, skipping cells not in `enabled`, or `undefined` when the\n * key is not a grid key. Left and right step within the row, and across rows\n * under `wrap`; up and down step within the column, and across columns under\n * `wrap`. Home and End are the row's first and last enabled cell; with Ctrl\n * they are the grid's. At an edge without `wrap` the key is consumed and\n * `current` is returned. From `-1` (nothing current) a forward key lands on\n * the first enabled cell and a backward key on the last. Under `rtl`, left\n * and right swap.\n */\nexport const move = (\n enabled: ReadonlyArray<number>,\n count: number,\n current: number,\n key: string,\n modifiers: KeyboardModifiers,\n options: MoveOptions,\n): number | undefined => {\n if (enabled.length === 0 || modifiers.altKey || modifiers.metaKey) return undefined\n const first = enabled[0]!\n const last = enabled[enabled.length - 1]!\n const isEnabled = (index: number) => enabled.includes(index)\n const { columns } = options\n const row = (index: number) => Math.floor(index / columns)\n\n if (key === 'Home' || key === 'End') {\n if (modifiers.ctrlKey || current === -1) return key === 'Home' ? first : last\n const inRow = enabled.filter(index => row(index) === row(current))\n return key === 'Home' ? (inRow[0] ?? current) : (inRow[inRow.length - 1] ?? current)\n }\n if (modifiers.ctrlKey) return undefined\n\n const forwardKey = options.direction === 'rtl' ? 'ArrowLeft' : 'ArrowRight'\n const backwardKey = options.direction === 'rtl' ? 'ArrowRight' : 'ArrowLeft'\n const axis: 'row' | 'column' | undefined =\n key === forwardKey || key === backwardKey\n ? 'row'\n : key === 'ArrowDown' || key === 'ArrowUp'\n ? 'column'\n : undefined\n if (axis === undefined) return undefined\n const step = key === forwardKey || key === 'ArrowDown' ? 1 : -1\n if (current === -1) return step === 1 ? first : last\n\n if (axis === 'row') {\n // Reading order; without wrap the walk stops at the row's edge.\n for (let index = current + step; index >= 0 && index < count; index += step) {\n if (!options.wrap && row(index) !== row(current)) return current\n if (isEnabled(index)) return index\n }\n return current\n }\n // Column-major; without wrap the walk stops at the column's edge.\n const column = current % columns\n for (let index = current + step * columns; ; index += step * columns) {\n if (index < 0 || index >= count) {\n if (!options.wrap) return current\n const nextColumn = column + step\n if (nextColumn < 0 || nextColumn >= columns) return current\n // Continue from the top (or bottom) of the neighbouring column.\n const start =\n step === 1\n ? nextColumn\n : nextColumn + columns * Math.floor((count - 1 - nextColumn) / columns)\n for (let next = start; next >= 0 && next < count; next += step * columns) {\n if (isEnabled(next)) return next\n }\n return current\n }\n if (isEnabled(index)) return index\n }\n}\n\nexport interface BehaviorOptions<Input, Slots> {\n /** The slot that receives the arrow keys. */\n readonly container: keyof Slots & string\n /** The slot rendered once per cell; must carry the cell's id (see `Behaviors.Collection`). */\n readonly item: keyof Slots & string\n readonly items: (input: Input) => Behaviors.Collection.Items<unknown>\n /** Default `'ltr'`; return `'rtl'` to swap left and right. */\n readonly direction?: (input: Input) => RovingTabindex.Direction\n}\n\n/**\n * Wires a placed `GridNavigation` to the slots exactly as `RovingTabindex`\n * does, with `move` above deciding the cell: the container's arrows, Home and\n * End focus the next cell (synchronously, then dispatch) or, under `virtual`,\n * only dispatch and point with `aria-activedescendant`; each cell gets\n * `tabindex` 0 or -1 and reports `Focused` when focused.\n */\nexport const behavior =\n <Field extends string>(declared: Declared<typeof bundle, Field>, args: Args) =>\n <Slots>(slots: Slots) =>\n <Input extends { readonly [K in Field]: Model }, ParentMessage>(\n options: BehaviorOptions<Input, Slots>,\n ): Behavior.NamedBehavior<Slots, Input, ParentMessage> => {\n const wrap = (id: string): ParentMessage =>\n declared.wrapper.make(Message.Focused({ id })) as unknown as ParentMessage\n const slice = (input: Input): Model => input[declared.field]\n const itemsOf = perInput(options.items)\n return Behavior.forSlots(slots)<Input, ParentMessage>(\n {\n [options.container]: Behavior.slot({\n requires: { capability: Capability.Interactive },\n attributes: ({\n input,\n h,\n }: {\n readonly input: Input\n readonly h: HtmlBuilder<ParentMessage>\n }) => {\n const items = itemsOf(input)\n const current = slice(input).current\n const from = current === null ? -1 : items.indexOf(current)\n const direction = options.direction?.(input) ?? 'ltr'\n const stop = RovingTabindex.tabStop(items, current)\n const stopId = stop === -1 ? undefined : items.ids[stop]\n const target = (key: string, modifiers: KeyboardModifiers): string | undefined => {\n const next = move(items.enabled, items.size, from, key, modifiers, {\n columns: args.columns,\n wrap: args.wrap,\n direction,\n })\n return next === undefined ? undefined : items.ids[next]\n }\n if (args.virtual) {\n return [\n h.OnKeyDownPreventDefault((key, modifiers) =>\n Option.map(Option.fromNullishOr(target(key, modifiers)), wrap),\n ),\n ...(stopId === undefined ? [] : [h.AriaActiveDescendant(stopId)]),\n ]\n }\n return [\n h.OnKeyDownFocus((key, modifiers) =>\n Option.map(Option.fromNullishOr(target(key, modifiers)), id => ({\n focusSelector: RovingTabindex.idSelector(id),\n message: wrap(id),\n })),\n ),\n ]\n },\n }),\n [options.item]: Behavior.slot({\n requires: { capability: Capability.Focusable },\n attributes: ({\n input,\n h,\n item,\n }: {\n readonly input: Input\n readonly h: HtmlBuilder<ParentMessage>\n readonly item?: SlotItem\n }) => {\n if (item === undefined) return []\n return RovingTabindex.itemAttributes(\n h,\n itemsOf(input),\n slice(input).current,\n item,\n args.virtual,\n wrap,\n )\n },\n }),\n // Keyed by values the caller chose; `forSlots` checks both keys exist.\n } as unknown as Behavior.BehaviorSpec<Slots, Input, ParentMessage>,\n { name: 'GridNavigation' },\n )\n }\n"],"mappings":"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"}
@@ -0,0 +1,21 @@
1
+ import * as RovingTabindex from "./roving-tabindex.js";
2
+ import * as BundleBehavior from "./bundle-behavior.js";
3
+ import * as DismissLayer from "./dismiss-layer.js";
4
+ import * as EditableText from "./editable-text.js";
5
+ import * as FocusScope from "./focus-scope.js";
6
+ import * as FocusVisible from "./focus-visible.js";
7
+ import * as GridNavigation from "./grid-navigation.js";
8
+ import * as Layers from "./layers.js";
9
+ import * as LiveAnnounce from "./live-announce.js";
10
+ import * as ListNavigation from "./list-navigation.js";
11
+ import * as LongPress from "./long-press.js";
12
+ import * as Move from "./move.js";
13
+ import * as Overlay from "./overlay.js";
14
+ import * as Press from "./press.js";
15
+ import * as Selection from "./selection.js";
16
+ import * as Targets from "./targets.js";
17
+ import * as PointerDrag from "./pointer-drag.js";
18
+ import * as Placing from "./placing.js";
19
+ import * as TreeNavigation from "./tree-navigation.js";
20
+ import * as Typeahead from "./typeahead.js";
21
+ export { BundleBehavior, DismissLayer, EditableText, FocusScope, FocusVisible, GridNavigation, Layers, ListNavigation, LiveAnnounce, LongPress, Move, Overlay, Placing, PointerDrag, Press, RovingTabindex, Selection, Targets, TreeNavigation, Typeahead };
@@ -0,0 +1,21 @@
1
+ import * as RovingTabindex from "./roving-tabindex.js";
2
+ import * as BundleBehavior from "./bundle-behavior.js";
3
+ import * as DismissLayer from "./dismiss-layer.js";
4
+ import * as EditableText from "./editable-text.js";
5
+ import * as FocusScope from "./focus-scope.js";
6
+ import * as FocusVisible from "./focus-visible.js";
7
+ import * as GridNavigation from "./grid-navigation.js";
8
+ import * as Layers from "./layers.js";
9
+ import * as LiveAnnounce from "./live-announce.js";
10
+ import * as ListNavigation from "./list-navigation.js";
11
+ import * as LongPress from "./long-press.js";
12
+ import * as Move from "./move.js";
13
+ import * as Overlay from "./overlay.js";
14
+ import * as Press from "./press.js";
15
+ import * as Selection from "./selection.js";
16
+ import * as Targets from "./targets.js";
17
+ import * as PointerDrag from "./pointer-drag.js";
18
+ import * as Placing from "./placing.js";
19
+ import * as TreeNavigation from "./tree-navigation.js";
20
+ import * as Typeahead from "./typeahead.js";
21
+ export { BundleBehavior, DismissLayer, EditableText, FocusScope, FocusVisible, GridNavigation, Layers, ListNavigation, LiveAnnounce, LongPress, Move, Overlay, Placing, PointerDrag, Press, RovingTabindex, Selection, Targets, TreeNavigation, Typeahead };
@@ -0,0 +1,12 @@
1
+ import { HideOutside as hideOutsideMount, ScrollLock as scrollLockMount } from "../dom/layers.js";
2
+ import { Behavior } from "foldkit-mixins";
3
+ /** Locks the document's scroll while the container is mounted; nested locks release together. */
4
+ export declare const scrollLock: <Slots>(slots: Slots) => <Input, ParentMessage>(options: {
5
+ readonly container: keyof Slots & string;
6
+ }) => Behavior.NamedBehavior<Slots, Input, ParentMessage>;
7
+ /** Marks everything outside the container inert while it is mounted. */
8
+ export declare const hideOutside: <Slots>(slots: Slots) => <Input, ParentMessage>(options: {
9
+ readonly container: keyof Slots & string;
10
+ }) => Behavior.NamedBehavior<Slots, Input, ParentMessage>;
11
+ export { hideOutsideMount, scrollLockMount };
12
+ //# sourceMappingURL=layers.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"layers.d.ts","names":[],"sources":["../../src/interaction/layers.ts"],"mappings":";;;qBA8Ba,aAhBV,OAAK,OAAS,WACd,OAAO,eAAa;WACV,iBAAiB;MACxB,SAAS,cAAc,OAAO,OAAO;;qBAgB9B,cAnBV,OAAK,OAAS,WACd,OAAO,eAAa;WACV,iBAAiB;MACxB,SAAS,cAAc,OAAO,OAAO"}
@@ -0,0 +1,14 @@
1
+ import { HideOutside, HideOutside as hideOutsideMount, ScrollLock, ScrollLock as scrollLockMount } from "../dom/layers.js";
2
+ import { Behavior, Capability } from "foldkit-mixins";
3
+ // src/interaction/layers.ts
4
+ const mountOn = (name, mount) => (slots) => (options) => Behavior.forSlots(slots)({ [options.container]: Behavior.slot({
5
+ requires: { capability: Capability.Container },
6
+ mount
7
+ }) }, { name });
8
+ /** Locks the document's scroll while the container is mounted; nested locks release together. */
9
+ const scrollLock = mountOn("ScrollLock", () => ScrollLock());
10
+ /** Marks everything outside the container inert while it is mounted. */
11
+ const hideOutside = mountOn("HideOutside", () => HideOutside());
12
+ export { hideOutside, hideOutsideMount, scrollLock, scrollLockMount };
13
+
14
+ //# sourceMappingURL=layers.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"layers.js","names":["ScrollLockMount","HideOutsideMount"],"sources":["../../src/interaction/layers.ts"],"sourcesContent":["/**\n * `ScrollLock` and `HideOutside` as Behaviors: each attaches its\n * `foldkit-primitives/dom` Mount to a container slot. No Bundle, because the\n * lock and the inert set are document facts Foldkit already refcounts and\n * keys.\n */\nimport type { MountAction } from 'foldkit/mount'\nimport { Behavior, Capability } from 'foldkit-mixins'\nimport { HideOutside as HideOutsideMount, ScrollLock as ScrollLockMount } from '../dom/layers.js'\n\nexport { HideOutside as hideOutsideMount, ScrollLock as scrollLockMount } from '../dom/layers.js'\n\nconst mountOn =\n (name: string, mount: () => MountAction<never>) =>\n <Slots>(slots: Slots) =>\n <Input, ParentMessage>(options: {\n readonly container: keyof Slots & string\n }): Behavior.NamedBehavior<Slots, Input, ParentMessage> =>\n Behavior.forSlots(slots)<Input, ParentMessage>(\n {\n [options.container]: Behavior.slot({\n requires: { capability: Capability.Container },\n mount,\n }),\n // Keyed by a value the caller chose; `forSlots` checks the key exists.\n } as unknown as Behavior.BehaviorSpec<Slots, Input, ParentMessage>,\n { name },\n )\n\n/** Locks the document's scroll while the container is mounted; nested locks release together. */\nexport const scrollLock = mountOn('ScrollLock', () => ScrollLockMount())\n\n/** Marks everything outside the container inert while it is mounted. */\nexport const hideOutside = mountOn('HideOutside', () => HideOutsideMount())\n"],"mappings":";;;AAYA,MAAM,WACH,MAAc,WACP,WACe,YAGrB,SAAS,SAAS,KAAK,CAAC,CACtB,GACG,QAAQ,YAAY,SAAS,KAAK;CACjC,UAAU,EAAE,YAAY,WAAW,UAAU;CAC7C;AACF,CAAC,EAEH,GACA,EAAE,KAAK,CACT;;AAGJ,MAAa,aAAa,QAAQ,oBAAoBA,WAAgB,CAAC;;AAGvE,MAAa,cAAc,QAAQ,qBAAqBC,YAAiB,CAAC"}
@@ -0,0 +1,105 @@
1
+ import { Schema } from "effect";
2
+ import { Bundle, Declared } from "foldkit-bundle";
3
+ import { Behavior, Behaviors } from "foldkit-mixins";
4
+ import * as RovingTabindex from "./roving-tabindex.js";
5
+ import { KeyboardModifiers } from "foldkit/html";
6
+ export declare const Model: Schema.Struct<{
7
+ readonly current: Schema.NullOr<Schema.String>;
8
+ readonly query: Schema.String;
9
+ readonly generation: Schema.Number;
10
+ }>;
11
+ export type Model = typeof Model.Type;
12
+ export declare const Message: import("foldkit/message").MessageUnion<{
13
+ /** An item became current: focused, or reached by a key. */
14
+ readonly Focused: {
15
+ id: Schema.String;
16
+ };
17
+ /** A printable key extended the query; `match` is the item it now picks, if any. */
18
+ readonly Typed: {
19
+ char: Schema.String;
20
+ match: Schema.NullOr<Schema.String>;
21
+ };
22
+ readonly Expired: {
23
+ generation: Schema.Number;
24
+ };
25
+ readonly Cleared: {};
26
+ }>;
27
+ export type Message = typeof Message.Type;
28
+ export declare const Args: Schema.Struct<{
29
+ readonly orientation: Schema.Literals<readonly ["vertical", "horizontal", "both"]>;
30
+ readonly loop: Schema.Boolean;
31
+ readonly virtual: Schema.Boolean;
32
+ /** How long the typeahead query survives after the last key. */
33
+ readonly timeoutMs: Schema.Number;
34
+ /** How many enabled items PageUp and PageDown move. */
35
+ readonly page: Schema.Number;
36
+ }>;
37
+ export type Args = typeof Args.Type;
38
+ export declare const bundle: Bundle.Bundle<"ListNavigation", {
39
+ readonly orientation: "both" | "horizontal" | "vertical";
40
+ readonly loop: boolean;
41
+ readonly virtual: boolean;
42
+ readonly timeoutMs: number;
43
+ readonly page: number;
44
+ }, {
45
+ readonly current: string | null;
46
+ readonly query: string;
47
+ readonly generation: number;
48
+ }, {
49
+ readonly _tag: "Cleared";
50
+ } | {
51
+ readonly _tag: "Expired";
52
+ readonly generation: number;
53
+ } | {
54
+ readonly _tag: "Focused";
55
+ readonly id: string;
56
+ } | {
57
+ readonly _tag: "Typed";
58
+ readonly char: string;
59
+ readonly match: string | null;
60
+ }, never, never, never, void, {}, {}>;
61
+ export interface BehaviorOptions<Input, Slots, ParentMessage> {
62
+ readonly container: keyof Slots & string;
63
+ /** The slot rendered once per item; must carry the item's id (see `Behaviors.Collection`). */
64
+ readonly item: keyof Slots & string;
65
+ readonly items: (input: Input) => Behaviors.Collection.Items<unknown>;
66
+ /** The text an item is matched by when typing. */
67
+ readonly text: (input: Input, index: number) => string;
68
+ readonly direction?: (input: Input) => RovingTabindex.Direction;
69
+ /**
70
+ * Whether a printable key moves the pointer. Off when the container is a
71
+ * text field: letters belong to the field, and arrows still navigate.
72
+ * Defaults to on.
73
+ */
74
+ readonly typeahead?: boolean;
75
+ /**
76
+ * Enter on the current enabled item. One handler with the arrows: a second
77
+ * key handler on the same slot would be a second owner of `keydown`.
78
+ */
79
+ readonly commit?: (input: Input, id: string) => ParentMessage;
80
+ }
81
+ /**
82
+ * The key's outcome, before it is turned into an attribute: navigation to an
83
+ * id, a typed character with its match, or nothing.
84
+ */
85
+ export type KeyOutcome = {
86
+ readonly _tag: 'Navigate';
87
+ readonly id: string;
88
+ } | {
89
+ readonly _tag: 'Type';
90
+ readonly char: string;
91
+ readonly match: string | null;
92
+ };
93
+ export declare const keyOutcome: (items: Behaviors.Collection.Items<unknown>, texts: ReadonlyArray<string>, state: {
94
+ readonly current: string | null;
95
+ readonly query: string;
96
+ }, key: string, modifiers: KeyboardModifiers, options: RovingTabindex.MoveOptions) => KeyOutcome | undefined;
97
+ /**
98
+ * Wires a placed `ListNavigation` to the slots. The container gets one key
99
+ * handler: arrows, Home, End, PageUp and PageDown move by id; a printable key
100
+ * extends the query and moves to its match. Each item gets `tabindex` and
101
+ * `OnFocus` as under `RovingTabindex`. Under `virtual` nothing takes DOM focus
102
+ * and the container carries `aria-activedescendant`.
103
+ */
104
+ export declare const behavior: <Field extends string>(declared: Declared<typeof bundle, Field>, args: Args) => <Slots>(slots: Slots) => <Input extends { readonly [K in Field]: Model; }, ParentMessage>(options: BehaviorOptions<Input, Slots, ParentMessage>) => Behavior.NamedBehavior<Slots, Input, ParentMessage>;
105
+ //# sourceMappingURL=list-navigation.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"list-navigation.d.ts","names":[],"sources":["../../src/interaction/list-navigation.ts"],"mappings":";;;;;qBAkBa,OAAK,OAAA;;;;;YAKN,eAAe,MAAM;qBAEpB,mCAAO;;;IAEP,IAAE,OAAA;;;;IAEJ,MAAI,OAAA;IAAiB,OAAK,OAAA,OAAA,OAAA;;;IACxB,YAAU,OAAA;;;;YAGX,iBAAiB,QAAQ;qBAExB,MAAI,OAAA;;;;;;;;;YAYL,cAAc,KAAK;qBAElB,QAAM,OAAA;;;;;;;;;;;;;;;;;;;;;;;iBA6BF,gBAAgB,OAAO,OAAO;WACpC,iBAAiB;;WAEjB,YAAY;WACZ,QAAQ,OAAO,UAAU,UAAU,WAAW;;WAE9C,OAAO,OAAO,OAAO;WACrB,aAAa,OAAO,UAAU,eAAe;;;;;;WAM7C;;;;;WAKA,UAAU,OAAO,OAAO,eAAe;;;;;;YAOtC;WACG;WAA2B;;WAC3B;WAAuB;WAAuB;;qBAEhD,aAAU,OACd,UAAU,WAAW,gBAAc,OACnC,uBAAqB;WACV;WAAiC;GAAe,aACvD,WACA,mBAAiB,SACnB,eAAe,gBACvB;;;;;;;;qBAkBU,WACV,sBAAoB,UAAY,gBAAgB,QAAQ,QAAM,MAAQ,UACtE,OAAK,OAAS,WACd,0BAA0B,KAAK,QAAQ,UAAS,eAAa,SACnD,gBAAgB,OAAO,OAAO,mBACtC,SAAS,cAAc,OAAO,OAAO"}