optikos 0.3.0 → 0.4.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 (432) hide show
  1. package/CHANGELOG.md +39 -1
  2. package/dist/bind.js +1 -1
  3. package/dist/bind.js.map +4 -4
  4. package/dist/{chunk-5JEXM5S7.js → chunk-2GKIF7A6.js} +2 -2
  5. package/dist/chunk-2HNQ2XRY.js +2 -0
  6. package/dist/chunk-2HNQ2XRY.js.map +7 -0
  7. package/dist/chunk-2QMI2RRB.js +2 -0
  8. package/dist/chunk-2QMI2RRB.js.map +7 -0
  9. package/dist/{chunk-W3H7GTJY.js → chunk-2YRQULDC.js} +2 -2
  10. package/dist/{chunk-ZPPELYNJ.js → chunk-3BG75P7T.js} +2 -2
  11. package/dist/{chunk-GNU4VOOE.js → chunk-3F4MN2BU.js} +2 -2
  12. package/dist/chunk-3FCIZKIN.js +2 -0
  13. package/dist/chunk-3FCIZKIN.js.map +7 -0
  14. package/dist/{chunk-5DJTP53N.js → chunk-3FK52VQX.js} +2 -2
  15. package/dist/chunk-3QRA3XOA.js +2 -0
  16. package/dist/chunk-3QRA3XOA.js.map +7 -0
  17. package/dist/chunk-3TCITFUU.js +2 -0
  18. package/dist/chunk-3TCITFUU.js.map +7 -0
  19. package/dist/chunk-3VDLX7ET.js +2 -0
  20. package/dist/chunk-3VDLX7ET.js.map +7 -0
  21. package/dist/{chunk-3TAW4AKH.js → chunk-4AZ44KV4.js} +2 -2
  22. package/dist/{chunk-TZOQWCVH.js → chunk-4CWYF4O7.js} +2 -2
  23. package/dist/{chunk-REW4LR46.js → chunk-4OB2IM5L.js} +2 -2
  24. package/dist/{chunk-2YZB6XQR.js → chunk-4S3HRFQB.js} +2 -2
  25. package/dist/chunk-5BMG5ZBY.js +2 -0
  26. package/dist/{chunk-KLLAY2IM.js.map → chunk-5BMG5ZBY.js.map} +2 -2
  27. package/dist/chunk-5PWPAN62.js +2 -0
  28. package/dist/chunk-5PWPAN62.js.map +7 -0
  29. package/dist/chunk-5PYJ6FJK.js +2 -0
  30. package/dist/chunk-5PYJ6FJK.js.map +7 -0
  31. package/dist/{chunk-OGRFQTXA.js → chunk-643FOYQB.js} +2 -2
  32. package/dist/{chunk-JOFQJGZK.js → chunk-6BOM5KZR.js} +2 -2
  33. package/dist/chunk-6LJK4QWF.js +2 -0
  34. package/dist/chunk-6LJK4QWF.js.map +7 -0
  35. package/dist/{chunk-JK74QK3M.js → chunk-6PZPBPAD.js} +2 -2
  36. package/dist/chunk-7Y2GHQRB.js +2 -0
  37. package/dist/{chunk-YHEMA56R.js → chunk-AQ3RTHG5.js} +2 -2
  38. package/dist/{chunk-M242VYZA.js → chunk-AT7VFZRB.js} +2 -2
  39. package/dist/{chunk-ZVK4L5GK.js → chunk-BCVOUMJJ.js} +2 -2
  40. package/dist/{chunk-HOF4JGMQ.js → chunk-BIGL3ZVD.js} +2 -2
  41. package/dist/chunk-BJWREA76.js +2 -0
  42. package/dist/chunk-BJWREA76.js.map +7 -0
  43. package/dist/{chunk-ZWNQREWS.js → chunk-BQEFLPDA.js} +2 -2
  44. package/dist/{chunk-ZWNQREWS.js.map → chunk-BQEFLPDA.js.map} +2 -2
  45. package/dist/{chunk-FEHGU6EP.js → chunk-C3MWS7P2.js} +2 -2
  46. package/dist/{chunk-G2KUK6AT.js → chunk-CFGCB37K.js} +2 -2
  47. package/dist/{chunk-JI265XFO.js → chunk-CMV3F6HR.js} +2 -2
  48. package/dist/{chunk-TOLTUOZS.js → chunk-CWIE74NX.js} +2 -2
  49. package/dist/{chunk-4EZJ5FKJ.js → chunk-DIOJGTUN.js} +2 -2
  50. package/dist/chunk-DJUSVBD5.js +2 -0
  51. package/dist/chunk-DJUSVBD5.js.map +7 -0
  52. package/dist/{chunk-HXDTGP2K.js → chunk-DWA45BWR.js} +2 -2
  53. package/dist/chunk-DWTDNKXX.js +2 -0
  54. package/dist/chunk-DWTDNKXX.js.map +7 -0
  55. package/dist/chunk-ESCLDVFS.js +2 -0
  56. package/dist/{chunk-YBAYEU25.js.map → chunk-ESCLDVFS.js.map} +1 -1
  57. package/dist/chunk-EXIADWI7.js +2 -0
  58. package/dist/chunk-EXIADWI7.js.map +7 -0
  59. package/dist/{chunk-5QUY72FX.js → chunk-F4HZUAKM.js} +2 -2
  60. package/dist/chunk-FCJI2JF7.js +3 -0
  61. package/dist/chunk-FCJI2JF7.js.map +7 -0
  62. package/dist/{chunk-Q26YZYTD.js → chunk-FPU53CCV.js} +2 -2
  63. package/dist/{chunk-3S24ZRPK.js → chunk-GEBAYD6N.js} +2 -2
  64. package/dist/{chunk-G2DAD3MQ.js → chunk-GEJKFE4X.js} +2 -2
  65. package/dist/chunk-GFFZTFQH.js +2 -0
  66. package/dist/chunk-GFFZTFQH.js.map +7 -0
  67. package/dist/chunk-GFJRGBQR.js +2 -0
  68. package/dist/chunk-GFJRGBQR.js.map +7 -0
  69. package/dist/chunk-GZIDE5K2.js +2 -0
  70. package/dist/chunk-GZIDE5K2.js.map +7 -0
  71. package/dist/{chunk-5Q76ACVI.js → chunk-H25XXQVH.js} +2 -2
  72. package/dist/chunk-HG7OOHGD.js +2 -0
  73. package/dist/chunk-HG7OOHGD.js.map +7 -0
  74. package/dist/{chunk-2ZUZ5HDL.js → chunk-HLS5FI55.js} +2 -2
  75. package/dist/chunk-HRW25TMU.js +2 -0
  76. package/dist/chunk-HX6TWXTX.js +2 -0
  77. package/dist/chunk-HX6TWXTX.js.map +7 -0
  78. package/dist/chunk-I5A74NMJ.js +2 -0
  79. package/dist/chunk-I5A74NMJ.js.map +7 -0
  80. package/dist/chunk-IUOEPAWG.js +2 -0
  81. package/dist/chunk-IUOEPAWG.js.map +7 -0
  82. package/dist/{chunk-IHE2MQ3W.js → chunk-J5QPFJ7M.js} +2 -2
  83. package/dist/chunk-JE56CJX2.js +2 -0
  84. package/dist/chunk-JE56CJX2.js.map +7 -0
  85. package/dist/chunk-JJLOUMCJ.js +2 -0
  86. package/dist/chunk-JJLOUMCJ.js.map +7 -0
  87. package/dist/chunk-JLKIHXZP.js +3 -0
  88. package/dist/chunk-JLKIHXZP.js.map +7 -0
  89. package/dist/{chunk-5BC72727.js → chunk-JSEI44A7.js} +2 -2
  90. package/dist/chunk-L5SQQFO7.js +2 -0
  91. package/dist/chunk-L5SQQFO7.js.map +7 -0
  92. package/dist/chunk-M2ZRKHE4.js +2 -0
  93. package/dist/chunk-M2ZRKHE4.js.map +7 -0
  94. package/dist/chunk-M7FNPRV4.js +2 -0
  95. package/dist/chunk-M7FNPRV4.js.map +7 -0
  96. package/dist/chunk-MNSDGJKA.js +3 -0
  97. package/dist/chunk-MNSDGJKA.js.map +7 -0
  98. package/dist/{chunk-DBMWS3O5.js → chunk-MQ5BYGFY.js} +2 -2
  99. package/dist/chunk-N2LS4JD6.js +2 -0
  100. package/dist/chunk-N2LS4JD6.js.map +7 -0
  101. package/dist/chunk-NJ5IFOPR.js +4 -0
  102. package/dist/{chunk-XX2MVWFS.js.map → chunk-NJ5IFOPR.js.map} +1 -1
  103. package/dist/{chunk-NXSTUFS7.js → chunk-NNR2FNHG.js} +2 -2
  104. package/dist/chunk-NQV4THNE.js +2 -0
  105. package/dist/{chunk-UXXJOU5J.js.map → chunk-NQV4THNE.js.map} +1 -1
  106. package/dist/{chunk-XHOBNSBO.js → chunk-P4O57S6N.js} +2 -2
  107. package/dist/{chunk-MB3MU6HR.js → chunk-PGVLRMTQ.js} +2 -2
  108. package/dist/chunk-PMOXLQ72.js +2 -0
  109. package/dist/chunk-PMOXLQ72.js.map +7 -0
  110. package/dist/chunk-Q6FY4L2F.js +2 -0
  111. package/dist/chunk-Q6FY4L2F.js.map +7 -0
  112. package/dist/chunk-R32HPK7R.js +2 -0
  113. package/dist/chunk-R32HPK7R.js.map +7 -0
  114. package/dist/{chunk-Z2JBUHKA.js → chunk-RG6SHPHF.js} +2 -2
  115. package/dist/{chunk-EDUMAMK4.js → chunk-S2CMWKVB.js} +2 -2
  116. package/dist/chunk-S4QD5NID.js +2 -0
  117. package/dist/chunk-S4QD5NID.js.map +7 -0
  118. package/dist/chunk-SB4ICXBV.js +2 -0
  119. package/dist/chunk-SB4ICXBV.js.map +7 -0
  120. package/dist/{chunk-23XLG2EM.js → chunk-SEW5OCQF.js} +2 -2
  121. package/dist/chunk-SWCB2GMN.js +2 -0
  122. package/dist/chunk-SWCB2GMN.js.map +7 -0
  123. package/dist/chunk-TQPQ4UEA.js +2 -0
  124. package/dist/chunk-TQPQ4UEA.js.map +7 -0
  125. package/dist/{chunk-Z2Z52GFT.js → chunk-U5L76VVB.js} +2 -2
  126. package/dist/chunk-UDXO3KM3.js +2 -0
  127. package/dist/chunk-UDXO3KM3.js.map +7 -0
  128. package/dist/{chunk-LQRFNQ2N.js → chunk-UQRQH2JW.js} +2 -2
  129. package/dist/chunk-V5G5JECN.js +2 -0
  130. package/dist/chunk-V5G5JECN.js.map +7 -0
  131. package/dist/{chunk-JBLRAM7Z.js → chunk-XFIREDWO.js} +2 -2
  132. package/dist/chunk-XQHATUKN.js +2 -0
  133. package/dist/{chunk-LW2WRUVL.js.map → chunk-XQHATUKN.js.map} +4 -4
  134. package/dist/chunk-XR677UYD.js +2 -0
  135. package/dist/chunk-XR677UYD.js.map +7 -0
  136. package/dist/{chunk-RNN55473.js → chunk-YDX2PCVL.js} +2 -2
  137. package/dist/{chunk-RNN55473.js.map → chunk-YDX2PCVL.js.map} +1 -1
  138. package/dist/chunk-YJTUFK4P.js +2 -0
  139. package/dist/chunk-YLFSCQL3.js +2 -0
  140. package/dist/chunk-YLFSCQL3.js.map +7 -0
  141. package/dist/chunk-YXOKWCYS.js +2 -0
  142. package/dist/chunk-YXOKWCYS.js.map +7 -0
  143. package/dist/{chunk-I4SP6JTU.js → chunk-Z6L55FTN.js} +2 -2
  144. package/dist/{chunk-6VBK2I5B.js → chunk-ZSPJZ3ZH.js} +2 -2
  145. package/dist/components/avatar.js +2 -0
  146. package/dist/components/avatar.js.map +7 -0
  147. package/dist/components/badge.js +1 -1
  148. package/dist/components/breadcrumb.js +1 -1
  149. package/dist/components/button.js +1 -1
  150. package/dist/components/calendar.js +1 -1
  151. package/dist/components/carousel.js +2 -0
  152. package/dist/components/carousel.js.map +7 -0
  153. package/dist/components/cellediting.js +1 -1
  154. package/dist/components/chart.js +2 -0
  155. package/dist/components/chart.js.map +7 -0
  156. package/dist/components/chat.js +1 -1
  157. package/dist/components/checkbox.js +1 -1
  158. package/dist/components/checkboxgroup.js +1 -1
  159. package/dist/components/chip.js +1 -1
  160. package/dist/components/codeviewer.js +1 -1
  161. package/dist/components/combobox.js +1 -1
  162. package/dist/components/commandpalette.js +1 -1
  163. package/dist/components/container.js +1 -1
  164. package/dist/components/dataview.js +1 -1
  165. package/dist/components/datefield.js +1 -1
  166. package/dist/components/daterangefield.js +1 -1
  167. package/dist/components/datetimefield.js +2 -0
  168. package/dist/components/datetimefield.js.map +7 -0
  169. package/dist/components/dial.js +1 -1
  170. package/dist/components/dropdown.js +1 -1
  171. package/dist/components/fieldgroup.js +1 -1
  172. package/dist/components/fieldlist.js +1 -1
  173. package/dist/components/fieldset.js +1 -1
  174. package/dist/components/filterbuilder.js +1 -1
  175. package/dist/components/form.js +1 -1
  176. package/dist/components/formactions.js +1 -1
  177. package/dist/components/formerrors.js +1 -1
  178. package/dist/components/formsection.js +1 -1
  179. package/dist/components/grid.js +1 -1
  180. package/dist/components/gridexport.js +2 -0
  181. package/dist/components/gridexport.js.map +7 -0
  182. package/dist/components/gridstate.js +2 -0
  183. package/dist/components/gridstate.js.map +7 -0
  184. package/dist/components/grouping.js +2 -0
  185. package/dist/components/grouping.js.map +7 -0
  186. package/dist/components/icon.js +1 -1
  187. package/dist/components/image.js +2 -0
  188. package/dist/components/image.js.map +7 -0
  189. package/dist/components/imagecanvas.js +2 -0
  190. package/dist/components/imagecanvas.js.map +7 -0
  191. package/dist/components/imagefield.js +2 -0
  192. package/dist/components/imagefield.js.map +7 -0
  193. package/dist/components/inputgroup.js +1 -1
  194. package/dist/components/label.js +1 -1
  195. package/dist/components/listbox.js +1 -1
  196. package/dist/components/lookupfield.js +1 -1
  197. package/dist/components/maskfield.js +2 -0
  198. package/dist/components/maskfield.js.map +7 -0
  199. package/dist/components/menu.js +1 -1
  200. package/dist/components/messagebox.js +1 -1
  201. package/dist/components/navmenu.js +1 -1
  202. package/dist/components/numberfield.js +1 -1
  203. package/dist/components/pagination.js +1 -1
  204. package/dist/components/panel.js +1 -1
  205. package/dist/components/pickerfield.js +1 -1
  206. package/dist/components/radiogroup.js +1 -1
  207. package/dist/components/rowediting.js +2 -0
  208. package/dist/components/rowediting.js.map +7 -0
  209. package/dist/components/searchgrid.js +1 -1
  210. package/dist/components/secretfield.js +1 -1
  211. package/dist/components/select.js +1 -1
  212. package/dist/components/shortcuts.js +2 -0
  213. package/dist/components/shortcuts.js.map +7 -0
  214. package/dist/components/slider.js +1 -1
  215. package/dist/components/spacer.js +1 -1
  216. package/dist/components/spinner.js +1 -1
  217. package/dist/components/stat.js +2 -0
  218. package/dist/components/stat.js.map +7 -0
  219. package/dist/components/stepform.js +1 -1
  220. package/dist/components/stepper.js +1 -1
  221. package/dist/components/suggestfield.js +1 -1
  222. package/dist/components/table.js +1 -1
  223. package/dist/components/tabs.js +1 -1
  224. package/dist/components/textarea.js +1 -1
  225. package/dist/components/textfield.js +1 -1
  226. package/dist/components/timefield.js +2 -0
  227. package/dist/components/timefield.js.map +7 -0
  228. package/dist/components/timeline.js +2 -0
  229. package/dist/components/timeline.js.map +7 -0
  230. package/dist/components/toast.js +1 -1
  231. package/dist/components/toggle.js +1 -1
  232. package/dist/components/toolbar.js +1 -1
  233. package/dist/components/tree.js +1 -1
  234. package/dist/components/treegrid.js +2 -0
  235. package/dist/components/treegrid.js.map +7 -0
  236. package/dist/components/viewmanager.js +1 -1
  237. package/dist/components/viewport.js +1 -1
  238. package/dist/components/widget.js +1 -1
  239. package/dist/components/window.js +1 -1
  240. package/dist/core.js +1 -1
  241. package/dist/css/avatar.css +68 -0
  242. package/dist/css/base.css +9 -0
  243. package/dist/css/carousel.css +119 -0
  244. package/dist/css/chart.css +168 -0
  245. package/dist/css/core.css +36 -0
  246. package/dist/css/datetimefield.css +15 -0
  247. package/dist/css/grid.css +40 -0
  248. package/dist/css/gridexport.css +35 -0
  249. package/dist/css/grouping.css +49 -0
  250. package/dist/css/image.css +46 -0
  251. package/dist/css/imagecanvas.css +75 -0
  252. package/dist/css/imagefield.css +103 -0
  253. package/dist/css/rowediting.css +39 -0
  254. package/dist/css/shortcuts.css +34 -0
  255. package/dist/css/stat.css +64 -0
  256. package/dist/css/stepform.css +1 -0
  257. package/dist/css/timeline.css +140 -0
  258. package/dist/css/treegrid.css +35 -0
  259. package/dist/css/window.css +2 -2
  260. package/dist/data.js +1 -1
  261. package/dist/dev.js +2 -0
  262. package/dist/dev.js.map +7 -0
  263. package/dist/index.js +16 -5
  264. package/dist/index.js.map +4 -4
  265. package/dist/optikos.css +1111 -21
  266. package/dist/testing.js +2 -0
  267. package/dist/testing.js.map +7 -0
  268. package/dist/themes/dark.css +7 -0
  269. package/dist/types/bind/index.d.ts +1 -1
  270. package/dist/types/bind/viewmodel.d.ts +33 -0
  271. package/dist/types/components/avatar.d.ts +1 -0
  272. package/dist/types/components/base/avatar/avatar.d.ts +22 -0
  273. package/dist/types/components/base/image/image.d.ts +25 -0
  274. package/dist/types/components/base/imagecanvas/imagecanvas.d.ts +39 -0
  275. package/dist/types/components/carousel.d.ts +1 -0
  276. package/dist/types/components/chart.d.ts +1 -0
  277. package/dist/types/components/charts/chart/chart.d.ts +64 -0
  278. package/dist/types/components/charts/stat/stat.d.ts +34 -0
  279. package/dist/types/components/data/cellediting/cellediting.d.ts +3 -0
  280. package/dist/types/components/data/grid/grid.d.ts +37 -0
  281. package/dist/types/components/data/gridexport/gridexport.d.ts +29 -0
  282. package/dist/types/components/data/gridstate/gridstate.d.ts +23 -0
  283. package/dist/types/components/data/grouping/grouping.d.ts +31 -0
  284. package/dist/types/components/data/rowediting/rowediting.d.ts +13 -0
  285. package/dist/types/components/data/searchgrid/searchgrid.d.ts +9 -2
  286. package/dist/types/components/data/timeline/timeline.d.ts +60 -0
  287. package/dist/types/components/data/treegrid/treegrid.d.ts +32 -0
  288. package/dist/types/components/datetimefield.d.ts +1 -0
  289. package/dist/types/components/fields/datetimefield/datetimefield.d.ts +28 -0
  290. package/dist/types/components/fields/imagefield/imagefield.d.ts +48 -0
  291. package/dist/types/components/fields/maskfield/maskfield.d.ts +28 -0
  292. package/dist/types/components/fields/numberfield/numberfield.d.ts +9 -0
  293. package/dist/types/components/fields/pickerfield/pickerfield.d.ts +3 -0
  294. package/dist/types/components/fields/timefield/timefield.d.ts +24 -0
  295. package/dist/types/components/form/fieldlist/fieldlist.d.ts +2 -0
  296. package/dist/types/components/form/form/form.d.ts +5 -0
  297. package/dist/types/components/form/stepform/stepform.d.ts +1 -1
  298. package/dist/types/components/gridexport.d.ts +1 -0
  299. package/dist/types/components/gridstate.d.ts +1 -0
  300. package/dist/types/components/grouping.d.ts +1 -0
  301. package/dist/types/components/image.d.ts +1 -0
  302. package/dist/types/components/imagecanvas.d.ts +1 -0
  303. package/dist/types/components/imagefield.d.ts +1 -0
  304. package/dist/types/components/layout/carousel/carousel.d.ts +58 -0
  305. package/dist/types/components/maskfield.d.ts +1 -0
  306. package/dist/types/components/navigation/navmenu/navmenu.d.ts +2 -0
  307. package/dist/types/components/overlays/commandpalette/commandpalette.d.ts +2 -0
  308. package/dist/types/components/overlays/menu/menu.d.ts +4 -1
  309. package/dist/types/components/overlays/shortcuts/shortcuts.d.ts +27 -0
  310. package/dist/types/components/overlays/window/window.d.ts +14 -1
  311. package/dist/types/components/rowediting.d.ts +1 -0
  312. package/dist/types/components/shortcuts.d.ts +1 -0
  313. package/dist/types/components/stat.d.ts +1 -0
  314. package/dist/types/components/timefield.d.ts +1 -0
  315. package/dist/types/components/timeline.d.ts +1 -0
  316. package/dist/types/components/treegrid.d.ts +1 -0
  317. package/dist/types/core/component.d.ts +7 -0
  318. package/dist/types/core/container.d.ts +10 -1
  319. package/dist/types/core/dev.d.ts +2 -0
  320. package/dist/types/core/field.d.ts +4 -0
  321. package/dist/types/core/i18n.d.ts +2 -0
  322. package/dist/types/core/index.d.ts +4 -1
  323. package/dist/types/core/path.d.ts +2 -0
  324. package/dist/types/core/permission.d.ts +11 -0
  325. package/dist/types/core/state.d.ts +9 -0
  326. package/dist/types/data/column.d.ts +8 -0
  327. package/dist/types/data/index.d.ts +1 -1
  328. package/dist/types/data/model.d.ts +2 -0
  329. package/dist/types/data/store.d.ts +21 -0
  330. package/dist/types/dev/index.d.ts +2 -0
  331. package/dist/types/dev/keys.d.ts +1 -0
  332. package/dist/types/index.d.ts +17 -0
  333. package/dist/types/testing/index.d.ts +25 -0
  334. package/dist/types/themes/color.d.ts +14 -0
  335. package/dist/types/themes/contrast.d.ts +15 -0
  336. package/dist/types/themes/define.d.ts +25 -3
  337. package/dist/types/themes/index.d.ts +3 -1
  338. package/dist/types/themes/seeds.d.ts +11 -0
  339. package/dist/types/ui/ui.d.ts +6 -0
  340. package/dist/ui.js +1 -1
  341. package/package.json +9 -1
  342. package/dist/chunk-2ZRNGG2N.js +0 -2
  343. package/dist/chunk-2ZRNGG2N.js.map +0 -7
  344. package/dist/chunk-4EQEHJB3.js +0 -2
  345. package/dist/chunk-4EQEHJB3.js.map +0 -7
  346. package/dist/chunk-4LZZ244E.js +0 -2
  347. package/dist/chunk-4LZZ244E.js.map +0 -7
  348. package/dist/chunk-4SYIIX5A.js +0 -2
  349. package/dist/chunk-4SYIIX5A.js.map +0 -7
  350. package/dist/chunk-7KMIFXHZ.js +0 -2
  351. package/dist/chunk-7KMIFXHZ.js.map +0 -7
  352. package/dist/chunk-A2NKDOYN.js +0 -2
  353. package/dist/chunk-A2NKDOYN.js.map +0 -7
  354. package/dist/chunk-CKXS375P.js +0 -2
  355. package/dist/chunk-CKXS375P.js.map +0 -7
  356. package/dist/chunk-EJGWCKE4.js +0 -2
  357. package/dist/chunk-EJGWCKE4.js.map +0 -7
  358. package/dist/chunk-ELYARUCN.js +0 -2
  359. package/dist/chunk-EV73ADN2.js +0 -2
  360. package/dist/chunk-EV73ADN2.js.map +0 -7
  361. package/dist/chunk-GD5JGKM7.js +0 -2
  362. package/dist/chunk-GD5JGKM7.js.map +0 -7
  363. package/dist/chunk-GZ7X34QP.js +0 -2
  364. package/dist/chunk-KCEUD232.js +0 -2
  365. package/dist/chunk-KCEUD232.js.map +0 -7
  366. package/dist/chunk-KLLAY2IM.js +0 -2
  367. package/dist/chunk-LBJSMXLV.js +0 -2
  368. package/dist/chunk-LBJSMXLV.js.map +0 -7
  369. package/dist/chunk-LW2WRUVL.js +0 -2
  370. package/dist/chunk-MW3RWBZ7.js +0 -2
  371. package/dist/chunk-MW3RWBZ7.js.map +0 -7
  372. package/dist/chunk-OEAXCCVM.js +0 -2
  373. package/dist/chunk-OEAXCCVM.js.map +0 -7
  374. package/dist/chunk-UB5RYS7T.js +0 -2
  375. package/dist/chunk-UB5RYS7T.js.map +0 -7
  376. package/dist/chunk-UXXJOU5J.js +0 -2
  377. package/dist/chunk-VU3GIDZ3.js +0 -2
  378. package/dist/chunk-VU3GIDZ3.js.map +0 -7
  379. package/dist/chunk-W2BAFOCN.js +0 -3
  380. package/dist/chunk-W2BAFOCN.js.map +0 -7
  381. package/dist/chunk-WFGTQZIQ.js +0 -2
  382. package/dist/chunk-WFGTQZIQ.js.map +0 -7
  383. package/dist/chunk-XX2MVWFS.js +0 -4
  384. package/dist/chunk-XYZ6VZ5T.js +0 -2
  385. package/dist/chunk-YBAYEU25.js +0 -2
  386. package/dist/chunk-YF75HKL6.js +0 -2
  387. package/dist/chunk-YF75HKL6.js.map +0 -7
  388. /package/dist/{chunk-5JEXM5S7.js.map → chunk-2GKIF7A6.js.map} +0 -0
  389. /package/dist/{chunk-W3H7GTJY.js.map → chunk-2YRQULDC.js.map} +0 -0
  390. /package/dist/{chunk-ZPPELYNJ.js.map → chunk-3BG75P7T.js.map} +0 -0
  391. /package/dist/{chunk-GNU4VOOE.js.map → chunk-3F4MN2BU.js.map} +0 -0
  392. /package/dist/{chunk-5DJTP53N.js.map → chunk-3FK52VQX.js.map} +0 -0
  393. /package/dist/{chunk-3TAW4AKH.js.map → chunk-4AZ44KV4.js.map} +0 -0
  394. /package/dist/{chunk-TZOQWCVH.js.map → chunk-4CWYF4O7.js.map} +0 -0
  395. /package/dist/{chunk-REW4LR46.js.map → chunk-4OB2IM5L.js.map} +0 -0
  396. /package/dist/{chunk-2YZB6XQR.js.map → chunk-4S3HRFQB.js.map} +0 -0
  397. /package/dist/{chunk-OGRFQTXA.js.map → chunk-643FOYQB.js.map} +0 -0
  398. /package/dist/{chunk-JOFQJGZK.js.map → chunk-6BOM5KZR.js.map} +0 -0
  399. /package/dist/{chunk-JK74QK3M.js.map → chunk-6PZPBPAD.js.map} +0 -0
  400. /package/dist/{chunk-GZ7X34QP.js.map → chunk-7Y2GHQRB.js.map} +0 -0
  401. /package/dist/{chunk-YHEMA56R.js.map → chunk-AQ3RTHG5.js.map} +0 -0
  402. /package/dist/{chunk-M242VYZA.js.map → chunk-AT7VFZRB.js.map} +0 -0
  403. /package/dist/{chunk-ZVK4L5GK.js.map → chunk-BCVOUMJJ.js.map} +0 -0
  404. /package/dist/{chunk-HOF4JGMQ.js.map → chunk-BIGL3ZVD.js.map} +0 -0
  405. /package/dist/{chunk-FEHGU6EP.js.map → chunk-C3MWS7P2.js.map} +0 -0
  406. /package/dist/{chunk-G2KUK6AT.js.map → chunk-CFGCB37K.js.map} +0 -0
  407. /package/dist/{chunk-JI265XFO.js.map → chunk-CMV3F6HR.js.map} +0 -0
  408. /package/dist/{chunk-TOLTUOZS.js.map → chunk-CWIE74NX.js.map} +0 -0
  409. /package/dist/{chunk-4EZJ5FKJ.js.map → chunk-DIOJGTUN.js.map} +0 -0
  410. /package/dist/{chunk-HXDTGP2K.js.map → chunk-DWA45BWR.js.map} +0 -0
  411. /package/dist/{chunk-5QUY72FX.js.map → chunk-F4HZUAKM.js.map} +0 -0
  412. /package/dist/{chunk-Q26YZYTD.js.map → chunk-FPU53CCV.js.map} +0 -0
  413. /package/dist/{chunk-3S24ZRPK.js.map → chunk-GEBAYD6N.js.map} +0 -0
  414. /package/dist/{chunk-G2DAD3MQ.js.map → chunk-GEJKFE4X.js.map} +0 -0
  415. /package/dist/{chunk-5Q76ACVI.js.map → chunk-H25XXQVH.js.map} +0 -0
  416. /package/dist/{chunk-2ZUZ5HDL.js.map → chunk-HLS5FI55.js.map} +0 -0
  417. /package/dist/{chunk-XYZ6VZ5T.js.map → chunk-HRW25TMU.js.map} +0 -0
  418. /package/dist/{chunk-IHE2MQ3W.js.map → chunk-J5QPFJ7M.js.map} +0 -0
  419. /package/dist/{chunk-5BC72727.js.map → chunk-JSEI44A7.js.map} +0 -0
  420. /package/dist/{chunk-DBMWS3O5.js.map → chunk-MQ5BYGFY.js.map} +0 -0
  421. /package/dist/{chunk-NXSTUFS7.js.map → chunk-NNR2FNHG.js.map} +0 -0
  422. /package/dist/{chunk-XHOBNSBO.js.map → chunk-P4O57S6N.js.map} +0 -0
  423. /package/dist/{chunk-MB3MU6HR.js.map → chunk-PGVLRMTQ.js.map} +0 -0
  424. /package/dist/{chunk-Z2JBUHKA.js.map → chunk-RG6SHPHF.js.map} +0 -0
  425. /package/dist/{chunk-EDUMAMK4.js.map → chunk-S2CMWKVB.js.map} +0 -0
  426. /package/dist/{chunk-23XLG2EM.js.map → chunk-SEW5OCQF.js.map} +0 -0
  427. /package/dist/{chunk-Z2Z52GFT.js.map → chunk-U5L76VVB.js.map} +0 -0
  428. /package/dist/{chunk-LQRFNQ2N.js.map → chunk-UQRQH2JW.js.map} +0 -0
  429. /package/dist/{chunk-JBLRAM7Z.js.map → chunk-XFIREDWO.js.map} +0 -0
  430. /package/dist/{chunk-ELYARUCN.js.map → chunk-YJTUFK4P.js.map} +0 -0
  431. /package/dist/{chunk-I4SP6JTU.js.map → chunk-Z6L55FTN.js.map} +0 -0
  432. /package/dist/{chunk-6VBK2I5B.js.map → chunk-ZSPJZ3ZH.js.map} +0 -0
