@nanisoft/prism-ui 0.16.1 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (170) hide show
  1. package/dist/.tsbuildinfo +1 -1
  2. package/dist/blocks/activity-feed-01/activity-feed-01.d.ts +120 -190
  3. package/dist/blocks/activity-feed-01/activity-feed-01.d.ts.map +1 -1
  4. package/dist/blocks/activity-feed-01/activity-feed-01.js +107 -97
  5. package/dist/blocks/activity-feed-01/index.d.ts +1 -1
  6. package/dist/blocks/activity-feed-01/index.d.ts.map +1 -1
  7. package/dist/blocks/auth-form-01/auth-form.d.ts +86 -53
  8. package/dist/blocks/auth-form-01/auth-form.d.ts.map +1 -1
  9. package/dist/blocks/auth-form-01/auth-form.js +95 -31
  10. package/dist/blocks/auth-form-01/index.d.ts +1 -1
  11. package/dist/blocks/auth-form-01/index.d.ts.map +1 -1
  12. package/dist/blocks/calendar-01/calendar.d.ts +28 -0
  13. package/dist/blocks/calendar-01/calendar.d.ts.map +1 -1
  14. package/dist/blocks/calendar-01/calendar.js +15 -1
  15. package/dist/blocks/card-index-01/card-index.d.ts +225 -0
  16. package/dist/blocks/card-index-01/card-index.d.ts.map +1 -0
  17. package/dist/blocks/card-index-01/card-index.js +154 -0
  18. package/dist/blocks/card-index-01/index.d.ts +3 -0
  19. package/dist/blocks/card-index-01/index.d.ts.map +1 -0
  20. package/dist/blocks/card-index-01/index.js +1 -0
  21. package/dist/blocks/chart-card-01/chart-card-01.d.ts +23 -21
  22. package/dist/blocks/chart-card-01/chart-card-01.d.ts.map +1 -1
  23. package/dist/blocks/chart-card-01/chart-card-01.js +46 -1
  24. package/dist/blocks/chart-card-01/index.d.ts +1 -1
  25. package/dist/blocks/chart-card-01/index.d.ts.map +1 -1
  26. package/dist/blocks/chart-group-01/chart-group-01.d.ts +3 -3
  27. package/dist/blocks/chart-group-01/chart-group-01.d.ts.map +1 -1
  28. package/dist/blocks/contact-01/contact.d.ts +30 -82
  29. package/dist/blocks/contact-01/contact.d.ts.map +1 -1
  30. package/dist/blocks/contact-01/contact.js +59 -30
  31. package/dist/blocks/contact-01/index.d.ts +1 -1
  32. package/dist/blocks/contact-01/index.d.ts.map +1 -1
  33. package/dist/blocks/dashboard-01/dashboard-01.d.ts +26 -71
  34. package/dist/blocks/dashboard-01/dashboard-01.d.ts.map +1 -1
  35. package/dist/blocks/dashboard-01/dashboard-01.js +34 -23
  36. package/dist/blocks/dashboard-01/index.d.ts +1 -1
  37. package/dist/blocks/dashboard-01/index.d.ts.map +1 -1
  38. package/dist/blocks/data-table-01/data-table.d.ts +276 -59
  39. package/dist/blocks/data-table-01/data-table.d.ts.map +1 -1
  40. package/dist/blocks/data-table-01/data-table.js +217 -35
  41. package/dist/blocks/data-table-01/index.d.ts +1 -1
  42. package/dist/blocks/data-table-01/index.d.ts.map +1 -1
  43. package/dist/blocks/directory-01/directory-01.d.ts +23 -2
  44. package/dist/blocks/directory-01/directory-01.d.ts.map +1 -1
  45. package/dist/blocks/directory-01/directory-01.js +3 -3
  46. package/dist/blocks/empty-state-01/empty-state.d.ts +60 -21
  47. package/dist/blocks/empty-state-01/empty-state.d.ts.map +1 -1
  48. package/dist/blocks/empty-state-01/empty-state.js +52 -17
  49. package/dist/blocks/index-detail-01/index-detail.d.ts +85 -0
  50. package/dist/blocks/index-detail-01/index-detail.d.ts.map +1 -0
  51. package/dist/blocks/index-detail-01/index-detail.js +58 -0
  52. package/dist/blocks/index-detail-01/index.d.ts +3 -0
  53. package/dist/blocks/index-detail-01/index.d.ts.map +1 -0
  54. package/dist/blocks/index-detail-01/index.js +1 -0
  55. package/dist/blocks/index.d.ts +20 -8
  56. package/dist/blocks/index.d.ts.map +1 -1
  57. package/dist/blocks/index.js +7 -0
  58. package/dist/blocks/issue-detail-01/issue-detail.d.ts +18 -0
  59. package/dist/blocks/issue-detail-01/issue-detail.d.ts.map +1 -1
  60. package/dist/blocks/issue-detail-01/issue-detail.js +18 -0
  61. package/dist/blocks/nothing-chosen-01/index.d.ts +3 -0
  62. package/dist/blocks/nothing-chosen-01/index.d.ts.map +1 -0
  63. package/dist/blocks/nothing-chosen-01/index.js +1 -0
  64. package/dist/blocks/nothing-chosen-01/nothing-chosen.d.ts +119 -0
  65. package/dist/blocks/nothing-chosen-01/nothing-chosen.d.ts.map +1 -0
  66. package/dist/blocks/nothing-chosen-01/nothing-chosen.js +79 -0
  67. package/dist/blocks/project-dashboard-01/index.d.ts +1 -1
  68. package/dist/blocks/project-dashboard-01/index.d.ts.map +1 -1
  69. package/dist/blocks/project-dashboard-01/project-dashboard.d.ts +21 -27
  70. package/dist/blocks/project-dashboard-01/project-dashboard.d.ts.map +1 -1
  71. package/dist/blocks/project-dashboard-01/project-dashboard.js +45 -5
  72. package/dist/blocks/provisioning-01/index.d.ts +1 -1
  73. package/dist/blocks/provisioning-01/index.d.ts.map +1 -1
  74. package/dist/blocks/provisioning-01/provisioning.d.ts +9 -97
  75. package/dist/blocks/provisioning-01/provisioning.d.ts.map +1 -1
  76. package/dist/blocks/provisioning-01/provisioning.js +26 -13
  77. package/dist/blocks/record-detail-01/index.d.ts +3 -0
  78. package/dist/blocks/record-detail-01/index.d.ts.map +1 -0
  79. package/dist/blocks/record-detail-01/index.js +1 -0
  80. package/dist/blocks/record-detail-01/record-detail.d.ts +239 -0
  81. package/dist/blocks/record-detail-01/record-detail.d.ts.map +1 -0
  82. package/dist/blocks/record-detail-01/record-detail.js +150 -0
  83. package/dist/blocks/record-form-01/index.d.ts +3 -0
  84. package/dist/blocks/record-form-01/index.d.ts.map +1 -0
  85. package/dist/blocks/record-form-01/index.js +1 -0
  86. package/dist/blocks/record-form-01/record-form.d.ts +148 -0
  87. package/dist/blocks/record-form-01/record-form.d.ts.map +1 -0
  88. package/dist/blocks/record-form-01/record-form.js +107 -0
  89. package/dist/blocks/record-grid-01/index.d.ts +3 -0
  90. package/dist/blocks/record-grid-01/index.d.ts.map +1 -0
  91. package/dist/blocks/record-grid-01/index.js +1 -0
  92. package/dist/blocks/record-grid-01/record-grid.d.ts +145 -0
  93. package/dist/blocks/record-grid-01/record-grid.d.ts.map +1 -0
  94. package/dist/blocks/record-grid-01/record-grid.js +114 -0
  95. package/dist/blocks/record-wizard-01/index.d.ts +3 -0
  96. package/dist/blocks/record-wizard-01/index.d.ts.map +1 -0
  97. package/dist/blocks/record-wizard-01/index.js +1 -0
  98. package/dist/blocks/record-wizard-01/record-wizard.d.ts +152 -0
  99. package/dist/blocks/record-wizard-01/record-wizard.d.ts.map +1 -0
  100. package/dist/blocks/record-wizard-01/record-wizard.js +144 -0
  101. package/dist/blocks/settings-members-01/settings-members.d.ts +2 -1
  102. package/dist/blocks/settings-members-01/settings-members.d.ts.map +1 -1
  103. package/dist/blocks/settings-panel-01/index.d.ts +1 -1
  104. package/dist/blocks/settings-panel-01/index.d.ts.map +1 -1
  105. package/dist/blocks/settings-panel-01/settings-panel.d.ts +165 -67
  106. package/dist/blocks/settings-panel-01/settings-panel.d.ts.map +1 -1
  107. package/dist/blocks/settings-panel-01/settings-panel.js +92 -33
  108. package/dist/blocks/signup-01/index.d.ts +1 -1
  109. package/dist/blocks/signup-01/index.d.ts.map +1 -1
  110. package/dist/blocks/signup-01/signup-01.d.ts +10 -84
  111. package/dist/blocks/signup-01/signup-01.d.ts.map +1 -1
  112. package/dist/blocks/signup-01/signup-01.js +41 -23
  113. package/dist/blocks/stats-01/index.d.ts +5 -5
  114. package/dist/blocks/stats-01/index.d.ts.map +1 -1
  115. package/dist/blocks/stats-01/index.js +4 -4
  116. package/dist/blocks/stats-01/stats.d.ts +49 -14
  117. package/dist/blocks/stats-01/stats.d.ts.map +1 -1
  118. package/dist/blocks/stats-01/stats.js +65 -15
  119. package/dist/blocks/trend-01/index.d.ts +1 -1
  120. package/dist/blocks/trend-01/index.d.ts.map +1 -1
  121. package/dist/blocks/trend-01/trend.d.ts +26 -73
  122. package/dist/blocks/trend-01/trend.d.ts.map +1 -1
  123. package/dist/blocks/trend-01/trend.js +47 -30
  124. package/dist/catalog.d.ts.map +1 -1
  125. package/dist/catalog.js +93 -3
  126. package/dist/components/ui/metric.d.ts +4 -2
  127. package/dist/components/ui/metric.d.ts.map +1 -1
  128. package/dist/index.d.ts +10 -0
  129. package/dist/index.d.ts.map +1 -1
  130. package/dist/index.js +6 -0
  131. package/dist/lib/field-render.d.ts +107 -0
  132. package/dist/lib/field-render.d.ts.map +1 -0
  133. package/dist/lib/field-render.js +251 -0
  134. package/dist/lib/spec.d.ts +609 -0
  135. package/dist/lib/spec.d.ts.map +1 -0
  136. package/dist/lib/spec.js +1 -0
  137. package/dist/live/index.d.ts +2 -0
  138. package/dist/live/index.d.ts.map +1 -1
  139. package/dist/live/index.js +6 -0
  140. package/dist/live/message-thread-01/index.d.ts +3 -0
  141. package/dist/live/message-thread-01/index.d.ts.map +1 -0
  142. package/dist/live/message-thread-01/index.js +1 -0
  143. package/dist/live/message-thread-01/message-thread.d.ts +282 -0
  144. package/dist/live/message-thread-01/message-thread.d.ts.map +1 -0
  145. package/dist/live/message-thread-01/message-thread.js +221 -0
  146. package/dist/live/run-stream-01/run-stream.d.ts +2 -1
  147. package/dist/live/run-stream-01/run-stream.d.ts.map +1 -1
  148. package/dist/live/run-stream-01/run-stream.js +1 -7
  149. package/dist/live/status.d.ts +27 -0
  150. package/dist/live/status.d.ts.map +1 -0
  151. package/dist/live/status.js +15 -0
  152. package/dist/live/tool-call-row.d.ts +26 -0
  153. package/dist/live/tool-call-row.d.ts.map +1 -0
  154. package/dist/live/tool-call-row.js +60 -0
  155. package/dist/live/tool-ledger-01/tool-ledger.d.ts.map +1 -1
  156. package/dist/live/tool-ledger-01/tool-ledger.js +2 -42
  157. package/dist/pages/contact-page/index.d.ts +7 -7
  158. package/dist/pages/contact-page/index.d.ts.map +1 -1
  159. package/dist/pages/contact-page/index.js +17 -5
  160. package/dist/pages/document-page/document-page.d.ts +146 -0
  161. package/dist/pages/document-page/document-page.d.ts.map +1 -0
  162. package/dist/pages/document-page/document-page.js +80 -0
  163. package/dist/pages/document-page/index.d.ts +3 -0
  164. package/dist/pages/document-page/index.d.ts.map +1 -0
  165. package/dist/pages/document-page/index.js +1 -0
  166. package/dist/pages/index.d.ts +2 -0
  167. package/dist/pages/index.d.ts.map +1 -1
  168. package/dist/pages/index.js +6 -0
  169. package/dist/styles.css +35 -3
  170. package/package.json +7 -2
