@zeyos/zx 2.3.0 → 4.0.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 (150) hide show
  1. package/CHANGELOG.md +138 -0
  2. package/DESIGN-SYSTEM.md +96 -0
  3. package/README.md +29 -39
  4. package/dist/types/components/account-menu/account-menu.d.ts +144 -0
  5. package/dist/types/components/app-sidebar/app-sidebar.d.ts +243 -0
  6. package/dist/types/components/avatar/avatar.d.ts +100 -0
  7. package/dist/types/components/card/card.d.ts +128 -0
  8. package/dist/types/components/chart/chart.d.ts +322 -0
  9. package/dist/types/components/date-picker/month-picker.d.ts +6 -0
  10. package/dist/types/components/dialog/dialog.d.ts +9 -0
  11. package/dist/types/components/dock/dock.d.ts +495 -0
  12. package/dist/types/components/dropdown/dropdown.d.ts +2 -2
  13. package/dist/types/components/field/field.d.ts +14 -0
  14. package/dist/types/components/field-upload/field-upload.d.ts +37 -4
  15. package/dist/types/components/form/form.d.ts +25 -3
  16. package/dist/types/components/grid/grid.d.ts +172 -0
  17. package/dist/types/components/launcher/launcher.d.ts +359 -0
  18. package/dist/types/components/layout/layout.d.ts +4 -4
  19. package/dist/types/components/menu-button/menu-button.d.ts +10 -2
  20. package/dist/types/components/modal/modal.d.ts +25 -0
  21. package/dist/types/components/multi-value-editor/multi-value-editor.d.ts +7 -1
  22. package/dist/types/components/questionnaire/items.d.ts +327 -0
  23. package/dist/types/components/questionnaire/questionnaire.d.ts +449 -0
  24. package/dist/types/components/select/select.d.ts +51 -0
  25. package/dist/types/components/sheet/sheet-stack.d.ts +167 -0
  26. package/dist/types/components/sheet/sheet.d.ts +294 -0
  27. package/dist/types/components/split-view/split-view.d.ts +2 -21
  28. package/dist/types/components/table/table.d.ts +223 -15
  29. package/dist/types/components/tooltip/tooltip.d.ts +2 -2
  30. package/dist/types/components/value-list/value-list.d.ts +24 -3
  31. package/dist/types/core/dom.d.ts +122 -0
  32. package/dist/types/core/drag-axis.d.ts +111 -0
  33. package/dist/types/core/position.d.ts +4 -2
  34. package/dist/types/index.d.ts +13 -2
  35. package/dist/types/internal/app-rail.d.ts +265 -0
  36. package/dist/types/zeyos/icons.d.ts +5 -0
  37. package/dist/types/zeyos/index.d.ts +2 -1
  38. package/dist/types/zeyos/launcher.d.ts +147 -0
  39. package/dist/types/zeyos/select.d.ts +39 -0
  40. package/dist/zx-zeyos.esm.js +1870 -133
  41. package/dist/zx-zeyos.esm.min.js +1 -1
  42. package/dist/zx.css +2006 -267
  43. package/dist/zx.esm.js +8987 -2757
  44. package/dist/zx.esm.min.js +3 -3
  45. package/dist/zx.global.js +8987 -2757
  46. package/dist/zx.global.min.js +3 -3
  47. package/dist/zx.min.css +1 -1
  48. package/docs/api.json +4396 -2344
  49. package/docs/llms.md +463 -86
  50. package/docs/llms.txt +32 -19
  51. package/package.json +10 -17
  52. package/src/components/account-menu/account-menu.css +70 -0
  53. package/src/components/account-menu/account-menu.js +208 -0
  54. package/src/components/app-rail/app-rail.css +107 -0
  55. package/src/components/app-sidebar/app-sidebar.css +80 -0
  56. package/src/components/app-sidebar/app-sidebar.js +588 -0
  57. package/src/components/avatar/avatar.css +61 -0
  58. package/src/components/avatar/avatar.js +222 -0
  59. package/src/components/button/button.css +0 -1
  60. package/src/components/card/card.css +149 -0
  61. package/src/components/card/card.js +285 -0
  62. package/src/components/chart/chart.css +61 -0
  63. package/src/components/chart/chart.js +523 -0
  64. package/src/components/date-picker/month-picker.js +9 -0
  65. package/src/components/dialog/dialog.js +11 -4
  66. package/src/components/dock/dock.css +228 -0
  67. package/src/components/dock/dock.js +977 -0
  68. package/src/components/dropdown/dropdown.js +1 -1
  69. package/src/components/field/field.js +2 -0
  70. package/src/components/field-upload/field-upload.js +9 -4
  71. package/src/components/form/form.js +6 -3
  72. package/src/components/grid/grid.css +6 -0
  73. package/src/components/grid/grid.js +220 -0
  74. package/src/components/launcher/launcher.css +210 -0
  75. package/src/components/launcher/launcher.js +765 -0
  76. package/src/components/layout/layout.js +2 -2
  77. package/src/components/menu-button/menu-button.js +27 -2
  78. package/src/components/modal/modal.css +5 -1
  79. package/src/components/modal/modal.js +37 -2
  80. package/src/components/multi-value-editor/multi-value-editor.js +2 -1
  81. package/src/components/questionnaire/items.js +370 -0
  82. package/src/components/questionnaire/questionnaire.css +387 -0
  83. package/src/components/questionnaire/questionnaire.js +1033 -0
  84. package/src/components/select/field-adapter.js +9 -4
  85. package/src/components/select/select.css +144 -11
  86. package/src/components/select/select.js +259 -27
  87. package/src/components/sheet/sheet-stack.js +304 -0
  88. package/src/components/sheet/sheet.css +351 -0
  89. package/src/components/sheet/sheet.js +551 -0
  90. package/src/components/split-view/split-view.js +76 -161
  91. package/src/components/table/table.css +43 -0
  92. package/src/components/table/table.js +531 -52
  93. package/src/components/tooltip/tooltip.js +5 -2
  94. package/src/components/value-list/value-list.js +6 -3
  95. package/src/core/dom.js +322 -0
  96. package/src/core/drag-axis.js +203 -0
  97. package/src/core/position.js +68 -22
  98. package/src/index.js +20 -2
  99. package/src/internal/app-rail.js +718 -0
  100. package/src/zeyos/icons.js +8 -3
  101. package/src/zeyos/index.js +7 -1
  102. package/src/zeyos/launcher.js +338 -0
  103. package/src/zeyos/modules.js +1 -0
  104. package/src/zeyos/select.js +115 -1
  105. package/styles/tokens/dark.css +2 -3
  106. package/styles/tokens/global.css +6 -6
  107. package/styles/tokens/modules.css +1 -0
  108. package/styles/tokens/semantic.css +5 -3
  109. package/styles/tokens/themes.css +1 -1
  110. package/styles/zx.css +11 -1
  111. package/MIGRATION.md +0 -598
  112. package/dist/types/compat/base.d.ts +0 -156
  113. package/dist/types/compat/globals.d.ts +0 -20
  114. package/dist/types/compat/index.d.ts +0 -128
  115. package/dist/types/compat/map/basic.d.ts +0 -175
  116. package/dist/types/compat/map/data.d.ts +0 -102
  117. package/dist/types/compat/map/date-time.d.ts +0 -80
  118. package/dist/types/compat/map/factory.d.ts +0 -9
  119. package/dist/types/compat/map/form.d.ts +0 -98
  120. package/dist/types/compat/map/helpers.d.ts +0 -12
  121. package/dist/types/compat/map/http.d.ts +0 -36
  122. package/dist/types/compat/map/layout.d.ts +0 -106
  123. package/dist/types/compat/map/options.d.ts +0 -80
  124. package/dist/types/compat/map/select.d.ts +0 -95
  125. package/dist/types/compat/map/stubs.d.ts +0 -32
  126. package/dist/types/compat/map/utilities.d.ts +0 -37
  127. package/dist/types/compat-entry.d.ts +0 -5
  128. package/dist/types/components/permission/permission.d.ts +0 -96
  129. package/dist/zx-compat.esm.js +0 -17484
  130. package/dist/zx-compat.esm.min.js +0 -1
  131. package/dist/zx-compat.global.js +0 -23635
  132. package/dist/zx-compat.global.min.js +0 -3
  133. package/src/compat/base.js +0 -291
  134. package/src/compat/globals.js +0 -165
  135. package/src/compat/index.js +0 -84
  136. package/src/compat/map/basic.js +0 -464
  137. package/src/compat/map/data.js +0 -232
  138. package/src/compat/map/date-time.js +0 -177
  139. package/src/compat/map/factory.js +0 -45
  140. package/src/compat/map/form.js +0 -330
  141. package/src/compat/map/helpers.js +0 -46
  142. package/src/compat/map/http.js +0 -117
  143. package/src/compat/map/layout.js +0 -256
  144. package/src/compat/map/options.js +0 -267
  145. package/src/compat/map/select.js +0 -198
  146. package/src/compat/map/stubs.js +0 -26
  147. package/src/compat/map/utilities.js +0 -113
  148. package/src/compat-entry.js +0 -11
  149. package/src/components/permission/permission.css +0 -47
  150. package/src/components/permission/permission.js +0 -201
