@zodal/ui-vanilla 0.1.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.
package/README.md ADDED
@@ -0,0 +1,162 @@
1
+ # @zodal/ui-vanilla
2
+
3
+ zodal UI renderer for vanilla HTML/JS -- no React, no framework dependencies.
4
+
5
+ Produces plain `HTMLElement` instances from zodal's headless configuration objects.
6
+
7
+ ## Install
8
+
9
+ ```bash
10
+ npm install @zodal/ui-vanilla @zodal/core @zodal/ui
11
+ ```
12
+
13
+ ## Quick Start
14
+
15
+ ```typescript
16
+ import { defineCollection } from '@zodal/core';
17
+ import { toColumnDefs } from '@zodal/ui';
18
+ import { createVanillaRegistry } from '@zodal/ui-vanilla';
19
+ import { z } from 'zod';
20
+
21
+ const schema = z.object({
22
+ name: z.string(),
23
+ age: z.number(),
24
+ active: z.boolean(),
25
+ });
26
+
27
+ const collection = defineCollection(schema);
28
+ const columns = toColumnDefs(collection);
29
+ const registry = createVanillaRegistry();
30
+
31
+ // Render a cell
32
+ for (const col of columns) {
33
+ const field = collection.fieldAffordances[col.id];
34
+ if (field) {
35
+ const renderCell = registry.resolve(field, { mode: 'cell' });
36
+ const element = renderCell({ value: 'Alice', config: col, row: {} });
37
+ document.body.appendChild(element);
38
+ }
39
+ }
40
+ ```
41
+
42
+ ## Supported Renderers
43
+
44
+ ### Cell Renderers (table display)
45
+
46
+ | Renderer | Zod Type | Description |
47
+ |----------|----------|-------------|
48
+ | TextCell | string (+ fallback) | Plain text, optional truncation |
49
+ | NumberCell | number, int, float | Formatted numbers |
50
+ | CurrencyCell | number + currency meta | USD currency formatting |
51
+ | BooleanCell | boolean | Checkmark / cross |
52
+ | DateCell | date | Localized date string |
53
+ | BadgeCell | enum | Badge with data-variant |
54
+ | ArrayCell | array | Comma-separated values |
55
+
56
+ ### Form Renderers (data entry)
57
+
58
+ | Renderer | Zod Type | Description |
59
+ |----------|----------|-------------|
60
+ | TextInput | string (+ fallback) | Text input with label |
61
+ | NumberInput | number, int, float | Number input |
62
+ | CheckboxInput | boolean | Checkbox with label |
63
+ | SelectInput | enum | Dropdown with options |
64
+ | DateInput | date | Date picker |
65
+
66
+ ### Filter Renderers (filtering)
67
+
68
+ | Renderer | Filter Type | Description |
69
+ |----------|-------------|-------------|
70
+ | TextFilter | search (+ fallback) | Text search input |
71
+ | SelectFilter | select, multiSelect | Dropdown with "All" option |
72
+ | RangeFilter | range | Min/Max number inputs |
73
+ | BooleanFilter | boolean | All/Yes/No dropdown |
74
+
75
+ ## Styling
76
+
77
+ All elements use `.zodal-*` CSS class names. Style them however you want:
78
+
79
+ ```css
80
+ .zodal-cell { font-family: inherit; }
81
+ .zodal-field { margin-bottom: 1rem; }
82
+ .zodal-label { display: block; font-weight: 600; margin-bottom: 0.25rem; }
83
+ .zodal-input { padding: 0.5rem; border: 1px solid #ccc; border-radius: 4px; }
84
+ .zodal-badge { padding: 2px 8px; border-radius: 9999px; font-size: 0.75rem; }
85
+ .zodal-help { font-size: 0.875rem; color: #666; margin-top: 0.25rem; }
86
+ .zodal-muted { color: #999; }
87
+ .zodal-filter { padding: 0.25rem; }
88
+ .zodal-filter-range { display: flex; gap: 4px; }
89
+ ```
90
+
91
+ ## Browser Usage (import maps)
92
+
93
+ ```html
94
+ <script type="importmap">
95
+ { "imports": {
96
+ "zod": "https://esm.sh/zod@4",
97
+ "@zodal/core": "https://esm.sh/@zodal/core@0.1.0",
98
+ "@zodal/ui": "https://esm.sh/@zodal/ui@0.1.0",
99
+ "@zodal/ui-vanilla": "https://esm.sh/@zodal/ui-vanilla@0.1.0"
100
+ }}
101
+ </script>
102
+ <script type="module">
103
+ import { createVanillaRegistry } from '@zodal/ui-vanilla';
104
+ const registry = createVanillaRegistry();
105
+ // ...
106
+ </script>
107
+ ```
108
+
109
+ ## Customization
110
+
111
+ Override any renderer by registering a higher-priority entry:
112
+
113
+ ```typescript
114
+ import { createRendererRegistry, PRIORITY } from '@zodal/ui';
115
+ import { cellRenderers, formRenderers, filterRenderers } from '@zodal/ui-vanilla';
116
+
117
+ const registry = createRendererRegistry();
118
+ for (const entry of [...cellRenderers, ...formRenderers, ...filterRenderers]) {
119
+ registry.register(entry);
120
+ }
121
+
122
+ // Add a custom renderer at higher priority
123
+ registry.register({
124
+ tester: (field, ctx) =>
125
+ ctx.mode === 'cell' && field.zodType === 'string' ? PRIORITY.APP : -1,
126
+ renderer: (props) => {
127
+ const el = document.createElement('strong');
128
+ el.textContent = String(props.value);
129
+ return el;
130
+ },
131
+ name: 'BoldTextCell',
132
+ });
133
+ ```
134
+
135
+ ## Selective Import
136
+
137
+ Use individual renderer arrays to pick only what you need:
138
+
139
+ ```typescript
140
+ import { cellRenderers } from '@zodal/ui-vanilla';
141
+ import { createRendererRegistry } from '@zodal/ui';
142
+
143
+ const registry = createRendererRegistry();
144
+ for (const entry of cellRenderers) {
145
+ registry.register(entry);
146
+ }
147
+ ```
148
+
149
+ ## Development
150
+
151
+ ```bash
152
+ pnpm install
153
+ pnpm build # Build with tsup
154
+ pnpm test # Run tests
155
+ pnpm typecheck # TypeScript check
156
+ ```
157
+
158
+ ## License
159
+
160
+ MIT
161
+
162
+
package/dist/index.cjs ADDED
@@ -0,0 +1,392 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/index.ts
21
+ var index_exports = {};
22
+ __export(index_exports, {
23
+ cellRenderers: () => cellRenderers,
24
+ createVanillaRegistry: () => createVanillaRegistry,
25
+ filterRenderers: () => filterRenderers,
26
+ formRenderers: () => formRenderers
27
+ });
28
+ module.exports = __toCommonJS(index_exports);
29
+
30
+ // src/registry.ts
31
+ var import_ui4 = require("@zodal/ui");
32
+
33
+ // src/renderers/cell-renderers.ts
34
+ var import_ui = require("@zodal/ui");
35
+
36
+ // src/dom.ts
37
+ function el(tag, attrs, ...children) {
38
+ const element = document.createElement(tag);
39
+ if (attrs) {
40
+ for (const [key, value] of Object.entries(attrs)) {
41
+ if (key.startsWith("on") && typeof value === "function") {
42
+ const event = key.slice(2).toLowerCase();
43
+ element.addEventListener(event, value);
44
+ } else if (key === "style" && typeof value === "object") {
45
+ Object.assign(element.style, value);
46
+ } else if (value !== void 0 && value !== null && value !== false) {
47
+ element.setAttribute(key, String(value));
48
+ }
49
+ }
50
+ }
51
+ for (const child of children) {
52
+ if (child == null) continue;
53
+ element.appendChild(
54
+ typeof child === "string" ? document.createTextNode(child) : child
55
+ );
56
+ }
57
+ return element;
58
+ }
59
+
60
+ // src/renderers/cell-renderers.ts
61
+ function textCell({ value, config }) {
62
+ const str = String(value ?? "");
63
+ const truncate = config.meta.truncate;
64
+ if (truncate && str.length > truncate) {
65
+ return el("span", { title: str, class: "zodal-cell zodal-cell-text" }, str.slice(0, truncate) + "...");
66
+ }
67
+ return el("span", { class: "zodal-cell zodal-cell-text" }, str);
68
+ }
69
+ function numberCell({ value, config }) {
70
+ if (value == null) return el("span", { class: "zodal-cell zodal-muted" }, "\u2014");
71
+ const formatted = config.meta.displayFormat === "currency" ? new Intl.NumberFormat("en-US", { style: "currency", currency: "USD" }).format(value) : String(value);
72
+ return el("span", { class: "zodal-cell zodal-cell-number" }, formatted);
73
+ }
74
+ function booleanCell({ value }) {
75
+ return el("span", { class: "zodal-cell zodal-cell-boolean" }, value ? "\u2713" : "\u2717");
76
+ }
77
+ function dateCell({ value }) {
78
+ if (value == null) return el("span", { class: "zodal-cell zodal-muted" }, "\u2014");
79
+ const date = value instanceof Date ? value : new Date(value);
80
+ return el("span", { class: "zodal-cell zodal-cell-date" }, date.toLocaleDateString());
81
+ }
82
+ function badgeCell({ value, config }) {
83
+ const str = String(value ?? "");
84
+ const variant = config.meta.badge?.[str] ?? "default";
85
+ return el("span", {
86
+ class: "zodal-cell zodal-badge",
87
+ "data-variant": variant
88
+ }, str);
89
+ }
90
+ function arrayCell({ value }) {
91
+ if (!Array.isArray(value)) return el("span", { class: "zodal-cell zodal-muted" }, "\u2014");
92
+ return el("span", { class: "zodal-cell zodal-cell-array" }, value.join(", "));
93
+ }
94
+ var cellRenderers = [
95
+ {
96
+ tester: () => import_ui.PRIORITY.FALLBACK,
97
+ renderer: textCell,
98
+ name: "TextCell (fallback)"
99
+ },
100
+ {
101
+ tester: (field, ctx) => ctx.mode === "cell" && field.zodType === "string" ? import_ui.PRIORITY.DEFAULT : -1,
102
+ renderer: textCell,
103
+ name: "TextCell"
104
+ },
105
+ {
106
+ tester: (field, ctx) => ctx.mode === "cell" && ["number", "int", "float"].includes(field.zodType) ? import_ui.PRIORITY.DEFAULT : -1,
107
+ renderer: numberCell,
108
+ name: "NumberCell"
109
+ },
110
+ {
111
+ tester: (field, ctx) => ctx.mode === "cell" && field.zodType === "boolean" ? import_ui.PRIORITY.DEFAULT : -1,
112
+ renderer: booleanCell,
113
+ name: "BooleanCell"
114
+ },
115
+ {
116
+ tester: (field, ctx) => ctx.mode === "cell" && field.zodType === "date" ? import_ui.PRIORITY.DEFAULT : -1,
117
+ renderer: dateCell,
118
+ name: "DateCell"
119
+ },
120
+ {
121
+ tester: (field, ctx) => ctx.mode === "cell" && field.zodType === "enum" ? import_ui.PRIORITY.DEFAULT : -1,
122
+ renderer: badgeCell,
123
+ name: "BadgeCell"
124
+ },
125
+ {
126
+ tester: (field, ctx) => ctx.mode === "cell" && field.zodType === "array" ? import_ui.PRIORITY.DEFAULT : -1,
127
+ renderer: arrayCell,
128
+ name: "ArrayCell"
129
+ },
130
+ {
131
+ tester: (field, ctx) => ctx.mode === "cell" && field.displayFormat === "currency" ? import_ui.PRIORITY.LIBRARY : -1,
132
+ renderer: numberCell,
133
+ name: "CurrencyCell"
134
+ }
135
+ ];
136
+
137
+ // src/renderers/form-renderers.ts
138
+ var import_ui2 = require("@zodal/ui");
139
+ function textInput({ field, config }) {
140
+ return el(
141
+ "div",
142
+ { class: "zodal-field" },
143
+ el("label", { for: config.name, class: "zodal-label" }, config.label),
144
+ el("input", {
145
+ id: config.name,
146
+ type: "text",
147
+ value: String(field.value ?? ""),
148
+ class: "zodal-input",
149
+ placeholder: config.placeholder,
150
+ required: config.required,
151
+ disabled: config.disabled,
152
+ onInput: (e) => field.onChange(e.target.value)
153
+ }),
154
+ config.helpText ? el("p", { class: "zodal-help" }, config.helpText) : null
155
+ );
156
+ }
157
+ function numberInput({ field, config }) {
158
+ return el(
159
+ "div",
160
+ { class: "zodal-field" },
161
+ el("label", { for: config.name, class: "zodal-label" }, config.label),
162
+ el("input", {
163
+ id: config.name,
164
+ type: "number",
165
+ value: field.value ?? "",
166
+ class: "zodal-input",
167
+ required: config.required,
168
+ disabled: config.disabled,
169
+ onInput: (e) => field.onChange(Number(e.target.value))
170
+ })
171
+ );
172
+ }
173
+ function checkboxInput({ field, config }) {
174
+ return el(
175
+ "div",
176
+ { class: "zodal-field" },
177
+ el(
178
+ "label",
179
+ { class: "zodal-label" },
180
+ el("input", {
181
+ type: "checkbox",
182
+ checked: Boolean(field.value),
183
+ class: "zodal-input",
184
+ disabled: config.disabled,
185
+ onChange: (e) => field.onChange(e.target.checked)
186
+ }),
187
+ " ",
188
+ config.label
189
+ )
190
+ );
191
+ }
192
+ function selectInput({ field, config }) {
193
+ const select = el(
194
+ "select",
195
+ {
196
+ id: config.name,
197
+ class: "zodal-input",
198
+ required: config.required,
199
+ disabled: config.disabled,
200
+ onChange: (e) => field.onChange(e.target.value)
201
+ },
202
+ el("option", { value: "" }, `Select ${config.label}...`),
203
+ ...(config.options ?? []).map(
204
+ (opt) => el("option", { value: opt.value }, opt.label)
205
+ )
206
+ );
207
+ select.value = String(field.value ?? "");
208
+ return el(
209
+ "div",
210
+ { class: "zodal-field" },
211
+ el("label", { for: config.name, class: "zodal-label" }, config.label),
212
+ select
213
+ );
214
+ }
215
+ function dateInput({ field, config }) {
216
+ const dateValue = field.value instanceof Date ? field.value.toISOString().split("T")[0] : String(field.value ?? "");
217
+ return el(
218
+ "div",
219
+ { class: "zodal-field" },
220
+ el("label", { for: config.name, class: "zodal-label" }, config.label),
221
+ el("input", {
222
+ id: config.name,
223
+ type: "date",
224
+ value: dateValue,
225
+ class: "zodal-input",
226
+ required: config.required,
227
+ disabled: config.disabled,
228
+ onInput: (e) => field.onChange(new Date(e.target.value))
229
+ })
230
+ );
231
+ }
232
+ var formRenderers = [
233
+ {
234
+ tester: (_, ctx) => ctx.mode === "form" ? import_ui2.PRIORITY.FALLBACK : -1,
235
+ renderer: textInput,
236
+ name: "TextInput (fallback)"
237
+ },
238
+ {
239
+ tester: (field, ctx) => ctx.mode === "form" && field.zodType === "string" ? import_ui2.PRIORITY.DEFAULT : -1,
240
+ renderer: textInput,
241
+ name: "TextInput"
242
+ },
243
+ {
244
+ tester: (field, ctx) => ctx.mode === "form" && ["number", "int", "float"].includes(field.zodType) ? import_ui2.PRIORITY.DEFAULT : -1,
245
+ renderer: numberInput,
246
+ name: "NumberInput"
247
+ },
248
+ {
249
+ tester: (field, ctx) => ctx.mode === "form" && field.zodType === "boolean" ? import_ui2.PRIORITY.DEFAULT : -1,
250
+ renderer: checkboxInput,
251
+ name: "CheckboxInput"
252
+ },
253
+ {
254
+ tester: (field, ctx) => ctx.mode === "form" && field.zodType === "enum" ? import_ui2.PRIORITY.DEFAULT : -1,
255
+ renderer: selectInput,
256
+ name: "SelectInput"
257
+ },
258
+ {
259
+ tester: (field, ctx) => ctx.mode === "form" && field.zodType === "date" ? import_ui2.PRIORITY.DEFAULT : -1,
260
+ renderer: dateInput,
261
+ name: "DateInput"
262
+ }
263
+ ];
264
+
265
+ // src/renderers/filter-renderers.ts
266
+ var import_ui3 = require("@zodal/ui");
267
+ function textFilter({ field, config }) {
268
+ return el("input", {
269
+ type: "text",
270
+ value: String(field.value ?? ""),
271
+ placeholder: `Filter ${config.label}...`,
272
+ class: "zodal-filter zodal-filter-text",
273
+ onInput: (e) => field.onChange(e.target.value)
274
+ });
275
+ }
276
+ function selectFilter({ field, config }) {
277
+ const select = el(
278
+ "select",
279
+ {
280
+ class: "zodal-filter zodal-filter-select",
281
+ onChange: (e) => field.onChange(e.target.value || void 0)
282
+ },
283
+ el("option", { value: "" }, `All ${config.label}`),
284
+ ...(config.options ?? []).map(
285
+ (opt) => el("option", { value: opt.value }, opt.label)
286
+ )
287
+ );
288
+ select.value = String(field.value ?? "");
289
+ return select;
290
+ }
291
+ function rangeFilter({ field, config }) {
292
+ const [min, max] = Array.isArray(field.value) ? field.value : [void 0, void 0];
293
+ return el(
294
+ "div",
295
+ { style: { display: "flex", gap: "4px" }, class: "zodal-filter zodal-filter-range" },
296
+ el("input", {
297
+ type: "number",
298
+ value: min ?? "",
299
+ placeholder: "Min",
300
+ min: config.bounds?.min,
301
+ max: config.bounds?.max,
302
+ class: "zodal-input",
303
+ onInput: (e) => {
304
+ const v = e.target.value;
305
+ field.onChange([v ? Number(v) : void 0, max]);
306
+ }
307
+ }),
308
+ el("input", {
309
+ type: "number",
310
+ value: max ?? "",
311
+ placeholder: "Max",
312
+ min: config.bounds?.min,
313
+ max: config.bounds?.max,
314
+ class: "zodal-input",
315
+ onInput: (e) => {
316
+ const v = e.target.value;
317
+ field.onChange([min, v ? Number(v) : void 0]);
318
+ }
319
+ })
320
+ );
321
+ }
322
+ function booleanFilter({ field, config }) {
323
+ const select = el(
324
+ "select",
325
+ {
326
+ class: "zodal-filter zodal-filter-boolean",
327
+ onChange: (e) => {
328
+ const v = e.target.value;
329
+ field.onChange(v === "true" ? true : v === "false" ? false : void 0);
330
+ }
331
+ },
332
+ el("option", { value: "" }, "All"),
333
+ el("option", { value: "true" }, "Yes"),
334
+ el("option", { value: "false" }, "No")
335
+ );
336
+ select.value = field.value === true ? "true" : field.value === false ? "false" : "";
337
+ return select;
338
+ }
339
+ var filterRenderers = [
340
+ {
341
+ tester: (_, ctx) => ctx.mode === "filter" ? import_ui3.PRIORITY.FALLBACK : -1,
342
+ renderer: textFilter,
343
+ name: "TextFilter (fallback)"
344
+ },
345
+ {
346
+ tester: (field, ctx) => ctx.mode === "filter" && field.filterable === "search" ? import_ui3.PRIORITY.DEFAULT : -1,
347
+ renderer: textFilter,
348
+ name: "TextFilter"
349
+ },
350
+ {
351
+ tester: (field, ctx) => ctx.mode === "filter" && field.filterable === "select" ? import_ui3.PRIORITY.DEFAULT : -1,
352
+ renderer: selectFilter,
353
+ name: "SelectFilter"
354
+ },
355
+ {
356
+ tester: (field, ctx) => ctx.mode === "filter" && field.filterable === "multiSelect" ? import_ui3.PRIORITY.DEFAULT : -1,
357
+ renderer: selectFilter,
358
+ name: "MultiSelectFilter"
359
+ },
360
+ {
361
+ tester: (field, ctx) => ctx.mode === "filter" && field.filterable === "range" ? import_ui3.PRIORITY.DEFAULT : -1,
362
+ renderer: rangeFilter,
363
+ name: "RangeFilter"
364
+ },
365
+ {
366
+ tester: (field, ctx) => ctx.mode === "filter" && field.zodType === "boolean" ? import_ui3.PRIORITY.DEFAULT : -1,
367
+ renderer: booleanFilter,
368
+ name: "BooleanFilter"
369
+ }
370
+ ];
371
+
372
+ // src/registry.ts
373
+ function createVanillaRegistry() {
374
+ const registry = (0, import_ui4.createRendererRegistry)();
375
+ const allRenderers = [
376
+ ...cellRenderers,
377
+ ...formRenderers,
378
+ ...filterRenderers
379
+ ];
380
+ for (const entry of allRenderers) {
381
+ registry.register(entry);
382
+ }
383
+ return registry;
384
+ }
385
+ // Annotate the CommonJS export names for ESM import in node:
386
+ 0 && (module.exports = {
387
+ cellRenderers,
388
+ createVanillaRegistry,
389
+ filterRenderers,
390
+ formRenderers
391
+ });
392
+ //# sourceMappingURL=index.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/index.ts","../src/registry.ts","../src/renderers/cell-renderers.ts","../src/dom.ts","../src/renderers/form-renderers.ts","../src/renderers/filter-renderers.ts"],"sourcesContent":["export { createVanillaRegistry } from './registry.js';\nexport type { VanillaRenderer } from './registry.js';\nexport { cellRenderers } from './renderers/cell-renderers.js';\nexport { formRenderers } from './renderers/form-renderers.js';\nexport { filterRenderers } from './renderers/filter-renderers.js';\nexport type { CellProps, FormFieldProps, FilterFieldProps } from './types.js';\n","import { createRendererRegistry } from '@zodal/ui';\nimport type { RendererEntry } from '@zodal/ui';\nimport { cellRenderers } from './renderers/cell-renderers.js';\nimport { formRenderers } from './renderers/form-renderers.js';\nimport { filterRenderers } from './renderers/filter-renderers.js';\n\n/** A vanilla renderer function: takes props, returns an HTMLElement. */\nexport type VanillaRenderer = (props: any) => HTMLElement;\n\n/**\n * Create a RendererRegistry pre-loaded with all vanilla DOM renderers.\n */\nexport function createVanillaRegistry() {\n const registry = createRendererRegistry<VanillaRenderer>();\n const allRenderers: RendererEntry<VanillaRenderer>[] = [\n ...cellRenderers,\n ...formRenderers,\n ...filterRenderers,\n ];\n for (const entry of allRenderers) {\n registry.register(entry);\n }\n return registry;\n}\n","/**\n * Cell renderers for table display.\n * Plain DOM elements — no framework dependency.\n */\n\nimport { PRIORITY } from '@zodal/ui';\nimport type { RendererEntry } from '@zodal/ui';\nimport { el } from '../dom.js';\nimport type { CellProps } from '../types.js';\n\nfunction textCell({ value, config }: CellProps): HTMLElement {\n const str = String(value ?? '');\n const truncate = config.meta.truncate;\n if (truncate && str.length > truncate) {\n return el('span', { title: str, class: 'zodal-cell zodal-cell-text' }, str.slice(0, truncate) + '...');\n }\n return el('span', { class: 'zodal-cell zodal-cell-text' }, str);\n}\n\nfunction numberCell({ value, config }: CellProps): HTMLElement {\n if (value == null) return el('span', { class: 'zodal-cell zodal-muted' }, '\\u2014');\n const formatted = config.meta.displayFormat === 'currency'\n ? new Intl.NumberFormat('en-US', { style: 'currency', currency: 'USD' }).format(value as number)\n : String(value);\n return el('span', { class: 'zodal-cell zodal-cell-number' }, formatted);\n}\n\nfunction booleanCell({ value }: CellProps): HTMLElement {\n return el('span', { class: 'zodal-cell zodal-cell-boolean' }, value ? '\\u2713' : '\\u2717');\n}\n\nfunction dateCell({ value }: CellProps): HTMLElement {\n if (value == null) return el('span', { class: 'zodal-cell zodal-muted' }, '\\u2014');\n const date = value instanceof Date ? value : new Date(value as string);\n return el('span', { class: 'zodal-cell zodal-cell-date' }, date.toLocaleDateString());\n}\n\nfunction badgeCell({ value, config }: CellProps): HTMLElement {\n const str = String(value ?? '');\n const variant = config.meta.badge?.[str] ?? 'default';\n return el('span', {\n class: 'zodal-cell zodal-badge',\n 'data-variant': variant,\n }, str);\n}\n\nfunction arrayCell({ value }: CellProps): HTMLElement {\n if (!Array.isArray(value)) return el('span', { class: 'zodal-cell zodal-muted' }, '\\u2014');\n return el('span', { class: 'zodal-cell zodal-cell-array' }, value.join(', '));\n}\n\nexport type CellRenderer = (props: CellProps) => HTMLElement;\n\nexport const cellRenderers: RendererEntry<CellRenderer>[] = [\n {\n tester: () => PRIORITY.FALLBACK,\n renderer: textCell,\n name: 'TextCell (fallback)',\n },\n {\n tester: (field, ctx) => ctx.mode === 'cell' && field.zodType === 'string' ? PRIORITY.DEFAULT : -1,\n renderer: textCell,\n name: 'TextCell',\n },\n {\n tester: (field, ctx) => ctx.mode === 'cell' && ['number', 'int', 'float'].includes(field.zodType) ? PRIORITY.DEFAULT : -1,\n renderer: numberCell,\n name: 'NumberCell',\n },\n {\n tester: (field, ctx) => ctx.mode === 'cell' && field.zodType === 'boolean' ? PRIORITY.DEFAULT : -1,\n renderer: booleanCell,\n name: 'BooleanCell',\n },\n {\n tester: (field, ctx) => ctx.mode === 'cell' && field.zodType === 'date' ? PRIORITY.DEFAULT : -1,\n renderer: dateCell,\n name: 'DateCell',\n },\n {\n tester: (field, ctx) => ctx.mode === 'cell' && field.zodType === 'enum' ? PRIORITY.DEFAULT : -1,\n renderer: badgeCell,\n name: 'BadgeCell',\n },\n {\n tester: (field, ctx) => ctx.mode === 'cell' && field.zodType === 'array' ? PRIORITY.DEFAULT : -1,\n renderer: arrayCell,\n name: 'ArrayCell',\n },\n {\n tester: (field, ctx) => ctx.mode === 'cell' && (field as any).displayFormat === 'currency' ? PRIORITY.LIBRARY : -1,\n renderer: numberCell,\n name: 'CurrencyCell',\n },\n];\n","/**\n * Internal DOM element factory.\n * Replaces React.createElement with native DOM API.\n */\nexport function el(\n tag: string,\n attrs?: Record<string, any> | null,\n ...children: (Node | string | null | undefined)[]\n): HTMLElement {\n const element = document.createElement(tag);\n if (attrs) {\n for (const [key, value] of Object.entries(attrs)) {\n if (key.startsWith('on') && typeof value === 'function') {\n const event = key.slice(2).toLowerCase();\n element.addEventListener(event, value);\n } else if (key === 'style' && typeof value === 'object') {\n Object.assign(element.style, value);\n } else if (value !== undefined && value !== null && value !== false) {\n element.setAttribute(key, String(value));\n }\n }\n }\n for (const child of children) {\n if (child == null) continue;\n element.appendChild(\n typeof child === 'string' ? document.createTextNode(child) : child,\n );\n }\n return element;\n}\n","/**\n * Form field renderers.\n * Plain DOM elements with native event listeners.\n */\n\nimport { PRIORITY } from '@zodal/ui';\nimport type { RendererEntry } from '@zodal/ui';\nimport { el } from '../dom.js';\nimport type { FormFieldProps } from '../types.js';\n\nfunction textInput({ field, config }: FormFieldProps): HTMLElement {\n return el('div', { class: 'zodal-field' },\n el('label', { for: config.name, class: 'zodal-label' }, config.label),\n el('input', {\n id: config.name,\n type: 'text',\n value: String(field.value ?? ''),\n class: 'zodal-input',\n placeholder: config.placeholder,\n required: config.required,\n disabled: config.disabled,\n onInput: (e: Event) => field.onChange((e.target as HTMLInputElement).value),\n }),\n config.helpText ? el('p', { class: 'zodal-help' }, config.helpText) : null,\n );\n}\n\nfunction numberInput({ field, config }: FormFieldProps): HTMLElement {\n return el('div', { class: 'zodal-field' },\n el('label', { for: config.name, class: 'zodal-label' }, config.label),\n el('input', {\n id: config.name,\n type: 'number',\n value: field.value ?? '',\n class: 'zodal-input',\n required: config.required,\n disabled: config.disabled,\n onInput: (e: Event) => field.onChange(Number((e.target as HTMLInputElement).value)),\n }),\n );\n}\n\nfunction checkboxInput({ field, config }: FormFieldProps): HTMLElement {\n return el('div', { class: 'zodal-field' },\n el('label', { class: 'zodal-label' },\n el('input', {\n type: 'checkbox',\n checked: Boolean(field.value),\n class: 'zodal-input',\n disabled: config.disabled,\n onChange: (e: Event) => field.onChange((e.target as HTMLInputElement).checked),\n }),\n ' ',\n config.label,\n ),\n );\n}\n\nfunction selectInput({ field, config }: FormFieldProps): HTMLElement {\n const select = el('select', {\n id: config.name,\n class: 'zodal-input',\n required: config.required,\n disabled: config.disabled,\n onChange: (e: Event) => field.onChange((e.target as HTMLSelectElement).value),\n },\n el('option', { value: '' }, `Select ${config.label}...`),\n ...(config.options ?? []).map(opt =>\n el('option', { value: opt.value }, opt.label)\n ),\n );\n // Set selected value after creation\n (select as HTMLSelectElement).value = String(field.value ?? '');\n\n return el('div', { class: 'zodal-field' },\n el('label', { for: config.name, class: 'zodal-label' }, config.label),\n select,\n );\n}\n\nfunction dateInput({ field, config }: FormFieldProps): HTMLElement {\n const dateValue = field.value instanceof Date\n ? (field.value as Date).toISOString().split('T')[0]\n : String(field.value ?? '');\n\n return el('div', { class: 'zodal-field' },\n el('label', { for: config.name, class: 'zodal-label' }, config.label),\n el('input', {\n id: config.name,\n type: 'date',\n value: dateValue,\n class: 'zodal-input',\n required: config.required,\n disabled: config.disabled,\n onInput: (e: Event) => field.onChange(new Date((e.target as HTMLInputElement).value)),\n }),\n );\n}\n\nexport type FormRenderer = (props: FormFieldProps) => HTMLElement;\n\nexport const formRenderers: RendererEntry<FormRenderer>[] = [\n {\n tester: (_, ctx) => ctx.mode === 'form' ? PRIORITY.FALLBACK : -1,\n renderer: textInput,\n name: 'TextInput (fallback)',\n },\n {\n tester: (field, ctx) => ctx.mode === 'form' && field.zodType === 'string' ? PRIORITY.DEFAULT : -1,\n renderer: textInput,\n name: 'TextInput',\n },\n {\n tester: (field, ctx) => ctx.mode === 'form' && ['number', 'int', 'float'].includes(field.zodType) ? PRIORITY.DEFAULT : -1,\n renderer: numberInput,\n name: 'NumberInput',\n },\n {\n tester: (field, ctx) => ctx.mode === 'form' && field.zodType === 'boolean' ? PRIORITY.DEFAULT : -1,\n renderer: checkboxInput,\n name: 'CheckboxInput',\n },\n {\n tester: (field, ctx) => ctx.mode === 'form' && field.zodType === 'enum' ? PRIORITY.DEFAULT : -1,\n renderer: selectInput,\n name: 'SelectInput',\n },\n {\n tester: (field, ctx) => ctx.mode === 'form' && field.zodType === 'date' ? PRIORITY.DEFAULT : -1,\n renderer: dateInput,\n name: 'DateInput',\n },\n];\n","/**\n * Filter widget renderers.\n * Plain DOM elements with native event listeners.\n */\n\nimport { PRIORITY } from '@zodal/ui';\nimport type { RendererEntry } from '@zodal/ui';\nimport { el } from '../dom.js';\nimport type { FilterFieldProps } from '../types.js';\n\nfunction textFilter({ field, config }: FilterFieldProps): HTMLElement {\n return el('input', {\n type: 'text',\n value: String(field.value ?? ''),\n placeholder: `Filter ${config.label}...`,\n class: 'zodal-filter zodal-filter-text',\n onInput: (e: Event) => field.onChange((e.target as HTMLInputElement).value),\n });\n}\n\nfunction selectFilter({ field, config }: FilterFieldProps): HTMLElement {\n const select = el('select', {\n class: 'zodal-filter zodal-filter-select',\n onChange: (e: Event) => field.onChange((e.target as HTMLSelectElement).value || undefined),\n },\n el('option', { value: '' }, `All ${config.label}`),\n ...(config.options ?? []).map(opt =>\n el('option', { value: opt.value }, opt.label)\n ),\n );\n (select as HTMLSelectElement).value = String(field.value ?? '');\n return select;\n}\n\nfunction rangeFilter({ field, config }: FilterFieldProps): HTMLElement {\n const [min, max] = Array.isArray(field.value) ? field.value : [undefined, undefined];\n return el('div', { style: { display: 'flex', gap: '4px' }, class: 'zodal-filter zodal-filter-range' },\n el('input', {\n type: 'number',\n value: min ?? '',\n placeholder: 'Min',\n min: config.bounds?.min,\n max: config.bounds?.max,\n class: 'zodal-input',\n onInput: (e: Event) => {\n const v = (e.target as HTMLInputElement).value;\n field.onChange([v ? Number(v) : undefined, max]);\n },\n }),\n el('input', {\n type: 'number',\n value: max ?? '',\n placeholder: 'Max',\n min: config.bounds?.min,\n max: config.bounds?.max,\n class: 'zodal-input',\n onInput: (e: Event) => {\n const v = (e.target as HTMLInputElement).value;\n field.onChange([min, v ? Number(v) : undefined]);\n },\n }),\n );\n}\n\nfunction booleanFilter({ field, config }: FilterFieldProps): HTMLElement {\n const select = el('select', {\n class: 'zodal-filter zodal-filter-boolean',\n onChange: (e: Event) => {\n const v = (e.target as HTMLSelectElement).value;\n field.onChange(v === 'true' ? true : v === 'false' ? false : undefined);\n },\n },\n el('option', { value: '' }, 'All'),\n el('option', { value: 'true' }, 'Yes'),\n el('option', { value: 'false' }, 'No'),\n );\n // Set initial value\n (select as HTMLSelectElement).value = field.value === true ? 'true' : field.value === false ? 'false' : '';\n return select;\n}\n\nexport type FilterRenderer = (props: FilterFieldProps) => HTMLElement;\n\nexport const filterRenderers: RendererEntry<FilterRenderer>[] = [\n {\n tester: (_, ctx) => ctx.mode === 'filter' ? PRIORITY.FALLBACK : -1,\n renderer: textFilter,\n name: 'TextFilter (fallback)',\n },\n {\n tester: (field, ctx) => ctx.mode === 'filter' && (field as any).filterable === 'search' ? PRIORITY.DEFAULT : -1,\n renderer: textFilter,\n name: 'TextFilter',\n },\n {\n tester: (field, ctx) => ctx.mode === 'filter' && (field as any).filterable === 'select' ? PRIORITY.DEFAULT : -1,\n renderer: selectFilter,\n name: 'SelectFilter',\n },\n {\n tester: (field, ctx) => ctx.mode === 'filter' && (field as any).filterable === 'multiSelect' ? PRIORITY.DEFAULT : -1,\n renderer: selectFilter,\n name: 'MultiSelectFilter',\n },\n {\n tester: (field, ctx) => ctx.mode === 'filter' && (field as any).filterable === 'range' ? PRIORITY.DEFAULT : -1,\n renderer: rangeFilter,\n name: 'RangeFilter',\n },\n {\n tester: (field, ctx) => ctx.mode === 'filter' && field.zodType === 'boolean' ? PRIORITY.DEFAULT : -1,\n renderer: booleanFilter,\n name: 'BooleanFilter',\n },\n];\n"],"mappings":"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","names":["import_ui","import_ui","import_ui"]}
@@ -0,0 +1,65 @@
1
+ import * as _zodal_ui from '@zodal/ui';
2
+ import { ColumnConfig, FilterFieldConfig, FormFieldConfig, RendererEntry } from '@zodal/ui';
3
+
4
+ /** A vanilla renderer function: takes props, returns an HTMLElement. */
5
+ type VanillaRenderer = (props: any) => HTMLElement;
6
+ /**
7
+ * Create a RendererRegistry pre-loaded with all vanilla DOM renderers.
8
+ */
9
+ declare function createVanillaRegistry(): _zodal_ui.RendererRegistry<VanillaRenderer>;
10
+
11
+ /** Props passed to cell renderer functions. */
12
+ interface CellProps {
13
+ /** The cell value. */
14
+ value: unknown;
15
+ /** The column configuration from toColumnDefs(). */
16
+ config: ColumnConfig;
17
+ /** The full row data. */
18
+ row: Record<string, unknown>;
19
+ }
20
+ /** Props passed to form field renderer functions. */
21
+ interface FormFieldProps {
22
+ /** Form field binding (value + onChange). */
23
+ field: {
24
+ value: unknown;
25
+ onChange: (value: unknown) => void;
26
+ };
27
+ /** The form field configuration from toFormConfig(). */
28
+ config: FormFieldConfig;
29
+ }
30
+ /** Props passed to filter renderer functions. */
31
+ interface FilterFieldProps {
32
+ /** Filter field binding (value + onChange). */
33
+ field: {
34
+ value: unknown;
35
+ onChange: (value: unknown) => void;
36
+ };
37
+ /** The filter field configuration from toFilterConfig(). */
38
+ config: FilterFieldConfig;
39
+ }
40
+
41
+ /**
42
+ * Cell renderers for table display.
43
+ * Plain DOM elements — no framework dependency.
44
+ */
45
+
46
+ type CellRenderer = (props: CellProps) => HTMLElement;
47
+ declare const cellRenderers: RendererEntry<CellRenderer>[];
48
+
49
+ /**
50
+ * Form field renderers.
51
+ * Plain DOM elements with native event listeners.
52
+ */
53
+
54
+ type FormRenderer = (props: FormFieldProps) => HTMLElement;
55
+ declare const formRenderers: RendererEntry<FormRenderer>[];
56
+
57
+ /**
58
+ * Filter widget renderers.
59
+ * Plain DOM elements with native event listeners.
60
+ */
61
+
62
+ type FilterRenderer = (props: FilterFieldProps) => HTMLElement;
63
+ declare const filterRenderers: RendererEntry<FilterRenderer>[];
64
+
65
+ export { type CellProps, type FilterFieldProps, type FormFieldProps, type VanillaRenderer, cellRenderers, createVanillaRegistry, filterRenderers, formRenderers };
@@ -0,0 +1,65 @@
1
+ import * as _zodal_ui from '@zodal/ui';
2
+ import { ColumnConfig, FilterFieldConfig, FormFieldConfig, RendererEntry } from '@zodal/ui';
3
+
4
+ /** A vanilla renderer function: takes props, returns an HTMLElement. */
5
+ type VanillaRenderer = (props: any) => HTMLElement;
6
+ /**
7
+ * Create a RendererRegistry pre-loaded with all vanilla DOM renderers.
8
+ */
9
+ declare function createVanillaRegistry(): _zodal_ui.RendererRegistry<VanillaRenderer>;
10
+
11
+ /** Props passed to cell renderer functions. */
12
+ interface CellProps {
13
+ /** The cell value. */
14
+ value: unknown;
15
+ /** The column configuration from toColumnDefs(). */
16
+ config: ColumnConfig;
17
+ /** The full row data. */
18
+ row: Record<string, unknown>;
19
+ }
20
+ /** Props passed to form field renderer functions. */
21
+ interface FormFieldProps {
22
+ /** Form field binding (value + onChange). */
23
+ field: {
24
+ value: unknown;
25
+ onChange: (value: unknown) => void;
26
+ };
27
+ /** The form field configuration from toFormConfig(). */
28
+ config: FormFieldConfig;
29
+ }
30
+ /** Props passed to filter renderer functions. */
31
+ interface FilterFieldProps {
32
+ /** Filter field binding (value + onChange). */
33
+ field: {
34
+ value: unknown;
35
+ onChange: (value: unknown) => void;
36
+ };
37
+ /** The filter field configuration from toFilterConfig(). */
38
+ config: FilterFieldConfig;
39
+ }
40
+
41
+ /**
42
+ * Cell renderers for table display.
43
+ * Plain DOM elements — no framework dependency.
44
+ */
45
+
46
+ type CellRenderer = (props: CellProps) => HTMLElement;
47
+ declare const cellRenderers: RendererEntry<CellRenderer>[];
48
+
49
+ /**
50
+ * Form field renderers.
51
+ * Plain DOM elements with native event listeners.
52
+ */
53
+
54
+ type FormRenderer = (props: FormFieldProps) => HTMLElement;
55
+ declare const formRenderers: RendererEntry<FormRenderer>[];
56
+
57
+ /**
58
+ * Filter widget renderers.
59
+ * Plain DOM elements with native event listeners.
60
+ */
61
+
62
+ type FilterRenderer = (props: FilterFieldProps) => HTMLElement;
63
+ declare const filterRenderers: RendererEntry<FilterRenderer>[];
64
+
65
+ export { type CellProps, type FilterFieldProps, type FormFieldProps, type VanillaRenderer, cellRenderers, createVanillaRegistry, filterRenderers, formRenderers };
package/dist/index.js ADDED
@@ -0,0 +1,362 @@
1
+ // src/registry.ts
2
+ import { createRendererRegistry } from "@zodal/ui";
3
+
4
+ // src/renderers/cell-renderers.ts
5
+ import { PRIORITY } from "@zodal/ui";
6
+
7
+ // src/dom.ts
8
+ function el(tag, attrs, ...children) {
9
+ const element = document.createElement(tag);
10
+ if (attrs) {
11
+ for (const [key, value] of Object.entries(attrs)) {
12
+ if (key.startsWith("on") && typeof value === "function") {
13
+ const event = key.slice(2).toLowerCase();
14
+ element.addEventListener(event, value);
15
+ } else if (key === "style" && typeof value === "object") {
16
+ Object.assign(element.style, value);
17
+ } else if (value !== void 0 && value !== null && value !== false) {
18
+ element.setAttribute(key, String(value));
19
+ }
20
+ }
21
+ }
22
+ for (const child of children) {
23
+ if (child == null) continue;
24
+ element.appendChild(
25
+ typeof child === "string" ? document.createTextNode(child) : child
26
+ );
27
+ }
28
+ return element;
29
+ }
30
+
31
+ // src/renderers/cell-renderers.ts
32
+ function textCell({ value, config }) {
33
+ const str = String(value ?? "");
34
+ const truncate = config.meta.truncate;
35
+ if (truncate && str.length > truncate) {
36
+ return el("span", { title: str, class: "zodal-cell zodal-cell-text" }, str.slice(0, truncate) + "...");
37
+ }
38
+ return el("span", { class: "zodal-cell zodal-cell-text" }, str);
39
+ }
40
+ function numberCell({ value, config }) {
41
+ if (value == null) return el("span", { class: "zodal-cell zodal-muted" }, "\u2014");
42
+ const formatted = config.meta.displayFormat === "currency" ? new Intl.NumberFormat("en-US", { style: "currency", currency: "USD" }).format(value) : String(value);
43
+ return el("span", { class: "zodal-cell zodal-cell-number" }, formatted);
44
+ }
45
+ function booleanCell({ value }) {
46
+ return el("span", { class: "zodal-cell zodal-cell-boolean" }, value ? "\u2713" : "\u2717");
47
+ }
48
+ function dateCell({ value }) {
49
+ if (value == null) return el("span", { class: "zodal-cell zodal-muted" }, "\u2014");
50
+ const date = value instanceof Date ? value : new Date(value);
51
+ return el("span", { class: "zodal-cell zodal-cell-date" }, date.toLocaleDateString());
52
+ }
53
+ function badgeCell({ value, config }) {
54
+ const str = String(value ?? "");
55
+ const variant = config.meta.badge?.[str] ?? "default";
56
+ return el("span", {
57
+ class: "zodal-cell zodal-badge",
58
+ "data-variant": variant
59
+ }, str);
60
+ }
61
+ function arrayCell({ value }) {
62
+ if (!Array.isArray(value)) return el("span", { class: "zodal-cell zodal-muted" }, "\u2014");
63
+ return el("span", { class: "zodal-cell zodal-cell-array" }, value.join(", "));
64
+ }
65
+ var cellRenderers = [
66
+ {
67
+ tester: () => PRIORITY.FALLBACK,
68
+ renderer: textCell,
69
+ name: "TextCell (fallback)"
70
+ },
71
+ {
72
+ tester: (field, ctx) => ctx.mode === "cell" && field.zodType === "string" ? PRIORITY.DEFAULT : -1,
73
+ renderer: textCell,
74
+ name: "TextCell"
75
+ },
76
+ {
77
+ tester: (field, ctx) => ctx.mode === "cell" && ["number", "int", "float"].includes(field.zodType) ? PRIORITY.DEFAULT : -1,
78
+ renderer: numberCell,
79
+ name: "NumberCell"
80
+ },
81
+ {
82
+ tester: (field, ctx) => ctx.mode === "cell" && field.zodType === "boolean" ? PRIORITY.DEFAULT : -1,
83
+ renderer: booleanCell,
84
+ name: "BooleanCell"
85
+ },
86
+ {
87
+ tester: (field, ctx) => ctx.mode === "cell" && field.zodType === "date" ? PRIORITY.DEFAULT : -1,
88
+ renderer: dateCell,
89
+ name: "DateCell"
90
+ },
91
+ {
92
+ tester: (field, ctx) => ctx.mode === "cell" && field.zodType === "enum" ? PRIORITY.DEFAULT : -1,
93
+ renderer: badgeCell,
94
+ name: "BadgeCell"
95
+ },
96
+ {
97
+ tester: (field, ctx) => ctx.mode === "cell" && field.zodType === "array" ? PRIORITY.DEFAULT : -1,
98
+ renderer: arrayCell,
99
+ name: "ArrayCell"
100
+ },
101
+ {
102
+ tester: (field, ctx) => ctx.mode === "cell" && field.displayFormat === "currency" ? PRIORITY.LIBRARY : -1,
103
+ renderer: numberCell,
104
+ name: "CurrencyCell"
105
+ }
106
+ ];
107
+
108
+ // src/renderers/form-renderers.ts
109
+ import { PRIORITY as PRIORITY2 } from "@zodal/ui";
110
+ function textInput({ field, config }) {
111
+ return el(
112
+ "div",
113
+ { class: "zodal-field" },
114
+ el("label", { for: config.name, class: "zodal-label" }, config.label),
115
+ el("input", {
116
+ id: config.name,
117
+ type: "text",
118
+ value: String(field.value ?? ""),
119
+ class: "zodal-input",
120
+ placeholder: config.placeholder,
121
+ required: config.required,
122
+ disabled: config.disabled,
123
+ onInput: (e) => field.onChange(e.target.value)
124
+ }),
125
+ config.helpText ? el("p", { class: "zodal-help" }, config.helpText) : null
126
+ );
127
+ }
128
+ function numberInput({ field, config }) {
129
+ return el(
130
+ "div",
131
+ { class: "zodal-field" },
132
+ el("label", { for: config.name, class: "zodal-label" }, config.label),
133
+ el("input", {
134
+ id: config.name,
135
+ type: "number",
136
+ value: field.value ?? "",
137
+ class: "zodal-input",
138
+ required: config.required,
139
+ disabled: config.disabled,
140
+ onInput: (e) => field.onChange(Number(e.target.value))
141
+ })
142
+ );
143
+ }
144
+ function checkboxInput({ field, config }) {
145
+ return el(
146
+ "div",
147
+ { class: "zodal-field" },
148
+ el(
149
+ "label",
150
+ { class: "zodal-label" },
151
+ el("input", {
152
+ type: "checkbox",
153
+ checked: Boolean(field.value),
154
+ class: "zodal-input",
155
+ disabled: config.disabled,
156
+ onChange: (e) => field.onChange(e.target.checked)
157
+ }),
158
+ " ",
159
+ config.label
160
+ )
161
+ );
162
+ }
163
+ function selectInput({ field, config }) {
164
+ const select = el(
165
+ "select",
166
+ {
167
+ id: config.name,
168
+ class: "zodal-input",
169
+ required: config.required,
170
+ disabled: config.disabled,
171
+ onChange: (e) => field.onChange(e.target.value)
172
+ },
173
+ el("option", { value: "" }, `Select ${config.label}...`),
174
+ ...(config.options ?? []).map(
175
+ (opt) => el("option", { value: opt.value }, opt.label)
176
+ )
177
+ );
178
+ select.value = String(field.value ?? "");
179
+ return el(
180
+ "div",
181
+ { class: "zodal-field" },
182
+ el("label", { for: config.name, class: "zodal-label" }, config.label),
183
+ select
184
+ );
185
+ }
186
+ function dateInput({ field, config }) {
187
+ const dateValue = field.value instanceof Date ? field.value.toISOString().split("T")[0] : String(field.value ?? "");
188
+ return el(
189
+ "div",
190
+ { class: "zodal-field" },
191
+ el("label", { for: config.name, class: "zodal-label" }, config.label),
192
+ el("input", {
193
+ id: config.name,
194
+ type: "date",
195
+ value: dateValue,
196
+ class: "zodal-input",
197
+ required: config.required,
198
+ disabled: config.disabled,
199
+ onInput: (e) => field.onChange(new Date(e.target.value))
200
+ })
201
+ );
202
+ }
203
+ var formRenderers = [
204
+ {
205
+ tester: (_, ctx) => ctx.mode === "form" ? PRIORITY2.FALLBACK : -1,
206
+ renderer: textInput,
207
+ name: "TextInput (fallback)"
208
+ },
209
+ {
210
+ tester: (field, ctx) => ctx.mode === "form" && field.zodType === "string" ? PRIORITY2.DEFAULT : -1,
211
+ renderer: textInput,
212
+ name: "TextInput"
213
+ },
214
+ {
215
+ tester: (field, ctx) => ctx.mode === "form" && ["number", "int", "float"].includes(field.zodType) ? PRIORITY2.DEFAULT : -1,
216
+ renderer: numberInput,
217
+ name: "NumberInput"
218
+ },
219
+ {
220
+ tester: (field, ctx) => ctx.mode === "form" && field.zodType === "boolean" ? PRIORITY2.DEFAULT : -1,
221
+ renderer: checkboxInput,
222
+ name: "CheckboxInput"
223
+ },
224
+ {
225
+ tester: (field, ctx) => ctx.mode === "form" && field.zodType === "enum" ? PRIORITY2.DEFAULT : -1,
226
+ renderer: selectInput,
227
+ name: "SelectInput"
228
+ },
229
+ {
230
+ tester: (field, ctx) => ctx.mode === "form" && field.zodType === "date" ? PRIORITY2.DEFAULT : -1,
231
+ renderer: dateInput,
232
+ name: "DateInput"
233
+ }
234
+ ];
235
+
236
+ // src/renderers/filter-renderers.ts
237
+ import { PRIORITY as PRIORITY3 } from "@zodal/ui";
238
+ function textFilter({ field, config }) {
239
+ return el("input", {
240
+ type: "text",
241
+ value: String(field.value ?? ""),
242
+ placeholder: `Filter ${config.label}...`,
243
+ class: "zodal-filter zodal-filter-text",
244
+ onInput: (e) => field.onChange(e.target.value)
245
+ });
246
+ }
247
+ function selectFilter({ field, config }) {
248
+ const select = el(
249
+ "select",
250
+ {
251
+ class: "zodal-filter zodal-filter-select",
252
+ onChange: (e) => field.onChange(e.target.value || void 0)
253
+ },
254
+ el("option", { value: "" }, `All ${config.label}`),
255
+ ...(config.options ?? []).map(
256
+ (opt) => el("option", { value: opt.value }, opt.label)
257
+ )
258
+ );
259
+ select.value = String(field.value ?? "");
260
+ return select;
261
+ }
262
+ function rangeFilter({ field, config }) {
263
+ const [min, max] = Array.isArray(field.value) ? field.value : [void 0, void 0];
264
+ return el(
265
+ "div",
266
+ { style: { display: "flex", gap: "4px" }, class: "zodal-filter zodal-filter-range" },
267
+ el("input", {
268
+ type: "number",
269
+ value: min ?? "",
270
+ placeholder: "Min",
271
+ min: config.bounds?.min,
272
+ max: config.bounds?.max,
273
+ class: "zodal-input",
274
+ onInput: (e) => {
275
+ const v = e.target.value;
276
+ field.onChange([v ? Number(v) : void 0, max]);
277
+ }
278
+ }),
279
+ el("input", {
280
+ type: "number",
281
+ value: max ?? "",
282
+ placeholder: "Max",
283
+ min: config.bounds?.min,
284
+ max: config.bounds?.max,
285
+ class: "zodal-input",
286
+ onInput: (e) => {
287
+ const v = e.target.value;
288
+ field.onChange([min, v ? Number(v) : void 0]);
289
+ }
290
+ })
291
+ );
292
+ }
293
+ function booleanFilter({ field, config }) {
294
+ const select = el(
295
+ "select",
296
+ {
297
+ class: "zodal-filter zodal-filter-boolean",
298
+ onChange: (e) => {
299
+ const v = e.target.value;
300
+ field.onChange(v === "true" ? true : v === "false" ? false : void 0);
301
+ }
302
+ },
303
+ el("option", { value: "" }, "All"),
304
+ el("option", { value: "true" }, "Yes"),
305
+ el("option", { value: "false" }, "No")
306
+ );
307
+ select.value = field.value === true ? "true" : field.value === false ? "false" : "";
308
+ return select;
309
+ }
310
+ var filterRenderers = [
311
+ {
312
+ tester: (_, ctx) => ctx.mode === "filter" ? PRIORITY3.FALLBACK : -1,
313
+ renderer: textFilter,
314
+ name: "TextFilter (fallback)"
315
+ },
316
+ {
317
+ tester: (field, ctx) => ctx.mode === "filter" && field.filterable === "search" ? PRIORITY3.DEFAULT : -1,
318
+ renderer: textFilter,
319
+ name: "TextFilter"
320
+ },
321
+ {
322
+ tester: (field, ctx) => ctx.mode === "filter" && field.filterable === "select" ? PRIORITY3.DEFAULT : -1,
323
+ renderer: selectFilter,
324
+ name: "SelectFilter"
325
+ },
326
+ {
327
+ tester: (field, ctx) => ctx.mode === "filter" && field.filterable === "multiSelect" ? PRIORITY3.DEFAULT : -1,
328
+ renderer: selectFilter,
329
+ name: "MultiSelectFilter"
330
+ },
331
+ {
332
+ tester: (field, ctx) => ctx.mode === "filter" && field.filterable === "range" ? PRIORITY3.DEFAULT : -1,
333
+ renderer: rangeFilter,
334
+ name: "RangeFilter"
335
+ },
336
+ {
337
+ tester: (field, ctx) => ctx.mode === "filter" && field.zodType === "boolean" ? PRIORITY3.DEFAULT : -1,
338
+ renderer: booleanFilter,
339
+ name: "BooleanFilter"
340
+ }
341
+ ];
342
+
343
+ // src/registry.ts
344
+ function createVanillaRegistry() {
345
+ const registry = createRendererRegistry();
346
+ const allRenderers = [
347
+ ...cellRenderers,
348
+ ...formRenderers,
349
+ ...filterRenderers
350
+ ];
351
+ for (const entry of allRenderers) {
352
+ registry.register(entry);
353
+ }
354
+ return registry;
355
+ }
356
+ export {
357
+ cellRenderers,
358
+ createVanillaRegistry,
359
+ filterRenderers,
360
+ formRenderers
361
+ };
362
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/registry.ts","../src/renderers/cell-renderers.ts","../src/dom.ts","../src/renderers/form-renderers.ts","../src/renderers/filter-renderers.ts"],"sourcesContent":["import { createRendererRegistry } from '@zodal/ui';\nimport type { RendererEntry } from '@zodal/ui';\nimport { cellRenderers } from './renderers/cell-renderers.js';\nimport { formRenderers } from './renderers/form-renderers.js';\nimport { filterRenderers } from './renderers/filter-renderers.js';\n\n/** A vanilla renderer function: takes props, returns an HTMLElement. */\nexport type VanillaRenderer = (props: any) => HTMLElement;\n\n/**\n * Create a RendererRegistry pre-loaded with all vanilla DOM renderers.\n */\nexport function createVanillaRegistry() {\n const registry = createRendererRegistry<VanillaRenderer>();\n const allRenderers: RendererEntry<VanillaRenderer>[] = [\n ...cellRenderers,\n ...formRenderers,\n ...filterRenderers,\n ];\n for (const entry of allRenderers) {\n registry.register(entry);\n }\n return registry;\n}\n","/**\n * Cell renderers for table display.\n * Plain DOM elements — no framework dependency.\n */\n\nimport { PRIORITY } from '@zodal/ui';\nimport type { RendererEntry } from '@zodal/ui';\nimport { el } from '../dom.js';\nimport type { CellProps } from '../types.js';\n\nfunction textCell({ value, config }: CellProps): HTMLElement {\n const str = String(value ?? '');\n const truncate = config.meta.truncate;\n if (truncate && str.length > truncate) {\n return el('span', { title: str, class: 'zodal-cell zodal-cell-text' }, str.slice(0, truncate) + '...');\n }\n return el('span', { class: 'zodal-cell zodal-cell-text' }, str);\n}\n\nfunction numberCell({ value, config }: CellProps): HTMLElement {\n if (value == null) return el('span', { class: 'zodal-cell zodal-muted' }, '\\u2014');\n const formatted = config.meta.displayFormat === 'currency'\n ? new Intl.NumberFormat('en-US', { style: 'currency', currency: 'USD' }).format(value as number)\n : String(value);\n return el('span', { class: 'zodal-cell zodal-cell-number' }, formatted);\n}\n\nfunction booleanCell({ value }: CellProps): HTMLElement {\n return el('span', { class: 'zodal-cell zodal-cell-boolean' }, value ? '\\u2713' : '\\u2717');\n}\n\nfunction dateCell({ value }: CellProps): HTMLElement {\n if (value == null) return el('span', { class: 'zodal-cell zodal-muted' }, '\\u2014');\n const date = value instanceof Date ? value : new Date(value as string);\n return el('span', { class: 'zodal-cell zodal-cell-date' }, date.toLocaleDateString());\n}\n\nfunction badgeCell({ value, config }: CellProps): HTMLElement {\n const str = String(value ?? '');\n const variant = config.meta.badge?.[str] ?? 'default';\n return el('span', {\n class: 'zodal-cell zodal-badge',\n 'data-variant': variant,\n }, str);\n}\n\nfunction arrayCell({ value }: CellProps): HTMLElement {\n if (!Array.isArray(value)) return el('span', { class: 'zodal-cell zodal-muted' }, '\\u2014');\n return el('span', { class: 'zodal-cell zodal-cell-array' }, value.join(', '));\n}\n\nexport type CellRenderer = (props: CellProps) => HTMLElement;\n\nexport const cellRenderers: RendererEntry<CellRenderer>[] = [\n {\n tester: () => PRIORITY.FALLBACK,\n renderer: textCell,\n name: 'TextCell (fallback)',\n },\n {\n tester: (field, ctx) => ctx.mode === 'cell' && field.zodType === 'string' ? PRIORITY.DEFAULT : -1,\n renderer: textCell,\n name: 'TextCell',\n },\n {\n tester: (field, ctx) => ctx.mode === 'cell' && ['number', 'int', 'float'].includes(field.zodType) ? PRIORITY.DEFAULT : -1,\n renderer: numberCell,\n name: 'NumberCell',\n },\n {\n tester: (field, ctx) => ctx.mode === 'cell' && field.zodType === 'boolean' ? PRIORITY.DEFAULT : -1,\n renderer: booleanCell,\n name: 'BooleanCell',\n },\n {\n tester: (field, ctx) => ctx.mode === 'cell' && field.zodType === 'date' ? PRIORITY.DEFAULT : -1,\n renderer: dateCell,\n name: 'DateCell',\n },\n {\n tester: (field, ctx) => ctx.mode === 'cell' && field.zodType === 'enum' ? PRIORITY.DEFAULT : -1,\n renderer: badgeCell,\n name: 'BadgeCell',\n },\n {\n tester: (field, ctx) => ctx.mode === 'cell' && field.zodType === 'array' ? PRIORITY.DEFAULT : -1,\n renderer: arrayCell,\n name: 'ArrayCell',\n },\n {\n tester: (field, ctx) => ctx.mode === 'cell' && (field as any).displayFormat === 'currency' ? PRIORITY.LIBRARY : -1,\n renderer: numberCell,\n name: 'CurrencyCell',\n },\n];\n","/**\n * Internal DOM element factory.\n * Replaces React.createElement with native DOM API.\n */\nexport function el(\n tag: string,\n attrs?: Record<string, any> | null,\n ...children: (Node | string | null | undefined)[]\n): HTMLElement {\n const element = document.createElement(tag);\n if (attrs) {\n for (const [key, value] of Object.entries(attrs)) {\n if (key.startsWith('on') && typeof value === 'function') {\n const event = key.slice(2).toLowerCase();\n element.addEventListener(event, value);\n } else if (key === 'style' && typeof value === 'object') {\n Object.assign(element.style, value);\n } else if (value !== undefined && value !== null && value !== false) {\n element.setAttribute(key, String(value));\n }\n }\n }\n for (const child of children) {\n if (child == null) continue;\n element.appendChild(\n typeof child === 'string' ? document.createTextNode(child) : child,\n );\n }\n return element;\n}\n","/**\n * Form field renderers.\n * Plain DOM elements with native event listeners.\n */\n\nimport { PRIORITY } from '@zodal/ui';\nimport type { RendererEntry } from '@zodal/ui';\nimport { el } from '../dom.js';\nimport type { FormFieldProps } from '../types.js';\n\nfunction textInput({ field, config }: FormFieldProps): HTMLElement {\n return el('div', { class: 'zodal-field' },\n el('label', { for: config.name, class: 'zodal-label' }, config.label),\n el('input', {\n id: config.name,\n type: 'text',\n value: String(field.value ?? ''),\n class: 'zodal-input',\n placeholder: config.placeholder,\n required: config.required,\n disabled: config.disabled,\n onInput: (e: Event) => field.onChange((e.target as HTMLInputElement).value),\n }),\n config.helpText ? el('p', { class: 'zodal-help' }, config.helpText) : null,\n );\n}\n\nfunction numberInput({ field, config }: FormFieldProps): HTMLElement {\n return el('div', { class: 'zodal-field' },\n el('label', { for: config.name, class: 'zodal-label' }, config.label),\n el('input', {\n id: config.name,\n type: 'number',\n value: field.value ?? '',\n class: 'zodal-input',\n required: config.required,\n disabled: config.disabled,\n onInput: (e: Event) => field.onChange(Number((e.target as HTMLInputElement).value)),\n }),\n );\n}\n\nfunction checkboxInput({ field, config }: FormFieldProps): HTMLElement {\n return el('div', { class: 'zodal-field' },\n el('label', { class: 'zodal-label' },\n el('input', {\n type: 'checkbox',\n checked: Boolean(field.value),\n class: 'zodal-input',\n disabled: config.disabled,\n onChange: (e: Event) => field.onChange((e.target as HTMLInputElement).checked),\n }),\n ' ',\n config.label,\n ),\n );\n}\n\nfunction selectInput({ field, config }: FormFieldProps): HTMLElement {\n const select = el('select', {\n id: config.name,\n class: 'zodal-input',\n required: config.required,\n disabled: config.disabled,\n onChange: (e: Event) => field.onChange((e.target as HTMLSelectElement).value),\n },\n el('option', { value: '' }, `Select ${config.label}...`),\n ...(config.options ?? []).map(opt =>\n el('option', { value: opt.value }, opt.label)\n ),\n );\n // Set selected value after creation\n (select as HTMLSelectElement).value = String(field.value ?? '');\n\n return el('div', { class: 'zodal-field' },\n el('label', { for: config.name, class: 'zodal-label' }, config.label),\n select,\n );\n}\n\nfunction dateInput({ field, config }: FormFieldProps): HTMLElement {\n const dateValue = field.value instanceof Date\n ? (field.value as Date).toISOString().split('T')[0]\n : String(field.value ?? '');\n\n return el('div', { class: 'zodal-field' },\n el('label', { for: config.name, class: 'zodal-label' }, config.label),\n el('input', {\n id: config.name,\n type: 'date',\n value: dateValue,\n class: 'zodal-input',\n required: config.required,\n disabled: config.disabled,\n onInput: (e: Event) => field.onChange(new Date((e.target as HTMLInputElement).value)),\n }),\n );\n}\n\nexport type FormRenderer = (props: FormFieldProps) => HTMLElement;\n\nexport const formRenderers: RendererEntry<FormRenderer>[] = [\n {\n tester: (_, ctx) => ctx.mode === 'form' ? PRIORITY.FALLBACK : -1,\n renderer: textInput,\n name: 'TextInput (fallback)',\n },\n {\n tester: (field, ctx) => ctx.mode === 'form' && field.zodType === 'string' ? PRIORITY.DEFAULT : -1,\n renderer: textInput,\n name: 'TextInput',\n },\n {\n tester: (field, ctx) => ctx.mode === 'form' && ['number', 'int', 'float'].includes(field.zodType) ? PRIORITY.DEFAULT : -1,\n renderer: numberInput,\n name: 'NumberInput',\n },\n {\n tester: (field, ctx) => ctx.mode === 'form' && field.zodType === 'boolean' ? PRIORITY.DEFAULT : -1,\n renderer: checkboxInput,\n name: 'CheckboxInput',\n },\n {\n tester: (field, ctx) => ctx.mode === 'form' && field.zodType === 'enum' ? PRIORITY.DEFAULT : -1,\n renderer: selectInput,\n name: 'SelectInput',\n },\n {\n tester: (field, ctx) => ctx.mode === 'form' && field.zodType === 'date' ? PRIORITY.DEFAULT : -1,\n renderer: dateInput,\n name: 'DateInput',\n },\n];\n","/**\n * Filter widget renderers.\n * Plain DOM elements with native event listeners.\n */\n\nimport { PRIORITY } from '@zodal/ui';\nimport type { RendererEntry } from '@zodal/ui';\nimport { el } from '../dom.js';\nimport type { FilterFieldProps } from '../types.js';\n\nfunction textFilter({ field, config }: FilterFieldProps): HTMLElement {\n return el('input', {\n type: 'text',\n value: String(field.value ?? ''),\n placeholder: `Filter ${config.label}...`,\n class: 'zodal-filter zodal-filter-text',\n onInput: (e: Event) => field.onChange((e.target as HTMLInputElement).value),\n });\n}\n\nfunction selectFilter({ field, config }: FilterFieldProps): HTMLElement {\n const select = el('select', {\n class: 'zodal-filter zodal-filter-select',\n onChange: (e: Event) => field.onChange((e.target as HTMLSelectElement).value || undefined),\n },\n el('option', { value: '' }, `All ${config.label}`),\n ...(config.options ?? []).map(opt =>\n el('option', { value: opt.value }, opt.label)\n ),\n );\n (select as HTMLSelectElement).value = String(field.value ?? '');\n return select;\n}\n\nfunction rangeFilter({ field, config }: FilterFieldProps): HTMLElement {\n const [min, max] = Array.isArray(field.value) ? field.value : [undefined, undefined];\n return el('div', { style: { display: 'flex', gap: '4px' }, class: 'zodal-filter zodal-filter-range' },\n el('input', {\n type: 'number',\n value: min ?? '',\n placeholder: 'Min',\n min: config.bounds?.min,\n max: config.bounds?.max,\n class: 'zodal-input',\n onInput: (e: Event) => {\n const v = (e.target as HTMLInputElement).value;\n field.onChange([v ? Number(v) : undefined, max]);\n },\n }),\n el('input', {\n type: 'number',\n value: max ?? '',\n placeholder: 'Max',\n min: config.bounds?.min,\n max: config.bounds?.max,\n class: 'zodal-input',\n onInput: (e: Event) => {\n const v = (e.target as HTMLInputElement).value;\n field.onChange([min, v ? Number(v) : undefined]);\n },\n }),\n );\n}\n\nfunction booleanFilter({ field, config }: FilterFieldProps): HTMLElement {\n const select = el('select', {\n class: 'zodal-filter zodal-filter-boolean',\n onChange: (e: Event) => {\n const v = (e.target as HTMLSelectElement).value;\n field.onChange(v === 'true' ? true : v === 'false' ? false : undefined);\n },\n },\n el('option', { value: '' }, 'All'),\n el('option', { value: 'true' }, 'Yes'),\n el('option', { value: 'false' }, 'No'),\n );\n // Set initial value\n (select as HTMLSelectElement).value = field.value === true ? 'true' : field.value === false ? 'false' : '';\n return select;\n}\n\nexport type FilterRenderer = (props: FilterFieldProps) => HTMLElement;\n\nexport const filterRenderers: RendererEntry<FilterRenderer>[] = [\n {\n tester: (_, ctx) => ctx.mode === 'filter' ? PRIORITY.FALLBACK : -1,\n renderer: textFilter,\n name: 'TextFilter (fallback)',\n },\n {\n tester: (field, ctx) => ctx.mode === 'filter' && (field as any).filterable === 'search' ? PRIORITY.DEFAULT : -1,\n renderer: textFilter,\n name: 'TextFilter',\n },\n {\n tester: (field, ctx) => ctx.mode === 'filter' && (field as any).filterable === 'select' ? PRIORITY.DEFAULT : -1,\n renderer: selectFilter,\n name: 'SelectFilter',\n },\n {\n tester: (field, ctx) => ctx.mode === 'filter' && (field as any).filterable === 'multiSelect' ? PRIORITY.DEFAULT : -1,\n renderer: selectFilter,\n name: 'MultiSelectFilter',\n },\n {\n tester: (field, ctx) => ctx.mode === 'filter' && (field as any).filterable === 'range' ? PRIORITY.DEFAULT : -1,\n renderer: rangeFilter,\n name: 'RangeFilter',\n },\n {\n tester: (field, ctx) => ctx.mode === 'filter' && field.zodType === 'boolean' ? PRIORITY.DEFAULT : -1,\n renderer: booleanFilter,\n name: 'BooleanFilter',\n },\n];\n"],"mappings":"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","names":["PRIORITY","PRIORITY","PRIORITY","PRIORITY"]}
package/package.json ADDED
@@ -0,0 +1,52 @@
1
+ {
2
+ "name": "@zodal/ui-vanilla",
3
+ "version": "0.1.0",
4
+ "description": "zodal UI renderer package for vanilla HTML/JS DOM elements",
5
+ "type": "module",
6
+ "main": "dist/index.cjs",
7
+ "module": "dist/index.js",
8
+ "types": "dist/index.d.ts",
9
+ "exports": {
10
+ ".": {
11
+ "types": "./dist/index.d.ts",
12
+ "import": "./dist/index.js",
13
+ "require": "./dist/index.cjs"
14
+ }
15
+ },
16
+ "publishConfig": {
17
+ "access": "public"
18
+ },
19
+ "files": [
20
+ "dist"
21
+ ],
22
+ "peerDependencies": {
23
+ "@zodal/core": "^0.1.0",
24
+ "@zodal/ui": "^0.1.0"
25
+ },
26
+ "devDependencies": {
27
+ "@zodal/core": "^0.1.0",
28
+ "@zodal/ui": "^0.1.0",
29
+ "jsdom": "^26.0.0",
30
+ "tsup": "^8.0.0",
31
+ "typescript": "^5.7.0",
32
+ "vitest": "^3.0.0"
33
+ },
34
+ "license": "MIT",
35
+ "repository": {
36
+ "type": "git",
37
+ "url": "https://github.com/i2mint/zodal-ui-vanilla.git"
38
+ },
39
+ "keywords": [
40
+ "zodal",
41
+ "renderer",
42
+ "vanilla",
43
+ "ui",
44
+ "dom",
45
+ "html"
46
+ ],
47
+ "scripts": {
48
+ "build": "tsup",
49
+ "test": "vitest run",
50
+ "typecheck": "tsc --noEmit"
51
+ }
52
+ }