@vielzeug/craftit 2.0.1 → 3.0.1

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 (432) hide show
  1. package/README.md +60 -108
  2. package/dist/controls/a11y-control.cjs +2 -0
  3. package/dist/controls/a11y-control.cjs.map +1 -0
  4. package/dist/controls/a11y-control.d.ts +16 -0
  5. package/dist/controls/a11y-control.d.ts.map +1 -0
  6. package/dist/controls/a11y-control.js +2 -0
  7. package/dist/controls/a11y-control.js.map +1 -0
  8. package/dist/controls/checkable-control.cjs +2 -0
  9. package/dist/controls/checkable-control.cjs.map +1 -0
  10. package/dist/controls/checkable-control.d.ts +15 -0
  11. package/dist/controls/checkable-control.d.ts.map +1 -0
  12. package/dist/controls/checkable-control.js +2 -0
  13. package/dist/controls/checkable-control.js.map +1 -0
  14. package/dist/controls/choice-field-control.cjs +2 -0
  15. package/dist/controls/choice-field-control.cjs.map +1 -0
  16. package/dist/controls/choice-field-control.d.ts +3 -0
  17. package/dist/controls/choice-field-control.d.ts.map +1 -0
  18. package/dist/controls/choice-field-control.js +2 -0
  19. package/dist/controls/choice-field-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 +111 -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 +12 -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 +21 -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 +23 -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/overlay-control.cjs +2 -0
  59. package/dist/controls/overlay-control.cjs.map +1 -0
  60. package/dist/{labs/overlay.d.ts → controls/overlay-control.d.ts} +19 -14
  61. package/dist/controls/overlay-control.d.ts.map +1 -0
  62. package/dist/controls/overlay-control.js +2 -0
  63. package/dist/controls/overlay-control.js.map +1 -0
  64. package/dist/controls/popup-list-control.cjs +2 -0
  65. package/dist/controls/popup-list-control.cjs.map +1 -0
  66. package/dist/controls/popup-list-control.d.ts +160 -0
  67. package/dist/controls/popup-list-control.d.ts.map +1 -0
  68. package/dist/controls/popup-list-control.js +2 -0
  69. package/dist/controls/popup-list-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/swipe-control.cjs +2 -0
  89. package/dist/controls/swipe-control.cjs.map +1 -0
  90. package/dist/controls/swipe-control.d.ts +32 -0
  91. package/dist/controls/swipe-control.d.ts.map +1 -0
  92. package/dist/controls/swipe-control.js +2 -0
  93. package/dist/controls/swipe-control.js.map +1 -0
  94. package/dist/controls/text-field-control.cjs +2 -0
  95. package/dist/controls/text-field-control.cjs.map +1 -0
  96. package/dist/controls/text-field-control.d.ts +3 -0
  97. package/dist/controls/text-field-control.d.ts.map +1 -0
  98. package/dist/controls/text-field-control.js +2 -0
  99. package/dist/controls/text-field-control.js.map +1 -0
  100. package/dist/controls.cjs +1 -0
  101. package/dist/controls.js +1 -0
  102. package/dist/craftit.cjs +1 -1
  103. package/dist/craftit.cjs.map +1 -1
  104. package/dist/craftit.js +1 -1
  105. package/dist/craftit.js.map +1 -1
  106. package/dist/directives/classMap.cjs +2 -0
  107. package/dist/directives/classMap.cjs.map +1 -0
  108. package/dist/directives/classMap.d.ts +19 -0
  109. package/dist/directives/classMap.d.ts.map +1 -0
  110. package/dist/directives/classMap.js +2 -0
  111. package/dist/directives/classMap.js.map +1 -0
  112. package/dist/directives/each.cjs +1 -1
  113. package/dist/directives/each.cjs.map +1 -1
  114. package/dist/directives/each.d.ts +12 -49
  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/guard.cjs +2 -0
  119. package/dist/directives/guard.cjs.map +1 -0
  120. package/dist/directives/guard.d.ts +10 -0
  121. package/dist/directives/guard.d.ts.map +1 -0
  122. package/dist/directives/guard.js +2 -0
  123. package/dist/directives/guard.js.map +1 -0
  124. package/dist/directives/live.cjs +2 -0
  125. package/dist/directives/live.cjs.map +1 -0
  126. package/dist/directives/live.d.ts +23 -0
  127. package/dist/directives/live.d.ts.map +1 -0
  128. package/dist/directives/live.js +2 -0
  129. package/dist/directives/live.js.map +1 -0
  130. package/dist/directives/raw.cjs +1 -1
  131. package/dist/directives/raw.cjs.map +1 -1
  132. package/dist/directives/raw.d.ts +4 -6
  133. package/dist/directives/raw.d.ts.map +1 -1
  134. package/dist/directives/raw.js +1 -1
  135. package/dist/directives/raw.js.map +1 -1
  136. package/dist/directives/resource.cjs +2 -0
  137. package/dist/directives/resource.cjs.map +1 -0
  138. package/dist/directives/resource.d.ts +32 -0
  139. package/dist/directives/resource.d.ts.map +1 -0
  140. package/dist/directives/resource.js +2 -0
  141. package/dist/directives/resource.js.map +1 -0
  142. package/dist/directives/styleMap.cjs +2 -0
  143. package/dist/directives/styleMap.cjs.map +1 -0
  144. package/dist/directives/styleMap.d.ts +11 -0
  145. package/dist/directives/styleMap.d.ts.map +1 -0
  146. package/dist/directives/styleMap.js +2 -0
  147. package/dist/directives/styleMap.js.map +1 -0
  148. package/dist/directives/when.cjs +1 -1
  149. package/dist/directives/when.cjs.map +1 -1
  150. package/dist/directives/when.d.ts +7 -14
  151. package/dist/directives/when.d.ts.map +1 -1
  152. package/dist/directives/when.js +1 -1
  153. package/dist/directives/when.js.map +1 -1
  154. package/dist/errors.cjs +2 -0
  155. package/dist/errors.cjs.map +1 -0
  156. package/dist/errors.d.ts +12 -0
  157. package/dist/errors.d.ts.map +1 -0
  158. package/dist/errors.js +2 -0
  159. package/dist/errors.js.map +1 -0
  160. package/dist/form.cjs +2 -0
  161. package/dist/form.cjs.map +1 -0
  162. package/dist/form.d.ts +15 -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 +78 -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 +16 -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 +111 -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 +5 -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/mutation-observe.cjs +2 -0
  197. package/dist/observers/mutation-observe.cjs.map +1 -0
  198. package/dist/observers/mutation-observe.d.ts +10 -0
  199. package/dist/observers/mutation-observe.d.ts.map +1 -0
  200. package/dist/observers/mutation-observe.js +2 -0
  201. package/dist/observers/mutation-observe.js.map +1 -0
  202. package/dist/observers/resize-observe.cjs +2 -0
  203. package/dist/observers/resize-observe.cjs.map +1 -0
  204. package/dist/observers/resize-observe.d.ts +11 -0
  205. package/dist/observers/resize-observe.d.ts.map +1 -0
  206. package/dist/observers/resize-observe.js +2 -0
  207. package/dist/observers/resize-observe.js.map +1 -0
  208. package/dist/observers.cjs +1 -0
  209. package/dist/observers.js +1 -0
  210. package/dist/props.cjs +2 -0
  211. package/dist/props.cjs.map +1 -0
  212. package/dist/props.d.ts +39 -0
  213. package/dist/props.d.ts.map +1 -0
  214. package/dist/props.js +2 -0
  215. package/dist/props.js.map +1 -0
  216. package/dist/registration.cjs +2 -0
  217. package/dist/registration.cjs.map +1 -0
  218. package/dist/registration.d.ts +38 -0
  219. package/dist/registration.d.ts.map +1 -0
  220. package/dist/registration.js +2 -0
  221. package/dist/registration.js.map +1 -0
  222. package/dist/runtime.cjs +2 -0
  223. package/dist/runtime.cjs.map +1 -0
  224. package/dist/runtime.d.ts +33 -0
  225. package/dist/runtime.d.ts.map +1 -0
  226. package/dist/runtime.js +2 -0
  227. package/dist/runtime.js.map +1 -0
  228. package/dist/template-bindings.cjs +2 -0
  229. package/dist/template-bindings.cjs.map +1 -0
  230. package/dist/template-bindings.d.ts +25 -0
  231. package/dist/template-bindings.d.ts.map +1 -0
  232. package/dist/template-bindings.js +2 -0
  233. package/dist/template-bindings.js.map +1 -0
  234. package/dist/template-compiler.cjs +2 -0
  235. package/dist/template-compiler.cjs.map +1 -0
  236. package/dist/template-compiler.d.ts +4 -0
  237. package/dist/template-compiler.d.ts.map +1 -0
  238. package/dist/template-compiler.js +2 -0
  239. package/dist/template-compiler.js.map +1 -0
  240. package/dist/testing/index.d.ts +2 -0
  241. package/dist/testing/index.d.ts.map +1 -0
  242. package/dist/testing/testing.cjs +2 -0
  243. package/dist/testing/testing.cjs.map +1 -0
  244. package/dist/{test/test.d.ts → testing/testing.d.ts} +18 -11
  245. package/dist/testing/testing.d.ts.map +1 -0
  246. package/dist/testing/testing.js +2 -0
  247. package/dist/testing/testing.js.map +1 -0
  248. package/dist/testing.cjs +1 -0
  249. package/dist/testing.js +1 -0
  250. package/package.json +21 -22
  251. package/dist/core/component.cjs +0 -2
  252. package/dist/core/component.cjs.map +0 -1
  253. package/dist/core/component.d.ts +0 -172
  254. package/dist/core/component.d.ts.map +0 -1
  255. package/dist/core/component.js +0 -2
  256. package/dist/core/component.js.map +0 -1
  257. package/dist/core/host.cjs +0 -2
  258. package/dist/core/host.cjs.map +0 -1
  259. package/dist/core/host.d.ts +0 -77
  260. package/dist/core/host.d.ts.map +0 -1
  261. package/dist/core/host.js +0 -2
  262. package/dist/core/host.js.map +0 -1
  263. package/dist/core/internal.cjs +0 -2
  264. package/dist/core/internal.cjs.map +0 -1
  265. package/dist/core/internal.d.ts +0 -107
  266. package/dist/core/internal.d.ts.map +0 -1
  267. package/dist/core/internal.js +0 -2
  268. package/dist/core/internal.js.map +0 -1
  269. package/dist/core/runtime-bindings.cjs +0 -2
  270. package/dist/core/runtime-bindings.cjs.map +0 -1
  271. package/dist/core/runtime-bindings.d.ts +0 -6
  272. package/dist/core/runtime-bindings.d.ts.map +0 -1
  273. package/dist/core/runtime-bindings.js +0 -2
  274. package/dist/core/runtime-bindings.js.map +0 -1
  275. package/dist/core/runtime-lifecycle.cjs +0 -2
  276. package/dist/core/runtime-lifecycle.cjs.map +0 -1
  277. package/dist/core/runtime-lifecycle.d.ts +0 -116
  278. package/dist/core/runtime-lifecycle.d.ts.map +0 -1
  279. package/dist/core/runtime-lifecycle.js +0 -2
  280. package/dist/core/runtime-lifecycle.js.map +0 -1
  281. package/dist/core/runtime.cjs +0 -1
  282. package/dist/core/runtime.d.ts +0 -3
  283. package/dist/core/runtime.d.ts.map +0 -1
  284. package/dist/core/runtime.js +0 -1
  285. package/dist/core/template-bindings.cjs +0 -2
  286. package/dist/core/template-bindings.cjs.map +0 -1
  287. package/dist/core/template-bindings.d.ts +0 -59
  288. package/dist/core/template-bindings.d.ts.map +0 -1
  289. package/dist/core/template-bindings.js +0 -2
  290. package/dist/core/template-bindings.js.map +0 -1
  291. package/dist/core/template-compiler.cjs +0 -2
  292. package/dist/core/template-compiler.cjs.map +0 -1
  293. package/dist/core/template-compiler.d.ts +0 -25
  294. package/dist/core/template-compiler.d.ts.map +0 -1
  295. package/dist/core/template-compiler.js +0 -2
  296. package/dist/core/template-compiler.js.map +0 -1
  297. package/dist/core/template-dom.cjs +0 -2
  298. package/dist/core/template-dom.cjs.map +0 -1
  299. package/dist/core/template-dom.d.ts +0 -13
  300. package/dist/core/template-dom.d.ts.map +0 -1
  301. package/dist/core/template-dom.js +0 -2
  302. package/dist/core/template-dom.js.map +0 -1
  303. package/dist/core/template-html.cjs +0 -2
  304. package/dist/core/template-html.cjs.map +0 -1
  305. package/dist/core/template-html.d.ts +0 -26
  306. package/dist/core/template-html.d.ts.map +0 -1
  307. package/dist/core/template-html.js +0 -2
  308. package/dist/core/template-html.js.map +0 -1
  309. package/dist/core/template.cjs +0 -2
  310. package/dist/core/template.cjs.map +0 -1
  311. package/dist/core/template.d.ts +0 -11
  312. package/dist/core/template.d.ts.map +0 -1
  313. package/dist/core/template.js +0 -2
  314. package/dist/core/template.js.map +0 -1
  315. package/dist/core/utilities.cjs +0 -2
  316. package/dist/core/utilities.cjs.map +0 -1
  317. package/dist/core/utilities.d.ts +0 -68
  318. package/dist/core/utilities.d.ts.map +0 -1
  319. package/dist/core/utilities.js +0 -2
  320. package/dist/core/utilities.js.map +0 -1
  321. package/dist/directives/attr.cjs +0 -2
  322. package/dist/directives/attr.cjs.map +0 -1
  323. package/dist/directives/attr.d.ts +0 -14
  324. package/dist/directives/attr.d.ts.map +0 -1
  325. package/dist/directives/attr.js +0 -2
  326. package/dist/directives/attr.js.map +0 -1
  327. package/dist/directives/bind.cjs +0 -2
  328. package/dist/directives/bind.cjs.map +0 -1
  329. package/dist/directives/bind.d.ts +0 -30
  330. package/dist/directives/bind.d.ts.map +0 -1
  331. package/dist/directives/bind.js +0 -2
  332. package/dist/directives/bind.js.map +0 -1
  333. package/dist/directives/choose.cjs +0 -2
  334. package/dist/directives/choose.cjs.map +0 -1
  335. package/dist/directives/choose.d.ts +0 -34
  336. package/dist/directives/choose.d.ts.map +0 -1
  337. package/dist/directives/choose.js +0 -2
  338. package/dist/directives/choose.js.map +0 -1
  339. package/dist/directives/classes.cjs +0 -2
  340. package/dist/directives/classes.cjs.map +0 -1
  341. package/dist/directives/classes.d.ts +0 -20
  342. package/dist/directives/classes.d.ts.map +0 -1
  343. package/dist/directives/classes.js +0 -2
  344. package/dist/directives/classes.js.map +0 -1
  345. package/dist/directives/index.cjs +0 -1
  346. package/dist/directives/index.d.ts +0 -14
  347. package/dist/directives/index.d.ts.map +0 -1
  348. package/dist/directives/index.js +0 -1
  349. package/dist/directives/match.cjs +0 -2
  350. package/dist/directives/match.cjs.map +0 -1
  351. package/dist/directives/match.d.ts +0 -31
  352. package/dist/directives/match.d.ts.map +0 -1
  353. package/dist/directives/match.js +0 -2
  354. package/dist/directives/match.js.map +0 -1
  355. package/dist/directives/memo.cjs +0 -2
  356. package/dist/directives/memo.cjs.map +0 -1
  357. package/dist/directives/memo.d.ts +0 -23
  358. package/dist/directives/memo.d.ts.map +0 -1
  359. package/dist/directives/memo.js +0 -2
  360. package/dist/directives/memo.js.map +0 -1
  361. package/dist/directives/on.cjs +0 -2
  362. package/dist/directives/on.cjs.map +0 -1
  363. package/dist/directives/on.d.ts +0 -25
  364. package/dist/directives/on.d.ts.map +0 -1
  365. package/dist/directives/on.js +0 -2
  366. package/dist/directives/on.js.map +0 -1
  367. package/dist/directives/spread.cjs +0 -2
  368. package/dist/directives/spread.cjs.map +0 -1
  369. package/dist/directives/spread.d.ts +0 -14
  370. package/dist/directives/spread.d.ts.map +0 -1
  371. package/dist/directives/spread.js +0 -2
  372. package/dist/directives/spread.js.map +0 -1
  373. package/dist/directives/style.cjs +0 -2
  374. package/dist/directives/style.cjs.map +0 -1
  375. package/dist/directives/style.d.ts +0 -22
  376. package/dist/directives/style.d.ts.map +0 -1
  377. package/dist/directives/style.js +0 -2
  378. package/dist/directives/style.js.map +0 -1
  379. package/dist/directives/until.cjs +0 -2
  380. package/dist/directives/until.cjs.map +0 -1
  381. package/dist/directives/until.d.ts +0 -26
  382. package/dist/directives/until.d.ts.map +0 -1
  383. package/dist/directives/until.js +0 -2
  384. package/dist/directives/until.js.map +0 -1
  385. package/dist/labs/a11y.cjs +0 -2
  386. package/dist/labs/a11y.cjs.map +0 -1
  387. package/dist/labs/a11y.d.ts +0 -61
  388. package/dist/labs/a11y.d.ts.map +0 -1
  389. package/dist/labs/a11y.js +0 -2
  390. package/dist/labs/a11y.js.map +0 -1
  391. package/dist/labs/index.d.ts +0 -8
  392. package/dist/labs/index.d.ts.map +0 -1
  393. package/dist/labs/list.cjs +0 -2
  394. package/dist/labs/list.cjs.map +0 -1
  395. package/dist/labs/list.d.ts +0 -26
  396. package/dist/labs/list.d.ts.map +0 -1
  397. package/dist/labs/list.js +0 -2
  398. package/dist/labs/list.js.map +0 -1
  399. package/dist/labs/observers.cjs +0 -2
  400. package/dist/labs/observers.cjs.map +0 -1
  401. package/dist/labs/observers.d.ts +0 -42
  402. package/dist/labs/observers.d.ts.map +0 -1
  403. package/dist/labs/observers.js +0 -2
  404. package/dist/labs/observers.js.map +0 -1
  405. package/dist/labs/overlay.cjs +0 -2
  406. package/dist/labs/overlay.cjs.map +0 -1
  407. package/dist/labs/overlay.d.ts.map +0 -1
  408. package/dist/labs/overlay.js +0 -2
  409. package/dist/labs/overlay.js.map +0 -1
  410. package/dist/labs/selectable.cjs +0 -2
  411. package/dist/labs/selectable.cjs.map +0 -1
  412. package/dist/labs/selectable.d.ts +0 -70
  413. package/dist/labs/selectable.d.ts.map +0 -1
  414. package/dist/labs/selectable.js +0 -2
  415. package/dist/labs/selectable.js.map +0 -1
  416. package/dist/labs/selection.cjs +0 -2
  417. package/dist/labs/selection.cjs.map +0 -1
  418. package/dist/labs/selection.d.ts +0 -68
  419. package/dist/labs/selection.d.ts.map +0 -1
  420. package/dist/labs/selection.js +0 -2
  421. package/dist/labs/selection.js.map +0 -1
  422. package/dist/labs.cjs +0 -1
  423. package/dist/labs.js +0 -1
  424. package/dist/test/index.d.ts +0 -2
  425. package/dist/test/index.d.ts.map +0 -1
  426. package/dist/test/test.cjs +0 -2
  427. package/dist/test/test.cjs.map +0 -1
  428. package/dist/test/test.d.ts.map +0 -1
  429. package/dist/test/test.js +0 -2
  430. package/dist/test/test.js.map +0 -1
  431. package/dist/test.cjs +0 -1
  432. package/dist/test.js +0 -1