@@ -1,330 +0,0 @@
1
- import {
2
- Field as ZxField,
3
- Fieldset as ZxFieldset,
4
- FieldUpload as ZxFieldUpload,
5
- Form as ZxForm,
6
- MultiValueEditor as ZxMultiValueEditor,
7
- ValueList as ZxValueList
8
- } from '../../index.js';
9
- import { GxWrapper } from '../base.js';
10
- import { legacyContent, targetElement, textLabel } from './helpers.js';
11
- import {
12
- translateChecklistOptions, translateDateboxFormat, translateFieldOptions, translateSelectOptions
13
- } from './options.js';
14
-
15
- /** Legacy bootstrap form. */
16
- export class Form extends GxWrapper {
17
- static legacyName = 'gx.bootstrap.Form';
18
-
19
- /** @param {Element|string|null} display @param {Record<string, any>} [options={}] */
20
- constructor(display, options = {}) {
21
- super(options, { fields: {}, horizontal: ['col-md-3', 'col-md-9'], columns: false });
22
- const component = new ZxForm(display, { fieldsets: [], actions: normalizeActions(options.actions) });
23
- this._fieldsets = [];
24
- this._attach(component, {
25
- events: {
26
- submit: { type: 'submit', args: (detail) => [detail.values, this] },
27
- change: { type: 'change', args: (detail) => [detail.id, detail.value, this] },
28
- invalid: { type: 'invalid', args: (detail) => [detail.errors, this] }
29
- },
30
- ui: { body: () => component._body, actions: () => component._actions }
31
- });
32
- if (options.fields && typeof options.fields === 'object') {
33
- this.addFieldset({ fields: options.fields, title: options.title, horizontal: options.horizontal, columns: options.columns });
34
- }
35
- }
36
-
37
- /** @param {Fieldset|Record<string, any>} fieldset @returns {Fieldset} */
38
- addFieldset(fieldset) {
39
- const wrapper = fieldset instanceof Fieldset ? fieldset : new Fieldset(null, {
40
- horizontal: this.options.horizontal, columns: this.options.columns, ...fieldset
41
- });
42
- this._fieldsets.push(wrapper);
43
- this._zx.addFieldset(wrapper._zx);
44
- return wrapper;
45
- }
46
- /** @param {unknown} content @returns {this} */
47
- addActions(content) {
48
- const actions = normalizeActions(content);
49
- if (actions.length) this._zx.setActions(actions);
50
- else {
51
- const values = Array.isArray(content) ? content : [content];
52
- for (const value of values) {
53
- const node = legacyContent(value);
54
- if (node?.nodeType === 1) this._zx._actions.prepend(node);
55
- }
56
- this._zx._actions.hidden = false;
57
- }
58
- return this;
59
- }
60
- /** @param {string} id @returns {unknown} */ getValue(id) { return this.getField(id)?.getValue() ?? null; }
61
- /** @returns {Record<string, unknown>} */ getValues() { return Object.assign({}, ...this._fieldsets.map((fieldset) => fieldset.getValues())); }
62
- /** @param {string} id @returns {Field|null} */ getField(id) { for (const fieldset of this._fieldsets) { const field = fieldset.getField(id); if (field) return field; } return null; }
63
- /** @returns {Fieldset[]} */ getFieldsets() { return this._fieldsets.slice(); }
64
- /** @param {string} id @param {unknown} value @returns {this} */ setValue(id, value) { this.getField(id)?.setValue(value); return this; }
65
- /** @param {Record<string, unknown>} values @returns {this} */ setValues(values) { for (const fieldset of this._fieldsets) fieldset.setValues(values); return this; }
66
- /** @param {Record<string, unknown>} [highlights={}] @param {string} [type='error'] @returns {number} */ setHighlights(highlights = {}, type = 'error') { return this._fieldsets.reduce((count, fieldset) => count + fieldset.setHighlights(highlights, type), 0); }
67
- /** @param {Record<string, unknown>} [highlights={}] @param {string} [type='error'] @returns {number} */ setHintHighlights(highlights = {}, type = 'error') { return this.setHighlights(highlights, type); }
68
- /** @returns {this} */ reset() { for (const fieldset of this._fieldsets) fieldset.reset().setHighlights(); return this; }
69
- }
70
-
71
- /** Legacy bootstrap fieldset. */
72
- export class Fieldset extends GxWrapper {
73
- static legacyName = 'gx.bootstrap.Fieldset';
74
-
75
- /** @param {Element|string|null} display @param {Record<string, any>} [options={}] */
76
- constructor(display, options = {}) {
77
- super(options, { fields: {}, title: null, columns: 1 });
78
- const columns = Number(options.columns) || 1;
79
- const component = new ZxFieldset(display, { title: options.title ?? '', columns: Math.max(1, Math.min(3, columns)), fields: {} });
80
- this._fields = {};
81
- this._attach(component, { ui: { columns: () => component._grid } });
82
- if (options.fields && typeof options.fields === 'object') this.addFields(options.fields);
83
- }
84
-
85
- /** @param {Record<string, any>} fields @returns {this} */ addFields(fields) { for (const [id, source] of Object.entries(fields ?? {})) this.addFieldItem(id, source); return this; }
86
- /** @param {string} id @param {unknown} field @returns {Field|unknown} */
87
- addFieldItem(id, field) {
88
- if (this.hasField(id)) throw new Error(`Field "${id}" already exists.`);
89
- let wrapper = field;
90
- if (!(field instanceof Field)) {
91
- if (field?.type != null) wrapper = new Field({ ...field, id });
92
- else if (field?.field != null) wrapper = new Field({ ...field, id, type: field.type ?? 'custom' });
93
- else if (field?.nodeType || field?._zx) wrapper = new Field({ id, label: id, type: 'custom', field });
94
- else wrapper = new Field({ ...(field ?? {}), id });
95
- }
96
- this._fields[id] = wrapper;
97
- this._zx.addField(id, wrapper instanceof Field ? wrapper._zx : wrapper?._zx ?? wrapper);
98
- return wrapper;
99
- }
100
- /** @param {string} id @param {string|Function|Element} type @param {Record<string, any>} [options={}] @returns {Field} */
101
- addField(id, type, options = {}) { return /** @type {Field} */ (this.addFieldItem(id, new Field({ ...options, id, type }))); }
102
- /** @returns {this} */ clear() { this._zx.clear(); this._fields = {}; return this; }
103
- /** @param {string} id @returns {boolean} */ hasField(id) { return Object.hasOwn(this._fields, id); }
104
- /** @param {string} id @returns {Field|null} */ getField(id) { return this._fields[id] ?? null; }
105
- /** @returns {Record<string, Field>} */ getFields() { return { ...this._fields }; }
106
- /** @param {string} id @returns {unknown} */ getValue(id) { return this._fields[id]?.getValue?.() ?? null; }
107
- /** @returns {Record<string, unknown>} */ getValues() { const values = {}; for (const [id, field] of Object.entries(this._fields)) if (!id.startsWith('__')) values[id] = field.getValue?.(); return values; }
108
- /** @param {string} id @param {unknown} value @returns {this} */ setValue(id, value) { this._fields[id]?.setValue?.(value); return this; }
109
- /** @param {Record<string, unknown>} values @returns {this} */ setValues(values) { for (const [id, value] of Object.entries(values ?? {})) this.setValue(id, value); return this; }
110
- /** @returns {this} */ reset() { for (const field of Object.values(this._fields)) field.reset?.(); return this; }
111
- /** @param {string} id @returns {this} */ focus(id) { this._fields[id]?.focus?.(); return this; }
112
- /** @param {Record<string, unknown>} [highlights={}] @param {string} [type='error'] @returns {number} */
113
- setHighlights(highlights = {}, type = 'error') {
114
- let count = 0;
115
- for (const [id, field] of Object.entries(this._fields)) {
116
- const highlight = highlights?.[id];
117
- if (highlight && typeof highlight === 'object') { field.setHighlight(highlight.label, highlight.type ?? type); count += 1; }
118
- else if (highlight) { field.setHighlight(highlight, type); count += 1; }
119
- else field.setHighlight();
120
- }
121
- return count;
122
- }
123
- /** @param {Record<string, unknown>} [highlights={}] @param {string} [type='error'] @returns {number} */ setHintHighlights(highlights = {}, type = 'error') { return this.setHighlights(highlights, type); }
124
- }
125
-
126
- /** Legacy bootstrap single field. */
127
- export class Field extends GxWrapper {
128
- static legacyName = 'gx.bootstrap.Field';
129
-
130
- /** @param {Record<string, any>} [options={}] */
131
- constructor(options = {}) {
132
- super(options, { label: '', type: 'text', description: '', default: null });
133
- const translated = translateLegacyField(options);
134
- const component = new ZxField(null, translated);
135
- this._type = translated.type;
136
- this._attach(component, {
137
- events: { setValue: { type: 'change', args: (detail) => [detail.value] }, change: { type: 'change', args: (detail) => [detail.value] } },
138
- ui: {
139
- label: () => component.el.querySelector('.zx-field__label'),
140
- field: () => component.getInput(),
141
- controlwrapper: () => component.el.querySelector('.zx-field__control'),
142
- highlight: () => component.el.querySelector('.zx-field__highlight'),
143
- description: () => component.el.querySelector('.zx-field__description'),
144
- hint: () => component.el.querySelector('.zx-field__control')
145
- },
146
- setters: { value: 'setValue', default: 'setValue', disabled: 'setDisabled' }
147
- });
148
- }
149
- /** @param {string} label @returns {this} */ setLabel(label) { const element = this.display('label'); if (element) element.textContent = textLabel(label); return this; }
150
- /** @param {string} help @returns {this} */ setHelp(help) { const element = this.display('description'); if (element) element.textContent = String(help ?? ''); return this; }
151
- /** @returns {unknown} */ getValue() { return this._zx.getValue(); }
152
- /** @param {unknown} value @returns {this} */ setValue(value) { this._zx.setValue(value); return this; }
153
- /** @param {boolean} disabled @returns {this} */ setDisabled(disabled) { this._zx.setDisabled(disabled); return this; }
154
- /** @param {unknown} label @param {string} [type='warning'] @returns {this} */
155
- setHighlight(label, type = 'warning') { if (!label) this._zx.clearHighlight(); else this._zx.setHighlight(String(label), highlightKind(type)); return this; }
156
- /** @param {unknown} label @param {string} [type='warning'] @returns {this} */ setHintHighlight(label, type = 'warning') { return this.setHighlight(label, type); }
157
- /** @returns {this} */ reset() { this._zx.reset(); return this; }
158
- /** @returns {this} */ focus() { this._zx.focus(); return this; }
159
- }
160
-
161
- /** Legacy bootstrap chip list. */
162
- export class ValueList extends GxWrapper {
163
- static legacyName = 'gx.bootstrap.ValueList';
164
-
165
- /** @param {Element|string|null} display @param {Record<string, any>} [options={}] */
166
- constructor(display, options = {}) {
167
- super(options, { deletable: true });
168
- const component = new ZxValueList(display, { values: options.values ?? options.default ?? [], deletable: options.deletable !== false });
169
- this._attach(component, { events: { change: { type: 'change', args: (detail) => [detail.values] }, click: { type: 'add', args: (detail) => [detail.value] } }, ui: { textbox: () => component._input, list: () => component._list } });
170
- }
171
- /** @param {unknown} value @returns {boolean} */ addValue(value) { return this._zx.addValue(value); }
172
- /** @returns {unknown[]} */ getValues() { return this._zx.getValues(); }
173
- /** @param {unknown[]} values @returns {this} */ setValues(values) { this._zx.setValues(values ?? []); return this; }
174
- /** @returns {this} */ enable() { this._zx.enable(); return this; }
175
- /** @returns {this} */ disable() { this._zx.disable(); return this; }
176
- /** @returns {this} */ focus() { this._zx.focus(); return this; }
177
- }
178
-
179
- /** Legacy JSON-string multi-value editor. */
180
- export class MultiValueEditor extends GxWrapper {
181
- static legacyName = 'gx.bootstrap.MultiValueEditor';
182
-
183
- /** @param {Element|string|null} display @param {Record<string, any>} [options={}] */
184
- constructor(display, options = {}) {
185
- super(options, { options: false, default: false });
186
- const values = parseValues(options.default || options.values || options.options);
187
- const component = new ZxMultiValueEditor(display, { values, options: null });
188
- this._attach(component, { events: { change: { type: 'change', args: (detail) => [JSON.stringify(detail.values)] } }, ui: { optionsbox: () => component._rows, btnAdd: () => component._add } });
189
- }
190
- /** @returns {string} */ getValue() { return JSON.stringify(this._zx.getValues()); }
191
- /** @param {string|unknown[]} value @returns {this} */ setValue(value) { this._zx.setValues(parseValues(value)); return this; }
192
- }
193
-
194
- /** Legacy bootstrap upload field. */
195
- export class FieldUpload extends GxWrapper {
196
- static legacyName = 'gx.bootstrap.FieldUpload';
197
-
198
- /** @param {Record<string, any>} [options={}] */
199
- constructor(options = {}) {
200
- super(options, { inputname: 'upload', uploadurl: './index.php', params: {}, imageurl: '' });
201
- const component = new ZxFieldUpload(null, {
202
- url: options.uploadurl ?? options.url ?? './index.php', paramName: options.inputname ?? options.paramName ?? 'upload',
203
- params: options.params ?? {}, accept: options.accept ?? null, multiple: Boolean(options.multiple),
204
- autoUpload: options.autoUpload !== false, http: options.http ?? null
205
- });
206
- this._value = null;
207
- this._attach(component, {
208
- events: {
209
- success: { type: 'success', args: (detail) => { this._handleResponse(detail.response); return [detail.response]; } },
210
- failure: { type: 'error', args: (detail) => { options.showError?.(this, detail.error); return [detail.error]; } },
211
- progress: { type: 'progress', args: (detail) => [detail.percent] }
212
- },
213
- ui: { select: () => component._input, placeholder: () => component._preview, progress: () => component._progress }
214
- });
215
- if (options.default) this.setValue(options.default);
216
- if (options.disabled) this.setDisabled(true);
217
- }
218
- /** @param {unknown} source @returns {this} */ setValue(source) { this._value = source; this.setImage(source); return this; }
219
- /** @returns {null} */ getValue() { return null; }
220
- /** @param {unknown} source @returns {this} */
221
- setImage(source) { this._zx._preview.replaceChildren(); if (source) { const image = document.createElement('img'); image.src = String(this.options.imageurl ?? '') + String(source); image.alt = ''; this._zx._preview.append(image); } return this; }
222
- /** @param {boolean} disabled @returns {this} */ setDisabled(disabled) { this._zx.setDisabled(disabled); return this; }
223
- /** @returns {this} */ reset() { this._zx.clear(); return this; }
224
- /** @param {unknown} response @returns {void} */
225
- _handleResponse(response) {
226
- if (typeof this.options.parseResponse === 'function') this.options.parseResponse(this, response, (value) => { if (value != null) this.setValue(value); });
227
- }
228
- }
229
-
230
- /** @param {Record<string, any>} options @returns {Record<string, any>} */
231
- function translateLegacyField(options) {
232
- const translated = translateFieldOptions(options);
233
- const nested = options.options && typeof options.options === 'object' && !Array.isArray(options.options) ? options.options : {};
234
- if (options.field != null || (typeof options.type !== 'string' && options.type != null)) {
235
- const source = options.field ?? options.type;
236
- const instance = typeof source === 'function' ? new source(null, Object.keys(nested).length ? nested : options) : source;
237
- translated.type = 'custom';
238
- translated.adapter = () => externalAdapter(instance);
239
- return translated;
240
- }
241
- if (translated.type === 'zxselect') {
242
- translated.props = translateSelectOptions({ ...nested, ...options });
243
- translated.props.items = Array.isArray(options.data) ? options.data : (nested.data ?? []);
244
- translated.props.valueKey = options.elementIndex ?? nested.elementIndex ?? 'ID';
245
- translated.props.labelKey = options.elementLabel ?? nested.elementLabel ?? 'name';
246
- } else if (translated.type === 'checklist') {
247
- translated.props = translateChecklistOptions(Object.keys(nested).length ? nested : options);
248
- translated.props.items = nested.data ?? options.data ?? [];
249
- } else if (translated.type === 'date' || translated.type === 'datetime') {
250
- const source = Object.keys(nested).length ? nested : options;
251
- translated.props = { format: translateDateboxFormat(source.format ?? '%d.%m.%Y'), time: translated.type === 'datetime' };
252
- translated.value = normalizeFormDate(translated.value ?? source.date);
253
- } else if (translated.type === 'month') {
254
- translated.props = { ...nested };
255
- translated.value = normalizeFormDate(translated.value ?? nested.date ?? options.date);
256
- } else if (translated.type === 'time') {
257
- const source = Object.keys(nested).length ? nested : options;
258
- translated.props = { unit: source.unit ?? 'minutes', seconds: source.seconds !== false, signed: Boolean(source.prefix) };
259
- translated.value = translated.value ?? source.time ?? 0;
260
- } else if (translated.type === 'html') {
261
- translated.value = legacyContent(options.content ?? translated.value);
262
- }
263
- return translated;
264
- }
265
-
266
- /** @param {unknown} source @returns {import('../../components/field/field.js').FieldAdapter} */
267
- function externalAdapter(source) {
268
- const element = source?._zx?.toElement?.() ?? source?.toElement?.() ?? source;
269
- if (!element?.nodeType) throw new TypeError('Custom legacy field must provide a DOM element');
270
- return {
271
- el: element,
272
- get: () => source?.getValue?.() ?? source?.getValues?.() ?? source?.get?.() ?? ('value' in element ? element.value : null),
273
- set: (value) => {
274
- if (typeof source?.setValue === 'function') source.setValue(value);
275
- else if (typeof source?.setValues === 'function') source.setValues(value);
276
- else if (typeof source?.set === 'function') source.set(value);
277
- else if ('value' in element) element.value = value == null ? '' : String(value);
278
- },
279
- focus: () => source?.focus?.() ?? element.focus?.(),
280
- setDisabled: (disabled) => {
281
- if (typeof source?.setDisabled === 'function') source.setDisabled(disabled);
282
- else if (disabled) source?.disable?.(); else source?.enable?.();
283
- if ('disabled' in element) element.disabled = disabled;
284
- }
285
- };
286
- }
287
-
288
- /** @param {unknown} actions @returns {Array<Record<string, any>>} */
289
- function normalizeActions(actions) {
290
- const list = Array.isArray(actions) ? actions : (actions && typeof actions === 'object' && !actions.nodeType ? Object.values(actions) : []);
291
- return list.filter((action) => action && typeof action === 'object' && !action.nodeType && !action.tag).map((action, index) => ({
292
- id: action.id ?? String(index), label: action.label ?? action.text ?? '', icon: action.icon ?? null,
293
- kind: actionKind(action.kind ?? action.type ?? (action.primary ? 'primary' : 'default')),
294
- type: action.submit ? 'submit' : (action.type === 'reset' ? 'reset' : 'button'),
295
- onClick: action.onClick ?? action.onclick ?? action.click
296
- }));
297
- }
298
-
299
- /** @param {unknown} type @returns {'danger'|'warning'|'success'|'default'} */
300
- function highlightKind(type) {
301
- const value = String(type ?? '').toLowerCase();
302
- if (value === 'error' || value === 'danger') return 'danger';
303
- if (value === 'success' || value === 'primary') return 'success';
304
- if (value === 'warning') return 'warning';
305
- return 'default';
306
- }
307
-
308
- /** @param {unknown} kind @returns {'default'|'primary'|'danger'|'ghost'} */
309
- function actionKind(kind) {
310
- const value = String(kind ?? '').toLowerCase();
311
- if (value === 'error' || value === 'danger') return 'danger';
312
- if (value === 'primary' || value === 'success') return 'primary';
313
- if (value === 'ghost' || value === 'link') return 'ghost';
314
- return 'default';
315
- }
316
-
317
- /** @param {unknown} value @returns {unknown[]} */
318
- function parseValues(value) {
319
- if (Array.isArray(value)) return value;
320
- if (!value) return [];
321
- try { const parsed = JSON.parse(String(value)); return Array.isArray(parsed) ? parsed : []; } catch { return []; }
322
- }
323
-
324
- /** @param {unknown} value @returns {unknown} */
325
- function normalizeFormDate(value) {
326
- if (value instanceof Date || value == null) return value;
327
- if (typeof value === 'number') return new Date(value * (Math.abs(value) < 1e12 ? 1000 : 1));
328
- const date = new Date(String(value));
329
- return Number.isNaN(date.getTime()) ? null : date;
330
- }
@@ -1,46 +0,0 @@
1
- import { parse } from '../globals.js';
2
-
3
- /** @param {Element|string|null|undefined} target @returns {Element|null} */
4
- export function targetElement(target) {
5
- if (target == null) return null;
6
- if (typeof target === 'string') return document.querySelector(target);
7
- return target?.nodeType === 1 ? target : null;
8
- }
9
-
10
- /** @param {unknown} value @returns {unknown} */
11
- export function legacyContent(value) {
12
- if (value == null || typeof value === 'string' || typeof value === 'number') return value;
13
- if (value?.nodeType || typeof value?.toElement === 'function' || typeof value === 'function') return value;
14
- return parse(value) || String(value);
15
- }
16
-
17
- /** @param {unknown} value @returns {'info'|'success'|'warning'|'error'} */
18
- export function messageKind(value) {
19
- const name = String(value ?? '').toLowerCase().replace(/^s_msg_32_/, '').replace(/^icon-/, '');
20
- if (name.includes('error') || name.includes('danger') || name.includes('remove')) return 'error';
21
- if (name.includes('success') || name.includes('ok') || name.includes('check')) return 'success';
22
- if (name.includes('warn')) return 'warning';
23
- return 'info';
24
- }
25
-
26
- /** @param {Function} fn @param {string} legacyName @param {string} replacement @returns {void} */
27
- export function warnFunctionOnce(fn, legacyName, replacement) {
28
- if (Object.hasOwn(fn, '_compatWarned')) return;
29
- Object.defineProperty(fn, '_compatWarned', { value: true });
30
- console.warn(`${legacyName} is running on the Zx compat layer — migrate to zx.${replacement}`);
31
- }
32
-
33
- /** @param {Function} owner @param {string} method @param {string} replacement @returns {void} */
34
- export function warnMethodOnce(owner, method, replacement) {
35
- const key = `_compatMethod_${method}`;
36
- if (Object.hasOwn(owner, key)) return;
37
- Object.defineProperty(owner, key, { value: true });
38
- console.warn(`${owner.legacyName}.${method} has no direct Zx equivalent; use ${replacement}`);
39
- }
40
-
41
- /** @param {unknown} value @returns {string} */
42
- export function textLabel(value) {
43
- if (value == null) return '';
44
- if (typeof value === 'string' || typeof value === 'number') return String(value);
45
- return String(value.label ?? value.title ?? value.text ?? value.name ?? value.value ?? '');
46
- }
@@ -1,117 +0,0 @@
1
- import { Http, zeyosService } from '../../index.js';
2
- import { GxWrapper } from '../base.js';
3
-
4
- /** Legacy generic HTTP client. */
5
- export class Client extends GxWrapper {
6
- static legacyName = 'gx.zeyos.Client';
7
-
8
- /** @param {Record<string, any>} [options={}] */
9
- constructor(options = {}) {
10
- super(options, { url: './remotecall.php' });
11
- this._http = new Http({ base: String(options.url ?? './remotecall.php'), headers: options.headers ?? {}, timeout: options.timeout ?? 30000 });
12
- }
13
- /** @param {string} path @param {unknown} data @param {Function|Record<string, Function>} [callback] @param {string} [resulttype] @returns {Promise<unknown>} */
14
- post(path, data, callback, resulttype) { return this.request(data, 'POST', callback, resulttype, path); }
15
- /** @param {string} path @param {unknown} data @param {Function|Record<string, Function>} [callback] @param {string} [resulttype] @returns {Promise<unknown>} */
16
- get(path, data, callback, resulttype) { return this.request(data, 'GET', callback, resulttype, path); }
17
- /** @param {unknown} data @param {string} [method='GET'] @param {Function|Record<string, Function>} [callback] @param {string} [resulttype] @param {string} [path=''] @returns {Promise<unknown>} */
18
- async request(data, method = 'GET', callback, resulttype, path = '') {
19
- registerCallbackEvents(this, callback);
20
- this.fireEvent('request');
21
- try {
22
- const normalizedMethod = String(method).toUpperCase();
23
- const result = await this._http.request(String(path ?? ''), normalizedMethod === 'GET'
24
- ? { method: normalizedMethod, query: data }
25
- : { method: normalizedMethod, data });
26
- if (resulttype && legacyType(result) !== resulttype) throw new TypeError(`Invalid server response: expected ${resulttype}`);
27
- if (typeof callback === 'function') callback.call(this, result);
28
- this.fireEvent('success', [result]);
29
- return result;
30
- } catch (error) {
31
- this.fireEvent('failure', [error]);
32
- throw error;
33
- } finally {
34
- this.fireEvent('complete');
35
- }
36
- }
37
- }
38
-
39
- /** Legacy ZeyOS REST request client. */
40
- export class Request extends GxWrapper {
41
- static legacyName = 'gx.zeyos.Request';
42
-
43
- /** @param {Record<string, any>} [options={}] */
44
- constructor(options = {}) {
45
- super(options, { service: false, accesskey: false });
46
- this._files = null;
47
- this.setService(options.service ?? '', options.accesskey ?? '');
48
- if (typeof options.showError === 'function') this.showError = options.showError;
49
- }
50
- /** @param {string} service @param {string} [accesskey=''] @returns {this} */
51
- setService(service, accesskey = '') {
52
- this.options.service = service;
53
- this.options.accesskey = accesskey;
54
- this.baseUrl = `${this.options.apiBase ?? '../remotecall/'}${service}${accesskey ? `:${accesskey}` : ''}/`;
55
- this._http = zeyosService(String(service), String(accesskey), {
56
- apiBase: this.options.apiBase ?? '../remotecall/', headers: this.options.headers ?? {}, timeout: this.options.timeout ?? 30000
57
- });
58
- return this;
59
- }
60
- /** @param {string} path @param {unknown} data @param {Function} [callback] @param {string} [method='GET'] @returns {Promise<unknown>} */
61
- async send(path, data, callback, method = 'GET') {
62
- this.fireEvent('request');
63
- try {
64
- const verb = String(method ?? 'GET').toUpperCase();
65
- const request = { method: verb };
66
- if (verb === 'GET') request.query = data;
67
- else request.data = data;
68
- if (this._files) request.files = this._files;
69
- const result = await this._http.request(String(path ?? ''), request);
70
- this._files = null;
71
- this.fireEvent('success', [result]);
72
- callback?.call(this, result, '200 OK');
73
- return result;
74
- } catch (caught) {
75
- this._files = null;
76
- const error = caught instanceof Error ? caught : new Error(String(caught));
77
- this.fireEvent('failure', [error]);
78
- this.fireEvent('error', [error.message, error.response ?? null, error.response?.headers ?? null]);
79
- this.fireEvent('exception', [error, null]);
80
- this.showError?.(error.message);
81
- throw error;
82
- } finally {
83
- this.fireEvent('complete');
84
- }
85
- }
86
- /** @param {string} path @param {unknown} data @param {Function} [callback] @returns {Promise<unknown>} */ post(path, data, callback) { return this.send(path, data, callback, 'POST'); }
87
- /** @param {string} path @param {unknown} data @param {Function} [callback] @returns {Promise<unknown>} */ get(path, data, callback) { return this.send(path, data, callback, 'GET'); }
88
- /** @param {string} path @param {unknown} data @param {Function} [callback] @returns {Promise<unknown>} */ put(path, data, callback) { return this.send(path, data, callback, 'PUT'); }
89
- /** @param {string} path @param {unknown} data @param {Function} [callback] @returns {Promise<unknown>} */ delete(path, data, callback) { return this.send(path, data, callback, 'DELETE'); }
90
- /** @param {string} path @param {unknown} data @param {File[]|FileList|Element[]} files @param {Function} [callback] @returns {Promise<unknown>} */
91
- upload(path, data, files, callback) { this._files = normalizeFiles(files); return this.send(path, data, callback, 'POST'); }
92
- /** @param {string} path @returns {Window|null} */ openLink(path) { return window.open(this.baseUrl + String(path ?? ''), '_blank'); }
93
- /** @param {string} error @returns {void} */ showError(error) { console.error(error); }
94
- }
95
-
96
- /** @param {GxWrapper} wrapper @param {Function|Record<string, Function>|undefined} callbacks @returns {void} */
97
- function registerCallbackEvents(wrapper, callbacks) {
98
- if (!callbacks || typeof callbacks !== 'object') return;
99
- for (const [type, callback] of Object.entries(callbacks)) wrapper.addEvent(type, callback);
100
- }
101
-
102
- /** @param {unknown} value @returns {string} */
103
- function legacyType(value) {
104
- if (Array.isArray(value)) return 'array';
105
- if (value === null) return 'null';
106
- return typeof value === 'object' ? 'object' : typeof value;
107
- }
108
-
109
- /** @param {File[]|FileList|Element[]|unknown} files @returns {File[]} */
110
- function normalizeFiles(files) {
111
- const values = files == null ? [] : Array.from(files);
112
- return values.flatMap((value) => {
113
- if (typeof File !== 'undefined' && value instanceof File) return [value];
114
- if (value?.files) return Array.from(value.files);
115
- return [];
116
- });
117
- }