@@ -0,0 +1,2 @@
1
+ import{b as c}from"./chunk-V5G5JECN.js";import"./chunk-4C666HHU.js";var a=(t=0)=>new Promise(o=>setTimeout(o,t));function l(t,o){let e=t instanceof HTMLElement?t:t.el.querySelector("input,textarea");if(!e)return void t.setValue(o);e.value=o,e.dispatchEvent(new Event("input",{bubbles:!0}))}function u(t,o){let e={},r=(n,i="")=>{for(let s in n){let p=i+s;n[s]&&typeof n[s]=="object"&&!Array.isArray(n[s])&&!t.getField(p)?r(n[s],`${p}.`):e[p]=n[s]}};r(o);for(let n in e){let i=t.getField(n);if(!i)throw new Error(`Optikos testing: the form has no field "${n}"`);typeof e[n]=="string"&&i.el.querySelector("input[type=text],input:not([type]),textarea")&&!i.el.querySelector("[role=combobox]")?l(i,e[n]):i.setValue(e[n])}return t}async function f(t,o){o&&u(t,o);let e=null,r=t.on("submit",n=>e=n);return t.submit(),await a(),r(),e}function y(t){let o={};for(let e of t.getFields())e.name&&e.getError()&&c(o,e.name,e.getError());return o}function g(t,o){let e=t.getStore(),r=typeof o=="number"?e.getAt(o):e.getRange().find(o);if(!r)throw new Error("Optikos testing: no such row in the grid");return t.select(r),t.emit("row-click",r),r}async function m(t){return t.loading&&await new Promise(o=>t.once("load",o)),await a(),t}async function w(t,o=0){t.openDialog(),await a();let e=t.win,r=e?.query(n=>n.constructor.type==="searchgrid")[0];if(!r)throw new Error("Optikos testing: the lookup window did not open");return await m(r.store),r.grid.select(o),[...e.el.querySelectorAll(".op-panel__footer button")].pop().click(),await a(),t.getValue()}var k=t=>((t instanceof HTMLElement?t:t.el).textContent??"").replace(/\s+/g," ").trim();export{g as clickRow,y as errors,u as fill,a as flush,m as loaded,w as pickLookup,f as submit,k as text,l as type};
2
+ //# sourceMappingURL=testing.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/testing/index.ts"],
4
+ "sourcesContent": ["// Helpers for testing an app built with Optikos (Vitest + happy-dom, or any DOM): fill a form, pick a row, wait for a store.\n// They go through the public API and real DOM events, so a test reads like what the user does.\nimport type { Form } from '../components/form/form/form';\nimport type { Grid } from '../components/data/grid/grid';\nimport type { Field } from '../core/field';\nimport type { Component } from '../core/component';\nimport type { Store } from '../data/store';\nimport type { Model } from '../data/model';\nimport type { LookupField } from '../components/fields/lookupfield/lookupfield';\nimport { setPath } from '../core/path';\n\n/** Lets pending promises, microtasks and 0 ms timers run (after `fill`, `store.load()`, a debounce of `ms`...). */\nexport const flush = (ms = 0): Promise<void> => new Promise((done) => setTimeout(done, ms));\n\n/** Types into a field the way a user does: sets the input and fires `input`, so parsing, masks and validation run. Falls back to `setValue`. */\nexport function type(field: Field<any> | HTMLInputElement, text: string): void {\n const input = field instanceof HTMLElement ? field : (field.el.querySelector('input,textarea') as HTMLInputElement | null);\n if (!input) return void (field as Field<any>).setValue(text);\n input.value = text;\n input.dispatchEvent(new Event('input', { bubbles: true }));\n}\n\n/** Fills a form from an object (`{ 'address.city': 'Rio', name: 'Ada' }` or nested). Text fields are typed into; the rest get `setValue`. */\nexport function fill(form: Form, values: Record<string, any>): Form {\n const flat: Record<string, any> = {};\n const walk = (o: Record<string, any>, prefix = '') => {\n for (const k in o) {\n const path = prefix + k;\n if (o[k] && typeof o[k] === 'object' && !Array.isArray(o[k]) && !form.getField(path)) walk(o[k], `${path}.`);\n else flat[path] = o[k];\n }\n };\n walk(values);\n for (const name in flat) {\n const f = form.getField(name);\n if (!f) throw new Error(`Optikos testing: the form has no field \"${name}\"`);\n if (typeof flat[name] === 'string' && f.el.querySelector('input[type=text],input:not([type]),textarea') && !f.el.querySelector('[role=combobox]')) type(f, flat[name]);\n else f.setValue(flat[name]);\n }\n return form;\n}\n\n/** Fills and submits. Resolves with the values when the form was valid and submitted, or `null`. */\nexport async function submit(form: Form, values?: Record<string, any>): Promise<Record<string, any> | null> {\n if (values) fill(form, values);\n let sent: Record<string, any> | null = null;\n const off = form.on('submit', (v: Record<string, any>) => (sent = v));\n form.submit();\n await flush();\n off();\n return sent;\n}\n\n/** What the form shows as errors: `{ fieldName: message }`. */\nexport function errors(form: Form): Record<string, string> {\n const out: Record<string, string> = {};\n for (const f of form.getFields()) if (f.name && f.getError()) setPath(out, f.name, f.getError());\n return out;\n}\n\n/** Selects a grid row by index, or by the first record the predicate accepts; returns its record. */\nexport function clickRow<T extends Record<string, any>>(grid: Grid<T>, which: number | ((rec: Model<T>) => boolean)): Model<T> {\n const store = grid.getStore();\n const rec = typeof which === 'number' ? store.getAt(which) : store.getRange().find(which);\n if (!rec) throw new Error('Optikos testing: no such row in the grid');\n grid.select(rec);\n grid.emit('row-click', rec);\n return rec;\n}\n\n/** Waits until the store is not loading (and, if it has not started yet, until its first `load`). */\nexport async function loaded<T extends Record<string, any>>(store: Store<T>): Promise<Store<T>> {\n if (store.loading) await new Promise((done) => store.once('load', done));\n await flush();\n return store;\n}\n\n/** Opens a lookup's search window, selects the record at `row` and confirms. Resolves with what the field then holds. */\nexport async function pickLookup(field: LookupField<any>, row = 0): Promise<unknown> {\n field.openDialog();\n await flush();\n const win = (field as unknown as { win?: Component & { query(f: (c: Component) => boolean): Component[] } }).win;\n const sg = win?.query((c) => (c.constructor as { type?: string }).type === 'searchgrid')[0] as unknown as { store: Store<any>; grid: Grid } | undefined;\n if (!sg) throw new Error('Optikos testing: the lookup window did not open');\n await loaded(sg.store);\n sg.grid.select(row);\n [...win!.el.querySelectorAll<HTMLButtonElement>('.op-panel__footer button')].pop()!.click();\n await flush();\n return field.getValue();\n}\n\n/** The text a component shows, collapsed to single spaces. */\nexport const text = (c: Component | HTMLElement): string => ((c instanceof HTMLElement ? c : c.el).textContent ?? '').replace(/\\s+/g, ' ').trim();\n"],
5
+ "mappings": "oEAYO,IAAMA,EAAQ,CAACC,EAAK,IAAqB,IAAI,QAASC,GAAS,WAAWA,EAAMD,CAAE,CAAC,EAGnF,SAASE,EAAKC,EAAsCC,EAAoB,CAC7E,IAAMC,EAAQF,aAAiB,YAAcA,EAASA,EAAM,GAAG,cAAc,gBAAgB,EAC7F,GAAI,CAACE,EAAO,OAAO,KAAMF,EAAqB,SAASC,CAAI,EAC3DC,EAAM,MAAQD,EACdC,EAAM,cAAc,IAAI,MAAM,QAAS,CAAE,QAAS,EAAK,CAAC,CAAC,CAC3D,CAGO,SAASC,EAAKC,EAAYC,EAAmC,CAClE,IAAMC,EAA4B,CAAC,EAC7BC,EAAO,CAACC,EAAwBC,EAAS,KAAO,CACpD,QAAWC,KAAKF,EAAG,CACjB,IAAMG,EAAOF,EAASC,EAClBF,EAAEE,CAAC,GAAK,OAAOF,EAAEE,CAAC,GAAM,UAAY,CAAC,MAAM,QAAQF,EAAEE,CAAC,CAAC,GAAK,CAACN,EAAK,SAASO,CAAI,EAAGJ,EAAKC,EAAEE,CAAC,EAAG,GAAGC,CAAI,GAAG,EACtGL,EAAKK,CAAI,EAAIH,EAAEE,CAAC,CACvB,CACF,EACAH,EAAKF,CAAM,EACX,QAAWO,KAAQN,EAAM,CACvB,IAAMO,EAAIT,EAAK,SAASQ,CAAI,EAC5B,GAAI,CAACC,EAAG,MAAM,IAAI,MAAM,2CAA2CD,CAAI,GAAG,EACtE,OAAON,EAAKM,CAAI,GAAM,UAAYC,EAAE,GAAG,cAAc,6CAA6C,GAAK,CAACA,EAAE,GAAG,cAAc,iBAAiB,EAAGd,EAAKc,EAAGP,EAAKM,CAAI,CAAC,EAChKC,EAAE,SAASP,EAAKM,CAAI,CAAC,CAC5B,CACA,OAAOR,CACT,CAGA,eAAsBU,EAAOV,EAAYC,EAAmE,CACtGA,GAAQF,EAAKC,EAAMC,CAAM,EAC7B,IAAIU,EAAmC,KACjCC,EAAMZ,EAAK,GAAG,SAAWa,GAA4BF,EAAOE,CAAE,EACpE,OAAAb,EAAK,OAAO,EACZ,MAAMR,EAAM,EACZoB,EAAI,EACGD,CACT,CAGO,SAASG,EAAOd,EAAoC,CACzD,IAAMe,EAA8B,CAAC,EACrC,QAAWN,KAAKT,EAAK,UAAU,EAAOS,EAAE,MAAQA,EAAE,SAAS,GAAGO,EAAQD,EAAKN,EAAE,KAAMA,EAAE,SAAS,CAAC,EAC/F,OAAOM,CACT,CAGO,SAASE,EAAwCC,EAAeC,EAAwD,CAC7H,IAAMC,EAAQF,EAAK,SAAS,EACtBG,EAAM,OAAOF,GAAU,SAAWC,EAAM,MAAMD,CAAK,EAAIC,EAAM,SAAS,EAAE,KAAKD,CAAK,EACxF,GAAI,CAACE,EAAK,MAAM,IAAI,MAAM,0CAA0C,EACpE,OAAAH,EAAK,OAAOG,CAAG,EACfH,EAAK,KAAK,YAAaG,CAAG,EACnBA,CACT,CAGA,eAAsBC,EAAsCF,EAAoC,CAC9F,OAAIA,EAAM,SAAS,MAAM,IAAI,QAAS1B,GAAS0B,EAAM,KAAK,OAAQ1B,CAAI,CAAC,EACvE,MAAMF,EAAM,EACL4B,CACT,CAGA,eAAsBG,EAAW3B,EAAyB4B,EAAM,EAAqB,CACnF5B,EAAM,WAAW,EACjB,MAAMJ,EAAM,EACZ,IAAMiC,EAAO7B,EAAgG,IACvG8B,EAAKD,GAAK,MAAOE,GAAOA,EAAE,YAAkC,OAAS,YAAY,EAAE,CAAC,EAC1F,GAAI,CAACD,EAAI,MAAM,IAAI,MAAM,iDAAiD,EAC1E,aAAMJ,EAAOI,EAAG,KAAK,EACrBA,EAAG,KAAK,OAAOF,CAAG,EAClB,CAAC,GAAGC,EAAK,GAAG,iBAAoC,0BAA0B,CAAC,EAAE,IAAI,EAAG,MAAM,EAC1F,MAAMjC,EAAM,EACLI,EAAM,SAAS,CACxB,CAGO,IAAMC,EAAQ8B,KAAyCA,aAAa,YAAcA,EAAIA,EAAE,IAAI,aAAe,IAAI,QAAQ,OAAQ,GAAG,EAAE,KAAK",
6
+ "names": ["flush", "ms", "done", "type", "field", "text", "input", "fill", "form", "values", "flat", "walk", "o", "prefix", "k", "path", "name", "f", "submit", "sent", "off", "v", "errors", "out", "setPath", "clickRow", "grid", "which", "store", "rec", "loaded", "pickLookup", "row", "win", "sg", "c"]
7
+ }
@@ -26,6 +26,13 @@
26
26
  --op-color-warning-soft: #36270c;
