@vielzeug/craftit 2.0.1 → 2.1.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 (400) hide show
  1. package/README.md +71 -53
  2. package/dist/component.cjs +2 -0
  3. package/dist/component.cjs.map +1 -0
  4. package/dist/component.d.ts +39 -0
  5. package/dist/component.d.ts.map +1 -0
  6. package/dist/component.js +2 -0
  7. package/dist/component.js.map +1 -0
  8. package/dist/controls/a11y-control.cjs +2 -0
  9. package/dist/controls/a11y-control.cjs.map +1 -0
  10. package/dist/controls/a11y-control.d.ts +16 -0
  11. package/dist/controls/a11y-control.d.ts.map +1 -0
  12. package/dist/controls/a11y-control.js +2 -0
  13. package/dist/controls/a11y-control.js.map +1 -0
  14. package/dist/controls/checkable-control.cjs +2 -0
  15. package/dist/controls/checkable-control.cjs.map +1 -0
  16. package/dist/controls/checkable-control.d.ts +15 -0
  17. package/dist/controls/checkable-control.d.ts.map +1 -0
  18. package/dist/controls/checkable-control.js +2 -0
  19. package/dist/controls/checkable-control.js.map +1 -0
  20. package/dist/controls/field-control.cjs +2 -0
  21. package/dist/controls/field-control.cjs.map +1 -0
  22. package/dist/controls/field-control.d.ts +156 -0
  23. package/dist/controls/field-control.d.ts.map +1 -0
  24. package/dist/controls/field-control.js +2 -0
  25. package/dist/controls/field-control.js.map +1 -0
  26. package/dist/controls/index.d.ts +10 -0
  27. package/dist/controls/index.d.ts.map +1 -0
  28. package/dist/controls/internal/control-state.cjs +2 -0
  29. package/dist/controls/internal/control-state.cjs.map +1 -0
  30. package/dist/controls/internal/control-state.d.ts +19 -0
  31. package/dist/controls/internal/control-state.d.ts.map +1 -0
  32. package/dist/controls/internal/control-state.js +2 -0
  33. package/dist/controls/internal/control-state.js.map +1 -0
  34. package/dist/controls/internal/keyboard-utils.cjs +2 -0
  35. package/dist/controls/internal/keyboard-utils.cjs.map +1 -0
  36. package/dist/controls/internal/keyboard-utils.d.ts +7 -0
  37. package/dist/controls/internal/keyboard-utils.d.ts.map +1 -0
  38. package/dist/controls/internal/keyboard-utils.js +2 -0
  39. package/dist/controls/internal/keyboard-utils.js.map +1 -0
  40. package/dist/controls/internal/number-utils.cjs +2 -0
  41. package/dist/controls/internal/number-utils.cjs.map +1 -0
  42. package/dist/controls/internal/number-utils.d.ts +6 -0
  43. package/dist/controls/internal/number-utils.d.ts.map +1 -0
  44. package/dist/controls/internal/number-utils.js +2 -0
  45. package/dist/controls/internal/number-utils.js.map +1 -0
  46. package/dist/controls/internal/validation-utils.cjs +2 -0
  47. package/dist/controls/internal/validation-utils.cjs.map +1 -0
  48. package/dist/controls/internal/validation-utils.d.ts +13 -0
  49. package/dist/controls/internal/validation-utils.d.ts.map +1 -0
  50. package/dist/controls/internal/validation-utils.js +2 -0
  51. package/dist/controls/internal/validation-utils.js.map +1 -0
  52. package/dist/controls/list-control.cjs +2 -0
  53. package/dist/controls/list-control.cjs.map +1 -0
  54. package/dist/controls/list-control.d.ts +21 -0
  55. package/dist/controls/list-control.d.ts.map +1 -0
  56. package/dist/controls/list-control.js +2 -0
  57. package/dist/controls/list-control.js.map +1 -0
  58. package/dist/controls/list-key-control.cjs +2 -0
  59. package/dist/controls/list-key-control.cjs.map +1 -0
  60. package/dist/controls/list-key-control.d.ts +14 -0
  61. package/dist/controls/list-key-control.d.ts.map +1 -0
  62. package/dist/controls/list-key-control.js +2 -0
  63. package/dist/controls/list-key-control.js.map +1 -0
  64. package/dist/controls/overlay-control.cjs +2 -0
  65. package/dist/controls/overlay-control.cjs.map +1 -0
  66. package/dist/controls/overlay-control.d.ts +37 -0
  67. package/dist/controls/overlay-control.d.ts.map +1 -0
  68. package/dist/controls/overlay-control.js +2 -0
  69. package/dist/controls/overlay-control.js.map +1 -0
  70. package/dist/controls/press-control.cjs +2 -0
  71. package/dist/controls/press-control.cjs.map +1 -0
  72. package/dist/controls/press-control.d.ts +12 -0
  73. package/dist/controls/press-control.d.ts.map +1 -0
  74. package/dist/controls/press-control.js +2 -0
  75. package/dist/controls/press-control.js.map +1 -0
  76. package/dist/controls/slider-control.cjs +2 -0
  77. package/dist/controls/slider-control.cjs.map +1 -0
  78. package/dist/controls/slider-control.d.ts +19 -0
  79. package/dist/controls/slider-control.d.ts.map +1 -0
  80. package/dist/controls/slider-control.js +2 -0
  81. package/dist/controls/slider-control.js.map +1 -0
  82. package/dist/controls/spinner-control.cjs +2 -0
  83. package/dist/controls/spinner-control.cjs.map +1 -0
  84. package/dist/controls/spinner-control.d.ts +18 -0
  85. package/dist/controls/spinner-control.d.ts.map +1 -0
  86. package/dist/controls/spinner-control.js +2 -0
  87. package/dist/controls/spinner-control.js.map +1 -0
  88. package/dist/controls.cjs +1 -0
  89. package/dist/controls.js +1 -0
  90. package/dist/craftit.cjs +1 -1
  91. package/dist/craftit.cjs.map +1 -1
  92. package/dist/craftit.js +1 -1
  93. package/dist/craftit.js.map +1 -1
  94. package/dist/directives/attr.cjs +1 -1
  95. package/dist/directives/attr.cjs.map +1 -1
  96. package/dist/directives/attr.d.ts +4 -6
  97. package/dist/directives/attr.d.ts.map +1 -1
  98. package/dist/directives/attr.js +1 -1
  99. package/dist/directives/attr.js.map +1 -1
  100. package/dist/directives/bind.cjs +1 -1
  101. package/dist/directives/bind.cjs.map +1 -1
  102. package/dist/directives/bind.d.ts +20 -12
  103. package/dist/directives/bind.d.ts.map +1 -1
  104. package/dist/directives/bind.js +1 -1
  105. package/dist/directives/bind.js.map +1 -1
  106. package/dist/directives/choose.cjs +1 -1
  107. package/dist/directives/choose.cjs.map +1 -1
  108. package/dist/directives/choose.d.ts +17 -12
  109. package/dist/directives/choose.d.ts.map +1 -1
  110. package/dist/directives/choose.js +1 -1
  111. package/dist/directives/choose.js.map +1 -1
  112. package/dist/directives/each.cjs +1 -1
  113. package/dist/directives/each.cjs.map +1 -1
  114. package/dist/directives/each.d.ts +19 -31
  115. package/dist/directives/each.d.ts.map +1 -1
  116. package/dist/directives/each.js +1 -1
  117. package/dist/directives/each.js.map +1 -1
  118. package/dist/directives/index.d.ts +1 -2
  119. package/dist/directives/index.d.ts.map +1 -1
  120. package/dist/directives/memo.cjs +1 -1
  121. package/dist/directives/memo.cjs.map +1 -1
  122. package/dist/directives/memo.d.ts +8 -4
  123. package/dist/directives/memo.d.ts.map +1 -1
  124. package/dist/directives/memo.js +1 -1
  125. package/dist/directives/memo.js.map +1 -1
  126. package/dist/directives/on.cjs +1 -1
  127. package/dist/directives/on.cjs.map +1 -1
  128. package/dist/directives/on.d.ts +1 -1
  129. package/dist/directives/on.d.ts.map +1 -1
  130. package/dist/directives/on.js +1 -1
  131. package/dist/directives/on.js.map +1 -1
  132. package/dist/directives/raw.cjs +1 -1
  133. package/dist/directives/raw.cjs.map +1 -1
  134. package/dist/directives/raw.d.ts +1 -1
  135. package/dist/directives/raw.d.ts.map +1 -1
  136. package/dist/directives/raw.js +1 -1
  137. package/dist/directives/raw.js.map +1 -1
  138. package/dist/directives/spread.cjs +1 -1
  139. package/dist/directives/spread.cjs.map +1 -1
  140. package/dist/directives/spread.d.ts +1 -1
  141. package/dist/directives/spread.d.ts.map +1 -1
  142. package/dist/directives/spread.js +1 -1
  143. package/dist/directives/spread.js.map +1 -1
  144. package/dist/directives/style.cjs +1 -1
  145. package/dist/directives/style.cjs.map +1 -1
  146. package/dist/directives/style.js +1 -1
  147. package/dist/directives/style.js.map +1 -1
  148. package/dist/directives/until.cjs.map +1 -1
  149. package/dist/directives/until.d.ts +1 -1
  150. package/dist/directives/until.d.ts.map +1 -1
  151. package/dist/directives/until.js.map +1 -1
  152. package/dist/directives/when.cjs +1 -1
  153. package/dist/directives/when.cjs.map +1 -1
  154. package/dist/directives/when.d.ts +11 -5
  155. package/dist/directives/when.d.ts.map +1 -1
  156. package/dist/directives/when.js +1 -1
  157. package/dist/directives/when.js.map +1 -1
  158. package/dist/directives.cjs +1 -0
  159. package/dist/directives.js +1 -0
  160. package/dist/form.cjs +2 -0
  161. package/dist/form.cjs.map +1 -0
  162. package/dist/form.d.ts +29 -0
  163. package/dist/form.d.ts.map +1 -0
  164. package/dist/form.js +2 -0
  165. package/dist/form.js.map +1 -0
  166. package/dist/host.cjs +2 -0
  167. package/dist/host.cjs.map +1 -0
  168. package/dist/host.d.ts +75 -0
  169. package/dist/host.d.ts.map +1 -0
  170. package/dist/host.js +2 -0
  171. package/dist/host.js.map +1 -0
  172. package/dist/index.cjs +1 -1
  173. package/dist/index.d.ts +8 -9
  174. package/dist/index.d.ts.map +1 -1
  175. package/dist/index.js +1 -1
  176. package/dist/internal.cjs +2 -0
  177. package/dist/internal.cjs.map +1 -0
  178. package/dist/internal.d.ts +171 -0
  179. package/dist/internal.d.ts.map +1 -0
  180. package/dist/internal.js +2 -0
  181. package/dist/internal.js.map +1 -0
  182. package/dist/observers/index.d.ts +4 -0
  183. package/dist/observers/index.d.ts.map +1 -0
  184. package/dist/observers/intersection-observe.cjs +2 -0
  185. package/dist/observers/intersection-observe.cjs.map +1 -0
  186. package/dist/observers/intersection-observe.d.ts +9 -0
  187. package/dist/observers/intersection-observe.d.ts.map +1 -0
  188. package/dist/observers/intersection-observe.js +2 -0
  189. package/dist/observers/intersection-observe.js.map +1 -0
  190. package/dist/observers/media-observe.cjs +2 -0
  191. package/dist/observers/media-observe.cjs.map +1 -0
  192. package/dist/observers/media-observe.d.ts +8 -0
  193. package/dist/observers/media-observe.d.ts.map +1 -0
  194. package/dist/observers/media-observe.js +2 -0
  195. package/dist/observers/media-observe.js.map +1 -0
  196. package/dist/observers/resize-observe.cjs +2 -0
  197. package/dist/observers/resize-observe.cjs.map +1 -0
  198. package/dist/observers/resize-observe.d.ts +11 -0
  199. package/dist/observers/resize-observe.d.ts.map +1 -0
  200. package/dist/observers/resize-observe.js +2 -0
  201. package/dist/observers/resize-observe.js.map +1 -0
  202. package/dist/observers.cjs +1 -0
  203. package/dist/observers.js +1 -0
  204. package/dist/props.cjs +2 -0
  205. package/dist/props.cjs.map +1 -0
  206. package/dist/props.d.ts +52 -0
  207. package/dist/props.d.ts.map +1 -0
  208. package/dist/props.js +2 -0
  209. package/dist/props.js.map +1 -0
  210. package/dist/registration.cjs +2 -0
  211. package/dist/registration.cjs.map +1 -0
  212. package/dist/registration.d.ts +18 -0
  213. package/dist/registration.d.ts.map +1 -0
  214. package/dist/registration.js +2 -0
  215. package/dist/registration.js.map +1 -0
  216. package/dist/runtime-bindings.cjs +2 -0
  217. package/dist/runtime-bindings.cjs.map +1 -0
  218. package/dist/runtime-bindings.d.ts.map +1 -0
  219. package/dist/runtime-bindings.js +2 -0
  220. package/dist/runtime-bindings.js.map +1 -0
  221. package/dist/runtime-core.cjs +2 -0
  222. package/dist/runtime-core.cjs.map +1 -0
  223. package/dist/runtime-core.d.ts +21 -0
  224. package/dist/runtime-core.d.ts.map +1 -0
  225. package/dist/runtime-core.js +2 -0
  226. package/dist/runtime-core.js.map +1 -0
  227. package/dist/runtime-lifecycle.cjs +2 -0
  228. package/dist/runtime-lifecycle.cjs.map +1 -0
  229. package/dist/runtime-lifecycle.d.ts +24 -0
  230. package/dist/runtime-lifecycle.d.ts.map +1 -0
  231. package/dist/runtime-lifecycle.js +2 -0
  232. package/dist/runtime-lifecycle.js.map +1 -0
  233. package/dist/runtime.cjs +2 -0
  234. package/dist/runtime.cjs.map +1 -0
  235. package/dist/runtime.d.ts +21 -0
  236. package/dist/runtime.d.ts.map +1 -0
  237. package/dist/runtime.js +2 -0
  238. package/dist/runtime.js.map +1 -0
  239. package/dist/template-bindings.cjs +2 -0
  240. package/dist/template-bindings.cjs.map +1 -0
  241. package/dist/{core/template-bindings.d.ts → template-bindings.d.ts} +4 -1
  242. package/dist/template-bindings.d.ts.map +1 -0
  243. package/dist/template-bindings.js +2 -0
  244. package/dist/template-bindings.js.map +1 -0
  245. package/dist/template-compiler.cjs +2 -0
  246. package/dist/template-compiler.cjs.map +1 -0
  247. package/dist/{core/template-compiler.d.ts → template-compiler.d.ts} +1 -2
  248. package/dist/template-compiler.d.ts.map +1 -0
  249. package/dist/template-compiler.js +2 -0
  250. package/dist/template-compiler.js.map +1 -0
  251. package/dist/template-dom.cjs +2 -0
  252. package/dist/{core/template-dom.js.map → template-dom.cjs.map} +1 -1
  253. package/dist/template-dom.d.ts.map +1 -0
  254. package/dist/template-dom.js +2 -0
  255. package/dist/template-dom.js.map +1 -0
  256. package/dist/template-html.cjs +2 -0
  257. package/dist/template-html.cjs.map +1 -0
  258. package/dist/{core/template-html.d.ts → template-html.d.ts} +1 -4
  259. package/dist/template-html.d.ts.map +1 -0
  260. package/dist/template-html.js +2 -0
  261. package/dist/template-html.js.map +1 -0
  262. package/dist/template.cjs +2 -0
  263. package/dist/template.cjs.map +1 -0
  264. package/dist/{core/template.d.ts → template.d.ts} +2 -3
  265. package/dist/template.d.ts.map +1 -0
  266. package/dist/template.js +2 -0
  267. package/dist/template.js.map +1 -0
  268. package/dist/testing/index.d.ts +2 -0
  269. package/dist/testing/index.d.ts.map +1 -0
  270. package/dist/testing/testing.cjs +2 -0
  271. package/dist/testing/testing.cjs.map +1 -0
  272. package/dist/{test/test.d.ts → testing/testing.d.ts} +8 -8
  273. package/dist/testing/testing.d.ts.map +1 -0
  274. package/dist/testing/testing.js +2 -0
  275. package/dist/testing/testing.js.map +1 -0
  276. package/dist/testing.cjs +1 -0
  277. package/dist/testing.js +1 -0
  278. package/package.json +19 -14
  279. package/dist/core/component.cjs +0 -2
  280. package/dist/core/component.cjs.map +0 -1
  281. package/dist/core/component.d.ts +0 -172
  282. package/dist/core/component.d.ts.map +0 -1
  283. package/dist/core/component.js +0 -2
  284. package/dist/core/component.js.map +0 -1
  285. package/dist/core/host.cjs +0 -2
  286. package/dist/core/host.cjs.map +0 -1
  287. package/dist/core/host.d.ts +0 -77
  288. package/dist/core/host.d.ts.map +0 -1
  289. package/dist/core/host.js +0 -2
  290. package/dist/core/host.js.map +0 -1
  291. package/dist/core/internal.cjs +0 -2
  292. package/dist/core/internal.cjs.map +0 -1
  293. package/dist/core/internal.d.ts +0 -107
  294. package/dist/core/internal.d.ts.map +0 -1
  295. package/dist/core/internal.js +0 -2
  296. package/dist/core/internal.js.map +0 -1
  297. package/dist/core/runtime-bindings.cjs +0 -2
  298. package/dist/core/runtime-bindings.cjs.map +0 -1
  299. package/dist/core/runtime-bindings.d.ts.map +0 -1
  300. package/dist/core/runtime-bindings.js +0 -2
  301. package/dist/core/runtime-bindings.js.map +0 -1
  302. package/dist/core/runtime-lifecycle.cjs +0 -2
  303. package/dist/core/runtime-lifecycle.cjs.map +0 -1
  304. package/dist/core/runtime-lifecycle.d.ts +0 -116
  305. package/dist/core/runtime-lifecycle.d.ts.map +0 -1
  306. package/dist/core/runtime-lifecycle.js +0 -2
  307. package/dist/core/runtime-lifecycle.js.map +0 -1
  308. package/dist/core/runtime.cjs +0 -1
  309. package/dist/core/runtime.d.ts +0 -3
  310. package/dist/core/runtime.d.ts.map +0 -1
  311. package/dist/core/runtime.js +0 -1
  312. package/dist/core/template-bindings.cjs +0 -2
  313. package/dist/core/template-bindings.cjs.map +0 -1
  314. package/dist/core/template-bindings.d.ts.map +0 -1
  315. package/dist/core/template-bindings.js +0 -2
  316. package/dist/core/template-bindings.js.map +0 -1
  317. package/dist/core/template-compiler.cjs +0 -2
  318. package/dist/core/template-compiler.cjs.map +0 -1
  319. package/dist/core/template-compiler.d.ts.map +0 -1
  320. package/dist/core/template-compiler.js +0 -2
  321. package/dist/core/template-compiler.js.map +0 -1
  322. package/dist/core/template-dom.cjs +0 -2
  323. package/dist/core/template-dom.cjs.map +0 -1
  324. package/dist/core/template-dom.d.ts.map +0 -1
  325. package/dist/core/template-dom.js +0 -2
  326. package/dist/core/template-html.cjs +0 -2
  327. package/dist/core/template-html.cjs.map +0 -1
  328. package/dist/core/template-html.d.ts.map +0 -1
  329. package/dist/core/template-html.js +0 -2
  330. package/dist/core/template-html.js.map +0 -1
  331. package/dist/core/template.cjs +0 -2
  332. package/dist/core/template.cjs.map +0 -1
  333. package/dist/core/template.d.ts.map +0 -1
  334. package/dist/core/template.js +0 -2
  335. package/dist/core/template.js.map +0 -1
  336. package/dist/core/utilities.cjs +0 -2
  337. package/dist/core/utilities.cjs.map +0 -1
  338. package/dist/core/utilities.d.ts +0 -68
  339. package/dist/core/utilities.d.ts.map +0 -1
  340. package/dist/core/utilities.js +0 -2
  341. package/dist/core/utilities.js.map +0 -1
  342. package/dist/directives/index.cjs +0 -1
  343. package/dist/directives/index.js +0 -1
  344. package/dist/directives/match.cjs +0 -2
  345. package/dist/directives/match.cjs.map +0 -1
  346. package/dist/directives/match.d.ts +0 -31
  347. package/dist/directives/match.d.ts.map +0 -1
  348. package/dist/directives/match.js +0 -2
  349. package/dist/directives/match.js.map +0 -1
  350. package/dist/labs/a11y.cjs +0 -2
  351. package/dist/labs/a11y.cjs.map +0 -1
  352. package/dist/labs/a11y.d.ts +0 -61
  353. package/dist/labs/a11y.d.ts.map +0 -1
  354. package/dist/labs/a11y.js +0 -2
  355. package/dist/labs/a11y.js.map +0 -1
  356. package/dist/labs/index.d.ts +0 -8
  357. package/dist/labs/index.d.ts.map +0 -1
  358. package/dist/labs/list.cjs +0 -2
  359. package/dist/labs/list.cjs.map +0 -1
  360. package/dist/labs/list.d.ts +0 -26
  361. package/dist/labs/list.d.ts.map +0 -1
  362. package/dist/labs/list.js +0 -2
  363. package/dist/labs/list.js.map +0 -1
  364. package/dist/labs/observers.cjs +0 -2
  365. package/dist/labs/observers.cjs.map +0 -1
  366. package/dist/labs/observers.d.ts +0 -42
  367. package/dist/labs/observers.d.ts.map +0 -1
  368. package/dist/labs/observers.js +0 -2
  369. package/dist/labs/observers.js.map +0 -1
  370. package/dist/labs/overlay.cjs +0 -2
  371. package/dist/labs/overlay.cjs.map +0 -1
  372. package/dist/labs/overlay.d.ts +0 -35
  373. package/dist/labs/overlay.d.ts.map +0 -1
  374. package/dist/labs/overlay.js +0 -2
  375. package/dist/labs/overlay.js.map +0 -1
  376. package/dist/labs/selectable.cjs +0 -2
  377. package/dist/labs/selectable.cjs.map +0 -1
  378. package/dist/labs/selectable.d.ts +0 -70
  379. package/dist/labs/selectable.d.ts.map +0 -1
  380. package/dist/labs/selectable.js +0 -2
  381. package/dist/labs/selectable.js.map +0 -1
  382. package/dist/labs/selection.cjs +0 -2
  383. package/dist/labs/selection.cjs.map +0 -1
  384. package/dist/labs/selection.d.ts +0 -68
  385. package/dist/labs/selection.d.ts.map +0 -1
  386. package/dist/labs/selection.js +0 -2
  387. package/dist/labs/selection.js.map +0 -1
  388. package/dist/labs.cjs +0 -1
  389. package/dist/labs.js +0 -1
  390. package/dist/test/index.d.ts +0 -2
  391. package/dist/test/index.d.ts.map +0 -1
  392. package/dist/test/test.cjs +0 -2
  393. package/dist/test/test.cjs.map +0 -1
  394. package/dist/test/test.d.ts.map +0 -1
  395. package/dist/test/test.js +0 -2
  396. package/dist/test/test.js.map +0 -1
  397. package/dist/test.cjs +0 -1
  398. package/dist/test.js +0 -1
  399. /package/dist/{core/runtime-bindings.d.ts → runtime-bindings.d.ts} +0 -0
  400. /package/dist/{core/template-dom.d.ts → template-dom.d.ts} +0 -0
