@zeyos/zx 2.1.0 → 2.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (311) hide show
  1. package/CHANGELOG.md +51 -0
  2. package/README.md +15 -0
  3. package/dist/types/compat/base.d.ts +156 -0
  4. package/dist/types/compat/globals.d.ts +20 -0
  5. package/dist/types/compat/index.d.ts +128 -0
  6. package/dist/types/compat/map/basic.d.ts +175 -0
  7. package/dist/types/compat/map/data.d.ts +102 -0
  8. package/dist/types/compat/map/date-time.d.ts +80 -0
  9. package/dist/types/compat/map/factory.d.ts +9 -0
  10. package/dist/types/compat/map/form.d.ts +98 -0
  11. package/dist/types/compat/map/helpers.d.ts +12 -0
  12. package/dist/types/compat/map/http.d.ts +36 -0
  13. package/dist/types/compat/map/layout.d.ts +106 -0
  14. package/dist/types/compat/map/options.d.ts +80 -0
  15. package/dist/types/compat/map/select.d.ts +95 -0
  16. package/dist/types/compat/map/stubs.d.ts +32 -0
  17. package/dist/types/compat/map/utilities.d.ts +37 -0
  18. package/dist/types/compat-entry.d.ts +5 -0
  19. package/dist/types/components/badge/badge.d.ts +46 -0
  20. package/dist/types/components/breadcrumb/breadcrumb.d.ts +200 -0
  21. package/dist/types/components/button/button.d.ts +42 -0
  22. package/dist/types/components/check-button/check-button.d.ts +98 -0
  23. package/dist/types/components/checklist/checklist.d.ts +143 -0
  24. package/dist/types/components/checklist/field-adapter.d.ts +5 -0
  25. package/dist/types/components/context-menu/context-menu.d.ts +130 -0
  26. package/dist/types/components/copy/copy-button.d.ts +48 -0
  27. package/dist/types/components/copy/copy-input.d.ts +91 -0
  28. package/dist/types/components/data-filter/data-filter.d.ts +250 -0
  29. package/dist/types/components/data-filter/filter-core.d.ts +52 -0
  30. package/dist/types/components/date-picker/date-picker.d.ts +137 -0
  31. package/dist/types/components/date-picker/date-range-picker.d.ts +350 -0
  32. package/dist/types/components/date-picker/field-adapter.d.ts +6 -0
  33. package/dist/types/components/date-picker/month-picker.d.ts +75 -0
  34. package/dist/types/components/date-picker/range-field-adapter.d.ts +7 -0
  35. package/dist/types/components/date-picker/time-picker.d.ts +127 -0
  36. package/dist/types/components/datebox/date-range-box.d.ts +218 -0
  37. package/dist/types/components/datebox/datebox.d.ts +160 -0
  38. package/dist/types/components/datebox/field-adapter.d.ts +5 -0
  39. package/dist/types/components/dialog/dialog.d.ts +284 -0
  40. package/dist/types/components/dropdown/dropdown.d.ts +118 -0
  41. package/dist/types/components/empty-state/empty-state.d.ts +38 -0
  42. package/dist/types/components/field/field.d.ts +231 -0
  43. package/dist/types/components/field-upload/field-adapter.d.ts +5 -0
  44. package/dist/types/components/field-upload/field-upload.d.ts +213 -0
  45. package/dist/types/components/fieldset/fieldset.d.ts +125 -0
  46. package/dist/types/components/finder/finder.d.ts +252 -0
  47. package/dist/types/components/form/form.d.ts +194 -0
  48. package/dist/types/components/groupbox/groupbox.d.ts +89 -0
  49. package/dist/types/components/layout/layout.d.ts +132 -0
  50. package/dist/types/components/loading/inline-loading.d.ts +86 -0
  51. package/dist/types/components/loading/progress-bar.d.ts +168 -0
  52. package/dist/types/components/loading/spinner.d.ts +34 -0
  53. package/dist/types/components/master-panel/master-panel.d.ts +112 -0
  54. package/dist/types/components/menu-button/menu-button.d.ts +142 -0
  55. package/dist/types/components/message/message.d.ts +212 -0
  56. package/dist/types/components/modal/modal.d.ts +105 -0
  57. package/dist/types/components/multi-value-editor/field-adapter.d.ts +5 -0
  58. package/dist/types/components/multi-value-editor/multi-value-editor.d.ts +66 -0
  59. package/dist/types/components/navigation-bar/navigation-bar.d.ts +229 -0
  60. package/dist/types/components/number-field/field-adapter.d.ts +5 -0
  61. package/dist/types/components/number-field/number-field.d.ts +292 -0
  62. package/dist/types/components/pagination/pagination.d.ts +267 -0
  63. package/dist/types/components/panel/panel.d.ts +194 -0
  64. package/dist/types/components/permission/permission.d.ts +93 -0
  65. package/dist/types/components/rating/field-adapter.d.ts +5 -0
  66. package/dist/types/components/rating/rating.d.ts +213 -0
  67. package/dist/types/components/search/search.d.ts +98 -0
  68. package/dist/types/components/select/field-adapter.d.ts +5 -0
  69. package/dist/types/components/select/filter.d.ts +11 -0
  70. package/dist/types/components/select/select.d.ts +235 -0
  71. package/dist/types/components/skeleton/skeleton.d.ts +97 -0
  72. package/dist/types/components/slider/field-adapter.d.ts +5 -0
  73. package/dist/types/components/slider/slider.d.ts +216 -0
  74. package/dist/types/components/split-view/split-view.d.ts +335 -0
  75. package/dist/types/components/stepper/stepper.d.ts +314 -0
  76. package/dist/types/components/stepper/steps.d.ts +131 -0
  77. package/dist/types/components/tabbox/tabbox.d.ts +230 -0
  78. package/dist/types/components/table/sort.d.ts +49 -0
  79. package/dist/types/components/table/table.d.ts +872 -0
  80. package/dist/types/components/tag-picker/field-adapter.d.ts +5 -0
  81. package/dist/types/components/tag-picker/tag-picker.d.ts +375 -0
  82. package/dist/types/components/timebox/field-adapter.d.ts +5 -0
  83. package/dist/types/components/timebox/timebox.d.ts +121 -0
  84. package/dist/types/components/toggle/field-adapter.d.ts +5 -0
  85. package/dist/types/components/toggle/toggle.d.ts +94 -0
  86. package/dist/types/components/toolbar/toolbar.d.ts +230 -0
  87. package/dist/types/components/tooltip/tooltip.d.ts +183 -0
  88. package/dist/types/components/tree/hierarchy.d.ts +113 -0
  89. package/dist/types/components/tree/tree.d.ts +383 -0
  90. package/dist/types/components/truncate/truncate.d.ts +61 -0
  91. package/dist/types/components/value-list/field-adapter.d.ts +5 -0
  92. package/dist/types/components/value-list/value-list.d.ts +143 -0
  93. package/dist/types/core/breakpoint.d.ts +68 -0
  94. package/dist/types/core/component.d.ts +115 -0
  95. package/dist/types/core/date.d.ts +50 -0
  96. package/dist/types/core/dom.d.ts +86 -0
  97. package/dist/types/core/export.d.ts +70 -0
  98. package/dist/types/core/fontawesome.d.ts +107 -0
  99. package/dist/types/core/format.d.ts +107 -0
  100. package/dist/types/core/http.d.ts +122 -0
  101. package/dist/types/core/i18n.d.ts +35 -0
  102. package/dist/types/core/icons.d.ts +137 -0
  103. package/dist/types/core/keyboard.d.ts +72 -0
  104. package/dist/types/core/position.d.ts +45 -0
  105. package/dist/types/core/storage.d.ts +46 -0
  106. package/dist/types/core/util.d.ts +117 -0
  107. package/dist/types/elements/define.d.ts +73 -0
  108. package/dist/types/elements/reflect.d.ts +27 -0
  109. package/dist/types/index.d.ts +79 -0
  110. package/dist/types/zeyos/connect.d.ts +65 -0
  111. package/dist/types/zeyos/form.d.ts +140 -0
  112. package/dist/types/zeyos/icons.d.ts +104 -0
  113. package/dist/types/zeyos/index.d.ts +12 -0
  114. package/dist/types/zeyos/modules.d.ts +110 -0
  115. package/dist/types/zeyos/query.d.ts +157 -0
  116. package/dist/types/zeyos/schema.d.ts +79 -0
  117. package/dist/types/zeyos/select.d.ts +167 -0
  118. package/dist/types/zeyos/table.d.ts +205 -0
  119. package/dist/zx-compat.esm.js +375 -39
  120. package/dist/zx-compat.esm.min.js +1 -1
  121. package/dist/zx-compat.global.js +372 -73
  122. package/dist/zx-compat.global.min.js +3 -3
  123. package/dist/zx-zeyos.esm.js +355 -49
  124. package/dist/zx-zeyos.esm.min.js +1 -1
  125. package/dist/zx.css +68 -6
  126. package/dist/zx.esm.js +359 -73
  127. package/dist/zx.esm.min.js +3 -3
  128. package/dist/zx.global.js +359 -73
  129. package/dist/zx.global.min.js +3 -3
  130. package/dist/zx.min.css +1 -1
  131. package/docs/api.json +48 -2
  132. package/docs/llms.md +31 -0
  133. package/package.json +37 -9
  134. package/src/compat/base.js +291 -0
  135. package/src/compat/globals.js +165 -0
  136. package/src/compat/index.js +84 -0
  137. package/src/compat/map/basic.js +464 -0
  138. package/src/compat/map/data.js +232 -0
  139. package/src/compat/map/date-time.js +177 -0
  140. package/src/compat/map/factory.js +45 -0
  141. package/src/compat/map/form.js +330 -0
  142. package/src/compat/map/helpers.js +46 -0
  143. package/src/compat/map/http.js +117 -0
  144. package/src/compat/map/layout.js +256 -0
  145. package/src/compat/map/options.js +267 -0
  146. package/src/compat/map/select.js +198 -0
  147. package/src/compat/map/stubs.js +26 -0
  148. package/src/compat/map/utilities.js +113 -0
  149. package/src/compat-entry.js +11 -0
  150. package/src/components/badge/badge.css +147 -0
  151. package/src/components/badge/badge.js +92 -0
  152. package/src/components/breadcrumb/breadcrumb.css +105 -0
  153. package/src/components/breadcrumb/breadcrumb.js +331 -0
  154. package/src/components/button/button.css +104 -0
  155. package/src/components/button/button.js +76 -0
  156. package/src/components/check-button/check-button.css +66 -0
  157. package/src/components/check-button/check-button.js +167 -0
  158. package/src/components/checklist/checklist.css +65 -0
  159. package/src/components/checklist/checklist.js +282 -0
  160. package/src/components/checklist/field-adapter.js +46 -0
  161. package/src/components/context-menu/context-menu.css +54 -0
  162. package/src/components/context-menu/context-menu.js +334 -0
  163. package/src/components/copy/copy-button.css +27 -0
  164. package/src/components/copy/copy-button.js +78 -0
  165. package/src/components/copy/copy-input.css +59 -0
  166. package/src/components/copy/copy-input.js +123 -0
  167. package/src/components/data-filter/data-filter.css +53 -0
  168. package/src/components/data-filter/data-filter.js +400 -0
  169. package/src/components/data-filter/filter-core.js +128 -0
  170. package/src/components/date-picker/date-picker.css +181 -0
  171. package/src/components/date-picker/date-picker.js +500 -0
  172. package/src/components/date-picker/date-range-picker.css +264 -0
  173. package/src/components/date-picker/date-range-picker.js +990 -0
  174. package/src/components/date-picker/field-adapter.js +36 -0
  175. package/src/components/date-picker/month-picker.js +223 -0
  176. package/src/components/date-picker/range-field-adapter.js +31 -0
  177. package/src/components/date-picker/time-picker.css +191 -0
  178. package/src/components/date-picker/time-picker.js +406 -0
  179. package/src/components/datebox/date-range-box.css +128 -0
  180. package/src/components/datebox/date-range-box.js +492 -0
  181. package/src/components/datebox/datebox.css +108 -0
  182. package/src/components/datebox/datebox.js +358 -0
  183. package/src/components/datebox/field-adapter.js +34 -0
  184. package/src/components/dialog/dialog.css +74 -0
  185. package/src/components/dialog/dialog.js +450 -0
  186. package/src/components/dropdown/dropdown.css +24 -0
  187. package/src/components/dropdown/dropdown.js +288 -0
  188. package/src/components/empty-state/empty-state.css +80 -0
  189. package/src/components/empty-state/empty-state.js +92 -0
  190. package/src/components/field/field.css +127 -0
  191. package/src/components/field/field.js +605 -0
  192. package/src/components/field-upload/field-adapter.js +21 -0
  193. package/src/components/field-upload/field-upload.css +108 -0
  194. package/src/components/field-upload/field-upload.js +475 -0
  195. package/src/components/fieldset/fieldset.css +37 -0
  196. package/src/components/fieldset/fieldset.js +307 -0
  197. package/src/components/finder/finder.css +98 -0
  198. package/src/components/finder/finder.js +509 -0
  199. package/src/components/form/form.css +32 -0
  200. package/src/components/form/form.js +302 -0
  201. package/src/components/groupbox/groupbox.css +51 -0
  202. package/src/components/groupbox/groupbox.js +199 -0
  203. package/src/components/layout/layout.css +117 -0
  204. package/src/components/layout/layout.js +136 -0
  205. package/src/components/loading/inline-loading.css +34 -0
  206. package/src/components/loading/inline-loading.js +140 -0
  207. package/src/components/loading/progress-bar.css +115 -0
  208. package/src/components/loading/progress-bar.js +259 -0
  209. package/src/components/loading/spinner.css +58 -0
  210. package/src/components/loading/spinner.js +57 -0
  211. package/src/components/master-panel/master-panel.css +51 -0
  212. package/src/components/master-panel/master-panel.js +203 -0
  213. package/src/components/menu-button/menu-button.css +49 -0
  214. package/src/components/menu-button/menu-button.js +294 -0
  215. package/src/components/message/message.css +122 -0
  216. package/src/components/message/message.js +499 -0
  217. package/src/components/modal/modal.css +47 -0
  218. package/src/components/modal/modal.js +203 -0
  219. package/src/components/multi-value-editor/field-adapter.js +44 -0
  220. package/src/components/multi-value-editor/multi-value-editor.css +56 -0
  221. package/src/components/multi-value-editor/multi-value-editor.js +170 -0
  222. package/src/components/navigation-bar/navigation-bar.css +130 -0
  223. package/src/components/navigation-bar/navigation-bar.js +450 -0
  224. package/src/components/number-field/field-adapter.js +40 -0
  225. package/src/components/number-field/number-field.css +77 -0
  226. package/src/components/number-field/number-field.js +545 -0
  227. package/src/components/pagination/pagination.css +95 -0
  228. package/src/components/pagination/pagination.js +481 -0
  229. package/src/components/panel/panel.css +123 -0
  230. package/src/components/panel/panel.js +336 -0
  231. package/src/components/permission/permission.css +47 -0
  232. package/src/components/permission/permission.js +198 -0
  233. package/src/components/rating/field-adapter.js +34 -0
  234. package/src/components/rating/rating.css +97 -0
  235. package/src/components/rating/rating.js +395 -0
  236. package/src/components/search/search.css +70 -0
  237. package/src/components/search/search.js +193 -0
  238. package/src/components/select/field-adapter.js +24 -0
  239. package/src/components/select/filter.js +39 -0
  240. package/src/components/select/select.css +180 -0
  241. package/src/components/select/select.js +663 -0
  242. package/src/components/skeleton/skeleton.css +76 -0
  243. package/src/components/skeleton/skeleton.js +139 -0
  244. package/src/components/slider/field-adapter.js +36 -0
  245. package/src/components/slider/slider.css +181 -0
  246. package/src/components/slider/slider.js +399 -0
  247. package/src/components/split-view/split-view.css +139 -0
  248. package/src/components/split-view/split-view.js +806 -0
  249. package/src/components/stepper/stepper.css +234 -0
  250. package/src/components/stepper/stepper.js +459 -0
  251. package/src/components/stepper/steps.js +131 -0
  252. package/src/components/tabbox/tabbox.css +281 -0
  253. package/src/components/tabbox/tabbox.js +484 -0
  254. package/src/components/table/sort.js +85 -0
  255. package/src/components/table/table.css +364 -0
  256. package/src/components/table/table.js +1711 -0
  257. package/src/components/tag-picker/field-adapter.js +35 -0
  258. package/src/components/tag-picker/tag-picker.css +169 -0
  259. package/src/components/tag-picker/tag-picker.js +837 -0
  260. package/src/components/timebox/field-adapter.js +24 -0
  261. package/src/components/timebox/timebox.css +51 -0
  262. package/src/components/timebox/timebox.js +276 -0
  263. package/src/components/toggle/field-adapter.js +24 -0
  264. package/src/components/toggle/toggle.css +66 -0
  265. package/src/components/toggle/toggle.js +150 -0
  266. package/src/components/toolbar/toolbar.css +81 -0
  267. package/src/components/toolbar/toolbar.js +511 -0
  268. package/src/components/tooltip/tooltip.css +36 -0
  269. package/src/components/tooltip/tooltip.js +420 -0
  270. package/src/components/tree/hierarchy.js +151 -0
  271. package/src/components/tree/tree.css +99 -0
  272. package/src/components/tree/tree.js +784 -0
  273. package/src/components/truncate/truncate.css +20 -0
  274. package/src/components/truncate/truncate.js +92 -0
  275. package/src/components/value-list/field-adapter.js +24 -0
  276. package/src/components/value-list/value-list.css +108 -0
  277. package/src/components/value-list/value-list.js +336 -0
  278. package/src/core/breakpoint.js +150 -0
  279. package/src/core/component.js +292 -0
  280. package/src/core/date.js +216 -0
  281. package/src/core/dom.js +260 -0
  282. package/src/core/export.js +204 -0
  283. package/src/core/fontawesome.js +177 -0
  284. package/src/core/format.js +283 -0
  285. package/src/core/http.js +246 -0
  286. package/src/core/i18n.js +83 -0
  287. package/src/core/icons.js +283 -0
  288. package/src/core/keyboard.js +240 -0
  289. package/src/core/position.js +177 -0
  290. package/src/core/storage.js +175 -0
  291. package/src/core/util.js +336 -0
  292. package/src/elements/define.js +715 -0
  293. package/src/elements/reflect.js +79 -0
  294. package/src/index.js +131 -0
  295. package/src/zeyos/connect.js +142 -0
  296. package/src/zeyos/form.js +254 -0
  297. package/src/zeyos/icons.js +92 -0
  298. package/src/zeyos/index.js +21 -0
  299. package/src/zeyos/modules.js +269 -0
  300. package/src/zeyos/query.js +199 -0
  301. package/src/zeyos/schema.js +474 -0
  302. package/src/zeyos/select.js +175 -0
  303. package/src/zeyos/table.js +272 -0
  304. package/styles/base.css +124 -0
  305. package/styles/icons.css +34 -0
  306. package/styles/tokens/dark.css +84 -0
  307. package/styles/tokens/density.css +9 -0
  308. package/styles/tokens/global.css +80 -0
  309. package/styles/tokens/modules.css +109 -0
  310. package/styles/tokens/semantic.css +49 -0
  311. package/styles/zx.css +61 -0
