optikos 0.3.0 → 0.5.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 (466) hide show
  1. package/CHANGELOG.md +58 -1
  2. package/dist/bind.js +1 -1
  3. package/dist/bind.js.map +4 -4
  4. package/dist/build.js +2 -0
  5. package/dist/build.js.map +7 -0
  6. package/dist/chunk-2CVMT3IW.js +3 -0
  7. package/dist/chunk-2CVMT3IW.js.map +7 -0
  8. package/dist/{chunk-5JEXM5S7.js → chunk-2GKIF7A6.js} +2 -2
  9. package/dist/{chunk-5BC72727.js → chunk-2I4Y7I7C.js} +2 -2
  10. package/dist/{chunk-Z2Z52GFT.js → chunk-2I7HDIOU.js} +2 -2
  11. package/dist/chunk-2QMI2RRB.js +2 -0
  12. package/dist/chunk-2QMI2RRB.js.map +7 -0
  13. package/dist/chunk-34KVSA2V.js +3 -0
  14. package/dist/chunk-34KVSA2V.js.map +7 -0
  15. package/dist/chunk-37PYJAA2.js +2 -0
  16. package/dist/{chunk-UXXJOU5J.js.map → chunk-37PYJAA2.js.map} +1 -1
  17. package/dist/{chunk-ZPPELYNJ.js → chunk-3BG75P7T.js} +2 -2
  18. package/dist/{chunk-GNU4VOOE.js → chunk-3F4MN2BU.js} +2 -2
  19. package/dist/{chunk-5DJTP53N.js → chunk-3FK52VQX.js} +2 -2
  20. package/dist/chunk-3OA3P37P.js +2 -0
  21. package/dist/chunk-3OA3P37P.js.map +7 -0
  22. package/dist/chunk-3TCITFUU.js +2 -0
  23. package/dist/chunk-3TCITFUU.js.map +7 -0
  24. package/dist/chunk-3VDLX7ET.js +2 -0
  25. package/dist/chunk-3VDLX7ET.js.map +7 -0
  26. package/dist/{chunk-REW4LR46.js → chunk-4OB2IM5L.js} +2 -2
  27. package/dist/chunk-5G5PHOZJ.js +2 -0
  28. package/dist/chunk-5G5PHOZJ.js.map +7 -0
  29. package/dist/{chunk-EDUMAMK4.js → chunk-5GCTM37D.js} +2 -2
  30. package/dist/chunk-5PYJ6FJK.js +2 -0
  31. package/dist/chunk-5PYJ6FJK.js.map +7 -0
  32. package/dist/chunk-632LUU52.js +2 -0
  33. package/dist/chunk-632LUU52.js.map +7 -0
  34. package/dist/{chunk-JOFQJGZK.js → chunk-6BOM5KZR.js} +2 -2
  35. package/dist/{chunk-Z2JBUHKA.js → chunk-6NP4AEV4.js} +2 -2
  36. package/dist/chunk-6PPRYSLN.js +2 -0
  37. package/dist/chunk-6PPRYSLN.js.map +7 -0
  38. package/dist/{chunk-NXSTUFS7.js → chunk-6TZJO2G2.js} +2 -2
  39. package/dist/chunk-7Y2GHQRB.js +2 -0
  40. package/dist/chunk-A36JFIA3.js +2 -0
  41. package/dist/chunk-A36JFIA3.js.map +7 -0
  42. package/dist/{chunk-G2KUK6AT.js → chunk-ADHKL2GM.js} +2 -2
  43. package/dist/{chunk-JI265XFO.js → chunk-AJN66F32.js} +2 -2
  44. package/dist/{chunk-YHEMA56R.js → chunk-AQ3RTHG5.js} +2 -2
  45. package/dist/{chunk-ZVK4L5GK.js → chunk-BCVOUMJJ.js} +2 -2
  46. package/dist/{chunk-HOF4JGMQ.js → chunk-BIGL3ZVD.js} +2 -2
  47. package/dist/{chunk-ZWNQREWS.js → chunk-BQEFLPDA.js} +2 -2
  48. package/dist/{chunk-ZWNQREWS.js.map → chunk-BQEFLPDA.js.map} +2 -2
  49. package/dist/{chunk-HXDTGP2K.js → chunk-BRGT4O6Q.js} +2 -2
  50. package/dist/{chunk-OGRFQTXA.js → chunk-BTGJ3MP4.js} +2 -2
  51. package/dist/{chunk-TOLTUOZS.js → chunk-CWIE74NX.js} +2 -2
  52. package/dist/{chunk-M242VYZA.js → chunk-CXZKCBQE.js} +2 -2
  53. package/dist/{chunk-4EZJ5FKJ.js → chunk-DIOJGTUN.js} +2 -2
  54. package/dist/chunk-DJUSVBD5.js +2 -0
  55. package/dist/chunk-DJUSVBD5.js.map +7 -0
  56. package/dist/chunk-DLRGB5NY.js +2 -0
  57. package/dist/chunk-DLRGB5NY.js.map +7 -0
  58. package/dist/chunk-DY3ZYMXD.js +2 -0
  59. package/dist/chunk-DY3ZYMXD.js.map +7 -0
  60. package/dist/chunk-EO777UIN.js +2 -0
  61. package/dist/chunk-EO777UIN.js.map +7 -0
  62. package/dist/chunk-ESCLDVFS.js +2 -0
  63. package/dist/{chunk-YBAYEU25.js.map → chunk-ESCLDVFS.js.map} +1 -1
  64. package/dist/{chunk-2ZUZ5HDL.js → chunk-ESRS5ZQV.js} +2 -2
  65. package/dist/{chunk-RNN55473.js → chunk-FNZI6MFG.js} +2 -2
  66. package/dist/{chunk-RNN55473.js.map → chunk-FNZI6MFG.js.map} +1 -1
  67. package/dist/{chunk-JK74QK3M.js → chunk-FSR6BDVO.js} +2 -2
  68. package/dist/{chunk-6VBK2I5B.js → chunk-G26R2F3W.js} +2 -2
  69. package/dist/{chunk-G2DAD3MQ.js → chunk-GEJKFE4X.js} +2 -2
  70. package/dist/chunk-GFJRGBQR.js +2 -0
  71. package/dist/chunk-GFJRGBQR.js.map +7 -0
  72. package/dist/chunk-GLAY4RJF.js +2 -0
  73. package/dist/chunk-GLAY4RJF.js.map +7 -0
  74. package/dist/chunk-GNKVLJ5H.js +2 -0
  75. package/dist/chunk-GNKVLJ5H.js.map +7 -0
  76. package/dist/chunk-GZIDE5K2.js +2 -0
  77. package/dist/chunk-GZIDE5K2.js.map +7 -0
  78. package/dist/{chunk-5Q76ACVI.js → chunk-H25XXQVH.js} +2 -2
  79. package/dist/chunk-HG7OOHGD.js +2 -0
  80. package/dist/chunk-HG7OOHGD.js.map +7 -0
  81. package/dist/chunk-HRW25TMU.js +2 -0
  82. package/dist/chunk-HX6TWXTX.js +2 -0
  83. package/dist/chunk-HX6TWXTX.js.map +7 -0
  84. package/dist/chunk-I5A74NMJ.js +2 -0
  85. package/dist/chunk-I5A74NMJ.js.map +7 -0
  86. package/dist/chunk-IODSL7KU.js +2 -0
  87. package/dist/chunk-IODSL7KU.js.map +7 -0
  88. package/dist/chunk-J2TCHWYD.js +2 -0
  89. package/dist/chunk-J2TCHWYD.js.map +7 -0
  90. package/dist/chunk-J5BZAKC6.js +2 -0
  91. package/dist/chunk-J5BZAKC6.js.map +7 -0
  92. package/dist/chunk-JBOKM5YA.js +2 -0
  93. package/dist/{chunk-KLLAY2IM.js.map → chunk-JBOKM5YA.js.map} +2 -2
  94. package/dist/chunk-L5SQQFO7.js +2 -0
  95. package/dist/chunk-L5SQQFO7.js.map +7 -0
  96. package/dist/chunk-L6DOWGBO.js +2 -0
  97. package/dist/chunk-L6DOWGBO.js.map +7 -0
  98. package/dist/{chunk-W3H7GTJY.js → chunk-LHWY6G6Q.js} +2 -2
  99. package/dist/chunk-LLHDEUIA.js +2 -0
  100. package/dist/chunk-LLHDEUIA.js.map +7 -0
  101. package/dist/chunk-LXWCTCZV.js +2 -0
  102. package/dist/chunk-LXWCTCZV.js.map +7 -0
  103. package/dist/chunk-M2ZRKHE4.js +2 -0
  104. package/dist/chunk-M2ZRKHE4.js.map +7 -0
  105. package/dist/{chunk-Q26YZYTD.js → chunk-M7HLHGQV.js} +2 -2
  106. package/dist/{chunk-IHE2MQ3W.js → chunk-MGSCSS7X.js} +2 -2
  107. package/dist/chunk-MM2OC66E.js +4 -0
  108. package/dist/{chunk-XX2MVWFS.js.map → chunk-MM2OC66E.js.map} +1 -1
  109. package/dist/{chunk-DBMWS3O5.js → chunk-MQ5BYGFY.js} +2 -2
  110. package/dist/chunk-MQEALOU3.js +3 -0
  111. package/dist/chunk-MQEALOU3.js.map +7 -0
  112. package/dist/chunk-NAUSRVB6.js +2 -0
  113. package/dist/chunk-NAUSRVB6.js.map +7 -0
  114. package/dist/chunk-NEVDHDJ4.js +3 -0
  115. package/dist/chunk-NEVDHDJ4.js.map +7 -0
  116. package/dist/{chunk-5QUY72FX.js → chunk-NWHH3CYH.js} +2 -2
  117. package/dist/chunk-OADWLPSF.js +2 -0
  118. package/dist/chunk-OADWLPSF.js.map +7 -0
  119. package/dist/{chunk-3TAW4AKH.js → chunk-OB3VIRQR.js} +2 -2
  120. package/dist/{chunk-MB3MU6HR.js → chunk-PGVLRMTQ.js} +2 -2
  121. package/dist/chunk-Q6FY4L2F.js +2 -0
  122. package/dist/chunk-Q6FY4L2F.js.map +7 -0
  123. package/dist/{chunk-TZOQWCVH.js → chunk-QOSTS5I3.js} +2 -2
  124. package/dist/chunk-QVBDBGS4.js +2 -0
  125. package/dist/chunk-QVBDBGS4.js.map +7 -0
  126. package/dist/{chunk-3S24ZRPK.js → chunk-RMATRKXV.js} +2 -2
  127. package/dist/{chunk-I4SP6JTU.js → chunk-S3ILIWSW.js} +2 -2
  128. package/dist/chunk-S4QD5NID.js +2 -0
  129. package/dist/chunk-S4QD5NID.js.map +7 -0
  130. package/dist/{chunk-XHOBNSBO.js → chunk-SEUIIPHS.js} +2 -2
  131. package/dist/{chunk-23XLG2EM.js → chunk-SEW5OCQF.js} +2 -2
  132. package/dist/chunk-T5OGUCY2.js +2 -0
  133. package/dist/chunk-T5OGUCY2.js.map +7 -0
  134. package/dist/chunk-TMBGEZSD.js +2 -0
  135. package/dist/chunk-TMBGEZSD.js.map +7 -0
  136. package/dist/chunk-TVO3Z2BM.js +2 -0
  137. package/dist/chunk-TVO3Z2BM.js.map +7 -0
  138. package/dist/{chunk-LQRFNQ2N.js → chunk-U25QSLAH.js} +2 -2
  139. package/dist/chunk-UCWICDYG.js +2 -0
  140. package/dist/chunk-UCWICDYG.js.map +7 -0
  141. package/dist/chunk-UDXO3KM3.js +2 -0
  142. package/dist/chunk-UDXO3KM3.js.map +7 -0
  143. package/dist/{chunk-FEHGU6EP.js → chunk-UL364TLO.js} +2 -2
  144. package/dist/chunk-UUAGMZD2.js +2 -0
  145. package/dist/chunk-UUAGMZD2.js.map +7 -0
  146. package/dist/chunk-V5G5JECN.js +2 -0
  147. package/dist/chunk-V5G5JECN.js.map +7 -0
  148. package/dist/chunk-XFDNXSU5.js +2 -0
  149. package/dist/chunk-XFDNXSU5.js.map +7 -0
  150. package/dist/{chunk-JBLRAM7Z.js → chunk-XNRZJP4E.js} +2 -2
  151. package/dist/chunk-YJTUFK4P.js +2 -0
  152. package/dist/chunk-YLFSCQL3.js +2 -0
  153. package/dist/chunk-YLFSCQL3.js.map +7 -0
  154. package/dist/chunk-Z6HZY2YG.js +2 -0
  155. package/dist/chunk-Z6HZY2YG.js.map +7 -0
  156. package/dist/chunk-ZEIE2OCQ.js +2 -0
  157. package/dist/chunk-ZEIE2OCQ.js.map +7 -0
  158. package/dist/{chunk-2YZB6XQR.js → chunk-ZLYZFHEN.js} +2 -2
  159. package/dist/components/avatar.js +2 -0
  160. package/dist/components/avatar.js.map +7 -0
  161. package/dist/components/badge.js +1 -1
  162. package/dist/components/breadcrumb.js +1 -1
  163. package/dist/components/button.js +1 -1
  164. package/dist/components/calendar.js +1 -1
  165. package/dist/components/carousel.js +2 -0
  166. package/dist/components/carousel.js.map +7 -0
  167. package/dist/components/cellediting.js +1 -1
  168. package/dist/components/chart.js +2 -0
  169. package/dist/components/chart.js.map +7 -0
  170. package/dist/components/chat.js +1 -1
  171. package/dist/components/checkbox.js +1 -1
  172. package/dist/components/checkboxgroup.js +1 -1
  173. package/dist/components/chip.js +1 -1
  174. package/dist/components/codeviewer.js +1 -1
  175. package/dist/components/columntotals.js +2 -0
  176. package/dist/components/columntotals.js.map +7 -0
  177. package/dist/components/combobox.js +1 -1
  178. package/dist/components/commandpalette.js +1 -1
  179. package/dist/components/container.js +1 -1
  180. package/dist/components/dataview.js +1 -1
  181. package/dist/components/datefield.js +1 -1
  182. package/dist/components/daterangefield.js +1 -1
  183. package/dist/components/datetimefield.js +2 -0
  184. package/dist/components/datetimefield.js.map +7 -0
  185. package/dist/components/dial.js +1 -1
  186. package/dist/components/dropdown.js +1 -1
  187. package/dist/components/exportbar.js +2 -0
  188. package/dist/components/exportbar.js.map +7 -0
  189. package/dist/components/fieldgroup.js +1 -1
  190. package/dist/components/fieldlist.js +1 -1
  191. package/dist/components/fieldset.js +1 -1
  192. package/dist/components/filterbuilder.js +1 -1
  193. package/dist/components/form.js +1 -1
  194. package/dist/components/formactions.js +1 -1
  195. package/dist/components/formerrors.js +1 -1
  196. package/dist/components/formsection.js +1 -1
  197. package/dist/components/grid.js +1 -1
  198. package/dist/components/gridexport.js +2 -0
  199. package/dist/components/gridexport.js.map +7 -0
  200. package/dist/components/gridstate.js +2 -0
  201. package/dist/components/gridstate.js.map +7 -0
  202. package/dist/components/grouping.js +2 -0
  203. package/dist/components/grouping.js.map +7 -0
  204. package/dist/components/icon.js +1 -1
  205. package/dist/components/image.js +2 -0
  206. package/dist/components/image.js.map +7 -0
  207. package/dist/components/imagecanvas.js +2 -0
  208. package/dist/components/imagecanvas.js.map +7 -0
  209. package/dist/components/imagefield.js +2 -0
  210. package/dist/components/imagefield.js.map +7 -0
  211. package/dist/components/inputgroup.js +1 -1
  212. package/dist/components/label.js +1 -1
  213. package/dist/components/listbox.js +1 -1
  214. package/dist/components/lookupfield.js +1 -1
  215. package/dist/components/maskfield.js +2 -0
  216. package/dist/components/maskfield.js.map +7 -0
  217. package/dist/components/menu.js +1 -1
  218. package/dist/components/messagebox.js +1 -1
  219. package/dist/components/navmenu.js +1 -1
  220. package/dist/components/numberfield.js +1 -1
  221. package/dist/components/pagination.js +1 -1
  222. package/dist/components/panel.js +1 -1
  223. package/dist/components/pickerfield.js +1 -1
  224. package/dist/components/radiogroup.js +1 -1
  225. package/dist/components/rowediting.js +2 -0
  226. package/dist/components/rowediting.js.map +7 -0
  227. package/dist/components/searchgrid.js +1 -1
  228. package/dist/components/secretfield.js +1 -1
  229. package/dist/components/select.js +1 -1
  230. package/dist/components/shortcuts.js +2 -0
  231. package/dist/components/shortcuts.js.map +7 -0
  232. package/dist/components/slider.js +1 -1
  233. package/dist/components/spacer.js +1 -1
  234. package/dist/components/spinner.js +1 -1
  235. package/dist/components/stat.js +2 -0
  236. package/dist/components/stat.js.map +7 -0
  237. package/dist/components/stepform.js +1 -1
  238. package/dist/components/stepper.js +1 -1
  239. package/dist/components/suggestfield.js +1 -1
  240. package/dist/components/table.js +1 -1
  241. package/dist/components/tabs.js +1 -1
  242. package/dist/components/textarea.js +1 -1
  243. package/dist/components/textfield.js +1 -1
  244. package/dist/components/timeentry.js +2 -0
  245. package/dist/components/timeentry.js.map +7 -0
  246. package/dist/components/timefield.js +2 -0
  247. package/dist/components/timefield.js.map +7 -0
  248. package/dist/components/timeline.js +2 -0
  249. package/dist/components/timeline.js.map +7 -0
  250. package/dist/components/toast.js +1 -1
  251. package/dist/components/toggle.js +1 -1
  252. package/dist/components/toolbar.js +1 -1
  253. package/dist/components/tree.js +1 -1
  254. package/dist/components/treegrid.js +2 -0
  255. package/dist/components/treegrid.js.map +7 -0
  256. package/dist/components/viewmanager.js +1 -1
  257. package/dist/components/viewport.js +1 -1
  258. package/dist/components/widget.js +1 -1
  259. package/dist/components/window.js +1 -1
  260. package/dist/core.js +1 -1
  261. package/dist/css/avatar.css +68 -0
  262. package/dist/css/base.css +9 -0
  263. package/dist/css/carousel.css +119 -0
  264. package/dist/css/chart.css +168 -0
  265. package/dist/css/columntotals.css +56 -0
  266. package/dist/css/core.css +36 -0
  267. package/dist/css/datetimefield.css +15 -0
  268. package/dist/css/exportbar.css +9 -0
  269. package/dist/css/grid.css +52 -0
  270. package/dist/css/gridexport.css +35 -0
  271. package/dist/css/grouping.css +56 -0
  272. package/dist/css/image.css +46 -0
  273. package/dist/css/imagecanvas.css +75 -0
  274. package/dist/css/imagefield.css +103 -0
  275. package/dist/css/rowediting.css +39 -0
  276. package/dist/css/shortcuts.css +34 -0
  277. package/dist/css/stat.css +64 -0
  278. package/dist/css/stepform.css +1 -0
  279. package/dist/css/timeentry.css +116 -0
  280. package/dist/css/timeline.css +185 -0
  281. package/dist/css/treegrid.css +35 -0
  282. package/dist/css/window.css +2 -2
  283. package/dist/data.js +1 -1
  284. package/dist/dev.js +2 -0
  285. package/dist/dev.js.map +7 -0
  286. package/dist/index.js +16 -5
  287. package/dist/index.js.map +4 -4
  288. package/dist/optikos.css +1480 -142
  289. package/dist/testing.js +2 -0
  290. package/dist/testing.js.map +7 -0
  291. package/dist/themes/dark.css +7 -0
  292. package/dist/types/bind/index.d.ts +1 -1
  293. package/dist/types/bind/viewmodel.d.ts +33 -0
  294. package/dist/types/build/build.d.ts +49 -0
  295. package/dist/types/build/index.d.ts +1 -0
  296. package/dist/types/components/avatar.d.ts +1 -0
  297. package/dist/types/components/base/avatar/avatar.d.ts +22 -0
  298. package/dist/types/components/base/image/image.d.ts +25 -0
  299. package/dist/types/components/base/imagecanvas/imagecanvas.d.ts +39 -0
  300. package/dist/types/components/carousel.d.ts +1 -0
  301. package/dist/types/components/chart.d.ts +1 -0
  302. package/dist/types/components/charts/chart/chart.d.ts +64 -0
  303. package/dist/types/components/charts/stat/stat.d.ts +34 -0
  304. package/dist/types/components/columntotals.d.ts +1 -0
  305. package/dist/types/components/data/cellediting/cellediting.d.ts +3 -0
  306. package/dist/types/components/data/columntotals/columntotals.d.ts +24 -0
  307. package/dist/types/components/data/exportbar/exportbar.d.ts +24 -0
  308. package/dist/types/components/data/grid/footer.d.ts +6 -0
  309. package/dist/types/components/data/grid/grid.d.ts +37 -0
  310. package/dist/types/components/data/gridexport/gridexport.d.ts +29 -0
  311. package/dist/types/components/data/gridstate/gridstate.d.ts +23 -0
  312. package/dist/types/components/data/grouping/controls.d.ts +27 -0
  313. package/dist/types/components/data/grouping/grouping.d.ts +43 -0
  314. package/dist/types/components/data/rowediting/rowediting.d.ts +13 -0
  315. package/dist/types/components/data/searchgrid/searchgrid.d.ts +9 -2
  316. package/dist/types/components/data/timeentry/timeentry.d.ts +37 -0
  317. package/dist/types/components/data/timeline/timeline.d.ts +63 -0
  318. package/dist/types/components/data/treegrid/treegrid.d.ts +32 -0
  319. package/dist/types/components/datetimefield.d.ts +1 -0
  320. package/dist/types/components/exportbar.d.ts +1 -0
  321. package/dist/types/components/fields/datetimefield/datetimefield.d.ts +28 -0
  322. package/dist/types/components/fields/imagefield/imagefield.d.ts +48 -0
  323. package/dist/types/components/fields/maskfield/maskfield.d.ts +28 -0
  324. package/dist/types/components/fields/numberfield/numberfield.d.ts +9 -0
  325. package/dist/types/components/fields/pickerfield/pickerfield.d.ts +3 -0
  326. package/dist/types/components/fields/timefield/timefield.d.ts +24 -0
  327. package/dist/types/components/form/fieldlist/fieldlist.d.ts +2 -0
  328. package/dist/types/components/form/form/form.d.ts +5 -0
  329. package/dist/types/components/form/stepform/stepform.d.ts +1 -1
  330. package/dist/types/components/gridexport.d.ts +1 -0
  331. package/dist/types/components/gridstate.d.ts +1 -0
  332. package/dist/types/components/grouping.d.ts +1 -0
  333. package/dist/types/components/image.d.ts +1 -0
  334. package/dist/types/components/imagecanvas.d.ts +1 -0
  335. package/dist/types/components/imagefield.d.ts +1 -0
  336. package/dist/types/components/layout/carousel/carousel.d.ts +58 -0
  337. package/dist/types/components/maskfield.d.ts +1 -0
  338. package/dist/types/components/navigation/navmenu/navmenu.d.ts +2 -0
  339. package/dist/types/components/overlays/commandpalette/commandpalette.d.ts +2 -0
  340. package/dist/types/components/overlays/menu/menu.d.ts +4 -1
  341. package/dist/types/components/overlays/shortcuts/shortcuts.d.ts +27 -0
  342. package/dist/types/components/overlays/window/window.d.ts +14 -1
  343. package/dist/types/components/rowediting.d.ts +1 -0
  344. package/dist/types/components/shortcuts.d.ts +1 -0
  345. package/dist/types/components/stat.d.ts +1 -0
  346. package/dist/types/components/timeentry.d.ts +1 -0
  347. package/dist/types/components/timefield.d.ts +1 -0
  348. package/dist/types/components/timeline.d.ts +1 -0
  349. package/dist/types/components/treegrid.d.ts +1 -0
  350. package/dist/types/core/component.d.ts +7 -0
  351. package/dist/types/core/container.d.ts +10 -1
  352. package/dist/types/core/dev.d.ts +2 -0
  353. package/dist/types/core/field.d.ts +4 -0
  354. package/dist/types/core/i18n.d.ts +2 -0
  355. package/dist/types/core/index.d.ts +4 -1
  356. package/dist/types/core/path.d.ts +2 -0
  357. package/dist/types/core/permission.d.ts +11 -0
  358. package/dist/types/core/state.d.ts +9 -0
  359. package/dist/types/data/column.d.ts +11 -1
  360. package/dist/types/data/index.d.ts +1 -1
  361. package/dist/types/data/model.d.ts +2 -0
  362. package/dist/types/data/store.d.ts +21 -0
  363. package/dist/types/dev/index.d.ts +2 -0
  364. package/dist/types/dev/keys.d.ts +1 -0
  365. package/dist/types/index.d.ts +21 -0
  366. package/dist/types/testing/index.d.ts +25 -0
  367. package/dist/types/themes/color.d.ts +14 -0
  368. package/dist/types/themes/contrast.d.ts +15 -0
  369. package/dist/types/themes/define.d.ts +25 -3
  370. package/dist/types/themes/index.d.ts +3 -1
  371. package/dist/types/themes/seeds.d.ts +11 -0
  372. package/dist/types/ui/ui.d.ts +6 -0
  373. package/dist/ui.js +1 -1
  374. package/package.json +13 -1
  375. package/dist/chunk-2ZRNGG2N.js +0 -2
  376. package/dist/chunk-2ZRNGG2N.js.map +0 -7
  377. package/dist/chunk-4EQEHJB3.js +0 -2
  378. package/dist/chunk-4EQEHJB3.js.map +0 -7
  379. package/dist/chunk-4LZZ244E.js +0 -2
  380. package/dist/chunk-4LZZ244E.js.map +0 -7
  381. package/dist/chunk-4SYIIX5A.js +0 -2
  382. package/dist/chunk-4SYIIX5A.js.map +0 -7
  383. package/dist/chunk-7KMIFXHZ.js +0 -2
  384. package/dist/chunk-7KMIFXHZ.js.map +0 -7
  385. package/dist/chunk-A2NKDOYN.js +0 -2
  386. package/dist/chunk-A2NKDOYN.js.map +0 -7
  387. package/dist/chunk-CKXS375P.js +0 -2
  388. package/dist/chunk-CKXS375P.js.map +0 -7
  389. package/dist/chunk-EJGWCKE4.js +0 -2
  390. package/dist/chunk-EJGWCKE4.js.map +0 -7
  391. package/dist/chunk-ELYARUCN.js +0 -2
  392. package/dist/chunk-EV73ADN2.js +0 -2
  393. package/dist/chunk-EV73ADN2.js.map +0 -7
  394. package/dist/chunk-GD5JGKM7.js +0 -2
  395. package/dist/chunk-GD5JGKM7.js.map +0 -7
  396. package/dist/chunk-GZ7X34QP.js +0 -2
  397. package/dist/chunk-KCEUD232.js +0 -2
  398. package/dist/chunk-KCEUD232.js.map +0 -7
  399. package/dist/chunk-KLLAY2IM.js +0 -2
  400. package/dist/chunk-LBJSMXLV.js +0 -2
  401. package/dist/chunk-LBJSMXLV.js.map +0 -7
  402. package/dist/chunk-LW2WRUVL.js +0 -2
  403. package/dist/chunk-LW2WRUVL.js.map +0 -7
  404. package/dist/chunk-MW3RWBZ7.js +0 -2
  405. package/dist/chunk-MW3RWBZ7.js.map +0 -7
  406. package/dist/chunk-OEAXCCVM.js +0 -2
  407. package/dist/chunk-OEAXCCVM.js.map +0 -7
  408. package/dist/chunk-UB5RYS7T.js +0 -2
  409. package/dist/chunk-UB5RYS7T.js.map +0 -7
  410. package/dist/chunk-UXXJOU5J.js +0 -2
  411. package/dist/chunk-VU3GIDZ3.js +0 -2
  412. package/dist/chunk-VU3GIDZ3.js.map +0 -7
  413. package/dist/chunk-W2BAFOCN.js +0 -3
  414. package/dist/chunk-W2BAFOCN.js.map +0 -7
  415. package/dist/chunk-WFGTQZIQ.js +0 -2
  416. package/dist/chunk-WFGTQZIQ.js.map +0 -7
  417. package/dist/chunk-XX2MVWFS.js +0 -4
  418. package/dist/chunk-XYZ6VZ5T.js +0 -2
  419. package/dist/chunk-YBAYEU25.js +0 -2
  420. package/dist/chunk-YF75HKL6.js +0 -2
  421. package/dist/chunk-YF75HKL6.js.map +0 -7
  422. /package/dist/{chunk-5JEXM5S7.js.map → chunk-2GKIF7A6.js.map} +0 -0
  423. /package/dist/{chunk-5BC72727.js.map → chunk-2I4Y7I7C.js.map} +0 -0
  424. /package/dist/{chunk-Z2Z52GFT.js.map → chunk-2I7HDIOU.js.map} +0 -0
  425. /package/dist/{chunk-ZPPELYNJ.js.map → chunk-3BG75P7T.js.map} +0 -0
  426. /package/dist/{chunk-GNU4VOOE.js.map → chunk-3F4MN2BU.js.map} +0 -0
  427. /package/dist/{chunk-5DJTP53N.js.map → chunk-3FK52VQX.js.map} +0 -0
  428. /package/dist/{chunk-REW4LR46.js.map → chunk-4OB2IM5L.js.map} +0 -0
  429. /package/dist/{chunk-EDUMAMK4.js.map → chunk-5GCTM37D.js.map} +0 -0
  430. /package/dist/{chunk-JOFQJGZK.js.map → chunk-6BOM5KZR.js.map} +0 -0
  431. /package/dist/{chunk-Z2JBUHKA.js.map → chunk-6NP4AEV4.js.map} +0 -0
  432. /package/dist/{chunk-NXSTUFS7.js.map → chunk-6TZJO2G2.js.map} +0 -0
  433. /package/dist/{chunk-GZ7X34QP.js.map → chunk-7Y2GHQRB.js.map} +0 -0
  434. /package/dist/{chunk-G2KUK6AT.js.map → chunk-ADHKL2GM.js.map} +0 -0
  435. /package/dist/{chunk-JI265XFO.js.map → chunk-AJN66F32.js.map} +0 -0
  436. /package/dist/{chunk-YHEMA56R.js.map → chunk-AQ3RTHG5.js.map} +0 -0
  437. /package/dist/{chunk-ZVK4L5GK.js.map → chunk-BCVOUMJJ.js.map} +0 -0
  438. /package/dist/{chunk-HOF4JGMQ.js.map → chunk-BIGL3ZVD.js.map} +0 -0
  439. /package/dist/{chunk-HXDTGP2K.js.map → chunk-BRGT4O6Q.js.map} +0 -0
  440. /package/dist/{chunk-OGRFQTXA.js.map → chunk-BTGJ3MP4.js.map} +0 -0
  441. /package/dist/{chunk-TOLTUOZS.js.map → chunk-CWIE74NX.js.map} +0 -0
  442. /package/dist/{chunk-M242VYZA.js.map → chunk-CXZKCBQE.js.map} +0 -0
  443. /package/dist/{chunk-4EZJ5FKJ.js.map → chunk-DIOJGTUN.js.map} +0 -0
  444. /package/dist/{chunk-2ZUZ5HDL.js.map → chunk-ESRS5ZQV.js.map} +0 -0
  445. /package/dist/{chunk-JK74QK3M.js.map → chunk-FSR6BDVO.js.map} +0 -0
  446. /package/dist/{chunk-6VBK2I5B.js.map → chunk-G26R2F3W.js.map} +0 -0
  447. /package/dist/{chunk-G2DAD3MQ.js.map → chunk-GEJKFE4X.js.map} +0 -0
  448. /package/dist/{chunk-5Q76ACVI.js.map → chunk-H25XXQVH.js.map} +0 -0
  449. /package/dist/{chunk-XYZ6VZ5T.js.map → chunk-HRW25TMU.js.map} +0 -0
  450. /package/dist/{chunk-W3H7GTJY.js.map → chunk-LHWY6G6Q.js.map} +0 -0
  451. /package/dist/{chunk-Q26YZYTD.js.map → chunk-M7HLHGQV.js.map} +0 -0
  452. /package/dist/{chunk-IHE2MQ3W.js.map → chunk-MGSCSS7X.js.map} +0 -0
  453. /package/dist/{chunk-DBMWS3O5.js.map → chunk-MQ5BYGFY.js.map} +0 -0
  454. /package/dist/{chunk-5QUY72FX.js.map → chunk-NWHH3CYH.js.map} +0 -0
  455. /package/dist/{chunk-3TAW4AKH.js.map → chunk-OB3VIRQR.js.map} +0 -0
  456. /package/dist/{chunk-MB3MU6HR.js.map → chunk-PGVLRMTQ.js.map} +0 -0
  457. /package/dist/{chunk-TZOQWCVH.js.map → chunk-QOSTS5I3.js.map} +0 -0
  458. /package/dist/{chunk-3S24ZRPK.js.map → chunk-RMATRKXV.js.map} +0 -0
  459. /package/dist/{chunk-I4SP6JTU.js.map → chunk-S3ILIWSW.js.map} +0 -0
  460. /package/dist/{chunk-XHOBNSBO.js.map → chunk-SEUIIPHS.js.map} +0 -0
  461. /package/dist/{chunk-23XLG2EM.js.map → chunk-SEW5OCQF.js.map} +0 -0
  462. /package/dist/{chunk-LQRFNQ2N.js.map → chunk-U25QSLAH.js.map} +0 -0
  463. /package/dist/{chunk-FEHGU6EP.js.map → chunk-UL364TLO.js.map} +0 -0
  464. /package/dist/{chunk-JBLRAM7Z.js.map → chunk-XNRZJP4E.js.map} +0 -0
  465. /package/dist/{chunk-ELYARUCN.js.map → chunk-YJTUFK4P.js.map} +0 -0
  466. /package/dist/{chunk-2YZB6XQR.js.map → chunk-ZLYZFHEN.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,49 @@
1
+ import { Grid, type GridConfig } from '../components/data/grid/grid.js';
2
+ import { Form, type FormConfig } from '../components/form/form/form.js';
3
+ import type { FilterField } from '../components/data/filterbuilder/filterbuilder.js';
4
+ import type { Column } from '../data/column.js';
5
+ import type { Component } from '../core/component.js';
6
+ export type FieldKind = 'text' | 'email' | 'area' | 'number' | 'money' | 'duration' | 'date' | 'datetime' | 'select' | 'bool';
7
+ type Cfg = Record<string, any>;
8
+ export interface FieldSpec {
9
+ /** The record's property. */
10
+ name: string;
11
+ /** Default: the name as words (`unitPrice` → "Unit price"). */
12
+ label?: string;
13
+ /** Default `text`. `duration` is a number of minutes, shown as `7h 30m`. */
14
+ type?: FieldKind;
15
+ /** For `select`. */
16
+ options?: Array<string | number | {
17
+ value: string | number;
18
+ label: string;
19
+ }>;
20
+ /** Picks the value in a lookup window: a LookupDef or the name given to `registerLookup`. */
21
+ lookup?: Cfg | string;
22
+ required?: boolean;
23
+ readonly?: boolean;
24
+ /** A band over the grid header and a section of the form. */
25
+ group?: string;
26
+ /** Total of the (filtered) rows in the grid: the starting total of the `columnTotals()` plugin. */
27
+ summary?: Column['summary'];
28
+ /** Grid column width in px. */
29
+ width?: number;
30
+ /** Leaves the field out of some of the builds. */
31
+ hide?: Array<'grid' | 'form' | 'filter'>;
32
+ /** Overrides for what each build makes. */
33
+ column?: Partial<Column>;
34
+ field?: Cfg;
35
+ filter?: Partial<FilterField>;
36
+ }
37
+ /** Grid columns: right-aligned numbers and money, formatted dates and booleans. */
38
+ export declare function buildColumns(specs: FieldSpec[]): Column[];
39
+ /** Form fields (instances), in order. */
40
+ export declare function buildFields(specs: FieldSpec[]): Component[];
41
+ /** Fields for a `FilterBuilder`; `bool` filters as a Yes/No choice. */
42
+ export declare function buildFilterFields(specs: FieldSpec[]): FilterField[];
43
+ /** A `Grid` whose columns come from the specs. `cfg` adds or overrides anything (`store`, `selection`, ...). */
44
+ export declare const buildGrid: (specs: FieldSpec[], cfg?: Partial<GridConfig>) => Grid<any>;
45
+ /** A `Form` with the fields in `columns` columns (default 2); specs with a `group` go in a `FieldSet` of that title. */
46
+ export declare function buildForm(specs: FieldSpec[], cfg?: FormConfig & {
47
+ columns?: number;
48
+ }): Form;
49
+ export {};
@@ -0,0 +1 @@
1
+ export { buildColumns, buildFields, buildFilterFields, buildGrid, buildForm, type FieldSpec, type FieldKind } from './build.js';
@@ -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
+ }
@@ -0,0 +1 @@
1
+ export * from '../components/data/columntotals/columntotals.js';
@@ -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)`.
@@ -0,0 +1,24 @@
1
+ import type { Model } from '../../../data/model.js';
2
+ import type { GridPlugin } from '../grid/grid.js';
3
+ /** An operation offered in the column menu besides the built-in ones. */
4
+ export interface TotalOperation {
5
+ text: string;
6
+ /** The column's values and the records of every filtered row. */
7
+ run: (values: any[], recs: Model[]) => unknown;
8
+ }
9
+ export interface ColumnTotalsOptions {
10
+ /** Your own operations (a median, a weighted mean...). Offered on every column. */
11
+ operations?: TotalOperation[];
12
+ /**
13
+ * Where the answer goes: `'bar'` (default) keeps it in a bar under the grid; `'modal'` answers in a dialog and `'toast'` in a
14
+ * notice, once, and nothing stays on the grid.
15
+ */
16
+ show?: 'bar' | 'modal' | 'toast';
17
+ /** `bar` only: under the grid (default) or `'top'`, right under the header, above the rows (a row of the grid itself). */
18
+ position?: 'bottom' | 'top';
19
+ }
20
+ /**
21
+ * A button on every column header opens a menu of totals (sum, average, minimum, maximum, count, your own); the choice
22
+ * shows in a bar under the grid, over every filtered row. A column's `summary` is where it starts and where it is kept.
23
+ */
24
+ export declare function columnTotals(options?: ColumnTotalsOptions): GridPlugin;
@@ -0,0 +1,24 @@
1
+ import type { GridPlugin } from '../grid/grid.js';
2
+ export type ExportBarAction = 'csv' | 'xlsx' | 'page' | 'print';
3
+ export interface ExportBarOptions {
4
+ /** Each button: `false` leaves it out. `csv`, `xlsx` and `print` default to true; `page` (CSV of the page on screen) to true on a paged grid. */
5
+ csv?: boolean;
6
+ xlsx?: boolean;
7
+ page?: boolean;
8
+ print?: boolean;
9
+ /** File name without extension. Default `export`. */
10
+ filename?: string;
11
+ /** A heading above the printed table. */
12
+ title?: string;
13
+ /** Show the text beside the icons. Default false (icons with a tooltip). */
14
+ labels?: boolean;
15
+ }
16
+ export interface ExportBar extends GridPlugin {
17
+ setVisible(action: ExportBarAction, visible: boolean): void;
18
+ setDisabled(action: ExportBarAction, disabled: boolean): void;
19
+ }
20
+ /**
21
+ * Export and print buttons inside the grid, in a row with the pager: `plugins: [exportBar({ print: false })]`. They run
22
+ * `exportGrid` and `printGrid`, which still work on their own from your own buttons.
23
+ */
24
+ export declare function exportBar(options?: ExportBarOptions): ExportBar;
@@ -0,0 +1,6 @@
1
+ import type { Grid } from './grid.js';
2
+ /**
3
+ * The row under a grid where the pager and the plugins' icon buttons sit side by side. Each plugin adds its own group;
4
+ * the last one out gives the pager back.
5
+ */
6
+ export declare function addFooterGroup(grid: Grid, group: HTMLElement): () => void;
@@ -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,27 @@
1
+ import type { Model } from '../../../data/model.js';
2
+ import type { Grid } from '../grid/grid.js';
3
+ export type GroupingControl = 'expand' | 'collapse' | 'by';
4
+ /** A way to group, offered in the "Group by" menu: a record field or any function of the record. */
5
+ export interface GroupChoice {
6
+ text: string;
7
+ field?: string;
8
+ by?: (rec: Model) => unknown;
9
+ }
10
+ interface Target {
11
+ expandAll(): void;
12
+ collapseAll(): void;
13
+ setGroupBy(by: string | ((rec: Model) => unknown) | null): void;
14
+ }
15
+ /** Icon buttons in the grid's footer row (beside the pager): expand all, collapse all and a "Group by" menu. */
16
+ export declare function groupingControls(grid: Grid, target: Target, o: {
17
+ expand?: boolean;
18
+ collapse?: boolean;
19
+ by?: boolean;
20
+ choices: GroupChoice[];
21
+ current?: string;
22
+ }): {
23
+ set: (a: GroupingControl, visible: boolean) => void | undefined;
24
+ disable: (a: GroupingControl, disabled: boolean) => void | undefined;
25
+ destroy(): void;
26
+ };
27
+ export {};
@@ -0,0 +1,43 @@
1
+ import type { Model } from '../../../data/model.js';
2
+ import { summarize } from '../../../data/column.js';
3
+ import { type GroupChoice, type GroupingControl } from './controls.js';
4
+ import type { GridPlugin } from '../grid/grid.js';
5
+ export { summarize };
6
+ export type { GroupChoice, GroupingControl };
7
+ export interface GroupingOptions {
8
+ /** Record field to group by. */
9
+ field?: string;
10
+ /** Or any function of the record (a year, a range): its result is the group. */
11
+ by?: (rec: Model) => unknown;
12
+ /** Text of a group header (before the count). Default: the key. */
13
+ label?: (key: unknown, recs: Model[]) => string;
14
+ /** Total rows of the columns that have a `summary`: `group` (under each group), `grand` (at the end) or `both`. Default `group`. */
15
+ summary?: 'group' | 'grand' | 'both';
16
+ /** Start with every group closed. */
17
+ collapsed?: boolean;
18
+ /** Icon buttons inside the grid, beside the pager: expand all, collapse all and, with `choices`, a "Group by" menu. `false` leaves one out. */
19
+ controls?: boolean | {
20
+ expand?: boolean;
21
+ collapse?: boolean;
22
+ by?: boolean;
23
+ };
24
+ /** The ways to group offered by the controls' menu (a field or a function each). */
25
+ choices?: GroupChoice[];
26
+ }
27
+ export interface Grouping extends GridPlugin {
28
+ expandAll(): void;
29
+ collapseAll(): void;
30
+ /** Changes what to group by; `null` shows the plain list. */
31
+ setGroupBy(by: string | ((rec: Model) => unknown) | null): void;
32
+ /** Opens or closes one group by its key. */
33
+ toggle(key: unknown, open?: boolean): void;
34
+ /** The in-grid controls: show or hide one. */
35
+ setControlVisible(control: GroupingControl, visible: boolean): void;
36
+ setControlDisabled(control: GroupingControl, disabled: boolean): void;
37
+ }
38
+ /**
39
+ * Groups the rows of the current page (a remote store groups what it loaded, not the whole set) under a header with
40
+ * its count; the header toggles by click, Enter/Space, → and ←. Sorting works inside each group. Group headers and total
41
+ * rows are virtual rows like any other. Fires `group-toggle(key, open)` on the grid.
42
+ */
43
+ export declare function grouping(options?: GroupingOptions): Grouping;