@@ -0,0 +1,156 @@
1
+ import { type ReadonlySignal, type Signal } from '@vielzeug/stateit';
2
+ import { type FormFieldHandle } from '../form';
3
+ import { type Directive } from '../internal';
4
+ import { type ControlContextOptions, type ControlValidationMode, type FormControlValidationTrigger } from './internal/control-state';
5
+ export type { FormControlValidationTrigger } from './internal/control-state';
6
+ export { createValidationControl } from './internal/control-state';
7
+ export type { ValidationReporter } from './internal/control-state';
8
+ export type TextFieldControlContext = {
9
+ disabled?: ReadonlySignal<boolean | undefined>;
10
+ validateOn?: ReadonlySignal<ControlValidationMode>;
11
+ };
12
+ export type TextFieldOptions = Omit<ControlContextOptions, 'disabled' | 'validateOn'> & {
13
+ autocomplete?: ReadonlySignal<string | undefined>;
14
+ context?: TextFieldControlContext;
15
+ disabled?: ReadonlySignal<boolean | undefined>;
16
+ elementRef?: {
17
+ value: HTMLInputElement | HTMLTextAreaElement | null;
18
+ };
19
+ error?: ReadonlySignal<string | undefined>;
20
+ helper?: ReadonlySignal<string | undefined>;
21
+ inputmode?: ReadonlySignal<string | undefined>;
22
+ label?: ReadonlySignal<string | undefined>;
23
+ labelPlacement?: ReadonlySignal<'inset' | 'outside' | undefined>;
24
+ maxLength?: ReadonlySignal<number | undefined>;
25
+ minLength?: ReadonlySignal<number | undefined>;
26
+ name?: ReadonlySignal<string | undefined>;
27
+ onBlur?: (event: FocusEvent) => void;
28
+ onChange?: (event: Event, value: string) => void;
29
+ onInput?: (event: Event, value: string) => void;
30
+ onInputExtra?: (event: Event) => void;
31
+ onReset?: () => void;
32
+ pattern?: ReadonlySignal<string | undefined>;
33
+ placeholder?: ReadonlySignal<string | undefined>;
34
+ prefix: string;
35
+ readOnly?: ReadonlySignal<boolean | undefined>;
36
+ required?: ReadonlySignal<boolean | undefined>;
37
+ rows?: ReadonlySignal<number | undefined>;
38
+ type?: ReadonlySignal<string | undefined> | (() => string | undefined) | string;
39
+ validateOn?: ReadonlySignal<ControlValidationMode>;
40
+ value: ReadonlySignal<string | undefined>;
41
+ };
42
+ export type ChoiceFieldOptions<T> = {
43
+ context?: TextFieldControlContext;
44
+ disabled?: ReadonlySignal<boolean | undefined>;
45
+ error?: ReadonlySignal<string | undefined>;
46
+ getValue: (item: T) => string;
47
+ helper?: ReadonlySignal<string | undefined>;
48
+ label?: ReadonlySignal<string | undefined>;
49
+ labelPlacement?: ReadonlySignal<'inset' | 'outside' | undefined>;
50
+ mapControlledValue: (value: string) => T;
51
+ multiple?: ReadonlySignal<boolean | undefined>;
52
+ name?: ReadonlySignal<string | undefined>;
53
+ onReset?: () => void;
54
+ prefix: string;
55
+ validateOn?: ReadonlySignal<ControlValidationMode>;
56
+ value: ReadonlySignal<string | undefined>;
57
+ };
58
+ export type CheckableStateOptions = ControlContextOptions & {
59
+ checked: ReadonlySignal<boolean | undefined>;
60
+ clearIndeterminateFirst?: boolean;
61
+ error?: ReadonlySignal<string | undefined>;
62
+ group?: {
63
+ toggle: (value: string, originalEvent?: Event) => void;
64
+ };
65
+ helper?: ReadonlySignal<string | undefined>;
66
+ indeterminate?: ReadonlySignal<boolean | undefined>;
67
+ label?: ReadonlySignal<string | undefined>;
68
+ labelPlacement?: ReadonlySignal<'inset' | 'outside' | undefined>;
69
+ name?: ReadonlySignal<string | undefined>;
70
+ onReset?: () => void;
71
+ onToggle?: (payload: CheckableChangePayload) => void;
72
+ prefix: string;
73
+ value: ReadonlySignal<string | undefined>;
74
+ };
75
+ export type CheckableChangePayload = {
76
+ checked: boolean;
77
+ fieldValue: string;
78
+ originalEvent?: Event;
79
+ };
80
+ export type FieldControlBaseHandle = {
81
+ disabled: ReadonlySignal<boolean>;
82
+ errorId: string;
83
+ field: FormFieldHandle;
84
+ fieldId: string;
85
+ helperId: string;
86
+ labelInsetId: string;
87
+ labelInsetRef: {
88
+ value: HTMLLabelElement | null;
89
+ };
90
+ labelOutsideId: string;
91
+ labelOutsideRef: {
92
+ value: HTMLLabelElement | null;
93
+ };
94
+ triggerValidation: (on: FormControlValidationTrigger) => void;
95
+ validateOn: ReadonlySignal<ControlValidationMode> | undefined;
96
+ };
97
+ export type TextFieldHandle = FieldControlBaseHandle & {
98
+ assistive: ReadonlySignal<AssistiveState>;
99
+ attrs: Directive;
100
+ clear: (event?: Event) => void;
101
+ value: Signal<string>;
102
+ };
103
+ export type AssistiveState = {
104
+ counterAtLimit: boolean;
105
+ counterNearLimit: boolean;
106
+ counterText: string;
107
+ errorText: string;
108
+ hasCounter: boolean;
109
+ hasError: boolean;
110
+ hasHelper: boolean;
111
+ helperText: string;
112
+ hidden: boolean;
113
+ isError: boolean;
114
+ showHelper: boolean;
115
+ text: string;
116
+ };
117
+ export type AssistiveOptions = {
118
+ error?: ReadonlySignal<string | undefined>;
119
+ helper?: ReadonlySignal<string | undefined>;
120
+ maxLength?: ReadonlySignal<number | undefined>;
121
+ value?: ReadonlySignal<string | undefined>;
122
+ };
123
+ export type TextFieldLifecycleOptions = {
124
+ element: HTMLInputElement | HTMLSelectElement | HTMLTextAreaElement;
125
+ onBlur?: (event: FocusEvent) => void;
126
+ onChange?: (event: Event, value: string) => void;
127
+ onInput?: (event: Event, value: string) => void;
128
+ triggerValidation?: (on: FormControlValidationTrigger) => void;
129
+ };
130
+ export type CheckableStateHandle = FieldControlBaseHandle & {
131
+ assistive: ReadonlySignal<AssistiveState>;
132
+ checked: Signal<boolean>;
133
+ indeterminate: Signal<boolean>;
134
+ toggle: (event: Event) => void;
135
+ value: Signal<string>;
136
+ };
137
+ export type ChoiceFieldHandle<T> = FieldControlBaseHandle & {
138
+ assistive: ReadonlySignal<AssistiveState>;
139
+ clear: () => void;
140
+ field: FormFieldHandle;
141
+ formValue: ReadonlySignal<string>;
142
+ isMultiple: ReadonlySignal<boolean>;
143
+ isSelected: (value: string) => boolean;
144
+ removeValue: (value: string) => void;
145
+ replaceSelectedItems: (items: T[]) => void;
146
+ selectedItems: Signal<T[]>;
147
+ selectedValues: ReadonlySignal<string[]>;
148
+ selectItem: (item: T) => void;
149
+ toggleItem: (item: T) => void;
150
+ };
151
+ export declare const createAssistiveState: (options: AssistiveOptions) => import("@vielzeug/stateit").ComputedSignal<AssistiveState>;
152
+ export declare const createTextFieldControl: (options: TextFieldOptions) => TextFieldHandle;
153
+ export declare const mountTextFieldLifecycle: (options: TextFieldLifecycleOptions) => void;
154
+ export declare const createChoiceFieldControl: <T>(options: ChoiceFieldOptions<T>) => ChoiceFieldHandle<T>;
155
+ export declare const createCheckableStateControl: (options: CheckableStateOptions) => CheckableStateHandle;
156
+ //# sourceMappingURL=field-control.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"field-control.d.ts","sourceRoot":"","sources":["../../src/controls/field-control.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ import{effect as e,handle as t,onElement as n,watch as r}from"../runtime-lifecycle.js";import{createId as i,ref as a}from"../internal.js";import{spread as o}from"../directives/spread.js";import{defineField as s}from"../form.js";import{createControlState as c}from"./internal/control-state.js";import{computed as l,isSignal as u,signal as d}from"@vielzeug/stateit";var f=(e,t)=>{let n=`${e}-${t&&t.trim()?t.trim():i().replace(/^cft-/,``)}`,r=`label-${n}`;return{errorId:`error-${n}`,fieldId:n,helperId:`helper-${n}`,labelInsetId:r,labelOutsideId:`${r}-outside`}},p=t=>{let n=c(t),r=f(t.prefix,t.name?.value),i=a(),o=a();return e(()=>{let e=t.labelPlacement?.value??`inset`,n=t.label?.value??``;i.value&&(i.value.textContent=n,i.value.hidden=!n||e!==`inset`),o.value&&(o.value.textContent=n,o.value.hidden=!n||e!==`outside`)}),{disabled:n.disabled,errorId:r.errorId,fieldId:r.fieldId,helperId:r.helperId,labelInsetId:r.labelInsetId,labelInsetRef:i,labelOutsideId:r.labelOutsideId,labelOutsideRef:o,triggerValidation:(e,t)=>n.triggerValidation(e,t),validateOn:n.validateOn}},m=e=>({disabled:l(()=>!!e.disabled?.value||!!e.context?.disabled?.value),validateOn:e.validateOn??e.context?.validateOn}),h=e=>l(()=>{let t=e.value?.value??``,n=e.error?.value??``,r=e.helper?.value??``,i=!!n,a=!!r,o=n||r||``,s=e.maxLength?.value,c=Number(s),l=Number.isFinite(c)&&c>0?c:null,u=l!==null,d=u?`${t.length} / ${l}`:``,f=u?t.length/l:0;return{counterAtLimit:u?f>=1:!1,counterNearLimit:u?f>=.9&&f<1:!1,counterText:d,errorText:n,hasCounter:u,hasError:i,hasHelper:a,helperText:r,hidden:!o,isError:i,showHelper:!i&&a,text:o}}),g=e=>{if(e!==void 0)return u(e)?e.value:typeof e==`function`?e():e},_=e=>()=>{let t=g(e);if(!(t==null||t===``))return String(t)},v=e=>()=>{let t=g(e);if(!(t==null||Number.isNaN(Number(t))||Number(t)<=0))return Number(t)},y=e=>{let t=d(``),i=m(e),a=p({...e,...i});r(e.value,e=>{t.value=String(e??``)},{immediate:!0});let c=s({disabled:a.disabled,value:t},{onReset:()=>{t.value=``,e.onReset?.()}}),l=h({error:e.error,helper:e.helper,maxLength:e.maxLength,value:t}),u=n=>{n?.preventDefault?.(),t.value=``,e.onInput?.(n??new Event(`input`),``),e.onChange?.(n??new Event(`change`),``),a.triggerValidation(c,`change`),e.elementRef?.value?.focus()};return e.elementRef&&n(e.elementRef,t=>{b({element:t,onBlur:e.onBlur,onChange:e.onChange,onInput:(t,n)=>{e.onInputExtra?.(t),e.onInput?.(t,n)},triggerValidation:e=>a.triggerValidation(c,e)})}),{assistive:l,attrs:o({"?required":e.required,".disabled":e.disabled,".readOnly":e.readOnly,".type":e.type,".value":t,autocomplete:_(e.autocomplete),inputmode:_(e.inputmode),maxlength:v(e.maxLength),minlength:v(e.minLength),name:_(e.name),pattern:_(e.pattern),placeholder:_(e.placeholder),rows:v(e.rows)}),...a,clear:u,field:c,triggerValidation:e=>a.triggerValidation(c,e),value:t}},b=e=>{let{element:n,onBlur:r,onChange:i,onInput:a,triggerValidation:o}=e;a&&t(n,`input`,e=>{a(e,n.value)}),t(n,`change`,e=>{i?.(e,n.value),o?.(`change`)}),t(n,`blur`,e=>{r?.(e),o?.(`blur`)})},x=e=>e?e.split(`,`).map(e=>e.trim()).filter(Boolean):[],S=e=>{let t=p({...m(e),label:e.label,labelPlacement:e.labelPlacement,name:e.name,prefix:e.prefix}),n=d([]),i=l(()=>!!e.multiple?.value),a=l(()=>n.value.map(t=>e.getValue(t))),o=l(()=>i.value?a.value.join(`,`):a.value[0]??``),c=t=>{let n=i.value?t:t.slice(0,1),r=[],a=new Set;for(let t of n){let n=e.getValue(t);a.has(n)||(a.add(n),r.push(t))}return r},u=e=>{n.value=c(e)},f=()=>{u([])},g=t=>{n.value=n.value.filter(n=>e.getValue(n)!==t)},_=t=>{if(i.value){let r=e.getValue(t);if(n.value.some(t=>e.getValue(t)===r))return;u([...n.value,t]);return}u([t])},v=t=>{if(i.value){let r=e.getValue(t);if(n.value.some(t=>e.getValue(t)===r)){g(r);return}u([...n.value,t]);return}u([t])},y=t=>{u(x(typeof t==`string`?t:String(t??``)).map(t=>e.mapControlledValue(t)))},b=s({disabled:t.disabled,value:o},{onReset:()=>{f(),e.onReset?.()}}),S=h({error:e.error,helper:e.helper});return r(e.value,e=>{y(e)},{immediate:!0}),e.multiple&&r(e.multiple,()=>y(e.value.value)),{...t,assistive:S,clear:f,field:b,formValue:o,isMultiple:i,isSelected:t=>n.value.some(n=>e.getValue(n)===t),removeValue:g,replaceSelectedItems:u,selectedItems:n,selectedValues:a,selectItem:_,toggleItem:v,triggerValidation:e=>t.triggerValidation(b,e)}},C=e=>{let t=d(``),n=p(e),i=d(!!e.checked.value),a=d(!!e.indeterminate?.value),o=h({error:e.error,helper:e.helper});r(e.checked,e=>{i.value=!!e},{immediate:!0}),e.indeterminate&&r(e.indeterminate,e=>{a.value=!!e},{immediate:!0});let c=s({disabled:n.disabled,toFormValue:e=>e,value:l(()=>i.value?e.value.value??``:null)},{onReset:()=>{i.value=!!e.checked.value,a.value=!!e.indeterminate?.value,e.onReset?.()}});r(e.value,e=>{t.value=String(e??``)},{immediate:!0});let u=t=>({checked:i.value,fieldValue:e.value.value??``,originalEvent:t}),f=t=>{if(!n.disabled.value){if(e.group){a.value=!1,e.group.toggle(e.value.value??``,t),e.onToggle?.(u(t));return}e.clearIndeterminateFirst&&a.value||(i.value=!i.value),a.value=!1,e.onToggle?.(u(t))}};return{...n,assistive:o,checked:i,field:c,indeterminate:a,toggle:f,triggerValidation:e=>n.triggerValidation(c,e),value:t}};export{C as createCheckableStateControl,S as createChoiceFieldControl,y as createTextFieldControl,b as mountTextFieldLifecycle};
2
+ //# sourceMappingURL=field-control.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"field-control.js","names":[],"sources":["../../src/controls/field-control.ts"],"sourcesContent":["import { computed, isSignal, type ReadonlySignal, type Signal, signal } from '@vielzeug/stateit';\n\nimport { spread } from '../directives/spread';\nimport { defineField, type FormFieldHandle } from '../form';\nimport { createId, ref, type Directive } from '../internal';\nimport { effect, handle, onElement, watch } from '../runtime-lifecycle';\nimport {\n createControlState,\n type ControlContextOptions,\n type ControlValidationMode,\n type FormControlValidationTrigger,\n} from './internal/control-state';\n\nexport type { FormControlValidationTrigger } from './internal/control-state';\nexport { createValidationControl } from './internal/control-state';\nexport type { ValidationReporter } from './internal/control-state';\n\n// Discriminated union types for text vs checkable variants\nexport type TextFieldControlContext = {\n disabled?: ReadonlySignal<boolean | undefined>;\n validateOn?: ReadonlySignal<ControlValidationMode>;\n};\n\nexport type TextFieldOptions = Omit<ControlContextOptions, 'disabled' | 'validateOn'> & {\n autocomplete?: ReadonlySignal<string | undefined>;\n context?: TextFieldControlContext;\n disabled?: ReadonlySignal<boolean | undefined>;\n elementRef?: { value: HTMLInputElement | HTMLTextAreaElement | null };\n error?: ReadonlySignal<string | undefined>;\n helper?: ReadonlySignal<string | undefined>;\n inputmode?: ReadonlySignal<string | undefined>;\n label?: ReadonlySignal<string | undefined>;\n labelPlacement?: ReadonlySignal<'inset' | 'outside' | undefined>;\n maxLength?: ReadonlySignal<number | undefined>;\n minLength?: ReadonlySignal<number | undefined>;\n name?: ReadonlySignal<string | undefined>;\n onBlur?: (event: FocusEvent) => void;\n onChange?: (event: Event, value: string) => void;\n onInput?: (event: Event, value: string) => void;\n onInputExtra?: (event: Event) => void;\n onReset?: () => void;\n pattern?: ReadonlySignal<string | undefined>;\n placeholder?: ReadonlySignal<string | undefined>;\n prefix: string;\n readOnly?: ReadonlySignal<boolean | undefined>;\n required?: ReadonlySignal<boolean | undefined>;\n rows?: ReadonlySignal<number | undefined>;\n type?: ReadonlySignal<string | undefined> | (() => string | undefined) | string;\n validateOn?: ReadonlySignal<ControlValidationMode>;\n value: ReadonlySignal<string | undefined>;\n};\n\nexport type ChoiceFieldOptions<T> = {\n context?: TextFieldControlContext;\n disabled?: ReadonlySignal<boolean | undefined>;\n error?: ReadonlySignal<string | undefined>;\n getValue: (item: T) => string;\n helper?: ReadonlySignal<string | undefined>;\n label?: ReadonlySignal<string | undefined>;\n labelPlacement?: ReadonlySignal<'inset' | 'outside' | undefined>;\n mapControlledValue: (value: string) => T;\n multiple?: ReadonlySignal<boolean | undefined>;\n name?: ReadonlySignal<string | undefined>;\n onReset?: () => void;\n prefix: string;\n validateOn?: ReadonlySignal<ControlValidationMode>;\n value: ReadonlySignal<string | undefined>;\n};\n\nexport type CheckableStateOptions = ControlContextOptions & {\n checked: ReadonlySignal<boolean | undefined>;\n clearIndeterminateFirst?: boolean;\n error?: ReadonlySignal<string | undefined>;\n group?: { toggle: (value: string, originalEvent?: Event) => void };\n helper?: ReadonlySignal<string | undefined>;\n indeterminate?: ReadonlySignal<boolean | undefined>;\n label?: ReadonlySignal<string | undefined>;\n labelPlacement?: ReadonlySignal<'inset' | 'outside' | undefined>;\n name?: ReadonlySignal<string | undefined>;\n onReset?: () => void;\n onToggle?: (payload: CheckableChangePayload) => void;\n prefix: string;\n value: ReadonlySignal<string | undefined>;\n};\n\nexport type CheckableChangePayload = {\n checked: boolean;\n fieldValue: string;\n originalEvent?: Event;\n};\n\nexport type FieldControlBaseHandle = {\n disabled: ReadonlySignal<boolean>;\n errorId: string;\n field: FormFieldHandle;\n fieldId: string;\n helperId: string;\n labelInsetId: string;\n labelInsetRef: { value: HTMLLabelElement | null };\n labelOutsideId: string;\n labelOutsideRef: { value: HTMLLabelElement | null };\n triggerValidation: (on: FormControlValidationTrigger) => void;\n validateOn: ReadonlySignal<ControlValidationMode> | undefined;\n};\n\nexport type TextFieldHandle = FieldControlBaseHandle & {\n assistive: ReadonlySignal<AssistiveState>;\n attrs: Directive;\n clear: (event?: Event) => void;\n value: Signal<string>;\n};\n\nexport type AssistiveState = {\n counterAtLimit: boolean;\n counterNearLimit: boolean;\n counterText: string;\n errorText: string;\n hasCounter: boolean;\n hasError: boolean;\n hasHelper: boolean;\n helperText: string;\n hidden: boolean;\n isError: boolean;\n showHelper: boolean;\n text: string;\n};\n\nexport type AssistiveOptions = {\n error?: ReadonlySignal<string | undefined>;\n helper?: ReadonlySignal<string | undefined>;\n maxLength?: ReadonlySignal<number | undefined>;\n value?: ReadonlySignal<string | undefined>;\n};\n\nexport type TextFieldLifecycleOptions = {\n element: HTMLInputElement | HTMLSelectElement | HTMLTextAreaElement;\n onBlur?: (event: FocusEvent) => void;\n onChange?: (event: Event, value: string) => void;\n onInput?: (event: Event, value: string) => void;\n triggerValidation?: (on: FormControlValidationTrigger) => void;\n};\n\nexport type CheckableStateHandle = FieldControlBaseHandle & {\n assistive: ReadonlySignal<AssistiveState>;\n checked: Signal<boolean>;\n indeterminate: Signal<boolean>;\n toggle: (event: Event) => void;\n value: Signal<string>;\n};\n\nexport type ChoiceFieldHandle<T> = FieldControlBaseHandle & {\n assistive: ReadonlySignal<AssistiveState>;\n clear: () => void;\n field: FormFieldHandle;\n formValue: ReadonlySignal<string>;\n isMultiple: ReadonlySignal<boolean>;\n isSelected: (value: string) => boolean;\n removeValue: (value: string) => void;\n replaceSelectedItems: (items: T[]) => void;\n selectedItems: Signal<T[]>;\n selectedValues: ReadonlySignal<string[]>;\n selectItem: (item: T) => void;\n toggleItem: (item: T) => void;\n};\n\ntype ReactiveValue<T> = ReadonlySignal<T> | (() => T) | T;\n\n/**\n * Generates a stable set of ARIA-related IDs for a field control.\n * Snapshot `name` at call time — IDs are stable strings, not reactive.\n */\nconst createFieldIds = (prefix: string, name?: string | null) => {\n const normalizedName = name && name.trim() ? name.trim() : createId().replace(/^cft-/, '');\n const fieldId = `${prefix}-${normalizedName}`;\n const labelInsetId = `label-${fieldId}`;\n\n return {\n errorId: `error-${fieldId}`,\n fieldId,\n helperId: `helper-${fieldId}`,\n labelInsetId,\n labelOutsideId: `${labelInsetId}-outside`,\n };\n};\n\nconst createBaseFieldHandle = (\n options: {\n label?: ReadonlySignal<string | undefined>;\n labelPlacement?: ReadonlySignal<'inset' | 'outside' | undefined>;\n name?: ReadonlySignal<string | undefined>;\n prefix: string;\n } & ControlContextOptions,\n) => {\n const controlState = createControlState(options);\n const ids = createFieldIds(options.prefix, options.name?.value);\n const labelInsetRef = ref<HTMLLabelElement>();\n const labelOutsideRef = ref<HTMLLabelElement>();\n\n const syncLabels = () => {\n const placement = options.labelPlacement?.value ?? 'inset';\n const text = options.label?.value ?? '';\n\n if (labelInsetRef.value) {\n labelInsetRef.value.textContent = text;\n labelInsetRef.value.hidden = !text || placement !== 'inset';\n }\n\n if (labelOutsideRef.value) {\n labelOutsideRef.value.textContent = text;\n labelOutsideRef.value.hidden = !text || placement !== 'outside';\n }\n };\n\n effect(syncLabels);\n\n return {\n disabled: controlState.disabled,\n errorId: ids.errorId,\n fieldId: ids.fieldId,\n helperId: ids.helperId,\n labelInsetId: ids.labelInsetId,\n labelInsetRef,\n labelOutsideId: ids.labelOutsideId,\n labelOutsideRef,\n triggerValidation: (field: FormFieldHandle, on: FormControlValidationTrigger) =>\n controlState.triggerValidation(field, on),\n validateOn: controlState.validateOn,\n };\n};\n\nconst resolveControlContext = (options: {\n context?: TextFieldControlContext;\n disabled?: ReadonlySignal<boolean | undefined>;\n validateOn?: ReadonlySignal<ControlValidationMode>;\n}) => {\n return {\n disabled: computed(() => Boolean(options.disabled?.value) || Boolean(options.context?.disabled?.value)),\n validateOn: options.validateOn ?? options.context?.validateOn,\n };\n};\n\nexport const createAssistiveState = (options: AssistiveOptions) => {\n return computed<AssistiveState>(() => {\n const value = options.value?.value ?? '';\n const errorText = options.error?.value ?? '';\n const helperText = options.helper?.value ?? '';\n const hasError = Boolean(errorText);\n const hasHelper = Boolean(helperText);\n const text = errorText || helperText || '';\n const maxLength = options.maxLength?.value;\n const parsedMaxLength = Number(maxLength);\n const validMaxLength = Number.isFinite(parsedMaxLength) && parsedMaxLength > 0 ? parsedMaxLength : null;\n const hasCounter = validMaxLength !== null;\n const counterText = hasCounter ? `${value.length} / ${validMaxLength}` : '';\n const ratio = hasCounter ? value.length / validMaxLength : 0;\n\n return {\n counterAtLimit: hasCounter ? ratio >= 1 : false,\n counterNearLimit: hasCounter ? ratio >= 0.9 && ratio < 1 : false,\n counterText,\n errorText,\n hasCounter,\n hasError,\n hasHelper,\n helperText,\n hidden: !text,\n isError: hasError,\n showHelper: !hasError && hasHelper,\n text,\n };\n });\n};\n\nconst resolveReactiveValue = <T>(value: ReactiveValue<T> | undefined): T | undefined => {\n if (value === undefined) return undefined;\n\n if (isSignal(value)) return (value as ReadonlySignal<T>).value;\n\n if (typeof value === 'function') return (value as () => T)();\n\n return value;\n};\n\nconst optionalStringSource = (value: ReactiveValue<string | undefined> | undefined): (() => string | undefined) => {\n return () => {\n const next = resolveReactiveValue(value);\n\n if (next == null || next === '') return undefined;\n\n return String(next);\n };\n};\n\nconst optionalNumberSource = (value: ReactiveValue<number | undefined> | undefined): (() => number | undefined) => {\n return () => {\n const next = resolveReactiveValue(value);\n\n if (next == null || Number.isNaN(Number(next)) || Number(next) <= 0) return undefined;\n\n return Number(next);\n };\n};\n\nexport const createTextFieldControl = (options: TextFieldOptions): TextFieldHandle => {\n const value = signal('');\n const controlContext = resolveControlContext(options);\n const base = createBaseFieldHandle({\n ...options,\n ...controlContext,\n });\n\n watch(\n options.value,\n (next) => {\n value.value = String(next ?? '');\n },\n { immediate: true },\n );\n\n const field = defineField(\n {\n disabled: base.disabled,\n value,\n },\n {\n onReset: () => {\n value.value = '';\n options.onReset?.();\n },\n },\n );\n\n const assistive = createAssistiveState({\n error: options.error,\n helper: options.helper,\n maxLength: options.maxLength,\n value,\n });\n\n const clear = (event?: Event): void => {\n event?.preventDefault?.();\n\n value.value = '';\n options.onInput?.(event ?? new Event('input'), '');\n options.onChange?.(event ?? new Event('change'), '');\n base.triggerValidation(field, 'change');\n options.elementRef?.value?.focus();\n };\n\n if (options.elementRef) {\n onElement(options.elementRef, (element) => {\n mountTextFieldLifecycle({\n element,\n onBlur: options.onBlur,\n onChange: options.onChange,\n onInput: (event, nextValue) => {\n options.onInputExtra?.(event);\n options.onInput?.(event, nextValue);\n },\n triggerValidation: (on) => base.triggerValidation(field, on),\n });\n });\n }\n\n const attrs = spread({\n '?required': options.required,\n '.disabled': options.disabled,\n '.readOnly': options.readOnly,\n '.type': options.type,\n '.value': value,\n autocomplete: optionalStringSource(options.autocomplete),\n inputmode: optionalStringSource(options.inputmode),\n maxlength: optionalNumberSource(options.maxLength),\n minlength: optionalNumberSource(options.minLength),\n name: optionalStringSource(options.name),\n pattern: optionalStringSource(options.pattern),\n placeholder: optionalStringSource(options.placeholder),\n rows: optionalNumberSource(options.rows),\n });\n\n return {\n assistive,\n attrs,\n ...base,\n clear,\n field,\n triggerValidation: (on: FormControlValidationTrigger) => base.triggerValidation(field, on),\n value,\n };\n};\n\nexport const mountTextFieldLifecycle = (options: TextFieldLifecycleOptions): void => {\n const { element, onBlur, onChange, onInput, triggerValidation } = options;\n\n if (onInput) {\n handle(element, 'input', (event: Event) => {\n onInput(event, element.value);\n });\n }\n\n handle(element, 'change', (event: Event) => {\n onChange?.(event, element.value);\n triggerValidation?.('change');\n });\n\n handle(element, 'blur', (event: Event) => {\n onBlur?.(event as FocusEvent);\n triggerValidation?.('blur');\n });\n};\n\nconst parseChoiceFieldValues = (value: string | undefined): string[] => {\n if (!value) return [];\n\n return value\n .split(',')\n .map((entry) => entry.trim())\n .filter(Boolean);\n};\n\nexport const createChoiceFieldControl = <T>(options: ChoiceFieldOptions<T>): ChoiceFieldHandle<T> => {\n const controlContext = resolveControlContext(options);\n const base = createBaseFieldHandle({\n ...controlContext,\n label: options.label,\n labelPlacement: options.labelPlacement,\n name: options.name,\n prefix: options.prefix,\n });\n const selectedItems = signal<T[]>([]);\n const isMultiple = computed(() => Boolean(options.multiple?.value));\n const selectedValues = computed(() => selectedItems.value.map((item) => options.getValue(item)));\n const formValue = computed(() =>\n isMultiple.value ? selectedValues.value.join(',') : (selectedValues.value[0] ?? ''),\n );\n\n const normalizeSelectedItems = (items: T[]): T[] => {\n const normalized = isMultiple.value ? items : items.slice(0, 1);\n const uniqueItems: T[] = [];\n const seen = new Set<string>();\n\n for (const item of normalized) {\n const value = options.getValue(item);\n\n if (seen.has(value)) continue;\n\n seen.add(value);\n uniqueItems.push(item);\n }\n\n return uniqueItems;\n };\n\n const replaceSelectedItems = (items: T[]): void => {\n selectedItems.value = normalizeSelectedItems(items);\n };\n\n const clear = (): void => {\n replaceSelectedItems([]);\n };\n\n const removeValue = (value: string): void => {\n selectedItems.value = selectedItems.value.filter((item) => options.getValue(item) !== value);\n };\n\n const selectItem = (item: T): void => {\n if (isMultiple.value) {\n const value = options.getValue(item);\n\n if (selectedItems.value.some((current) => options.getValue(current) === value)) return;\n\n replaceSelectedItems([...selectedItems.value, item]);\n\n return;\n }\n\n replaceSelectedItems([item]);\n };\n\n const toggleItem = (item: T): void => {\n if (isMultiple.value) {\n const value = options.getValue(item);\n\n if (selectedItems.value.some((current) => options.getValue(current) === value)) {\n removeValue(value);\n\n return;\n }\n\n replaceSelectedItems([...selectedItems.value, item]);\n\n return;\n }\n\n replaceSelectedItems([item]);\n };\n\n const syncControlledValue = (nextValue: unknown): void => {\n const values = parseChoiceFieldValues(typeof nextValue === 'string' ? nextValue : String(nextValue ?? ''));\n\n replaceSelectedItems(values.map((value) => options.mapControlledValue(value)));\n };\n\n const field = defineField(\n {\n disabled: base.disabled,\n value: formValue,\n },\n {\n onReset: () => {\n clear();\n options.onReset?.();\n },\n },\n );\n\n const assistive = createAssistiveState({\n error: options.error,\n helper: options.helper,\n });\n\n watch(\n options.value,\n (next) => {\n syncControlledValue(next);\n },\n { immediate: true },\n );\n\n if (options.multiple) {\n watch(options.multiple, () => syncControlledValue(options.value.value));\n }\n\n return {\n ...base,\n assistive,\n clear,\n field,\n formValue,\n isMultiple,\n isSelected: (value: string) => selectedItems.value.some((item) => options.getValue(item) === value),\n removeValue,\n replaceSelectedItems,\n selectedItems,\n selectedValues,\n selectItem,\n toggleItem,\n triggerValidation: (on: FormControlValidationTrigger) => base.triggerValidation(field, on),\n };\n};\n\nexport const createCheckableStateControl = (options: CheckableStateOptions): CheckableStateHandle => {\n const value = signal('');\n const base = createBaseFieldHandle(options);\n const checked = signal(Boolean(options.checked.value));\n const indeterminate = signal(Boolean(options.indeterminate?.value));\n const assistive = createAssistiveState({ error: options.error, helper: options.helper });\n\n watch(\n options.checked,\n (next) => {\n checked.value = Boolean(next);\n },\n { immediate: true },\n );\n\n if (options.indeterminate) {\n watch(\n options.indeterminate,\n (next) => {\n indeterminate.value = Boolean(next);\n },\n { immediate: true },\n );\n }\n\n const field = defineField(\n {\n disabled: base.disabled,\n toFormValue: (next: string | null) => next,\n value: computed(() => (checked.value ? (options.value.value ?? '') : null)),\n },\n {\n onReset: () => {\n checked.value = Boolean(options.checked.value);\n indeterminate.value = Boolean(options.indeterminate?.value);\n options.onReset?.();\n },\n },\n );\n\n watch(\n options.value,\n (next) => {\n value.value = String(next ?? '');\n },\n { immediate: true },\n );\n\n const createPayload = (event: Event): CheckableChangePayload => ({\n checked: checked.value,\n fieldValue: options.value.value ?? '',\n originalEvent: event,\n });\n\n const toggle = (event: Event): void => {\n if (base.disabled.value) return;\n\n if (options.group) {\n indeterminate.value = false;\n options.group.toggle(options.value.value ?? '', event);\n options.onToggle?.(createPayload(event));\n\n return;\n }\n\n if (options.clearIndeterminateFirst && indeterminate.value) {\n indeterminate.value = false;\n } else {\n checked.value = !checked.value;\n indeterminate.value = false;\n }\n\n options.onToggle?.(createPayload(event));\n };\n\n return {\n ...base,\n assistive,\n checked,\n field,\n indeterminate,\n toggle,\n triggerValidation: (on: FormControlValidationTrigger) => base.triggerValidation(field, on),\n value,\n };\n};\n"],"mappings":"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"}
@@ -0,0 +1,10 @@
1
+ export { createCheckableFieldControl, type CheckableFieldControlHandle, type CheckableFieldControlOptions, } from './checkable-control';
2
+ export { createChoiceFieldControl, mountTextFieldLifecycle, createTextFieldControl, createValidationControl, type ChoiceFieldOptions, type TextFieldLifecycleOptions, type CheckableChangePayload, type ValidationReporter, type FormControlValidationTrigger, } from './field-control';
3
+ export { createListControl, type ListControl, type ListNavigationOptions } from './list-control';
4
+ export { createListKeyControl, type ListKeyControl, type ListKeyControlOptions } from './list-key-control';
5
+ export { createPressControl, type PressControl, type PressControlOptions, type PressTrigger } from './press-control';
6
+ export { createA11yControl, type A11yControlConfig, type A11yControlHandle, type A11yTone } from './a11y-control';
7
+ export { createOverlayControl, type OverlayCloseReason, type OverlayControl, type OverlayControlOptions, type OverlayOpenReason, type OverlayCloseDetail, type OverlayOpenDetail, } from './overlay-control';
8
+ export { createSpinnerControl, type SpinnerControl, type SpinnerControlOptions } from './spinner-control';
9
+ export { createSliderControl, type SliderControl, type SliderControlOptions } from './slider-control';
10
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/controls/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,2BAA2B,EAC3B,KAAK,2BAA2B,EAChC,KAAK,4BAA4B,GAClC,MAAM,qBAAqB,CAAC;AAE7B,OAAO,EACL,wBAAwB,EACxB,uBAAuB,EACvB,sBAAsB,EACtB,uBAAuB,EACvB,KAAK,kBAAkB,EACvB,KAAK,yBAAyB,EAC9B,KAAK,sBAAsB,EAC3B,KAAK,kBAAkB,EACvB,KAAK,4BAA4B,GAClC,MAAM,iBAAiB,CAAC;AAEzB,OAAO,EAAE,iBAAiB,EAAE,KAAK,WAAW,EAAE,KAAK,qBAAqB,EAAE,MAAM,gBAAgB,CAAC;AACjG,OAAO,EAAE,oBAAoB,EAAE,KAAK,cAAc,EAAE,KAAK,qBAAqB,EAAE,MAAM,oBAAoB,CAAC;AAC3G,OAAO,EAAE,kBAAkB,EAAE,KAAK,YAAY,EAAE,KAAK,mBAAmB,EAAE,KAAK,YAAY,EAAE,MAAM,iBAAiB,CAAC;AACrH,OAAO,EAAE,iBAAiB,EAAE,KAAK,iBAAiB,EAAE,KAAK,iBAAiB,EAAE,KAAK,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAClH,OAAO,EACL,oBAAoB,EACpB,KAAK,kBAAkB,EACvB,KAAK,cAAc,EACnB,KAAK,qBAAqB,EAC1B,KAAK,iBAAiB,EACtB,KAAK,kBAAkB,EACvB,KAAK,iBAAiB,GACvB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,oBAAoB,EAAE,KAAK,cAAc,EAAE,KAAK,qBAAqB,EAAE,MAAM,mBAAmB,CAAC;AAC1G,OAAO,EAAE,mBAAmB,EAAE,KAAK,aAAa,EAAE,KAAK,oBAAoB,EAAE,MAAM,kBAAkB,CAAC"}
@@ -0,0 +1,2 @@
1
+ let e=require(`@vielzeug/stateit`);var t=(e,t)=>e?.value===t,n=(e,n,r)=>{t(e,r)&&n.reportValidity()},r=t=>{let r=(0,e.computed)(()=>!!t.disabled?.value),i=t.validateOn;return{disabled:r,triggerValidation:(e,t)=>n(i,e,t),validateOn:i}},i=(e,t)=>({triggerValidation:r=>n(e,t,r)});exports.createControlState=r,exports.createValidationControl=i;
2
+ //# sourceMappingURL=control-state.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"control-state.cjs","names":[],"sources":["../../../src/controls/internal/control-state.ts"],"sourcesContent":["import { computed, type ReadonlySignal } from '@vielzeug/stateit';\n\nexport type FormControlValidationTrigger = 'blur' | 'change';\n\nexport type ControlValidationMode = 'blur' | 'change' | 'submit' | undefined;\n\nexport type ValidationReporter = {\n reportValidity: () => void;\n};\n\nexport type ControlContextOptions = {\n disabled?: ReadonlySignal<boolean | undefined>;\n validateOn?: ReadonlySignal<ControlValidationMode>;\n};\n\nconst shouldReportValidity = (\n validateOn: ReadonlySignal<ControlValidationMode> | undefined,\n on: FormControlValidationTrigger,\n): boolean => {\n return validateOn?.value === on;\n};\n\nconst triggerValidationForField = (\n validateOn: ReadonlySignal<ControlValidationMode> | undefined,\n field: ValidationReporter,\n on: FormControlValidationTrigger,\n): void => {\n if (shouldReportValidity(validateOn, on)) field.reportValidity();\n};\n\nexport const createControlState = (options: ControlContextOptions) => {\n const disabled = computed(() => Boolean(options.disabled?.value));\n\n const validateOn = options.validateOn;\n\n return {\n disabled,\n triggerValidation: (field: ValidationReporter, on: FormControlValidationTrigger): void =>\n triggerValidationForField(validateOn, field, on),\n validateOn,\n };\n};\n\nexport const createValidationControl = (\n validateOn: ReadonlySignal<ControlValidationMode> | undefined,\n field: ValidationReporter,\n) => {\n return {\n triggerValidation: (on: FormControlValidationTrigger): void => triggerValidationForField(validateOn, field, on),\n };\n};\n"],"mappings":"mCAeA,IAAM,GACJ,EACA,IAEO,GAAY,QAAU,EAGzB,GACJ,EACA,EACA,IACS,CACL,EAAqB,EAAY,EAAG,EAAE,EAAM,gBAAgB,EAGrD,EAAsB,GAAmC,CACpE,IAAM,GAAA,EAAA,EAAA,cAA0B,EAAQ,EAAQ,UAAU,MAAO,CAE3D,EAAa,EAAQ,WAE3B,MAAO,CACL,WACA,mBAAoB,EAA2B,IAC7C,EAA0B,EAAY,EAAO,EAAG,CAClD,aACD,EAGU,GACX,EACA,KAEO,CACL,kBAAoB,GAA2C,EAA0B,EAAY,EAAO,EAAG,CAChH"}
@@ -0,0 +1,19 @@
1
+ import { type ReadonlySignal } from '@vielzeug/stateit';
2
+ export type FormControlValidationTrigger = 'blur' | 'change';
3
+ export type ControlValidationMode = 'blur' | 'change' | 'submit' | undefined;
4
+ export type ValidationReporter = {
5
+ reportValidity: () => void;
6
+ };
7
+ export type ControlContextOptions = {
8
+ disabled?: ReadonlySignal<boolean | undefined>;
9
+ validateOn?: ReadonlySignal<ControlValidationMode>;
10
+ };
11
+ export declare const createControlState: (options: ControlContextOptions) => {
12
+ disabled: import("@vielzeug/stateit").ComputedSignal<boolean>;
13
+ triggerValidation: (field: ValidationReporter, on: FormControlValidationTrigger) => void;
14
+ validateOn: ReadonlySignal<ControlValidationMode> | undefined;
15
+ };
16
+ export declare const createValidationControl: (validateOn: ReadonlySignal<ControlValidationMode> | undefined, field: ValidationReporter) => {
17
+ triggerValidation: (on: FormControlValidationTrigger) => void;
18
+ };
19
+ //# sourceMappingURL=control-state.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"control-state.d.ts","sourceRoot":"","sources":["../../../src/controls/internal/control-state.ts"],"names":[],"mappings":"AAAA,OAAO,EAAY,KAAK,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAElE,MAAM,MAAM,4BAA4B,GAAG,MAAM,GAAG,QAAQ,CAAC;AAE7D,MAAM,MAAM,qBAAqB,GAAG,MAAM,GAAG,QAAQ,GAAG,QAAQ,GAAG,SAAS,CAAC;AAE7E,MAAM,MAAM,kBAAkB,GAAG;IAC/B,cAAc,EAAE,MAAM,IAAI,CAAC;CAC5B,CAAC;AAEF,MAAM,MAAM,qBAAqB,GAAG;IAClC,QAAQ,CAAC,EAAE,cAAc,CAAC,OAAO,GAAG,SAAS,CAAC,CAAC;IAC/C,UAAU,CAAC,EAAE,cAAc,CAAC,qBAAqB,CAAC,CAAC;CACpD,CAAC;AAiBF,eAAO,MAAM,kBAAkB,GAAI,SAAS,qBAAqB;;+BAOlC,kBAAkB,MAAM,4BAA4B,KAAG,IAAI;;CAIzF,CAAC;AAEF,eAAO,MAAM,uBAAuB,GAClC,YAAY,cAAc,CAAC,qBAAqB,CAAC,GAAG,SAAS,EAC7D,OAAO,kBAAkB;4BAGC,4BAA4B,KAAG,IAAI;CAE9D,CAAC"}
@@ -0,0 +1,2 @@
1
+ import{computed as e}from"@vielzeug/stateit";var t=(e,t)=>e?.value===t,n=(e,n,r)=>{t(e,r)&&n.reportValidity()},r=t=>{let r=e(()=>!!t.disabled?.value),i=t.validateOn;return{disabled:r,triggerValidation:(e,t)=>n(i,e,t),validateOn:i}},i=(e,t)=>({triggerValidation:r=>n(e,t,r)});export{r as createControlState,i as createValidationControl};
2
+ //# sourceMappingURL=control-state.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"control-state.js","names":[],"sources":["../../../src/controls/internal/control-state.ts"],"sourcesContent":["import { computed, type ReadonlySignal } from '@vielzeug/stateit';\n\nexport type FormControlValidationTrigger = 'blur' | 'change';\n\nexport type ControlValidationMode = 'blur' | 'change' | 'submit' | undefined;\n\nexport type ValidationReporter = {\n reportValidity: () => void;\n};\n\nexport type ControlContextOptions = {\n disabled?: ReadonlySignal<boolean | undefined>;\n validateOn?: ReadonlySignal<ControlValidationMode>;\n};\n\nconst shouldReportValidity = (\n validateOn: ReadonlySignal<ControlValidationMode> | undefined,\n on: FormControlValidationTrigger,\n): boolean => {\n return validateOn?.value === on;\n};\n\nconst triggerValidationForField = (\n validateOn: ReadonlySignal<ControlValidationMode> | undefined,\n field: ValidationReporter,\n on: FormControlValidationTrigger,\n): void => {\n if (shouldReportValidity(validateOn, on)) field.reportValidity();\n};\n\nexport const createControlState = (options: ControlContextOptions) => {\n const disabled = computed(() => Boolean(options.disabled?.value));\n\n const validateOn = options.validateOn;\n\n return {\n disabled,\n triggerValidation: (field: ValidationReporter, on: FormControlValidationTrigger): void =>\n triggerValidationForField(validateOn, field, on),\n validateOn,\n };\n};\n\nexport const createValidationControl = (\n validateOn: ReadonlySignal<ControlValidationMode> | undefined,\n field: ValidationReporter,\n) => {\n return {\n triggerValidation: (on: FormControlValidationTrigger): void => triggerValidationForField(validateOn, field, on),\n };\n};\n"],"mappings":"6CAeA,IAAM,GACJ,EACA,IAEO,GAAY,QAAU,EAGzB,GACJ,EACA,EACA,IACS,CACL,EAAqB,EAAY,EAAG,EAAE,EAAM,gBAAgB,EAGrD,EAAsB,GAAmC,CACpE,IAAM,EAAW,MAAe,EAAQ,EAAQ,UAAU,MAAO,CAE3D,EAAa,EAAQ,WAE3B,MAAO,CACL,WACA,mBAAoB,EAA2B,IAC7C,EAA0B,EAAY,EAAO,EAAG,CAClD,aACD,EAGU,GACX,EACA,KAEO,CACL,kBAAoB,GAA2C,EAA0B,EAAY,EAAO,EAAG,CAChH"}
@@ -0,0 +1,2 @@
1
+ var e=(e,t)=>{if(t.disabled?.())return!1;let n=t.keymap[e.key];if(!n)return!1;let r=t.preventDefault??`before`;r===`before`&&e.preventDefault();let i=n(e)!==!1;return r===`after`&&i&&e.preventDefault(),i};exports.dispatchKeyboardAction=e;
2
+ //# sourceMappingURL=keyboard-utils.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"keyboard-utils.cjs","names":[],"sources":["../../../src/controls/internal/keyboard-utils.ts"],"sourcesContent":["export type KeyboardDispatchOptions = {\n disabled?: () => boolean;\n keymap: Record<string, (event: KeyboardEvent) => boolean | void>;\n preventDefault?: 'after' | 'before' | false;\n};\n\nexport const dispatchKeyboardAction = (event: KeyboardEvent, options: KeyboardDispatchOptions): boolean => {\n if (options.disabled?.()) return false;\n\n const action = options.keymap[event.key];\n\n if (!action) return false;\n\n const preventDefaultMode = options.preventDefault ?? 'before';\n\n if (preventDefaultMode === 'before') event.preventDefault();\n\n const handled = action(event) !== false;\n\n if (preventDefaultMode === 'after' && handled) event.preventDefault();\n\n return handled;\n};\n"],"mappings":"AAMA,IAAa,GAA0B,EAAsB,IAA8C,CACzG,GAAI,EAAQ,YAAY,CAAE,MAAO,GAEjC,IAAM,EAAS,EAAQ,OAAO,EAAM,KAEpC,GAAI,CAAC,EAAQ,MAAO,GAEpB,IAAM,EAAqB,EAAQ,gBAAkB,SAEjD,IAAuB,UAAU,EAAM,gBAAgB,CAE3D,IAAM,EAAU,EAAO,EAAM,GAAK,GAIlC,OAFI,IAAuB,SAAW,GAAS,EAAM,gBAAgB,CAE9D"}
@@ -0,0 +1,7 @@
1
+ export type KeyboardDispatchOptions = {
2
+ disabled?: () => boolean;
3
+ keymap: Record<string, (event: KeyboardEvent) => boolean | void>;
4
+ preventDefault?: 'after' | 'before' | false;
5
+ };
6
+ export declare const dispatchKeyboardAction: (event: KeyboardEvent, options: KeyboardDispatchOptions) => boolean;
7
+ //# sourceMappingURL=keyboard-utils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"keyboard-utils.d.ts","sourceRoot":"","sources":["../../../src/controls/internal/keyboard-utils.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,uBAAuB,GAAG;IACpC,QAAQ,CAAC,EAAE,MAAM,OAAO,CAAC;IACzB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,CAAC,KAAK,EAAE,aAAa,KAAK,OAAO,GAAG,IAAI,CAAC,CAAC;IACjE,cAAc,CAAC,EAAE,OAAO,GAAG,QAAQ,GAAG,KAAK,CAAC;CAC7C,CAAC;AAEF,eAAO,MAAM,sBAAsB,GAAI,OAAO,aAAa,EAAE,SAAS,uBAAuB,KAAG,OAgB/F,CAAC"}
@@ -0,0 +1,2 @@
1
+ var e=(e,t)=>{if(t.disabled?.())return!1;let n=t.keymap[e.key];if(!n)return!1;let r=t.preventDefault??`before`;r===`before`&&e.preventDefault();let i=n(e)!==!1;return r===`after`&&i&&e.preventDefault(),i};export{e as dispatchKeyboardAction};
2
+ //# sourceMappingURL=keyboard-utils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"keyboard-utils.js","names":[],"sources":["../../../src/controls/internal/keyboard-utils.ts"],"sourcesContent":["export type KeyboardDispatchOptions = {\n disabled?: () => boolean;\n keymap: Record<string, (event: KeyboardEvent) => boolean | void>;\n preventDefault?: 'after' | 'before' | false;\n};\n\nexport const dispatchKeyboardAction = (event: KeyboardEvent, options: KeyboardDispatchOptions): boolean => {\n if (options.disabled?.()) return false;\n\n const action = options.keymap[event.key];\n\n if (!action) return false;\n\n const preventDefaultMode = options.preventDefault ?? 'before';\n\n if (preventDefaultMode === 'before') event.preventDefault();\n\n const handled = action(event) !== false;\n\n if (preventDefaultMode === 'after' && handled) event.preventDefault();\n\n return handled;\n};\n"],"mappings":"AAMA,IAAa,GAA0B,EAAsB,IAA8C,CACzG,GAAI,EAAQ,YAAY,CAAE,MAAO,GAEjC,IAAM,EAAS,EAAQ,OAAO,EAAM,KAEpC,GAAI,CAAC,EAAQ,MAAO,GAEpB,IAAM,EAAqB,EAAQ,gBAAkB,SAEjD,IAAuB,UAAU,EAAM,gBAAgB,CAE3D,IAAM,EAAU,EAAO,EAAM,GAAK,GAIlC,OAFI,IAAuB,SAAW,GAAS,EAAM,gBAAgB,CAE9D"}
@@ -0,0 +1,2 @@
1
+ var e=e=>{let t=Number(e);return Number.isFinite(t)?t:void 0},t=(t,n)=>e(t)??n,n=(e,n)=>Math.abs(t(e,n))||n,r=(e,t)=>Number.isFinite(e)?e:t,i=(e,t,n)=>t!=null&&e<t?t:n!=null&&e>n?n:e;exports.clampNumber=i,exports.normalizeFinite=r,exports.toFiniteNumber=e,exports.toFiniteNumberOr=t,exports.toPositiveStep=n;
2
+ //# sourceMappingURL=number-utils.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"number-utils.cjs","names":[],"sources":["../../../src/controls/internal/number-utils.ts"],"sourcesContent":["export const toFiniteNumber = (value: unknown): number | undefined => {\n const parsed = Number(value);\n\n return Number.isFinite(parsed) ? parsed : undefined;\n};\n\nexport const toFiniteNumberOr = (value: unknown, fallback: number): number => {\n return toFiniteNumber(value) ?? fallback;\n};\n\nexport const toPositiveStep = (value: unknown, fallback: number): number => {\n return Math.abs(toFiniteNumberOr(value, fallback)) || fallback;\n};\n\nexport const normalizeFinite = (value: number, fallback: number): number => {\n return Number.isFinite(value) ? value : fallback;\n};\n\nexport const clampNumber = (value: number, min?: number, max?: number): number => {\n if (min != null && value < min) return min;\n\n if (max != null && value > max) return max;\n\n return value;\n};\n"],"mappings":"AAAA,IAAa,EAAkB,GAAuC,CACpE,IAAM,EAAS,OAAO,EAAM,CAE5B,OAAO,OAAO,SAAS,EAAO,CAAG,EAAS,IAAA,IAG/B,GAAoB,EAAgB,IACxC,EAAe,EAAM,EAAI,EAGrB,GAAkB,EAAgB,IACtC,KAAK,IAAI,EAAiB,EAAO,EAAS,CAAC,EAAI,EAG3C,GAAmB,EAAe,IACtC,OAAO,SAAS,EAAM,CAAG,EAAQ,EAG7B,GAAe,EAAe,EAAc,IACnD,GAAO,MAAQ,EAAQ,EAAY,EAEnC,GAAO,MAAQ,EAAQ,EAAY,EAEhC"}
@@ -0,0 +1,6 @@
1
+ export declare const toFiniteNumber: (value: unknown) => number | undefined;
2
+ export declare const toFiniteNumberOr: (value: unknown, fallback: number) => number;
3
+ export declare const toPositiveStep: (value: unknown, fallback: number) => number;
4
+ export declare const normalizeFinite: (value: number, fallback: number) => number;
5
+ export declare const clampNumber: (value: number, min?: number, max?: number) => number;
6
+ //# sourceMappingURL=number-utils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"number-utils.d.ts","sourceRoot":"","sources":["../../../src/controls/internal/number-utils.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,cAAc,GAAI,OAAO,OAAO,KAAG,MAAM,GAAG,SAIxD,CAAC;AAEF,eAAO,MAAM,gBAAgB,GAAI,OAAO,OAAO,EAAE,UAAU,MAAM,KAAG,MAEnE,CAAC;AAEF,eAAO,MAAM,cAAc,GAAI,OAAO,OAAO,EAAE,UAAU,MAAM,KAAG,MAEjE,CAAC;AAEF,eAAO,MAAM,eAAe,GAAI,OAAO,MAAM,EAAE,UAAU,MAAM,KAAG,MAEjE,CAAC;AAEF,eAAO,MAAM,WAAW,GAAI,OAAO,MAAM,EAAE,MAAM,MAAM,EAAE,MAAM,MAAM,KAAG,MAMvE,CAAC"}
@@ -0,0 +1,2 @@
1
+ var e=e=>{let t=Number(e);return Number.isFinite(t)?t:void 0},t=(t,n)=>e(t)??n,n=(e,n)=>Math.abs(t(e,n))||n,r=(e,t)=>Number.isFinite(e)?e:t,i=(e,t,n)=>t!=null&&e<t?t:n!=null&&e>n?n:e;export{i as clampNumber,r as normalizeFinite,e as toFiniteNumber,t as toFiniteNumberOr,n as toPositiveStep};
2
+ //# sourceMappingURL=number-utils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"number-utils.js","names":[],"sources":["../../../src/controls/internal/number-utils.ts"],"sourcesContent":["export const toFiniteNumber = (value: unknown): number | undefined => {\n const parsed = Number(value);\n\n return Number.isFinite(parsed) ? parsed : undefined;\n};\n\nexport const toFiniteNumberOr = (value: unknown, fallback: number): number => {\n return toFiniteNumber(value) ?? fallback;\n};\n\nexport const toPositiveStep = (value: unknown, fallback: number): number => {\n return Math.abs(toFiniteNumberOr(value, fallback)) || fallback;\n};\n\nexport const normalizeFinite = (value: number, fallback: number): number => {\n return Number.isFinite(value) ? value : fallback;\n};\n\nexport const clampNumber = (value: number, min?: number, max?: number): number => {\n if (min != null && value < min) return min;\n\n if (max != null && value > max) return max;\n\n return value;\n};\n"],"mappings":"AAAA,IAAa,EAAkB,GAAuC,CACpE,IAAM,EAAS,OAAO,EAAM,CAE5B,OAAO,OAAO,SAAS,EAAO,CAAG,EAAS,IAAA,IAG/B,GAAoB,EAAgB,IACxC,EAAe,EAAM,EAAI,EAGrB,GAAkB,EAAgB,IACtC,KAAK,IAAI,EAAiB,EAAO,EAAS,CAAC,EAAI,EAG3C,GAAmB,EAAe,IACtC,OAAO,SAAS,EAAM,CAAG,EAAQ,EAG7B,GAAe,EAAe,EAAc,IACnD,GAAO,MAAQ,EAAQ,EAAY,EAEnC,GAAO,MAAQ,EAAQ,EAAY,EAEhC"}
@@ -0,0 +1,2 @@
1
+ var e=(e,t,n)=>{for(let r=t;r<e.length;r++)if(n(e[r],r))return r;return-1},t=(e,t,n)=>{for(let r=t;r>=0;r--)if(n(e[r],r))return r;return-1};exports.findBackward=t,exports.findForward=e;
2
+ //# sourceMappingURL=validation-utils.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validation-utils.cjs","names":[],"sources":["../../../src/controls/internal/validation-utils.ts"],"sourcesContent":["/**\n * Shared validation utilities for control factories.\n * Only genuinely useful abstractions - trivial wrappers removed.\n */\n\n/**\n * Find index of first item matching predicate (forward scan).\n */\nexport const findForward = <T>(items: T[], start: number, predicate: (item: T, index: number) => boolean): number => {\n for (let idx = start; idx < items.length; idx++) {\n if (predicate(items[idx], idx)) return idx;\n }\n\n return -1;\n};\n\n/**\n * Find index of first item matching predicate (backward scan).\n */\nexport const findBackward = <T>(items: T[], start: number, predicate: (item: T, index: number) => boolean): number => {\n for (let idx = start; idx >= 0; idx--) {\n if (predicate(items[idx], idx)) return idx;\n }\n\n return -1;\n};\n"],"mappings":"AAQA,IAAa,GAAkB,EAAY,EAAe,IAA2D,CACnH,IAAK,IAAI,EAAM,EAAO,EAAM,EAAM,OAAQ,IACxC,GAAI,EAAU,EAAM,GAAM,EAAI,CAAE,OAAO,EAGzC,MAAO,IAMI,GAAmB,EAAY,EAAe,IAA2D,CACpH,IAAK,IAAI,EAAM,EAAO,GAAO,EAAG,IAC9B,GAAI,EAAU,EAAM,GAAM,EAAI,CAAE,OAAO,EAGzC,MAAO"}
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Shared validation utilities for control factories.
3
+ * Only genuinely useful abstractions - trivial wrappers removed.
4
+ */
5
+ /**
6
+ * Find index of first item matching predicate (forward scan).
7
+ */
8
+ export declare const findForward: <T>(items: T[], start: number, predicate: (item: T, index: number) => boolean) => number;
9
+ /**
10
+ * Find index of first item matching predicate (backward scan).
11
+ */
12
+ export declare const findBackward: <T>(items: T[], start: number, predicate: (item: T, index: number) => boolean) => number;
13
+ //# sourceMappingURL=validation-utils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validation-utils.d.ts","sourceRoot":"","sources":["../../../src/controls/internal/validation-utils.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH;;GAEG;AACH,eAAO,MAAM,WAAW,GAAI,CAAC,EAAE,OAAO,CAAC,EAAE,EAAE,OAAO,MAAM,EAAE,WAAW,CAAC,IAAI,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,KAAK,OAAO,KAAG,MAM1G,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,YAAY,GAAI,CAAC,EAAE,OAAO,CAAC,EAAE,EAAE,OAAO,MAAM,EAAE,WAAW,CAAC,IAAI,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,KAAK,OAAO,KAAG,MAM3G,CAAC"}
@@ -0,0 +1,2 @@
1
+ var e=(e,t,n)=>{for(let r=t;r<e.length;r++)if(n(e[r],r))return r;return-1},t=(e,t,n)=>{for(let r=t;r>=0;r--)if(n(e[r],r))return r;return-1};export{t as findBackward,e as findForward};
2
+ //# sourceMappingURL=validation-utils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validation-utils.js","names":[],"sources":["../../../src/controls/internal/validation-utils.ts"],"sourcesContent":["/**\n * Shared validation utilities for control factories.\n * Only genuinely useful abstractions - trivial wrappers removed.\n */\n\n/**\n * Find index of first item matching predicate (forward scan).\n */\nexport const findForward = <T>(items: T[], start: number, predicate: (item: T, index: number) => boolean): number => {\n for (let idx = start; idx < items.length; idx++) {\n if (predicate(items[idx], idx)) return idx;\n }\n\n return -1;\n};\n\n/**\n * Find index of first item matching predicate (backward scan).\n */\nexport const findBackward = <T>(items: T[], start: number, predicate: (item: T, index: number) => boolean): number => {\n for (let idx = start; idx >= 0; idx--) {\n if (predicate(items[idx], idx)) return idx;\n }\n\n return -1;\n};\n"],"mappings":"AAQA,IAAa,GAAkB,EAAY,EAAe,IAA2D,CACnH,IAAK,IAAI,EAAM,EAAO,EAAM,EAAM,OAAQ,IACxC,GAAI,EAAU,EAAM,GAAM,EAAI,CAAE,OAAO,EAGzC,MAAO,IAMI,GAAmB,EAAY,EAAe,IAA2D,CACpH,IAAK,IAAI,EAAM,EAAO,GAAO,EAAG,IAC9B,GAAI,EAAU,EAAM,GAAM,EAAI,CAAE,OAAO,EAGzC,MAAO"}
@@ -0,0 +1,2 @@
1
+ const e=require(`./internal/validation-utils.cjs`);var t=t=>{let n=(e,n)=>t.isItemDisabled?.(e,n)??e.disabled,r=(e,t)=>({index:Math.max(e,-1),moved:e>=0&&e!==t}),i=(e,n)=>(e>=0&&t.setIndex(e),r(e,n)),a=(t,r,i)=>i===`forward`?e.findForward(t,r,(e,t)=>!n(e,t)):e.findBackward(t,r,(e,t)=>!n(e,t)),o=()=>{let e=t.getItems(),n=t.getIndex();return e.length?i(a(e,0,`forward`),n):r(-1,n)},s=()=>{let e=t.getItems(),n=t.getIndex();return e.length?i(a(e,e.length-1,`backward`),n):r(-1,n)},c=e=>{let n=t.getItems(),o=t.getIndex();if(!n.length)return r(-1,o);let s=a(n,e===`forward`?Math.max(0,o+1):o-1,e);if(s>=0)return i(s,o);if(t.loop){let t=a(n,e===`forward`?0:n.length-1,e);if(t>=0)return i(t,o)}return r(o,o)};return{first:o,getActiveItem:()=>{let e=t.getItems(),n=t.getIndex();return n>=0&&n<e.length?e[n]:void 0},last:s,next:()=>c(`forward`),prev:()=>c(`backward`),reset:()=>{t.setIndex(-1)}}};exports.createListControl=t;
2
+ //# sourceMappingURL=list-control.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"list-control.cjs","names":[],"sources":["../../src/controls/list-control.ts"],"sourcesContent":["import { findBackward, findForward } from './internal/validation-utils';\n\nexport type ListNavigationOptions<T> = {\n getIndex: () => number;\n getItems: () => T[];\n isItemDisabled?: (item: T, index: number) => boolean;\n loop?: boolean;\n setIndex: (index: number) => void;\n};\n\nexport type ListControlResult = {\n index: number;\n moved: boolean;\n};\n\nexport type ListControl<T> = {\n first(): ListControlResult;\n getActiveItem(): T | undefined;\n last(): ListControlResult;\n next(): ListControlResult;\n prev(): ListControlResult;\n reset(): void;\n};\n\nexport const createListControl = <T>(options: ListNavigationOptions<T>): ListControl<T> => {\n const isDisabled = (item: T, index: number): boolean =>\n options.isItemDisabled?.(item, index) ?? (item as any).disabled;\n\n const result = (idx: number, current: number): ListControlResult => {\n return {\n index: Math.max(idx, -1),\n moved: idx >= 0 && idx !== current,\n };\n };\n\n const commitIndex = (idx: number, current: number): ListControlResult => {\n if (idx >= 0) options.setIndex(idx);\n\n return result(idx, current);\n };\n\n const findEnabledIndex = (items: T[], start: number, direction: 'forward' | 'backward'): number => {\n if (direction === 'forward') return findForward(items, start, (item, i) => !isDisabled(item, i));\n\n return findBackward(items, start, (item, i) => !isDisabled(item, i));\n };\n\n const first = (): ListControlResult => {\n const items = options.getItems();\n const current = options.getIndex();\n\n if (!items.length) return result(-1, current);\n\n return commitIndex(findEnabledIndex(items, 0, 'forward'), current);\n };\n\n const last = (): ListControlResult => {\n const items = options.getItems();\n const current = options.getIndex();\n\n if (!items.length) return result(-1, current);\n\n return commitIndex(findEnabledIndex(items, items.length - 1, 'backward'), current);\n };\n\n const move = (direction: 'forward' | 'backward'): ListControlResult => {\n const items = options.getItems();\n const current = options.getIndex();\n\n if (!items.length) return result(-1, current);\n\n const start = direction === 'forward' ? Math.max(0, current + 1) : current - 1;\n const idx = findEnabledIndex(items, start, direction);\n\n if (idx >= 0) return commitIndex(idx, current);\n\n if (options.loop) {\n const wrapStart = direction === 'forward' ? 0 : items.length - 1;\n const wrapped = findEnabledIndex(items, wrapStart, direction);\n\n if (wrapped >= 0) return commitIndex(wrapped, current);\n }\n\n return result(current, current);\n };\n\n const next = (): ListControlResult => move('forward');\n\n const prev = (): ListControlResult => move('backward');\n\n const getActiveItem = (): T | undefined => {\n const items = options.getItems();\n const index = options.getIndex();\n\n return index >= 0 && index < items.length ? items[index] : undefined;\n };\n\n const reset = (): void => {\n options.setIndex(-1);\n };\n\n return {\n first,\n getActiveItem,\n last,\n next,\n prev,\n reset,\n };\n};\n"],"mappings":"mDAwBA,IAAa,EAAwB,GAAsD,CACzF,IAAM,GAAc,EAAS,IAC3B,EAAQ,iBAAiB,EAAM,EAAM,EAAK,EAAa,SAEnD,GAAU,EAAa,KACpB,CACL,MAAO,KAAK,IAAI,EAAK,GAAG,CACxB,MAAO,GAAO,GAAK,IAAQ,EAC5B,EAGG,GAAe,EAAa,KAC5B,GAAO,GAAG,EAAQ,SAAS,EAAI,CAE5B,EAAO,EAAK,EAAQ,EAGvB,GAAoB,EAAY,EAAe,IAC/C,IAAc,UAAkB,EAAA,YAAY,EAAO,GAAQ,EAAM,IAAM,CAAC,EAAW,EAAM,EAAE,CAAC,CAEzF,EAAA,aAAa,EAAO,GAAQ,EAAM,IAAM,CAAC,EAAW,EAAM,EAAE,CAAC,CAGhE,MAAiC,CACrC,IAAM,EAAQ,EAAQ,UAAU,CAC1B,EAAU,EAAQ,UAAU,CAIlC,OAFK,EAAM,OAEJ,EAAY,EAAiB,EAAO,EAAG,UAAU,CAAE,EAAQ,CAFxC,EAAO,GAAI,EAAQ,EAKzC,MAAgC,CACpC,IAAM,EAAQ,EAAQ,UAAU,CAC1B,EAAU,EAAQ,UAAU,CAIlC,OAFK,EAAM,OAEJ,EAAY,EAAiB,EAAO,EAAM,OAAS,EAAG,WAAW,CAAE,EAAQ,CAFxD,EAAO,GAAI,EAAQ,EAKzC,EAAQ,GAAyD,CACrE,IAAM,EAAQ,EAAQ,UAAU,CAC1B,EAAU,EAAQ,UAAU,CAElC,GAAI,CAAC,EAAM,OAAQ,OAAO,EAAO,GAAI,EAAQ,CAG7C,IAAM,EAAM,EAAiB,EADf,IAAc,UAAY,KAAK,IAAI,EAAG,EAAU,EAAE,CAAG,EAAU,EAClC,EAAU,CAErD,GAAI,GAAO,EAAG,OAAO,EAAY,EAAK,EAAQ,CAE9C,GAAI,EAAQ,KAAM,CAEhB,IAAM,EAAU,EAAiB,EADf,IAAc,UAAY,EAAI,EAAM,OAAS,EACZ,EAAU,CAE7D,GAAI,GAAW,EAAG,OAAO,EAAY,EAAS,EAAQ,CAGxD,OAAO,EAAO,EAAS,EAAQ,EAkBjC,MAAO,CACL,QACA,kBAbyC,CACzC,IAAM,EAAQ,EAAQ,UAAU,CAC1B,EAAQ,EAAQ,UAAU,CAEhC,OAAO,GAAS,GAAK,EAAQ,EAAM,OAAS,EAAM,GAAS,IAAA,IAU3D,OACA,SAnBoC,EAAK,UAAU,CAoBnD,SAlBoC,EAAK,WAAW,CAmBpD,UAVwB,CACxB,EAAQ,SAAS,GAAG,EAUrB"}
@@ -0,0 +1,21 @@
1
+ export type ListNavigationOptions<T> = {
2
+ getIndex: () => number;
3
+ getItems: () => T[];
4
+ isItemDisabled?: (item: T, index: number) => boolean;
5
+ loop?: boolean;
6
+ setIndex: (index: number) => void;
7
+ };
8
+ export type ListControlResult = {
9
+ index: number;
10
+ moved: boolean;
11
+ };
12
+ export type ListControl<T> = {
13
+ first(): ListControlResult;
14
+ getActiveItem(): T | undefined;
15
+ last(): ListControlResult;
16
+ next(): ListControlResult;
17
+ prev(): ListControlResult;
18
+ reset(): void;
19
+ };
20
+ export declare const createListControl: <T>(options: ListNavigationOptions<T>) => ListControl<T>;
21
+ //# sourceMappingURL=list-control.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"list-control.d.ts","sourceRoot":"","sources":["../../src/controls/list-control.ts"],"names":[],"mappings":"AAEA,MAAM,MAAM,qBAAqB,CAAC,CAAC,IAAI;IACrC,QAAQ,EAAE,MAAM,MAAM,CAAC;IACvB,QAAQ,EAAE,MAAM,CAAC,EAAE,CAAC;IACpB,cAAc,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC;IACrD,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;CACnC,CAAC;AAEF,MAAM,MAAM,iBAAiB,GAAG;IAC9B,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,OAAO,CAAC;CAChB,CAAC;AAEF,MAAM,MAAM,WAAW,CAAC,CAAC,IAAI;IAC3B,KAAK,IAAI,iBAAiB,CAAC;IAC3B,aAAa,IAAI,CAAC,GAAG,SAAS,CAAC;IAC/B,IAAI,IAAI,iBAAiB,CAAC;IAC1B,IAAI,IAAI,iBAAiB,CAAC;IAC1B,IAAI,IAAI,iBAAiB,CAAC;IAC1B,KAAK,IAAI,IAAI,CAAC;CACf,CAAC;AAEF,eAAO,MAAM,iBAAiB,GAAI,CAAC,EAAE,SAAS,qBAAqB,CAAC,CAAC,CAAC,KAAG,WAAW,CAAC,CAAC,CAqFrF,CAAC"}
@@ -0,0 +1,2 @@
1
+ import{findBackward as e,findForward as t}from"./internal/validation-utils.js";var n=n=>{let r=(e,t)=>n.isItemDisabled?.(e,t)??e.disabled,i=(e,t)=>({index:Math.max(e,-1),moved:e>=0&&e!==t}),a=(e,t)=>(e>=0&&n.setIndex(e),i(e,t)),o=(n,i,a)=>a===`forward`?t(n,i,(e,t)=>!r(e,t)):e(n,i,(e,t)=>!r(e,t)),s=()=>{let e=n.getItems(),t=n.getIndex();return e.length?a(o(e,0,`forward`),t):i(-1,t)},c=()=>{let e=n.getItems(),t=n.getIndex();return e.length?a(o(e,e.length-1,`backward`),t):i(-1,t)},l=e=>{let t=n.getItems(),r=n.getIndex();if(!t.length)return i(-1,r);let s=o(t,e===`forward`?Math.max(0,r+1):r-1,e);if(s>=0)return a(s,r);if(n.loop){let n=o(t,e===`forward`?0:t.length-1,e);if(n>=0)return a(n,r)}return i(r,r)};return{first:s,getActiveItem:()=>{let e=n.getItems(),t=n.getIndex();return t>=0&&t<e.length?e[t]:void 0},last:c,next:()=>l(`forward`),prev:()=>l(`backward`),reset:()=>{n.setIndex(-1)}}};export{n as createListControl};
2
+ //# sourceMappingURL=list-control.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"list-control.js","names":[],"sources":["../../src/controls/list-control.ts"],"sourcesContent":["import { findBackward, findForward } from './internal/validation-utils';\n\nexport type ListNavigationOptions<T> = {\n getIndex: () => number;\n getItems: () => T[];\n isItemDisabled?: (item: T, index: number) => boolean;\n loop?: boolean;\n setIndex: (index: number) => void;\n};\n\nexport type ListControlResult = {\n index: number;\n moved: boolean;\n};\n\nexport type ListControl<T> = {\n first(): ListControlResult;\n getActiveItem(): T | undefined;\n last(): ListControlResult;\n next(): ListControlResult;\n prev(): ListControlResult;\n reset(): void;\n};\n\nexport const createListControl = <T>(options: ListNavigationOptions<T>): ListControl<T> => {\n const isDisabled = (item: T, index: number): boolean =>\n options.isItemDisabled?.(item, index) ?? (item as any).disabled;\n\n const result = (idx: number, current: number): ListControlResult => {\n return {\n index: Math.max(idx, -1),\n moved: idx >= 0 && idx !== current,\n };\n };\n\n const commitIndex = (idx: number, current: number): ListControlResult => {\n if (idx >= 0) options.setIndex(idx);\n\n return result(idx, current);\n };\n\n const findEnabledIndex = (items: T[], start: number, direction: 'forward' | 'backward'): number => {\n if (direction === 'forward') return findForward(items, start, (item, i) => !isDisabled(item, i));\n\n return findBackward(items, start, (item, i) => !isDisabled(item, i));\n };\n\n const first = (): ListControlResult => {\n const items = options.getItems();\n const current = options.getIndex();\n\n if (!items.length) return result(-1, current);\n\n return commitIndex(findEnabledIndex(items, 0, 'forward'), current);\n };\n\n const last = (): ListControlResult => {\n const items = options.getItems();\n const current = options.getIndex();\n\n if (!items.length) return result(-1, current);\n\n return commitIndex(findEnabledIndex(items, items.length - 1, 'backward'), current);\n };\n\n const move = (direction: 'forward' | 'backward'): ListControlResult => {\n const items = options.getItems();\n const current = options.getIndex();\n\n if (!items.length) return result(-1, current);\n\n const start = direction === 'forward' ? Math.max(0, current + 1) : current - 1;\n const idx = findEnabledIndex(items, start, direction);\n\n if (idx >= 0) return commitIndex(idx, current);\n\n if (options.loop) {\n const wrapStart = direction === 'forward' ? 0 : items.length - 1;\n const wrapped = findEnabledIndex(items, wrapStart, direction);\n\n if (wrapped >= 0) return commitIndex(wrapped, current);\n }\n\n return result(current, current);\n };\n\n const next = (): ListControlResult => move('forward');\n\n const prev = (): ListControlResult => move('backward');\n\n const getActiveItem = (): T | undefined => {\n const items = options.getItems();\n const index = options.getIndex();\n\n return index >= 0 && index < items.length ? items[index] : undefined;\n };\n\n const reset = (): void => {\n options.setIndex(-1);\n };\n\n return {\n first,\n getActiveItem,\n last,\n next,\n prev,\n reset,\n };\n};\n"],"mappings":"+EAwBA,IAAa,EAAwB,GAAsD,CACzF,IAAM,GAAc,EAAS,IAC3B,EAAQ,iBAAiB,EAAM,EAAM,EAAK,EAAa,SAEnD,GAAU,EAAa,KACpB,CACL,MAAO,KAAK,IAAI,EAAK,GAAG,CACxB,MAAO,GAAO,GAAK,IAAQ,EAC5B,EAGG,GAAe,EAAa,KAC5B,GAAO,GAAG,EAAQ,SAAS,EAAI,CAE5B,EAAO,EAAK,EAAQ,EAGvB,GAAoB,EAAY,EAAe,IAC/C,IAAc,UAAkB,EAAY,EAAO,GAAQ,EAAM,IAAM,CAAC,EAAW,EAAM,EAAE,CAAC,CAEzF,EAAa,EAAO,GAAQ,EAAM,IAAM,CAAC,EAAW,EAAM,EAAE,CAAC,CAGhE,MAAiC,CACrC,IAAM,EAAQ,EAAQ,UAAU,CAC1B,EAAU,EAAQ,UAAU,CAIlC,OAFK,EAAM,OAEJ,EAAY,EAAiB,EAAO,EAAG,UAAU,CAAE,EAAQ,CAFxC,EAAO,GAAI,EAAQ,EAKzC,MAAgC,CACpC,IAAM,EAAQ,EAAQ,UAAU,CAC1B,EAAU,EAAQ,UAAU,CAIlC,OAFK,EAAM,OAEJ,EAAY,EAAiB,EAAO,EAAM,OAAS,EAAG,WAAW,CAAE,EAAQ,CAFxD,EAAO,GAAI,EAAQ,EAKzC,EAAQ,GAAyD,CACrE,IAAM,EAAQ,EAAQ,UAAU,CAC1B,EAAU,EAAQ,UAAU,CAElC,GAAI,CAAC,EAAM,OAAQ,OAAO,EAAO,GAAI,EAAQ,CAG7C,IAAM,EAAM,EAAiB,EADf,IAAc,UAAY,KAAK,IAAI,EAAG,EAAU,EAAE,CAAG,EAAU,EAClC,EAAU,CAErD,GAAI,GAAO,EAAG,OAAO,EAAY,EAAK,EAAQ,CAE9C,GAAI,EAAQ,KAAM,CAEhB,IAAM,EAAU,EAAiB,EADf,IAAc,UAAY,EAAI,EAAM,OAAS,EACZ,EAAU,CAE7D,GAAI,GAAW,EAAG,OAAO,EAAY,EAAS,EAAQ,CAGxD,OAAO,EAAO,EAAS,EAAQ,EAkBjC,MAAO,CACL,QACA,kBAbyC,CACzC,IAAM,EAAQ,EAAQ,UAAU,CAC1B,EAAQ,EAAQ,UAAU,CAEhC,OAAO,GAAS,GAAK,EAAQ,EAAM,OAAS,EAAM,GAAS,IAAA,IAU3D,OACA,SAnBoC,EAAK,UAAU,CAoBnD,SAlBoC,EAAK,WAAW,CAmBpD,UAVwB,CACxB,EAAQ,SAAS,GAAG,EAUrB"}
@@ -0,0 +1,2 @@
1
+ const e=require(`./internal/keyboard-utils.cjs`);var t={first:[`Home`],last:[`End`],next:[`ArrowDown`],prev:[`ArrowUp`]},n=n=>{let r=()=>!!n.disabled?.(),i=()=>{let e=typeof n.keys==`function`?n.keys():n.keys;return{first:e?.first??t.first,last:e?.last??t.last,next:e?.next??t.next,prev:e?.prev??t.prev}};return{handleKeydown:t=>{let a=i(),o={},s=e=>{for(let t of a[e])o[t]=t=>{let r=n.control[e]();n.onInvoke?.(e,r,t)}};return s(`next`),s(`prev`),s(`first`),s(`last`),e.dispatchKeyboardAction(t,{disabled:r,keymap:o})}}};exports.createListKeyControl=n;
2
+ //# sourceMappingURL=list-key-control.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"list-key-control.cjs","names":[],"sources":["../../src/controls/list-key-control.ts"],"sourcesContent":["import type { ListControl } from './list-control';\n\nimport { dispatchKeyboardAction } from './internal/keyboard-utils';\n\ntype ListKeyAction = 'first' | 'last' | 'next' | 'prev';\n\nexport type ListKeyControlOptions = {\n control: Pick<ListControl<unknown>, ListKeyAction>;\n disabled?: () => boolean;\n keys?: Partial<Record<ListKeyAction, string[]>> | (() => Partial<Record<ListKeyAction, string[]>>);\n onInvoke?: (action: ListKeyAction, result: unknown, event: KeyboardEvent) => void;\n};\n\nexport type ListKeyControl = {\n handleKeydown: (event: KeyboardEvent) => boolean;\n};\n\nconst DEFAULT_KEYS: Record<ListKeyAction, string[]> = {\n first: ['Home'],\n last: ['End'],\n next: ['ArrowDown'],\n prev: ['ArrowUp'],\n};\n\nexport const createListKeyControl = (options: ListKeyControlOptions): ListKeyControl => {\n const isDisabled = (): boolean => Boolean(options.disabled?.());\n const resolveKeys = (): Record<ListKeyAction, string[]> => {\n const keys = typeof options.keys === 'function' ? options.keys() : options.keys;\n\n return {\n first: keys?.first ?? DEFAULT_KEYS.first,\n last: keys?.last ?? DEFAULT_KEYS.last,\n next: keys?.next ?? DEFAULT_KEYS.next,\n prev: keys?.prev ?? DEFAULT_KEYS.prev,\n };\n };\n\n const handleKeydown = (event: KeyboardEvent): boolean => {\n const keys = resolveKeys();\n const keymap: Record<string, (keyboardEvent: KeyboardEvent) => void> = {};\n\n const bindAction = (action: ListKeyAction) => {\n for (const key of keys[action]) {\n keymap[key] = (keyboardEvent: KeyboardEvent) => {\n const result = options.control[action]();\n\n options.onInvoke?.(action, result, keyboardEvent);\n };\n }\n };\n\n bindAction('next');\n bindAction('prev');\n bindAction('first');\n bindAction('last');\n\n return dispatchKeyboardAction(event, {\n disabled: isDisabled,\n keymap,\n });\n };\n\n return {\n handleKeydown,\n };\n};\n"],"mappings":"iDAiBA,IAAM,EAAgD,CACpD,MAAO,CAAC,OAAO,CACf,KAAM,CAAC,MAAM,CACb,KAAM,CAAC,YAAY,CACnB,KAAM,CAAC,UAAU,CAClB,CAEY,EAAwB,GAAmD,CACtF,IAAM,MAA4B,EAAQ,EAAQ,YAAY,CACxD,MAAqD,CACzD,IAAM,EAAO,OAAO,EAAQ,MAAS,WAAa,EAAQ,MAAM,CAAG,EAAQ,KAE3E,MAAO,CACL,MAAO,GAAM,OAAS,EAAa,MACnC,KAAM,GAAM,MAAQ,EAAa,KACjC,KAAM,GAAM,MAAQ,EAAa,KACjC,KAAM,GAAM,MAAQ,EAAa,KAClC,EA4BH,MAAO,CACL,cA1BqB,GAAkC,CACvD,IAAM,EAAO,GAAa,CACpB,EAAiE,EAAE,CAEnE,EAAc,GAA0B,CAC5C,IAAK,IAAM,KAAO,EAAK,GACrB,EAAO,GAAQ,GAAiC,CAC9C,IAAM,EAAS,EAAQ,QAAQ,IAAS,CAExC,EAAQ,WAAW,EAAQ,EAAQ,EAAc,GAUvD,OALA,EAAW,OAAO,CAClB,EAAW,OAAO,CAClB,EAAW,QAAQ,CACnB,EAAW,OAAO,CAEX,EAAA,uBAAuB,EAAO,CACnC,SAAU,EACV,SACD,CAAC,EAKH"}
@@ -0,0 +1,14 @@
1
+ import type { ListControl } from './list-control';
2
+ type ListKeyAction = 'first' | 'last' | 'next' | 'prev';
3
+ export type ListKeyControlOptions = {
4
+ control: Pick<ListControl<unknown>, ListKeyAction>;
5
+ disabled?: () => boolean;
6
+ keys?: Partial<Record<ListKeyAction, string[]>> | (() => Partial<Record<ListKeyAction, string[]>>);
7
+ onInvoke?: (action: ListKeyAction, result: unknown, event: KeyboardEvent) => void;
8
+ };
9
+ export type ListKeyControl = {
10
+ handleKeydown: (event: KeyboardEvent) => boolean;
11
+ };
12
+ export declare const createListKeyControl: (options: ListKeyControlOptions) => ListKeyControl;
13
+ export {};
14
+ //# sourceMappingURL=list-key-control.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"list-key-control.d.ts","sourceRoot":"","sources":["../../src/controls/list-key-control.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAIlD,KAAK,aAAa,GAAG,OAAO,GAAG,MAAM,GAAG,MAAM,GAAG,MAAM,CAAC;AAExD,MAAM,MAAM,qBAAqB,GAAG;IAClC,OAAO,EAAE,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC,EAAE,aAAa,CAAC,CAAC;IACnD,QAAQ,CAAC,EAAE,MAAM,OAAO,CAAC;IACzB,IAAI,CAAC,EAAE,OAAO,CAAC,MAAM,CAAC,aAAa,EAAE,MAAM,EAAE,CAAC,CAAC,GAAG,CAAC,MAAM,OAAO,CAAC,MAAM,CAAC,aAAa,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC;IACnG,QAAQ,CAAC,EAAE,CAAC,MAAM,EAAE,aAAa,EAAE,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,aAAa,KAAK,IAAI,CAAC;CACnF,CAAC;AAEF,MAAM,MAAM,cAAc,GAAG;IAC3B,aAAa,EAAE,CAAC,KAAK,EAAE,aAAa,KAAK,OAAO,CAAC;CAClD,CAAC;AASF,eAAO,MAAM,oBAAoB,GAAI,SAAS,qBAAqB,KAAG,cAyCrE,CAAC"}
@@ -0,0 +1,2 @@
1
+ import{dispatchKeyboardAction as e}from"./internal/keyboard-utils.js";var t={first:[`Home`],last:[`End`],next:[`ArrowDown`],prev:[`ArrowUp`]},n=n=>{let r=()=>!!n.disabled?.(),i=()=>{let e=typeof n.keys==`function`?n.keys():n.keys;return{first:e?.first??t.first,last:e?.last??t.last,next:e?.next??t.next,prev:e?.prev??t.prev}};return{handleKeydown:t=>{let a=i(),o={},s=e=>{for(let t of a[e])o[t]=t=>{let r=n.control[e]();n.onInvoke?.(e,r,t)}};return s(`next`),s(`prev`),s(`first`),s(`last`),e(t,{disabled:r,keymap:o})}}};export{n as createListKeyControl};
2
+ //# sourceMappingURL=list-key-control.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"list-key-control.js","names":[],"sources":["../../src/controls/list-key-control.ts"],"sourcesContent":["import type { ListControl } from './list-control';\n\nimport { dispatchKeyboardAction } from './internal/keyboard-utils';\n\ntype ListKeyAction = 'first' | 'last' | 'next' | 'prev';\n\nexport type ListKeyControlOptions = {\n control: Pick<ListControl<unknown>, ListKeyAction>;\n disabled?: () => boolean;\n keys?: Partial<Record<ListKeyAction, string[]>> | (() => Partial<Record<ListKeyAction, string[]>>);\n onInvoke?: (action: ListKeyAction, result: unknown, event: KeyboardEvent) => void;\n};\n\nexport type ListKeyControl = {\n handleKeydown: (event: KeyboardEvent) => boolean;\n};\n\nconst DEFAULT_KEYS: Record<ListKeyAction, string[]> = {\n first: ['Home'],\n last: ['End'],\n next: ['ArrowDown'],\n prev: ['ArrowUp'],\n};\n\nexport const createListKeyControl = (options: ListKeyControlOptions): ListKeyControl => {\n const isDisabled = (): boolean => Boolean(options.disabled?.());\n const resolveKeys = (): Record<ListKeyAction, string[]> => {\n const keys = typeof options.keys === 'function' ? options.keys() : options.keys;\n\n return {\n first: keys?.first ?? DEFAULT_KEYS.first,\n last: keys?.last ?? DEFAULT_KEYS.last,\n next: keys?.next ?? DEFAULT_KEYS.next,\n prev: keys?.prev ?? DEFAULT_KEYS.prev,\n };\n };\n\n const handleKeydown = (event: KeyboardEvent): boolean => {\n const keys = resolveKeys();\n const keymap: Record<string, (keyboardEvent: KeyboardEvent) => void> = {};\n\n const bindAction = (action: ListKeyAction) => {\n for (const key of keys[action]) {\n keymap[key] = (keyboardEvent: KeyboardEvent) => {\n const result = options.control[action]();\n\n options.onInvoke?.(action, result, keyboardEvent);\n };\n }\n };\n\n bindAction('next');\n bindAction('prev');\n bindAction('first');\n bindAction('last');\n\n return dispatchKeyboardAction(event, {\n disabled: isDisabled,\n keymap,\n });\n };\n\n return {\n handleKeydown,\n };\n};\n"],"mappings":"sEAiBA,IAAM,EAAgD,CACpD,MAAO,CAAC,OAAO,CACf,KAAM,CAAC,MAAM,CACb,KAAM,CAAC,YAAY,CACnB,KAAM,CAAC,UAAU,CAClB,CAEY,EAAwB,GAAmD,CACtF,IAAM,MAA4B,EAAQ,EAAQ,YAAY,CACxD,MAAqD,CACzD,IAAM,EAAO,OAAO,EAAQ,MAAS,WAAa,EAAQ,MAAM,CAAG,EAAQ,KAE3E,MAAO,CACL,MAAO,GAAM,OAAS,EAAa,MACnC,KAAM,GAAM,MAAQ,EAAa,KACjC,KAAM,GAAM,MAAQ,EAAa,KACjC,KAAM,GAAM,MAAQ,EAAa,KAClC,EA4BH,MAAO,CACL,cA1BqB,GAAkC,CACvD,IAAM,EAAO,GAAa,CACpB,EAAiE,EAAE,CAEnE,EAAc,GAA0B,CAC5C,IAAK,IAAM,KAAO,EAAK,GACrB,EAAO,GAAQ,GAAiC,CAC9C,IAAM,EAAS,EAAQ,QAAQ,IAAS,CAExC,EAAQ,WAAW,EAAQ,EAAQ,EAAc,GAUvD,OALA,EAAW,OAAO,CAClB,EAAW,OAAO,CAClB,EAAW,QAAQ,CACnB,EAAW,OAAO,CAEX,EAAuB,EAAO,CACnC,SAAU,EACV,SACD,CAAC,EAKH"}
@@ -0,0 +1,2 @@
1
+ const e=require(`../runtime-lifecycle.cjs`),t=require(`./internal/control-state.cjs`);let n=require(`@vielzeug/stateit`),r=require(`@vielzeug/floatit`);var i=i=>{let a=t.createControlState(i);e.effect(()=>{if(!i.isOpen.value||!i.positioner)return;let e=i.positioner.reference(),t=i.positioner.floating();if(!e||!t){i.positioner.update();return}(0,n.onCleanup)((0,r.autoUpdate)(e,t,()=>i.positioner?.update()))});let o=()=>typeof i.restoreFocus==`function`?i.restoreFocus():i.restoreFocus??!0,s=(e=`programmatic`)=>{a.disabled.value||i.isOpen.value||(i.setOpen(!0,e),requestAnimationFrame(()=>i.positioner?.update()),i.onOpen?.(e))},c=(e=`programmatic`,t)=>{i.isOpen.value&&(i.setOpen(!1,e),(t??o())&&i.elements.trigger?.focus(),i.onClose?.(e))},l=()=>{if(i.isOpen.value){c(`trigger`);return}s(`trigger`)},u=(e,t)=>e?e.contains(t):!1;return{bindOutsideClick:(e=document,t=!0)=>{let n=e=>{if(!i.isOpen.value)return;let t=e.composedPath()[0];t&&(u(i.elements.boundary,t)||u(i.elements.panel,t)||c(`outside-click`))};return e.addEventListener(`click`,n,{capture:t}),()=>e.removeEventListener(`click`,n,{capture:t})},close:c,open:s,toggle:l}};exports.createOverlayControl=i;
2
+ //# sourceMappingURL=overlay-control.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"overlay-control.cjs","names":[],"sources":["../../src/controls/overlay-control.ts"],"sourcesContent":["import { autoUpdate } from '@vielzeug/floatit';\nimport { onCleanup as onSignalCleanup, type ReadonlySignal } from '@vielzeug/stateit';\n\nimport { effect } from '../runtime-lifecycle';\nimport { createControlState, type ControlContextOptions } from './internal/control-state';\n\nexport type OverlayOpenReason = 'programmatic' | 'trigger';\nexport type OverlayCloseReason = 'escape' | 'outside-click' | 'programmatic' | 'trigger';\nexport type OverlayCloseDetail = { reason: OverlayCloseReason };\nexport type OverlayOpenDetail = { reason: OverlayOpenReason };\n\ntype OverlayPositioner = {\n floating: () => HTMLElement | null;\n reference: () => HTMLElement | null;\n update: () => void;\n};\n\nexport type OverlayControlOptions = ControlContextOptions & {\n elements: {\n boundary: HTMLElement;\n panel?: HTMLElement | null;\n trigger?: HTMLElement | null;\n };\n isOpen: ReadonlySignal<boolean>;\n onClose?: (reason: OverlayCloseReason) => void;\n onOpen?: (reason: OverlayOpenReason) => void;\n positioner?: OverlayPositioner;\n restoreFocus?: boolean | (() => boolean);\n setOpen: (next: boolean, reason: OverlayOpenReason | OverlayCloseReason) => void;\n};\n\nexport type OverlayControl = {\n bindOutsideClick(target?: Document | HTMLElement, capture?: boolean): () => void;\n close(reason?: OverlayCloseReason, restoreFocus?: boolean): void;\n open(reason?: OverlayOpenReason): void;\n toggle(): void;\n};\n\nexport const createOverlayControl = (options: OverlayControlOptions): OverlayControl => {\n const controlState = createControlState(options);\n\n // Effect handles positioning lifecycle automatically\n effect(() => {\n if (!options.isOpen.value || !options.positioner) return;\n\n const reference = options.positioner.reference();\n const floating = options.positioner.floating();\n\n if (!reference || !floating) {\n options.positioner.update();\n\n return;\n }\n\n const cleanup = autoUpdate(reference, floating, () => options.positioner?.update());\n\n onSignalCleanup(cleanup); // Auto-cleanup on effect re-run/end\n });\n\n const shouldRestoreFocus = (): boolean => {\n if (typeof options.restoreFocus === 'function') return options.restoreFocus();\n\n return options.restoreFocus ?? true;\n };\n\n const open = (reason: OverlayOpenReason = 'programmatic'): void => {\n if (controlState.disabled.value || options.isOpen.value) return;\n\n options.setOpen(true, reason);\n requestAnimationFrame(() => options.positioner?.update());\n options.onOpen?.(reason);\n };\n\n const close = (reason: OverlayCloseReason = 'programmatic', restoreFocus?: boolean): void => {\n if (!options.isOpen.value) return;\n\n options.setOpen(false, reason);\n\n const restore = restoreFocus ?? shouldRestoreFocus();\n\n if (restore) options.elements.trigger?.focus();\n\n options.onClose?.(reason);\n };\n\n const toggle = (): void => {\n if (options.isOpen.value) {\n close('trigger');\n\n return;\n }\n\n open('trigger');\n };\n\n const isInside = (element: HTMLElement | null | undefined, target: Node): boolean => {\n return element ? element.contains(target) : false;\n };\n\n const bindOutsideClick = (target: Document | HTMLElement = document, capture = true): (() => void) => {\n const handler = (event: Event) => {\n if (!options.isOpen.value) return;\n\n const el = event.composedPath()[0] as Node | null;\n\n if (!el) return;\n\n const inside = isInside(options.elements.boundary, el) || isInside(options.elements.panel, el);\n\n if (!inside) close('outside-click');\n };\n\n target.addEventListener('click', handler, { capture });\n\n return () => target.removeEventListener('click', handler, { capture });\n };\n\n return {\n bindOutsideClick,\n close,\n open,\n toggle,\n };\n};\n"],"mappings":"wJAsCA,IAAa,EAAwB,GAAmD,CACtF,IAAM,EAAe,EAAA,mBAAmB,EAAQ,CAGhD,EAAA,WAAa,CACX,GAAI,CAAC,EAAQ,OAAO,OAAS,CAAC,EAAQ,WAAY,OAElD,IAAM,EAAY,EAAQ,WAAW,WAAW,CAC1C,EAAW,EAAQ,WAAW,UAAU,CAE9C,GAAI,CAAC,GAAa,CAAC,EAAU,CAC3B,EAAQ,WAAW,QAAQ,CAE3B,QAKF,EAAA,EAAA,YAAA,EAAA,EAAA,YAF2B,EAAW,MAAgB,EAAQ,YAAY,QAAQ,CAAC,CAE3D,EACxB,CAEF,IAAM,MACA,OAAO,EAAQ,cAAiB,WAAmB,EAAQ,cAAc,CAEtE,EAAQ,cAAgB,GAG3B,GAAQ,EAA4B,iBAAyB,CAC7D,EAAa,SAAS,OAAS,EAAQ,OAAO,QAElD,EAAQ,QAAQ,GAAM,EAAO,CAC7B,0BAA4B,EAAQ,YAAY,QAAQ,CAAC,CACzD,EAAQ,SAAS,EAAO,GAGpB,GAAS,EAA6B,eAAgB,IAAiC,CACtF,EAAQ,OAAO,QAEpB,EAAQ,QAAQ,GAAO,EAAO,EAEd,GAAgB,GAAoB,GAEvC,EAAQ,SAAS,SAAS,OAAO,CAE9C,EAAQ,UAAU,EAAO,GAGrB,MAAqB,CACzB,GAAI,EAAQ,OAAO,MAAO,CACxB,EAAM,UAAU,CAEhB,OAGF,EAAK,UAAU,EAGX,GAAY,EAAyC,IAClD,EAAU,EAAQ,SAAS,EAAO,CAAG,GAqB9C,MAAO,CACL,kBAnBwB,EAAiC,SAAU,EAAU,KAAuB,CACpG,IAAM,EAAW,GAAiB,CAChC,GAAI,CAAC,EAAQ,OAAO,MAAO,OAE3B,IAAM,EAAK,EAAM,cAAc,CAAC,GAE3B,IAEU,EAAS,EAAQ,SAAS,SAAU,EAAG,EAAI,EAAS,EAAQ,SAAS,MAAO,EAAG,EAEjF,EAAM,gBAAgB,GAKrC,OAFA,EAAO,iBAAiB,QAAS,EAAS,CAAE,UAAS,CAAC,KAEzC,EAAO,oBAAoB,QAAS,EAAS,CAAE,UAAS,CAAC,EAKtE,QACA,OACA,SACD"}