domma-js 0.56.0 → 0.58.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 (121) hide show
  1. package/README.md +2 -2
  2. package/assets/types/generated/public/assets/flags/africa.d.ts +6 -0
  3. package/assets/types/generated/public/assets/flags/americas.d.ts +6 -0
  4. package/assets/types/generated/public/assets/flags/asia.d.ts +6 -0
  5. package/assets/types/generated/public/assets/flags/europe.d.ts +9 -0
  6. package/assets/types/generated/public/assets/flags/index.d.ts +11 -0
  7. package/assets/types/generated/public/assets/flags/oceania.d.ts +2 -0
  8. package/assets/types/generated/public/assets/icons/buildings.d.ts +6 -0
  9. package/assets/types/generated/public/assets/icons/code.d.ts +2 -0
  10. package/assets/types/generated/public/assets/icons/commerce.d.ts +7 -0
  11. package/assets/types/generated/public/assets/icons/communication.d.ts +7 -0
  12. package/assets/types/generated/public/assets/icons/devices.d.ts +6 -0
  13. package/assets/types/generated/public/assets/icons/emojis.d.ts +6 -0
  14. package/assets/types/generated/public/assets/icons/files.d.ts +7 -0
  15. package/assets/types/generated/public/assets/icons/finance.d.ts +6 -0
  16. package/assets/types/generated/public/assets/icons/forms.d.ts +5 -0
  17. package/assets/types/generated/public/assets/icons/health.d.ts +6 -0
  18. package/assets/types/generated/public/assets/icons/index.d.ts +24 -0
  19. package/assets/types/generated/public/assets/icons/media.d.ts +7 -0
  20. package/assets/types/generated/public/assets/icons/navigation.d.ts +7 -0
  21. package/assets/types/generated/public/assets/icons/seasonal.d.ts +6 -0
  22. package/assets/types/generated/public/assets/icons/social.d.ts +7 -0
  23. package/assets/types/generated/public/assets/icons/sport.d.ts +6 -0
  24. package/assets/types/generated/public/assets/icons/status.d.ts +7 -0
  25. package/assets/types/generated/public/assets/icons/transport.d.ts +7 -0
  26. package/assets/types/generated/public/assets/icons/ui.d.ts +7 -0
  27. package/assets/types/generated/public/assets/icons/weather.d.ts +6 -0
  28. package/assets/types/generated/src/auth.d.ts +424 -0
  29. package/assets/types/generated/src/avatar.d.ts +270 -0
  30. package/assets/types/generated/src/binding-source.d.ts +58 -0
  31. package/assets/types/generated/src/butterfly-drawing.d.ts +2 -0
  32. package/assets/types/generated/src/component-factory.d.ts +150 -0
  33. package/assets/types/generated/src/component.d.ts +162 -0
  34. package/assets/types/generated/src/components/back-to-top.d.ts +150 -0
  35. package/assets/types/generated/src/components/badge.d.ts +208 -0
  36. package/assets/types/generated/src/components/card.d.ts +189 -0
  37. package/assets/types/generated/src/components/command-palette.d.ts +352 -0
  38. package/assets/types/generated/src/components/dropzone.d.ts +342 -0
  39. package/assets/types/generated/src/components/focus-trap.d.ts +238 -0
  40. package/assets/types/generated/src/components/loader.d.ts +133 -0
  41. package/assets/types/generated/src/components/modal.d.ts +339 -0
  42. package/assets/types/generated/src/components/range-slider.d.ts +267 -0
  43. package/assets/types/generated/src/components/shared.d.ts +91 -0
  44. package/assets/types/generated/src/components/split-pane.d.ts +239 -0
  45. package/assets/types/generated/src/components/toast.d.ts +284 -0
  46. package/assets/types/generated/src/components/tooltip.d.ts +200 -0
  47. package/assets/types/generated/src/components/virtual-list.d.ts +340 -0
  48. package/assets/types/generated/src/config.d.ts +193 -0
  49. package/assets/types/generated/src/context-cursor.d.ts +69 -0
  50. package/assets/types/generated/src/context-menu.d.ts +596 -0
  51. package/assets/types/generated/src/dates.d.ts +367 -0
  52. package/assets/types/generated/src/dom.d.ts +1221 -0
  53. package/assets/types/generated/src/effects.d.ts +1281 -0
  54. package/assets/types/generated/src/elements.d.ts +4994 -0
  55. package/assets/types/generated/src/escape.d.ts +5 -0
  56. package/assets/types/generated/src/flags-bundle.d.ts +4 -0
  57. package/assets/types/generated/src/flags.d.ts +338 -0
  58. package/assets/types/generated/src/forms.d.ts +1060 -0
  59. package/assets/types/generated/src/globals.d.ts +45 -0
  60. package/assets/types/generated/src/http.d.ts +131 -0
  61. package/assets/types/generated/src/i18n.d.ts +261 -0
  62. package/assets/types/generated/src/icons.d.ts +213 -0
  63. package/assets/types/generated/src/index.d.ts +249 -0
  64. package/assets/types/generated/src/input-group.d.ts +135 -0
  65. package/assets/types/generated/src/models.d.ts +968 -0
  66. package/assets/types/generated/src/popover.d.ts +413 -0
  67. package/assets/types/generated/src/router.d.ts +344 -0
  68. package/assets/types/generated/src/safe-url.d.ts +10 -0
  69. package/assets/types/generated/src/sanitize.d.ts +97 -0
  70. package/assets/types/generated/src/schema-builder.d.ts +420 -0
  71. package/assets/types/generated/src/skeleton.d.ts +135 -0
  72. package/assets/types/generated/src/smooth-caret.d.ts +61 -0
  73. package/assets/types/generated/src/sortable.d.ts +368 -0
  74. package/assets/types/generated/src/storage.d.ts +93 -0
  75. package/assets/types/generated/src/tables.d.ts +901 -0
  76. package/assets/types/generated/src/theme.d.ts +262 -0
  77. package/assets/types/generated/src/ticker-tape-drawing.d.ts +2 -0
  78. package/assets/types/generated/src/treeview.d.ts +504 -0
  79. package/assets/types/generated/src/utils.d.ts +1667 -0
  80. package/assets/types/generated/src/web-components/base/domma-element.d.ts +134 -0
  81. package/assets/types/generated/src/web-components/index.d.ts +14 -0
  82. package/assets/types/generated/vendor/domma-reactive.d.ts +587 -0
  83. package/assets/types/index.d.ts +104 -226
  84. package/package.json +5 -2
  85. package/public/dist/bundles/domma-complete.css +20 -14
  86. package/public/dist/bundles/domma-data-focused.css +20 -14
  87. package/public/dist/bundles/domma-essentials.css +20 -14
  88. package/public/dist/bundles/domma-full.css +20 -14
  89. package/public/dist/bundles/domma-minimal.css +8 -8
  90. package/public/dist/domma-flags.esm.js +3 -3
  91. package/public/dist/domma-flags.esm.js.map +1 -1
  92. package/public/dist/domma-flags.min.js +3 -3
  93. package/public/dist/domma-flags.min.js.map +1 -1
  94. package/public/dist/domma-syntax.min.js +3 -3
  95. package/public/dist/domma.css +3 -3
  96. package/public/dist/domma.esm.js +5 -5
  97. package/public/dist/domma.esm.js.map +1 -1
  98. package/public/dist/domma.min.js +5 -5
  99. package/public/dist/domma.min.js.map +1 -1
  100. package/public/dist/elements.css +9 -3
  101. package/public/dist/grid.css +3 -3
  102. package/public/dist/syntax.css +3 -3
  103. package/public/dist/themes/domma-themes.css +3 -3
  104. package/templates/kickstart/.claude/snippets.md +1 -1
  105. package/templates/kickstart/CLAUDE.md +1 -1
  106. package/templates/kickstart/frontend/types/domma.d.ts +7 -4
  107. package/templates/kickstart-spa/.claude/snippets.md +1 -1
  108. package/assets/types/config.d.ts +0 -136
  109. package/assets/types/dates.d.ts +0 -209
  110. package/assets/types/dom.d.ts +0 -448
  111. package/assets/types/elements.d.ts +0 -1168
  112. package/assets/types/flags.d.ts +0 -130
  113. package/assets/types/http.d.ts +0 -97
  114. package/assets/types/i18n.d.ts +0 -99
  115. package/assets/types/icons.d.ts +0 -147
  116. package/assets/types/models.d.ts +0 -260
  117. package/assets/types/smooth-caret.d.ts +0 -12
  118. package/assets/types/storage.d.ts +0 -93
  119. package/assets/types/tables.d.ts +0 -327
  120. package/assets/types/theme.d.ts +0 -137
  121. package/assets/types/utils.d.ts +0 -675