@@ -0,0 +1,251 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { Calendar } from '../components/ui/calendar.js';
3
+ import { Checkbox } from '../components/ui/checkbox.js';
4
+ import { ChoiceCard } from '../components/ui/choice-card.js';
5
+ import { Combobox } from '../components/ui/combobox.js';
6
+ import { DatePicker } from '../components/ui/date-picker.js';
7
+ import { Dropzone } from '../components/ui/dropzone.js';
8
+ import { FileUpload } from '../components/ui/file-upload.js';
9
+ import { ImageListField } from '../components/ui/image-list-field.js';
10
+ import { Input } from '../components/ui/input.js';
11
+ import { MoneyField } from '../components/ui/money-field.js';
12
+ import { MultiCombobox } from '../components/ui/multi-combobox.js';
13
+ import { NativeSelect } from '../components/ui/native-select.js';
14
+ import { NumberField } from '../components/ui/number-field.js';
15
+ import { OneTimeCode } from '../components/ui/one-time-code.js';
16
+ import { PasswordField } from '../components/ui/password-field.js';
17
+ import { RadioGroup, RadioGroupItem } from '../components/ui/radio-group.js';
18
+ import { RangeField } from '../components/ui/range-field.js';
19
+ import { RepeatableRows } from '../components/ui/repeatable-rows.js';
20
+ import { SearchField } from '../components/ui/search-field.js';
21
+ import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue, } from '../components/ui/select.js';
22
+ import { Slider } from '../components/ui/slider.js';
23
+ import { Switch } from '../components/ui/switch.js';
24
+ import { Textarea } from '../components/ui/textarea.js';
25
+ import { Toggle } from '../components/ui/toggle.js';
26
+ import { ToggleGroup, ToggleGroupItem } from '../components/ui/toggle-group.js';
27
+ /** The label a Component that requires a `string` name can be given. */
28
+ export function fieldText(field) {
29
+ return typeof field.label === 'string' ? field.label : field.key;
30
+ }
31
+ /** The options on a choice-bearing arm, read without naming the shared shape. */
32
+ function optionsOf(field) {
33
+ const withOptions = field;
34
+ return withOptions.options ?? [];
35
+ }
36
+ /** The options a `Select` draws, as the record it displays values from. */
37
+ function selectItems(field) {
38
+ return Object.fromEntries(optionsOf(field).map((option) => [option.value, option.label]));
39
+ }
40
+ /** The options a `Combobox` and `MultiCombobox` draw, whose label is a string. */
41
+ function comboboxItems(field) {
42
+ return optionsOf(field).map((option) => ({
43
+ value: option.value,
44
+ label: typeof option.label === 'string' ? option.label : option.value,
45
+ }));
46
+ }
47
+ /** A `string | number | boolean` default, when a native control can take one. */
48
+ function inputDefault(value) {
49
+ return typeof value === 'boolean' ? undefined : value;
50
+ }
51
+ /** The same default as a string, for the components that only take one. */
52
+ function stringOf(value) {
53
+ return value === undefined ? undefined : String(value);
54
+ }
55
+ /** A `Date` from a spec default, or `null`. */
56
+ function dateOf(value) {
57
+ if (typeof value === 'string' || typeof value === 'number')
58
+ return new Date(value);
59
+ return null;
60
+ }
61
+ /** A string list from a held value, for the controls that hold a set. */
62
+ function asStringArray(value) {
63
+ return Array.isArray(value) ? value.map((entry) => String(entry)) : [];
64
+ }
65
+ /** A held value as an array, whatever it is. */
66
+ function asArray(value) {
67
+ return Array.isArray(value) ? value : [];
68
+ }
69
+ /** A held value as file rows, for `FileUpload`. */
70
+ function fileRows(value) {
71
+ return asArray(value).map((entry, index) => {
72
+ if (typeof File !== 'undefined' && entry instanceof File) {
73
+ return { id: `${entry.name}-${index}`, name: entry.name, size: entry.size };
74
+ }
75
+ return { id: String(index), name: String(entry), size: 0 };
76
+ });
77
+ }
78
+ /** A held value as image rows, for `ImageListField`. */
79
+ function imageRows(value) {
80
+ return asArray(value).map((entry, index) => ({ id: String(index), name: String(entry) }));
81
+ }
82
+ /** A held value as the text a form submits. */
83
+ export function serialize(value) {
84
+ if (value === undefined || value === null)
85
+ return '';
86
+ if (value instanceof Date)
87
+ return value.toISOString().slice(0, 10);
88
+ if (typeof File !== 'undefined' && value instanceof File)
89
+ return value.name;
90
+ if (Array.isArray(value))
91
+ return value.map((entry) => serialize(entry)).join(',');
92
+ if (typeof value === 'object')
93
+ return JSON.stringify(value) ?? '';
94
+ return String(value);
95
+ }
96
+ /** The seven weekday headings, from the platform rather than a table of words. */
97
+ function weekdays() {
98
+ const format = new Intl.DateTimeFormat(undefined, { weekday: 'short' });
99
+ return Array.from({ length: 7 }, (_, index) => format.format(new Date(2024, 0, 7 + index)));
100
+ }
101
+ const WEEKDAYS = weekdays();
102
+ /** A month caption, in the reader's own convention. */
103
+ function monthCaption(date) {
104
+ return date.toLocaleDateString(undefined, { month: 'long', year: 'numeric' });
105
+ }
106
+ /** A held value as a controlled string. */
107
+ function heldString(ctx, field) {
108
+ return typeof ctx.values[field.key] === 'string' ? ctx.values[field.key] : '';
109
+ }
110
+ /** A held value as a controlled number, or `null`. */
111
+ function heldNumber(ctx, field) {
112
+ return typeof ctx.values[field.key] === 'number' ? ctx.values[field.key] : null;
113
+ }
114
+ /**
115
+ * The kinds whose Component draws its own label.
116
+ *
117
+ * The rest have the Block's label drawn above the control, so a field has the
118
+ * same shell whether Prism drew the control or the caller did. These carry the
119
+ * label internally because their Component requires it, and drawing a second one
120
+ * would name the field twice.
121
+ */
122
+ export const SELF_LABELLED = new Set([
123
+ 'searchfield',
124
+ 'passwordfield',
125
+ 'moneyfield',
126
+ 'combobox',
127
+ 'multicombobox',
128
+ 'togglegroup',
129
+ 'choicecard',
130
+ 'calendar',
131
+ 'datepicker',
132
+ 'rangefield',
133
+ 'slider',
134
+ 'toggle',
135
+ 'dropzone',
136
+ 'fileupload',
137
+ 'imagelistfield',
138
+ 'repeatablerows',
139
+ ]);
140
+ /**
141
+ * The kinds whose value is not submitted by the control itself.
142
+ *
143
+ * A hidden input carries the held value under the field's key so the form still
144
+ * submits one complete payload. A control that renders its own hidden input from
145
+ * `name` is absent: a second input would submit the key twice.
146
+ */
147
+ export const NEEDS_HIDDEN = new Set([
148
+ 'searchfield',
149
+ 'passwordfield',
150
+ 'moneyfield',
151
+ 'togglegroup',
152
+ 'toggle',
153
+ 'dropzone',
154
+ 'fileupload',
155
+ 'imagelistfield',
156
+ 'repeatablerows',
157
+ ]);
158
+ /**
159
+ * The kinds whose control is a set of choices, and therefore needs options.
160
+ *
161
+ * Exported so a Block that refuses a choice with no options reads the same list
162
+ * the renderer does, rather than keeping a second one free to disagree with it.
163
+ * A Block that spelled the member names itself would also be spelling a
164
+ * capitalized Component name as a literal in its own source, which the copy gate
165
+ * reads as copy; the vocabulary belongs here.
166
+ */
167
+ export const CHOICE_KINDS = new Set([
168
+ 'Select',
169
+ 'NativeSelect',
170
+ 'Combobox',
171
+ 'MultiCombobox',
172
+ 'ToggleGroup',
173
+ 'RadioGroup',
174
+ 'ChoiceCard',
175
+ ]);
176
+ /**
177
+ * The kind names a Block or Page may name directly in its own source.
178
+ *
179
+ * A `FieldSpec` names a Component with a capitalized string, and a Block that
180
+ * builds one from its own flat prop would otherwise spell a Component name as a
181
+ * string literal, which the copy gate reads as copy rather than as a machine
182
+ * value. Naming the constants here keeps the vocabulary in the module that owns
183
+ * it and leaves the renderer's `CONTROL` map the one place a kind is drawn.
184
+ */
185
+ export const FieldKindName = {
186
+ input: 'Input',
187
+ textarea: 'Textarea',
188
+ nativeSelect: 'NativeSelect',
189
+ numberField: 'NumberField',
190
+ passwordField: 'PasswordField',
191
+ slot: 'slot',
192
+ };
193
+ /**
194
+ * The control drawn for one kind, keyed by the kind's lowercase name.
195
+ *
196
+ * The map covers every member of `FieldKind`, so a kind added to the union fails
197
+ * the compiler here until it is drawn. The lowercase keys are machine values
198
+ * rather than copy, which is the same reason a variant name is written in
199
+ * lowercase everywhere else in this package.
200
+ */
201
+ const CONTROL = {
202
+ input: (field, ctx) => (_jsx(Input, { id: ctx.id, name: field.key, value: ctx.controlled ? heldString(ctx, field) : undefined, onChange: ctx.controlled ? (event) => ctx.setValue(field.key, event.target.value) : undefined, defaultValue: ctx.controlled ? undefined : inputDefault(field.defaultValue), placeholder: field.placeholder, disabled: field.disabled, required: field.required, autoComplete: field.autoComplete, "aria-describedby": ctx.describedBy, "aria-invalid": ctx.invalid || undefined })),
203
+ textarea: (field, ctx) => (_jsx(Textarea, { id: ctx.id, name: field.key, rows: field.rows, value: ctx.controlled ? heldString(ctx, field) : undefined, onChange: ctx.controlled ? (event) => ctx.setValue(field.key, event.target.value) : undefined, defaultValue: ctx.controlled ? undefined : inputDefault(field.defaultValue), placeholder: field.placeholder, disabled: field.disabled, required: field.required, autoComplete: field.autoComplete, "aria-describedby": ctx.describedBy, "aria-invalid": ctx.invalid || undefined })),
204
+ numberfield: (field, ctx) => (_jsx(NumberField, { id: ctx.id, name: field.key, "aria-label": ctx.text, value: ctx.controlled ? heldNumber(ctx, field) : undefined, onValueChange: ctx.controlled ? (value) => ctx.setValue(field.key, value) : undefined, defaultValue: ctx.controlled
205
+ ? undefined
206
+ : typeof field.defaultValue === 'number'
207
+ ? field.defaultValue
208
+ : undefined, labels: { increment: `${ctx.text} +`, decrement: `${ctx.text} -` }, disabled: field.disabled, required: field.required, "aria-describedby": ctx.describedBy })),
209
+ moneyfield: (field, ctx) => (_jsx(MoneyField, { value: heldNumber(ctx, field), onValueChange: (value) => ctx.setValue(field.key, value), locale: field.locale ?? new Intl.NumberFormat().resolvedOptions().locale, currency: field.currency, id: ctx.id, "aria-label": ctx.text, disabled: field.disabled, describedBy: ctx.describedBy })),
210
+ searchfield: (field, ctx) => (_jsx(SearchField, { value: heldString(ctx, field), onValueChange: (value) => ctx.setValue(field.key, value), label: ctx.text, placeholder: field.placeholder, className: "w-full" })),
211
+ passwordfield: (field, ctx) => (_jsx(PasswordField, { value: heldString(ctx, field), onValueChange: (value) => ctx.setValue(field.key, value), label: ctx.text, revealLabel: `${ctx.text} +`, hideLabel: `${ctx.text} -` })),
212
+ onetimecode: (field, ctx) => (_jsx(OneTimeCode, { label: ctx.text, length: field.length ?? 6, name: field.key, defaultValue: stringOf(field.defaultValue), disabled: field.disabled, required: field.required })),
213
+ select: (field, ctx) => (_jsxs(Select, { name: field.key, defaultValue: stringOf(field.defaultValue), items: selectItems(field), disabled: field.disabled, required: field.required, children: [_jsx(SelectTrigger, { id: ctx.id, className: "w-full", "aria-describedby": ctx.describedBy, children: _jsx(SelectValue, { placeholder: field.placeholder }) }), _jsx(SelectContent, { children: optionsOf(field).map((option) => (_jsx(SelectItem, { value: option.value, children: option.label }, option.value))) })] })),
214
+ nativeselect: (field, ctx) => (_jsx(NativeSelect, { id: ctx.id, name: field.key, value: ctx.controlled ? heldString(ctx, field) : undefined, onChange: ctx.controlled ? (event) => ctx.setValue(field.key, event.target.value) : undefined, defaultValue: ctx.controlled ? undefined : stringOf(field.defaultValue), disabled: field.disabled, required: field.required, "aria-describedby": ctx.describedBy, "aria-invalid": ctx.invalid || undefined, children: optionsOf(field).map((option) => (_jsx("option", { value: option.value, children: typeof option.label === 'string' ? option.label : option.value }, option.value))) })),
215
+ combobox: (field, ctx) => (_jsx(Combobox, { name: field.key, defaultValue: stringOf(field.defaultValue), items: comboboxItems(field), label: ctx.text, empty: { message: (query) => query }, disabled: field.disabled, required: field.required })),
216
+ multicombobox: (field, ctx) => (_jsx(MultiCombobox, { name: field.key, items: comboboxItems(field), label: ctx.text, removeLabel: (label) => label, empty: { message: (query) => query }, disabled: field.disabled, required: field.required })),
217
+ togglegroup: (field, ctx) => (_jsx(ToggleGroup, { selectionMode: "multiple", "aria-label": ctx.text, value: asStringArray(ctx.values[field.key]), onValueChange: (value) => ctx.setValue(field.key, [...value]), disabled: field.disabled, className: "flex-wrap", children: optionsOf(field).map((option) => (_jsx(ToggleGroupItem, { value: option.value, children: option.label }, option.value))) })),
218
+ radiogroup: (field, ctx) => (_jsx(RadioGroup, { name: field.key, defaultValue: stringOf(field.defaultValue), "aria-labelledby": ctx.labelId, children: optionsOf(field).map((option) => (_jsxs("label", { className: "flex items-center gap-2 text-sm", children: [_jsx(RadioGroupItem, { value: option.value }), option.label] }, option.value))) })),
219
+ choicecard: (field, ctx) => (_jsx(ChoiceCard, { label: field.label, options: optionsOf(field).map((option) => ({
220
+ value: option.value,
221
+ label: option.label,
222
+ })), name: field.key, defaultValue: stringOf(field.defaultValue), disabled: field.disabled })),
223
+ calendar: (field, ctx) => {
224
+ const held = ctx.values[field.key];
225
+ const month = ctx.values[`${field.key}-month`];
226
+ const shown = month instanceof Date ? month : new Date();
227
+ return (_jsx(Calendar, { label: ctx.text, monthLabel: monthCaption(shown), weekdayLabels: WEEKDAYS, previousLabel: `${ctx.text} -`, nextLabel: `${ctx.text} +`, month: shown, onMonthChange: (next) => ctx.setValue(`${field.key}-month`, next), value: held instanceof Date ? held : null, onValueChange: (date) => ctx.setValue(field.key, date), dayLabel: (date) => date.toLocaleDateString(), name: field.key, disabled: field.disabled }));
228
+ },
229
+ datepicker: (field, ctx) => (_jsx(DatePicker, { name: field.key, defaultValue: dateOf(field.defaultValue), label: ctx.text, format: (date) => date.toLocaleDateString(), monthLabel: monthCaption, weekdayLabels: WEEKDAYS, previousLabel: `${ctx.text} -`, nextLabel: `${ctx.text} +`, placeholder: field.placeholder, disabled: field.disabled, required: field.required })),
230
+ slider: (field, ctx) => (_jsx(Slider, { name: field.key, "aria-label": ctx.text, defaultValue: typeof field.defaultValue === 'number' ? field.defaultValue : undefined, disabled: field.disabled, className: "w-full" })),
231
+ rangefield: (field, ctx) => (_jsx(RangeField, { label: ctx.text, name: field.key, boundLabel: (_bound, formatted) => formatted, spanLabel: (_span, formatted) => formatted, disabled: field.disabled })),
232
+ switch: (field, ctx) => (_jsx(Switch, { name: field.key, checked: Boolean(ctx.values[field.key] ?? field.defaultValue), onCheckedChange: (checked) => ctx.setValue(field.key, checked), disabled: field.disabled })),
233
+ checkbox: (field, ctx) => (_jsx(Checkbox, { name: field.key, "aria-label": ctx.text, defaultChecked: typeof field.defaultValue === 'boolean' ? field.defaultValue : undefined, disabled: field.disabled })),
234
+ toggle: (field, ctx) => (_jsx(Toggle, { "aria-label": ctx.text, pressed: Boolean(ctx.values[field.key] ?? false), onPressedChange: (pressed) => ctx.setValue(field.key, pressed), disabled: field.disabled, children: field.label })),
235
+ dropzone: (field, ctx) => (_jsx(Dropzone, { label: field.label, accept: field.accept?.join(','), multiple: field.multiple, disabled: field.disabled, onFiles: (files) => ctx.setValue(field.key, files) })),
236
+ fileupload: (field, ctx) => (_jsx(FileUpload, { files: fileRows(ctx.values[field.key]), label: field.label, removeLabel: (name) => name, onRemove: (id) => ctx.setValue(field.key, asArray(ctx.values[field.key]).filter((_entry, index) => String(index) !== id)) })),
237
+ imagelistfield: (field, ctx) => (_jsx(ImageListField, { images: imageRows(ctx.values[field.key]), cap: Number.MAX_SAFE_INTEGER, addLabel: field.label, empty: null, label: field.label, removeLabel: (name) => name, onAdd: () => ctx.setValue(field.key, [...asArray(ctx.values[field.key]), '']), onRemove: (id) => ctx.setValue(field.key, asArray(ctx.values[field.key]).filter((_entry, index) => String(index) !== id)) })),
238
+ repeatablerows: (field, ctx) => (_jsx(RepeatableRows, { rows: asArray(ctx.values[field.key]), label: field.label, addLabel: field.label, onAdd: () => ctx.setValue(field.key, [...asArray(ctx.values[field.key]), {}]), onRemove: (row) => ctx.setValue(field.key, asArray(ctx.values[field.key]).filter((entry) => entry !== row)), removeLabel: (index) => String(index + 1), rowLabel: (index) => String(index + 1), children: () => field.emptyRow ?? null })),
239
+ slot: (field) => field.control,
240
+ };
241
+ /**
242
+ * The control one field draws, whichever member of `FieldKind` it is.
243
+ *
244
+ * The kind is lowercased and looked up in the map above, so a kind the union
245
+ * grows is a compilation error at the map rather than a control that silently
246
+ * does not draw.
247
+ */
248
+ export function renderControl(field, ctx) {
249
+ const kind = field.kind.toLowerCase();
250
+ return CONTROL[kind](field, ctx);
251
+ }