optikos 0.0.0-stage → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (527) hide show
  1. package/CHANGELOG.md +146 -0
  2. package/LICENSE +21 -0
  3. package/README.md +213 -2
  4. package/THIRD_PARTY_NOTICES.md +83 -0
  5. package/dist/bind.js +2 -0
  6. package/dist/bind.js.map +7 -0
  7. package/dist/chunk-23XLG2EM.js +2 -0
  8. package/dist/chunk-23XLG2EM.js.map +7 -0
  9. package/dist/chunk-27UZFEXD.js +2 -0
  10. package/dist/chunk-27UZFEXD.js.map +7 -0
  11. package/dist/chunk-2UPUC4RK.js +2 -0
  12. package/dist/chunk-2UPUC4RK.js.map +7 -0
  13. package/dist/chunk-2ZRNGG2N.js +2 -0
  14. package/dist/chunk-2ZRNGG2N.js.map +7 -0
  15. package/dist/chunk-2ZUZ5HDL.js +2 -0
  16. package/dist/chunk-2ZUZ5HDL.js.map +7 -0
  17. package/dist/chunk-3DBEZGOY.js +2 -0
  18. package/dist/chunk-3DBEZGOY.js.map +7 -0
  19. package/dist/chunk-3S24ZRPK.js +2 -0
  20. package/dist/chunk-3S24ZRPK.js.map +7 -0
  21. package/dist/chunk-3TAW4AKH.js +2 -0
  22. package/dist/chunk-3TAW4AKH.js.map +7 -0
  23. package/dist/chunk-4AA4FQEM.js +2 -0
  24. package/dist/chunk-4AA4FQEM.js.map +7 -0
  25. package/dist/chunk-4C666HHU.js +2 -0
  26. package/dist/chunk-4C666HHU.js.map +7 -0
  27. package/dist/chunk-4EZJ5FKJ.js +2 -0
  28. package/dist/chunk-4EZJ5FKJ.js.map +7 -0
  29. package/dist/chunk-4LZZ244E.js +2 -0
  30. package/dist/chunk-4LZZ244E.js.map +7 -0
  31. package/dist/chunk-4SYIIX5A.js +2 -0
  32. package/dist/chunk-4SYIIX5A.js.map +7 -0
  33. package/dist/chunk-5BC72727.js +2 -0
  34. package/dist/chunk-5BC72727.js.map +7 -0
  35. package/dist/chunk-5DJTP53N.js +2 -0
  36. package/dist/chunk-5DJTP53N.js.map +7 -0
  37. package/dist/chunk-5JEXM5S7.js +2 -0
  38. package/dist/chunk-5JEXM5S7.js.map +7 -0
  39. package/dist/chunk-5Q76ACVI.js +2 -0
  40. package/dist/chunk-5Q76ACVI.js.map +7 -0
  41. package/dist/chunk-5QUY72FX.js +2 -0
  42. package/dist/chunk-5QUY72FX.js.map +7 -0
  43. package/dist/chunk-5YS7OD5E.js +2 -0
  44. package/dist/chunk-5YS7OD5E.js.map +7 -0
  45. package/dist/chunk-676AKAGF.js +2 -0
  46. package/dist/chunk-676AKAGF.js.map +7 -0
  47. package/dist/chunk-6NCXO5ZP.js +2 -0
  48. package/dist/chunk-6NCXO5ZP.js.map +7 -0
  49. package/dist/chunk-6VBK2I5B.js +2 -0
  50. package/dist/chunk-6VBK2I5B.js.map +7 -0
  51. package/dist/chunk-7KMIFXHZ.js +2 -0
  52. package/dist/chunk-7KMIFXHZ.js.map +7 -0
  53. package/dist/chunk-A2NKDOYN.js +2 -0
  54. package/dist/chunk-A2NKDOYN.js.map +7 -0
  55. package/dist/chunk-ATFJ7PNA.js +2 -0
  56. package/dist/chunk-ATFJ7PNA.js.map +7 -0
  57. package/dist/chunk-BXYWVRKJ.js +2 -0
  58. package/dist/chunk-BXYWVRKJ.js.map +7 -0
  59. package/dist/chunk-CKXS375P.js +2 -0
  60. package/dist/chunk-CKXS375P.js.map +7 -0
  61. package/dist/chunk-CUN5QO4T.js +2 -0
  62. package/dist/chunk-CUN5QO4T.js.map +7 -0
  63. package/dist/chunk-DBMWS3O5.js +2 -0
  64. package/dist/chunk-DBMWS3O5.js.map +7 -0
  65. package/dist/chunk-E4VNLYO2.js +2 -0
  66. package/dist/chunk-E4VNLYO2.js.map +7 -0
  67. package/dist/chunk-EDUMAMK4.js +2 -0
  68. package/dist/chunk-EDUMAMK4.js.map +7 -0
  69. package/dist/chunk-ELYARUCN.js +2 -0
  70. package/dist/chunk-ELYARUCN.js.map +7 -0
  71. package/dist/chunk-EV73ADN2.js +2 -0
  72. package/dist/chunk-EV73ADN2.js.map +7 -0
  73. package/dist/chunk-FEHGU6EP.js +3 -0
  74. package/dist/chunk-FEHGU6EP.js.map +7 -0
  75. package/dist/chunk-FHM5NUS4.js +3 -0
  76. package/dist/chunk-FHM5NUS4.js.map +7 -0
  77. package/dist/chunk-G2DAD3MQ.js +2 -0
  78. package/dist/chunk-G2DAD3MQ.js.map +7 -0
  79. package/dist/chunk-G2KUK6AT.js +2 -0
  80. package/dist/chunk-G2KUK6AT.js.map +7 -0
  81. package/dist/chunk-GBPLNXMP.js +2 -0
  82. package/dist/chunk-GBPLNXMP.js.map +7 -0
  83. package/dist/chunk-GNU4VOOE.js +2 -0
  84. package/dist/chunk-GNU4VOOE.js.map +7 -0
  85. package/dist/chunk-GZ7X34QP.js +2 -0
  86. package/dist/chunk-GZ7X34QP.js.map +7 -0
  87. package/dist/chunk-HOF4JGMQ.js +2 -0
  88. package/dist/chunk-HOF4JGMQ.js.map +7 -0
  89. package/dist/chunk-HXDTGP2K.js +2 -0
  90. package/dist/chunk-HXDTGP2K.js.map +7 -0
  91. package/dist/chunk-I4SP6JTU.js +2 -0
  92. package/dist/chunk-I4SP6JTU.js.map +7 -0
  93. package/dist/chunk-IHE2MQ3W.js +2 -0
  94. package/dist/chunk-IHE2MQ3W.js.map +7 -0
  95. package/dist/chunk-II6ITOA6.js +2 -0
  96. package/dist/chunk-II6ITOA6.js.map +7 -0
  97. package/dist/chunk-JBLRAM7Z.js +2 -0
  98. package/dist/chunk-JBLRAM7Z.js.map +7 -0
  99. package/dist/chunk-JI265XFO.js +2 -0
  100. package/dist/chunk-JI265XFO.js.map +7 -0
  101. package/dist/chunk-JK74QK3M.js +2 -0
  102. package/dist/chunk-JK74QK3M.js.map +7 -0
  103. package/dist/chunk-JOFQJGZK.js +2 -0
  104. package/dist/chunk-JOFQJGZK.js.map +7 -0
  105. package/dist/chunk-KCEUD232.js +2 -0
  106. package/dist/chunk-KCEUD232.js.map +7 -0
  107. package/dist/chunk-KLLAY2IM.js +2 -0
  108. package/dist/chunk-KLLAY2IM.js.map +7 -0
  109. package/dist/chunk-LBJSMXLV.js +2 -0
  110. package/dist/chunk-LBJSMXLV.js.map +7 -0
  111. package/dist/chunk-LQRFNQ2N.js +2 -0
  112. package/dist/chunk-LQRFNQ2N.js.map +7 -0
  113. package/dist/chunk-LW2WRUVL.js +2 -0
  114. package/dist/chunk-LW2WRUVL.js.map +7 -0
  115. package/dist/chunk-M242VYZA.js +2 -0
  116. package/dist/chunk-M242VYZA.js.map +7 -0
  117. package/dist/chunk-MB3MU6HR.js +2 -0
  118. package/dist/chunk-MB3MU6HR.js.map +7 -0
  119. package/dist/chunk-MW3RWBZ7.js +2 -0
  120. package/dist/chunk-MW3RWBZ7.js.map +7 -0
  121. package/dist/chunk-NXSTUFS7.js +2 -0
  122. package/dist/chunk-NXSTUFS7.js.map +7 -0
  123. package/dist/chunk-OEAXCCVM.js +2 -0
  124. package/dist/chunk-OEAXCCVM.js.map +7 -0
  125. package/dist/chunk-OGRFQTXA.js +2 -0
  126. package/dist/chunk-OGRFQTXA.js.map +7 -0
  127. package/dist/chunk-OWEQT2HN.js +2 -0
  128. package/dist/chunk-OWEQT2HN.js.map +7 -0
  129. package/dist/chunk-PZSHOSOS.js +2 -0
  130. package/dist/chunk-PZSHOSOS.js.map +7 -0
  131. package/dist/chunk-REW4LR46.js +2 -0
  132. package/dist/chunk-REW4LR46.js.map +7 -0
  133. package/dist/chunk-RNN55473.js +2 -0
  134. package/dist/chunk-RNN55473.js.map +7 -0
  135. package/dist/chunk-SA53QUBF.js +2 -0
  136. package/dist/chunk-SA53QUBF.js.map +7 -0
  137. package/dist/chunk-TIPK3SCJ.js +2 -0
  138. package/dist/chunk-TIPK3SCJ.js.map +7 -0
  139. package/dist/chunk-TOLTUOZS.js +2 -0
  140. package/dist/chunk-TOLTUOZS.js.map +7 -0
  141. package/dist/chunk-TZOQWCVH.js +2 -0
  142. package/dist/chunk-TZOQWCVH.js.map +7 -0
  143. package/dist/chunk-VF7BGP6L.js +2 -0
  144. package/dist/chunk-VF7BGP6L.js.map +7 -0
  145. package/dist/chunk-VU3GIDZ3.js +2 -0
  146. package/dist/chunk-VU3GIDZ3.js.map +7 -0
  147. package/dist/chunk-VV7CFMPZ.js +2 -0
  148. package/dist/chunk-VV7CFMPZ.js.map +7 -0
  149. package/dist/chunk-W3H7GTJY.js +2 -0
  150. package/dist/chunk-W3H7GTJY.js.map +7 -0
  151. package/dist/chunk-X2ASKUFD.js +2 -0
  152. package/dist/chunk-X2ASKUFD.js.map +7 -0
  153. package/dist/chunk-X6AULZI4.js +1 -0
  154. package/dist/chunk-X6AULZI4.js.map +7 -0
  155. package/dist/chunk-XHOBNSBO.js +2 -0
  156. package/dist/chunk-XHOBNSBO.js.map +7 -0
  157. package/dist/chunk-XX2MVWFS.js +4 -0
  158. package/dist/chunk-XX2MVWFS.js.map +7 -0
  159. package/dist/chunk-XYZ6VZ5T.js +2 -0
  160. package/dist/chunk-XYZ6VZ5T.js.map +7 -0
  161. package/dist/chunk-YBAYEU25.js +2 -0
  162. package/dist/chunk-YBAYEU25.js.map +7 -0
  163. package/dist/chunk-YHEMA56R.js +2 -0
  164. package/dist/chunk-YHEMA56R.js.map +7 -0
  165. package/dist/chunk-Z2JBUHKA.js +2 -0
  166. package/dist/chunk-Z2JBUHKA.js.map +7 -0
  167. package/dist/chunk-Z2Z52GFT.js +2 -0
  168. package/dist/chunk-Z2Z52GFT.js.map +7 -0
  169. package/dist/chunk-ZPPELYNJ.js +2 -0
  170. package/dist/chunk-ZPPELYNJ.js.map +7 -0
  171. package/dist/chunk-ZVK4L5GK.js +2 -0
  172. package/dist/chunk-ZVK4L5GK.js.map +7 -0
  173. package/dist/chunk-ZWNQREWS.js +2 -0
  174. package/dist/chunk-ZWNQREWS.js.map +7 -0
  175. package/dist/components/badge.js +2 -0
  176. package/dist/components/badge.js.map +7 -0
  177. package/dist/components/breadcrumb.js +2 -0
  178. package/dist/components/breadcrumb.js.map +7 -0
  179. package/dist/components/button.js +2 -0
  180. package/dist/components/button.js.map +7 -0
  181. package/dist/components/calendar.js +2 -0
  182. package/dist/components/calendar.js.map +7 -0
  183. package/dist/components/cellediting.js +2 -0
  184. package/dist/components/cellediting.js.map +7 -0
  185. package/dist/components/chat.js +2 -0
  186. package/dist/components/chat.js.map +7 -0
  187. package/dist/components/checkbox.js +2 -0
  188. package/dist/components/checkbox.js.map +7 -0
  189. package/dist/components/checkboxgroup.js +2 -0
  190. package/dist/components/checkboxgroup.js.map +7 -0
  191. package/dist/components/chip.js +2 -0
  192. package/dist/components/chip.js.map +7 -0
  193. package/dist/components/codeviewer.js +2 -0
  194. package/dist/components/codeviewer.js.map +7 -0
  195. package/dist/components/combobox.js +2 -0
  196. package/dist/components/combobox.js.map +7 -0
  197. package/dist/components/commandpalette.js +2 -0
  198. package/dist/components/commandpalette.js.map +7 -0
  199. package/dist/components/container.js +2 -0
  200. package/dist/components/container.js.map +7 -0
  201. package/dist/components/dataview.js +2 -0
  202. package/dist/components/dataview.js.map +7 -0
  203. package/dist/components/datefield.js +2 -0
  204. package/dist/components/datefield.js.map +7 -0
  205. package/dist/components/daterangefield.js +2 -0
  206. package/dist/components/daterangefield.js.map +7 -0
  207. package/dist/components/dial.js +2 -0
  208. package/dist/components/dial.js.map +7 -0
  209. package/dist/components/dropdown.js +2 -0
  210. package/dist/components/dropdown.js.map +7 -0
  211. package/dist/components/fieldgroup.js +2 -0
  212. package/dist/components/fieldgroup.js.map +7 -0
  213. package/dist/components/fieldlist.js +2 -0
  214. package/dist/components/fieldlist.js.map +7 -0
  215. package/dist/components/fieldset.js +2 -0
  216. package/dist/components/fieldset.js.map +7 -0
  217. package/dist/components/filterbuilder.js +2 -0
  218. package/dist/components/filterbuilder.js.map +7 -0
  219. package/dist/components/form.js +2 -0
  220. package/dist/components/form.js.map +7 -0
  221. package/dist/components/formactions.js +2 -0
  222. package/dist/components/formactions.js.map +7 -0
  223. package/dist/components/formerrors.js +2 -0
  224. package/dist/components/formerrors.js.map +7 -0
  225. package/dist/components/formsection.js +2 -0
  226. package/dist/components/formsection.js.map +7 -0
  227. package/dist/components/grid.js +2 -0
  228. package/dist/components/grid.js.map +7 -0
  229. package/dist/components/icon.js +2 -0
  230. package/dist/components/icon.js.map +7 -0
  231. package/dist/components/inputgroup.js +2 -0
  232. package/dist/components/inputgroup.js.map +7 -0
  233. package/dist/components/label.js +2 -0
  234. package/dist/components/label.js.map +7 -0
  235. package/dist/components/listbox.js +2 -0
  236. package/dist/components/listbox.js.map +7 -0
  237. package/dist/components/lookupfield.js +2 -0
  238. package/dist/components/lookupfield.js.map +7 -0
  239. package/dist/components/menu.js +2 -0
  240. package/dist/components/menu.js.map +7 -0
  241. package/dist/components/messagebox.js +2 -0
  242. package/dist/components/messagebox.js.map +7 -0
  243. package/dist/components/navmenu.js +2 -0
  244. package/dist/components/navmenu.js.map +7 -0
  245. package/dist/components/numberfield.js +2 -0
  246. package/dist/components/numberfield.js.map +7 -0
  247. package/dist/components/pagination.js +2 -0
  248. package/dist/components/pagination.js.map +7 -0
  249. package/dist/components/panel.js +2 -0
  250. package/dist/components/panel.js.map +7 -0
  251. package/dist/components/pickerfield.js +2 -0
  252. package/dist/components/pickerfield.js.map +7 -0
  253. package/dist/components/radiogroup.js +2 -0
  254. package/dist/components/radiogroup.js.map +7 -0
  255. package/dist/components/searchgrid.js +2 -0
  256. package/dist/components/searchgrid.js.map +7 -0
  257. package/dist/components/secretfield.js +2 -0
  258. package/dist/components/secretfield.js.map +7 -0
  259. package/dist/components/select.js +2 -0
  260. package/dist/components/select.js.map +7 -0
  261. package/dist/components/slider.js +2 -0
  262. package/dist/components/slider.js.map +7 -0
  263. package/dist/components/spacer.js +2 -0
  264. package/dist/components/spacer.js.map +7 -0
  265. package/dist/components/spinner.js +2 -0
  266. package/dist/components/spinner.js.map +7 -0
  267. package/dist/components/stepform.js +2 -0
  268. package/dist/components/stepform.js.map +7 -0
  269. package/dist/components/stepper.js +2 -0
  270. package/dist/components/stepper.js.map +7 -0
  271. package/dist/components/suggestfield.js +2 -0
  272. package/dist/components/suggestfield.js.map +7 -0
  273. package/dist/components/table.js +2 -0
  274. package/dist/components/table.js.map +7 -0
  275. package/dist/components/tabs.js +2 -0
  276. package/dist/components/tabs.js.map +7 -0
  277. package/dist/components/textarea.js +2 -0
  278. package/dist/components/textarea.js.map +7 -0
  279. package/dist/components/textfield.js +2 -0
  280. package/dist/components/textfield.js.map +7 -0
  281. package/dist/components/toast.js +2 -0
  282. package/dist/components/toast.js.map +7 -0
  283. package/dist/components/toggle.js +2 -0
  284. package/dist/components/toggle.js.map +7 -0
  285. package/dist/components/toolbar.js +2 -0
  286. package/dist/components/toolbar.js.map +7 -0
  287. package/dist/components/tooltip.js +2 -0
  288. package/dist/components/tooltip.js.map +7 -0
  289. package/dist/components/tree.js +2 -0
  290. package/dist/components/tree.js.map +7 -0
  291. package/dist/components/viewmanager.js +2 -0
  292. package/dist/components/viewmanager.js.map +7 -0
  293. package/dist/components/viewport.js +2 -0
  294. package/dist/components/viewport.js.map +7 -0
  295. package/dist/components/widget.js +2 -0
  296. package/dist/components/widget.js.map +7 -0
  297. package/dist/components/window.js +2 -0
  298. package/dist/components/window.js.map +7 -0
  299. package/dist/core.js +2 -0
  300. package/dist/core.js.map +7 -0
  301. package/dist/css/badge.css +39 -0
  302. package/dist/css/base.css +180 -0
  303. package/dist/css/breadcrumb.css +53 -0
  304. package/dist/css/button.css +103 -0
  305. package/dist/css/calendar.css +108 -0
  306. package/dist/css/cellediting.css +33 -0
  307. package/dist/css/chat.css +232 -0
  308. package/dist/css/checkbox.css +64 -0
  309. package/dist/css/checkboxgroup.css +12 -0
  310. package/dist/css/chip.css +64 -0
  311. package/dist/css/codeviewer.css +109 -0
  312. package/dist/css/commandpalette.css +167 -0
  313. package/dist/css/container.css +5 -0
  314. package/dist/css/core.css +88 -0
  315. package/dist/css/dataview.css +56 -0
  316. package/dist/css/dial.css +203 -0
  317. package/dist/css/dropdown.css +13 -0
  318. package/dist/css/field.css +62 -0
  319. package/dist/css/fieldgroup.css +26 -0
  320. package/dist/css/fieldlist.css +84 -0
  321. package/dist/css/fieldset.css +68 -0
  322. package/dist/css/filterbuilder.css +125 -0
  323. package/dist/css/form.css +8 -0
  324. package/dist/css/formactions.css +40 -0
  325. package/dist/css/formerrors.css +39 -0
  326. package/dist/css/formsection.css +45 -0
  327. package/dist/css/grid.css +378 -0
  328. package/dist/css/icon.css +16 -0
  329. package/dist/css/inputgroup.css +58 -0
  330. package/dist/css/label.css +12 -0
  331. package/dist/css/layout.css +116 -0
  332. package/dist/css/listbox.css +50 -0
  333. package/dist/css/menu.css +92 -0
  334. package/dist/css/messagebox.css +6 -0
  335. package/dist/css/motion.css +29 -0
  336. package/dist/css/navmenu.css +115 -0
  337. package/dist/css/pagination.css +23 -0
  338. package/dist/css/panel.css +84 -0
  339. package/dist/css/pickerfield.css +85 -0
  340. package/dist/css/radiogroup.css +53 -0
  341. package/dist/css/searchgrid.css +37 -0
  342. package/dist/css/secretfield.css +73 -0
  343. package/dist/css/slider.css +107 -0
  344. package/dist/css/spacer.css +7 -0
  345. package/dist/css/stepform.css +46 -0
  346. package/dist/css/stepper.css +122 -0
  347. package/dist/css/table.css +36 -0
  348. package/dist/css/tabs.css +108 -0
  349. package/dist/css/textarea.css +11 -0
  350. package/dist/css/textfield.css +59 -0
  351. package/dist/css/toast.css +91 -0
  352. package/dist/css/toggle.css +39 -0
  353. package/dist/css/toolbar.css +14 -0
  354. package/dist/css/tooltip.css +17 -0
  355. package/dist/css/tree.css +94 -0
  356. package/dist/css/viewport.css +9 -0
  357. package/dist/css/widget.css +135 -0
  358. package/dist/css/window.css +35 -0
  359. package/dist/data.js +2 -0
  360. package/dist/data.js.map +7 -0
  361. package/dist/index.js +8 -0
  362. package/dist/index.js.map +7 -0
  363. package/dist/motion.js +2 -0
  364. package/dist/motion.js.map +7 -0
  365. package/dist/optikos.css +4240 -0
  366. package/dist/themes/compact.css +17 -0
  367. package/dist/themes/dark.css +53 -0
  368. package/dist/types/bind/index.d.ts +23 -0
  369. package/dist/types/components/badge.d.ts +1 -0
  370. package/dist/types/components/base/badge/badge.d.ts +18 -0
  371. package/dist/types/components/base/button/button.d.ts +34 -0
  372. package/dist/types/components/base/chip/chip.d.ts +27 -0
  373. package/dist/types/components/base/codeviewer/codeviewer.d.ts +48 -0
  374. package/dist/types/components/base/icon/icon.d.ts +17 -0
  375. package/dist/types/components/base/label/label.d.ts +14 -0
  376. package/dist/types/components/breadcrumb.d.ts +1 -0
  377. package/dist/types/components/button.d.ts +1 -0
  378. package/dist/types/components/calendar.d.ts +1 -0
  379. package/dist/types/components/cellediting.d.ts +1 -0
  380. package/dist/types/components/chat/chat/chat.d.ts +84 -0
  381. package/dist/types/components/chat.d.ts +1 -0
  382. package/dist/types/components/checkbox.d.ts +1 -0
  383. package/dist/types/components/checkboxgroup.d.ts +1 -0
  384. package/dist/types/components/chip.d.ts +1 -0
  385. package/dist/types/components/codeviewer.d.ts +1 -0
  386. package/dist/types/components/combobox.d.ts +1 -0
  387. package/dist/types/components/commandpalette.d.ts +1 -0
  388. package/dist/types/components/container.d.ts +1 -0
  389. package/dist/types/components/data/cellediting/cellediting.d.ts +10 -0
  390. package/dist/types/components/data/dataview/dataview.d.ts +61 -0
  391. package/dist/types/components/data/filterbuilder/filterbuilder.d.ts +73 -0
  392. package/dist/types/components/data/grid/grid.d.ts +177 -0
  393. package/dist/types/components/data/pagination/pagination.d.ts +31 -0
  394. package/dist/types/components/data/searchgrid/searchgrid.d.ts +63 -0
  395. package/dist/types/components/data/table/table.d.ts +26 -0
  396. package/dist/types/components/data/tree/tree.d.ts +71 -0
  397. package/dist/types/components/data/viewmanager/viewmanager.d.ts +86 -0
  398. package/dist/types/components/dataview.d.ts +1 -0
  399. package/dist/types/components/datefield.d.ts +1 -0
  400. package/dist/types/components/daterangefield.d.ts +1 -0
  401. package/dist/types/components/dates/calendar/calendar.d.ts +48 -0
  402. package/dist/types/components/dial.d.ts +1 -0
  403. package/dist/types/components/dropdown.d.ts +1 -0
  404. package/dist/types/components/feedback/spinner/spinner.d.ts +11 -0
  405. package/dist/types/components/fieldgroup.d.ts +1 -0
  406. package/dist/types/components/fieldlist.d.ts +1 -0
  407. package/dist/types/components/fields/checkbox/checkbox.d.ts +20 -0
  408. package/dist/types/components/fields/checkboxgroup/checkboxgroup.d.ts +27 -0
  409. package/dist/types/components/fields/combobox/combobox.d.ts +15 -0
  410. package/dist/types/components/fields/datefield/datefield.d.ts +30 -0
  411. package/dist/types/components/fields/daterangefield/daterangefield.d.ts +32 -0
  412. package/dist/types/components/fields/dial/dial.d.ts +84 -0
  413. package/dist/types/components/fields/listbox/listbox.d.ts +54 -0
  414. package/dist/types/components/fields/lookupfield/lookupfield.d.ts +25 -0
  415. package/dist/types/components/fields/numberfield/numberfield.d.ts +31 -0
  416. package/dist/types/components/fields/pickerfield/pickerfield.d.ts +77 -0
  417. package/dist/types/components/fields/radiogroup/radiogroup.d.ts +26 -0
  418. package/dist/types/components/fields/secretfield/secretfield.d.ts +52 -0
  419. package/dist/types/components/fields/select/select.d.ts +10 -0
  420. package/dist/types/components/fields/slider/slider.d.ts +62 -0
  421. package/dist/types/components/fields/suggestfield/suggestfield.d.ts +34 -0
  422. package/dist/types/components/fields/textarea/textarea.d.ts +16 -0
  423. package/dist/types/components/fields/textfield/textfield.d.ts +38 -0
  424. package/dist/types/components/fields/toggle/toggle.d.ts +9 -0
  425. package/dist/types/components/fieldset.d.ts +1 -0
  426. package/dist/types/components/filterbuilder.d.ts +1 -0
  427. package/dist/types/components/form/fieldgroup/fieldgroup.d.ts +33 -0
  428. package/dist/types/components/form/fieldlist/fieldlist.d.ts +58 -0
  429. package/dist/types/components/form/form/form.d.ts +68 -0
  430. package/dist/types/components/form/formactions/formactions.d.ts +34 -0
  431. package/dist/types/components/form/formerrors/formerrors.d.ts +23 -0
  432. package/dist/types/components/form/formsection/formsection.d.ts +26 -0
  433. package/dist/types/components/form/inputgroup/inputgroup.d.ts +28 -0
  434. package/dist/types/components/form/stepform/stepform.d.ts +64 -0
  435. package/dist/types/components/form.d.ts +1 -0
  436. package/dist/types/components/formactions.d.ts +1 -0
  437. package/dist/types/components/formerrors.d.ts +1 -0
  438. package/dist/types/components/formsection.d.ts +1 -0
  439. package/dist/types/components/grid.d.ts +1 -0
  440. package/dist/types/components/icon.d.ts +1 -0
  441. package/dist/types/components/inputgroup.d.ts +1 -0
  442. package/dist/types/components/label.d.ts +1 -0
  443. package/dist/types/components/layout/container/container.d.ts +1 -0
  444. package/dist/types/components/layout/fieldset/fieldset.d.ts +30 -0
  445. package/dist/types/components/layout/panel/panel.d.ts +53 -0
  446. package/dist/types/components/layout/panel/reload.d.ts +1 -0
  447. package/dist/types/components/layout/spacer/spacer.d.ts +12 -0
  448. package/dist/types/components/layout/toolbar/toolbar.d.ts +15 -0
  449. package/dist/types/components/layout/viewport/viewport.d.ts +7 -0
  450. package/dist/types/components/listbox.d.ts +1 -0
  451. package/dist/types/components/lookupfield.d.ts +1 -0
  452. package/dist/types/components/menu.d.ts +1 -0
  453. package/dist/types/components/messagebox.d.ts +1 -0
  454. package/dist/types/components/navigation/breadcrumb/breadcrumb.d.ts +32 -0
  455. package/dist/types/components/navigation/navmenu/navmenu.d.ts +63 -0
  456. package/dist/types/components/navigation/stepper/stepper.d.ts +31 -0
  457. package/dist/types/components/navigation/tabs/tabs.d.ts +57 -0
  458. package/dist/types/components/navmenu.d.ts +1 -0
  459. package/dist/types/components/numberfield.d.ts +1 -0
  460. package/dist/types/components/overlays/commandpalette/commandpalette.d.ts +80 -0
  461. package/dist/types/components/overlays/dropdown/dropdown.d.ts +41 -0
  462. package/dist/types/components/overlays/menu/menu.d.ts +56 -0
  463. package/dist/types/components/overlays/messagebox/messagebox.d.ts +61 -0
  464. package/dist/types/components/overlays/toast/toast.d.ts +45 -0
  465. package/dist/types/components/overlays/tooltip/tooltip.d.ts +13 -0
  466. package/dist/types/components/overlays/widget/widget.d.ts +61 -0
  467. package/dist/types/components/overlays/window/window.d.ts +38 -0
  468. package/dist/types/components/pagination.d.ts +1 -0
  469. package/dist/types/components/panel.d.ts +1 -0
  470. package/dist/types/components/pickerfield.d.ts +1 -0
  471. package/dist/types/components/radiogroup.d.ts +1 -0
  472. package/dist/types/components/searchgrid.d.ts +1 -0
  473. package/dist/types/components/secretfield.d.ts +1 -0
  474. package/dist/types/components/select.d.ts +1 -0
  475. package/dist/types/components/slider.d.ts +1 -0
  476. package/dist/types/components/spacer.d.ts +1 -0
  477. package/dist/types/components/spinner.d.ts +1 -0
  478. package/dist/types/components/stepform.d.ts +1 -0
  479. package/dist/types/components/stepper.d.ts +1 -0
  480. package/dist/types/components/suggestfield.d.ts +1 -0
  481. package/dist/types/components/table.d.ts +1 -0
  482. package/dist/types/components/tabs.d.ts +1 -0
  483. package/dist/types/components/textarea.d.ts +1 -0
  484. package/dist/types/components/textfield.d.ts +1 -0
  485. package/dist/types/components/toast.d.ts +1 -0
  486. package/dist/types/components/toggle.d.ts +1 -0
  487. package/dist/types/components/toolbar.d.ts +1 -0
  488. package/dist/types/components/tooltip.d.ts +1 -0
  489. package/dist/types/components/tree.d.ts +1 -0
  490. package/dist/types/components/viewmanager.d.ts +1 -0
  491. package/dist/types/components/viewport.d.ts +1 -0
  492. package/dist/types/components/widget.d.ts +1 -0
  493. package/dist/types/components/window.d.ts +1 -0
  494. package/dist/types/core/component.d.ts +94 -0
  495. package/dist/types/core/container.d.ts +43 -0
  496. package/dist/types/core/date.d.ts +14 -0
  497. package/dist/types/core/dom.d.ts +11 -0
  498. package/dist/types/core/emitter.d.ts +12 -0
  499. package/dist/types/core/field.d.ts +78 -0
  500. package/dist/types/core/focus.d.ts +18 -0
  501. package/dist/types/core/i18n.d.ts +12 -0
  502. package/dist/types/core/index.d.ts +15 -0
  503. package/dist/types/core/layer.d.ts +6 -0
  504. package/dist/types/core/position.d.ts +19 -0
  505. package/dist/types/core/registry.d.ts +12 -0
  506. package/dist/types/core/validators.d.ts +10 -0
  507. package/dist/types/core/virtual.d.ts +24 -0
  508. package/dist/types/data/column.d.ts +32 -0
  509. package/dist/types/data/format.d.ts +4 -0
  510. package/dist/types/data/index.d.ts +5 -0
  511. package/dist/types/data/model.d.ts +28 -0
  512. package/dist/types/data/proxy.d.ts +61 -0
  513. package/dist/types/data/store.d.ts +94 -0
  514. package/dist/types/index.d.ts +67 -0
  515. package/dist/types/layout/layout.d.ts +27 -0
  516. package/dist/types/motion/config.d.ts +83 -0
  517. package/dist/types/motion/core.d.ts +40 -0
  518. package/dist/types/motion/extras.d.ts +66 -0
  519. package/dist/types/motion/index.d.ts +3 -0
  520. package/dist/types/themes/define.d.ts +31 -0
  521. package/dist/types/themes/index.d.ts +1 -0
  522. package/dist/types/ui/enums.d.ts +82 -0
  523. package/dist/types/ui/index.d.ts +2 -0
  524. package/dist/types/ui/ui.d.ts +67 -0
  525. package/dist/ui.js +2 -0
  526. package/dist/ui.js.map +7 -0
  527. package/package.json +104 -4