@@ -0,0 +1,1060 @@
1
+ /**
2
+ * Field types a form can render. Anything not listed renders as a text input.
3
+ * `boolean`/`checkbox` are one checkbox; `select`/`radio`/`checkbox-group`/`multiselect`/`chooser` take `options`;
4
+ * `slider` is an E.rangeSlider (as is `range` with `formConfig.slider`); `dropzone` is an E.dropzone (value: File[]);
5
+ * `signature` is an E.signature pad (value: base64 PNG).
6
+ * @typedef {'string'|'email'|'password'|'number'|'integer'|'float'|'boolean'|'checkbox'|'date'|'datetime'|'time'|'url'|'tel'|'color'|'range'|'file'|'hidden'|'signature'|'select'|'multiselect'|'textarea'|'radio'|'checkbox-group'|'chooser'|'slider'|'dropzone'|(string & {})} FormFieldType
7
+ */
8
+ /**
9
+ * A choice for select / radio / checkbox-group / multiselect / chooser fields. A plain string is both the
10
+ * value and (capitalised) the label. Chooser options also read icon, description, badge, tooltip, etc.
11
+ * @typedef {string|{value: any, label: string, [key: string]: any}} FormOption
12
+ */
13
+ /**
14
+ * An input-group addon for `formConfig.prefix` / `formConfig.suffix`: `{icon}` draws a Domma icon,
15
+ * `{text}` escaped text, `{html}` raw HTML (the caller's responsibility); a string is shorthand for `{text}`.
16
+ * @typedef {string|{icon: string}|{text: string|number}|{html: string}} FormAddon
17
+ */
18
+ /**
19
+ * How a field is presented (`fieldDef.formConfig`). Slider fields pass range/ticks/tickLabels/labels/format/
20
+ * tooltip/marks/minDistance/orientation/rtl/names/ariaLabels/className to E.rangeSlider; dropzone fields pass
21
+ * accept/multiple/maxFiles/maxSize/minSize/previews/upload/autoUpload/retry/labels/list/className to E.dropzone.
22
+ * @typedef {object} FormFieldConfig
23
+ * @property {string} [placeholder]
24
+ * @property {string} [hint] - Small text beside the label; also the message when `pattern` fails
25
+ * @property {string} [helperText] - Text under the control (HTML)
26
+ * @property {string} [tooltip] - Tooltip on the label (a slider field also passes it to E.rangeSlider)
27
+ * @property {number} [span] - Columns the field spans in a grid layout
28
+ * @property {boolean} [disabled]
29
+ * @property {number} [rows] - textarea rows (default 3)
30
+ * @property {number|'any'} [step] - Used when the field definition has no `step`
31
+ * @property {string} [autocomplete]
32
+ * @property {FormAddon} [prefix]
33
+ * @property {FormAddon} [suffix]
34
+ * @property {boolean} [reveal] - password: show / hide toggle
35
+ * @property {boolean} [clear] - text-like inputs and textareas: a clear button
36
+ * @property {boolean} [stepper] - number / integer / float: - and + buttons
37
+ * @property {boolean|number} [counter] - text-like inputs and textareas: a character counter; true reads `maxLength`
38
+ * @property {Record<string, string>|((value: number, where: 'tick'|'mark'|'tooltip'|'aria') => string)} [labels] - Text for the input extras or the dropzone; a slider's value formatter
39
+ * @property {string|string[]} [accept] - file / dropzone
40
+ * @property {boolean} [multiple] - file / dropzone (a dropzone allows several unless false)
41
+ * @property {boolean} [slider] - Render a `range` field as E.rangeSlider
42
+ * @property {boolean} [range] - slider: two thumbs, value [low, high]
43
+ * @property {import('./components/range-slider.js').RangeSliderOptions['ticks']} [ticks]
44
+ * @property {boolean} [tickLabels]
45
+ * @property {import('./components/range-slider.js').RangeSliderOptions['format']} [format]
46
+ * @property {import('./components/range-slider.js').RangeSliderOptions['marks']} [marks]
47
+ * @property {number} [minDistance]
48
+ * @property {'horizontal'|'vertical'} [orientation]
49
+ * @property {boolean|null} [rtl]
50
+ * @property {[string, string]|null} [names]
51
+ * @property {[string, string]|null} [ariaLabels]
52
+ * @property {string} [className]
53
+ * @property {number|null} [maxFiles]
54
+ * @property {number|null} [maxSize] - Bytes
55
+ * @property {number|null} [minSize] - Bytes
56
+ * @property {boolean} [previews]
57
+ * @property {import('./components/dropzone.js').DropzoneOptions['upload']} [upload]
58
+ * @property {boolean} [autoUpload]
59
+ * @property {number} [retry]
60
+ * @property {boolean|string|HTMLElement} [list]
61
+ */
62
+ /**
63
+ * One field of a form blueprint. The same object also feeds `M.create` (the form builds its model from the
64
+ * blueprint), so model keys such as `default`, `required` and `validate` apply to both.
65
+ * @typedef {object} FormFieldDefinition
66
+ * @property {FormFieldType} [type] - default 'string'
67
+ * @property {string} [label] - default: the capitalised field name
68
+ * @property {any} [default]
69
+ * @property {boolean} [required]
70
+ * @property {boolean} [readonly] - Renders the control disabled
71
+ * @property {number} [min]
72
+ * @property {number} [max]
73
+ * @property {number|'any'} [step]
74
+ * @property {number} [minLength]
75
+ * @property {number} [maxLength]
76
+ * @property {RegExp} [pattern]
77
+ * @property {(value: any, data: Record<string, any>) => boolean|string} [validate] - true passes; a string (or anything else) fails with that message
78
+ * @property {FormOption[]} [options] - Choices for select / radio / checkbox-group / multiselect / chooser
79
+ * @property {FormFieldConfig} [formConfig]
80
+ * @property {(value: any, row: Record<string, any>, index: number) => string} [tableRender] - `F.crud` table cell renderer
81
+ * @property {'card'|'chip'} [variant] - chooser (default 'card')
82
+ * @property {boolean} [multiple] - chooser: several choices (value is an array)
83
+ * @property {'comfortable'|'compact'} [density] - chooser
84
+ * @property {number} [columns] - chooser (default 3)
85
+ * @property {string} [accent] - chooser: semantic name or CSS colour (default 'primary')
86
+ * @property {'border'|'solid'|'glow'|'overlay'|'underline'} [accentStyle] - chooser
87
+ * @property {boolean} [glow] - chooser
88
+ * @property {string|null} [glowColour] - chooser
89
+ * @property {string} [shadow] - chooser (default 'none')
90
+ * @property {string|null} [shadowColour] - chooser
91
+ */
92
+ /**
93
+ * A form blueprint: field name -> definition. Fields render in key order unless `options.sections` says otherwise.
94
+ * @typedef {{[field: string]: FormFieldDefinition}} FormBlueprint
95
+ */
96
+ /**
97
+ * A group of fields (`options.sections`); with a title it is a fieldset with a legend.
98
+ * @typedef {object} FormSection
99
+ * @property {string} [title]
100
+ * @property {string[]} [fields] - Blueprint keys, in order
101
+ * @property {'grid'|'stacked'} [layout]
102
+ * @property {number} [columns] - grid columns (default 2)
103
+ */
104
+ /**
105
+ * @typedef {object} FormOptions
106
+ * @property {'stacked'|'grid'|'inline'} [layout] - default 'stacked'
107
+ * @property {2|3|number} [columns] - grid layout columns (2 or 3, default 2)
108
+ * @property {'top'|'left'|'floating'} [labelPosition] - default 'top'
109
+ * @property {boolean} [showLabels] - default true
110
+ * @property {boolean} [showHelperText] - default true
111
+ * @property {boolean} [showHints] - default true
112
+ * @property {'blur'|'change'|'submit'} [validationMode] - default 'blur'
113
+ * @property {'domma'|'bootstrap'|'tailwind'} [cssFramework] - default 'domma'
114
+ * @property {string} [className] - default 'domma-form'
115
+ * @property {string} [fieldClassName] - default 'domma-form-field'
116
+ * @property {string} [labelClassName] - default 'form-label'
117
+ * @property {string} [inputClassName] - default 'form-input'
118
+ * @property {string} [errorClassName] - default 'form-error'
119
+ * @property {string} [helperClassName] - default 'form-helper-text'
120
+ * @property {string} [hintClassName] - default 'form-hint'
121
+ * @property {boolean} [cardWrapper] - Wrap the form in a card (default false)
122
+ * @property {FormSection[]} [sections]
123
+ * @property {boolean} [showSubmitButton] - default true
124
+ * @property {string} [submitText] - default 'Submit'
125
+ * @property {string} [resetText] - Adds a reset button with this text
126
+ * @property {'left'|'center'|'right'} [buttonAlignment] - default 'right'
127
+ * @property {(data: Record<string, any>, form: FormInstance) => void} [onSubmit] - A valid submit
128
+ * @property {(errors: Record<string, string>, form: FormInstance) => void} [onValidationError] - An invalid submit
129
+ * @property {string} [persist] - Passed to the model: a storage key to keep the values under
130
+ * @property {boolean} [autoSave] - Passed to the model
131
+ */
132
+ /**
133
+ * What `handleSubmit()` returns.
134
+ * @typedef {object} FormSubmitResult
135
+ * @property {boolean} isValid
136
+ * @property {Record<string, any>} data
137
+ * @property {Record<string, string>} errors - field name -> message
138
+ */
139
+ /**
140
+ * One step of `F.wizard`.
141
+ * @typedef {object} FormWizardStep
142
+ * @property {string} [title] - default 'Step <n>'
143
+ * @property {string} [description]
144
+ * @property {FormBlueprint} fields - The step's blueprint
145
+ * @property {'stacked'|'grid'|'inline'} [layout]
146
+ */
147
+ /**
148
+ * `F.wizard` options; the rest are FormOptions applied to every step.
149
+ * @typedef {FormOptions & {
150
+ * schema: {steps: FormWizardStep[]},
151
+ * data?: Record<string, any>,
152
+ * prevText?: string,
153
+ * nextText?: string,
154
+ * finishText?: string,
155
+ * onStepChange?: (stepIndex: number, data: Record<string, any>) => void,
156
+ * onValidation?: (isValid: boolean, errors: Record<string, string>, stepIndex: number) => void,
157
+ * onSubmit?: (data: Record<string, any>, form: FormInstance) => void|Promise<void>,
158
+ * onError?: (error: any, data: Record<string, any>, form: FormInstance) => void
159
+ * }} FormWizardOptions
160
+ */
161
+ /**
162
+ * The control object `F.wizard` returns.
163
+ * @typedef {object} FormWizard
164
+ * @property {() => void} nextStep
165
+ * @property {() => void} prevStep
166
+ * @property {(stepIndex: number) => void} goToStep
167
+ * @property {() => number} getCurrentStep - 0-based
168
+ * @property {() => Record<string, any>} getStepData - The values gathered so far (a copy)
169
+ * @property {(data: Record<string, any>) => void} setStepData - Merge values in and re-render the step
170
+ * @property {() => boolean} validate - Validate the current step
171
+ * @property {() => HTMLElement|null} getElement
172
+ * @property {() => void} destroy - Tear down the current step's controls and remove the wizard
173
+ */
174
+ /**
175
+ * `F.modal` options; the rest are FormOptions (`onSubmit` and `showSubmitButton` are set by the modal).
176
+ * @typedef {FormOptions & {
177
+ * title?: string,
178
+ * saveText?: string,
179
+ * closeOnSave?: boolean,
180
+ * size?: string,
181
+ * onSave?: (data: Record<string, any>, form: FormInstance) => void|Promise<void>,
182
+ * onError?: (error: any, data: Record<string, any>, form: FormInstance) => void
183
+ * }} FormModalOptions
184
+ */
185
+ /**
186
+ * The control object `F.modal` returns. `close()` removes the modal from the page.
187
+ * @typedef {object} FormModal
188
+ * @property {() => void} open
189
+ * @property {() => void} close
190
+ * @property {() => boolean} isOpen
191
+ */
192
+ /**
193
+ * `F.crud` configuration.
194
+ * @typedef {object} FormCrudConfig
195
+ * @property {FormBlueprint} schema
196
+ * @property {string} endpoint - REST endpoint (GET list, POST create, PUT/DELETE `<endpoint>/<id>`); responses are `{success, data, message}`
197
+ * @property {string|HTMLElement} [tableSelector] - Where the table goes
198
+ * @property {string} [title] - default 'Manage Items'
199
+ * @property {string} [primaryKey] - default 'id'
200
+ * @property {string} [displayField] - default 'name'
201
+ * @property {Record<string, string>} [headers]
202
+ * @property {(error: any) => void} [onError]
203
+ * @property {(message: string) => void} [onSuccess]
204
+ */
205
+ /**
206
+ * The object `F.crud` returns. Call `init()` to load the data and build the table.
207
+ * @typedef {object} FormCrud
208
+ * @property {() => Promise<void>} init
209
+ * @property {() => Promise<void>} loadData
210
+ * @property {() => void} createTable
211
+ * @property {() => void} initializeTableIcons
212
+ * @property {() => void} bindEvents
213
+ * @property {() => Promise<void>} create - Open the create modal
214
+ * @property {(id: string|number) => Promise<void>} edit - Open the edit modal for an item
215
+ * @property {(id: string|number) => Promise<void>} delete - Confirm, then delete an item
216
+ * @property {() => Promise<void>} refresh
217
+ * @property {() => Record<string, any>[]} getData
218
+ * @property {() => import('./tables.js').TableInstance|null} getTable
219
+ * @property {(item: Record<string, any>) => void} addItem
220
+ * @property {(id: string|number, updates: Record<string, any>) => void} updateItem
221
+ * @property {(id: string|number) => void} removeItem
222
+ */
223
+ /** @typedef {Forma} FormInstance */
224
+ /**
225
+ * Forma Class - Generates forms from Model schemas
226
+ */
227
+ export class Forma {
228
+ static defaults: {
229
+ layout: string;
230
+ columns: number;
231
+ labelPosition: string;
232
+ showLabels: boolean;
233
+ showHelperText: boolean;
234
+ showHints: boolean;
235
+ validationMode: string;
236
+ cssFramework: string;
237
+ className: string;
238
+ fieldClassName: string;
239
+ labelClassName: string;
240
+ inputClassName: string;
241
+ errorClassName: string;
242
+ helperClassName: string;
243
+ hintClassName: string;
244
+ cardWrapper: boolean;
245
+ };
246
+ static inputTypes: {
247
+ string: string;
248
+ email: string;
249
+ password: string;
250
+ number: string;
251
+ integer: string;
252
+ float: string;
253
+ boolean: string;
254
+ date: string;
255
+ datetime: string;
256
+ time: string;
257
+ url: string;
258
+ tel: string;
259
+ color: string;
260
+ range: string;
261
+ file: string;
262
+ hidden: string;
263
+ signature: string;
264
+ };
265
+ /**
266
+ * @param {FormBlueprint} schema
267
+ * @param {Record<string, any>} [data] - Initial values
268
+ * @param {FormOptions} [options]
269
+ */
270
+ constructor(schema: FormBlueprint, data?: Record<string, any>, options?: FormOptions);
271
+ /** @type {FormBlueprint} */
272
+ schema: FormBlueprint;
273
+ /** @type {Record<string, any>} */
274
+ data: Record<string, any>;
275
+ /** @private */
276
+ private _startData;
277
+ /** @type {FormOptions} */
278
+ options: FormOptions;
279
+ /** @type {import('./models.js').Model|null} The model built from the blueprint */
280
+ model: import("./models.js").Model | null;
281
+ /** @type {Record<string, string>} field name -> error message */
282
+ errors: Record<string, string>;
283
+ /** @type {Set<string>} Fields that have lost focus at least once */
284
+ touched: Set<string>;
285
+ /** @type {typeof utils} */
286
+ utils: typeof utils;
287
+ /** @type {typeof models} */
288
+ models: typeof models;
289
+ /**
290
+ * Generate form HTML
291
+ * @returns {string}
292
+ */
293
+ render(): string;
294
+ /**
295
+ * Render form into DOM element
296
+ * @param {string|HTMLElement} selector - Container (its content is replaced)
297
+ * @returns {HTMLElement} The container
298
+ */
299
+ renderTo(selector: string | HTMLElement): HTMLElement;
300
+ /** @type {HTMLFormElement|null} The rendered <form> */
301
+ formElement: HTMLFormElement | null;
302
+ /**
303
+ * Build the complete form structure
304
+ * @private
305
+ */
306
+ private _buildForm;
307
+ /**
308
+ * Build a form section
309
+ * @private
310
+ */
311
+ private _buildSection;
312
+ /**
313
+ * Build individual field
314
+ * @private
315
+ */
316
+ private _buildField;
317
+ /**
318
+ * Builds an HTML input element based on the provided field definition and options.
319
+ *
320
+ * @param {string} fieldName - The name of the field, used as the 'name' attribute for the input.
321
+ * @param {Object} fieldDef - The field definition containing configuration details such as min, max, pattern, etc.
322
+ * @param {Object} inputOptions - Options to customize the input element including type, value, required, disabled, placeholder, etc.
323
+ *
324
+ * @return {string} A string representing the HTML input element with appropriate attributes and content based on the specified type.
325
+ * @private
326
+ */
327
+ private _buildInput;
328
+ /**
329
+ * The interactive extras a field asks for through formConfig, reduced to
330
+ * those its type can take, or null:
331
+ * reveal: true password - show / hide toggle
332
+ * clear: true single-line text-like inputs and textareas
333
+ * stepper: true number / integer / float - the - and + buttons
334
+ * counter: true | n text-like inputs and textareas; true reads the
335
+ * field's maxLength
336
+ *
337
+ * @param {string} type
338
+ * @param {Object} fieldDef
339
+ * @return {Object|null}
340
+ * @private
341
+ */
342
+ private _inputExtras;
343
+ /**
344
+ * Joins formConfig.prefix / formConfig.suffix addons to a control's markup.
345
+ * Used for single-line inputs, selects and textareas; a control with neither
346
+ * is returned untouched.
347
+ *
348
+ * @param {string} controlHtml
349
+ * @param {Object} formConfig
350
+ * @return {string}
351
+ * @private
352
+ */
353
+ private _wrapAddons;
354
+ /**
355
+ * Builds an input-group addon (prefix or suffix) for decoration inside a form input.
356
+ *
357
+ * Accepts a slot descriptor object from formConfig.prefix / formConfig.suffix:
358
+ * { icon: 'search' } → renders a Domma icon
359
+ * { text: '$' } → renders escaped plain text (currency, units, etc.)
360
+ * { html: '<kbd>K</kbd>' } → renders raw HTML (caller takes responsibility)
361
+ * '£' → shorthand for { text: '£' }
362
+ *
363
+ * @param {Object|undefined} slot The prefix/suffix descriptor, or falsy to skip.
364
+ * @param {'left'|'right'} side Which side the addon renders on.
365
+ * @return {string} The addon HTML, or '' if no addon should be rendered.
366
+ * @private
367
+ */
368
+ private _buildAddon;
369
+ /**
370
+ * Constructs the HTML select element based on field definition and current value.
371
+ *
372
+ * @param fieldName
373
+ * @param {Object} fieldDef - The field definition containing options, required status, and other attributes.
374
+ * @param attrs
375
+ * @param currentValue
376
+ * @return {string} A string representing the generated HTML `<select>` element with appropriate options.
377
+ * @private
378
+ */
379
+ private _buildSelect;
380
+ /**
381
+ * Constructs the HTML structure for a radio group based on provided field definitions and attributes.
382
+ *
383
+ * @return {string} A string containing the generated HTML markup for the radio group with proper styling classes.
384
+ * @param fieldName
385
+ * @param fieldDef
386
+ * @param attrs
387
+ * @param currentValue
388
+ * @private
389
+ */
390
+ private _buildRadioGroup;
391
+ /**
392
+ * Build checkbox group
393
+ * @private
394
+ */
395
+ private _buildCheckboxGroup;
396
+ /**
397
+ * Build a placeholder element for a chooser field. The element is
398
+ * hydrated post-render by `_initChooserFields`, which instantiates
399
+ * `Domma.elements.chooser()` inside it. The configuration is round-tripped
400
+ * via a dataset attribute (JSON, attribute-quoted) so the form pipeline
401
+ * stays string-based until hydration time.
402
+ *
403
+ * @param {string} fieldName blueprint key
404
+ * @param {Object} fieldDef blueprint definition
405
+ * @param {Object} attrs attribute object built by _buildField
406
+ * @param {*} currentValue current model value (string or array)
407
+ * @returns {string} HTML string
408
+ * @private
409
+ */
410
+ private _buildChooser;
411
+ /**
412
+ * Bind events to form
413
+ * @param {HTMLElement} formElement
414
+ * @returns {void}
415
+ */
416
+ _bindEvents(formElement: HTMLElement): void;
417
+ /**
418
+ * The current value of a field from the model, the data, or its default.
419
+ * @private
420
+ */
421
+ private _initialValue;
422
+ /** Store a value a component reported, as the chooser fields do. @private */
423
+ private _storeFieldValue;
424
+ /**
425
+ * Turn every `[data-slider-field]` input into an E.rangeSlider. Slider options come from
426
+ * the field definition (min / max / step) and formConfig (range, ticks, tickLabels,
427
+ * labels, tooltip, marks, minDistance, orientation, rtl, names). With `range: true` the
428
+ * value is [low, high].
429
+ * @param {HTMLElement} formElement
430
+ * @private
431
+ */
432
+ private _initSliderFields;
433
+ /**
434
+ * Turn every `[data-dropzone-field]` placeholder into an E.dropzone over its file input.
435
+ * formConfig passes accept, multiple, maxFiles, maxSize, minSize, previews, upload,
436
+ * autoUpload, retry and labels through. The value is the array of File objects.
437
+ * @param {HTMLElement} formElement
438
+ * @private
439
+ */
440
+ private _initDropzoneFields;
441
+ /** @private */
442
+ private _destroyFieldControls;
443
+ /**
444
+ * Bind E.inputGroup to every control that carries `data-input-extras`,
445
+ * reusing the addon group _wrapAddons may already have written. Instances
446
+ * live on `this._inputGroups` keyed by field name; a re-render or
447
+ * destroy() tears the previous ones down.
448
+ *
449
+ * @param {HTMLElement} formElement
450
+ * @private
451
+ */
452
+ private _initInputExtras;
453
+ /** @private */
454
+ private _destroyInputExtras;
455
+ _inputGroups: {};
456
+ /**
457
+ * Put every field back to the value the form started with (its data, else the schema
458
+ * default): the model, the native inputs, and the slider / dropzone / chooser controls.
459
+ * A `[data-action="reset"]` button inside the form calls it.
460
+ * @returns {this}
461
+ */
462
+ reset(): this;
463
+ /**
464
+ * Remove the listeners and controls the form's input extras added.
465
+ * @returns {void}
466
+ */
467
+ destroy(): void;
468
+ /**
469
+ * Locate every `[data-chooser-field]` placeholder in the rendered form
470
+ * and instantiate `Domma.elements.chooser()` inside it. Stores each
471
+ * control instance on `this._choosers` keyed by field name so
472
+ * `_getFieldValueByName` and `validateField` can read its current value.
473
+ *
474
+ * @param {HTMLElement} formElement
475
+ * @private
476
+ */
477
+ private _initChooserFields;
478
+ _choosers: {};
479
+ /**
480
+ * Initialise any signature fields inside a rendered form.
481
+ * @param {HTMLElement} formElement
482
+ * @private
483
+ */
484
+ private _initSignatureFields;
485
+ /**
486
+ * Initialize tooltips on form labels
487
+ * @private
488
+ */
489
+ private _initTooltips;
490
+ /**
491
+ * Get form data
492
+ * @returns {Record<string, any>}
493
+ */
494
+ getData(): Record<string, any>;
495
+ /**
496
+ * Set form data (merged into the current values)
497
+ * @param {Record<string, any>} data
498
+ * @returns {void}
499
+ */
500
+ setData(data: Record<string, any>): void;
501
+ /**
502
+ * Validate entire form
503
+ * @returns {boolean}
504
+ */
505
+ validate(): boolean;
506
+ /**
507
+ * Validate single field
508
+ * @param {string} fieldName
509
+ * @returns {boolean}
510
+ */
511
+ validateField(fieldName: string): boolean;
512
+ /**
513
+ * Set field error
514
+ * @param {string} fieldName
515
+ * @param {string} message
516
+ * @returns {void}
517
+ */
518
+ setFieldError(fieldName: string, message: string): void;
519
+ /**
520
+ * Clear field error
521
+ * @param {string} fieldName
522
+ * @returns {void}
523
+ */
524
+ clearFieldError(fieldName: string): void;
525
+ /**
526
+ * Handle form submission: validate, then call `onSubmit` or `onValidationError`.
527
+ * @returns {FormSubmitResult}
528
+ */
529
+ handleSubmit(): FormSubmitResult;
530
+ /**
531
+ * Get value from form field element
532
+ * @private
533
+ */
534
+ private _getFieldValue;
535
+ /**
536
+ * Get field value by field name
537
+ * @param {string} fieldName
538
+ * @returns {any}
539
+ */
540
+ _getFieldValueByName(fieldName: string): any;
541
+ /**
542
+ * Validate field value against schema definition
543
+ * @private
544
+ */
545
+ private _validateFieldValue;
546
+ }
547
+ export namespace forms {
548
+ /**
549
+ * Create a new form builder instance (call `renderTo()` to put it on the page)
550
+ * @param {FormBlueprint} schema
551
+ * @param {Record<string, any>} [data] - Initial values
552
+ * @param {FormOptions} [options]
553
+ * @returns {FormInstance}
554
+ */
555
+ function create(schema: FormBlueprint, data?: Record<string, any>, options?: FormOptions): FormInstance;
556
+ /**
557
+ * Render form into element
558
+ * @param {string|HTMLElement} selector - Container (its content is replaced)
559
+ * @param {FormBlueprint} schema
560
+ * @param {Record<string, any>} [data] - Initial values
561
+ * @param {FormOptions} [options]
562
+ * @returns {HTMLElement} The container
563
+ */
564
+ function render(selector: string | HTMLElement, schema: FormBlueprint, data?: Record<string, any>, options?: FormOptions): HTMLElement;
565
+ /**
566
+ * Create wizard form (multi-step form)
567
+ * @param {string|HTMLElement} selector - Container
568
+ * @param {FormWizardOptions} options
569
+ * @returns {FormWizard}
570
+ */
571
+ function wizard(selector: string | HTMLElement, options?: FormWizardOptions): FormWizard;
572
+ /**
573
+ * Create modal form (integration with existing modal system). The modal is added to the page
574
+ * at once, hidden; call `open()`.
575
+ * @param {FormBlueprint} schema
576
+ * @param {Record<string, any>} [data] - Initial values
577
+ * @param {FormModalOptions} [options]
578
+ * @returns {FormModal}
579
+ */
580
+ function modal(schema: FormBlueprint, data?: Record<string, any>, options?: FormModalOptions): FormModal;
581
+ /**
582
+ * CRUD Helper - Complete Create, Read, Update, Delete functionality
583
+ * @param {FormCrudConfig} config
584
+ * @returns {FormCrud}
585
+ */
586
+ function crud(config: FormCrudConfig): FormCrud;
587
+ }
588
+ /**
589
+ * Field types a form can render. Anything not listed renders as a text input.
590
+ * `boolean`/`checkbox` are one checkbox; `select`/`radio`/`checkbox-group`/`multiselect`/`chooser` take `options`;
591
+ * `slider` is an E.rangeSlider (as is `range` with `formConfig.slider`); `dropzone` is an E.dropzone (value: File[]);
592
+ * `signature` is an E.signature pad (value: base64 PNG).
593
+ */
594
+ export type FormFieldType = "string" | "email" | "password" | "number" | "integer" | "float" | "boolean" | "checkbox" | "date" | "datetime" | "time" | "url" | "tel" | "color" | "range" | "file" | "hidden" | "signature" | "select" | "multiselect" | "textarea" | "radio" | "checkbox-group" | "chooser" | "slider" | "dropzone" | (string & {});
595
+ /**
596
+ * A choice for select / radio / checkbox-group / multiselect / chooser fields. A plain string is both the
597
+ * value and (capitalised) the label. Chooser options also read icon, description, badge, tooltip, etc.
598
+ */
599
+ export type FormOption = string | {
600
+ value: any;
601
+ label: string;
602
+ [key: string]: any;
603
+ };
604
+ /**
605
+ * An input-group addon for `formConfig.prefix` / `formConfig.suffix`: `{icon}` draws a Domma icon,
606
+ * `{text}` escaped text, `{html}` raw HTML (the caller's responsibility); a string is shorthand for `{text}`.
607
+ */
608
+ export type FormAddon = string | {
609
+ icon: string;
610
+ } | {
611
+ text: string | number;
612
+ } | {
613
+ html: string;
614
+ };
615
+ /**
616
+ * How a field is presented (`fieldDef.formConfig`). Slider fields pass range/ticks/tickLabels/labels/format/
617
+ * tooltip/marks/minDistance/orientation/rtl/names/ariaLabels/className to E.rangeSlider; dropzone fields pass
618
+ * accept/multiple/maxFiles/maxSize/minSize/previews/upload/autoUpload/retry/labels/list/className to E.dropzone.
619
+ */
620
+ export type FormFieldConfig = {
621
+ placeholder?: string;
622
+ /**
623
+ * - Small text beside the label; also the message when `pattern` fails
624
+ */
625
+ hint?: string;
626
+ /**
627
+ * - Text under the control (HTML)
628
+ */
629
+ helperText?: string;
630
+ /**
631
+ * - Tooltip on the label (a slider field also passes it to E.rangeSlider)
632
+ */
633
+ tooltip?: string;
634
+ /**
635
+ * - Columns the field spans in a grid layout
636
+ */
637
+ span?: number;
638
+ disabled?: boolean;
639
+ /**
640
+ * - textarea rows (default 3)
641
+ */
642
+ rows?: number;
643
+ /**
644
+ * - Used when the field definition has no `step`
645
+ */
646
+ step?: number | "any";
647
+ autocomplete?: string;
648
+ prefix?: FormAddon;
649
+ suffix?: FormAddon;
650
+ /**
651
+ * - password: show / hide toggle
652
+ */
653
+ reveal?: boolean;
654
+ /**
655
+ * - text-like inputs and textareas: a clear button
656
+ */
657
+ clear?: boolean;
658
+ /**
659
+ * - number / integer / float: - and + buttons
660
+ */
661
+ stepper?: boolean;
662
+ /**
663
+ * - text-like inputs and textareas: a character counter; true reads `maxLength`
664
+ */
665
+ counter?: boolean | number;
666
+ /**
667
+ * - Text for the input extras or the dropzone; a slider's value formatter
668
+ */
669
+ labels?: Record<string, string> | ((value: number, where: "tick" | "mark" | "tooltip" | "aria") => string);
670
+ /**
671
+ * - file / dropzone
672
+ */
673
+ accept?: string | string[];
674
+ /**
675
+ * - file / dropzone (a dropzone allows several unless false)
676
+ */
677
+ multiple?: boolean;
678
+ /**
679
+ * - Render a `range` field as E.rangeSlider
680
+ */
681
+ slider?: boolean;
682
+ /**
683
+ * - slider: two thumbs, value [low, high]
684
+ */
685
+ range?: boolean;
686
+ ticks?: import("./components/range-slider.js").RangeSliderOptions["ticks"];
687
+ tickLabels?: boolean;
688
+ format?: import("./components/range-slider.js").RangeSliderOptions["format"];
689
+ marks?: import("./components/range-slider.js").RangeSliderOptions["marks"];
690
+ minDistance?: number;
691
+ orientation?: "horizontal" | "vertical";
692
+ rtl?: boolean | null;
693
+ names?: [string, string] | null;
694
+ ariaLabels?: [string, string] | null;
695
+ className?: string;
696
+ maxFiles?: number | null;
697
+ /**
698
+ * - Bytes
699
+ */
700
+ maxSize?: number | null;
701
+ /**
702
+ * - Bytes
703
+ */
704
+ minSize?: number | null;
705
+ previews?: boolean;
706
+ upload?: import("./components/dropzone.js").DropzoneOptions["upload"];
707
+ autoUpload?: boolean;
708
+ retry?: number;
709
+ list?: boolean | string | HTMLElement;
710
+ };
711
+ /**
712
+ * One field of a form blueprint. The same object also feeds `M.create` (the form builds its model from the
713
+ * blueprint), so model keys such as `default`, `required` and `validate` apply to both.
714
+ */
715
+ export type FormFieldDefinition = {
716
+ /**
717
+ * - default 'string'
718
+ */
719
+ type?: FormFieldType;
720
+ /**
721
+ * - default: the capitalised field name
722
+ */
723
+ label?: string;
724
+ default?: any;
725
+ required?: boolean;
726
+ /**
727
+ * - Renders the control disabled
728
+ */
729
+ readonly?: boolean;
730
+ min?: number;
731
+ max?: number;
732
+ step?: number | "any";
733
+ minLength?: number;
734
+ maxLength?: number;
735
+ pattern?: RegExp;
736
+ /**
737
+ * - true passes; a string (or anything else) fails with that message
738
+ */
739
+ validate?: (value: any, data: Record<string, any>) => boolean | string;
740
+ /**
741
+ * - Choices for select / radio / checkbox-group / multiselect / chooser
742
+ */
743
+ options?: FormOption[];
744
+ formConfig?: FormFieldConfig;
745
+ /**
746
+ * - `F.crud` table cell renderer
747
+ */
748
+ tableRender?: (value: any, row: Record<string, any>, index: number) => string;
749
+ /**
750
+ * - chooser (default 'card')
751
+ */
752
+ variant?: "card" | "chip";
753
+ /**
754
+ * - chooser: several choices (value is an array)
755
+ */
756
+ multiple?: boolean;
757
+ /**
758
+ * - chooser
759
+ */
760
+ density?: "comfortable" | "compact";
761
+ /**
762
+ * - chooser (default 3)
763
+ */
764
+ columns?: number;
765
+ /**
766
+ * - chooser: semantic name or CSS colour (default 'primary')
767
+ */
768
+ accent?: string;
769
+ /**
770
+ * - chooser
771
+ */
772
+ accentStyle?: "border" | "solid" | "glow" | "overlay" | "underline";
773
+ /**
774
+ * - chooser
775
+ */
776
+ glow?: boolean;
777
+ /**
778
+ * - chooser
779
+ */
780
+ glowColour?: string | null;
781
+ /**
782
+ * - chooser (default 'none')
783
+ */
784
+ shadow?: string;
785
+ /**
786
+ * - chooser
787
+ */
788
+ shadowColour?: string | null;
789
+ };
790
+ /**
791
+ * A form blueprint: field name -> definition. Fields render in key order unless `options.sections` says otherwise.
792
+ */
793
+ export type FormBlueprint = {
794
+ [field: string]: FormFieldDefinition;
795
+ };
796
+ /**
797
+ * A group of fields (`options.sections`); with a title it is a fieldset with a legend.
798
+ */
799
+ export type FormSection = {
800
+ title?: string;
801
+ /**
802
+ * - Blueprint keys, in order
803
+ */
804
+ fields?: string[];
805
+ layout?: "grid" | "stacked";
806
+ /**
807
+ * - grid columns (default 2)
808
+ */
809
+ columns?: number;
810
+ };
811
+ export type FormOptions = {
812
+ /**
813
+ * - default 'stacked'
814
+ */
815
+ layout?: "stacked" | "grid" | "inline";
816
+ /**
817
+ * - grid layout columns (2 or 3, default 2)
818
+ */
819
+ columns?: 2 | 3 | number;
820
+ /**
821
+ * - default 'top'
822
+ */
823
+ labelPosition?: "top" | "left" | "floating";
824
+ /**
825
+ * - default true
826
+ */
827
+ showLabels?: boolean;
828
+ /**
829
+ * - default true
830
+ */
831
+ showHelperText?: boolean;
832
+ /**
833
+ * - default true
834
+ */
835
+ showHints?: boolean;
836
+ /**
837
+ * - default 'blur'
838
+ */
839
+ validationMode?: "blur" | "change" | "submit";
840
+ /**
841
+ * - default 'domma'
842
+ */
843
+ cssFramework?: "domma" | "bootstrap" | "tailwind";
844
+ /**
845
+ * - default 'domma-form'
846
+ */
847
+ className?: string;
848
+ /**
849
+ * - default 'domma-form-field'
850
+ */
851
+ fieldClassName?: string;
852
+ /**
853
+ * - default 'form-label'
854
+ */
855
+ labelClassName?: string;
856
+ /**
857
+ * - default 'form-input'
858
+ */
859
+ inputClassName?: string;
860
+ /**
861
+ * - default 'form-error'
862
+ */
863
+ errorClassName?: string;
864
+ /**
865
+ * - default 'form-helper-text'
866
+ */
867
+ helperClassName?: string;
868
+ /**
869
+ * - default 'form-hint'
870
+ */
871
+ hintClassName?: string;
872
+ /**
873
+ * - Wrap the form in a card (default false)
874
+ */
875
+ cardWrapper?: boolean;
876
+ sections?: FormSection[];
877
+ /**
878
+ * - default true
879
+ */
880
+ showSubmitButton?: boolean;
881
+ /**
882
+ * - default 'Submit'
883
+ */
884
+ submitText?: string;
885
+ /**
886
+ * - Adds a reset button with this text
887
+ */
888
+ resetText?: string;
889
+ /**
890
+ * - default 'right'
891
+ */
892
+ buttonAlignment?: "left" | "center" | "right";
893
+ /**
894
+ * - A valid submit
895
+ */
896
+ onSubmit?: (data: Record<string, any>, form: FormInstance) => void;
897
+ /**
898
+ * - An invalid submit
899
+ */
900
+ onValidationError?: (errors: Record<string, string>, form: FormInstance) => void;
901
+ /**
902
+ * - Passed to the model: a storage key to keep the values under
903
+ */
904
+ persist?: string;
905
+ /**
906
+ * - Passed to the model
907
+ */
908
+ autoSave?: boolean;
909
+ };
910
+ /**
911
+ * What `handleSubmit()` returns.
912
+ */
913
+ export type FormSubmitResult = {
914
+ isValid: boolean;
915
+ data: Record<string, any>;
916
+ /**
917
+ * - field name -> message
918
+ */
919
+ errors: Record<string, string>;
920
+ };
921
+ /**
922
+ * One step of `F.wizard`.
923
+ */
924
+ export type FormWizardStep = {
925
+ /**
926
+ * - default 'Step <n>'
927
+ */
928
+ title?: string;
929
+ description?: string;
930
+ /**
931
+ * - The step's blueprint
932
+ */
933
+ fields: FormBlueprint;
934
+ layout?: "stacked" | "grid" | "inline";
935
+ };
936
+ /**
937
+ * `F.wizard` options; the rest are FormOptions applied to every step.
938
+ */
939
+ export type FormWizardOptions = FormOptions & {
940
+ schema: {
941
+ steps: FormWizardStep[];
942
+ };
943
+ data?: Record<string, any>;
944
+ prevText?: string;
945
+ nextText?: string;
946
+ finishText?: string;
947
+ onStepChange?: (stepIndex: number, data: Record<string, any>) => void;
948
+ onValidation?: (isValid: boolean, errors: Record<string, string>, stepIndex: number) => void;
949
+ onSubmit?: (data: Record<string, any>, form: FormInstance) => void | Promise<void>;
950
+ onError?: (error: any, data: Record<string, any>, form: FormInstance) => void;
951
+ };
952
+ /**
953
+ * The control object `F.wizard` returns.
954
+ */
955
+ export type FormWizard = {
956
+ nextStep: () => void;
957
+ prevStep: () => void;
958
+ goToStep: (stepIndex: number) => void;
959
+ /**
960
+ * - 0-based
961
+ */
962
+ getCurrentStep: () => number;
963
+ /**
964
+ * - The values gathered so far (a copy)
965
+ */
966
+ getStepData: () => Record<string, any>;
967
+ /**
968
+ * - Merge values in and re-render the step
969
+ */
970
+ setStepData: (data: Record<string, any>) => void;
971
+ /**
972
+ * - Validate the current step
973
+ */
974
+ validate: () => boolean;
975
+ getElement: () => HTMLElement | null;
976
+ /**
977
+ * - Tear down the current step's controls and remove the wizard
978
+ */
979
+ destroy: () => void;
980
+ };
981
+ /**
982
+ * `F.modal` options; the rest are FormOptions (`onSubmit` and `showSubmitButton` are set by the modal).
983
+ */
984
+ export type FormModalOptions = FormOptions & {
985
+ title?: string;
986
+ saveText?: string;
987
+ closeOnSave?: boolean;
988
+ size?: string;
989
+ onSave?: (data: Record<string, any>, form: FormInstance) => void | Promise<void>;
990
+ onError?: (error: any, data: Record<string, any>, form: FormInstance) => void;
991
+ };
992
+ /**
993
+ * The control object `F.modal` returns. `close()` removes the modal from the page.
994
+ */
995
+ export type FormModal = {
996
+ open: () => void;
997
+ close: () => void;
998
+ isOpen: () => boolean;
999
+ };
1000
+ /**
1001
+ * `F.crud` configuration.
1002
+ */
1003
+ export type FormCrudConfig = {
1004
+ schema: FormBlueprint;
1005
+ /**
1006
+ * - REST endpoint (GET list, POST create, PUT/DELETE `<endpoint>/<id>`); responses are `{success, data, message}`
1007
+ */
1008
+ endpoint: string;
1009
+ /**
1010
+ * - Where the table goes
1011
+ */
1012
+ tableSelector?: string | HTMLElement;
1013
+ /**
1014
+ * - default 'Manage Items'
1015
+ */
1016
+ title?: string;
1017
+ /**
1018
+ * - default 'id'
1019
+ */
1020
+ primaryKey?: string;
1021
+ /**
1022
+ * - default 'name'
1023
+ */
1024
+ displayField?: string;
1025
+ headers?: Record<string, string>;
1026
+ onError?: (error: any) => void;
1027
+ onSuccess?: (message: string) => void;
1028
+ };
1029
+ /**
1030
+ * The object `F.crud` returns. Call `init()` to load the data and build the table.
1031
+ */
1032
+ export type FormCrud = {
1033
+ init: () => Promise<void>;
1034
+ loadData: () => Promise<void>;
1035
+ createTable: () => void;
1036
+ initializeTableIcons: () => void;
1037
+ bindEvents: () => void;
1038
+ /**
1039
+ * - Open the create modal
1040
+ */
1041
+ create: () => Promise<void>;
1042
+ /**
1043
+ * - Open the edit modal for an item
1044
+ */
1045
+ edit: (id: string | number) => Promise<void>;
1046
+ /**
1047
+ * - Confirm, then delete an item
1048
+ */
1049
+ delete: (id: string | number) => Promise<void>;
1050
+ refresh: () => Promise<void>;
1051
+ getData: () => Record<string, any>[];
1052
+ getTable: () => import("./tables.js").TableInstance | null;
1053
+ addItem: (item: Record<string, any>) => void;
1054
+ updateItem: (id: string | number, updates: Record<string, any>) => void;
1055
+ removeItem: (id: string | number) => void;
1056
+ };
1057
+ export type FormInstance = Forma;
1058
+ export type Forms = typeof forms;
1059
+ import { utils } from './utils.js';
1060
+ import { models } from './models.js';