@@ -0,0 +1,84 @@
1
+ import { GxWrapper } from './base.js';
2
+ import { installElementStorage, installGlobals, parse } from './globals.js';
3
+ import {
4
+ BootstrapMessage, BootstrapPopup, CheckButton, Dialog, Dropdown, MenuButton, Msgbox, Popup,
5
+ PopupAlert, PopupConfirm, PopupConfirmCanceled, Toggle
6
+ } from './map/basic.js';
7
+ import {
8
+ BootstrapChecklist, BootstrapTable, Checklist, DataFilter, Permission, SimpleTable, Table
9
+ } from './map/data.js';
10
+ import {
11
+ BootstrapTimebox, CoreTimebox, Datebox, DatePicker, MonthPicker, Timebox, TimePicker
12
+ } from './map/date-time.js';
13
+ import { Factory } from './map/factory.js';
14
+ import { Field, Fieldset, FieldUpload, Form, MultiValueEditor, ValueList } from './map/form.js';
15
+ import { Client, Request } from './map/http.js';
16
+ import {
17
+ BootstrapTabbox, Groupbox, MasterPanel, NavigationBar, Panel, Search, Tabbox
18
+ } from './map/layout.js';
19
+ import {
20
+ BootstrapSelect, BootstrapSelectDyn, BootstrapSelectFilter, BootstrapSelectPrio,
21
+ Select, SelectDyn, SelectDynREST, SelectFilter, SelectPrio
22
+ } from './map/select.js';
23
+ import { Container, Settings, Blend, Collapse, HGroup, Hud, Templates, Toggling } from './map/stubs.js';
24
+ import { util } from './map/utilities.js';
25
+
26
+ /** Compatibility utilities and explicit global/prototype installers. */
27
+ const compat = Object.freeze({ installGlobals, installElementStorage, parse, GxWrapper });
28
+
29
+ /** Window-independent legacy gx namespace. */
30
+ export const gx = {
31
+ core: { Settings },
32
+ ui: {
33
+ Container, SimpleTable, Timebox: CoreTimebox,
34
+ Collapse, Blend, Hud, Toggling, HGroup, Templates
35
+ },
36
+ util,
37
+ zeyos: {
38
+ Toggle, Msgbox, Popup, Dialog, Dropdown,
39
+ Select, SelectFilter, SelectDyn, SelectPrio,
40
+ Checklist, Permission, Table, Tabbox,
41
+ Panel, MasterPanel, Groupbox, Search,
42
+ Datebox, DatePicker, TimePicker, MonthPicker, Timebox,
43
+ Client, Request, Factory
44
+ },
45
+ bootstrap: {
46
+ Message: BootstrapMessage,
47
+ Popup: BootstrapPopup,
48
+ PopupAlert,
49
+ PopupConfirm,
50
+ PopupConfirmCanceled,
51
+ MenuButton,
52
+ CheckButton,
53
+ Select: BootstrapSelect,
54
+ SelectFilter: BootstrapSelectFilter,
55
+ SelectDyn: BootstrapSelectDyn,
56
+ SelectDynREST,
57
+ SelectPrio: BootstrapSelectPrio,
58
+ Checklist: BootstrapChecklist,
59
+ Table: BootstrapTable,
60
+ Tabbox: BootstrapTabbox,
61
+ NavigationBar,
62
+ Timebox: BootstrapTimebox,
63
+ Form,
64
+ Fieldset,
65
+ Field,
66
+ ValueList,
67
+ MultiValueEditor,
68
+ FieldUpload,
69
+ DataFilter
70
+ },
71
+ compat
72
+ };
73
+
74
+ /** Assigns the compatibility namespace to a browser-like host without installing optional globals. @param {typeof globalThis} [host=globalThis] @returns {typeof gx} */
75
+ export function install(host = globalThis) {
76
+ installElementStorage(host);
77
+ host.gx = gx;
78
+ return gx;
79
+ }
80
+
81
+ gx.install = install;
82
+
83
+ export { GxWrapper, installElementStorage, installGlobals, parse };
84
+ export default gx;
@@ -0,0 +1,464 @@
1
+ import {
2
+ CheckButton as ZxCheckButton,
3
+ Dialog as ZxDialog,
4
+ MenuButton as ZxMenuButton,
5
+ Message as ZxMessage,
6
+ Toggle as ZxToggle
7
+ } from '../../index.js';
8
+ import { GxWrapper } from '../base.js';
9
+ import { legacyContent, messageKind, targetElement, textLabel, warnFunctionOnce, warnMethodOnce } from './helpers.js';
10
+
11
+ /** Legacy ZeyOS switch. */
12
+ export class Toggle extends GxWrapper {
13
+ static legacyName = 'gx.zeyos.Toggle';
14
+
15
+ /** @param {Element|string|null} display @param {Record<string, any>} [options={}] */
16
+ constructor(display, options = {}) {
17
+ super(options, { on: false, value: true });
18
+ const { target, host } = buttonTarget(display);
19
+ const component = new ZxToggle(target, {
20
+ checked: Boolean(options.on), value: options.value ?? true,
21
+ label: options.label ?? null, disabled: Boolean(options.disabled)
22
+ });
23
+ if (host) host.append(component.toElement());
24
+ this._attach(component, {
25
+ events: {
26
+ check: { type: 'change', filter: (detail) => detail.checked, args: () => [this] },
27
+ uncheck: { type: 'change', filter: (detail) => !detail.checked, args: () => [this] },
28
+ change: { type: 'change', args: (detail) => [detail.checked] }
29
+ },
30
+ setters: { on: (value) => value ? this.setChecked() : this.setUnchecked(), value: (value) => { component.options.value = value; } }
31
+ });
32
+ component.on('change', () => this._syncAct());
33
+ this._syncAct();
34
+ }
35
+
36
+ /** @returns {boolean} */
37
+ getState() { return this._zx.get(); }
38
+ /** @returns {unknown} */
39
+ getValue() { return this._zx.getValue(); }
40
+ /** @returns {this} */
41
+ toggle() { this._zx.toggle(); this._syncAct(); return this; }
42
+ /** @param {boolean} [suppress=false] @returns {this} */
43
+ setChecked(suppress = false) { this._zx.set(true, { silent: Boolean(suppress) }); this._syncAct(); return this; }
44
+ /** @param {boolean} [suppress=false] @returns {this} */
45
+ setUnchecked(suppress = false) { this._zx.set(false, { silent: Boolean(suppress) }); this._syncAct(); return this; }
46
+ /** @returns {void} */
47
+ _syncAct() { this._mirrorAct(this.toElement(), this.getState()); }
48
+ }
49
+
50
+ /** Legacy ZeyOS floating message box. */
51
+ export class Msgbox extends GxWrapper {
52
+ static legacyName = 'gx.zeyos.Msgbox';
53
+
54
+ /** @param {Record<string, any>} [options={}] */
55
+ constructor(options = {}) {
56
+ super(options, { closable: true, content: false });
57
+ const component = new ZxMessage(null, { timeout: 0, closable: options.closable !== false, maxVisible: 1 });
58
+ document.body.append(component.toElement());
59
+ this._handle = null;
60
+ this._content = options.content || '';
61
+ this._attach(component, { ui: { frame: 'root', content: 'root', img: 'root' } });
62
+ }
63
+
64
+ /** @param {unknown} content @returns {this} */
65
+ setContent(content) { this._content = legacyContent(content); return this; }
66
+ /** @param {unknown} [message] @param {string} [className='info'] @returns {this} */
67
+ show(message, className = 'info') {
68
+ if (message != null) this.setContent(message);
69
+ this._handle?.close();
70
+ this._handle = this._zx.show(this._content, { kind: messageKind(className), timeout: 0, closable: this.options.closable !== false });
71
+ this._mirrorAct(this.toElement(), true);
72
+ return this;
73
+ }
74
+ /** @returns {this} */
75
+ hide() { this._handle?.close(); this._handle = null; this._mirrorAct(this.toElement(), false); return this; }
76
+ }
77
+
78
+ /** Legacy bootstrap message/status service. */
79
+ export class BootstrapMessage extends GxWrapper {
80
+ static legacyName = 'gx.bootstrap.Message';
81
+
82
+ /** @param {Element|string|null} display @param {Record<string, any>} [options={}] */
83
+ constructor(display, options = {}) {
84
+ super(options, { duration: 3000 });
85
+ const component = new ZxMessage(targetElement(display), {
86
+ timeout: Number(options.duration) || 0, closable: true, maxVisible: options.maxVisible ?? 5
87
+ });
88
+ if (!targetElement(display)) document.body.append(component.toElement());
89
+ this._handles = new Map();
90
+ this._progress = null;
91
+ this._progressValue = 0;
92
+ this._attach(component, { ui: { windows: 'root', status: 'root' } });
93
+ }
94
+
95
+ /** @param {unknown} message @param {string} [iconClass='info'] @param {boolean} [closable=true] @param {boolean} [_blend=false] @param {boolean} [autoclose=true] @returns {Element} */
96
+ addMessage(message, iconClass = 'info', closable = true, _blend = false, autoclose = true) {
97
+ const marker = document.createElement('span');
98
+ marker.hidden = true;
99
+ const handle = this._zx.show(legacyContent(message), {
100
+ kind: messageKind(iconClass), closable: closable !== false,
101
+ timeout: autoclose === false ? 0 : Number(this.options.duration) || 0
102
+ });
103
+ this._handles.set(marker, handle);
104
+ return marker;
105
+ }
106
+ /** @param {Element} marker @returns {this} */
107
+ closeMessage(marker) { this._handles.get(marker)?.close(); this._handles.delete(marker); return this; }
108
+ /** @returns {this} */
109
+ clear() { for (const handle of this._handles.values()) handle.close(); this._handles.clear(); return this; }
110
+ /** @param {number} progress @param {string} [message=''] @param {boolean} [_blend=false] @returns {this} */
111
+ showStatus(progress, message = '', _blend = false) {
112
+ if (!this._progress) this._progress = ZxMessage.progress(String(message));
113
+ this._progressValue = Number(progress) || 0;
114
+ this._progress.update(this._progressValue, String(message));
115
+ return this;
116
+ }
117
+ /** @param {number} progress @param {string} [message] @returns {this} */
118
+ incProgress(progress, message) { return this.setProgress(this._progressValue + (Number(progress) || 0), message); }
119
+ /** @param {number} progress @param {string} [message] @param {unknown} [_tween] @returns {this} */
120
+ setProgress(progress, message, _tween) {
121
+ if (!this._progress) this._progress = ZxMessage.progress(String(message ?? ''));
122
+ this._progressValue = Number(progress) || 0;
123
+ this._progress.update(this._progressValue, message == null ? undefined : String(message));
124
+ return this;
125
+ }
126
+ /** @returns {this} */
127
+ hideStatus() { this._progress?.done(); this._progress = null; this._progressValue = 0; return this; }
128
+ }
129
+
130
+ /** Shared Dialog-backed popup behavior. */
131
+ class PopupBase extends GxWrapper {
132
+ /** @param {Record<string, any>} options */
133
+ constructor(options = {}) {
134
+ super(options, { width: 600, closable: true, content: null });
135
+ const component = new ZxDialog(null, {
136
+ title: String(options.title ?? ''), size: numericWidth(options.width),
137
+ closable: options.closable !== false,
138
+ lightDismiss: Boolean(options.overlayDismiss ?? options.clickable),
139
+ content: legacyContent(options.content)
140
+ });
141
+ this._attach(component, {
142
+ events: {
143
+ show: { type: 'open', args: () => [this] },
144
+ hide: { type: 'close', args: (detail) => [detail.result, this] },
145
+ open: { type: 'open', args: () => [this] }
146
+ },
147
+ ui: { modal: 'root', aside: 'content', body: 'content', content: 'content', title: 'title', footer: 'footer', cross: 'close' },
148
+ setters: { content: 'setContent', title: 'setTitle', open: (value) => value ? this.show() : this.hide() }
149
+ });
150
+ this.isOpen = false;
151
+ if (options.footer) component.setButtons(footerButtons(options.footer));
152
+ if (options.open) this.show();
153
+ }
154
+
155
+ /** @param {unknown} [argument] @returns {this} */
156
+ show(argument) { this.isOpen = true; this._showArgument = argument; this._zx.open(); return this; }
157
+ /** @param {unknown} [argument] @returns {this} */
158
+ hide(argument) { this.isOpen = false; this._zx.close(argument); return this; }
159
+ /** @param {unknown} content @returns {this} */
160
+ setContent(content) { this._zx.setContent(legacyContent(content)); return this; }
161
+ /** @param {string} title @returns {this} */
162
+ setTitle(title) { this._zx.setTitle(title); return this; }
163
+ /** @returns {Element} */
164
+ getContent() { return this._zx.refs.content; }
165
+ /** @param {unknown} [_x] @param {unknown} [_y] @returns {this} */
166
+ setPosition(_x, _y) { warnMethodOnce(this.constructor, 'setPosition', 'CSS dialog positioning'); return this; }
167
+ }
168
+
169
+ /** Legacy ZeyOS popup. */
170
+ export class Popup extends PopupBase {
171
+ static legacyName = 'gx.zeyos.Popup';
172
+ }
173
+
174
+ /** Legacy bootstrap popup. */
175
+ export class BootstrapPopup extends PopupBase {
176
+ static legacyName = 'gx.bootstrap.Popup';
177
+ }
178
+
179
+ /** Sentinel returned when a legacy confirmation is canceled. */
180
+ export const PopupConfirmCanceled = Object.freeze({});
181
+
182
+ /** @param {string} title @param {unknown} message @param {Record<string, any>|string} [options={}] @returns {Promise<void>} */
183
+ export function PopupAlert(title, message, options = {}) {
184
+ warnFunctionOnce(PopupAlert, 'gx.bootstrap.PopupAlert', 'Dialog.alert');
185
+ const settings = typeof options === 'string' ? { type: options } : options;
186
+ return new Promise((resolve) => {
187
+ const popup = new BootstrapPopup({ ...settings, title, content: message, width: settings.width ?? 400 });
188
+ popup._zx.setButtons([{ label: settings.okLabel ?? 'Ok', kind: 'primary', autofocus: true, action: () => {
189
+ if (typeof settings.onOk === 'function' && settings.onOk() === false) return;
190
+ popup.hide(); resolve();
191
+ } }]);
192
+ popup._zx.once('close', () => popup.destroy());
193
+ popup.show();
194
+ });
195
+ }
196
+
197
+ /** @param {string} title @param {unknown} message @param {Record<string, any>|string} [options={}] @returns {Promise<void|typeof PopupConfirmCanceled>} */
198
+ export function PopupConfirm(title, message, options = {}) {
199
+ warnFunctionOnce(PopupConfirm, 'gx.bootstrap.PopupConfirm', 'Dialog.confirm');
200
+ const settings = typeof options === 'string' ? { type: options } : options;
201
+ return new Promise((resolve) => {
202
+ const popup = new BootstrapPopup({ ...settings, title, content: message, width: settings.width ?? 400, closable: false });
203
+ popup._zx.setButtons([
204
+ { label: settings.cancelLabel ?? 'Cancel', action: () => { popup.hide(); resolve(PopupConfirmCanceled); } },
205
+ { label: settings.okLabel ?? 'Ok', kind: 'primary', action: () => {
206
+ if (typeof settings.onOk === 'function' && settings.onOk() === false) return;
207
+ popup.hide(); resolve();
208
+ } }
209
+ ]);
210
+ popup._zx.once('close', () => popup.destroy());
211
+ popup.show();
212
+ });
213
+ }
214
+
215
+ /** Legacy multi-frame ZeyOS dialog. */
216
+ export class Dialog extends GxWrapper {
217
+ static legacyName = 'gx.zeyos.Dialog';
218
+
219
+ /** @param {Element|string|null} _display @param {Record<string, any>} [options={}] */
220
+ constructor(_display, options = {}) {
221
+ super(options, { title: '', height: 400 });
222
+ const component = new ZxDialog(null, { title: String(options.title ?? ''), content: null });
223
+ this._frames = {};
224
+ this._current = null;
225
+ this._attach(component, { ui: { title: 'title', content: 'content', footer: 'footer' }, setters: { title: 'setTitle' } });
226
+ }
227
+
228
+ /** @param {string} title @returns {this} */
229
+ setTitle(title) { this._zx.setTitle(textLabel(title)); return this; }
230
+ /** @param {string} key @param {Record<string, any>} options @param {boolean} [open] @returns {this} */
231
+ addFrame(key, options, open) {
232
+ const buttons = footerButtons(options?.footer);
233
+ const view = this._zx.addView(String(key), {
234
+ title: options?.title == null ? undefined : textLabel(options.title),
235
+ content: legacyContent(options?.content), buttons
236
+ });
237
+ this._frames[key] = { title: options?.title ?? null, content: view.content, footer: buttons, view };
238
+ if ((!this._current && open !== false) || open === true) this.openFrame(key);
239
+ return this;
240
+ }
241
+ /** @param {string} key @returns {Record<string, any>} */
242
+ openFrame(key) { this._zx.showView(String(key)); this._current = this._frames[key]; return this._current; }
243
+ /** @param {string} key @returns {Record<string, any>|null} */
244
+ getFrame(key) { return this._frames[key] ?? null; }
245
+ /** @param {string} key @param {unknown} content @param {Function} onSubmit @param {boolean} [open] @returns {unknown} */
246
+ addSubmitFrame(key, content, onSubmit, open) {
247
+ this.addFrame(key, { title: this.options.title, content: containerFor(content), footer: {
248
+ close: { label: 'Close', click: () => this._zx.close() },
249
+ ok: { label: 'OK', primary: true, click: () => onSubmit?.() }
250
+ } }, open);
251
+ return content;
252
+ }
253
+ /** @param {string} key @param {Record<string, [unknown, unknown]>} form @param {Function} onSubmit @param {boolean} [open] @returns {Record<string, unknown>} */
254
+ addFormFrame(key, form, onSubmit, open) {
255
+ const fields = {};
256
+ const container = document.createElement('div');
257
+ for (const [name, definition] of Object.entries(form ?? {})) {
258
+ const label = document.createElement('p');
259
+ label.textContent = definition?.[0] == null ? '' : String(definition[0]);
260
+ container.append(label);
261
+ const field = definition?.[1];
262
+ const node = legacyContent(field);
263
+ if (node?.nodeType) container.append(node); else if (node?.toElement?.()) container.append(node.toElement());
264
+ fields[name] = field;
265
+ }
266
+ this.addSubmitFrame(key, container, onSubmit, open);
267
+ return fields;
268
+ }
269
+ /** @param {string} key @param {unknown} message @param {string} [link] @param {boolean} [open] @returns {this} */
270
+ addSuccessFrame(key, message, link, open) {
271
+ const container = containerFor(message);
272
+ if (link) {
273
+ const anchor = document.createElement('a'); anchor.href = link; anchor.textContent = 'Open'; container.append(anchor);
274
+ }
275
+ return this.addFrame(key, { title: this.options.title, content: container }, open);
276
+ }
277
+ /** @param {Record<string, any>} form @returns {Record<string, unknown>} */
278
+ getFormValues(form) {
279
+ const values = {};
280
+ for (const [key, field] of Object.entries(form ?? {})) {
281
+ if (field?.value != null) values[key] = field.value;
282
+ else if (typeof field?.getValue === 'function') values[key] = field.getValue();
283
+ else if (typeof field?.getValues === 'function') values[key] = field.getValues();
284
+ else if (typeof field?.getId === 'function') values[key] = field.getId();
285
+ else if (typeof field?.get === 'function') values[key] = field.get();
286
+ }
287
+ return values;
288
+ }
289
+ }
290
+
291
+ /** Legacy object-backed dropdown. */
292
+ export class Dropdown extends GxWrapper {
293
+ static legacyName = 'gx.zeyos.Dropdown';
294
+
295
+ /** @param {Element|string|null} display @param {Record<string, any>} [options={}] */
296
+ constructor(display, options = {}) {
297
+ super(options, { items: {}, label: '', resettable: false, compact: false, upside: false });
298
+ const { target, host } = buttonTarget(display);
299
+ this._items = normalizeDropdownItems(options.items, options.resettable, options.emptyCaption);
300
+ this._selected = null;
301
+ const component = new ZxMenuButton(target, {
302
+ label: String(options.label ?? ''), items: this._items,
303
+ placement: options.upside ? 'top-start' : 'bottom-start'
304
+ });
305
+ if (host) host.append(component.toElement());
306
+ this._attach(component, {
307
+ events: {
308
+ change: { type: 'select', args: (detail) => {
309
+ this._selected = detail.value == null ? null : detail.item;
310
+ component.setLabel(detail.value == null ? String(options.label ?? '') : String(detail.item.label));
311
+ return [detail.value, detail.item.label, this];
312
+ } }
313
+ },
314
+ ui: { frame: 'root', button: 'root', section: () => document.querySelector(`[aria-labelledby="${component.el.id}"]`) },
315
+ setters: { items: 'setItems' }
316
+ });
317
+ }
318
+ /** @param {Record<string, unknown>} items @returns {this} */
319
+ setItems(items) { this._items = normalizeDropdownItems(items, this.options.resettable, this.options.emptyCaption); this._zx.setItems(this._items); return this; }
320
+ /** @param {unknown} value @param {string} [text] @returns {this} */
321
+ selectItem(value, text) {
322
+ const item = this._items.find((entry) => entry !== '-' && entry.value == value);
323
+ this._selected = item ?? { value, label: text ?? String(value) };
324
+ this._zx.setLabel(text ?? this._selected.label); this.fireEvent('change', [value, text ?? this._selected.label, this]); this._zx.close(); return this;
325
+ }
326
+ /** @returns {this} */
327
+ reset() { this._selected = null; this._zx.setLabel(String(this.options.label ?? '')); this.fireEvent('change', [null, this.options.emptyCaption, this]); this._zx.close(); return this; }
328
+ /** @returns {{value: unknown, label: string}|null} */
329
+ getSelected() { return this._selected ? { value: this._selected.value, label: this._selected.label } : null; }
330
+ /** @returns {unknown} */
331
+ getValue() { return this._selected?.value ?? ''; }
332
+ /** @returns {this} */
333
+ show() { this._zx.open(); return this; }
334
+ /** @returns {this} */
335
+ close() { this._zx.close(); return this; }
336
+ /** @returns {this} */
337
+ toggle() { this._zx.isOpen() ? this._zx.close() : this._zx.open(); return this; }
338
+ }
339
+
340
+ /** Legacy bootstrap menu button. */
341
+ export class MenuButton extends GxWrapper {
342
+ static legacyName = 'gx.bootstrap.MenuButton';
343
+
344
+ /** @param {Element|string|null} display @param {Record<string, any>} [options={}] */
345
+ constructor(display, options = {}) {
346
+ super(options, { entries: [], label: '', orientation: 'left', direction: 'down' });
347
+ const { target, host } = buttonTarget(display);
348
+ this._entries = [];
349
+ const component = new ZxMenuButton(target, {
350
+ label: String(options.label ?? ''), items: [], kind: styleKind(options.style),
351
+ placement: `${options.direction === 'up' ? 'top' : 'bottom'}-${options.orientation === 'right' ? 'end' : 'start'}`
352
+ });
353
+ if (host) host.append(component.toElement());
354
+ this._attach(component, { events: { change: { type: 'select', args: (detail) => [detail.value, detail.item, this] } }, ui: { button: 'root', frame: 'root', menu: 'root' } });
355
+ for (const entry of options.entries ?? []) this.add(entry);
356
+ }
357
+ /** @param {string|false|null} label @param {string} [icon] @returns {Element|null} */
358
+ add(label, icon) {
359
+ if (!label) { this._entries.push('-'); this._zx.setItems(this._entries); return null; }
360
+ const item = { label: String(label), icon, value: this._entries.length };
361
+ this._entries.push(item); this._zx.setItems(this._entries);
362
+ return this.toElement();
363
+ }
364
+ /** @returns {this} */
365
+ divider() { this.add(false); return this; }
366
+ /** @returns {this} */
367
+ toggle() { this._zx.isOpen() ? this._zx.close() : this._zx.open(); return this; }
368
+ /** @returns {this} */
369
+ open() { this._zx.open(); return this; }
370
+ /** @returns {this} */
371
+ close() { this._zx.close(); return this; }
372
+ /** @param {string} label @returns {this} */
373
+ setLabel(label) { this._zx.setLabel(label); return this; }
374
+ /** @param {string} style @returns {this} */
375
+ setStyle(style) { this.toElement().setAttribute('data-kind', styleKind(style)); return this; }
376
+ }
377
+
378
+ /** Legacy bootstrap two-state check button. */
379
+ export class CheckButton extends GxWrapper {
380
+ static legacyName = 'gx.bootstrap.CheckButton';
381
+
382
+ /** @param {Element|string|null} display @param {Record<string, any>} [options={}] */
383
+ constructor(display, options = {}) {
384
+ super(options, { label: '', value: false });
385
+ const { target, host } = buttonTarget(display);
386
+ const component = new ZxCheckButton(target, { label: options.label, checked: Boolean(options.value), disabled: Boolean(options.disabled) });
387
+ if (host) host.append(component.toElement());
388
+ this._attach(component, {
389
+ events: {
390
+ change: { type: 'change', args: (detail) => [detail.checked] },
391
+ check: { type: 'change', filter: (detail) => detail.checked, args: () => [] },
392
+ uncheck: { type: 'change', filter: (detail) => !detail.checked, args: () => [] }
393
+ },
394
+ ui: { button: 'root', indicator: 'root', group: 'root' },
395
+ setters: { value: 'set', disabled: 'setDisabled', label: 'setLabel' }
396
+ });
397
+ }
398
+ /** @returns {boolean} */ get() { return this._zx.get(); }
399
+ /** @param {boolean} [suppress=false] @returns {false} */ toggle(suppress = false) { this._zx.set(!this.get(), { silent: Boolean(suppress) }); return false; }
400
+ /** @param {boolean} [suppress=false] @returns {this} */ check(suppress = false) { this._zx.set(true, { silent: Boolean(suppress) }); return this; }
401
+ /** @param {boolean} [suppress=false] @returns {this} */ uncheck(suppress = false) { this._zx.set(false, { silent: Boolean(suppress) }); return this; }
402
+ /** @param {boolean} value @returns {this} */ set(value) { return value ? this.check() : this.uncheck(); }
403
+ /** @param {boolean} disabled @returns {this} */ setDisabled(disabled) { disabled ? this._zx.disable() : this._zx.enable(); return this; }
404
+ /** @param {string|string[]} label @returns {this} */ setLabel(label) { this._zx.setLabel(label); return this; }
405
+ }
406
+
407
+ /** @param {Element|string|null|undefined} display @returns {{target: HTMLButtonElement|null, host: Element|null}} */
408
+ function buttonTarget(display) {
409
+ const element = targetElement(display);
410
+ if (element?.localName === 'button') return { target: element, host: null };
411
+ return { target: null, host: element };
412
+ }
413
+
414
+ /** @param {unknown} width @returns {'sm'|'md'|'lg'|number} */
415
+ function numericWidth(width) {
416
+ if (typeof width === 'number' && Number.isFinite(width)) return width;
417
+ const number = Number.parseFloat(String(width ?? ''));
418
+ return Number.isFinite(number) ? number : 'md';
419
+ }
420
+
421
+ /** @param {unknown} footer @returns {Array<Record<string, any>>} */
422
+ function footerButtons(footer) {
423
+ if (!footer) return [];
424
+ const entries = Array.isArray(footer) ? footer : (footer?.nodeType ? [footer] : Object.values(footer));
425
+ return entries.map((entry) => {
426
+ if (entry?.nodeType) return { label: entry.textContent ?? '', action: () => entry.click?.() };
427
+ return { label: String(entry?.label ?? ''), kind: entry?.primary ? 'primary' : 'default', action: () => entry?.click?.() };
428
+ });
429
+ }
430
+
431
+ /** @param {unknown} content @returns {HTMLElement} */
432
+ function containerFor(content) {
433
+ const container = document.createElement('div');
434
+ const values = Array.isArray(content) ? content : [content];
435
+ for (const value of values) {
436
+ const node = legacyContent(value);
437
+ if (node?.nodeType) container.append(node);
438
+ else if (node != null) container.append(document.createTextNode(String(node)));
439
+ }
440
+ return container;
441
+ }
442
+
443
+ /** @param {Record<string, unknown>} items @param {boolean} resettable @param {unknown} emptyCaption @returns {Array<Record<string, any>>} */
444
+ function normalizeDropdownItems(items = {}, resettable = false, emptyCaption = null) {
445
+ const list = [];
446
+ if (resettable) list.push({ label: String(emptyCaption ?? 'Empty'), value: null });
447
+ for (const [value, source] of Object.entries(items ?? {})) {
448
+ const object = source && typeof source === 'object' ? source : null;
449
+ list.push({
450
+ label: String(object?.text ?? object?.label ?? source), value,
451
+ onselect: typeof object?.onClick === 'function' ? object.onClick : undefined
452
+ });
453
+ }
454
+ return list;
455
+ }
456
+
457
+ /** @param {unknown} style @returns {'default'|'primary'|'danger'|'ghost'} */
458
+ function styleKind(style) {
459
+ const value = String(style ?? '').toLowerCase();
460
+ if (value.includes('danger') || value.includes('error')) return 'danger';
461
+ if (value.includes('primary') || value.includes('success')) return 'primary';
462
+ if (value.includes('link') || value.includes('ghost')) return 'ghost';
463
+ return 'default';
464
+ }