package/CHANGELOG.md ADDED
@@ -0,0 +1,146 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project are documented here. The format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
4
+ and the project uses [Semantic Versioning](https://semver.org/). Until 1.0, minor versions may contain breaking changes.
5
+
6
+ ## [Unreleased]
7
+
8
+ ## [0.2.0] - 2026-11-10
9
+
10
+ ### Added
11
+
12
+ - Form utils: `showIf`/`enableIf` on any item of a form (a field hidden by its rule does not validate and is left out
13
+ of `getValues`), `Form.focusField(field)`, the form-level `dirty-change` event, and two components: `FormErrors`
14
+ (`type: 'formerrors'`, an error summary whose links reveal and focus each field) and `FormActions`
15
+ (`type: 'formactions'`, Cancel / Save with an "Unsaved changes" status, `requireChanges`, `sticky`).
16
+
17
+ - `FieldList` component (`type: 'fieldlist'`): a repeating block of fields (add, remove, reorder rows, by mouse or
18
+ keyboard); it is one form field whose value is an array of row objects, with `min`/`max`, and validating the form
19
+ validates every row.
20
+
21
+ - Compound fields: `FieldGroup` (`type: 'fieldgroup'`): several inputs under one label, one help line and one error
22
+ line (`role=group`); and `InputGroup` (`type: 'inputgroup'`): text (`R$`, `.com`) or buttons joined to any field's box,
23
+ the text read as part of the input's description.
24
+
25
+ - Form layouts: `columns` on Form, FieldSet and FormSection (a responsive grid), `colspan: 'full'`, `labelWidth` (left
26
+ labels in a column), FieldSet `variant` (`box`, `line`, `plain`) and `description`, and the `FormSection` component
27
+ (`type: 'formsection'`): title and description beside the fields, stacked when the section is narrow.
28
+
29
+ - Reload buttons: `reloadable` on Panel (so Window and Widget too) and on Tabs adds a ↻ that calls `onReload(panel)`; a
30
+ returned Promise shows the loading mask until it settles. `Panel.reload()`, `Tabs.reloadTab()`, `before-reload`/`reload`
31
+ events; R reloads a focused reloadable tab. New `refresh` icon.
32
+
33
+ - Widget: `resizable` (the inner edge while docked, a corner grip once moved; a focusable splitter with arrow keys) and
34
+ the `resize({ width, height })` event.
35
+
36
+ - `CodeViewer` component (`type: 'codeviewer'`): read-only code with syntax colors (ts/js, json, css, html, sh), line
37
+ numbers that a selection never copies, marked lines, `startLine`, wrap or scroll, and a copy button. The docs site
38
+ uses it for every code block, which also fixes the code fences of the guides (they were styled as inline code).
39
+
40
+ - Menu: `group` on items (named `role=group` sections, ungrouped first) and `search: true` (a search field that filters
41
+ the items; a search that matches a group name shows the whole group). FilterBuilder fields take a `group` too, like
42
+ `Column.group`: the `pick` menu is grouped and searchable past 6 fields, and the field select uses `<optgroup>`s.
43
+
44
+ - `Dial` component (`type: 'dial'`, `ui.dial`): picks one value from a range (an age, a year) or a list (the months) on
45
+ a flat ruler that slides under a fixed needle, with a large readout whose digits roll like an odometer. Snap points
46
+ (decades by default) get the labels, Page Up/Down jump between them, and a flick glides on to the nearest one ahead.
47
+ `shape: 'circle'` turns it into a clock face.
48
+
49
+ - `addMessages(lang, messages)` (from `optikos` and `optikos/core`): adds translation keys to a locale without overwriting
50
+ keys the app already set.
51
+
52
+ - `Grid<T>`: the record type flows from a typed `Store<T>` to `getSelection()`, `getStore()`, bulk and row actions and
53
+ column renderers; `Column.field` autocompletes the record's keys. `new Grid({ store })` infers it. Untyped grids keep
54
+ working as before (the default is `any`).
55
+
56
+ - Documentation in English with a Portuguese translation (`docs/pt-BR/`); the docs site has a language picker
57
+ (English/Português) that also switches the components' own messages, and the MCP server takes a `lang` argument.
58
+
59
+ - `defineTheme`: a plain value sets the group's own token (`radius: '0.75rem'` → `--op-radius`).
60
+ - Docs site redesigned as a showcase: a landing page with a live form and measured sizes, recipes (complete small
61
+ screens whose shown code is the code that runs), a gallery of the demos (published with the site) and tabbed
62
+ component pages.
63
+
64
+ - Grid plugins (`plugins: [...]`) and the first one, `cellEditing()`: double click or F2 to edit a cell, Enter to save,
65
+ Tab to the next editable cell; editors come from `Column.editor`. New Grid helpers for plugins: `cellAt`, `getCell`,
66
+ `getColumns`, `getActive`.
67
+
68
+ - `Tree` component: expand/collapse, single or multiple selection, tri-state cascading checkboxes, children loaded on
69
+ demand, filter, and the WAI-ARIA tree keyboard.
70
+
71
+ - `Toggle` (an on/off switch, `role="switch"`) and the `ui.toggle()` shortcut.
72
+
73
+ - `CheckboxGroup` (several choices; the value is the list of checked values) and `ui.checkGroup()`.
74
+
75
+ - `Badge` (status label or count in six tones) and `Chip` (selectable filter or removable tag).
76
+
77
+ ### Changed
78
+
79
+ - No automatic focus on fields: on a phone it pops up the keyboard over the page. Window, Widget, `MessageBox.prompt`
80
+ and StepForm (on a new step) now focus the dialog, widget or step panel itself; `autoFocus: true` focuses the first
81
+ field as before. A Menu with `search` and the Grid's column menu open on their first item (typing a letter goes to
82
+ the search field), and LookupField's search window opens on the dialog. Focus that answers an explicit action stays:
83
+ adding a row, editing a cell, a failed validation jumping to the field.
84
+ - MessageBox (`alert`, `confirm`, `prompt`) no longer dims the page: it is still modal, over a clear backdrop. Pass
85
+ `mask: true` to dim it. Window has the same `mask` option (default `true`) and `setMask`.
86
+ - **Themes (breaking):** the package now ships only `light` (default), `dark` and `compact`. The default look is the
87
+ former `corporate` theme (steel blue on cool gray, small radii, hairline borders, a navy sidebar, 2.375rem controls,
88
+ 2.75rem rows, 15px text) and `dark` is its night version. `optikos/themes/{corporate,brutal,soft,terminal,editorial,brand}.css`
89
+ were removed, and `ThemeName` keeps only `Light` and `Dark`. Grid headers and panel title bars now use the strong
90
+ border, the selected Grid row shows a primary bar (`--op-grid-selected-bar`, `--op-grid-selected-bar-width`), the
91
+ primary button has a subtle inner shadow (`--op-button-primary-shadow`) and the tab bar sits on `surface-2`; new
92
+ tokens `--op-grid-header-border` and `--op-panel-header-border`.
93
+ - Grid: `role="grid"` (with focus, `aria-activedescendant`, row and column counts) moved from the root element to an inner
94
+ `.op-grid__table`, because the root also holds the bulk bar and the pager. Code that read those attributes from
95
+ `grid.el` should query `grid.el.querySelector('[role=grid]')`; `grid.focus()` keeps working.
96
+ - Accessibility fixes found by automated axe checks in every theme: Button keeps its name while loading (and is
97
+ `aria-disabled`), Stepper steps keep their names on phones, DateField/DateRangeField follow the date picker combobox
98
+ pattern, an unnamed Dropdown dialog is named by its anchor, and contrast fixes in the light (`fg-muted`), `dark`
99
+ (primary), `soft`, `brutal`, `brand` and `brand night` themes and in Chat bubbles.
100
+ - Each component now ships its own `en`/`pt-BR` messages, so the core is 2.2 kB (gzip) smaller and every standalone component about 0.5 kB smaller.
101
+ Custom locales passed to `setLocale({...})` keep working; missing keys still fall back to English.
102
+
103
+ ### Fixed
104
+
105
+ - Floating elements (menus, dropdowns) taller than the room on both sides of their anchor are capped to the larger side
106
+ and scroll, instead of running off the window (long menus in big themes).
107
+
108
+ - Tabs: each panel has `tabindex="0"` (WAI-ARIA tabs pattern), so a panel with nothing focusable inside, or one that
109
+ scrolls, can be reached with the keyboard.
110
+
111
+ - `ariaLabel` on a field without a visible label now names its input (it used to land on the wrapper).
112
+ - Grid: the row-actions column header has a (visually hidden) name.
113
+
114
+ - `ui.grid(2, ...)` keeps the column count numeric, so the grid collapses to one column on narrow containers like
115
+ `layout: { type: 'grid', columns: 2 }` does.
116
+ - `ui.*` containers accept declarative configs among their items (`ui.form([{ type: 'fieldset', ... }, ui.text(...)])`)
117
+ without a type error.
118
+
119
+ - Store: sorting text is 13× faster (100k records: 5.4 s → 0.41 s). The comparison reuses one `Intl.Collator` instead of
120
+ building one per `localeCompare` call; the order is unchanged.
121
+
122
+ ## [0.1.0] - 2026-11-08
123
+
124
+ First public release.
125
+
126
+ ### Added
127
+
128
+ - Core: `Component`, `Container`, `Field`, the `create`/`register` registry, layouts (`fit`, `hbox`, `vbox`, `border`,
129
+ `grid`, `card`, responsive below a container width), validators, i18n (`en`, `pt-BR`), focus and positioning utilities,
130
+ list virtualization.
131
+ - Data: `Store` with local or remote sorting, filter trees (AND/OR) and paging; `Model`; memory, function and REST proxies; formatters.
132
+ - Components: button, icon, label; container, panel, viewport, fieldset, toolbar, spacer; textfield, textarea,
133
+ numberfield, secretfield, checkbox, radiogroup, select, combobox, suggestfield, lookupfield, datefield, daterangefield,
134
+ slider, listbox; form (with tabs) and stepform; grid, table, dataview, pagination, filterbuilder, searchgrid,
135
+ viewmanager; calendar; window, MessageBox, toast, menu, dropdown, tooltip, widget, commandpalette; tabs, breadcrumb,
136
+ navmenu, stepper; spinner and loading masks; chat.
137
+ - `optikos/bind`: `signal`, `computed`, `effect`, `bind`, `fromStore`.
138
+ - `optikos/motion`: animation helpers on the Web Animations API with one global setting and a kill switch.
139
+ - `optikos/ui`: `ui.*` shortcuts and enums.
140
+ - Themes: design tokens in `@layer optikos`, `defineTheme()`/`setTheme()`, and the ready-made themes `dark`, `compact`,
141
+ `corporate`, `soft`, `brutal`, `terminal`, `editorial` and `brand`.
142
+ - Per-component entry points (`optikos/components/<name>`) and stylesheets (`optikos/css/<name>.css`).
143
+
144
+ [Unreleased]: https://github.com/Denis-Zickuhr/optikos/compare/v0.2.0...HEAD
145
+ [0.2.0]: https://github.com/Denis-Zickuhr/optikos/compare/v0.1.0...v0.2.0
146
+ [0.1.0]: https://github.com/Denis-Zickuhr/optikos/releases/tag/v0.1.0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Denis Zickuhr
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -1,3 +1,214 @@
1
- # Temporary Holding Version
1
+ <p align="center"><img src="https://raw.githubusercontent.com/Denis-Zickuhr/optikos/main/site/seal.svg" alt="Optikos" width="150" /></p>
2
2
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
3
+ # Optikos
4
+
5
+ [![npm](https://img.shields.io/npm/v/optikos)](https://www.npmjs.com/package/optikos)
6
+ [![license: MIT](https://img.shields.io/badge/license-MIT-blue)](https://github.com/Denis-Zickuhr/optikos/blob/main/LICENSE)
7
+
8
+ Declarative UI components in plain TypeScript: describe screens, forms, grids and windows as configuration objects,
9
+ with no runtime dependencies.
10
+
11
+ - **Fast**: no virtual DOM. Setters update only the part of the DOM that changed, and grids and long lists are virtualized.
12
+ - **Light**: zero runtime dependencies. Each component can be imported on its own, and its size is checked on every build.
13
+ - **Complete**: fields, pickers, data grid, filter builder, windows, menus, tabs, command palette, chat and more.
14
+ - **Themeable**: every color, space, radius, font and shadow is a CSS custom property, and all styles live in `@layer optikos`.
15
+ - **Accessible**: keyboard support, focus management and ARIA are part of each component's spec.
16
+ - **Extensible**: your own components, layouts and themes use the same public API as the built-in ones.
17
+
18
+ ## Install
19
+
20
+ ```sh
21
+ npm i optikos
22
+ ```
23
+
24
+ ## Quick start
25
+
26
+ ```ts
27
+ import { create, toast, type Form } from 'optikos';
28
+ import 'optikos/optikos.css';
29
+ import 'optikos/themes/dark.css';
30
+
31
+ document.documentElement.setAttribute('data-op-theme', 'dark');
32
+
33
+ const form = create<Form>({
34
+ type: 'form',
35
+ items: [
36
+ { type: 'textfield', name: 'name', label: 'Name', required: true },
37
+ { type: 'textfield', name: 'email', label: 'Email', inputType: 'email' },
38
+ { type: 'select', name: 'plan', label: 'Plan', options: ['Free', 'Pro'] },
39
+ ],
40
+ });
41
+
42
+ create({
43
+ type: 'panel',
44
+ title: 'New customer',
45
+ renderTo: document.body,
46
+ items: [form],
47
+ buttons: [{ text: 'Save', variant: 'primary', handler: () => form.isValid() && toast(`Saved ${form.getValues().name}`) }],
48
+ });
49
+ ```
50
+
51
+ `create()` builds a component tree from a config. Each `type` is a registered component class, so you can also write
52
+ `new TextField({ ... })`, or use the `ui` shortcuts:
53
+
54
+ ```ts
55
+ import { ui } from 'optikos';
56
+
57
+ const signup = ui.form([
58
+ ui.text('name', 'Name', { required: true }),
59
+ ui.email('email', 'Email'),
60
+ ui.row(ui.date('from', 'From'), ui.date('to', 'To')),
61
+ ui.primary('Sign up', () => signup.submit()),
62
+ ]);
63
+ ```
64
+
65
+ ### Data grid
66
+
67
+ ```ts
68
+ import { create, Store } from 'optikos';
69
+
70
+ const orders = new Store({
71
+ data: [
72
+ { id: 1, customer: 'Ada Lovelace', total: 120 },
73
+ { id: 2, customer: 'Alan Turing', total: 80 },
74
+ ],
75
+ });
76
+
77
+ create({
78
+ type: 'grid',
79
+ store: orders,
80
+ height: 320,
81
+ paging: true,
82
+ renderTo: document.body,
83
+ columns: [
84
+ { field: 'id', header: '#', width: 60, sortable: true },
85
+ { field: 'customer', header: 'Customer', flex: 1, sortable: true },
86
+ { field: 'total', header: 'Total', format: 'money', align: 'right' },
87
+ ],
88
+ });
89
+
90
+ orders.filter({ field: 'customer', op: 'contains', value: 'ada' });
91
+ ```
92
+
93
+ A `Store` can also load from a function or a REST endpoint, with remote sorting, filtering and paging.
94
+
95
+ ### Reactive bindings (optional)
96
+
97
+ Components only have setters. `optikos/bind` adds signals on top and calls those setters for you:
98
+
99
+ ```ts
100
+ import { create, type Button } from 'optikos';
101
+ import { signal, bind } from 'optikos/bind';
102
+
103
+ const clicks = signal(0);
104
+ const button = create<Button>({ type: 'button', text: 'Click me', renderTo: document.body, handler: () => clicks.update((n) => n + 1) });
105
+ bind(button, { text: () => `Clicked ${clicks()} times` });
106
+ ```
107
+
108
+ ## Imports
109
+
110
+ | Import | What you get |
111
+ |---|---|
112
+ | `optikos` | everything: core, data, themes, motion, `ui`, and every component registered |
113
+ | `optikos/core` | `Component`, `Container`, `Field`, `create`, `register`, layouts, validators, i18n (no components) |
114
+ | `optikos/components/<name>` | one component, which registers its `type` (e.g. `optikos/components/grid`) |
115
+ | `optikos/data` | `Store`, `Model`, proxies, formatters |
116
+ | `optikos/bind` | `signal`, `computed`, `effect`, `bind`, `fromStore` |
117
+ | `optikos/motion` | animation helpers and the global motion settings |
118
+ | `optikos/ui` | the `ui.*` shortcuts and enums (`Variant`, `Direction`, `Op`...) |
119
+ | `optikos/optikos.css` | all styles: tokens, layouts and every component |
120
+ | `optikos/css/<name>.css` | one stylesheet (`base.css` holds the tokens; `core.css`, `field.css` and `layout.css` are shared) |
121
+ | `optikos/themes/<theme>.css` | a ready-made theme |
122
+
123
+ Components register themselves when their module is imported, so the package is marked as having side effects.
124
+ Importing from `optikos` therefore includes every component. To ship less, import the core and only the components you use:
125
+
126
+ ```ts
127
+ import { create } from 'optikos/core';
128
+ import 'optikos/components/button';
129
+ import 'optikos/components/textfield';
130
+
131
+ create({ type: 'textfield', label: 'Search', renderTo: document.body });
132
+ ```
133
+
134
+ ## Components
135
+
136
+ | Category | Components (`type`) |
137
+ |---|---|
138
+ | Base | `button`, `icon`, `label`, `badge`, `chip` |
139
+ | Layout | `container`, `panel`, `viewport`, `fieldset`, `toolbar`, `spacer`, plus the layouts `fit`, `hbox`, `vbox`, `border`, `grid`, `card` |
140
+ | Fields | `textfield`, `textarea`, `numberfield`, `secretfield`, `checkbox`, `toggle`, `checkboxgroup`, `radiogroup`, `select`, `combobox`, `suggestfield`, `lookupfield`, `datefield`, `daterangefield`, `slider`, `listbox` |
141
+ | Forms | `form` (validation, `load`/`getValues`, tabs), `stepform` (multi-step wizard) |
142
+ | Data | `grid` (virtualized, sorting, selection, paging, column menu, bulk actions, inline editing with the `cellEditing()` plugin), `table`, `dataview`, `pagination`, `filterbuilder`, `searchgrid`, `viewmanager` (saved views), `tree` |
143
+ | Dates | `calendar` (single date or range) |
144
+ | Overlays | `window`, `MessageBox` (alert/confirm/prompt), `toast()`, `menu`, `dropdown`, `tooltip`, `widget`, `commandpalette` |
145
+ | Navigation | `tabs`, `breadcrumb`, `navmenu`, `stepper` |
146
+ | Feedback | `spinner`, plus `loading: true` on any component |
147
+ | Chat | `chat` (messages, typing indicator, streaming replies, suggestions) |
148
+
149
+ ## Themes and tokens
150
+
151
+ All styles are in `@layer optikos`, so any CSS you write outside a layer wins without `!important`.
152
+ A theme is a value of `data-op-theme`, on `<html>` or on any element to scope it. Themes can be combined: `data-op-theme="dark compact"`.
153
+
154
+ Ready-made themes: `light` (default, included in `optikos.css`), `dark` and `compact` (density). Each one is a file in
155
+ `optikos/themes/<theme>.css`.
156
+
157
+ Write a theme in CSS:
158
+
159
+ ```css
160
+ @layer optikos {
161
+ [data-op-theme~='ocean'] { --op-color-primary: #0e7490; --op-radius: 0.125rem; }
162
+ }
163
+ ```
164
+
165
+ or in TypeScript, with typed keys:
166
+
167
+ ```ts
168
+ import { defineTheme, setTheme } from 'optikos';
169
+
170
+ const brand = defineTheme({
171
+ color: { primary: '#7c3aed', primarySoft: '#f5f3ff' },
172
+ button: { radius: '62.5rem' },
173
+ }, 'brand');
174
+
175
+ brand.inject(); // installs the CSS without activating it
176
+ setTheme('dark brand'); // sets data-op-theme on <html> (or on any element: setTheme(names, el))
177
+ ```
178
+
179
+ Components also accept per-instance tokens: `{ type: 'button', theme: { radius: '0' } }`.
180
+
181
+ ## Browser support
182
+
183
+ Current evergreen browsers. The JavaScript targets ES2022, and the CSS uses cascade layers, `:has()`, `color-mix()`,
184
+ `inert` and `dvh` units, which works in Chrome/Edge 111+, Firefox 121+ and Safari 16.2+. No polyfills are included.
185
+
186
+ ## Documentation and demos
187
+
188
+ - [Docs site](https://denis-zickuhr.github.io/optikos/), in English and Portuguese: every component with live, editable
189
+ examples, its spec sheet, the guides and the design tokens.
190
+ - [Docs sources](https://github.com/Denis-Zickuhr/optikos/tree/main/docs) (Portuguese translation in `docs/pt-BR`): one spec sheet per component in
191
+ [`docs/components`](https://github.com/Denis-Zickuhr/optikos/tree/main/docs/components), plus guides on
192
+ [theming](https://github.com/Denis-Zickuhr/optikos/blob/main/docs/theming.md),
193
+ [motion](https://github.com/Denis-Zickuhr/optikos/blob/main/docs/motion.md),
194
+ [`ui` shortcuts](https://github.com/Denis-Zickuhr/optikos/blob/main/docs/ui.md) and
195
+ [architecture decisions](https://github.com/Denis-Zickuhr/optikos/blob/main/docs/architecture.md) (in Portuguese).
196
+ - [Recipes and live demos](https://denis-zickuhr.github.io/optikos/#/demos) on the docs site: CRM, admin dashboard, ERP,
197
+ chat, photo gallery, shop, event landing page, workbench, motion lab and customization ([source](https://github.com/Denis-Zickuhr/optikos/tree/main/demos)).
198
+
199
+ ## Contributing / Development
200
+
201
+ ```sh
202
+ npm install
203
+ npm run dev # dev server: index of sandboxes and demos at /dev/
204
+ npm run sandbox -- fields # one sandbox category
205
+ npm run demo -- crm # one demo
206
+ npm run site # living docs, with live reload
207
+ npm run check # generate index, typecheck, tests, build with size budgets
208
+ ```
209
+
210
+ See [CONTRIBUTING.md](CONTRIBUTING.md) and the project rules in [AGENTS.md](AGENTS.md).
211
+
212
+ ## License
213
+
214
+ [MIT](LICENSE) © Denis Zickuhr. The built-in icons come from Lucide and Feather; see [THIRD_PARTY_NOTICES.md](THIRD_PARTY_NOTICES.md).
@@ -0,0 +1,83 @@
1
+ # Third-party notices
2
+
3
+ Optikos is MIT licensed (see `LICENSE`). It ships the third-party material listed below.
4
+
5
+ ## Built-in icons
6
+
7
+ The SVG paths of the built-in icons (`src/components/base/icon/icon.ts`, bundled into `dist/`) are taken from or
8
+ derived from [Lucide](https://lucide.dev) (ISC) and [Feather](https://feathericons.com) (MIT). Lucide's own license
9
+ also covers the Lucide icons that come from Feather. Both license texts follow.
10
+
11
+ ### Lucide — ISC License
12
+
13
+ ```
14
+ ISC License
15
+
16
+ Copyright (c) 2026 Lucide Icons and Contributors
17
+
18
+ Permission to use, copy, modify, and/or distribute this software for any
19
+ purpose with or without fee is hereby granted, provided that the above
20
+ copyright notice and this permission notice appear in all copies.
21
+
22
+ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
23
+ WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
24
+ MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
25
+ ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
26
+ WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
27
+ ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
28
+ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
29
+
30
+ ---
31
+
32
+ The following Lucide icons are derived from the Feather project:
33
+
34
+ airplay, alert-circle, alert-octagon, alert-triangle, aperture, arrow-down-circle, arrow-down-left, arrow-down-right, arrow-down, arrow-left-circle, arrow-left, arrow-right-circle, arrow-right, arrow-up-circle, arrow-up-left, arrow-up-right, arrow-up, at-sign, calendar, cast, check, chevron-down, chevron-left, chevron-right, chevron-up, chevrons-down, chevrons-left, chevrons-right, chevrons-up, circle, clipboard, clock, code, columns, command, compass, corner-down-left, corner-down-right, corner-left-down, corner-left-up, corner-right-down, corner-right-up, corner-up-left, corner-up-right, crosshair, database, divide-circle, divide-square, dollar-sign, download, external-link, feather, frown, hash, headphones, help-circle, info, italic, key, layout, life-buoy, link-2, link, loader, lock, log-in, log-out, maximize, meh, minimize, minimize-2, minus-circle, minus-square, minus, monitor, moon, more-horizontal, more-vertical, move, music, navigation-2, navigation, octagon, pause-circle, percent, plus-circle, plus-square, plus, power, radio, rss, search, server, share, shopping-bag, sidebar, smartphone, smile, square, table-2, tablet, target, terminal, trash-2, trash, triangle, tv, type, upload, x-circle, x-octagon, x-square, x, zoom-in, zoom-out
35
+
36
+ The MIT License (MIT) (for the icons listed above)
37
+
38
+ Copyright (c) 2013-present Cole Bemis
39
+
40
+ Permission is hereby granted, free of charge, to any person obtaining a copy
41
+ of this software and associated documentation files (the "Software"), to deal
42
+ in the Software without restriction, including without limitation the rights
43
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
44
+ copies of the Software, and to permit persons to whom the Software is
45
+ furnished to do so, subject to the following conditions:
46
+
47
+ The above copyright notice and this permission notice shall be included in all
48
+ copies or substantial portions of the Software.
49
+
50
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
51
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
52
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
53
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
54
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
55
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
56
+ SOFTWARE.
57
+ ```
58
+
59
+ ### Feather — MIT License
60
+
61
+ ```
62
+ The MIT License (MIT)
63
+
64
+ Copyright (c) 2013-2023 Cole Bemis
65
+
66
+ Permission is hereby granted, free of charge, to any person obtaining a copy
67
+ of this software and associated documentation files (the "Software"), to deal
68
+ in the Software without restriction, including without limitation the rights
69
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
70
+ copies of the Software, and to permit persons to whom the Software is
71
+ furnished to do so, subject to the following conditions:
72
+
73
+ The above copyright notice and this permission notice shall be included in all
74
+ copies or substantial portions of the Software.
75
+
76
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
77
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
78
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
79
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
80
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
81
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
82
+ SOFTWARE.
83
+ ```
package/dist/bind.js ADDED
@@ -0,0 +1,2 @@
1
+ import"./chunk-4C666HHU.js";var s;function d(t){let n=t,e=new Set,o=(()=>(s&&(e.add(s),s.deps.add(e)),n));return o.set=r=>{if(!Object.is(r,n)){n=r;for(let i of[...e])i.run()}},o.update=r=>o.set(r(n)),o}function f(t){let n,e={deps:new Set,run(){for(let r of e.deps)r.delete(e);e.deps.clear(),n?.();let o=s;s=e;try{n=t()}finally{s=o}}};return e.run(),()=>{for(let o of e.deps)o.delete(e);e.deps.clear(),n?.()}}function a(t){let n=d(void 0);return f(()=>n.set(t())),n}function p(t){let n=d(0);return t.subscribe(()=>n.update(e=>e+1)),()=>(n(),t)}function l(t,n){for(let e in n){let o=`set${e[0].toUpperCase()}${e.slice(1)}`,r=t[o];if(typeof r!="function")throw new Error(`Optikos bind: ${t.constructor.name} has no ${o}()`);let i=n[e];t.own(f(()=>{r.call(t,i())}));let c=i.set;e==="value"&&c&&t.own(t.on("change",u=>c(u)))}}export{l as bind,a as computed,f as effect,p as fromStore,d as signal};
2
+ //# sourceMappingURL=bind.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/bind/index.ts"],
4
+ "sourcesContent": ["// Optional reactive layer. Components only know setters; this module calls them from signals.\n// Nothing in `core` or `components` imports this file.\nimport type { Component } from '../core/component';\n\ntype Sub = () => void;\nlet running: Effect | undefined;\n\ninterface Effect {\n run(): void;\n deps: Set<Set<Effect>>;\n}\n\nexport interface Signal<T> {\n (): T;\n set(value: T): void;\n update(fn: (v: T) => T): void;\n}\n\nexport function signal<T>(initial: T): Signal<T> {\n let value = initial;\n const subs = new Set<Effect>();\n const read = (() => {\n if (running) {\n subs.add(running);\n running.deps.add(subs);\n }\n return value;\n }) as Signal<T>;\n read.set = (v) => {\n if (Object.is(v, value)) return;\n value = v;\n for (const e of [...subs]) e.run();\n };\n read.update = (fn) => read.set(fn(value));\n return read;\n}\n\n/** Runs `fn` now and again whenever a signal it read changes. Returns the dispose function. */\nexport function effect(fn: () => void | Sub): () => void {\n let cleanup: void | Sub;\n const e: Effect = {\n deps: new Set(),\n run() {\n for (const d of e.deps) d.delete(e);\n e.deps.clear();\n cleanup?.();\n const prev = running;\n running = e;\n try {\n cleanup = fn();\n } finally {\n running = prev;\n }\n },\n };\n e.run();\n return () => {\n for (const d of e.deps) d.delete(e);\n e.deps.clear();\n cleanup?.();\n };\n}\n\n/** A read-only signal derived from others. */\nexport function computed<T>(fn: () => T): () => T {\n const s = signal<T>(undefined as T);\n effect(() => s.set(fn()));\n return s;\n}\n\n/** Wraps a Store (or anything with `subscribe`) so reading it inside an effect/computed re-runs that effect on every change. Call it once, outside effects. */\nexport function fromStore<S extends { subscribe(fn: () => void): () => void }>(store: S): () => S {\n const tick = signal(0);\n store.subscribe(() => tick.update((n) => n + 1));\n return () => (tick(), store);\n}\n\n/**\n * `bind(button, { text: () => `Count: ${n()}`, disabled: isBusy })` \u2192 `button.setText(...)`, `button.setDisabled(...)`\n * re-run when the sources change, and are disposed with the component. A source that is a writable signal on `value`\n * is two-way: the field's `change` event writes back.\n */\nexport function bind(cmp: Component<any>, map: Record<string, () => unknown>): void {\n for (const key in map) {\n const setter = `set${key[0].toUpperCase()}${key.slice(1)}`;\n const fn = (cmp as unknown as Record<string, unknown>)[setter];\n if (typeof fn !== 'function') throw new Error(`Optikos bind: ${cmp.constructor.name} has no ${setter}()`);\n const src = map[key];\n cmp.own(effect(() => void fn.call(cmp, src())));\n const write = (src as { set?: (v: unknown) => void }).set;\n if (key === 'value' && write) cmp.own(cmp.on('change', (v) => write(v)));\n }\n}\n"],
5
+ "mappings": "4BAKA,IAAIA,EAaG,SAASC,EAAUC,EAAuB,CAC/C,IAAIC,EAAQD,EACNE,EAAO,IAAI,IACXC,GAAQ,KACRL,IACFI,EAAK,IAAIJ,CAAO,EAChBA,EAAQ,KAAK,IAAII,CAAI,GAEhBD,IAET,OAAAE,EAAK,IAAOC,GAAM,CAChB,GAAI,QAAO,GAAGA,EAAGH,CAAK,EACtB,CAAAA,EAAQG,EACR,QAAWC,IAAK,CAAC,GAAGH,CAAI,EAAGG,EAAE,IAAI,EACnC,EACAF,EAAK,OAAUG,GAAOH,EAAK,IAAIG,EAAGL,CAAK,CAAC,EACjCE,CACT,CAGO,SAASI,EAAOD,EAAkC,CACvD,IAAIE,EACE,EAAY,CAChB,KAAM,IAAI,IACV,KAAM,CACJ,QAAWC,KAAK,EAAE,KAAMA,EAAE,OAAO,CAAC,EAClC,EAAE,KAAK,MAAM,EACbD,IAAU,EACV,IAAME,EAAOZ,EACbA,EAAU,EACV,GAAI,CACFU,EAAUF,EAAG,CACf,QAAE,CACAR,EAAUY,CACZ,CACF,CACF,EACA,SAAE,IAAI,EACC,IAAM,CACX,QAAWD,KAAK,EAAE,KAAMA,EAAE,OAAO,CAAC,EAClC,EAAE,KAAK,MAAM,EACbD,IAAU,CACZ,CACF,CAGO,SAASG,EAAYL,EAAsB,CAChD,IAAMM,EAAIb,EAAU,MAAc,EAClC,OAAAQ,EAAO,IAAMK,EAAE,IAAIN,EAAG,CAAC,CAAC,EACjBM,CACT,CAGO,SAASC,EAA+DC,EAAmB,CAChG,IAAMC,EAAOhB,EAAO,CAAC,EACrB,OAAAe,EAAM,UAAU,IAAMC,EAAK,OAAQC,GAAMA,EAAI,CAAC,CAAC,EACxC,KAAOD,EAAK,EAAGD,EACxB,CAOO,SAASG,EAAKC,EAAqBC,EAA0C,CAClF,QAAWC,KAAOD,EAAK,CACrB,IAAME,EAAS,MAAMD,EAAI,CAAC,EAAE,YAAY,CAAC,GAAGA,EAAI,MAAM,CAAC,CAAC,GAClDd,EAAMY,EAA2CG,CAAM,EAC7D,GAAI,OAAOf,GAAO,WAAY,MAAM,IAAI,MAAM,iBAAiBY,EAAI,YAAY,IAAI,WAAWG,CAAM,IAAI,EACxG,IAAMC,EAAMH,EAAIC,CAAG,EACnBF,EAAI,IAAIX,EAAO,IAAG,CAAQD,EAAG,KAAKY,EAAKI,EAAI,CAAC,EAAC,CAAC,EAC9C,IAAMC,EAASD,EAAuC,IAClDF,IAAQ,SAAWG,GAAOL,EAAI,IAAIA,EAAI,GAAG,SAAWd,GAAMmB,EAAMnB,CAAC,CAAC,CAAC,CACzE,CACF",
6
+ "names": ["running", "signal", "initial", "value", "subs", "read", "v", "e", "fn", "effect", "cleanup", "d", "prev", "computed", "s", "fromStore", "store", "tick", "n", "bind", "cmp", "map", "key", "setter", "src", "write"]
7
+ }
@@ -0,0 +1,2 @@
1
+ import{a as i}from"./chunk-A2NKDOYN.js";import{a as o}from"./chunk-TIPK3SCJ.js";var t=class extends i{baseCls="op-spacer";tag="span";onRender(){let e=this.config;e.width==null&&e.flex==null&&!e.line&&(this.el.style.flex="1"),this.setLine(!!e.line)}setLine(e){this.config.line=e,this.rendered&&(this.el.classList.toggle("op-spacer--line",e),e?this.el.setAttribute("role","separator"):this.el.setAttribute("aria-hidden","true"),e&&this.el.removeAttribute("aria-hidden"))}};o("spacer",t);export{t as a};
2
+ //# sourceMappingURL=chunk-23XLG2EM.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/components/layout/spacer/spacer.ts"],
4
+ "sourcesContent": ["import { Component, type ComponentConfig } from '../../../core/component';\nimport { register } from '../../../core/registry';\n\nexport interface SpacerConfig extends ComponentConfig {\n /** Renders a vertical separator line. */\n line?: boolean;\n}\n\n/** Without `width`/`flex` it takes the free space (`flex: 1`), pushing the next items away. */\nexport class Spacer extends Component<SpacerConfig> {\n protected override baseCls = 'op-spacer';\n protected override tag = 'span' as const;\n protected override onRender() {\n const c = this.config;\n if (c.width == null && c.flex == null && !c.line) this.el.style.flex = '1';\n this.setLine(!!c.line);\n }\n setLine(line: boolean) {\n this.config.line = line;\n if (!this.rendered) return;\n this.el.classList.toggle('op-spacer--line', line);\n if (line) this.el.setAttribute('role', 'separator');\n else this.el.setAttribute('aria-hidden', 'true');\n if (line) this.el.removeAttribute('aria-hidden');\n }\n}\nregister('spacer', Spacer);\n"],
5
+ "mappings": "gFASO,IAAMA,EAAN,cAAqBC,CAAwB,CAC/B,QAAU,YACV,IAAM,OACN,UAAW,CAC5B,IAAMC,EAAI,KAAK,OACXA,EAAE,OAAS,MAAQA,EAAE,MAAQ,MAAQ,CAACA,EAAE,OAAM,KAAK,GAAG,MAAM,KAAO,KACvE,KAAK,QAAQ,CAAC,CAACA,EAAE,IAAI,CACvB,CACA,QAAQC,EAAe,CACrB,KAAK,OAAO,KAAOA,EACd,KAAK,WACV,KAAK,GAAG,UAAU,OAAO,kBAAmBA,CAAI,EAC5CA,EAAM,KAAK,GAAG,aAAa,OAAQ,WAAW,EAC7C,KAAK,GAAG,aAAa,cAAe,MAAM,EAC3CA,GAAM,KAAK,GAAG,gBAAgB,aAAa,EACjD,CACF,EACAC,EAAS,SAAUJ,CAAM",
6
+ "names": ["Spacer", "Component", "c", "line", "register"]
7
+ }
@@ -0,0 +1,2 @@
1
+ import{a as S}from"./chunk-JOFQJGZK.js";import{a as F}from"./chunk-VU3GIDZ3.js";import{a as w}from"./chunk-GNU4VOOE.js";import{c as f}from"./chunk-ZWNQREWS.js";import{a as y}from"./chunk-2ZRNGG2N.js";import{a as l}from"./chunk-2ZUZ5HDL.js";import{a as v}from"./chunk-A2NKDOYN.js";import{b as p}from"./chunk-PZSHOSOS.js";import{a as x}from"./chunk-TIPK3SCJ.js";import{e as c,f as a}from"./chunk-MW3RWBZ7.js";c("en",{stepBack:"Back",stepNext:"Next",stepFinish:"Finish",stepReview:"Review"});c("pt-BR",{stepBack:"Voltar",stepNext:"Pr\xF3ximo",stepFinish:"Concluir",stepReview:"Revis\xE3o"});var d=class extends v{baseCls="op-stepform__review";setContent(e){this.el.replaceChildren(...e)}},m=class extends F{baseCls="op-form op-stepform";stepper;body;pane;backBtn;nextBtn;finishBtn;index=0;constructor(e){let t,i=e.steps??[],s=e.review?new d:void 0,r=new S({steps:[...i.map(({title:o,description:k,icon:_,optional:A})=>({title:o,description:k,icon:_,optional:A})),...s?[{title:e.reviewTitle??a("stepReview")}]:[]]}),n=[...i.map(o=>({type:"container",title:o.title,cls:"op-stepform__step",layout:o.layout??{type:"grid",columns:2,gap:12},items:o.items})),...s?[{type:"container",title:e.reviewTitle??a("stepReview"),cls:"op-stepform__step",items:[s]}]:[]],h=new f({cls:"op-stepform__body",flex:1,layout:{type:"card"},items:n}),u=new l({text:e.backText??a("stepBack"),handler:()=>t.back()}),b=new l({text:e.nextText??a("stepNext"),variant:"primary",handler:()=>t.next()}),g=new l({text:e.finishText??a("stepFinish"),variant:"primary",htmlType:"submit"}),B=e.cancelText?[new l({text:e.cancelText,variant:"ghost",handler:()=>t.emit("cancel")})]:[],T=new w({cls:"op-stepform__footer",items:[...B,"->",u,b,g]});super({...e,layout:{type:"vbox"},items:[r,h,T]}),t=this,Object.assign(this,{stepper:r,body:h,pane:s,backBtn:u,nextBtn:b,finishBtn:g}),r.on("before-select",o=>(t.goTo(o),!1)),h.on("activate",()=>t.onActivate())}cfg(){return this.config}count(){return this.body.items.length}real(){return this.count()-(this.pane?1:0)}getStep(){return this.index}getStepCount(){return this.count()}getStepper(){return this.stepper}stepFields(e){let t=this.body.items[e];return t instanceof f?t.query(i=>i instanceof y):[]}validateStep(e){if(e>=this.real())return!0;let t=this.stepFields(e).filter(i=>!i.validate());return this.stepper.setStepState(e,t.length?"error":"done"),!t.length}goTo(e){if(e<0||e>=this.count()||e===this.index||this.emit("before-step-change",this.index,e)===!1)return!1;let t=e;if(this.cfg().linear!==!1&&e>this.index){for(let i=this.index;i<e;i++)if(!this.validateStep(i)){t=i;break}}return t!==this.index&&this.body.setActiveItem(t),t!==e&&this.stepFields(t).find(i=>i.getError())?.focus(),t===e}next(){return this.goTo(this.index+1)}back(){return this.goTo(this.index-1)}onActivate(){let e=this.body.items.indexOf(this.body.getActiveItem());if(e<0)return;let t=this.index;this.index=e,this.stepper.setActive(e);let i=this.count()-1;this.backBtn.config.hidden=e===0,this.nextBtn.config.hidden=e===i,this.finishBtn.config.hidden=e!==i;for(let[s,r]of[[this.backBtn,e===0],[this.nextBtn,e===i],[this.finishBtn,e!==i]])s.rendered&&(s.el.hidden=r);if(this.pane&&e===i&&this.refreshReview(),e!==t&&(this.emit("step-change",e,t),this.rendered&&this.el.isConnected&&!this.stepFields(e).some(s=>s.getError()))){let s=this.body.items[e]?.el;this.config.autoFocus?this.stepFields(e)[0]?.focus():s&&(s.tabIndex=-1,s.focus())}}refreshReview(){let e=this.getValues(),t=this.cfg().review;if(typeof t=="function")return this.pane.setContent([t(e,this)]);let i=[];for(let s=0;s<this.real();s++){let r=this.stepFields(s).filter(n=>n.name);r.length&&(i.push(p("h3","op-stepform__review-title",{},String(this.body.items[s].config.title??""))),i.push(p("dl","op-stepform__review-list",{},...r.flatMap(n=>[p("dt","",{},n.config.label??n.config.boxLabel??n.name),p("dd","",{},this.show_(n))]))))}this.pane.setContent(i)}show_(e){let t=e.getValue();if(typeof t=="boolean")return t?"\u2713":"\u2014";if(e.config.inputType==="password")return t?"\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022":"\u2014";let i=e.getDisplayText();return i||(t&&typeof t=="object"&&!Array.isArray(t)?Object.values(t).filter(Boolean).join(" \u2013 ")||"\u2014":Array.isArray(t)&&t.join(", ")||"\u2014")}submit(){if(this.index<this.count()-1)return this.next(),!1;let e=super.submit();for(let t=0;t<this.real();t++)this.stepper.setStepState(t,this.stepFields(t).some(i=>i.getError())?"error":"done");return e&&this.emit("finish",this.getValues()),e}reset(){super.reset(),this.clearErrors();for(let e=0;e<this.count();e++)this.stepper.setStepState(e,"pending");this.index!==0&&this.body.setActiveItem(0)}};x("stepform",m);export{m as a};
2
+ //# sourceMappingURL=chunk-27UZFEXD.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/components/form/stepform/stepform.ts"],
4
+ "sourcesContent": ["import { Form, type FormConfig } from '../form/form';\nimport { Container, type ContainerConfig } from '../../../core/container';\nimport { Component } from '../../../core/component';\nimport { Field } from '../../../core/field';\nimport { register } from '../../../core/registry';\nimport { h } from '../../../core/dom';\nimport { t, addMessages } from '../../../core/i18n';\nimport type { LayoutSpec } from '../../../layout/layout';\nimport { Stepper } from '../../navigation/stepper/stepper';\nimport { Button } from '../../base/button/button';\nimport { Toolbar } from '../../layout/toolbar/toolbar';\nimport '../../layout/container/container';\n\naddMessages('en', {\n stepBack: 'Back',\n stepNext: 'Next',\n stepFinish: 'Finish',\n stepReview: 'Review',\n});\naddMessages('pt-BR', {\n stepBack: 'Voltar',\n stepNext: 'Pr\u00F3ximo',\n stepFinish: 'Concluir',\n stepReview: 'Revis\u00E3o',\n});\n\nexport interface FormStep {\n title: string;\n description?: string;\n icon?: string;\n /** May be left alone: the stepper says \"optional\" (its fields are still validated if filled wrongly). */\n optional?: boolean;\n items: ContainerConfig['items'];\n /** Default: two columns (one on a phone). */\n layout?: LayoutSpec;\n}\n\nexport interface StepFormConfig extends FormConfig {\n steps: FormStep[];\n /** Moving forward validates the steps on the way. `false` lets the user click any step. Default true. */\n linear?: boolean;\n /** Adds a last \"Review\" step with a summary of the values; a function renders the summary yourself. */\n review?: boolean | ((values: Record<string, any>, form: StepForm) => string | Node);\n reviewTitle?: string;\n backText?: string;\n nextText?: string;\n finishText?: string;\n /** Shows a Cancel button (fires `cancel`). */\n cancelText?: string;\n /** On a new step, focus its first field (a phone keyboard pops up). Default false: the step panel gets the focus. */\n autoFocus?: boolean;\n}\n\n/** The summary pane of the review step. */\nclass ReviewPane extends Component {\n protected override baseCls = 'op-stepform__review';\n setContent(nodes: Array<Node | string>) {\n this.el.replaceChildren(...nodes);\n }\n}\n\n/** One form, several steps: a Stepper on top, one step at a time, Back / Next / Finish, validation per step and an optional review. */\nexport class StepForm extends Form {\n protected override baseCls = 'op-form op-stepform';\n private stepper!: Stepper;\n private body!: Container;\n private pane?: ReviewPane;\n private backBtn!: Button;\n private nextBtn!: Button;\n private finishBtn!: Button;\n private index = 0;\n\n constructor(config: StepFormConfig) {\n let me!: StepForm;\n const steps = config.steps ?? [];\n const review = config.review ? new ReviewPane() : undefined;\n const stepper = new Stepper({ steps: [...steps.map(({ title, description, icon, optional }) => ({ title, description, icon, optional })), ...(review ? [{ title: config.reviewTitle ?? t('stepReview') }] : [])] });\n const panels = [\n ...steps.map((s) => ({ type: 'container', title: s.title, cls: 'op-stepform__step', layout: s.layout ?? { type: 'grid', columns: 2, gap: 12 }, items: s.items })),\n ...(review ? [{ type: 'container', title: config.reviewTitle ?? t('stepReview'), cls: 'op-stepform__step', items: [review] }] : []),\n ];\n const body = new Container({ cls: 'op-stepform__body', flex: 1, layout: { type: 'card' }, items: panels as never });\n const backBtn = new Button({ text: config.backText ?? t('stepBack'), handler: () => me.back() });\n const nextBtn = new Button({ text: config.nextText ?? t('stepNext'), variant: 'primary', handler: () => me.next() });\n const finishBtn = new Button({ text: config.finishText ?? t('stepFinish'), variant: 'primary', htmlType: 'submit' });\n const cancel = config.cancelText ? [new Button({ text: config.cancelText, variant: 'ghost', handler: () => me.emit('cancel') })] : [];\n const footer = new Toolbar({ cls: 'op-stepform__footer', items: [...cancel, '->', backBtn, nextBtn, finishBtn] });\n super({ ...config, layout: { type: 'vbox' }, items: [stepper, body, footer] });\n me = this;\n Object.assign(this, { stepper, body, pane: review, backBtn, nextBtn, finishBtn });\n stepper.on('before-select', (i: number) => (me.goTo(i), false));\n body.on('activate', () => me.onActivate());\n }\n\n private cfg(): StepFormConfig {\n return this.config as unknown as StepFormConfig;\n }\n\n private count(): number {\n return this.body.items.length;\n }\n private real(): number {\n return this.count() - (this.pane ? 1 : 0);\n }\n\n getStep(): number {\n return this.index;\n }\n getStepCount(): number {\n return this.count();\n }\n getStepper(): Stepper {\n return this.stepper;\n }\n\n private stepFields(i: number): Field<any>[] {\n const step = this.body.items[i];\n return step instanceof Container ? (step.query((c) => c instanceof Field) as Field<any>[]) : [];\n }\n\n /** Validates one step's fields (marks the errors, sets its state on the stepper). */\n validateStep(i: number): boolean {\n if (i >= this.real()) return true;\n const bad = this.stepFields(i).filter((f) => !f.validate());\n this.stepper.setStepState(i, bad.length ? 'error' : 'done');\n return !bad.length;\n }\n\n /** Moves to a step. Forward with `linear` validates the steps on the way and stops at the first invalid one. Returns whether it got there. */\n goTo(j: number): boolean {\n if (j < 0 || j >= this.count() || j === this.index) return false;\n if (this.emit('before-step-change', this.index, j) === false) return false;\n let target = j;\n if (this.cfg().linear !== false && j > this.index) {\n for (let k = this.index; k < j; k++) {\n if (!this.validateStep(k)) {\n target = k;\n break;\n }\n }\n }\n if (target !== this.index) this.body.setActiveItem(target);\n if (target !== j) this.stepFields(target).find((f) => f.getError())?.focus();\n return target === j;\n }\n next(): boolean {\n return this.goTo(this.index + 1);\n }\n back(): boolean {\n return this.goTo(this.index - 1);\n }\n\n /** The card layout changed the visible step (by `goTo`, or because `validate` brought an invalid field into view). */\n private onActivate(): void {\n const i = this.body.items.indexOf(this.body.getActiveItem()!);\n if (i < 0) return;\n const from = this.index;\n this.index = i;\n this.stepper.setActive(i);\n const last = this.count() - 1;\n this.backBtn.config.hidden = i === 0;\n this.nextBtn.config.hidden = i === last;\n this.finishBtn.config.hidden = i !== last;\n for (const [b, hide] of [[this.backBtn, i === 0], [this.nextBtn, i === last], [this.finishBtn, i !== last]] as const) if (b.rendered) b.el.hidden = hide;\n if (this.pane && i === last) this.refreshReview();\n if (i !== from) {\n this.emit('step-change', i, from);\n if (this.rendered && this.el.isConnected && !this.stepFields(i).some((f) => f.getError())) {\n const panel = this.body.items[i]?.el;\n if ((this.config as StepFormConfig).autoFocus) this.stepFields(i)[0]?.focus();\n else if (panel) ((panel.tabIndex = -1), panel.focus());\n }\n }\n }\n\n private refreshReview(): void {\n const values = this.getValues();\n const fn = this.cfg().review;\n if (typeof fn === 'function') return this.pane!.setContent([fn(values, this)]);\n const out: Array<Node | string> = [];\n for (let i = 0; i < this.real(); i++) {\n const rows = this.stepFields(i).filter((f) => f.name);\n if (!rows.length) continue;\n out.push(h('h3', 'op-stepform__review-title', {}, String((this.body.items[i].config as { title?: string }).title ?? '')));\n out.push(h('dl', 'op-stepform__review-list', {}, ...rows.flatMap((f) => [h('dt', '', {}, f.config.label ?? (f.config as { boxLabel?: string }).boxLabel ?? f.name!), h('dd', '', {}, this.show_(f))])));\n }\n this.pane!.setContent(out);\n }\n\n /** What the user sees for a field (its display text; ticks for booleans, dots for passwords). */\n private show_(f: Field<any>): string {\n const v = f.getValue();\n if (typeof v === 'boolean') return v ? '\u2713' : '\u2014';\n if ((f.config as { inputType?: string }).inputType === 'password') return v ? '\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022' : '\u2014';\n const text = f.getDisplayText();\n if (text) return text;\n return v && typeof v === 'object' && !Array.isArray(v) ? Object.values(v).filter(Boolean).join(' \u2013 ') || '\u2014' : Array.isArray(v) ? v.join(', ') || '\u2014' : '\u2014';\n }\n\n /** Enter and the Finish button: Next on every step but the last; on the last, validate everything and `finish`. */\n override submit(): boolean {\n if (this.index < this.count() - 1) {\n this.next();\n return false;\n }\n const ok = super.submit();\n for (let i = 0; i < this.real(); i++) this.stepper.setStepState(i, this.stepFields(i).some((f) => f.getError()) ? 'error' : 'done');\n if (ok) this.emit('finish', this.getValues());\n return ok;\n }\n\n /** Clears the values and goes back to the first step. */\n override reset(): void {\n super.reset();\n this.clearErrors();\n for (let i = 0; i < this.count(); i++) this.stepper.setStepState(i, 'pending');\n if (this.index !== 0) this.body.setActiveItem(0);\n }\n}\nregister('stepform', StepForm);\n"],
5
+ "mappings": "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",
6
+ "names": ["addMessages", "ReviewPane", "Component", "nodes", "StepForm", "Form", "config", "me", "steps", "review", "stepper", "Stepper", "title", "description", "icon", "optional", "t", "panels", "s", "body", "Container", "backBtn", "Button", "nextBtn", "finishBtn", "cancel", "footer", "Toolbar", "i", "step", "c", "Field", "bad", "f", "j", "target", "k", "from", "last", "b", "hide", "panel", "values", "fn", "out", "rows", "h", "v", "text", "ok", "register"]
7
+ }
@@ -0,0 +1,2 @@
1
+ var a={enabled:!0,respectReducedMotion:!0,ease:{out:"cubic-bezier(0, 0, 0.2, 1)",in:"cubic-bezier(0.4, 0, 1, 1)",inOut:"cubic-bezier(0.4, 0, 0.2, 1)"},duration:{dropdown:200,popover:200,modal:240,press:100,pulse:450,reveal:350,swap:220,move:450,enter:250},dropdownRange:[150,250],exitRatio:.8,stagger:{step:30,max:12},press:{scale:.97},popover:{scale:.95},stretch:{amount:.12},arc:{bend:.25},blur:4,rubber:{resistance:.55,settle:320},allowBounce:!1,originFromTrigger:!0};function p(e){if(/spring|elastic|bounce/i.test(e))return!0;let o=/cubic-bezier\(([^)]+)\)/i.exec(e);if(!o)return!1;let[,t,,n]=o[1].split(",").map(Number);return t<0||t>1||n<0||n>1}var r=structuredClone(a),i=new Set,c=(e,o)=>{let t=Array.isArray(e)?[...e]:{...e};for(let n in o)t[n]=o[n]&&typeof o[n]=="object"&&!Array.isArray(o[n])&&e[n]?c(e[n],o[n]):o[n];return t},m=()=>typeof matchMedia=="function"&&matchMedia("(prefers-reduced-motion: reduce)").matches;function u(){if(typeof document>"u")return;let e=r,o=s.isOn(),t=document.documentElement.style,n=(d,l)=>t.setProperty(`--op-motion-${d}`,String(l));n("ease-out",e.ease.out),n("ease-in",e.ease.in),n("ease-in-out",e.ease.inOut),n("press-scale",o?e.press.scale:1),n("press-duration",`${o?e.duration.press:0}ms`),n("popover-scale",o?e.popover.scale:1),n("dropdown-duration",`${o?s.dropdownMs():0}ms`),n("exit-ratio",e.exitRatio),n("stagger-step",`${o?e.stagger.step:0}ms`),n("blur",`${e.blur}px`),document.documentElement.classList.toggle("op-motion-off",!o)}var s={get(){return r},set(e){let o=[],t=c(r,e);for(let n of Object.keys(t.ease))!t.allowBounce&&p(t.ease[n])&&(o.push(`ease.${n}: "${t.ease[n]}" bounces (set allowBounce: true to use it)`),t.ease[n]=r.ease[n]);return r=t,u(),i.forEach(n=>n(r)),{rejected:o}},reset(){r=structuredClone(a),u(),i.forEach(e=>e(r))},enable(){s.set({enabled:!0})},disable(){s.set({enabled:!1})},isOn(){return r.enabled&&!(r.respectReducedMotion&&m())},dropdownMs(){let[e,o]=r.dropdownRange;return Math.max(e,Math.min(o,r.duration.dropdown))},ms(e,o="enter"){let t=e==="dropdown"?s.dropdownMs():r.duration[e];return o==="exit"?Math.round(t*r.exitRatio):t},easing(e){return e==="enter"?r.ease.out:e==="exit"?r.ease.in:r.ease.inOut},on(e){return i.add(e),()=>{i.delete(e)}}};u();export{a,p as b,s as c};
2
+ //# sourceMappingURL=chunk-2UPUC4RK.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/motion/config.ts"],
4
+ "sourcesContent": ["/** Global motion settings: one object, one switch. Defaults are the numbers of the 20 motion rules. */\nexport interface MotionConfig {\n enabled: boolean;\n /** When true (default) a user who asked the OS for reduced motion gets none. */\n respectReducedMotion: boolean;\n ease: { out: string; in: string; inOut: string };\n /** Milliseconds. */\n duration: { dropdown: number; popover: number; modal: number; press: number; pulse: number; reveal: number; swap: number; move: number; enter: number };\n /** The dropdown duration is clamped into this range (rule 2). */\n dropdownRange: [number, number];\n /** Exit duration = enter duration \u00D7 this (rule 15). */\n exitRatio: number;\n stagger: { step: number; max: number };\n press: { scale: number };\n popover: { scale: number };\n stretch: { amount: number };\n arc: { bend: number };\n /** Blur in px used by crossfades (rule 18). */\n blur: number;\n rubber: { resistance: number; settle: number };\n /** Rule 13: easings that overshoot are refused unless this is true. */\n allowBounce: boolean;\n originFromTrigger: boolean;\n}\n\nexport const DEFAULTS: MotionConfig = {\n enabled: true,\n respectReducedMotion: true,\n ease: { out: 'cubic-bezier(0, 0, 0.2, 1)', in: 'cubic-bezier(0.4, 0, 1, 1)', inOut: 'cubic-bezier(0.4, 0, 0.2, 1)' },\n duration: { dropdown: 200, popover: 200, modal: 240, press: 100, pulse: 450, reveal: 350, swap: 220, move: 450, enter: 250 },\n dropdownRange: [150, 250],\n exitRatio: 0.8,\n stagger: { step: 30, max: 12 },\n press: { scale: 0.97 },\n popover: { scale: 0.95 },\n stretch: { amount: 0.12 },\n arc: { bend: 0.25 },\n blur: 4,\n rubber: { resistance: 0.55, settle: 320 },\n allowBounce: false,\n originFromTrigger: true,\n};\n\nexport type DeepPartial<T> = { [K in keyof T]?: T[K] extends object ? (T[K] extends unknown[] ? T[K] : DeepPartial<T[K]>) : T[K] };\n\n/** A `cubic-bezier` whose control points leave [0, 1] on the y axis overshoots (bounces); springs always do. */\nexport function isBouncy(easing: string): boolean {\n if (/spring|elastic|bounce/i.test(easing)) return true;\n const m = /cubic-bezier\\(([^)]+)\\)/i.exec(easing);\n if (!m) return false;\n const [, y1, , y2] = m[1].split(',').map(Number);\n return y1 < 0 || y1 > 1 || y2 < 0 || y2 > 1;\n}\n\ntype Listener = (c: Readonly<MotionConfig>) => void;\nlet current: MotionConfig = structuredClone(DEFAULTS);\nconst listeners = new Set<Listener>();\n\nconst merge = (base: any, patch: any): any => {\n const out = Array.isArray(base) ? [...base] : { ...base };\n for (const k in patch) out[k] = patch[k] && typeof patch[k] === 'object' && !Array.isArray(patch[k]) && base[k] ? merge(base[k], patch[k]) : patch[k];\n return out;\n};\n\nconst reduced = () => typeof matchMedia === 'function' && matchMedia('(prefers-reduced-motion: reduce)').matches;\n\n/** Writes the settings that CSS needs as custom properties on <html>, and the `op-motion-off` class. */\nfunction apply(): void {\n if (typeof document === 'undefined') return;\n const c = current;\n const on = motion.isOn();\n const s = document.documentElement.style;\n const set = (k: string, v: string | number) => s.setProperty(`--op-motion-${k}`, String(v));\n set('ease-out', c.ease.out);\n set('ease-in', c.ease.in);\n set('ease-in-out', c.ease.inOut);\n set('press-scale', on ? c.press.scale : 1);\n set('press-duration', `${on ? c.duration.press : 0}ms`);\n set('popover-scale', on ? c.popover.scale : 1);\n set('dropdown-duration', `${on ? motion.dropdownMs() : 0}ms`);\n set('exit-ratio', c.exitRatio);\n set('stagger-step', `${on ? c.stagger.step : 0}ms`);\n set('blur', `${c.blur}px`);\n document.documentElement.classList.toggle('op-motion-off', !on);\n}\n\nexport const motion = {\n get(): Readonly<MotionConfig> {\n return current;\n },\n /**\n * Changes the settings (deep merge). Easings that bounce are refused while `allowBounce` is false; the rest of the patch\n * still applies. Returns what was refused.\n */\n set(patch: DeepPartial<MotionConfig>): { rejected: string[] } {\n const rejected: string[] = [];\n const next = merge(current, patch) as MotionConfig;\n for (const k of Object.keys(next.ease) as Array<keyof MotionConfig['ease']>) {\n if (!next.allowBounce && isBouncy(next.ease[k])) {\n rejected.push(`ease.${k}: \"${next.ease[k]}\" bounces (set allowBounce: true to use it)`);\n next.ease[k] = current.ease[k];\n }\n }\n current = next;\n apply();\n listeners.forEach((fn) => fn(current));\n return { rejected };\n },\n reset(): void {\n current = structuredClone(DEFAULTS);\n apply();\n listeners.forEach((fn) => fn(current));\n },\n enable(): void {\n motion.set({ enabled: true });\n },\n disable(): void {\n motion.set({ enabled: false });\n },\n /** Motion is switched on and the user did not ask for reduced motion (unless `respectReducedMotion` is off). */\n isOn(): boolean {\n return current.enabled && !(current.respectReducedMotion && reduced());\n },\n /** The dropdown duration, clamped into `dropdownRange`. */\n dropdownMs(): number {\n const [lo, hi] = current.dropdownRange;\n return Math.max(lo, Math.min(hi, current.duration.dropdown));\n },\n /** Duration for a kind of motion in a phase: exits are `exitRatio` times shorter (rule 15). */\n ms(kind: keyof MotionConfig['duration'], phase: 'enter' | 'exit' = 'enter'): number {\n const base = kind === 'dropdown' ? motion.dropdownMs() : current.duration[kind];\n return phase === 'exit' ? Math.round(base * current.exitRatio) : base;\n },\n /** Easing for a phase: entrances ease-out, exits ease-in, movement ease-in-out. */\n easing(phase: 'enter' | 'exit' | 'move'): string {\n return phase === 'enter' ? current.ease.out : phase === 'exit' ? current.ease.in : current.ease.inOut;\n },\n /** Subscribe to changes; returns the unsubscribe function. */\n on(fn: Listener): () => void {\n listeners.add(fn);\n return () => void listeners.delete(fn);\n },\n};\napply();\n"],
5
+ "mappings": "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",
6
+ "names": ["DEFAULTS", "isBouncy", "easing", "m", "y1", "y2", "current", "listeners", "merge", "base", "patch", "out", "k", "reduced", "apply", "c", "on", "motion", "s", "set", "v", "rejected", "next", "fn", "lo", "hi", "kind", "phase"]
7
+ }
@@ -0,0 +1,2 @@
1
+ import{a as o}from"./chunk-A2NKDOYN.js";import{b as r,c as s}from"./chunk-PZSHOSOS.js";import{f as l}from"./chunk-MW3RWBZ7.js";var n=class extends o{baseCls="op-field";value;original;error="";inputEl;labelEl;helpEl;errorEl;dirty=!1;cancelSettle;constructor(e={}){super(e),this.value=this.original=e.value??this.emptyValue()}get name(){return this.config.name}emptyValue(){return""}isEmpty(e){return e==null||e===""||Array.isArray(e)&&!e.length}isEqual(e,t){return e===t||JSON.stringify(e)===JSON.stringify(t)}build(){let e=this.config,t=r("div",`${this.baseCls}${e.labelPos==="left"?" op-field--label-left":""}`);this.labelEl=r("label","op-field__label");let i=r("div","op-field__control",{},this.createControl());return this.helpEl=r("div","op-field__help",{id:`${this.id}-help`}),this.errorEl=r("div","op-field__error",{id:`${this.id}-error`,role:"alert"}),t.append(this.labelEl,i,this.helpEl,this.errorEl),t}onRender(){let e=this.config,t=this.inputEl;t.id||=s("op-input"),this.labelEl.htmlFor=t.id,e.ariaLabel&&t!==this.el&&(t.setAttribute("aria-label",e.ariaLabel),this.el.removeAttribute("aria-label")),this.setLabel(e.label??""),this.setHelp(e.help??""),this.setRequired(!!e.required),this.setReadonly(!!e.readonly),this.applyValue(this.value),this.paintError(),this.listen(this.el,"focusin",()=>{this.el.classList.add("is-focused"),this.emit("focus")}),this.listen(this.el,"focusout",i=>{this.el.contains(i.relatedTarget)||(this.flushSettled(),this.el.classList.remove("is-focused"),(e.validateOn??"blur")==="blur"&&this.validate(),this.emit("blur"))})}focusEl(){return this.render(),this.inputEl}getValue(){return this.value}setValue(e,t=!1){let i=this.value;this.value=e,this.rendered&&this.applyValue(e),this.isEqual(i,e)||this.changed(i,t)}commit(e){let t=this.value;this.value=e,this.isEqual(t,e)||this.changed(t,!1)}changed(e,t){this.updateDirty(),!t&&((this.config.validateOn==="change"||this.error)&&this.validate(),this.emit("change",this.value,e),this.queueSettled())}queueSettled(){this.cancelSettle?.(),this.cancelSettle=void 0;let e=this.config.debounce;if(!e)return void this.emit("settled",this.value);this.cancelSettle=this.later(()=>{this.cancelSettle=void 0,this.emit("settled",this.value)},e)}flushSettled(){this.cancelSettle&&(this.cancelSettle(),this.cancelSettle=void 0,this.emit("settled",this.value))}updateDirty(){let e=this.isDirty();e!==this.dirty&&(this.dirty=e,this.rendered&&this.el.classList.toggle("is-dirty",e),this.emit("dirty-change",e))}getDisplayText(){let e=this.value;return this.isEmpty(e)?"":String(e)}clear(){this.setValue(this.emptyValue())}isDirty(){return!this.isEqual(this.value,this.original)}markClean(){this.original=this.value,this.updateDirty()}reset(){this.setValue(this.original,!0),this.clearError()}check(){let e=this.value;if(this.isEmpty(e))return this.config.required?l("required"):"";for(let t of this.config.validators??[]){let i=t(e,this);if(typeof i=="string")return i}return""}validate(){let e=this.check();return e?this.setError(e):this.clearError(),!e}isValid(){return!this.check()}getError(){return this.error}setError(e){let t=this.error;this.error=e,this.paintError(),e&&e!==t&&this.emit("invalid",e)}clearError(){this.error&&(this.error="",this.paintError(),this.emit("valid"))}paintError(){this.rendered&&(this.errorEl.textContent=this.error,this.el.classList.toggle("is-invalid",!!this.error),this.inputEl.setAttribute("aria-invalid",String(!!this.error)),this.describe())}describe(){let e=[this.error&&this.errorEl.id,this.config.help&&this.helpEl.id].filter(Boolean);e.length?this.inputEl.setAttribute("aria-describedby",e.join(" ")):this.inputEl.removeAttribute("aria-describedby")}setLabel(e){this.config.label=e,this.rendered&&(this.labelEl.textContent=e,this.labelEl.hidden=!e)}setHelp(e){this.config.help=e,this.rendered&&(this.helpEl.textContent=e,this.helpEl.hidden=!e,this.describe())}setRequired(e){this.config.required=e,this.rendered&&(this.el.classList.toggle("is-required",e),this.inputEl.setAttribute("aria-required",String(e)))}setReadonly(e){this.config.readonly=e,this.rendered&&(this.el.classList.toggle("is-readonly",e),this.onReadonly(e))}setValidators(e){this.config.validators=e}onReadonly(e){}};export{n as a};
2
+ //# sourceMappingURL=chunk-2ZRNGG2N.js.map