package/README.md CHANGED
@@ -1,10 +1,10 @@
1
1
  # @vielzeug/craftit
2
2
 
3
- > Functional web components with signals, typed props, and template bindings
3
+ > Functional web components with signals, typed props, lifecycle hooks, and headless controls.
4
4
 
5
5
  [![npm version](https://img.shields.io/npm/v/@vielzeug/craftit)](https://www.npmjs.com/package/@vielzeug/craftit) [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
6
6
 
7
- **Craftit** provides a compact API for authoring custom elements with fine-grained reactivity. It builds on `@vielzeug/stateit` (re-exported from the main entry) and adds component lifecycle, templating, typed props, context, slots/emits, form-associated helpers, and observer utilities.
7
+ Craftit is Vielzeug's custom-element authoring library built on `@vielzeug/stateit`.
8
8
 
9
9
  ## Installation
10
10
 
@@ -17,144 +17,96 @@ pnpm add @vielzeug/craftit
17
17
  ## Quick Start
18
18
 
19
19
  ```ts
20
- import { defineComponent, signal, computed, html } from '@vielzeug/craftit';
20
+ import { computed, css, define, html, prop, signal } from '@vielzeug/craftit';
21
21
 
22
- defineComponent({
23
- setup() {
22
+ define('my-counter', {
23
+ props: {
24
+ label: prop.string('Count'),
25
+ step: prop.number(1),
26
+ },
27
+ setup(props, { host }) {
24
28
  const count = signal(0);
25
29
  const doubled = computed(() => count.value * 2);
26
30
 
27
- return html`
28
- <button @click=${() => count.value++}>Count: ${count}</button>
31
+ host.class({ 'is-positive': () => count.value > 0 });
32
+
33
+ return () => html`
34
+ <button @click=${() => (count.value += props.step.value)}>
35
+ ${props.label}: ${count}
36
+ </button>
29
37
  <p>Doubled: ${doubled}</p>
30
38
  `;
31
39
  },
32
- tag: 'my-counter',
40
+ styles: [
41
+ css`
42
+ :host {
43
+ display: inline-grid;
44
+ gap: 0.5rem;
45
+ }
46
+ `,
47
+ ],
33
48
  });
34
49
  ```
35
50
 
36
- ## Features
37
-
38
- - ✅ **Component authoring** — `defineComponent({ tag, props, setup, ... })`
39
- - ✅ **Signals included** — all `@vielzeug/stateit` exports are re-exported
40
- - ✅ **Reactive templates** — `html` tagged template with text/attr/prop/event/ref bindings
41
- - ✅ **Lifecycle helpers** — `onMount`, `onCleanup`, `onError`, `handle`, `watch`, `effect`, `fire.*`
42
- - ✅ **Typed component APIs** — `defineComponent`, `prop`, `typed`, setup-context `emit` and `slots`
43
- - ✅ **Context / DI** — `createContext`, `provide`, `inject`, `syncContextProps`
44
- - ✅ **Form-associated controls** — `defineField` with `ElementInternals`
45
- - ✅ **Observer utilities** — `observeResize` (main API) + `observeIntersection` / `observeMedia` (`/labs`)
46
- - ✅ **Directive subpath** — `@vielzeug/craftit/directives`
47
- - ✅ **Test subpath** — `@vielzeug/craftit/test`
48
-
49
- ## Entry Points
50
-
51
- | Entry | Purpose |
52
- |---|---|
53
- | `@vielzeug/craftit` | Main API (components + stateit re-exports) |
54
- | `@vielzeug/craftit/directives` | Directive helpers like `each`, `when`, `bind`, `match`, `until` |
55
- | `@vielzeug/craftit/test` | Mount/query/event testing utilities |
56
-
57
- ## Usage Highlights
58
-
59
- ### Typed props + emits
60
-
61
- ```ts
62
- import { defineComponent, html } from '@vielzeug/craftit';
63
-
64
- defineComponent<
65
- { disabled: boolean; label: string },
66
- { change: string }
67
- >({
68
- props: {
69
- disabled: { default: false },
70
- label: { default: 'Name' },
71
- },
72
- setup({ emit, props }) {
73
- return html`
74
- <label>${props.label}</label>
75
- <input
76
- :disabled=${props.disabled}
77
- @input=${(e: Event) => emit('change', (e.target as HTMLInputElement).value)}
78
- />
79
- `;
80
- },
81
- tag: 'name-input',
82
- });
83
- ```
51
+ ## Authoring Model
84
52
 
85
- ### Directives subpath
53
+ - `setup(props, ctx)` returns a template function: `() => html\`...\``
54
+ - Use `onMounted()` for post-mount DOM initialization
55
+ - Use `onCleanup()` for teardown
56
+ - Use `onElement(ref, cb)` for ref-driven effects
86
57
 
87
58
  ```ts
88
- import { defineComponent, signal, html } from '@vielzeug/craftit';
89
- import { each, when } from '@vielzeug/craftit/directives';
59
+ import { define, html, onCleanup, onMounted, signal } from '@vielzeug/craftit';
90
60
 
91
- defineComponent({
61
+ define('auto-save-field', {
92
62
  setup() {
93
- const todos = signal([{ id: 1, text: 'Write docs', done: false }]);
94
-
95
- return html`
96
- ${when(
97
- () => todos.value.length > 0,
98
- () => html`<ul>${each(todos, (todo) => html`<li>${todo.text}</li>`, () => html``, { key: (t) => t.id })}</ul>`,
99
- () => html`<p>No todos</p>`,
100
- )}
101
- `;
102
- },
103
- tag: 'todo-list',
104
- });
105
- ```
106
-
107
- ### Form-associated field
63
+ const value = signal('');
108
64
 
109
- ```ts
110
- import { defineComponent, defineField, signal, html } from '@vielzeug/craftit';
65
+ onMounted(() => {
66
+ console.log('ready for DOM interactions');
67
+ });
111
68
 
112
- defineComponent({
113
- formAssociated: true,
114
- setup() {
115
- const value = signal('');
116
- const field = defineField({ value });
69
+ onCleanup(() => {
70
+ console.log('saving', value.value);
71
+ });
117
72
 
118
- return html`
119
- <input
120
- type="email"
121
- :value=${value}
73
+ return () => html`
74
+ <textarea
122
75
  @input=${(e: Event) => {
123
- value.value = (e.target as HTMLInputElement).value;
124
- field.setCustomValidity(value.value.includes('@') ? '' : 'Invalid email');
76
+ value.value = (e.target as HTMLTextAreaElement).value;
125
77
  }}
126
- />
78
+ ></textarea>
127
79
  `;
128
80
  },
129
- tag: 'email-field',
130
81
  });