27
27
  --op-color-info: #6ea8ec;
28
28
  --op-color-info-soft: #172a45;
29
+ --op-chart-2: #f0a35e;
30
+ --op-chart-3: #5cc493;
31
+ --op-chart-4: #c79bea;
32
+ --op-chart-5: #5fc4d6;
33
+ --op-chart-6: #f28b82;
34
+ --op-chart-7: #e0c45c;
35
+ --op-chart-8: #9ba7b8;
29
36
  --op-color-focus: #6ea8ec;
30
37
  --op-color-disabled-fg: #647186;
31
38
  --op-color-disabled-bg: #1a222e;
@@ -20,4 +20,4 @@ export declare function fromStore<S extends {
20
20
  * is two-way: the field's `change` event writes back.
21
21
  */
22
22
  export declare function bind(cmp: Component<any>, map: Record<string, () => unknown>): void;
23
- export {};
23
+ export { viewModel, bindVM, bindForm, type ViewModel, type ViewModelConfig } from './viewmodel.js';
@@ -0,0 +1,33 @@
1
+ import type { Component } from '../core/component.js';
2
+ import type { Field } from '../core/field.js';
3
+ import type { Model } from '../data/model.js';
4
+ export interface ViewModelConfig {
5
+ /** The starting data, nested as you like (`{ qty: 2, record: { name: 'Ada' } }`). */
6
+ data?: Record<string, any>;
7
+ /** Values computed from the data and each other: `{ total: (get) => get('qty') * get('price') }`. They are read like data (`get('total')`) and rerun when what they read changes. */
8
+ formulas?: Record<string, (get: <T = any>(path: string) => T) => unknown>;
9
+ }
10
+ export interface ViewModel {
11
+ /** Reads a dotted path. Inside an `effect`, `computed` or `bind` it makes the reader rerun when that path changes. */
12
+ get<T = any>(path: string): T;
13
+ /** Writes a dotted path and notifies whoever read it, or something under it, or above it. A formula cannot be written. */
14
+ set(path: string, value: unknown): void;
15
+ /** Makes `name` stand for a record (a Model, or a plain object): `link('record', grid.getSelection()[0])`. A write to `record.x` goes through `model.set`, so the record is marked modified. `null` clears it. */
16
+ link(name: string, record: Model | Record<string, any> | null): void;
17
+ /** Counts the `link` calls for `name` (reactive): a form uses it to know it was given a new record. */
18
+ linked(name: string): number;
19
+ }
20
+ /** Shared state for a screen: the Ext `ViewModel` subset that matters (data, formulas, a linked record) without the rest. */
21
+ export declare function viewModel(config?: ViewModelConfig): ViewModel;
22
+ /**
23
+ * Ext's `bind: { text: '{record.name}', disabled: '{!canSave}' }` for any component: each key calls its setter whenever
24
+ * what the string reads changes. A field's `value: '{record.name}'` is two ways: the field's `change` writes back.
25
+ */
26
+ export declare function bindVM(cmp: Component<any>, vm: ViewModel, map: Record<string, string>): void;
27
+ /**
28
+ * Binds every named field of a form to `record.<name>` of the view model, both ways. When the record is replaced (`link`)
29
+ * the form is loaded from it and becomes clean; a change in the form writes through to the record (a Model is marked modified).
30
+ */
31
+ export declare function bindForm(form: Component<any> & {
32
+ getFields(): Array<Field<any>>;
33
+ }, vm: ViewModel, name?: string): void;
@@ -0,0 +1 @@
1
+ export * from '../components/base/avatar/avatar.js';
@@ -0,0 +1,22 @@
1
+ import { Component, type ComponentConfig } from '../../../core/component.js';
2
+ export interface AvatarConfig extends ComponentConfig {
3
+ /** A person's or team's name: the initials when there is no picture, and the accessible name. */
4
+ name?: string;
5
+ /** Picture URL. If it fails to load the initials show. */
6
+ src?: string;
7
+ size?: 'sm' | 'md' | 'lg' | 'xl';
8
+ shape?: 'circle' | 'square';
9
+ status?: 'online' | 'away' | 'busy' | 'offline';
10
+ }
11
+ /** A picture or the initials of a name, on a color picked from the name (so the same person always looks the same). */
12
+ export declare class Avatar extends Component<AvatarConfig> {
13
+ protected baseCls: string;
14
+ private img?;
15
+ private text;
16
+ private dot;
17
+ protected build(): HTMLSpanElement;
18
+ protected onRender(): void;
19
+ setName(name: string): void;
20
+ setSrc(src: string | undefined): void;
21
+ setStatus(status: AvatarConfig['status']): void;
22
+ }
@@ -0,0 +1,25 @@
1
+ import { Component, type ComponentConfig } from '../../../core/component.js';
2
+ export interface ImageConfig extends ComponentConfig {
3
+ src?: string;
4
+ /** What the picture shows, for screen readers. Empty (the default) marks it decorative. */
5
+ alt?: string;
6
+ /** Aspect ratio as CSS: `'16/9'`, `'1'`. The box keeps it while the picture loads, so the page does not jump. */
7
+ ratio?: string;
8
+ fit?: 'cover' | 'contain';
9
+ /** Shown while the picture is missing or fails: an icon name, or a second URL if it contains a `/` or a `.`. Default `image`. */
10
+ fallback?: string;
11
+ /** `lazy` (default) waits until the picture is near the screen. */
12
+ eager?: boolean;
13
+ rounded?: boolean;
14
+ }
15
+ /** A picture in a box that keeps its aspect ratio and shows a fallback when the file is missing. */
16
+ export declare class Image extends Component<ImageConfig> {
17
+ protected baseCls: string;
18
+ private img?;
19
+ private ph;
20
+ protected build(): HTMLDivElement;
21
+ protected onRender(): void;
22
+ setSrc(src: string | undefined, fallback?: boolean): void;
23
+ setAlt(alt: string): void;
24
+ setRatio(ratio: string): void;
25
+ }
@@ -0,0 +1,39 @@
1
+ import { Component, type ComponentConfig } from '../../../core/component.js';
2
+ export interface ImageCanvasConfig extends ComponentConfig {
3
+ src?: string;
4
+ alt?: string;
5
+ /** How the image fills the box at zoom 1. Default `contain`. */
6
+ fit?: 'contain' | 'cover';
7
+ /** Default `true`. */
8
+ zoomable?: boolean;
9
+ /** Default 8. */
10
+ maxZoom?: number;
11
+ /** The zoom buttons. Default `true`. */
12
+ showTools?: boolean;
13
+ /** CSS `aspect-ratio` of the box (e.g. `'16 / 9'`). */
14
+ ratio?: string;
15
+ }
16
+ /** An image that fills its box, with zoom and pan. A plain `<img>` moved by a CSS transform. */
17
+ export declare class ImageCanvas extends Component<ImageCanvasConfig> {
18
+ protected baseCls: string;
19
+ private stage;
20
+ private img;
21
+ private status;
22
+ private zoom;
23
+ private x;
24
+ private y;
25
+ private pointers;
26
+ protected onRender(): void;
27
+ private bindZoom;
28
+ private pan;
29
+ /** Keeps the image covering the box, then moves it. */
30
+ private paint;
31
+ /** Zooms to `level` (1 to `maxZoom`), keeping the point under the pointer (client coordinates) still; the centre by default. */
32
+ zoomTo(level: number, clientX?: number, clientY?: number): void;
33
+ zoomBy(factor: number, clientX?: number, clientY?: number): void;
34
+ reset(): void;
35
+ getZoom(): number;
36
+ setSrc(src: string): void;
37
+ setAlt(alt: string): void;
38
+ setFit(fit: 'contain' | 'cover'): void;
39
+ }
@@ -0,0 +1 @@
1
+ export * from '../components/layout/carousel/carousel.js';
@@ -0,0 +1 @@
1
+ export * from '../components/charts/chart/chart.js';
@@ -0,0 +1,64 @@
1
+ import { Component, type ComponentConfig } from '../../../core/component.js';
2
+ import { type Formatter } from '../../../data/format.js';
3
+ import type { Store } from '../../../data/store.js';
4
+ export interface ChartSeries {
5
+ /** Record field with the value. */
6
+ field: string;
7
+ /** Name in the legend and tooltip. Default: the field. */
8
+ label?: string;
9
+ /** Any CSS color. Default: the theme's `--op-chart-N` in order. */
10
+ color?: string;
11
+ }
12
+ export interface ChartConfig extends ComponentConfig {
13
+ kind?: 'bar' | 'line' | 'area' | 'pie' | 'donut' | 'sparkline';
14
+ /** Records. Give `data` or a `store` (any change of the store repaints the chart). */
15
+ data?: Array<Record<string, any>>;
16
+ store?: Store<any>;
17
+ /** Field with the category: the x axis, or the name of each slice. */
18
+ x: string;
19
+ /** Series to draw (a field name, or an object). A pie and a donut draw the first one. */
20
+ series: Array<string | ChartSeries>;
21
+ /** `bar` and `area` pile the series up instead of putting them side by side. */
22
+ stacked?: boolean;
23
+ /** Default: shown when there is more than one series, or for a pie. */
24
+ legend?: boolean;
25
+ /** Name of a registered format (`money`, `number`, `percent`...) or a function, for the axis and the tooltip. Default `number`. */
26
+ format?: string | Formatter;
27
+ /** Accessible name; also the caption of the data table read by screen readers. */
28
+ title?: string;
29
+ /** Height in px. Default 240 (sparkline 36). */
30
+ height?: number;
31
+ }
32
+ /** Bar, line, area, pie, donut and sparkline charts in SVG. Colors come from the theme (`--op-chart-1`...), so dark mode and white-label just work. */
33
+ export declare class Chart extends Component<ChartConfig> {
34
+ protected baseCls: string;
35
+ private svg;
36
+ private plot;
37
+ private tip;
38
+ private legendEl;
39
+ private sr;
40
+ private hidden;
41
+ private rows;
42
+ private active;
43
+ private geom;
44
+ private queued;
45
+ private offStore?;
46
+ protected build(): HTMLDivElement;
47
+ protected onRender(): void;
48
+ private bindStore;
49
+ setStore(store: Store<any>): void;
50
+ setData(data: Array<Record<string, any>>): void;
51
+ setKind(kind: NonNullable<ChartConfig['kind']>): void;
52
+ setSeries(series: ChartConfig['series']): void;
53
+ private series;
54
+ private fmt;
55
+ private isPie;
56
+ private slices;
57
+ private paint;
58
+ private paintXY;
59
+ private paintPie;
60
+ private paintLegend;
61
+ private paintTable;
62
+ private activate;
63
+ private onKey;
64
+ }
@@ -0,0 +1,34 @@
1
+ import { Component, type ComponentConfig } from '../../../core/component.js';
2
+ import { type Formatter } from '../../../data/format.js';
3
+ export interface StatConfig extends ComponentConfig {
4
+ label: string;
5
+ value?: number | string | null;
6
+ /** Name of a registered format (`money`, `percent`...) or a function, for a numeric `value`. */
7
+ format?: string | Formatter;
8
+ /** The change since the last period, as a fraction (`0.125` shows `+12.5%`). */
9
+ delta?: number;
10
+ /** Which way is good news. `down` for costs, errors or waiting times. Default `up`. */
11
+ good?: 'up' | 'down';
12
+ /** Small text under the value ("vs last week"). */
13
+ caption?: string;
14
+ icon?: string;
15
+ /** Numbers for a sparkline beside the value. */
16
+ trend?: number[];
17
+ }
18
+ /** A KPI tile: a label, a big value, the change since last time and an optional sparkline. */
19
+ export declare class Stat extends Component<StatConfig> {
20
+ protected baseCls: string;
21
+ private labelEl;
22
+ private valueEl;
23
+ private deltaEl;
24
+ private captionEl;
25
+ private chart?;
26
+ protected build(): HTMLDivElement;
27
+ protected onRender(): void;
28
+ setLabel(label: string): void;
29
+ setValue(value: number | string | null): void;
30
+ setDelta(delta: number | undefined): void;
31
+ setCaption(caption: string): void;
32
+ setTrend(trend: number[] | undefined): void;
33
+ protected onDestroy(): void;
34
+ }
@@ -1,8 +1,11 @@
1
+ import type { Column } from '../../../data/column.js';
1
2
  import type { GridPlugin } from '../grid/grid.js';
2
3
  export interface CellEditingOptions {
3
4
  /** What starts editing with the pointer: a double click (default) or a single click. F2 and Enter always do. */
4
5
  trigger?: 'dblclick' | 'click';
5
6
  }
7
+ /** The field config for a column's editor: from `editor`, else from the type of the current value. */
8
+ export declare function editorConfig(col: Column, value: unknown): Record<string, any>;
6
9
  /**
7
10
  * Inline editing plugin. Events on the grid: `before-edit(record, field)` (cancelable), `edit(record, field, value, old)`
8
11
  * after a valid value was written to the record (`record.set`, so it is marked modified), `edit-cancel(record, field)`.
@@ -41,6 +41,21 @@ export interface GridPlugin<T extends Record<string, any> = any> {
41
41
  init(grid: Grid<T>): void | (() => void);
42
42
  destroy?(): void;
43
43
  }
44
+ /**
45
+ * One displayed row. Without a row layout every store record is a row; a plugin (grouping, tree) replaces the list with
46
+ * its own, mixing records with rows that are not records (a group header, a total).
47
+ */
48
+ export interface RowEntry<T extends Record<string, any> = any> {
49
+ /** The record this row shows; absent on a header or total row (which cannot be selected). */
50
+ rec?: Model<T>;
51
+ /** `aria-level` and, with `expanded`, `aria-expanded`: for rows that open and close (a group, a tree node). */
52
+ level?: number;
53
+ expanded?: boolean;
54
+ /** Extra classes on the row (`op-grid__row--group`...). */
55
+ cls?: string;
56
+ /** Fills the row's cells after the grid did (or, on a row without a record, instead of it). */
57
+ paint?(cells: HTMLElement[], row: HTMLElement): void;
58
+ }
44
59
  /** What `cellAt` finds under a DOM node: the row index, its record, the column and the cell element. */
45
60
  export interface GridCell<T extends Record<string, any> = any> {
46
61
  index: number;
@@ -52,12 +67,16 @@ export interface GridAction<T extends Record<string, any> = any> {
52
67
  text: string;
53
68
  icon?: string;
54
69
  variant?: 'default' | 'danger';
70
+ /** Left out (or disabled) while `setPermissionResolver` denies it. */
71
+ permission?: string;
55
72
  handler: (records: Model<T>[], grid: Grid<T>) => void;
56
73
  }
57
74
  export interface GridRowAction<T extends Record<string, any> = any> {
58
75
  text: string;
59
76
  icon?: string;
60
77
  variant?: 'default' | 'danger';
78
+ /** Left out (or disabled) while `setPermissionResolver` denies it. */
79
+ permission?: string;
61
80
  /** Disabled for the records where this returns true. */
62
81
  disabled?: (record: Model<T>) => boolean;
63
82
  handler: (record: Model<T>, grid: Grid<T>) => void;
@@ -66,6 +85,7 @@ export interface ColumnState {
66
85
  field: string;
67
86
  hidden: boolean;
68
87
  width?: number;
88
+ locked?: 'start' | 'end';
69
89
  }
70
90
  /** Data grid with a virtualized body: only the visible rows (plus a small overscan) exist in the DOM. */
71
91
  /** `T` is the record shape; `new Grid({ store })` infers it from a typed `Store<T>`. */
@@ -81,6 +101,8 @@ export declare class Grid<T extends Record<string, any> = any> extends Component
81
101
  private table;
82
102
  private pager?;
83
103
  private v;
104
+ private entries?;
105
+ private lockEdge;
84
106
  private selected;
85
107
  private active;
86
108
  private anchor;
@@ -99,6 +121,7 @@ export declare class Grid<T extends Record<string, any> = any> extends Component
99
121
  private colChips?;
100
122
  private colGroup;
101
123
  private cols;
124
+ /** Visible columns; the locked ones are kept together at their edge, whatever the order they were given or dragged to. */
102
125
  private userCols;
103
126
  private visibleActions;
104
127
  private mode;
@@ -113,6 +136,8 @@ export declare class Grid<T extends Record<string, any> = any> extends Component
113
136
  /** The active row index (keyboard cursor), or -1. */
114
137
  getActive(): number;
115
138
  notifyMount(): void;
139
+ /** The header follows the body sideways; its locked cells hold still, and the edges say when there is more to scroll. */
140
+ private onScrollX;
116
141
  /** Re-measures row height and scrollbar (needed after the grid becomes visible or resizes). */
117
142
  private layout;
118
143
  private bindStore;
@@ -120,8 +145,18 @@ export declare class Grid<T extends Record<string, any> = any> extends Component
120
145
  private sync;
121
146
  setStore(store: Store<T>): void;
122
147
  getStore(): Store<T>;
148
+ private count;
149
+ private recAt;
150
+ /** For plugins: replaces the displayed rows (`undefined` goes back to one row per store record) and repaints. */
151
+ setRowLayout(rows: RowEntry<T>[] | undefined): void;
152
+ /** The displayed row `i`: its record, or the header/total a plugin put there. */
153
+ getRowEntry(i: number): RowEntry<T> | undefined;
154
+ /** How many rows are displayed (records plus whatever a plugin added). */
155
+ getRowCount(): number;
123
156
  /** Column widths → the CSS grid template shared by the header and every row. */
124
157
  private layoutColumns;
158
+ /** Classes and offset of a locked cell (header or body); `n` is the column's place. */
159
+ private lock;
125
160
  private buildHeader;
126
161
  /** Labels over runs of neighbouring columns that share a group (a dragged column can split a group: it shows twice). */
127
162
  private groupBand;
@@ -129,6 +164,8 @@ export declare class Grid<T extends Record<string, any> = any> extends Component
129
164
  getColumnGroups(): string[];
130
165
  /** Shows or hides every column of a group at once (at least one column always stays visible). */
131
166
  setColumnGroupVisible(group: string, visible: boolean): void;
167
+ /** Pins a column to the start or the end while the body scrolls sideways (`null` releases it). A locked column needs a `width` (default 140). */
168
+ setColumnLocked(field: string, locked: 'start' | 'end' | null): void;
132
169
  setColumns(columns: Column[]): void;
133
170
  /** Order, visibility and width of every column; save it and give it back to `setColumnState`. */
134
171
  getColumnState(): ColumnState[];
@@ -0,0 +1,29 @@
1
+ import type { Grid } from '../grid/grid.js';
2
+ export interface ExportOptions {
3
+ format?: 'csv' | 'xlsx';
4
+ /** File name without extension. Default `export`. */
5
+ filename?: string;
6
+ /** `all` (default): every record that matches the sort and filters, across pages (a remote store is read through its proxy). `page`: what the grid shows now. */
7
+ scope?: 'all' | 'page';
8
+ /** Page size for reading a remote store. Default 500. */
9
+ pageSize?: number;
10
+ /** `false` only builds the file and returns it. Default true: the browser downloads it. */
11
+ download?: boolean;
12
+ }
13
+ /**
14
+ * Exports a grid: the visible columns in their current order, values as shown (money, dates...), the current sort and filters.
15
+ * Resolves with the file; downloads it unless `download: false`.
16
+ */
17
+ export declare function exportGrid(grid: Grid, o?: ExportOptions): Promise<Blob>;
18
+ export interface PrintOptions {
19
+ /** A heading above the table. */
20
+ title?: string;
21
+ /** `all` (default) prints every record that matches the filters, which the virtual list on screen does not render. */
22
+ scope?: 'all' | 'page';
23
+ pageSize?: number;
24
+ }
25
+ /**
26
+ * Prints a grid as a plain table: every row, the visible columns, the header repeated on each page, and none of the
27
+ * application around it. Resolves after the print dialog closed.
28
+ */
29
+ export declare function printGrid(grid: Grid, o?: PrintOptions): Promise<void>;
@@ -0,0 +1,23 @@
1
+ import type { GridPlugin, ColumnState } from '../grid/grid.js';
2
+ import type { FilterNode, Sorter } from '../../../data/proxy.js';
3
+ export interface GridState {
4
+ columns?: ColumnState[];
5
+ sorters?: Sorter[];
6
+ filters?: FilterNode[];
7
+ page?: number;
8
+ pageSize?: number;
9
+ }
10
+ export interface PersistOptions {
11
+ /** What to keep. All on by default. */
12
+ columns?: boolean;
13
+ sort?: boolean;
14
+ filters?: boolean;
15
+ page?: boolean;
16
+ /** ms to wait after a change before saving. Default 300. */
17
+ delay?: number;
18
+ }
19
+ /**
20
+ * Keeps widths, order and visibility of the columns, the sort, the filters, the page size and the page under `key`
21
+ * (`setStateStorage` decides where: the browser by default) and puts them back when the grid is created.
22
+ */
23
+ export declare function persistState(key: string, o?: PersistOptions): GridPlugin;
@@ -0,0 +1,31 @@
1
+ import type { Model } from '../../../data/model.js';
2
+ import type { Column } from '../../../data/column.js';
3
+ import type { GridPlugin } from '../grid/grid.js';
4
+ export interface GroupingOptions {
5
+ /** Record field to group by. */
6
+ field?: string;
7
+ /** Or any function of the record (a year, a range): its result is the group. */
8
+ by?: (rec: Model) => unknown;
9
+ /** Text of a group header (before the count). Default: the key. */
10
+ label?: (key: unknown, recs: Model[]) => string;
11
+ /** Total rows of the columns that have a `summary`: `group` (under each group), `grand` (at the end) or `both`. Default `group`. */
12
+ summary?: 'group' | 'grand' | 'both';
13
+ /** Start with every group closed. */
14
+ collapsed?: boolean;
15
+ }
16
+ export interface Grouping extends GridPlugin {
17
+ expandAll(): void;
18
+ collapseAll(): void;
19
+ /** Changes what to group by; `null` shows the plain list. */
20
+ setGroupBy(by: string | ((rec: Model) => unknown) | null): void;
21
+ /** Opens or closes one group by its key. */
22
+ toggle(key: unknown, open?: boolean): void;
23
+ }
24
+ /** The value of a column's `summary` over some records. */
25
+ export declare function summarize(col: Column, recs: Model[]): unknown;
26
+ /**
27
+ * Groups the rows of the current page (a remote store groups what it loaded, not the whole set) under a header with
28
+ * its count; the header toggles by click, Enter/Space, → and ←. Sorting works inside each group. Group headers and total
29
+ * rows are virtual rows like any other. Fires `group-toggle(key, open)` on the grid.
30
+ */
31
+ export declare function grouping(options?: GroupingOptions): Grouping;
@@ -0,0 +1,13 @@
1
+ import type { GridPlugin } from '../grid/grid.js';
2
+ export interface RowEditingOptions {
3
+ /** What starts editing with the pointer: a double click (default) or a single click. F2 and Enter always do. */
4
+ trigger?: 'dblclick' | 'click';
5
+ }
6
+ /**
7
+ * Edits every `editor` column of a row at once, under a bar with Save and Cancel. Enter saves, Esc cancels, Tab walks the
8
+ * editors and the buttons and wraps; Save validates every field and keeps the row open while one is invalid.
9
+ * Events on the grid: `before-edit(record)` (cancelable), `edit(record, values, old)` after the new values were written
10
+ * (`record.set`, so it is marked modified; a remote store's app saves from here), `cancel-edit(record)`.
11
+ * Use it instead of `cellEditing()`, not beside it.
12
+ */
13
+ export declare function rowEditing(options?: RowEditingOptions): GridPlugin;
@@ -5,11 +5,18 @@ import type { Model } from '../../../data/model.js';
5
5
  import type { Column } from '../../../data/column.js';
6
6
  import type { FilterOp, FilterSpec } from '../../../data/proxy.js';
7
7
  import { Grid } from '../grid/grid.js';
8
- /** A filter field of a lookup: any field config, plus how its value is matched. */
9
- export type LookupFilter = AnyConfig & {
8
+ /** A filter field of a lookup: a field config or a field instance (`ui.text(...)`); `op` and `field` say how its value is matched. */
9
+ export type LookupFilter = (AnyConfig & {
10
10
  name: string;
11
11
  op?: FilterOp;
12
12
  field?: string;
13
+ }) | Component;
14
+ /** `name`, `op`, `field` and `type` of a filter, whether it was given as a config or an instance. */
15
+ export declare const filterInfo: (f: LookupFilter) => {
16
+ name: string;
17
+ op?: FilterOp;
18
+ field?: string;
19
+ type?: string;
13
20
  };
14
21
  /** Everything that describes "search for a record": shared by SearchGrid and LookupField. */
15
22
  export interface LookupDef {
@@ -0,0 +1,60 @@
1
+ import { Component, type ComponentConfig } from '../../../core/component.js';
2
+ import type { Store } from '../../../data/store.js';
3
+ export interface TimelineItem {
4
+ id?: string | number;
5
+ title: string;
6
+ text?: string;
7
+ icon?: string;
8
+ tone?: 'default' | 'success' | 'warning' | 'danger' | 'info';
9
+ /** `list`: when it happened (an ISO date or time, or any text). */
10
+ time?: string;
11
+ /** `range`: ISO dates or date-times. */
12
+ start?: string;
13
+ end?: string;
14
+ /** `range`: the row (a person, a room, a phase). */
15
+ lane?: string;
16
+ }
17
+ export interface TimelineConfig extends ComponentConfig {
18
+ /** `list`: events one under the other, with a marker (default). `range`: a schedule: bars over a time axis, one row per `lane`. */
19
+ mode?: 'list' | 'range';
20
+ items?: TimelineItem[];
21
+ /** Items from a Store (its records are `TimelineItem`s). */
22
+ store?: Store<any>;
23
+ /** `range`: the order of the rows. Default: order of appearance. */
24
+ lanes?: string[];
25
+ /** `range`: the window shown. Default: from the first start to the last end. */
26
+ from?: string;
27
+ to?: string;
28
+ /** `range`: a marker at the current time. Default true. */
29
+ now?: boolean;
30
+ /** Optional features (`timeEntry()`...). See `TimelinePlugin`. */
31
+ plugins?: TimelinePlugin[];
32
+ }
33
+ /** Extends a Timeline without growing its base: `init` runs once it is rendered and may return a cleanup. The timeline fires `paint` after every repaint. */
34
+ export interface TimelinePlugin {
35
+ init(timeline: Timeline): void | (() => void);
36
+ }
37
+ /** The time axis of a `range` timeline: its ends in ms, and how to read and write the item dates (`clock`: `'HH:mm'` of one day, else ISO). */
38
+ export interface TimelineScale {
39
+ lo: number;
40
+ hi: number;
41
+ clock: boolean;
42
+ parse(v: string): number;
43
+ format(ms: number): string;
44
+ }
45
+ /** Events as a vertical list, or a schedule (phases, staff shifts) as bars on a time axis. Click or Enter on an item fires `select`. */
46
+ export declare class Timeline extends Component<TimelineConfig> {
47
+ protected baseCls: string;
48
+ private items;
49
+ private scale?;
50
+ protected build(): HTMLDivElement;
51
+ protected onRender(): void;
52
+ private pick;
53
+ getItems(): TimelineItem[];
54
+ /** The time axis of a `range` timeline (set by the last paint), for plugins. */
55
+ getScale(): TimelineScale | undefined;
56
+ setItems(items: TimelineItem[]): void;
57
+ private paint;
58
+ private list;
59
+ private range;
60
+ }
@@ -0,0 +1,32 @@
1
+ import type { Model } from '../../../data/model.js';
2
+ import type { GridPlugin } from '../grid/grid.js';
3
+ export interface TreeGridOptions {
4
+ /** Column that shows the indentation and the expander. Default: the first one. */
5
+ treeColumn?: string;
6
+ /** Field that holds the parent's id (`null` or missing: a root). Default `parentId`. */
7
+ parentField?: string;
8
+ /** Loads the children of a node the first time it opens: resolves with their rows (the plugin sets `parentField` and adds them to the store). Without it every node is already in the store. */
9
+ load?: (node: Model) => Promise<Array<Record<string, any>>> | Array<Record<string, any>>;
10
+ /** With `load`: the field that says a node has no children (default `leaf`), so it gets no expander. */
11
+ leafField?: string;
12
+ /** Start with every node open. */
13
+ expanded?: boolean;
14
+ }
15
+ export interface TreeGrid extends GridPlugin {
16
+ expand(id: string | number): void;
17
+ collapse(id: string | number): void;
18
+ expandAll(): void;
19
+ collapseAll(): void;
20
+ }
21
+ /** Nested data (`{ id, name, children: [...] }`) → the flat rows the plugin wants, each with its `parentId`. */
22
+ export declare function flattenTree<T extends Record<string, any>>(nodes: T[], o?: {
23
+ children?: string;
24
+ parentField?: string;
25
+ }, parent?: unknown): Array<Record<string, any>>;
26
+ /**
27
+ * Indents each record under its parent with an expander; ←/→ close/open and walk to the parent/first child (ARIA treegrid),
28
+ * click on the chevron toggles. The rest of the columns are ordinary: format, renderer, sort (siblings), resize, lock.
29
+ * A record whose parent is filtered out (or not on the page) shows as a root. Events on the grid: `expand-node(record)`,
30
+ * `collapse-node(record)`, `load-error(record, error)`.
31
+ */
32
+ export declare function treeGrid(options?: TreeGridOptions): TreeGrid;
@@ -0,0 +1 @@
1
+ export * from '../components/fields/datetimefield/datetimefield.js';