131
82
  ```
132
83
 
84
+ ## Features
85
+
86
+ - Signals included: `signal`, `computed`, `watch`, `batch`, `untrack`, `scope`, and related primitives from `@vielzeug/stateit`
87
+ - Component authoring: `define(tag, { props, setup, styles, formAssociated })`
88
+ - Props: `prop.*` helpers and raw `PropDef` objects; shared bundles can type against `PropsDef<...>`
89
+ - Lifecycle hooks: `onMounted`, `onCleanup`, `onElement`, `effect`, `handle` (auto-cleans inside setup/scope; returns manual cleanup outside it)
90
+ - Directives: `each`, `classMap`, `styleMap`, `guard`, `when`, `live`, `until`, `raw`
91
+ - Host/slot APIs: `host.bind`, `syncAria`, `slots.has`, `slots.elements`
92
+ - Form-associated elements: `defineField()`
93
+ - Published subpaths: `@vielzeug/craftit/controls`, `@vielzeug/craftit/observers`, `@vielzeug/craftit/testing`
94
+
133
95
  ## API Summary
134
96
 
135
- | Group | Main exports |
136
- |---|---|
137
- | Components | `defineComponent`, `DefineComponentOptions`, `DefineComponentSetupContext`, `BuildPropSchema` |
138
- | Runtime | `onMount`, `onCleanup`, `onError`, `handle`, `aria`, `effect`, `watch`, `fire` |
139
- | Props | `prop`, `typed`, `PropOptions`, `PropDef`, `InferPropsSignals` |
140
- | Slots / emits | setup-context `slots`, setup-context `emit`, `onSlotChange`, `Slots`, `EmitFn` |
141
- | Context | `createContext`, `provide`, `inject`, `syncContextProps`, `InjectionKey` |
142
- | Form | `defineField`, `FormFieldOptions`, `FormFieldCallbacks`, `FormFieldHandle` |
143
- | Observers | `observeResize`, `observeIntersection`, `observeMedia` |
144
- | Utilities | `html`, `css`, `createId`, `createFormIds`, `guard`, `escapeHtml`, `toKebab` |
145
- | Re-exported from stateit | `signal`, `computed`, `batch`, `untrack`, `readonly`, and more |
97
+ | Area | Exports |
98
+ | --- | --- |
99
+ | Component authoring | `define`, `prop`, `type ComponentDefinition`, `type SetupContextBag`, `type PropsDef`, `type PropDef` |
100
+ | Runtime | `onMounted`, `effect`, `handle`, `onCleanup`, `onElement` |
101
+ | Templates and directives | `html`, `css`, `each`, `classMap`, `styleMap`, `guard`, `when`, `live`, `until`, `raw` |
102
+ | Element references | `ref`, `refs`, `createId` |
103
+ | Context and slots | `createContext`, `provide`, `inject`, `injectStrict`, `syncAria` |
104
+ | Form | `defineField`, `type FormFieldOptions`, `type FormFieldHandle` |
146
105
 
147
106
  ## Documentation
148
107
 
149
108
  Full docs at **[vielzeug.dev/craftit](https://vielzeug.dev/craftit)**
150
109
 
151
- | | |
152
- |---|---|
153
- | [Overview](https://vielzeug.dev/craftit/) | Install and architecture overview |
154
- | [Usage Guide](https://vielzeug.dev/craftit/usage) | Practical patterns and subpath usage |
155
- | [API Reference](https://vielzeug.dev/craftit/api) | Complete signatures and types |
156
- | [Examples](https://vielzeug.dev/craftit/examples) | End-to-end component examples |
157
-
158
110
  ## License
159
111
 
160
112
  MIT © [Helmuth Saatkamp](https://github.com/helmuthdu) — Part of the [Vielzeug](https://github.com/helmuthdu/vielzeug) monorepo.
@@ -0,0 +1,2 @@
1
+ const e=require(`../runtime.cjs`),t=require(`../internal.cjs`);var n=e=>{let t=e.querySelector(`slot`);return t instanceof HTMLSlotElement?t.assignedNodes({flatten:!0}).some(e=>(e.textContent?.trim().length??0)>0):(e.textContent?.trim().length??0)>0};function r(r){let i=e.currentElementOrThrow(),a=r.labelId||t.createId(`a11y-label`),o=r.helperId||t.createId(`a11y-helper`),s=(e,t,n)=>{e.getAttribute(t)!==n&&e.setAttribute(t,n)},c=(e,t)=>{e.textContent!==t&&(e.textContent=t)};s(i,`role`,r.role);let l=null,u=null,d=new Map,f=(e,t)=>{let n=new Set;for(let r of[e,t])if(r)for(let e of Array.from(r.querySelectorAll(`slot`)))e instanceof HTMLSlotElement&&n.add(e);for(let[e,t]of d)n.has(e)||(t(),d.delete(e));for(let e of n){if(d.has(e))continue;let t=()=>p();e.addEventListener(`slotchange`,t),d.set(e,()=>e.removeEventListener(`slotchange`,t))}},p=()=>{if(!i.shadowRoot)return;let e=l,t=u;f(e,t);let d=r.checked?.(),p=r.invalid?.(),m=r.helperText?.();e?(e.id!==a&&(e.id=a),n(e)?s(i,`aria-labelledby`,a):i.removeAttribute(`aria-labelledby`)):i.removeAttribute(`aria-labelledby`),t?(t.id!==o&&(t.id=o),m?(c(t,m),t.hidden&&=!1,s(i,`aria-describedby`,o),(r.helperTone?.()??`default`)===`error`?s(t,`role`,`alert`):t.removeAttribute(`role`)):(c(t,``),t.hidden||=!0,t.removeAttribute(`role`),i.removeAttribute(`aria-describedby`))):i.removeAttribute(`aria-describedby`),d===void 0?i.removeAttribute(`aria-checked`):s(i,`aria-checked`,d),p===void 0?i.removeAttribute(`aria-invalid`):s(i,`aria-invalid`,String(p))};return e.effect(()=>{p()}),e.onMounted(()=>{l=i.shadowRoot?.querySelector(`[data-a11y-label]`)??null,u=i.shadowRoot?.querySelector(`[data-a11y-helper]`)??null,p()}),e.onCleanup(()=>{for(let e of d.values())e();d.clear()}),{helperId:o,labelId:a}}exports.createA11yControl=r;
2
+ //# sourceMappingURL=a11y-control.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"a11y-control.cjs","names":[],"sources":["../../src/controls/a11y-control.ts"],"sourcesContent":["import { createId } from '../internal';\nimport { currentElementOrThrow, effect, onCleanup, onMounted } from '../runtime';\n\nexport type A11yTone = 'default' | 'error';\n\nexport type A11yControlConfig = {\n checked?: () => 'true' | 'false' | 'mixed' | undefined;\n helperId?: string;\n helperText?: () => string | undefined;\n helperTone?: () => A11yTone;\n invalid?: () => boolean;\n labelId?: string;\n role: string;\n};\n\nexport type A11yControlHandle = {\n helperId: string;\n labelId: string;\n};\n\nconst hasLabelContent = (labelElement: HTMLElement): boolean => {\n const slot = labelElement.querySelector('slot');\n\n if (slot instanceof HTMLSlotElement) {\n return slot.assignedNodes({ flatten: true }).some((node) => (node.textContent?.trim().length ?? 0) > 0);\n }\n\n return (labelElement.textContent?.trim().length ?? 0) > 0;\n};\n\nexport function createA11yControl(config: A11yControlConfig): A11yControlHandle {\n const host = currentElementOrThrow();\n const labelId = config.labelId || createId('a11y-label');\n const helperId = config.helperId || createId('a11y-helper');\n\n const setAttr = (element: Element, name: string, value: string): void => {\n if (element.getAttribute(name) !== value) element.setAttribute(name, value);\n };\n\n const setText = (element: Node, value: string): void => {\n if (element.textContent !== value) element.textContent = value;\n };\n\n setAttr(host, 'role', config.role);\n\n let labelEl: HTMLElement | null = null;\n let helperEl: HTMLDivElement | null = null;\n\n const slotCleanupByElement = new Map<HTMLSlotElement, () => void>();\n\n const syncSlotListeners = (labelElement: HTMLElement | null, helperElement: HTMLDivElement | null): void => {\n const nextSlots = new Set<HTMLSlotElement>();\n\n for (const container of [labelElement, helperElement]) {\n if (!container) continue;\n\n for (const slot of Array.from(container.querySelectorAll('slot'))) {\n if (slot instanceof HTMLSlotElement) nextSlots.add(slot);\n }\n }\n\n for (const [slot, cleanup] of slotCleanupByElement) {\n if (nextSlots.has(slot)) continue;\n\n cleanup();\n slotCleanupByElement.delete(slot);\n }\n\n for (const slot of nextSlots) {\n if (slotCleanupByElement.has(slot)) continue;\n\n const slotHandler = () => sync();\n\n slot.addEventListener('slotchange', slotHandler);\n slotCleanupByElement.set(slot, () => slot.removeEventListener('slotchange', slotHandler));\n }\n };\n\n const sync = (): void => {\n const shadow = host.shadowRoot;\n\n if (!shadow) return;\n\n const labelElement = labelEl;\n const helperElement = helperEl;\n\n syncSlotListeners(labelElement, helperElement);\n\n const checked = config.checked?.();\n const invalid = config.invalid?.();\n const helperText = config.helperText?.();\n\n // Sync label\n if (labelElement) {\n if (labelElement.id !== labelId) labelElement.id = labelId;\n\n if (hasLabelContent(labelElement)) setAttr(host, 'aria-labelledby', labelId);\n else host.removeAttribute('aria-labelledby');\n } else {\n host.removeAttribute('aria-labelledby');\n }\n\n // Sync helper\n if (helperElement) {\n if (helperElement.id !== helperId) helperElement.id = helperId;\n\n if (helperText) {\n setText(helperElement, helperText);\n\n if (helperElement.hidden) helperElement.hidden = false;\n\n setAttr(host, 'aria-describedby', helperId);\n\n if ((config.helperTone?.() ?? 'default') === 'error') setAttr(helperElement, 'role', 'alert');\n else helperElement.removeAttribute('role');\n } else {\n setText(helperElement, '');\n\n if (!helperElement.hidden) helperElement.hidden = true;\n\n helperElement.removeAttribute('role');\n host.removeAttribute('aria-describedby');\n }\n } else {\n host.removeAttribute('aria-describedby');\n }\n\n // Sync checked\n if (checked === undefined) host.removeAttribute('aria-checked');\n else setAttr(host, 'aria-checked', checked);\n\n // Sync invalid\n if (invalid === undefined) host.removeAttribute('aria-invalid');\n else setAttr(host, 'aria-invalid', String(invalid));\n };\n\n // Keep ARIA in sync with reactive config changes.\n effect(() => {\n sync();\n });\n\n // Query shadow DOM refs once after first render, then sync.\n onMounted(() => {\n labelEl = (host.shadowRoot?.querySelector('[data-a11y-label]') ?? null) as HTMLElement | null;\n helperEl = (host.shadowRoot?.querySelector('[data-a11y-helper]') ?? null) as HTMLDivElement | null;\n sync();\n });\n\n onCleanup(() => {\n for (const cleanup of slotCleanupByElement.values()) cleanup();\n slotCleanupByElement.clear();\n });\n\n return { helperId, labelId };\n}\n"],"mappings":"+DAoBA,IAAM,EAAmB,GAAuC,CAC9D,IAAM,EAAO,EAAa,cAAc,MAAM,EAM9C,OAJI,aAAgB,gBACX,EAAK,cAAc,CAAE,QAAS,EAAK,CAAC,EAAE,KAAM,IAAU,EAAK,aAAa,KAAK,EAAE,QAAU,GAAK,CAAC,GAGhG,EAAa,aAAa,KAAK,EAAE,QAAU,GAAK,CAC1D,EAEA,SAAgB,EAAkB,EAA8C,CAC9E,IAAM,EAAO,EAAA,sBAAsB,EAC7B,EAAU,EAAO,SAAW,EAAA,SAAS,YAAY,EACjD,EAAW,EAAO,UAAY,EAAA,SAAS,aAAa,EAEpD,GAAW,EAAkB,EAAc,IAAwB,CACnE,EAAQ,aAAa,CAAI,IAAM,GAAO,EAAQ,aAAa,EAAM,CAAK,CAC5E,EAEM,GAAW,EAAe,IAAwB,CAClD,EAAQ,cAAgB,IAAO,EAAQ,YAAc,EAC3D,EAEA,EAAQ,EAAM,OAAQ,EAAO,IAAI,EAEjC,IAAI,EAA8B,KAC9B,EAAkC,KAEhC,EAAuB,IAAI,IAE3B,GAAqB,EAAkC,IAA+C,CAC1G,IAAM,EAAY,IAAI,IAEtB,IAAK,IAAM,IAAa,CAAC,EAAc,CAAa,EAC7C,KAEL,IAAK,IAAM,KAAQ,MAAM,KAAK,EAAU,iBAAiB,MAAM,CAAC,EAC1D,aAAgB,iBAAiB,EAAU,IAAI,CAAI,EAI3D,IAAK,GAAM,CAAC,EAAM,KAAY,EACxB,EAAU,IAAI,CAAI,IAEtB,EAAQ,EACR,EAAqB,OAAO,CAAI,GAGlC,IAAK,IAAM,KAAQ,EAAW,CAC5B,GAAI,EAAqB,IAAI,CAAI,EAAG,SAEpC,IAAM,MAAoB,EAAK,EAE/B,EAAK,iBAAiB,aAAc,CAAW,EAC/C,EAAqB,IAAI,MAAY,EAAK,oBAAoB,aAAc,CAAW,CAAC,CAC1F,CACF,EAEM,MAAmB,CAGvB,GAAI,CAFW,EAAK,WAEP,OAEb,IAAM,EAAe,EACf,EAAgB,EAEtB,EAAkB,EAAc,CAAa,EAE7C,IAAM,EAAU,EAAO,UAAU,EAC3B,EAAU,EAAO,UAAU,EAC3B,EAAa,EAAO,aAAa,EAGnC,GACE,EAAa,KAAO,IAAS,EAAa,GAAK,GAE/C,EAAgB,CAAY,EAAG,EAAQ,EAAM,kBAAmB,CAAO,EACtE,EAAK,gBAAgB,iBAAiB,GAE3C,EAAK,gBAAgB,iBAAiB,EAIpC,GACE,EAAc,KAAO,IAAU,EAAc,GAAK,GAElD,GACF,EAAQ,EAAe,CAAU,EAEjC,AAA0B,EAAc,SAAS,GAEjD,EAAQ,EAAM,mBAAoB,CAAQ,GAErC,EAAO,aAAa,GAAK,aAAe,QAAS,EAAQ,EAAe,OAAQ,OAAO,EACvF,EAAc,gBAAgB,MAAM,IAEzC,EAAQ,EAAe,EAAE,EAEzB,AAA2B,EAAc,SAAS,GAElD,EAAc,gBAAgB,MAAM,EACpC,EAAK,gBAAgB,kBAAkB,IAGzC,EAAK,gBAAgB,kBAAkB,EAIrC,IAAY,IAAA,GAAW,EAAK,gBAAgB,cAAc,EACzD,EAAQ,EAAM,eAAgB,CAAO,EAGtC,IAAY,IAAA,GAAW,EAAK,gBAAgB,cAAc,EACzD,EAAQ,EAAM,eAAgB,OAAO,CAAO,CAAC,CACpD,EAmBA,OAhBA,EAAA,WAAa,CACX,EAAK,CACP,CAAC,EAGD,EAAA,cAAgB,CACd,EAAW,EAAK,YAAY,cAAc,mBAAmB,GAAK,KAClE,EAAY,EAAK,YAAY,cAAc,oBAAoB,GAAK,KACpE,EAAK,CACP,CAAC,EAED,EAAA,cAAgB,CACd,IAAK,IAAM,KAAW,EAAqB,OAAO,EAAG,EAAQ,EAC7D,EAAqB,MAAM,CAC7B,CAAC,EAEM,CAAE,WAAU,SAAQ,CAC7B"}
@@ -0,0 +1,16 @@
1
+ export type A11yTone = 'default' | 'error';
2
+ export type A11yControlConfig = {
3
+ checked?: () => 'true' | 'false' | 'mixed' | undefined;
4
+ helperId?: string;
5
+ helperText?: () => string | undefined;
6
+ helperTone?: () => A11yTone;
7
+ invalid?: () => boolean;
8
+ labelId?: string;
9
+ role: string;
10
+ };
11
+ export type A11yControlHandle = {
12
+ helperId: string;
13
+ labelId: string;
14
+ };
15
+ export declare function createA11yControl(config: A11yControlConfig): A11yControlHandle;
16
+ //# sourceMappingURL=a11y-control.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"a11y-control.d.ts","sourceRoot":"","sources":["../../src/controls/a11y-control.ts"],"names":[],"mappings":"AAGA,MAAM,MAAM,QAAQ,GAAG,SAAS,GAAG,OAAO,CAAC;AAE3C,MAAM,MAAM,iBAAiB,GAAG;IAC9B,OAAO,CAAC,EAAE,MAAM,MAAM,GAAG,OAAO,GAAG,OAAO,GAAG,SAAS,CAAC;IACvD,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,MAAM,GAAG,SAAS,CAAC;IACtC,UAAU,CAAC,EAAE,MAAM,QAAQ,CAAC;IAC5B,OAAO,CAAC,EAAE,MAAM,OAAO,CAAC;IACxB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;CACd,CAAC;AAEF,MAAM,MAAM,iBAAiB,GAAG;IAC9B,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;CACjB,CAAC;AAYF,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,iBAAiB,GAAG,iBAAiB,CA4H9E"}
@@ -0,0 +1,2 @@
1
+ import{currentElementOrThrow as e,effect as t,onCleanup as n,onMounted as r}from"../runtime.js";import{createId as i}from"../internal.js";var a=e=>{let t=e.querySelector(`slot`);return t instanceof HTMLSlotElement?t.assignedNodes({flatten:!0}).some(e=>(e.textContent?.trim().length??0)>0):(e.textContent?.trim().length??0)>0};function o(o){let s=e(),c=o.labelId||i(`a11y-label`),l=o.helperId||i(`a11y-helper`),u=(e,t,n)=>{e.getAttribute(t)!==n&&e.setAttribute(t,n)},d=(e,t)=>{e.textContent!==t&&(e.textContent=t)};u(s,`role`,o.role);let f=null,p=null,m=new Map,h=(e,t)=>{let n=new Set;for(let r of[e,t])if(r)for(let e of Array.from(r.querySelectorAll(`slot`)))e instanceof HTMLSlotElement&&n.add(e);for(let[e,t]of m)n.has(e)||(t(),m.delete(e));for(let e of n){if(m.has(e))continue;let t=()=>g();e.addEventListener(`slotchange`,t),m.set(e,()=>e.removeEventListener(`slotchange`,t))}},g=()=>{if(!s.shadowRoot)return;let e=f,t=p;h(e,t);let n=o.checked?.(),r=o.invalid?.(),i=o.helperText?.();e?(e.id!==c&&(e.id=c),a(e)?u(s,`aria-labelledby`,c):s.removeAttribute(`aria-labelledby`)):s.removeAttribute(`aria-labelledby`),t?(t.id!==l&&(t.id=l),i?(d(t,i),t.hidden&&=!1,u(s,`aria-describedby`,l),(o.helperTone?.()??`default`)===`error`?u(t,`role`,`alert`):t.removeAttribute(`role`)):(d(t,``),t.hidden||=!0,t.removeAttribute(`role`),s.removeAttribute(`aria-describedby`))):s.removeAttribute(`aria-describedby`),n===void 0?s.removeAttribute(`aria-checked`):u(s,`aria-checked`,n),r===void 0?s.removeAttribute(`aria-invalid`):u(s,`aria-invalid`,String(r))};return t(()=>{g()}),r(()=>{f=s.shadowRoot?.querySelector(`[data-a11y-label]`)??null,p=s.shadowRoot?.querySelector(`[data-a11y-helper]`)??null,g()}),n(()=>{for(let e of m.values())e();m.clear()}),{helperId:l,labelId:c}}export{o as createA11yControl};
2
+ //# sourceMappingURL=a11y-control.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"a11y-control.js","names":[],"sources":["../../src/controls/a11y-control.ts"],"sourcesContent":["import { createId } from '../internal';\nimport { currentElementOrThrow, effect, onCleanup, onMounted } from '../runtime';\n\nexport type A11yTone = 'default' | 'error';\n\nexport type A11yControlConfig = {\n checked?: () => 'true' | 'false' | 'mixed' | undefined;\n helperId?: string;\n helperText?: () => string | undefined;\n helperTone?: () => A11yTone;\n invalid?: () => boolean;\n labelId?: string;\n role: string;\n};\n\nexport type A11yControlHandle = {\n helperId: string;\n labelId: string;\n};\n\nconst hasLabelContent = (labelElement: HTMLElement): boolean => {\n const slot = labelElement.querySelector('slot');\n\n if (slot instanceof HTMLSlotElement) {\n return slot.assignedNodes({ flatten: true }).some((node) => (node.textContent?.trim().length ?? 0) > 0);\n }\n\n return (labelElement.textContent?.trim().length ?? 0) > 0;\n};\n\nexport function createA11yControl(config: A11yControlConfig): A11yControlHandle {\n const host = currentElementOrThrow();\n const labelId = config.labelId || createId('a11y-label');\n const helperId = config.helperId || createId('a11y-helper');\n\n const setAttr = (element: Element, name: string, value: string): void => {\n if (element.getAttribute(name) !== value) element.setAttribute(name, value);\n };\n\n const setText = (element: Node, value: string): void => {\n if (element.textContent !== value) element.textContent = value;\n };\n\n setAttr(host, 'role', config.role);\n\n let labelEl: HTMLElement | null = null;\n let helperEl: HTMLDivElement | null = null;\n\n const slotCleanupByElement = new Map<HTMLSlotElement, () => void>();\n\n const syncSlotListeners = (labelElement: HTMLElement | null, helperElement: HTMLDivElement | null): void => {\n const nextSlots = new Set<HTMLSlotElement>();\n\n for (const container of [labelElement, helperElement]) {\n if (!container) continue;\n\n for (const slot of Array.from(container.querySelectorAll('slot'))) {\n if (slot instanceof HTMLSlotElement) nextSlots.add(slot);\n }\n }\n\n for (const [slot, cleanup] of slotCleanupByElement) {\n if (nextSlots.has(slot)) continue;\n\n cleanup();\n slotCleanupByElement.delete(slot);\n }\n\n for (const slot of nextSlots) {\n if (slotCleanupByElement.has(slot)) continue;\n\n const slotHandler = () => sync();\n\n slot.addEventListener('slotchange', slotHandler);\n slotCleanupByElement.set(slot, () => slot.removeEventListener('slotchange', slotHandler));\n }\n };\n\n const sync = (): void => {\n const shadow = host.shadowRoot;\n\n if (!shadow) return;\n\n const labelElement = labelEl;\n const helperElement = helperEl;\n\n syncSlotListeners(labelElement, helperElement);\n\n const checked = config.checked?.();\n const invalid = config.invalid?.();\n const helperText = config.helperText?.();\n\n // Sync label\n if (labelElement) {\n if (labelElement.id !== labelId) labelElement.id = labelId;\n\n if (hasLabelContent(labelElement)) setAttr(host, 'aria-labelledby', labelId);\n else host.removeAttribute('aria-labelledby');\n } else {\n host.removeAttribute('aria-labelledby');\n }\n\n // Sync helper\n if (helperElement) {\n if (helperElement.id !== helperId) helperElement.id = helperId;\n\n if (helperText) {\n setText(helperElement, helperText);\n\n if (helperElement.hidden) helperElement.hidden = false;\n\n setAttr(host, 'aria-describedby', helperId);\n\n if ((config.helperTone?.() ?? 'default') === 'error') setAttr(helperElement, 'role', 'alert');\n else helperElement.removeAttribute('role');\n } else {\n setText(helperElement, '');\n\n if (!helperElement.hidden) helperElement.hidden = true;\n\n helperElement.removeAttribute('role');\n host.removeAttribute('aria-describedby');\n }\n } else {\n host.removeAttribute('aria-describedby');\n }\n\n // Sync checked\n if (checked === undefined) host.removeAttribute('aria-checked');\n else setAttr(host, 'aria-checked', checked);\n\n // Sync invalid\n if (invalid === undefined) host.removeAttribute('aria-invalid');\n else setAttr(host, 'aria-invalid', String(invalid));\n };\n\n // Keep ARIA in sync with reactive config changes.\n effect(() => {\n sync();\n });\n\n // Query shadow DOM refs once after first render, then sync.\n onMounted(() => {\n labelEl = (host.shadowRoot?.querySelector('[data-a11y-label]') ?? null) as HTMLElement | null;\n helperEl = (host.shadowRoot?.querySelector('[data-a11y-helper]') ?? null) as HTMLDivElement | null;\n sync();\n });\n\n onCleanup(() => {\n for (const cleanup of slotCleanupByElement.values()) cleanup();\n slotCleanupByElement.clear();\n });\n\n return { helperId, labelId };\n}\n"],"mappings":"0IAoBA,IAAM,EAAmB,GAAuC,CAC9D,IAAM,EAAO,EAAa,cAAc,MAAM,EAM9C,OAJI,aAAgB,gBACX,EAAK,cAAc,CAAE,QAAS,EAAK,CAAC,EAAE,KAAM,IAAU,EAAK,aAAa,KAAK,EAAE,QAAU,GAAK,CAAC,GAGhG,EAAa,aAAa,KAAK,EAAE,QAAU,GAAK,CAC1D,EAEA,SAAgB,EAAkB,EAA8C,CAC9E,IAAM,EAAO,EAAsB,EAC7B,EAAU,EAAO,SAAW,EAAS,YAAY,EACjD,EAAW,EAAO,UAAY,EAAS,aAAa,EAEpD,GAAW,EAAkB,EAAc,IAAwB,CACnE,EAAQ,aAAa,CAAI,IAAM,GAAO,EAAQ,aAAa,EAAM,CAAK,CAC5E,EAEM,GAAW,EAAe,IAAwB,CAClD,EAAQ,cAAgB,IAAO,EAAQ,YAAc,EAC3D,EAEA,EAAQ,EAAM,OAAQ,EAAO,IAAI,EAEjC,IAAI,EAA8B,KAC9B,EAAkC,KAEhC,EAAuB,IAAI,IAE3B,GAAqB,EAAkC,IAA+C,CAC1G,IAAM,EAAY,IAAI,IAEtB,IAAK,IAAM,IAAa,CAAC,EAAc,CAAa,EAC7C,KAEL,IAAK,IAAM,KAAQ,MAAM,KAAK,EAAU,iBAAiB,MAAM,CAAC,EAC1D,aAAgB,iBAAiB,EAAU,IAAI,CAAI,EAI3D,IAAK,GAAM,CAAC,EAAM,KAAY,EACxB,EAAU,IAAI,CAAI,IAEtB,EAAQ,EACR,EAAqB,OAAO,CAAI,GAGlC,IAAK,IAAM,KAAQ,EAAW,CAC5B,GAAI,EAAqB,IAAI,CAAI,EAAG,SAEpC,IAAM,MAAoB,EAAK,EAE/B,EAAK,iBAAiB,aAAc,CAAW,EAC/C,EAAqB,IAAI,MAAY,EAAK,oBAAoB,aAAc,CAAW,CAAC,CAC1F,CACF,EAEM,MAAmB,CAGvB,GAAI,CAFW,EAAK,WAEP,OAEb,IAAM,EAAe,EACf,EAAgB,EAEtB,EAAkB,EAAc,CAAa,EAE7C,IAAM,EAAU,EAAO,UAAU,EAC3B,EAAU,EAAO,UAAU,EAC3B,EAAa,EAAO,aAAa,EAGnC,GACE,EAAa,KAAO,IAAS,EAAa,GAAK,GAE/C,EAAgB,CAAY,EAAG,EAAQ,EAAM,kBAAmB,CAAO,EACtE,EAAK,gBAAgB,iBAAiB,GAE3C,EAAK,gBAAgB,iBAAiB,EAIpC,GACE,EAAc,KAAO,IAAU,EAAc,GAAK,GAElD,GACF,EAAQ,EAAe,CAAU,EAEjC,AAA0B,EAAc,SAAS,GAEjD,EAAQ,EAAM,mBAAoB,CAAQ,GAErC,EAAO,aAAa,GAAK,aAAe,QAAS,EAAQ,EAAe,OAAQ,OAAO,EACvF,EAAc,gBAAgB,MAAM,IAEzC,EAAQ,EAAe,EAAE,EAEzB,AAA2B,EAAc,SAAS,GAElD,EAAc,gBAAgB,MAAM,EACpC,EAAK,gBAAgB,kBAAkB,IAGzC,EAAK,gBAAgB,kBAAkB,EAIrC,IAAY,IAAA,GAAW,EAAK,gBAAgB,cAAc,EACzD,EAAQ,EAAM,eAAgB,CAAO,EAGtC,IAAY,IAAA,GAAW,EAAK,gBAAgB,cAAc,EACzD,EAAQ,EAAM,eAAgB,OAAO,CAAO,CAAC,CACpD,EAmBA,OAhBA,MAAa,CACX,EAAK,CACP,CAAC,EAGD,MAAgB,CACd,EAAW,EAAK,YAAY,cAAc,mBAAmB,GAAK,KAClE,EAAY,EAAK,YAAY,cAAc,oBAAoB,GAAK,KACpE,EAAK,CACP,CAAC,EAED,MAAgB,CACd,IAAK,IAAM,KAAW,EAAqB,OAAO,EAAG,EAAQ,EAC7D,EAAqB,MAAM,CAC7B,CAAC,EAEM,CAAE,WAAU,SAAQ,CAC7B"}
@@ -0,0 +1,2 @@
1
+ const e=require(`./a11y-control.cjs`),t=require(`./field-control.cjs`),n=require(`./press-control.cjs`);let r=require(`@vielzeug/stateit`);var i=e=>{let n=(0,r.signal)(``),i=(0,r.signal)(!!e.checked.value),a=(0,r.signal)(!!e.indeterminate?.value),o=t.createAssistiveState({error:e.error,helper:e.helper});(0,r.watch)(e.checked,e=>{i.value=!!e},{immediate:!0}),e.indeterminate&&(0,r.watch)(e.indeterminate,e=>{a.value=!!e},{immediate:!0});let{base:s,triggerValidation:c}=t.createFieldControlBase(e,{toFormValue:e=>e,value:(0,r.computed)(()=>a.value?null:i.value?e.value.value??``:null)});(0,r.watch)(e.value,e=>{n.value=String(e??``)},{immediate:!0});let l=t=>({checked:i.value,originalEvent:t,value:e.value.value??``}),u=t=>{if(!s.disabled.value){if(e.group){a.value=!1,e.group.toggle(e.value.value??``,t),e.onToggle?.(l(t));return}e.clearIndeterminateFirst&&a.value||(i.value=!i.value),a.value=!1,e.onToggle?.(l(t))}};return{...s,assistive:o,checked:i,indeterminate:a,toggle:u,triggerValidation:c,value:n}},a=t=>{let r=i(t),a=e.createA11yControl({checked:()=>t.role===`checkbox`&&r.indeterminate.value?`mixed`:r.checked.value?`true`:`false`,helperText:()=>r.assistive.value.errorText||r.assistive.value.helperText,helperTone:()=>r.assistive.value.errorText?`error`:`default`,invalid:()=>!!r.assistive.value.errorText,role:t.role}),o=n.createPressControl({disabled:()=>r.disabled.value,onPress:e=>{if(t.onPress){t.onPress(r,e);return}r.toggle(e)}});return{...r,handleClick:o.handleClick,handleKeydown:o.handleKeydown,helperId:a.helperId,labelId:a.labelId}};exports.createCheckableFieldControl=a;
2
+ //# sourceMappingURL=checkable-control.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"checkable-control.cjs","names":[],"sources":["../../src/controls/checkable-control.ts"],"sourcesContent":["import { computed, signal, watch } from '@vielzeug/stateit';\n\nimport { createA11yControl } from './a11y-control';\nimport {\n createAssistiveState,\n createFieldControlBase,\n type CheckableChangePayload,\n type CheckableStateHandle,\n type CheckableStateOptions,\n} from './field-control';\nimport { createPressControl } from './press-control';\n\nexport type CheckableFieldControlOptions = CheckableStateOptions & {\n onPress?: (control: CheckableStateHandle, originalEvent: Event) => void;\n role: 'checkbox' | 'radio' | 'switch';\n};\n\nexport type CheckableFieldControlHandle = CheckableStateHandle & {\n handleClick: (event: MouseEvent) => boolean;\n handleKeydown: (event: KeyboardEvent) => boolean;\n helperId: string;\n labelId: string;\n};\n\n/** @internal */\nexport const createCheckableState = (options: CheckableStateOptions): CheckableStateHandle => {\n const value = signal('');\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 { base, triggerValidation } = createFieldControlBase(options, {\n toFormValue: (nextValue: string | null) => nextValue,\n value: computed(() => {\n if (indeterminate.value) return null;\n\n return checked.value ? (options.value.value ?? '') : null;\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 originalEvent: event,\n value: options.value.value ?? '',\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 indeterminate,\n toggle,\n triggerValidation,\n value,\n };\n};\n\nexport const createCheckableFieldControl = (options: CheckableFieldControlOptions): CheckableFieldControlHandle => {\n const control = createCheckableState(options);\n const a11y = createA11yControl({\n checked: () =>\n options.role === 'checkbox' && control.indeterminate.value ? 'mixed' : control.checked.value ? 'true' : 'false',\n helperText: () => control.assistive.value.errorText || control.assistive.value.helperText,\n helperTone: () => (control.assistive.value.errorText ? 'error' : 'default'),\n invalid: () => Boolean(control.assistive.value.errorText),\n role: options.role,\n });\n\n const press = createPressControl({\n disabled: () => control.disabled.value,\n onPress: (originalEvent) => {\n if (options.onPress) {\n options.onPress(control, originalEvent);\n\n return;\n }\n\n control.toggle(originalEvent);\n },\n });\n\n return {\n ...control,\n handleClick: press.handleClick,\n handleKeydown: press.handleKeydown,\n helperId: a11y.helperId,\n labelId: a11y.labelId,\n };\n};\n"],"mappings":"2IAyBA,IAAa,EAAwB,GAAyD,CAC5F,IAAM,GAAA,EAAA,EAAA,QAAe,EAAE,EACjB,GAAA,EAAA,EAAA,QAAiB,EAAQ,EAAQ,QAAQ,KAAM,EAC/C,GAAA,EAAA,EAAA,QAAuB,EAAQ,EAAQ,eAAe,KAAM,EAC5D,EAAY,EAAA,qBAAqB,CAAE,MAAO,EAAQ,MAAO,OAAQ,EAAQ,MAAO,CAAC,GAEvF,EAAA,EAAA,OACE,EAAQ,QACP,GAAS,CACR,EAAQ,MAAQ,EAAQ,CAC1B,EACA,CAAE,UAAW,EAAK,CACpB,EAEI,EAAQ,gBACV,EAAA,EAAA,OACE,EAAQ,cACP,GAAS,CACR,EAAc,MAAQ,EAAQ,CAChC,EACA,CAAE,UAAW,EAAK,CACpB,EAGF,GAAM,CAAE,OAAM,qBAAsB,EAAA,uBAAuB,EAAS,CAClE,YAAc,GAA6B,EAC3C,OAAA,EAAA,EAAA,cACM,EAAc,MAAc,KAEzB,EAAQ,MAAS,EAAQ,MAAM,OAAS,GAAM,IACtD,CACH,CAAC,GAED,EAAA,EAAA,OACE,EAAQ,MACP,GAAS,CACR,EAAM,MAAQ,OAAO,GAAQ,EAAE,CACjC,EACA,CAAE,UAAW,EAAK,CACpB,EAEA,IAAM,EAAiB,IAA0C,CAC/D,QAAS,EAAQ,MACjB,cAAe,EACf,MAAO,EAAQ,MAAM,OAAS,EAChC,GAEM,EAAU,GAAuB,CACjC,MAAK,SAAS,MAElB,IAAI,EAAQ,MAAO,CACjB,EAAc,MAAQ,GACtB,EAAQ,MAAM,OAAO,EAAQ,MAAM,OAAS,GAAI,CAAK,EACrD,EAAQ,WAAW,EAAc,CAAK,CAAC,EAEvC,MACF,CAEI,EAAQ,yBAA2B,EAAc,QAGnD,EAAQ,MAAQ,CAAC,EAAQ,OAFzB,EAAc,MAAQ,GAMxB,EAAQ,WAAW,EAAc,CAAK,CAAC,CATvC,CAUF,EAEA,MAAO,CACL,GAAG,EACH,YACA,UACA,gBACA,SACA,oBACA,OACF,CACF,EAEa,EAA+B,GAAuE,CACjH,IAAM,EAAU,EAAqB,CAAO,EACtC,EAAO,EAAA,kBAAkB,CAC7B,YACE,EAAQ,OAAS,YAAc,EAAQ,cAAc,MAAQ,QAAU,EAAQ,QAAQ,MAAQ,OAAS,QAC1G,eAAkB,EAAQ,UAAU,MAAM,WAAa,EAAQ,UAAU,MAAM,WAC/E,eAAmB,EAAQ,UAAU,MAAM,UAAY,QAAU,UACjE,YAAe,EAAQ,EAAQ,UAAU,MAAM,UAC/C,KAAM,EAAQ,IAChB,CAAC,EAEK,EAAQ,EAAA,mBAAmB,CAC/B,aAAgB,EAAQ,SAAS,MACjC,QAAU,GAAkB,CAC1B,GAAI,EAAQ,QAAS,CACnB,EAAQ,QAAQ,EAAS,CAAa,EAEtC,MACF,CAEA,EAAQ,OAAO,CAAa,CAC9B,CACF,CAAC,EAED,MAAO,CACL,GAAG,EACH,YAAa,EAAM,YACnB,cAAe,EAAM,cACrB,SAAU,EAAK,SACf,QAAS,EAAK,OAChB,CACF"}
@@ -0,0 +1,15 @@
1
+ import { type CheckableStateHandle, type CheckableStateOptions } from './field-control';
2
+ export type CheckableFieldControlOptions = CheckableStateOptions & {
3
+ onPress?: (control: CheckableStateHandle, originalEvent: Event) => void;
4
+ role: 'checkbox' | 'radio' | 'switch';
5
+ };
6
+ export type CheckableFieldControlHandle = CheckableStateHandle & {
7
+ handleClick: (event: MouseEvent) => boolean;
8
+ handleKeydown: (event: KeyboardEvent) => boolean;
9
+ helperId: string;
10
+ labelId: string;
11
+ };
12
+ /** @internal */
13
+ export declare const createCheckableState: (options: CheckableStateOptions) => CheckableStateHandle;
14
+ export declare const createCheckableFieldControl: (options: CheckableFieldControlOptions) => CheckableFieldControlHandle;
15
+ //# sourceMappingURL=checkable-control.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"checkable-control.d.ts","sourceRoot":"","sources":["../../src/controls/checkable-control.ts"],"names":[],"mappings":"AAGA,OAAO,EAIL,KAAK,oBAAoB,EACzB,KAAK,qBAAqB,EAC3B,MAAM,iBAAiB,CAAC;AAGzB,MAAM,MAAM,4BAA4B,GAAG,qBAAqB,GAAG;IACjE,OAAO,CAAC,EAAE,CAAC,OAAO,EAAE,oBAAoB,EAAE,aAAa,EAAE,KAAK,KAAK,IAAI,CAAC;IACxE,IAAI,EAAE,UAAU,GAAG,OAAO,GAAG,QAAQ,CAAC;CACvC,CAAC;AAEF,MAAM,MAAM,2BAA2B,GAAG,oBAAoB,GAAG;IAC/D,WAAW,EAAE,CAAC,KAAK,EAAE,UAAU,KAAK,OAAO,CAAC;IAC5C,aAAa,EAAE,CAAC,KAAK,EAAE,aAAa,KAAK,OAAO,CAAC;IACjD,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;CACjB,CAAC;AAEF,gBAAgB;AAChB,eAAO,MAAM,oBAAoB,GAAI,SAAS,qBAAqB,KAAG,oBA6ErE,CAAC;AAEF,eAAO,MAAM,2BAA2B,GAAI,SAAS,4BAA4B,KAAG,2BA+BnF,CAAC"}
@@ -0,0 +1,2 @@
1
+ import{createA11yControl as e}from"./a11y-control.js";import{createAssistiveState as t,createFieldControlBase as n}from"./field-control.js";import{createPressControl as r}from"./press-control.js";import{computed as i,signal as a,watch as o}from"@vielzeug/stateit";var s=e=>{let r=a(``),s=a(!!e.checked.value),c=a(!!e.indeterminate?.value),l=t({error:e.error,helper:e.helper});o(e.checked,e=>{s.value=!!e},{immediate:!0}),e.indeterminate&&o(e.indeterminate,e=>{c.value=!!e},{immediate:!0});let{base:u,triggerValidation:d}=n(e,{toFormValue:e=>e,value:i(()=>c.value?null:s.value?e.value.value??``:null)});o(e.value,e=>{r.value=String(e??``)},{immediate:!0});let f=t=>({checked:s.value,originalEvent:t,value:e.value.value??``}),p=t=>{if(!u.disabled.value){if(e.group){c.value=!1,e.group.toggle(e.value.value??``,t),e.onToggle?.(f(t));return}e.clearIndeterminateFirst&&c.value||(s.value=!s.value),c.value=!1,e.onToggle?.(f(t))}};return{...u,assistive:l,checked:s,indeterminate:c,toggle:p,triggerValidation:d,value:r}},c=t=>{let n=s(t),i=e({checked:()=>t.role===`checkbox`&&n.indeterminate.value?`mixed`:n.checked.value?`true`:`false`,helperText:()=>n.assistive.value.errorText||n.assistive.value.helperText,helperTone:()=>n.assistive.value.errorText?`error`:`default`,invalid:()=>!!n.assistive.value.errorText,role:t.role}),a=r({disabled:()=>n.disabled.value,onPress:e=>{if(t.onPress){t.onPress(n,e);return}n.toggle(e)}});return{...n,handleClick:a.handleClick,handleKeydown:a.handleKeydown,helperId:i.helperId,labelId:i.labelId}};export{c as createCheckableFieldControl};
2
+ //# sourceMappingURL=checkable-control.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"checkable-control.js","names":[],"sources":["../../src/controls/checkable-control.ts"],"sourcesContent":["import { computed, signal, watch } from '@vielzeug/stateit';\n\nimport { createA11yControl } from './a11y-control';\nimport {\n createAssistiveState,\n createFieldControlBase,\n type CheckableChangePayload,\n type CheckableStateHandle,\n type CheckableStateOptions,\n} from './field-control';\nimport { createPressControl } from './press-control';\n\nexport type CheckableFieldControlOptions = CheckableStateOptions & {\n onPress?: (control: CheckableStateHandle, originalEvent: Event) => void;\n role: 'checkbox' | 'radio' | 'switch';\n};\n\nexport type CheckableFieldControlHandle = CheckableStateHandle & {\n handleClick: (event: MouseEvent) => boolean;\n handleKeydown: (event: KeyboardEvent) => boolean;\n helperId: string;\n labelId: string;\n};\n\n/** @internal */\nexport const createCheckableState = (options: CheckableStateOptions): CheckableStateHandle => {\n const value = signal('');\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 { base, triggerValidation } = createFieldControlBase(options, {\n toFormValue: (nextValue: string | null) => nextValue,\n value: computed(() => {\n if (indeterminate.value) return null;\n\n return checked.value ? (options.value.value ?? '') : null;\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 originalEvent: event,\n value: options.value.value ?? '',\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 indeterminate,\n toggle,\n triggerValidation,\n value,\n };\n};\n\nexport const createCheckableFieldControl = (options: CheckableFieldControlOptions): CheckableFieldControlHandle => {\n const control = createCheckableState(options);\n const a11y = createA11yControl({\n checked: () =>\n options.role === 'checkbox' && control.indeterminate.value ? 'mixed' : control.checked.value ? 'true' : 'false',\n helperText: () => control.assistive.value.errorText || control.assistive.value.helperText,\n helperTone: () => (control.assistive.value.errorText ? 'error' : 'default'),\n invalid: () => Boolean(control.assistive.value.errorText),\n role: options.role,\n });\n\n const press = createPressControl({\n disabled: () => control.disabled.value,\n onPress: (originalEvent) => {\n if (options.onPress) {\n options.onPress(control, originalEvent);\n\n return;\n }\n\n control.toggle(originalEvent);\n },\n });\n\n return {\n ...control,\n handleClick: press.handleClick,\n handleKeydown: press.handleKeydown,\n helperId: a11y.helperId,\n labelId: a11y.labelId,\n };\n};\n"],"mappings":"wQAyBA,IAAa,EAAwB,GAAyD,CAC5F,IAAM,EAAQ,EAAO,EAAE,EACjB,EAAU,EAAO,EAAQ,EAAQ,QAAQ,KAAM,EAC/C,EAAgB,EAAO,EAAQ,EAAQ,eAAe,KAAM,EAC5D,EAAY,EAAqB,CAAE,MAAO,EAAQ,MAAO,OAAQ,EAAQ,MAAO,CAAC,EAEvF,EACE,EAAQ,QACP,GAAS,CACR,EAAQ,MAAQ,EAAQ,CAC1B,EACA,CAAE,UAAW,EAAK,CACpB,EAEI,EAAQ,eACV,EACE,EAAQ,cACP,GAAS,CACR,EAAc,MAAQ,EAAQ,CAChC,EACA,CAAE,UAAW,EAAK,CACpB,EAGF,GAAM,CAAE,OAAM,qBAAsB,EAAuB,EAAS,CAClE,YAAc,GAA6B,EAC3C,MAAO,MACD,EAAc,MAAc,KAEzB,EAAQ,MAAS,EAAQ,MAAM,OAAS,GAAM,IACtD,CACH,CAAC,EAED,EACE,EAAQ,MACP,GAAS,CACR,EAAM,MAAQ,OAAO,GAAQ,EAAE,CACjC,EACA,CAAE,UAAW,EAAK,CACpB,EAEA,IAAM,EAAiB,IAA0C,CAC/D,QAAS,EAAQ,MACjB,cAAe,EACf,MAAO,EAAQ,MAAM,OAAS,EAChC,GAEM,EAAU,GAAuB,CACjC,MAAK,SAAS,MAElB,IAAI,EAAQ,MAAO,CACjB,EAAc,MAAQ,GACtB,EAAQ,MAAM,OAAO,EAAQ,MAAM,OAAS,GAAI,CAAK,EACrD,EAAQ,WAAW,EAAc,CAAK,CAAC,EAEvC,MACF,CAEI,EAAQ,yBAA2B,EAAc,QAGnD,EAAQ,MAAQ,CAAC,EAAQ,OAFzB,EAAc,MAAQ,GAMxB,EAAQ,WAAW,EAAc,CAAK,CAAC,CATvC,CAUF,EAEA,MAAO,CACL,GAAG,EACH,YACA,UACA,gBACA,SACA,oBACA,OACF,CACF,EAEa,EAA+B,GAAuE,CACjH,IAAM,EAAU,EAAqB,CAAO,EACtC,EAAO,EAAkB,CAC7B,YACE,EAAQ,OAAS,YAAc,EAAQ,cAAc,MAAQ,QAAU,EAAQ,QAAQ,MAAQ,OAAS,QAC1G,eAAkB,EAAQ,UAAU,MAAM,WAAa,EAAQ,UAAU,MAAM,WAC/E,eAAmB,EAAQ,UAAU,MAAM,UAAY,QAAU,UACjE,YAAe,EAAQ,EAAQ,UAAU,MAAM,UAC/C,KAAM,EAAQ,IAChB,CAAC,EAEK,EAAQ,EAAmB,CAC/B,aAAgB,EAAQ,SAAS,MACjC,QAAU,GAAkB,CAC1B,GAAI,EAAQ,QAAS,CACnB,EAAQ,QAAQ,EAAS,CAAa,EAEtC,MACF,CAEA,EAAQ,OAAO,CAAa,CAC9B,CACF,CAAC,EAED,MAAO,CACL,GAAG,EACH,YAAa,EAAM,YACnB,cAAe,EAAM,cACrB,SAAU,EAAK,SACf,QAAS,EAAK,OAChB,CACF"}
@@ -0,0 +1,2 @@
1
+ const e=require(`./field-control.cjs`);let t=require(`@vielzeug/stateit`);var n=e=>e?e.split(`,`).map(e=>e.trim()).filter(Boolean):[],r=r=>{let i=(0,t.signal)([]),a=(0,t.computed)(()=>!!r.multiple?.value),o=(0,t.computed)(()=>a.value?i.value.join(`,`):i.value[0]??``),s=e=>{let t=a.value?e:e.slice(0,1);return[...new Set(t.map(e=>String(e??``)).filter(Boolean))]},c=e=>{i.value=s(e)},l=()=>{c([])},u=e=>{i.value=i.value.filter(t=>t!==e)},d=e=>{if(a.value){if(i.value.includes(e))return;c([...i.value,e]);return}c([e])},f=e=>{if(a.value){if(i.value.includes(e)){u(e);return}c([...i.value,e]);return}c([e])},p=e=>{let t=n(typeof e==`string`?e:String(e??``));t.length===i.value.length&&t.every((e,t)=>e===i.value[t])||c(t)},{base:m,triggerValidation:h}=e.createFieldControlBase(r,{value:o}),g=e.createAssistiveState({error:r.error,helper:r.helper});return(0,t.watch)(r.value,e=>{p(e)},{immediate:!0}),r.multiple&&(0,t.watch)(r.multiple,()=>p(r.value.value)),{...m,assistive:g,clear:l,formValue:o,removeValue:u,selectedValues:i,selectValue:d,setValues:c,toggleValue:f,triggerValidation:h}};exports.createChoiceField=r;
2
+ //# sourceMappingURL=choice-field-control.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"choice-field-control.cjs","names":[],"sources":["../../src/controls/choice-field-control.ts"],"sourcesContent":["import { computed, signal, watch } from '@vielzeug/stateit';\n\nimport {\n createAssistiveState,\n createFieldControlBase,\n type ChoiceFieldHandle,\n type ChoiceFieldOptions,\n} from './field-control';\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 createChoiceField = (options: ChoiceFieldOptions): ChoiceFieldHandle => {\n const selectedValues = signal<string[]>([]);\n const isMultiple = computed(() => Boolean(options.multiple?.value));\n const formValue = computed(() =>\n isMultiple.value ? selectedValues.value.join(',') : (selectedValues.value[0] ?? ''),\n );\n\n const normalizeSelectedValues = (values: string[]): string[] => {\n const normalized = isMultiple.value ? values : values.slice(0, 1);\n\n return [...new Set(normalized.map((entry) => String(entry ?? '')).filter(Boolean))];\n };\n\n const setValues = (values: string[]): void => {\n selectedValues.value = normalizeSelectedValues(values);\n };\n\n const clear = (): void => {\n setValues([]);\n };\n\n const removeValue = (value: string): void => {\n selectedValues.value = selectedValues.value.filter((current) => current !== value);\n };\n\n const selectValue = (value: string): void => {\n if (isMultiple.value) {\n if (selectedValues.value.includes(value)) return;\n\n setValues([...selectedValues.value, value]);\n\n return;\n }\n\n setValues([value]);\n };\n\n const toggleValue = (value: string): void => {\n if (isMultiple.value) {\n if (selectedValues.value.includes(value)) {\n removeValue(value);\n\n return;\n }\n\n setValues([...selectedValues.value, value]);\n\n return;\n }\n\n setValues([value]);\n };\n\n const syncControlledValue = (nextValue: unknown): void => {\n const values = parseChoiceFieldValues(typeof nextValue === 'string' ? nextValue : String(nextValue ?? ''));\n\n if (\n values.length === selectedValues.value.length &&\n values.every((value, index) => value === selectedValues.value[index])\n ) {\n return;\n }\n\n setValues(values);\n };\n\n const { base, triggerValidation } = createFieldControlBase(options, { value: formValue });\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 formValue,\n removeValue,\n selectedValues,\n selectValue,\n setValues,\n toggleValue,\n triggerValidation,\n };\n};\n"],"mappings":"0EASA,IAAM,EAA0B,GACzB,EAEE,EACJ,MAAM,GAAG,EACT,IAAK,GAAU,EAAM,KAAK,CAAC,EAC3B,OAAO,OAAO,EALE,CAAC,EAQT,EAAqB,GAAmD,CACnF,IAAM,GAAA,EAAA,EAAA,QAAkC,CAAC,CAAC,EACpC,GAAA,EAAA,EAAA,cAA4B,EAAQ,EAAQ,UAAU,KAAM,EAC5D,GAAA,EAAA,EAAA,cACJ,EAAW,MAAQ,EAAe,MAAM,KAAK,GAAG,EAAK,EAAe,MAAM,IAAM,EAClF,EAEM,EAA2B,GAA+B,CAC9D,IAAM,EAAa,EAAW,MAAQ,EAAS,EAAO,MAAM,EAAG,CAAC,EAEhE,MAAO,CAAC,GAAG,IAAI,IAAI,EAAW,IAAK,GAAU,OAAO,GAAS,EAAE,CAAC,EAAE,OAAO,OAAO,CAAC,CAAC,CACpF,EAEM,EAAa,GAA2B,CAC5C,EAAe,MAAQ,EAAwB,CAAM,CACvD,EAEM,MAAoB,CACxB,EAAU,CAAC,CAAC,CACd,EAEM,EAAe,GAAwB,CAC3C,EAAe,MAAQ,EAAe,MAAM,OAAQ,GAAY,IAAY,CAAK,CACnF,EAEM,EAAe,GAAwB,CAC3C,GAAI,EAAW,MAAO,CACpB,GAAI,EAAe,MAAM,SAAS,CAAK,EAAG,OAE1C,EAAU,CAAC,GAAG,EAAe,MAAO,CAAK,CAAC,EAE1C,MACF,CAEA,EAAU,CAAC,CAAK,CAAC,CACnB,EAEM,EAAe,GAAwB,CAC3C,GAAI,EAAW,MAAO,CACpB,GAAI,EAAe,MAAM,SAAS,CAAK,EAAG,CACxC,EAAY,CAAK,EAEjB,MACF,CAEA,EAAU,CAAC,GAAG,EAAe,MAAO,CAAK,CAAC,EAE1C,MACF,CAEA,EAAU,CAAC,CAAK,CAAC,CACnB,EAEM,EAAuB,GAA6B,CACxD,IAAM,EAAS,EAAuB,OAAO,GAAc,SAAW,EAAY,OAAO,GAAa,EAAE,CAAC,EAGvG,EAAO,SAAW,EAAe,MAAM,QACvC,EAAO,OAAO,EAAO,IAAU,IAAU,EAAe,MAAM,EAAM,GAKtE,EAAU,CAAM,CAClB,EAEM,CAAE,OAAM,qBAAsB,EAAA,uBAAuB,EAAS,CAAE,MAAO,CAAU,CAAC,EAElF,EAAY,EAAA,qBAAqB,CACrC,MAAO,EAAQ,MACf,OAAQ,EAAQ,MAClB,CAAC,EAcD,OAZA,EAAA,EAAA,OACE,EAAQ,MACP,GAAS,CACR,EAAoB,CAAI,CAC1B,EACA,CAAE,UAAW,EAAK,CACpB,EAEI,EAAQ,WACV,EAAA,EAAA,OAAM,EAAQ,aAAgB,EAAoB,EAAQ,MAAM,KAAK,CAAC,EAGjE,CACL,GAAG,EACH,YACA,QACA,YACA,cACA,iBACA,cACA,YACA,cACA,mBACF,CACF"}
@@ -0,0 +1,3 @@
1
+ import { type ChoiceFieldHandle, type ChoiceFieldOptions } from './field-control';
2
+ export declare const createChoiceField: (options: ChoiceFieldOptions) => ChoiceFieldHandle;
3
+ //# sourceMappingURL=choice-field-control.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"choice-field-control.d.ts","sourceRoot":"","sources":["../../src/controls/choice-field-control.ts"],"names":[],"mappings":"AAEA,OAAO,EAGL,KAAK,iBAAiB,EACtB,KAAK,kBAAkB,EACxB,MAAM,iBAAiB,CAAC;AAWzB,eAAO,MAAM,iBAAiB,GAAI,SAAS,kBAAkB,KAAG,iBAiG/D,CAAC"}
@@ -0,0 +1,2 @@
1
+ import{createAssistiveState as e,createFieldControlBase as t}from"./field-control.js";import{computed as n,signal as r,watch as i}from"@vielzeug/stateit";var a=e=>e?e.split(`,`).map(e=>e.trim()).filter(Boolean):[],o=o=>{let s=r([]),c=n(()=>!!o.multiple?.value),l=n(()=>c.value?s.value.join(`,`):s.value[0]??``),u=e=>{let t=c.value?e:e.slice(0,1);return[...new Set(t.map(e=>String(e??``)).filter(Boolean))]},d=e=>{s.value=u(e)},f=()=>{d([])},p=e=>{s.value=s.value.filter(t=>t!==e)},m=e=>{if(c.value){if(s.value.includes(e))return;d([...s.value,e]);return}d([e])},h=e=>{if(c.value){if(s.value.includes(e)){p(e);return}d([...s.value,e]);return}d([e])},g=e=>{let t=a(typeof e==`string`?e:String(e??``));t.length===s.value.length&&t.every((e,t)=>e===s.value[t])||d(t)},{base:_,triggerValidation:v}=t(o,{value:l}),y=e({error:o.error,helper:o.helper});return i(o.value,e=>{g(e)},{immediate:!0}),o.multiple&&i(o.multiple,()=>g(o.value.value)),{..._,assistive:y,clear:f,formValue:l,removeValue:p,selectedValues:s,selectValue:m,setValues:d,toggleValue:h,triggerValidation:v}};export{o as createChoiceField};
2
+ //# sourceMappingURL=choice-field-control.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"choice-field-control.js","names":[],"sources":["../../src/controls/choice-field-control.ts"],"sourcesContent":["import { computed, signal, watch } from '@vielzeug/stateit';\n\nimport {\n createAssistiveState,\n createFieldControlBase,\n type ChoiceFieldHandle,\n type ChoiceFieldOptions,\n} from './field-control';\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 createChoiceField = (options: ChoiceFieldOptions): ChoiceFieldHandle => {\n const selectedValues = signal<string[]>([]);\n const isMultiple = computed(() => Boolean(options.multiple?.value));\n const formValue = computed(() =>\n isMultiple.value ? selectedValues.value.join(',') : (selectedValues.value[0] ?? ''),\n );\n\n const normalizeSelectedValues = (values: string[]): string[] => {\n const normalized = isMultiple.value ? values : values.slice(0, 1);\n\n return [...new Set(normalized.map((entry) => String(entry ?? '')).filter(Boolean))];\n };\n\n const setValues = (values: string[]): void => {\n selectedValues.value = normalizeSelectedValues(values);\n };\n\n const clear = (): void => {\n setValues([]);\n };\n\n const removeValue = (value: string): void => {\n selectedValues.value = selectedValues.value.filter((current) => current !== value);\n };\n\n const selectValue = (value: string): void => {\n if (isMultiple.value) {\n if (selectedValues.value.includes(value)) return;\n\n setValues([...selectedValues.value, value]);\n\n return;\n }\n\n setValues([value]);\n };\n\n const toggleValue = (value: string): void => {\n if (isMultiple.value) {\n if (selectedValues.value.includes(value)) {\n removeValue(value);\n\n return;\n }\n\n setValues([...selectedValues.value, value]);\n\n return;\n }\n\n setValues([value]);\n };\n\n const syncControlledValue = (nextValue: unknown): void => {\n const values = parseChoiceFieldValues(typeof nextValue === 'string' ? nextValue : String(nextValue ?? ''));\n\n if (\n values.length === selectedValues.value.length &&\n values.every((value, index) => value === selectedValues.value[index])\n ) {\n return;\n }\n\n setValues(values);\n };\n\n const { base, triggerValidation } = createFieldControlBase(options, { value: formValue });\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 formValue,\n removeValue,\n selectedValues,\n selectValue,\n setValues,\n toggleValue,\n triggerValidation,\n };\n};\n"],"mappings":"0JASA,IAAM,EAA0B,GACzB,EAEE,EACJ,MAAM,GAAG,EACT,IAAK,GAAU,EAAM,KAAK,CAAC,EAC3B,OAAO,OAAO,EALE,CAAC,EAQT,EAAqB,GAAmD,CACnF,IAAM,EAAiB,EAAiB,CAAC,CAAC,EACpC,EAAa,MAAe,EAAQ,EAAQ,UAAU,KAAM,EAC5D,EAAY,MAChB,EAAW,MAAQ,EAAe,MAAM,KAAK,GAAG,EAAK,EAAe,MAAM,IAAM,EAClF,EAEM,EAA2B,GAA+B,CAC9D,IAAM,EAAa,EAAW,MAAQ,EAAS,EAAO,MAAM,EAAG,CAAC,EAEhE,MAAO,CAAC,GAAG,IAAI,IAAI,EAAW,IAAK,GAAU,OAAO,GAAS,EAAE,CAAC,EAAE,OAAO,OAAO,CAAC,CAAC,CACpF,EAEM,EAAa,GAA2B,CAC5C,EAAe,MAAQ,EAAwB,CAAM,CACvD,EAEM,MAAoB,CACxB,EAAU,CAAC,CAAC,CACd,EAEM,EAAe,GAAwB,CAC3C,EAAe,MAAQ,EAAe,MAAM,OAAQ,GAAY,IAAY,CAAK,CACnF,EAEM,EAAe,GAAwB,CAC3C,GAAI,EAAW,MAAO,CACpB,GAAI,EAAe,MAAM,SAAS,CAAK,EAAG,OAE1C,EAAU,CAAC,GAAG,EAAe,MAAO,CAAK,CAAC,EAE1C,MACF,CAEA,EAAU,CAAC,CAAK,CAAC,CACnB,EAEM,EAAe,GAAwB,CAC3C,GAAI,EAAW,MAAO,CACpB,GAAI,EAAe,MAAM,SAAS,CAAK,EAAG,CACxC,EAAY,CAAK,EAEjB,MACF,CAEA,EAAU,CAAC,GAAG,EAAe,MAAO,CAAK,CAAC,EAE1C,MACF,CAEA,EAAU,CAAC,CAAK,CAAC,CACnB,EAEM,EAAuB,GAA6B,CACxD,IAAM,EAAS,EAAuB,OAAO,GAAc,SAAW,EAAY,OAAO,GAAa,EAAE,CAAC,EAGvG,EAAO,SAAW,EAAe,MAAM,QACvC,EAAO,OAAO,EAAO,IAAU,IAAU,EAAe,MAAM,EAAM,GAKtE,EAAU,CAAM,CAClB,EAEM,CAAE,OAAM,qBAAsB,EAAuB,EAAS,CAAE,MAAO,CAAU,CAAC,EAElF,EAAY,EAAqB,CACrC,MAAO,EAAQ,MACf,OAAQ,EAAQ,MAClB,CAAC,EAcD,OAZA,EACE,EAAQ,MACP,GAAS,CACR,EAAoB,CAAI,CAC1B,EACA,CAAE,UAAW,EAAK,CACpB,EAEI,EAAQ,UACV,EAAM,EAAQ,aAAgB,EAAoB,EAAQ,MAAM,KAAK,CAAC,EAGjE,CACL,GAAG,EACH,YACA,QACA,YACA,cACA,iBACA,cACA,YACA,cACA,mBACF,CACF"}
@@ -0,0 +1,2 @@
1
+ const e=require(`../runtime.cjs`),t=require(`../internal.cjs`),n=require(`../form.cjs`),r=require(`./internal/control-state.cjs`);let i=require(`@vielzeug/stateit`);var a=(e,n)=>{let r=`${e}-${n&&n.trim()?n.trim():t.createId().replace(/^cft-/,``)}`,i=`label-${r}`;return{errorId:`error-${r}`,fieldId:r,helperId:`helper-${r}`,labelInsetId:i,labelOutsideId:`${i}-outside`}},o=(e,t)=>{let i=r.createControlState(e),o=a(e.prefix,e.name?.value),s={disabled:i.disabled,errorId:o.errorId,fieldId:o.fieldId,helperId:o.helperId,labelInsetId:o.labelInsetId,labelOutsideId:o.labelOutsideId},c=n.defineField({...t,disabled:t.disabled??s.disabled});return{base:s,triggerValidation:e=>i.triggerValidation(c,e)}},s=e=>(0,i.computed)(()=>{let t=e.value?.value??``,n=e.error?.value??``,r=e.helper?.value??``,i=e.maxLength?.value,a=Number(i),o=Number.isFinite(a)&&a>0?a:null,s=o!==null,c=s?`${t.length} / ${o}`:``,l=s?t.length/o:0;return{counterAtLimit:s?l>=1:!1,counterNearLimit:s?l>=.9&&l<1:!1,counterText:c,errorText:n,hasCounter:s,helperText:r}}),c=t=>{let{element:n,onBlur:r,onChange:i,onInput:a,triggerValidation:o}=t,s=[];return a&&s.push(e.listen(n,`input`,e=>{e.stopPropagation(),a(e,n.value)})),s.push(e.listen(n,`change`,e=>{e.stopPropagation(),i?.(e,n.value),o?.(`change`)})),s.push(e.listen(n,`blur`,e=>{r?.(e),o?.(`blur`)})),()=>{for(let e of s)e()}};exports.createAssistiveState=s,exports.createFieldControlBase=o,exports.mountTextFieldLifecycle=c;
2
+ //# sourceMappingURL=field-control.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"field-control.cjs","names":[],"sources":["../../src/controls/field-control.ts"],"sourcesContent":["import { computed, type ReadonlySignal, type Signal } from '@vielzeug/stateit';\n\nimport { defineField, type FormFieldOptions } from '../form';\nimport { createId } from '../internal';\nimport { listen } from '../runtime';\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 type { ValidationReporter } from './internal/control-state';\n\nexport type TextFieldControlContext = ControlContextOptions;\n\nexport type FieldBaseOptions = {\n context?: TextFieldControlContext;\n disabled?: ReadonlySignal<boolean | undefined>;\n error?: ReadonlySignal<string | undefined>;\n helper?: ReadonlySignal<string | undefined>;\n name?: ReadonlySignal<string | undefined>;\n prefix: string;\n validateOn?: ReadonlySignal<ControlValidationMode>;\n};\n\nexport type TextFieldOptions = FieldBaseOptions & {\n elementRef?: { value: HTMLInputElement | HTMLTextAreaElement | null };\n maxLength?: ReadonlySignal<number | 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 value: ReadonlySignal<string | undefined>;\n};\n\nexport type ChoiceFieldOptions = FieldBaseOptions & {\n multiple?: ReadonlySignal<boolean | undefined>;\n value: ReadonlySignal<string | undefined>;\n};\n\nexport type CheckableStateOptions = FieldBaseOptions & {\n checked: ReadonlySignal<boolean | undefined>;\n clearIndeterminateFirst?: boolean;\n group?: { toggle: (value: string, originalEvent?: Event) => void };\n indeterminate?: ReadonlySignal<boolean | undefined>;\n onToggle?: (payload: CheckableChangePayload) => void;\n value: ReadonlySignal<string | undefined>;\n};\n\nexport type CheckableChangePayload = {\n checked: boolean;\n originalEvent?: Event;\n value: string;\n};\n\nexport type FieldControlBaseHandle = {\n disabled: ReadonlySignal<boolean>;\n errorId: string;\n fieldId: string;\n helperId: string;\n labelInsetId: string;\n labelOutsideId: string;\n triggerValidation: (on: FormControlValidationTrigger) => void;\n};\n\nexport type TextFieldHandle = FieldControlBaseHandle & {\n assistive: ReadonlySignal<AssistiveState>;\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 helperText: 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 = FieldControlBaseHandle & {\n assistive: ReadonlySignal<AssistiveState>;\n clear: () => void;\n formValue: ReadonlySignal<string>;\n removeValue: (value: string) => void;\n selectedValues: ReadonlySignal<string[]>;\n selectValue: (value: string) => void;\n setValues: (values: string[]) => void;\n toggleValue: (value: string) => void;\n};\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\nexport const createFieldControlBase = <T = unknown>(\n options: {\n context?: TextFieldControlContext;\n name?: ReadonlySignal<string | undefined>;\n prefix: string;\n } & ControlContextOptions,\n fieldOptions: Omit<FormFieldOptions<T>, 'disabled'> & {\n disabled?: FormFieldOptions<T>['disabled'];\n },\n): {\n base: Omit<FieldControlBaseHandle, 'triggerValidation'>;\n triggerValidation: (on: FormControlValidationTrigger) => void;\n} => {\n const controlState = createControlState(options);\n const ids = createFieldIds(options.prefix, options.name?.value);\n\n const base: Omit<FieldControlBaseHandle, 'triggerValidation'> = {\n disabled: controlState.disabled,\n errorId: ids.errorId,\n fieldId: ids.fieldId,\n helperId: ids.helperId,\n labelInsetId: ids.labelInsetId,\n labelOutsideId: ids.labelOutsideId,\n };\n\n const field = defineField<T>({\n ...fieldOptions,\n disabled: fieldOptions.disabled ?? base.disabled,\n });\n\n return {\n base,\n triggerValidation: (on) => controlState.triggerValidation(field, on),\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 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 helperText,\n };\n });\n};\n\n/** @internal */\nexport const mountTextFieldLifecycle = (options: TextFieldLifecycleOptions): (() => void) => {\n const { element, onBlur, onChange, onInput, triggerValidation } = options;\n const disposers: Array<() => void> = [];\n\n if (onInput) {\n disposers.push(\n listen(element, 'input', (event: Event) => {\n // Prevent the native composed event from bubbling out of the shadow DOM\n // and being re-targeted onto the host element. The component emits its\n // own structured CustomEvent so external listeners never need the raw one.\n event.stopPropagation();\n onInput(event, element.value);\n }),\n );\n }\n\n disposers.push(\n listen(element, 'change', (event: Event) => {\n // Same reason as above — suppress the native change event from escaping.\n event.stopPropagation();\n onChange?.(event, element.value);\n triggerValidation?.('change');\n }),\n );\n\n disposers.push(\n listen(element, 'blur', (event: Event) => {\n onBlur?.(event as FocusEvent);\n triggerValidation?.('blur');\n }),\n );\n\n return () => {\n for (const dispose of disposers) dispose();\n };\n};\n"],"mappings":"qKAwHA,IAAM,GAAkB,EAAgB,IAAyB,CAE/D,IAAM,EAAU,GAAG,EAAO,GADH,GAAQ,EAAK,KAAK,EAAI,EAAK,KAAK,EAAI,EAAA,SAAS,EAAE,QAAQ,QAAS,EAAE,IAEnF,EAAe,SAAS,IAE9B,MAAO,CACL,QAAS,SAAS,IAClB,UACA,SAAU,UAAU,IACpB,eACA,eAAgB,GAAG,EAAa,SAClC,CACF,EAEa,GACX,EAKA,IAMG,CACH,IAAM,EAAe,EAAA,mBAAmB,CAAO,EACzC,EAAM,EAAe,EAAQ,OAAQ,EAAQ,MAAM,KAAK,EAExD,EAA0D,CAC9D,SAAU,EAAa,SACvB,QAAS,EAAI,QACb,QAAS,EAAI,QACb,SAAU,EAAI,SACd,aAAc,EAAI,aAClB,eAAgB,EAAI,cACtB,EAEM,EAAQ,EAAA,YAAe,CAC3B,GAAG,EACH,SAAU,EAAa,UAAY,EAAK,QAC1C,CAAC,EAED,MAAO,CACL,OACA,kBAAoB,GAAO,EAAa,kBAAkB,EAAO,CAAE,CACrE,CACF,EAEa,EAAwB,IACnC,EAAA,EAAA,cAAsC,CACpC,IAAM,EAAQ,EAAQ,OAAO,OAAS,GAChC,EAAY,EAAQ,OAAO,OAAS,GACpC,EAAa,EAAQ,QAAQ,OAAS,GACtC,EAAY,EAAQ,WAAW,MAC/B,EAAkB,OAAO,CAAS,EAClC,EAAiB,OAAO,SAAS,CAAe,GAAK,EAAkB,EAAI,EAAkB,KAC7F,EAAa,IAAmB,KAChC,EAAc,EAAa,GAAG,EAAM,OAAO,KAAK,IAAmB,GACnE,EAAQ,EAAa,EAAM,OAAS,EAAiB,EAE3D,MAAO,CACL,eAAgB,EAAa,GAAS,EAAI,GAC1C,iBAAkB,EAAa,GAAS,IAAO,EAAQ,EAAI,GAC3D,cACA,YACA,aACA,YACF,CACF,CAAC,EAIU,EAA2B,GAAqD,CAC3F,GAAM,CAAE,UAAS,SAAQ,WAAU,UAAS,qBAAsB,EAC5D,EAA+B,CAAC,EA8BtC,OA5BI,GACF,EAAU,KACR,EAAA,OAAO,EAAS,QAAU,GAAiB,CAIzC,EAAM,gBAAgB,EACtB,EAAQ,EAAO,EAAQ,KAAK,CAC9B,CAAC,CACH,EAGF,EAAU,KACR,EAAA,OAAO,EAAS,SAAW,GAAiB,CAE1C,EAAM,gBAAgB,EACtB,IAAW,EAAO,EAAQ,KAAK,EAC/B,IAAoB,QAAQ,CAC9B,CAAC,CACH,EAEA,EAAU,KACR,EAAA,OAAO,EAAS,OAAS,GAAiB,CACxC,IAAS,CAAmB,EAC5B,IAAoB,MAAM,CAC5B,CAAC,CACH,MAEa,CACX,IAAK,IAAM,KAAW,EAAW,EAAQ,CAC3C,CACF"}
@@ -0,0 +1,111 @@
1
+ import { type ReadonlySignal, type Signal } from '@vielzeug/stateit';
2
+ import { type FormFieldOptions } from '../form';
3
+ import { type ControlContextOptions, type ControlValidationMode, type FormControlValidationTrigger } from './internal/control-state';
4
+ export type { FormControlValidationTrigger } from './internal/control-state';
5
+ export type { ValidationReporter } from './internal/control-state';
6
+ export type TextFieldControlContext = ControlContextOptions;
7
+ export type FieldBaseOptions = {
8
+ context?: TextFieldControlContext;
9
+ disabled?: ReadonlySignal<boolean | undefined>;
10
+ error?: ReadonlySignal<string | undefined>;
11
+ helper?: ReadonlySignal<string | undefined>;
12
+ name?: ReadonlySignal<string | undefined>;
13
+ prefix: string;
14
+ validateOn?: ReadonlySignal<ControlValidationMode>;
15
+ };
16
+ export type TextFieldOptions = FieldBaseOptions & {
17
+ elementRef?: {
18
+ value: HTMLInputElement | HTMLTextAreaElement | null;
19
+ };
20
+ maxLength?: ReadonlySignal<number | undefined>;
21
+ onBlur?: (event: FocusEvent) => void;
22
+ onChange?: (event: Event, value: string) => void;
23
+ onInput?: (event: Event, value: string) => void;
24
+ onInputExtra?: (event: Event) => void;
25
+ value: ReadonlySignal<string | undefined>;
26
+ };
27
+ export type ChoiceFieldOptions = FieldBaseOptions & {
28
+ multiple?: ReadonlySignal<boolean | undefined>;
29
+ value: ReadonlySignal<string | undefined>;
30
+ };
31
+ export type CheckableStateOptions = FieldBaseOptions & {
32
+ checked: ReadonlySignal<boolean | undefined>;
33
+ clearIndeterminateFirst?: boolean;
34
+ group?: {
35
+ toggle: (value: string, originalEvent?: Event) => void;
36
+ };
37
+ indeterminate?: ReadonlySignal<boolean | undefined>;
38
+ onToggle?: (payload: CheckableChangePayload) => void;
39
+ value: ReadonlySignal<string | undefined>;
40
+ };
41
+ export type CheckableChangePayload = {
42
+ checked: boolean;
43
+ originalEvent?: Event;
44
+ value: string;
45
+ };
46
+ export type FieldControlBaseHandle = {
47
+ disabled: ReadonlySignal<boolean>;
48
+ errorId: string;
49
+ fieldId: string;
50
+ helperId: string;
51
+ labelInsetId: string;
52
+ labelOutsideId: string;
53
+ triggerValidation: (on: FormControlValidationTrigger) => void;
54
+ };
55
+ export type TextFieldHandle = FieldControlBaseHandle & {
56
+ assistive: ReadonlySignal<AssistiveState>;
57
+ clear: (event?: Event) => void;
58
+ value: Signal<string>;
59
+ };
60
+ export type AssistiveState = {
61
+ counterAtLimit: boolean;
62
+ counterNearLimit: boolean;
63
+ counterText: string;
64
+ errorText: string;
65
+ hasCounter: boolean;
66
+ helperText: string;
67
+ };
68
+ export type AssistiveOptions = {
69
+ error?: ReadonlySignal<string | undefined>;
70
+ helper?: ReadonlySignal<string | undefined>;
71
+ maxLength?: ReadonlySignal<number | undefined>;
72
+ value?: ReadonlySignal<string | undefined>;
73
+ };
74
+ export type TextFieldLifecycleOptions = {
75
+ element: HTMLInputElement | HTMLSelectElement | HTMLTextAreaElement;
76
+ onBlur?: (event: FocusEvent) => void;
77
+ onChange?: (event: Event, value: string) => void;
78
+ onInput?: (event: Event, value: string) => void;
79
+ triggerValidation?: (on: FormControlValidationTrigger) => void;
80
+ };
81
+ export type CheckableStateHandle = FieldControlBaseHandle & {
82
+ assistive: ReadonlySignal<AssistiveState>;
83
+ checked: Signal<boolean>;
84
+ indeterminate: Signal<boolean>;
85
+ toggle: (event: Event) => void;
86
+ value: Signal<string>;
87
+ };
88
+ export type ChoiceFieldHandle = FieldControlBaseHandle & {
89
+ assistive: ReadonlySignal<AssistiveState>;
90
+ clear: () => void;
91
+ formValue: ReadonlySignal<string>;
92
+ removeValue: (value: string) => void;
93
+ selectedValues: ReadonlySignal<string[]>;
94
+ selectValue: (value: string) => void;
95
+ setValues: (values: string[]) => void;
96
+ toggleValue: (value: string) => void;
97
+ };
98
+ export declare const createFieldControlBase: <T = unknown>(options: {
99
+ context?: TextFieldControlContext;
100
+ name?: ReadonlySignal<string | undefined>;
101
+ prefix: string;
102
+ } & ControlContextOptions, fieldOptions: Omit<FormFieldOptions<T>, "disabled"> & {
103
+ disabled?: FormFieldOptions<T>["disabled"];
104
+ }) => {
105
+ base: Omit<FieldControlBaseHandle, "triggerValidation">;
106
+ triggerValidation: (on: FormControlValidationTrigger) => void;
107
+ };
108
+ export declare const createAssistiveState: (options: AssistiveOptions) => import("@vielzeug/stateit").ComputedSignal<AssistiveState>;
109
+ /** @internal */
110
+ export declare const mountTextFieldLifecycle: (options: TextFieldLifecycleOptions) => (() => void);
111
+ //# 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{listen as e}from"../runtime.js";import{createId as t}from"../internal.js";import{defineField as n}from"../form.js";import{createControlState as r}from"./internal/control-state.js";import{computed as i}from"@vielzeug/stateit";var a=(e,n)=>{let r=`${e}-${n&&n.trim()?n.trim():t().replace(/^cft-/,``)}`,i=`label-${r}`;return{errorId:`error-${r}`,fieldId:r,helperId:`helper-${r}`,labelInsetId:i,labelOutsideId:`${i}-outside`}},o=(e,t)=>{let i=r(e),o=a(e.prefix,e.name?.value),s={disabled:i.disabled,errorId:o.errorId,fieldId:o.fieldId,helperId:o.helperId,labelInsetId:o.labelInsetId,labelOutsideId:o.labelOutsideId},c=n({...t,disabled:t.disabled??s.disabled});return{base:s,triggerValidation:e=>i.triggerValidation(c,e)}},s=e=>i(()=>{let t=e.value?.value??``,n=e.error?.value??``,r=e.helper?.value??``,i=e.maxLength?.value,a=Number(i),o=Number.isFinite(a)&&a>0?a:null,s=o!==null,c=s?`${t.length} / ${o}`:``,l=s?t.length/o:0;return{counterAtLimit:s?l>=1:!1,counterNearLimit:s?l>=.9&&l<1:!1,counterText:c,errorText:n,hasCounter:s,helperText:r}}),c=t=>{let{element:n,onBlur:r,onChange:i,onInput:a,triggerValidation:o}=t,s=[];return a&&s.push(e(n,`input`,e=>{e.stopPropagation(),a(e,n.value)})),s.push(e(n,`change`,e=>{e.stopPropagation(),i?.(e,n.value),o?.(`change`)})),s.push(e(n,`blur`,e=>{r?.(e),o?.(`blur`)})),()=>{for(let e of s)e()}};export{s as createAssistiveState,o as createFieldControlBase,c 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, type ReadonlySignal, type Signal } from '@vielzeug/stateit';\n\nimport { defineField, type FormFieldOptions } from '../form';\nimport { createId } from '../internal';\nimport { listen } from '../runtime';\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 type { ValidationReporter } from './internal/control-state';\n\nexport type TextFieldControlContext = ControlContextOptions;\n\nexport type FieldBaseOptions = {\n context?: TextFieldControlContext;\n disabled?: ReadonlySignal<boolean | undefined>;\n error?: ReadonlySignal<string | undefined>;\n helper?: ReadonlySignal<string | undefined>;\n name?: ReadonlySignal<string | undefined>;\n prefix: string;\n validateOn?: ReadonlySignal<ControlValidationMode>;\n};\n\nexport type TextFieldOptions = FieldBaseOptions & {\n elementRef?: { value: HTMLInputElement | HTMLTextAreaElement | null };\n maxLength?: ReadonlySignal<number | 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 value: ReadonlySignal<string | undefined>;\n};\n\nexport type ChoiceFieldOptions = FieldBaseOptions & {\n multiple?: ReadonlySignal<boolean | undefined>;\n value: ReadonlySignal<string | undefined>;\n};\n\nexport type CheckableStateOptions = FieldBaseOptions & {\n checked: ReadonlySignal<boolean | undefined>;\n clearIndeterminateFirst?: boolean;\n group?: { toggle: (value: string, originalEvent?: Event) => void };\n indeterminate?: ReadonlySignal<boolean | undefined>;\n onToggle?: (payload: CheckableChangePayload) => void;\n value: ReadonlySignal<string | undefined>;\n};\n\nexport type CheckableChangePayload = {\n checked: boolean;\n originalEvent?: Event;\n value: string;\n};\n\nexport type FieldControlBaseHandle = {\n disabled: ReadonlySignal<boolean>;\n errorId: string;\n fieldId: string;\n helperId: string;\n labelInsetId: string;\n labelOutsideId: string;\n triggerValidation: (on: FormControlValidationTrigger) => void;\n};\n\nexport type TextFieldHandle = FieldControlBaseHandle & {\n assistive: ReadonlySignal<AssistiveState>;\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 helperText: 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 = FieldControlBaseHandle & {\n assistive: ReadonlySignal<AssistiveState>;\n clear: () => void;\n formValue: ReadonlySignal<string>;\n removeValue: (value: string) => void;\n selectedValues: ReadonlySignal<string[]>;\n selectValue: (value: string) => void;\n setValues: (values: string[]) => void;\n toggleValue: (value: string) => void;\n};\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\nexport const createFieldControlBase = <T = unknown>(\n options: {\n context?: TextFieldControlContext;\n name?: ReadonlySignal<string | undefined>;\n prefix: string;\n } & ControlContextOptions,\n fieldOptions: Omit<FormFieldOptions<T>, 'disabled'> & {\n disabled?: FormFieldOptions<T>['disabled'];\n },\n): {\n base: Omit<FieldControlBaseHandle, 'triggerValidation'>;\n triggerValidation: (on: FormControlValidationTrigger) => void;\n} => {\n const controlState = createControlState(options);\n const ids = createFieldIds(options.prefix, options.name?.value);\n\n const base: Omit<FieldControlBaseHandle, 'triggerValidation'> = {\n disabled: controlState.disabled,\n errorId: ids.errorId,\n fieldId: ids.fieldId,\n helperId: ids.helperId,\n labelInsetId: ids.labelInsetId,\n labelOutsideId: ids.labelOutsideId,\n };\n\n const field = defineField<T>({\n ...fieldOptions,\n disabled: fieldOptions.disabled ?? base.disabled,\n });\n\n return {\n base,\n triggerValidation: (on) => controlState.triggerValidation(field, on),\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 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 helperText,\n };\n });\n};\n\n/** @internal */\nexport const mountTextFieldLifecycle = (options: TextFieldLifecycleOptions): (() => void) => {\n const { element, onBlur, onChange, onInput, triggerValidation } = options;\n const disposers: Array<() => void> = [];\n\n if (onInput) {\n disposers.push(\n listen(element, 'input', (event: Event) => {\n // Prevent the native composed event from bubbling out of the shadow DOM\n // and being re-targeted onto the host element. The component emits its\n // own structured CustomEvent so external listeners never need the raw one.\n event.stopPropagation();\n onInput(event, element.value);\n }),\n );\n }\n\n disposers.push(\n listen(element, 'change', (event: Event) => {\n // Same reason as above — suppress the native change event from escaping.\n event.stopPropagation();\n onChange?.(event, element.value);\n triggerValidation?.('change');\n }),\n );\n\n disposers.push(\n listen(element, 'blur', (event: Event) => {\n onBlur?.(event as FocusEvent);\n triggerValidation?.('blur');\n }),\n );\n\n return () => {\n for (const dispose of disposers) dispose();\n };\n};\n"],"mappings":"wOAwHA,IAAM,GAAkB,EAAgB,IAAyB,CAE/D,IAAM,EAAU,GAAG,EAAO,GADH,GAAQ,EAAK,KAAK,EAAI,EAAK,KAAK,EAAI,EAAS,EAAE,QAAQ,QAAS,EAAE,IAEnF,EAAe,SAAS,IAE9B,MAAO,CACL,QAAS,SAAS,IAClB,UACA,SAAU,UAAU,IACpB,eACA,eAAgB,GAAG,EAAa,SAClC,CACF,EAEa,GACX,EAKA,IAMG,CACH,IAAM,EAAe,EAAmB,CAAO,EACzC,EAAM,EAAe,EAAQ,OAAQ,EAAQ,MAAM,KAAK,EAExD,EAA0D,CAC9D,SAAU,EAAa,SACvB,QAAS,EAAI,QACb,QAAS,EAAI,QACb,SAAU,EAAI,SACd,aAAc,EAAI,aAClB,eAAgB,EAAI,cACtB,EAEM,EAAQ,EAAe,CAC3B,GAAG,EACH,SAAU,EAAa,UAAY,EAAK,QAC1C,CAAC,EAED,MAAO,CACL,OACA,kBAAoB,GAAO,EAAa,kBAAkB,EAAO,CAAE,CACrE,CACF,EAEa,EAAwB,GAC5B,MAA+B,CACpC,IAAM,EAAQ,EAAQ,OAAO,OAAS,GAChC,EAAY,EAAQ,OAAO,OAAS,GACpC,EAAa,EAAQ,QAAQ,OAAS,GACtC,EAAY,EAAQ,WAAW,MAC/B,EAAkB,OAAO,CAAS,EAClC,EAAiB,OAAO,SAAS,CAAe,GAAK,EAAkB,EAAI,EAAkB,KAC7F,EAAa,IAAmB,KAChC,EAAc,EAAa,GAAG,EAAM,OAAO,KAAK,IAAmB,GACnE,EAAQ,EAAa,EAAM,OAAS,EAAiB,EAE3D,MAAO,CACL,eAAgB,EAAa,GAAS,EAAI,GAC1C,iBAAkB,EAAa,GAAS,IAAO,EAAQ,EAAI,GAC3D,cACA,YACA,aACA,YACF,CACF,CAAC,EAIU,EAA2B,GAAqD,CAC3F,GAAM,CAAE,UAAS,SAAQ,WAAU,UAAS,qBAAsB,EAC5D,EAA+B,CAAC,EA8BtC,OA5BI,GACF,EAAU,KACR,EAAO,EAAS,QAAU,GAAiB,CAIzC,EAAM,gBAAgB,EACtB,EAAQ,EAAO,EAAQ,KAAK,CAC9B,CAAC,CACH,EAGF,EAAU,KACR,EAAO,EAAS,SAAW,GAAiB,CAE1C,EAAM,gBAAgB,EACtB,IAAW,EAAO,EAAQ,KAAK,EAC/B,IAAoB,QAAQ,CAC9B,CAAC,CACH,EAEA,EAAU,KACR,EAAO,EAAS,OAAS,GAAiB,CACxC,IAAS,CAAmB,EAC5B,IAAoB,MAAM,CAC5B,CAAC,CACH,MAEa,CACX,IAAK,IAAM,KAAW,EAAW,EAAQ,CAC3C,CACF"}
@@ -0,0 +1,12 @@
1
+ export { createCheckableFieldControl } from './checkable-control';
2
+ export { type CheckableChangePayload } from './field-control';
3
+ export { createTextField } from './text-field-control';
4
+ export { createChoiceField } from './choice-field-control';
5
+ export { createListControl } from './list-control';
6
+ export { createPressControl } from './press-control';
7
+ export { createOverlayControl, type OverlayCloseReason, type OverlayOpenReason, type OverlayCloseDetail, type OverlayOpenDetail, } from './overlay-control';
8
+ export { createSpinnerControl } from './spinner-control';
9
+ export { createSliderControl } from './slider-control';
10
+ export { createSwipeControl, type SwipeAxis, type SwipeControl, type SwipeControlDetail } from './swipe-control';
11
+ export { createPopupListControl } from './popup-list-control';
12
+ //# 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,EAAE,2BAA2B,EAAE,MAAM,qBAAqB,CAAC;AAElE,OAAO,EAAE,KAAK,sBAAsB,EAAE,MAAM,iBAAiB,CAAC;AAC9D,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AACvD,OAAO,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAE3D,OAAO,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AACnD,OAAO,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAC;AACrD,OAAO,EACL,oBAAoB,EACpB,KAAK,kBAAkB,EACvB,KAAK,iBAAiB,EACtB,KAAK,kBAAkB,EACvB,KAAK,iBAAiB,GACvB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,oBAAoB,EAAE,MAAM,mBAAmB,CAAC;AACzD,OAAO,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AACvD,OAAO,EAAE,kBAAkB,EAAE,KAAK,SAAS,EAAE,KAAK,YAAY,EAAE,KAAK,kBAAkB,EAAE,MAAM,iBAAiB,CAAC;AACjH,OAAO,EAAE,sBAAsB,EAAE,MAAM,sBAAsB,CAAC"}
@@ -0,0 +1,2 @@
1
+ let e=require(`@vielzeug/stateit`);var t=t=>{let n=(0,e.computed)(()=>!!t.disabled?.value||!!t.context?.disabled?.value),r=t.validateOn??t.context?.validateOn;return{disabled:n,triggerValidation:(e,t)=>{r?.value===t&&e.reportValidity()},validateOn:r}};exports.createControlState=t;
2
+ //# sourceMappingURL=control-state.cjs.map