@bsm-form/react-renderer 0.39.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/dist/index.cjs +5078 -0
- package/dist/index.d.cts +311 -0
- package/dist/index.d.ts +311 -0
- package/dist/index.js +4992 -0
- package/package.json +46 -0
package/dist/index.js
ADDED
|
@@ -0,0 +1,4992 @@
|
|
|
1
|
+
// src/renderer/layout-renderer.tsx
|
|
2
|
+
import { adaptLayout } from "@bsm-form/core";
|
|
3
|
+
|
|
4
|
+
// src/renderer/field-renderer.tsx
|
|
5
|
+
import { adaptField } from "@bsm-form/core";
|
|
6
|
+
import {
|
|
7
|
+
fieldAllowsBlurEvent,
|
|
8
|
+
fieldAllowsChangeEvent,
|
|
9
|
+
fieldAllowsCommitEvent
|
|
10
|
+
} from "@bsm-form/schema";
|
|
11
|
+
|
|
12
|
+
// src/registry/field-registry.ts
|
|
13
|
+
import { Checkbox, Switch } from "bsm-design-system";
|
|
14
|
+
|
|
15
|
+
// src/renderer/radio-group-field.tsx
|
|
16
|
+
import { RadioGroup } from "bsm-design-system";
|
|
17
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
18
|
+
function RadioGroupField({
|
|
19
|
+
"aria-describedby": ariaDescribedBy,
|
|
20
|
+
"aria-labelledby": ariaLabelledBy,
|
|
21
|
+
disabled,
|
|
22
|
+
error,
|
|
23
|
+
helperText,
|
|
24
|
+
id,
|
|
25
|
+
label,
|
|
26
|
+
onChange,
|
|
27
|
+
options,
|
|
28
|
+
value,
|
|
29
|
+
...groupProps
|
|
30
|
+
}) {
|
|
31
|
+
const normalizedOptions = normalizeRadioOptions(options);
|
|
32
|
+
const selectedOption = normalizedOptions.find(
|
|
33
|
+
(option) => Object.is(option.value, value)
|
|
34
|
+
);
|
|
35
|
+
const labelId = label && id ? `${id}-label` : void 0;
|
|
36
|
+
return /* @__PURE__ */ jsxs(
|
|
37
|
+
"fieldset",
|
|
38
|
+
{
|
|
39
|
+
disabled,
|
|
40
|
+
className: "m-0 flex flex-col items-start border-0 p-0",
|
|
41
|
+
children: [
|
|
42
|
+
label ? /* @__PURE__ */ jsx("legend", { id: labelId, className: "mb-1 text-sm text-fg", children: label }) : null,
|
|
43
|
+
/* @__PURE__ */ jsx(
|
|
44
|
+
RadioGroup,
|
|
45
|
+
{
|
|
46
|
+
...groupProps,
|
|
47
|
+
id,
|
|
48
|
+
value: selectedOption?.controlValue ?? "",
|
|
49
|
+
disabled,
|
|
50
|
+
"aria-invalid": error || void 0,
|
|
51
|
+
"aria-describedby": ariaDescribedBy,
|
|
52
|
+
"aria-labelledby": ariaLabelledBy ?? labelId,
|
|
53
|
+
onChange: (controlValue) => {
|
|
54
|
+
const optionValue = resolveRadioOptionValue(
|
|
55
|
+
normalizedOptions,
|
|
56
|
+
controlValue
|
|
57
|
+
);
|
|
58
|
+
if (optionValue !== void 0) {
|
|
59
|
+
onChange?.(optionValue);
|
|
60
|
+
}
|
|
61
|
+
},
|
|
62
|
+
children: normalizedOptions.map((option) => /* @__PURE__ */ jsx(
|
|
63
|
+
RadioGroup.Item,
|
|
64
|
+
{
|
|
65
|
+
id: id ? `${id}-${option.controlValue}` : void 0,
|
|
66
|
+
value: option.controlValue,
|
|
67
|
+
children: option.label
|
|
68
|
+
},
|
|
69
|
+
option.controlValue
|
|
70
|
+
))
|
|
71
|
+
}
|
|
72
|
+
),
|
|
73
|
+
helperText ? /* @__PURE__ */ jsx(
|
|
74
|
+
"p",
|
|
75
|
+
{
|
|
76
|
+
id: ariaDescribedBy,
|
|
77
|
+
role: error ? "alert" : void 0,
|
|
78
|
+
className: `mt-1 text-xs ${error ? "text-fg-error" : "text-fg-tertiary"}`,
|
|
79
|
+
children: helperText
|
|
80
|
+
}
|
|
81
|
+
) : null
|
|
82
|
+
]
|
|
83
|
+
}
|
|
84
|
+
);
|
|
85
|
+
}
|
|
86
|
+
function normalizeRadioOptions(options) {
|
|
87
|
+
if (!Array.isArray(options)) {
|
|
88
|
+
return [];
|
|
89
|
+
}
|
|
90
|
+
const normalizedOptions = [];
|
|
91
|
+
options.forEach((option, index) => {
|
|
92
|
+
if (typeof option !== "object" || option === null) {
|
|
93
|
+
return;
|
|
94
|
+
}
|
|
95
|
+
if (!("label" in option) || !("value" in option)) {
|
|
96
|
+
return;
|
|
97
|
+
}
|
|
98
|
+
if (typeof option.label !== "string" && typeof option.label !== "number" || typeof option.value !== "string" && typeof option.value !== "number") {
|
|
99
|
+
return;
|
|
100
|
+
}
|
|
101
|
+
normalizedOptions.push({
|
|
102
|
+
controlValue: `radio-option-${index}`,
|
|
103
|
+
label: String(option.label),
|
|
104
|
+
value: option.value
|
|
105
|
+
});
|
|
106
|
+
});
|
|
107
|
+
return normalizedOptions;
|
|
108
|
+
}
|
|
109
|
+
function resolveRadioOptionValue(options, controlValue) {
|
|
110
|
+
return options.find((option) => option.controlValue === controlValue)?.value;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
// src/renderer/slider-field.tsx
|
|
114
|
+
import { Slider } from "bsm-design-system";
|
|
115
|
+
import { jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
116
|
+
function SliderField({
|
|
117
|
+
"aria-describedby": ariaDescribedBy,
|
|
118
|
+
"aria-labelledby": ariaLabelledBy,
|
|
119
|
+
disabled,
|
|
120
|
+
error,
|
|
121
|
+
helperText,
|
|
122
|
+
id,
|
|
123
|
+
label,
|
|
124
|
+
max,
|
|
125
|
+
min,
|
|
126
|
+
minStepsBetweenThumbs,
|
|
127
|
+
mode,
|
|
128
|
+
onChange,
|
|
129
|
+
onCommit,
|
|
130
|
+
orientation,
|
|
131
|
+
step,
|
|
132
|
+
value,
|
|
133
|
+
variant,
|
|
134
|
+
...sliderProps
|
|
135
|
+
}) {
|
|
136
|
+
const bounds = normalizeSliderBounds(min, max);
|
|
137
|
+
const resolvedMode = resolveSliderMode(mode, value);
|
|
138
|
+
const componentValue = normalizeSliderComponentValue(
|
|
139
|
+
value,
|
|
140
|
+
resolvedMode,
|
|
141
|
+
bounds.min,
|
|
142
|
+
bounds.max
|
|
143
|
+
);
|
|
144
|
+
const labelId = label && id ? `${id}-label` : void 0;
|
|
145
|
+
const normalizedStep = normalizeSliderStep(step);
|
|
146
|
+
const normalizedMinSteps = normalizeSliderMinSteps(minStepsBetweenThumbs);
|
|
147
|
+
const toValue = (nextValue) => toEngineSliderValue(nextValue, resolvedMode);
|
|
148
|
+
return /* @__PURE__ */ jsxs2(
|
|
149
|
+
"fieldset",
|
|
150
|
+
{
|
|
151
|
+
disabled,
|
|
152
|
+
className: "m-0 flex flex-col items-start border-0 p-0",
|
|
153
|
+
children: [
|
|
154
|
+
label ? /* @__PURE__ */ jsx2("legend", { id: labelId, className: "mb-1 text-sm text-fg", children: label }) : null,
|
|
155
|
+
/* @__PURE__ */ jsx2(
|
|
156
|
+
Slider,
|
|
157
|
+
{
|
|
158
|
+
...sliderProps,
|
|
159
|
+
id,
|
|
160
|
+
value: componentValue,
|
|
161
|
+
min: bounds.min,
|
|
162
|
+
max: bounds.max,
|
|
163
|
+
step: normalizedStep,
|
|
164
|
+
minStepsBetweenThumbs: normalizedMinSteps,
|
|
165
|
+
orientation: orientation === "vertical" ? "vertical" : "horizontal",
|
|
166
|
+
variant: variant === "secondary" ? "secondary" : "primary",
|
|
167
|
+
disabled,
|
|
168
|
+
"aria-invalid": error || void 0,
|
|
169
|
+
"aria-describedby": ariaDescribedBy,
|
|
170
|
+
"aria-labelledby": ariaLabelledBy ?? labelId,
|
|
171
|
+
onChange: (nextValue) => {
|
|
172
|
+
const engineValue = toValue(nextValue);
|
|
173
|
+
if (engineValue !== void 0) {
|
|
174
|
+
onChange?.(engineValue);
|
|
175
|
+
}
|
|
176
|
+
},
|
|
177
|
+
onValueCommit: (nextValue) => {
|
|
178
|
+
const engineValue = toValue(nextValue);
|
|
179
|
+
if (engineValue !== void 0) {
|
|
180
|
+
onCommit?.(engineValue);
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
),
|
|
185
|
+
helperText ? /* @__PURE__ */ jsx2(
|
|
186
|
+
"p",
|
|
187
|
+
{
|
|
188
|
+
id: ariaDescribedBy,
|
|
189
|
+
role: error ? "alert" : void 0,
|
|
190
|
+
className: `mt-1 text-xs ${error ? "text-fg-error" : "text-fg-tertiary"}`,
|
|
191
|
+
children: helperText
|
|
192
|
+
}
|
|
193
|
+
) : null
|
|
194
|
+
]
|
|
195
|
+
}
|
|
196
|
+
);
|
|
197
|
+
}
|
|
198
|
+
function resolveSliderMode(mode, value) {
|
|
199
|
+
if (mode === "single" || mode === "range") {
|
|
200
|
+
return mode;
|
|
201
|
+
}
|
|
202
|
+
return Array.isArray(value) && value.length >= 2 ? "range" : "single";
|
|
203
|
+
}
|
|
204
|
+
function normalizeSliderBounds(min, max) {
|
|
205
|
+
const normalizedMin = isFiniteNumber(min) ? min : 0;
|
|
206
|
+
const normalizedMax = isFiniteNumber(max) ? max : 100;
|
|
207
|
+
return {
|
|
208
|
+
min: normalizedMin,
|
|
209
|
+
max: normalizedMax > normalizedMin ? normalizedMax : normalizedMin + 1
|
|
210
|
+
};
|
|
211
|
+
}
|
|
212
|
+
function normalizeSliderStep(step) {
|
|
213
|
+
return isPositiveFiniteNumber(step) ? step : 1;
|
|
214
|
+
}
|
|
215
|
+
function normalizeSliderMinSteps(minSteps) {
|
|
216
|
+
return isFiniteNumber(minSteps) ? Math.max(0, minSteps) : 0;
|
|
217
|
+
}
|
|
218
|
+
function normalizeSliderComponentValue(value, mode, min, max) {
|
|
219
|
+
if (mode === "single") {
|
|
220
|
+
return [clamp(isFiniteNumber(value) ? value : min, min, max)];
|
|
221
|
+
}
|
|
222
|
+
if (!isSliderRangeValue(value)) {
|
|
223
|
+
return [min, max];
|
|
224
|
+
}
|
|
225
|
+
const first = clamp(value[0], min, max);
|
|
226
|
+
const second = clamp(value[1], min, max);
|
|
227
|
+
return first <= second ? [first, second] : [second, first];
|
|
228
|
+
}
|
|
229
|
+
function toEngineSliderValue(value, mode) {
|
|
230
|
+
if (mode === "single") {
|
|
231
|
+
return isFiniteNumber(value[0]) ? value[0] : void 0;
|
|
232
|
+
}
|
|
233
|
+
if (!isSliderRangeValue(value)) {
|
|
234
|
+
return void 0;
|
|
235
|
+
}
|
|
236
|
+
return value[0] <= value[1] ? [value[0], value[1]] : [value[1], value[0]];
|
|
237
|
+
}
|
|
238
|
+
function isSliderValue(value) {
|
|
239
|
+
return isFiniteNumber(value) || isSliderRangeValue(value);
|
|
240
|
+
}
|
|
241
|
+
function isSliderRangeValue(value) {
|
|
242
|
+
return Array.isArray(value) && value.length === 2 && isFiniteNumber(value[0]) && isFiniteNumber(value[1]);
|
|
243
|
+
}
|
|
244
|
+
function isFiniteNumber(value) {
|
|
245
|
+
return typeof value === "number" && Number.isFinite(value);
|
|
246
|
+
}
|
|
247
|
+
function isPositiveFiniteNumber(value) {
|
|
248
|
+
return isFiniteNumber(value) && value > 0;
|
|
249
|
+
}
|
|
250
|
+
function clamp(value, min, max) {
|
|
251
|
+
return Math.min(Math.max(value, min), max);
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
// src/renderer/time-picker-field.tsx
|
|
255
|
+
import {
|
|
256
|
+
TimePicker
|
|
257
|
+
} from "bsm-design-system";
|
|
258
|
+
import { jsx as jsx3 } from "react/jsx-runtime";
|
|
259
|
+
function TimePickerField({
|
|
260
|
+
"aria-describedby": ariaDescribedBy,
|
|
261
|
+
disabled,
|
|
262
|
+
disabledHours,
|
|
263
|
+
disabledMinutes,
|
|
264
|
+
error,
|
|
265
|
+
helperText,
|
|
266
|
+
id,
|
|
267
|
+
label,
|
|
268
|
+
maxTime,
|
|
269
|
+
minTime,
|
|
270
|
+
onBlur,
|
|
271
|
+
onChange,
|
|
272
|
+
readOnly,
|
|
273
|
+
size,
|
|
274
|
+
value,
|
|
275
|
+
...timePickerProps
|
|
276
|
+
}) {
|
|
277
|
+
const bounds = normalizeTimeBounds(minTime, maxTime);
|
|
278
|
+
return /* @__PURE__ */ jsx3(
|
|
279
|
+
"fieldset",
|
|
280
|
+
{
|
|
281
|
+
id,
|
|
282
|
+
disabled,
|
|
283
|
+
"aria-describedby": ariaDescribedBy,
|
|
284
|
+
"aria-invalid": error || void 0,
|
|
285
|
+
"aria-readonly": readOnly || void 0,
|
|
286
|
+
onBlur,
|
|
287
|
+
className: "m-0 border-0 p-0",
|
|
288
|
+
children: /* @__PURE__ */ jsx3(
|
|
289
|
+
TimePicker,
|
|
290
|
+
{
|
|
291
|
+
...timePickerProps,
|
|
292
|
+
value: normalizeTimeComponentValue(value),
|
|
293
|
+
minTime: bounds.minTime,
|
|
294
|
+
maxTime: bounds.maxTime,
|
|
295
|
+
disabledHours: normalizeDisabledTimeParts(disabledHours, "hour"),
|
|
296
|
+
disabledMinutes: normalizeDisabledTimeParts(
|
|
297
|
+
disabledMinutes,
|
|
298
|
+
"minute"
|
|
299
|
+
),
|
|
300
|
+
size: isTimePickerSize(size) ? size : void 0,
|
|
301
|
+
disabled,
|
|
302
|
+
readOnly,
|
|
303
|
+
error,
|
|
304
|
+
label,
|
|
305
|
+
helperText,
|
|
306
|
+
onChange: (nextValue) => {
|
|
307
|
+
const engineValue = toEngineTimeValue(nextValue);
|
|
308
|
+
if (engineValue !== void 0) {
|
|
309
|
+
onChange?.(engineValue);
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
)
|
|
314
|
+
}
|
|
315
|
+
);
|
|
316
|
+
}
|
|
317
|
+
function normalizeTimeComponentValue(value) {
|
|
318
|
+
return normalizeCompleteTime(value) ?? {};
|
|
319
|
+
}
|
|
320
|
+
function toEngineTimeValue(value) {
|
|
321
|
+
if (typeof value !== "object" || value === null || Array.isArray(value)) {
|
|
322
|
+
return void 0;
|
|
323
|
+
}
|
|
324
|
+
const hour = "hour" in value ? value.hour : void 0;
|
|
325
|
+
const minute = "minute" in value ? value.minute : void 0;
|
|
326
|
+
const isEmpty = (hour === void 0 || hour === "") && (minute === void 0 || minute === "");
|
|
327
|
+
if (isEmpty) {
|
|
328
|
+
return "";
|
|
329
|
+
}
|
|
330
|
+
return normalizeCompleteTime(value);
|
|
331
|
+
}
|
|
332
|
+
function normalizeTimeFieldValue(value) {
|
|
333
|
+
return value === "" ? "" : toEngineTimeValue(value);
|
|
334
|
+
}
|
|
335
|
+
function normalizeTimeBounds(minTime, maxTime) {
|
|
336
|
+
const normalizedMin = normalizeCompleteTime(minTime);
|
|
337
|
+
const normalizedMax = normalizeCompleteTime(maxTime);
|
|
338
|
+
if (normalizedMin && normalizedMax && toMinutes(normalizedMin) > toMinutes(normalizedMax)) {
|
|
339
|
+
return { minTime: normalizedMax, maxTime: normalizedMin };
|
|
340
|
+
}
|
|
341
|
+
return { minTime: normalizedMin, maxTime: normalizedMax };
|
|
342
|
+
}
|
|
343
|
+
function normalizeDisabledTimeParts(values, part) {
|
|
344
|
+
if (!Array.isArray(values)) {
|
|
345
|
+
return void 0;
|
|
346
|
+
}
|
|
347
|
+
const max = part === "hour" ? 23 : 59;
|
|
348
|
+
const normalizedValues = values.flatMap((value) => {
|
|
349
|
+
const normalizedValue = normalizeTimePart(value, max);
|
|
350
|
+
return normalizedValue === void 0 ? [] : [normalizedValue];
|
|
351
|
+
});
|
|
352
|
+
return [...new Set(normalizedValues)];
|
|
353
|
+
}
|
|
354
|
+
function normalizeCompleteTime(value) {
|
|
355
|
+
if (typeof value !== "object" || value === null || Array.isArray(value)) {
|
|
356
|
+
return void 0;
|
|
357
|
+
}
|
|
358
|
+
if (!("hour" in value) || !("minute" in value)) {
|
|
359
|
+
return void 0;
|
|
360
|
+
}
|
|
361
|
+
const hour = normalizeTimePart(value.hour, 23);
|
|
362
|
+
const minute = normalizeTimePart(value.minute, 59);
|
|
363
|
+
return hour !== void 0 && minute !== void 0 ? { hour, minute } : void 0;
|
|
364
|
+
}
|
|
365
|
+
function normalizeTimePart(value, max) {
|
|
366
|
+
if (typeof value !== "string" || !/^\d{1,2}$/.test(value)) {
|
|
367
|
+
return void 0;
|
|
368
|
+
}
|
|
369
|
+
const numericValue = Number(value);
|
|
370
|
+
if (numericValue > max) {
|
|
371
|
+
return void 0;
|
|
372
|
+
}
|
|
373
|
+
return value.padStart(2, "0");
|
|
374
|
+
}
|
|
375
|
+
function isTimePickerSize(size) {
|
|
376
|
+
return size === "xs" || size === "sm" || size === "md" || size === "lg";
|
|
377
|
+
}
|
|
378
|
+
function toMinutes(value) {
|
|
379
|
+
return Number(value.hour) * 60 + Number(value.minute);
|
|
380
|
+
}
|
|
381
|
+
|
|
382
|
+
// src/renderer/input-otp-field.tsx
|
|
383
|
+
import { InputOTP } from "bsm-design-system";
|
|
384
|
+
import { jsx as jsx4, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
385
|
+
var DEFAULT_OTP_LENGTH = 6;
|
|
386
|
+
var MAX_OTP_LENGTH = 32;
|
|
387
|
+
var DEFAULT_OTP_PATTERN = "^\\d+$";
|
|
388
|
+
var OTP_FORMAT_PATTERN = /^[xX#]+(?:[-/ ][xX#]+)*$/;
|
|
389
|
+
function InputOtpField({
|
|
390
|
+
"aria-describedby": ariaDescribedBy,
|
|
391
|
+
"aria-labelledby": ariaLabelledBy,
|
|
392
|
+
disabled,
|
|
393
|
+
error,
|
|
394
|
+
format,
|
|
395
|
+
group,
|
|
396
|
+
helperText,
|
|
397
|
+
id,
|
|
398
|
+
label,
|
|
399
|
+
maxLength,
|
|
400
|
+
onBlur,
|
|
401
|
+
onChange,
|
|
402
|
+
pattern,
|
|
403
|
+
placeholderChar,
|
|
404
|
+
readOnly,
|
|
405
|
+
value,
|
|
406
|
+
...otpProps
|
|
407
|
+
}) {
|
|
408
|
+
const configuration = normalizeOtpConfiguration(format, maxLength, group);
|
|
409
|
+
const labelId = label && id ? `${id}-label` : void 0;
|
|
410
|
+
const sharedProps = {
|
|
411
|
+
...otpProps,
|
|
412
|
+
id,
|
|
413
|
+
value: normalizeOtpValue(value, configuration.maxLength),
|
|
414
|
+
pattern: normalizeOtpPattern(pattern),
|
|
415
|
+
placeholderChar: normalizeOtpPlaceholderChar(placeholderChar),
|
|
416
|
+
disabled,
|
|
417
|
+
readOnly,
|
|
418
|
+
"aria-invalid": error || void 0,
|
|
419
|
+
"aria-describedby": ariaDescribedBy,
|
|
420
|
+
"aria-labelledby": ariaLabelledBy ?? labelId,
|
|
421
|
+
onBlur,
|
|
422
|
+
onChange: (nextValue) => {
|
|
423
|
+
onChange?.(normalizeOtpValue(nextValue, configuration.maxLength));
|
|
424
|
+
}
|
|
425
|
+
};
|
|
426
|
+
return /* @__PURE__ */ jsxs3(
|
|
427
|
+
"fieldset",
|
|
428
|
+
{
|
|
429
|
+
disabled,
|
|
430
|
+
"aria-invalid": error || void 0,
|
|
431
|
+
"aria-readonly": readOnly || void 0,
|
|
432
|
+
className: "m-0 flex flex-col items-start border-0 p-0",
|
|
433
|
+
children: [
|
|
434
|
+
label ? /* @__PURE__ */ jsx4("legend", { id: labelId, className: "mb-1 text-sm text-fg", children: label }) : null,
|
|
435
|
+
configuration.format ? /* @__PURE__ */ jsx4(InputOTP, { ...sharedProps, format: configuration.format }) : /* @__PURE__ */ jsx4(
|
|
436
|
+
InputOTP,
|
|
437
|
+
{
|
|
438
|
+
...sharedProps,
|
|
439
|
+
maxLength: configuration.maxLength,
|
|
440
|
+
group: configuration.group
|
|
441
|
+
}
|
|
442
|
+
),
|
|
443
|
+
helperText ? /* @__PURE__ */ jsx4(
|
|
444
|
+
"p",
|
|
445
|
+
{
|
|
446
|
+
id: ariaDescribedBy,
|
|
447
|
+
role: error ? "alert" : void 0,
|
|
448
|
+
className: `mt-1 text-xs ${disabled ? "text-fg-disabled" : error ? "text-fg-error" : "text-fg-tertiary"}`,
|
|
449
|
+
children: helperText
|
|
450
|
+
}
|
|
451
|
+
) : null
|
|
452
|
+
]
|
|
453
|
+
}
|
|
454
|
+
);
|
|
455
|
+
}
|
|
456
|
+
function normalizeOtpConfiguration(format, maxLength, group) {
|
|
457
|
+
const normalizedFormat = normalizeOtpFormat(format);
|
|
458
|
+
if (normalizedFormat) {
|
|
459
|
+
return {
|
|
460
|
+
format: normalizedFormat,
|
|
461
|
+
maxLength: countOtpFormatSlots(normalizedFormat)
|
|
462
|
+
};
|
|
463
|
+
}
|
|
464
|
+
const normalizedMaxLength = normalizeOtpMaxLength(maxLength);
|
|
465
|
+
return {
|
|
466
|
+
maxLength: normalizedMaxLength,
|
|
467
|
+
group: normalizeOtpGroup(group, normalizedMaxLength)
|
|
468
|
+
};
|
|
469
|
+
}
|
|
470
|
+
function normalizeOtpValue(value, maxLength) {
|
|
471
|
+
return typeof value === "string" ? value.slice(0, maxLength) : "";
|
|
472
|
+
}
|
|
473
|
+
function normalizeOtpPattern(pattern) {
|
|
474
|
+
if (typeof pattern !== "string" || pattern.length === 0) {
|
|
475
|
+
return DEFAULT_OTP_PATTERN;
|
|
476
|
+
}
|
|
477
|
+
try {
|
|
478
|
+
new RegExp(pattern);
|
|
479
|
+
return pattern;
|
|
480
|
+
} catch {
|
|
481
|
+
return DEFAULT_OTP_PATTERN;
|
|
482
|
+
}
|
|
483
|
+
}
|
|
484
|
+
function normalizeOtpFormat(format) {
|
|
485
|
+
if (typeof format !== "string" || !OTP_FORMAT_PATTERN.test(format)) {
|
|
486
|
+
return void 0;
|
|
487
|
+
}
|
|
488
|
+
const slotCount = countOtpFormatSlots(format);
|
|
489
|
+
return slotCount <= MAX_OTP_LENGTH ? format : void 0;
|
|
490
|
+
}
|
|
491
|
+
function normalizeOtpMaxLength(maxLength) {
|
|
492
|
+
if (typeof maxLength !== "number" || !Number.isFinite(maxLength)) {
|
|
493
|
+
return DEFAULT_OTP_LENGTH;
|
|
494
|
+
}
|
|
495
|
+
return Math.min(
|
|
496
|
+
Math.max(Math.trunc(maxLength), 1),
|
|
497
|
+
MAX_OTP_LENGTH
|
|
498
|
+
);
|
|
499
|
+
}
|
|
500
|
+
function normalizeOtpGroup(group, maxLength) {
|
|
501
|
+
if (!Array.isArray(group) || group.length === 0) {
|
|
502
|
+
return void 0;
|
|
503
|
+
}
|
|
504
|
+
const normalizedGroup = group.filter(
|
|
505
|
+
(size) => typeof size === "number" && Number.isInteger(size) && size > 0
|
|
506
|
+
);
|
|
507
|
+
const totalLength = normalizedGroup.reduce((total, size) => total + size, 0);
|
|
508
|
+
return normalizedGroup.length === group.length && totalLength === maxLength ? normalizedGroup : void 0;
|
|
509
|
+
}
|
|
510
|
+
function normalizeOtpPlaceholderChar(placeholderChar) {
|
|
511
|
+
if (placeholderChar === null) {
|
|
512
|
+
return null;
|
|
513
|
+
}
|
|
514
|
+
if (typeof placeholderChar !== "string" || placeholderChar.length === 0) {
|
|
515
|
+
return void 0;
|
|
516
|
+
}
|
|
517
|
+
return [...placeholderChar][0];
|
|
518
|
+
}
|
|
519
|
+
function countOtpFormatSlots(format) {
|
|
520
|
+
return [...format].filter(
|
|
521
|
+
(character) => character === "x" || character === "X" || character === "#"
|
|
522
|
+
).length;
|
|
523
|
+
}
|
|
524
|
+
|
|
525
|
+
// src/renderer/select-field.tsx
|
|
526
|
+
import { Select } from "bsm-design-system";
|
|
527
|
+
import { jsx as jsx5 } from "react/jsx-runtime";
|
|
528
|
+
function SelectField({
|
|
529
|
+
"aria-describedby": ariaDescribedBy,
|
|
530
|
+
"aria-labelledby": ariaLabelledBy,
|
|
531
|
+
asyncSearch,
|
|
532
|
+
className,
|
|
533
|
+
clearable,
|
|
534
|
+
contentDirection,
|
|
535
|
+
disabled,
|
|
536
|
+
emptyText,
|
|
537
|
+
error,
|
|
538
|
+
helperText,
|
|
539
|
+
hint,
|
|
540
|
+
id,
|
|
541
|
+
label,
|
|
542
|
+
loading,
|
|
543
|
+
mode,
|
|
544
|
+
onBlur,
|
|
545
|
+
onChange,
|
|
546
|
+
onSearch,
|
|
547
|
+
options,
|
|
548
|
+
placeholder,
|
|
549
|
+
readOnly,
|
|
550
|
+
rounded,
|
|
551
|
+
scrollContent,
|
|
552
|
+
searchable,
|
|
553
|
+
size,
|
|
554
|
+
value
|
|
555
|
+
}) {
|
|
556
|
+
const normalizedOptions = normalizeSelectOptions(options);
|
|
557
|
+
const resolvedMode = normalizeSelectMode(mode);
|
|
558
|
+
const componentOptions = normalizedOptions.map((option) => ({
|
|
559
|
+
label: option.label,
|
|
560
|
+
value: option.controlValue
|
|
561
|
+
}));
|
|
562
|
+
const componentValue = toComponentSelectValue(
|
|
563
|
+
value,
|
|
564
|
+
normalizedOptions,
|
|
565
|
+
resolvedMode
|
|
566
|
+
);
|
|
567
|
+
const normalizedDisabled = disabled === true;
|
|
568
|
+
const normalizedReadOnly = readOnly === true;
|
|
569
|
+
const sharedProps = {
|
|
570
|
+
id,
|
|
571
|
+
asyncSearch: asyncSearch === true,
|
|
572
|
+
className: typeof className === "string" ? className : void 0,
|
|
573
|
+
clearable: typeof clearable === "boolean" ? clearable : void 0,
|
|
574
|
+
contentDirection: contentDirection === "ltr" || contentDirection === "rtl" ? contentDirection : void 0,
|
|
575
|
+
disabled: normalizedDisabled,
|
|
576
|
+
emptyText: typeof emptyText === "string" ? emptyText : void 0,
|
|
577
|
+
error: error === true,
|
|
578
|
+
helperText: typeof helperText === "string" ? helperText : void 0,
|
|
579
|
+
hint: typeof hint === "string" ? hint : void 0,
|
|
580
|
+
label: typeof label === "string" ? label : void 0,
|
|
581
|
+
loading: loading === true,
|
|
582
|
+
onSearch: typeof onSearch === "function" ? onSearch : void 0,
|
|
583
|
+
placeholder: typeof placeholder === "string" ? placeholder : void 0,
|
|
584
|
+
readOnly: normalizedReadOnly,
|
|
585
|
+
rounded: rounded === true,
|
|
586
|
+
scrollContent: scrollContent === true,
|
|
587
|
+
searchable: searchable === true,
|
|
588
|
+
size: isSelectSize(size) ? size : void 0,
|
|
589
|
+
"aria-describedby": ariaDescribedBy,
|
|
590
|
+
"aria-labelledby": ariaLabelledBy,
|
|
591
|
+
"aria-invalid": error === true || void 0,
|
|
592
|
+
"aria-readonly": normalizedReadOnly || void 0,
|
|
593
|
+
onBlur
|
|
594
|
+
};
|
|
595
|
+
const handleChange = (nextValue) => {
|
|
596
|
+
if (normalizedDisabled || normalizedReadOnly) {
|
|
597
|
+
return;
|
|
598
|
+
}
|
|
599
|
+
const engineValue = toEngineSelectValue(
|
|
600
|
+
nextValue,
|
|
601
|
+
normalizedOptions,
|
|
602
|
+
resolvedMode
|
|
603
|
+
);
|
|
604
|
+
if (engineValue !== void 0) {
|
|
605
|
+
onChange?.(engineValue);
|
|
606
|
+
}
|
|
607
|
+
};
|
|
608
|
+
if (resolvedMode === "multi") {
|
|
609
|
+
return /* @__PURE__ */ jsx5(
|
|
610
|
+
Select,
|
|
611
|
+
{
|
|
612
|
+
...sharedProps,
|
|
613
|
+
mode: "multi",
|
|
614
|
+
options: componentOptions,
|
|
615
|
+
value: componentValue,
|
|
616
|
+
onChange: handleChange
|
|
617
|
+
}
|
|
618
|
+
);
|
|
619
|
+
}
|
|
620
|
+
return /* @__PURE__ */ jsx5(
|
|
621
|
+
Select,
|
|
622
|
+
{
|
|
623
|
+
...sharedProps,
|
|
624
|
+
mode: "select",
|
|
625
|
+
options: componentOptions,
|
|
626
|
+
value: componentValue,
|
|
627
|
+
onChange: handleChange
|
|
628
|
+
}
|
|
629
|
+
);
|
|
630
|
+
}
|
|
631
|
+
function normalizeSelectMode(mode) {
|
|
632
|
+
return mode === "multi" ? "multi" : "select";
|
|
633
|
+
}
|
|
634
|
+
function normalizeSelectOptions(options) {
|
|
635
|
+
if (!Array.isArray(options)) {
|
|
636
|
+
return [];
|
|
637
|
+
}
|
|
638
|
+
const normalizedOptions = [];
|
|
639
|
+
options.forEach((option, index) => {
|
|
640
|
+
if (typeof option !== "object" || option === null || !("label" in option) || !("value" in option) || typeof option.label !== "string" && typeof option.label !== "number" || !isSelectOptionValue(option.value) || option.value === "") {
|
|
641
|
+
return;
|
|
642
|
+
}
|
|
643
|
+
if (normalizedOptions.some(
|
|
644
|
+
(candidate) => selectValuesEqual(candidate.value, option.value)
|
|
645
|
+
)) {
|
|
646
|
+
return;
|
|
647
|
+
}
|
|
648
|
+
normalizedOptions.push({
|
|
649
|
+
controlValue: `select-option-${index}`,
|
|
650
|
+
label: String(option.label),
|
|
651
|
+
value: option.value
|
|
652
|
+
});
|
|
653
|
+
});
|
|
654
|
+
return normalizedOptions;
|
|
655
|
+
}
|
|
656
|
+
function toComponentSelectValue(value, options, mode) {
|
|
657
|
+
if (mode === "multi") {
|
|
658
|
+
if (!Array.isArray(value)) {
|
|
659
|
+
return [];
|
|
660
|
+
}
|
|
661
|
+
const selectedControlValues = value.flatMap((item) => {
|
|
662
|
+
const option = options.find(
|
|
663
|
+
(candidate) => selectValuesEqual(candidate.value, item)
|
|
664
|
+
);
|
|
665
|
+
return option ? [option.controlValue] : [];
|
|
666
|
+
});
|
|
667
|
+
return [...new Set(selectedControlValues)];
|
|
668
|
+
}
|
|
669
|
+
if (!isSelectOptionValue(value)) {
|
|
670
|
+
return void 0;
|
|
671
|
+
}
|
|
672
|
+
return options.find((option) => selectValuesEqual(option.value, value))?.controlValue;
|
|
673
|
+
}
|
|
674
|
+
function toEngineSelectValue(value, options, mode) {
|
|
675
|
+
if (mode === "multi") {
|
|
676
|
+
if (!Array.isArray(value)) {
|
|
677
|
+
return void 0;
|
|
678
|
+
}
|
|
679
|
+
const engineValues = [];
|
|
680
|
+
for (const controlValue of value) {
|
|
681
|
+
if (typeof controlValue !== "string") {
|
|
682
|
+
return void 0;
|
|
683
|
+
}
|
|
684
|
+
const option = options.find(
|
|
685
|
+
(candidate) => candidate.controlValue === controlValue
|
|
686
|
+
);
|
|
687
|
+
if (!option) {
|
|
688
|
+
return void 0;
|
|
689
|
+
}
|
|
690
|
+
if (!engineValues.some((item) => selectValuesEqual(item, option.value))) {
|
|
691
|
+
engineValues.push(option.value);
|
|
692
|
+
}
|
|
693
|
+
}
|
|
694
|
+
return engineValues;
|
|
695
|
+
}
|
|
696
|
+
if (value === void 0 || value === null || value === "") {
|
|
697
|
+
return "";
|
|
698
|
+
}
|
|
699
|
+
if (typeof value !== "string") {
|
|
700
|
+
return void 0;
|
|
701
|
+
}
|
|
702
|
+
return options.find((option) => option.controlValue === value)?.value;
|
|
703
|
+
}
|
|
704
|
+
function isSelectValue(value) {
|
|
705
|
+
return isSelectOptionValue(value) || Array.isArray(value) && value.every(isSelectOptionValue);
|
|
706
|
+
}
|
|
707
|
+
function isSelectOptionValue(value) {
|
|
708
|
+
return typeof value === "string" || typeof value === "number" && Number.isFinite(value);
|
|
709
|
+
}
|
|
710
|
+
function selectValuesEqual(first, second) {
|
|
711
|
+
return first === second;
|
|
712
|
+
}
|
|
713
|
+
function isSelectSize(value) {
|
|
714
|
+
return value === "xs" || value === "sm" || value === "md" || value === "lg";
|
|
715
|
+
}
|
|
716
|
+
|
|
717
|
+
// src/renderer/text-fields.tsx
|
|
718
|
+
import {
|
|
719
|
+
Input,
|
|
720
|
+
Textarea
|
|
721
|
+
} from "bsm-design-system";
|
|
722
|
+
import { Fragment, jsx as jsx6, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
723
|
+
function TextInputField(props) {
|
|
724
|
+
return /* @__PURE__ */ jsx6(
|
|
725
|
+
InputFieldControl,
|
|
726
|
+
{
|
|
727
|
+
...props,
|
|
728
|
+
inputType: typeof props.type === "string" ? props.type : "text"
|
|
729
|
+
}
|
|
730
|
+
);
|
|
731
|
+
}
|
|
732
|
+
function NumberInputField(props) {
|
|
733
|
+
return /* @__PURE__ */ jsx6(InputFieldControl, { ...props, inputType: "number" });
|
|
734
|
+
}
|
|
735
|
+
function TextareaField({
|
|
736
|
+
"aria-describedby": ariaDescribedBy,
|
|
737
|
+
"aria-label": ariaLabel,
|
|
738
|
+
"aria-labelledby": ariaLabelledBy,
|
|
739
|
+
className,
|
|
740
|
+
error,
|
|
741
|
+
helperText,
|
|
742
|
+
id,
|
|
743
|
+
label,
|
|
744
|
+
value,
|
|
745
|
+
...props
|
|
746
|
+
}) {
|
|
747
|
+
const helperTextId = helperText && id ? `${id}-helper-text` : void 0;
|
|
748
|
+
const descriptionIds = mergeDescriptionIds(
|
|
749
|
+
ariaDescribedBy,
|
|
750
|
+
helperTextId
|
|
751
|
+
);
|
|
752
|
+
return /* @__PURE__ */ jsxs4(Fragment, { children: [
|
|
753
|
+
/* @__PURE__ */ jsx6(
|
|
754
|
+
Textarea,
|
|
755
|
+
{
|
|
756
|
+
...props,
|
|
757
|
+
className: typeof className === "string" ? className : "",
|
|
758
|
+
id,
|
|
759
|
+
value: normalizeTextFieldValue(value),
|
|
760
|
+
label,
|
|
761
|
+
helperText,
|
|
762
|
+
error: error === true,
|
|
763
|
+
"aria-label": ariaLabel ?? (!ariaLabelledBy ? normalizeAccessibleText(label) : void 0),
|
|
764
|
+
"aria-labelledby": ariaLabelledBy,
|
|
765
|
+
"aria-describedby": descriptionIds,
|
|
766
|
+
"aria-invalid": error === true || void 0
|
|
767
|
+
}
|
|
768
|
+
),
|
|
769
|
+
/* @__PURE__ */ jsx6(
|
|
770
|
+
AssistiveHelperText,
|
|
771
|
+
{
|
|
772
|
+
id: helperTextId,
|
|
773
|
+
error: error === true,
|
|
774
|
+
text: helperText
|
|
775
|
+
}
|
|
776
|
+
)
|
|
777
|
+
] });
|
|
778
|
+
}
|
|
779
|
+
function normalizeTextFieldValue(value) {
|
|
780
|
+
if (typeof value === "string") {
|
|
781
|
+
return value;
|
|
782
|
+
}
|
|
783
|
+
return typeof value === "number" && Number.isFinite(value) ? value : "";
|
|
784
|
+
}
|
|
785
|
+
function InputFieldControl({
|
|
786
|
+
"aria-describedby": ariaDescribedBy,
|
|
787
|
+
"aria-label": ariaLabel,
|
|
788
|
+
"aria-labelledby": ariaLabelledBy,
|
|
789
|
+
className,
|
|
790
|
+
error,
|
|
791
|
+
helperText,
|
|
792
|
+
hint,
|
|
793
|
+
id,
|
|
794
|
+
inputType,
|
|
795
|
+
label,
|
|
796
|
+
value,
|
|
797
|
+
...props
|
|
798
|
+
}) {
|
|
799
|
+
const helperTextId = helperText && id ? `${id}-helper-text` : void 0;
|
|
800
|
+
const descriptionIds = mergeDescriptionIds(
|
|
801
|
+
ariaDescribedBy,
|
|
802
|
+
helperTextId
|
|
803
|
+
);
|
|
804
|
+
const accessibleLabel = normalizeAccessibleText(label, hint);
|
|
805
|
+
return /* @__PURE__ */ jsxs4(Fragment, { children: [
|
|
806
|
+
/* @__PURE__ */ jsx6(
|
|
807
|
+
Input,
|
|
808
|
+
{
|
|
809
|
+
...props,
|
|
810
|
+
className: typeof className === "string" ? className : "",
|
|
811
|
+
id,
|
|
812
|
+
type: inputType,
|
|
813
|
+
value: normalizeTextFieldValue(value),
|
|
814
|
+
label,
|
|
815
|
+
hint,
|
|
816
|
+
helperText,
|
|
817
|
+
error: error === true,
|
|
818
|
+
"aria-label": ariaLabel ?? (!ariaLabelledBy ? accessibleLabel : void 0),
|
|
819
|
+
"aria-labelledby": ariaLabelledBy,
|
|
820
|
+
"aria-describedby": descriptionIds,
|
|
821
|
+
"aria-invalid": error === true || void 0
|
|
822
|
+
}
|
|
823
|
+
),
|
|
824
|
+
/* @__PURE__ */ jsx6(
|
|
825
|
+
AssistiveHelperText,
|
|
826
|
+
{
|
|
827
|
+
id: helperTextId,
|
|
828
|
+
error: error === true,
|
|
829
|
+
text: helperText
|
|
830
|
+
}
|
|
831
|
+
)
|
|
832
|
+
] });
|
|
833
|
+
}
|
|
834
|
+
function AssistiveHelperText({
|
|
835
|
+
error,
|
|
836
|
+
id,
|
|
837
|
+
text
|
|
838
|
+
}) {
|
|
839
|
+
if (!id || !text) {
|
|
840
|
+
return null;
|
|
841
|
+
}
|
|
842
|
+
return /* @__PURE__ */ jsx6("span", { id, role: error ? "alert" : void 0, className: "sr-only", children: text });
|
|
843
|
+
}
|
|
844
|
+
function mergeDescriptionIds(...ids) {
|
|
845
|
+
const uniqueIds = new Set(
|
|
846
|
+
ids.flatMap((id) => typeof id === "string" ? id.split(/\s+/) : [])
|
|
847
|
+
);
|
|
848
|
+
return uniqueIds.size > 0 ? [...uniqueIds].join(" ") : void 0;
|
|
849
|
+
}
|
|
850
|
+
function normalizeAccessibleText(...parts) {
|
|
851
|
+
const text = parts.filter((part) => Boolean(part)).join(" ").trim();
|
|
852
|
+
return text || void 0;
|
|
853
|
+
}
|
|
854
|
+
|
|
855
|
+
// src/renderer/segment-button-field.tsx
|
|
856
|
+
import { SegmentButton } from "bsm-design-system";
|
|
857
|
+
import { jsx as jsx7, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
858
|
+
function SegmentButtonField({
|
|
859
|
+
"aria-describedby": ariaDescribedBy,
|
|
860
|
+
ariaLabel,
|
|
861
|
+
className,
|
|
862
|
+
disabled,
|
|
863
|
+
error,
|
|
864
|
+
fullWidth,
|
|
865
|
+
helperText,
|
|
866
|
+
hint,
|
|
867
|
+
id,
|
|
868
|
+
label,
|
|
869
|
+
onBlur,
|
|
870
|
+
onChange,
|
|
871
|
+
options,
|
|
872
|
+
readOnly,
|
|
873
|
+
rounded,
|
|
874
|
+
size,
|
|
875
|
+
value
|
|
876
|
+
}) {
|
|
877
|
+
const normalizedOptions = normalizeSegmentButtonOptions(options);
|
|
878
|
+
const normalizedDisabled = disabled === true;
|
|
879
|
+
const normalizedReadOnly = readOnly === true;
|
|
880
|
+
const normalizedLabel = normalizeText(label);
|
|
881
|
+
const normalizedHint = normalizeText(hint);
|
|
882
|
+
const normalizedHelperText = normalizeText(helperText);
|
|
883
|
+
const labelId = normalizedLabel && id ? `${id}-label` : void 0;
|
|
884
|
+
const componentValue = toComponentSegmentButtonValue(
|
|
885
|
+
value,
|
|
886
|
+
normalizedOptions
|
|
887
|
+
);
|
|
888
|
+
return /* @__PURE__ */ jsxs5(
|
|
889
|
+
"fieldset",
|
|
890
|
+
{
|
|
891
|
+
id,
|
|
892
|
+
disabled: normalizedDisabled,
|
|
893
|
+
onBlur,
|
|
894
|
+
className: "m-0 flex flex-col items-start border-0 p-0",
|
|
895
|
+
children: [
|
|
896
|
+
normalizedLabel ? /* @__PURE__ */ jsxs5(
|
|
897
|
+
"legend",
|
|
898
|
+
{
|
|
899
|
+
id: labelId,
|
|
900
|
+
className: "mb-1 flex items-center gap-1 text-sm text-fg",
|
|
901
|
+
children: [
|
|
902
|
+
/* @__PURE__ */ jsx7("span", { children: normalizedLabel }),
|
|
903
|
+
normalizedHint ? /* @__PURE__ */ jsx7("span", { className: "text-fg-tertiary", children: normalizedHint }) : null
|
|
904
|
+
]
|
|
905
|
+
}
|
|
906
|
+
) : null,
|
|
907
|
+
/* @__PURE__ */ jsx7(
|
|
908
|
+
SegmentButton,
|
|
909
|
+
{
|
|
910
|
+
value: componentValue ?? "",
|
|
911
|
+
size: normalizeSegmentButtonSize(size),
|
|
912
|
+
disabled: normalizedDisabled,
|
|
913
|
+
rounded: rounded === true,
|
|
914
|
+
fullWidth: fullWidth === true,
|
|
915
|
+
className: normalizeClassName(className),
|
|
916
|
+
"aria-invalid": error === true || void 0,
|
|
917
|
+
"aria-readonly": normalizedReadOnly || void 0,
|
|
918
|
+
"aria-describedby": ariaDescribedBy,
|
|
919
|
+
"aria-labelledby": labelId,
|
|
920
|
+
"aria-label": labelId ? void 0 : normalizeText(ariaLabel),
|
|
921
|
+
onChange: (controlValue) => {
|
|
922
|
+
if (normalizedDisabled || normalizedReadOnly) {
|
|
923
|
+
return;
|
|
924
|
+
}
|
|
925
|
+
const optionValue = toEngineSegmentButtonValue(
|
|
926
|
+
controlValue,
|
|
927
|
+
normalizedOptions
|
|
928
|
+
);
|
|
929
|
+
if (optionValue !== void 0) {
|
|
930
|
+
onChange?.(optionValue);
|
|
931
|
+
}
|
|
932
|
+
},
|
|
933
|
+
children: normalizedOptions.map((option) => {
|
|
934
|
+
const itemDisabled = normalizedDisabled || option.disabled;
|
|
935
|
+
return /* @__PURE__ */ jsx7(
|
|
936
|
+
SegmentButton.Item,
|
|
937
|
+
{
|
|
938
|
+
value: option.controlValue,
|
|
939
|
+
disabled: itemDisabled,
|
|
940
|
+
"aria-disabled": itemDisabled || void 0,
|
|
941
|
+
tabIndex: itemDisabled ? -1 : void 0,
|
|
942
|
+
children: option.label
|
|
943
|
+
},
|
|
944
|
+
option.controlValue
|
|
945
|
+
);
|
|
946
|
+
})
|
|
947
|
+
}
|
|
948
|
+
),
|
|
949
|
+
normalizedHelperText ? /* @__PURE__ */ jsx7(
|
|
950
|
+
"p",
|
|
951
|
+
{
|
|
952
|
+
id: ariaDescribedBy,
|
|
953
|
+
role: error === true ? "alert" : void 0,
|
|
954
|
+
className: `mt-1 text-xs ${normalizedDisabled ? "text-fg-disabled" : error === true ? "text-fg-error" : "text-fg-tertiary"}`,
|
|
955
|
+
children: normalizedHelperText
|
|
956
|
+
}
|
|
957
|
+
) : null
|
|
958
|
+
]
|
|
959
|
+
}
|
|
960
|
+
);
|
|
961
|
+
}
|
|
962
|
+
function normalizeSegmentButtonOptions(options) {
|
|
963
|
+
if (!Array.isArray(options)) {
|
|
964
|
+
return [];
|
|
965
|
+
}
|
|
966
|
+
const normalizedOptions = [];
|
|
967
|
+
options.forEach((option, index) => {
|
|
968
|
+
if (typeof option !== "object" || option === null || !("label" in option) || !("value" in option)) {
|
|
969
|
+
return;
|
|
970
|
+
}
|
|
971
|
+
const label = normalizeOptionLabel(option.label);
|
|
972
|
+
if (!label || !isNonEmptySegmentButtonValue(option.value)) {
|
|
973
|
+
return;
|
|
974
|
+
}
|
|
975
|
+
if (normalizedOptions.some((candidate) => candidate.value === option.value)) {
|
|
976
|
+
return;
|
|
977
|
+
}
|
|
978
|
+
normalizedOptions.push({
|
|
979
|
+
controlValue: `segment-option-${index}`,
|
|
980
|
+
label,
|
|
981
|
+
value: option.value,
|
|
982
|
+
disabled: "disabled" in option && option.disabled === true
|
|
983
|
+
});
|
|
984
|
+
});
|
|
985
|
+
return normalizedOptions;
|
|
986
|
+
}
|
|
987
|
+
function normalizeSegmentButtonSize(value) {
|
|
988
|
+
return value === "xs" || value === "sm" || value === "lg" ? value : "md";
|
|
989
|
+
}
|
|
990
|
+
function toComponentSegmentButtonValue(value, options) {
|
|
991
|
+
return options.find((option) => option.value === value)?.controlValue;
|
|
992
|
+
}
|
|
993
|
+
function toEngineSegmentButtonValue(controlValue, options) {
|
|
994
|
+
if (typeof controlValue !== "string") {
|
|
995
|
+
return void 0;
|
|
996
|
+
}
|
|
997
|
+
const option = options.find(
|
|
998
|
+
(candidate) => candidate.controlValue === controlValue
|
|
999
|
+
);
|
|
1000
|
+
return option && !option.disabled ? option.value : void 0;
|
|
1001
|
+
}
|
|
1002
|
+
function isSegmentButtonValue(value) {
|
|
1003
|
+
return typeof value === "string" || typeof value === "number" && Number.isFinite(value);
|
|
1004
|
+
}
|
|
1005
|
+
function isNonEmptySegmentButtonValue(value) {
|
|
1006
|
+
return isSegmentButtonValue(value) && value !== "";
|
|
1007
|
+
}
|
|
1008
|
+
function normalizeOptionLabel(value) {
|
|
1009
|
+
if (typeof value !== "string" && typeof value !== "number") {
|
|
1010
|
+
return void 0;
|
|
1011
|
+
}
|
|
1012
|
+
const label = String(value).trim();
|
|
1013
|
+
return label || void 0;
|
|
1014
|
+
}
|
|
1015
|
+
function normalizeText(value) {
|
|
1016
|
+
if (typeof value !== "string") {
|
|
1017
|
+
return void 0;
|
|
1018
|
+
}
|
|
1019
|
+
const text = value.trim();
|
|
1020
|
+
return text || void 0;
|
|
1021
|
+
}
|
|
1022
|
+
function normalizeClassName(value) {
|
|
1023
|
+
return typeof value === "string" ? value.trim() || void 0 : void 0;
|
|
1024
|
+
}
|
|
1025
|
+
|
|
1026
|
+
// src/registry/field-registry.ts
|
|
1027
|
+
var FIELD_CHANGE_IGNORED = /* @__PURE__ */ Symbol("FIELD_CHANGE_IGNORED");
|
|
1028
|
+
var eventValueDefinition = (component) => ({
|
|
1029
|
+
component,
|
|
1030
|
+
toEngineValue: readEventValue
|
|
1031
|
+
});
|
|
1032
|
+
var fieldRegistry = {
|
|
1033
|
+
text: eventValueDefinition(TextInputField),
|
|
1034
|
+
number: eventValueDefinition(NumberInputField),
|
|
1035
|
+
textarea: eventValueDefinition(TextareaField),
|
|
1036
|
+
select: {
|
|
1037
|
+
component: SelectField,
|
|
1038
|
+
toEngineValue: (value) => isSelectValue(value) ? value : FIELD_CHANGE_IGNORED
|
|
1039
|
+
},
|
|
1040
|
+
checkbox: {
|
|
1041
|
+
component: Checkbox,
|
|
1042
|
+
toEngineValue: (value) => isCheckboxValue(value) ? value : FIELD_CHANGE_IGNORED,
|
|
1043
|
+
toComponentProps: (props) => {
|
|
1044
|
+
const componentProps = { ...props };
|
|
1045
|
+
const checked = isCheckboxValue(props.value) ? props.value : false;
|
|
1046
|
+
delete componentProps.value;
|
|
1047
|
+
delete componentProps.error;
|
|
1048
|
+
delete componentProps.helperText;
|
|
1049
|
+
return {
|
|
1050
|
+
...componentProps,
|
|
1051
|
+
checked,
|
|
1052
|
+
"aria-invalid": props.error === true
|
|
1053
|
+
};
|
|
1054
|
+
},
|
|
1055
|
+
rendersHelperText: false
|
|
1056
|
+
},
|
|
1057
|
+
switch: {
|
|
1058
|
+
component: Switch,
|
|
1059
|
+
toEngineValue: (value) => typeof value === "boolean" ? value : FIELD_CHANGE_IGNORED,
|
|
1060
|
+
toComponentProps: (props) => {
|
|
1061
|
+
const componentProps = { ...props };
|
|
1062
|
+
delete componentProps.value;
|
|
1063
|
+
delete componentProps.error;
|
|
1064
|
+
delete componentProps.helperText;
|
|
1065
|
+
delete componentProps.label;
|
|
1066
|
+
return {
|
|
1067
|
+
...componentProps,
|
|
1068
|
+
checked: typeof props.value === "boolean" ? props.value : false,
|
|
1069
|
+
"aria-invalid": props.error === true
|
|
1070
|
+
};
|
|
1071
|
+
},
|
|
1072
|
+
rendersHelperText: false,
|
|
1073
|
+
rendersLabel: false
|
|
1074
|
+
},
|
|
1075
|
+
radio: {
|
|
1076
|
+
component: RadioGroupField,
|
|
1077
|
+
toEngineValue: (value) => typeof value === "string" || typeof value === "number" ? value : FIELD_CHANGE_IGNORED
|
|
1078
|
+
},
|
|
1079
|
+
"segment-button": {
|
|
1080
|
+
component: SegmentButtonField,
|
|
1081
|
+
toEngineValue: (value) => isSegmentButtonValue(value) ? value : FIELD_CHANGE_IGNORED
|
|
1082
|
+
},
|
|
1083
|
+
slider: {
|
|
1084
|
+
component: SliderField,
|
|
1085
|
+
toEngineValue: (value) => isSliderValue(value) ? value : FIELD_CHANGE_IGNORED
|
|
1086
|
+
},
|
|
1087
|
+
time: {
|
|
1088
|
+
component: TimePickerField,
|
|
1089
|
+
toEngineValue: (value) => {
|
|
1090
|
+
const normalizedValue = normalizeTimeFieldValue(value);
|
|
1091
|
+
return normalizedValue === void 0 ? FIELD_CHANGE_IGNORED : normalizedValue;
|
|
1092
|
+
}
|
|
1093
|
+
},
|
|
1094
|
+
otp: {
|
|
1095
|
+
component: InputOtpField,
|
|
1096
|
+
toEngineValue: (value) => typeof value === "string" ? value : FIELD_CHANGE_IGNORED
|
|
1097
|
+
}
|
|
1098
|
+
};
|
|
1099
|
+
function readEventValue(change) {
|
|
1100
|
+
if (typeof change !== "object" || change === null || !("target" in change)) {
|
|
1101
|
+
return FIELD_CHANGE_IGNORED;
|
|
1102
|
+
}
|
|
1103
|
+
const target = change.target;
|
|
1104
|
+
if (typeof target !== "object" || target === null || !("value" in target)) {
|
|
1105
|
+
return FIELD_CHANGE_IGNORED;
|
|
1106
|
+
}
|
|
1107
|
+
return target.value;
|
|
1108
|
+
}
|
|
1109
|
+
function isCheckboxValue(value) {
|
|
1110
|
+
return typeof value === "boolean" || value === "indeterminate";
|
|
1111
|
+
}
|
|
1112
|
+
|
|
1113
|
+
// src/context/form-config.ts
|
|
1114
|
+
import { createContext, useContext } from "react";
|
|
1115
|
+
var ConfigContext = createContext({
|
|
1116
|
+
designMode: false
|
|
1117
|
+
});
|
|
1118
|
+
function useConfigContext() {
|
|
1119
|
+
const ctx = useContext(ConfigContext);
|
|
1120
|
+
if (!ctx) {
|
|
1121
|
+
throw new Error("Form Engine missing");
|
|
1122
|
+
}
|
|
1123
|
+
return ctx;
|
|
1124
|
+
}
|
|
1125
|
+
|
|
1126
|
+
// src/context/form-context.ts
|
|
1127
|
+
import { createContext as createContext2, useContext as useContext2 } from "react";
|
|
1128
|
+
var FormContext = createContext2(null);
|
|
1129
|
+
function useFormContext() {
|
|
1130
|
+
const ctx = useContext2(FormContext);
|
|
1131
|
+
if (!ctx) {
|
|
1132
|
+
throw new Error("Form Engine missing");
|
|
1133
|
+
}
|
|
1134
|
+
return ctx;
|
|
1135
|
+
}
|
|
1136
|
+
function useOptionalFormContext() {
|
|
1137
|
+
return useContext2(FormContext);
|
|
1138
|
+
}
|
|
1139
|
+
|
|
1140
|
+
// src/renderer/field-renderer.tsx
|
|
1141
|
+
import { useEffect, useState } from "react";
|
|
1142
|
+
|
|
1143
|
+
// src/renderer/design-visibility.ts
|
|
1144
|
+
import { useContext as useContext3 } from "react";
|
|
1145
|
+
function useDesignVisible(runtimeVisible) {
|
|
1146
|
+
const { designMode } = useContext3(ConfigContext);
|
|
1147
|
+
return designMode === true || runtimeVisible;
|
|
1148
|
+
}
|
|
1149
|
+
|
|
1150
|
+
// src/renderer/field-execution.ts
|
|
1151
|
+
function executeRendererFieldEvent(engine, nodeId, event, designMode, options) {
|
|
1152
|
+
if (designMode) {
|
|
1153
|
+
return void 0;
|
|
1154
|
+
}
|
|
1155
|
+
return engine.executeFieldEvent(nodeId, event, options);
|
|
1156
|
+
}
|
|
1157
|
+
|
|
1158
|
+
// src/renderer/repeat-renderer.tsx
|
|
1159
|
+
import { createContext as createContext3, useContext as useContext4 } from "react";
|
|
1160
|
+
import { jsx as jsx8, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
1161
|
+
var RepeatItemContext = createContext3(
|
|
1162
|
+
void 0
|
|
1163
|
+
);
|
|
1164
|
+
function useRepeatItem() {
|
|
1165
|
+
return useContext4(RepeatItemContext)?.item;
|
|
1166
|
+
}
|
|
1167
|
+
function useRepeatItemScope() {
|
|
1168
|
+
return useContext4(RepeatItemContext);
|
|
1169
|
+
}
|
|
1170
|
+
function RepeatRenderer({ node }) {
|
|
1171
|
+
if (node.schema.kind !== "layout" || node.schema.type !== "repeat") {
|
|
1172
|
+
return null;
|
|
1173
|
+
}
|
|
1174
|
+
const engine = useFormContext();
|
|
1175
|
+
const { designMode } = useConfigContext();
|
|
1176
|
+
const parentScope = useRepeatItemScope();
|
|
1177
|
+
const props = node.schema.props;
|
|
1178
|
+
const className = normalizeClassName2(props.className);
|
|
1179
|
+
const badge = describeRepeat(props);
|
|
1180
|
+
const parentPrefix = parentScope?.valuePrefix;
|
|
1181
|
+
if (designMode === true) {
|
|
1182
|
+
return /* @__PURE__ */ jsxs6(
|
|
1183
|
+
"div",
|
|
1184
|
+
{
|
|
1185
|
+
className: joinClassNames(
|
|
1186
|
+
"space-y-2 rounded border border-dashed border-gray-300 p-2",
|
|
1187
|
+
className
|
|
1188
|
+
),
|
|
1189
|
+
"data-repeat": "design",
|
|
1190
|
+
"data-repeat-mode": props.mode,
|
|
1191
|
+
children: [
|
|
1192
|
+
/* @__PURE__ */ jsxs6("div", { className: "text-[10px] font-medium uppercase tracking-wide text-gray-500", children: [
|
|
1193
|
+
"Repeat ",
|
|
1194
|
+
badge
|
|
1195
|
+
] }),
|
|
1196
|
+
node.children.map((child) => /* @__PURE__ */ jsx8(NodeRenderer, { node: child }, child.id))
|
|
1197
|
+
]
|
|
1198
|
+
}
|
|
1199
|
+
);
|
|
1200
|
+
}
|
|
1201
|
+
const items = engine.getRepeatItems(node.id, {
|
|
1202
|
+
...parentPrefix !== void 0 ? { valuePrefix: parentPrefix } : {}
|
|
1203
|
+
});
|
|
1204
|
+
const relativePath = props.mode === "values" && typeof props.path === "string" ? props.path.trim() : void 0;
|
|
1205
|
+
return /* @__PURE__ */ jsx8(
|
|
1206
|
+
"div",
|
|
1207
|
+
{
|
|
1208
|
+
className,
|
|
1209
|
+
"data-repeat": "runtime",
|
|
1210
|
+
"data-repeat-mode": props.mode,
|
|
1211
|
+
"data-repeat-count": items.length,
|
|
1212
|
+
children: items.map((item, index) => {
|
|
1213
|
+
const valuePrefix = relativePath !== void 0 ? joinPrefixes(parentPrefix, relativePath, String(index)) : parentPrefix;
|
|
1214
|
+
return /* @__PURE__ */ jsx8(
|
|
1215
|
+
RepeatItemContext.Provider,
|
|
1216
|
+
{
|
|
1217
|
+
value: {
|
|
1218
|
+
item,
|
|
1219
|
+
index,
|
|
1220
|
+
...valuePrefix !== void 0 ? { valuePrefix } : {}
|
|
1221
|
+
},
|
|
1222
|
+
children: /* @__PURE__ */ jsx8("div", { "data-repeat-index": index, children: node.children.map((child) => /* @__PURE__ */ jsx8(NodeRenderer, { node: child }, `${child.id}-${index}`)) })
|
|
1223
|
+
},
|
|
1224
|
+
`${node.id}-${index}`
|
|
1225
|
+
);
|
|
1226
|
+
})
|
|
1227
|
+
}
|
|
1228
|
+
);
|
|
1229
|
+
}
|
|
1230
|
+
function describeRepeat(props) {
|
|
1231
|
+
if (props.mode === "count") {
|
|
1232
|
+
return `\xD7${typeof props.count === "number" ? props.count : 0}`;
|
|
1233
|
+
}
|
|
1234
|
+
if (props.mode === "source" && typeof props.source === "string") {
|
|
1235
|
+
return `\u2190 ${props.source.trim()}`;
|
|
1236
|
+
}
|
|
1237
|
+
if (props.mode === "values" && typeof props.path === "string") {
|
|
1238
|
+
return `\u21C4 ${props.path.trim()}`;
|
|
1239
|
+
}
|
|
1240
|
+
return "";
|
|
1241
|
+
}
|
|
1242
|
+
function joinPrefixes(...parts) {
|
|
1243
|
+
return parts.filter((part) => typeof part === "string" && part.length > 0).join(".");
|
|
1244
|
+
}
|
|
1245
|
+
function normalizeClassName2(value) {
|
|
1246
|
+
return typeof value === "string" ? value.trim() : "";
|
|
1247
|
+
}
|
|
1248
|
+
function joinClassNames(...parts) {
|
|
1249
|
+
return parts.filter((part) => typeof part === "string" && part.length > 0).join(" ");
|
|
1250
|
+
}
|
|
1251
|
+
|
|
1252
|
+
// src/renderer/field-renderer.tsx
|
|
1253
|
+
import { jsx as jsx9, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
1254
|
+
function FieldRenderer({ node }) {
|
|
1255
|
+
if (node.schema.kind !== "field") return null;
|
|
1256
|
+
const engine = useFormContext();
|
|
1257
|
+
const { designMode } = useConfigContext();
|
|
1258
|
+
const repeatScope = useRepeatItemScope();
|
|
1259
|
+
const name = repeatScope?.valuePrefix !== void 0 ? `${repeatScope.valuePrefix}.${node.schema.name}` : node.schema.name;
|
|
1260
|
+
const [, forceUpdate] = useState(0);
|
|
1261
|
+
useEffect(() => {
|
|
1262
|
+
const unsubscribe = engine.subscribe(() => {
|
|
1263
|
+
forceUpdate((x) => x + 1);
|
|
1264
|
+
});
|
|
1265
|
+
return unsubscribe;
|
|
1266
|
+
}, [engine]);
|
|
1267
|
+
const runtimeVisible = engine.isVisible(name);
|
|
1268
|
+
const show = useDesignVisible(runtimeVisible);
|
|
1269
|
+
const definition = fieldRegistry[node.schema.type];
|
|
1270
|
+
if (!definition) {
|
|
1271
|
+
return null;
|
|
1272
|
+
}
|
|
1273
|
+
const fieldType = node.schema.type;
|
|
1274
|
+
const fireFieldEvent = (event) => {
|
|
1275
|
+
void executeRendererFieldEvent(
|
|
1276
|
+
engine,
|
|
1277
|
+
node.id,
|
|
1278
|
+
event,
|
|
1279
|
+
designMode === true
|
|
1280
|
+
);
|
|
1281
|
+
};
|
|
1282
|
+
const field = {
|
|
1283
|
+
value: engine.getValue(name),
|
|
1284
|
+
error: engine.getError(name),
|
|
1285
|
+
touched: engine.isTouched(name),
|
|
1286
|
+
touch: () => engine.touch(name),
|
|
1287
|
+
disabled: engine.isDisabled(name) || engine.isFormDisabled(),
|
|
1288
|
+
dirty: engine.isDirty(name),
|
|
1289
|
+
visible: runtimeVisible,
|
|
1290
|
+
setValue: (change) => {
|
|
1291
|
+
const value = definition.toEngineValue(change);
|
|
1292
|
+
if (value !== FIELD_CHANGE_IGNORED) {
|
|
1293
|
+
engine.setValue(name, value);
|
|
1294
|
+
if (fieldAllowsChangeEvent(fieldType)) {
|
|
1295
|
+
fireFieldEvent("change");
|
|
1296
|
+
}
|
|
1297
|
+
}
|
|
1298
|
+
}
|
|
1299
|
+
};
|
|
1300
|
+
if (!show) return null;
|
|
1301
|
+
const Component = definition.component;
|
|
1302
|
+
const options = engine.getOptions(name);
|
|
1303
|
+
const optionsLoading = engine.isOptionsSourceLoading(name);
|
|
1304
|
+
const engineState = engine.getState();
|
|
1305
|
+
const schema = node.schema.type === "select" || node.schema.type === "radio" || node.schema.type === "segment-button" ? {
|
|
1306
|
+
...node.schema,
|
|
1307
|
+
props: {
|
|
1308
|
+
...node.schema.props,
|
|
1309
|
+
options
|
|
1310
|
+
}
|
|
1311
|
+
} : node.schema;
|
|
1312
|
+
const props = adaptField({
|
|
1313
|
+
schema,
|
|
1314
|
+
field,
|
|
1315
|
+
setValue: field.setValue,
|
|
1316
|
+
state: {
|
|
1317
|
+
isLoading: engineState.isLoading,
|
|
1318
|
+
pendingActionIds: engineState.pendingActionIds,
|
|
1319
|
+
resourceInFlight: engineState.resourceInFlight
|
|
1320
|
+
},
|
|
1321
|
+
loading: optionsLoading
|
|
1322
|
+
});
|
|
1323
|
+
const helperText = typeof props.helperText === "string" ? props.helperText : void 0;
|
|
1324
|
+
const label = typeof schema.props?.label === "string" ? schema.props.label : void 0;
|
|
1325
|
+
const helperTextId = helperText ? `${node.id}-helper-text` : void 0;
|
|
1326
|
+
const inputId = repeatScope?.valuePrefix !== void 0 ? `${node.id}-${repeatScope.index}` : node.id;
|
|
1327
|
+
const baseComponentProps = {
|
|
1328
|
+
...props,
|
|
1329
|
+
id: inputId,
|
|
1330
|
+
name,
|
|
1331
|
+
"aria-describedby": helperTextId,
|
|
1332
|
+
onBlur: () => {
|
|
1333
|
+
field.touch();
|
|
1334
|
+
if (fieldAllowsBlurEvent(fieldType)) {
|
|
1335
|
+
fireFieldEvent("blur");
|
|
1336
|
+
}
|
|
1337
|
+
},
|
|
1338
|
+
...fieldAllowsCommitEvent(fieldType) ? {
|
|
1339
|
+
onCommit: (change) => {
|
|
1340
|
+
const value = definition.toEngineValue(change);
|
|
1341
|
+
if (value !== FIELD_CHANGE_IGNORED) {
|
|
1342
|
+
engine.setValue(name, value);
|
|
1343
|
+
field.touch();
|
|
1344
|
+
fireFieldEvent("commit");
|
|
1345
|
+
}
|
|
1346
|
+
}
|
|
1347
|
+
} : {}
|
|
1348
|
+
};
|
|
1349
|
+
const componentProps = definition.toComponentProps?.(baseComponentProps) ?? baseComponentProps;
|
|
1350
|
+
const component = /* @__PURE__ */ jsx9(Component, { ...componentProps });
|
|
1351
|
+
const externalLabel = definition.rendersLabel === false && label;
|
|
1352
|
+
const externalHelperText = definition.rendersHelperText === false && helperText;
|
|
1353
|
+
if (!externalLabel && !externalHelperText) {
|
|
1354
|
+
return component;
|
|
1355
|
+
}
|
|
1356
|
+
return /* @__PURE__ */ jsxs7("div", { className: "flex flex-col items-start", children: [
|
|
1357
|
+
externalLabel ? /* @__PURE__ */ jsx9("label", { htmlFor: inputId, className: "mb-1 text-sm text-fg", children: label }) : null,
|
|
1358
|
+
component,
|
|
1359
|
+
externalHelperText ? /* @__PURE__ */ jsx9(
|
|
1360
|
+
"p",
|
|
1361
|
+
{
|
|
1362
|
+
id: helperTextId,
|
|
1363
|
+
role: props.error ? "alert" : void 0,
|
|
1364
|
+
className: `mt-1 text-xs ${props.error ? "text-fg-error" : "text-fg-tertiary"}`,
|
|
1365
|
+
children: helperText
|
|
1366
|
+
}
|
|
1367
|
+
) : null
|
|
1368
|
+
] });
|
|
1369
|
+
}
|
|
1370
|
+
|
|
1371
|
+
// src/renderer/action-renderer.tsx
|
|
1372
|
+
import { adaptAction } from "@bsm-form/core";
|
|
1373
|
+
|
|
1374
|
+
// src/renderer/action-button.tsx
|
|
1375
|
+
import { isValidElement } from "react";
|
|
1376
|
+
import {
|
|
1377
|
+
Button
|
|
1378
|
+
} from "bsm-design-system";
|
|
1379
|
+
import { jsx as jsx10 } from "react/jsx-runtime";
|
|
1380
|
+
function ActionButton({
|
|
1381
|
+
"aria-label": ariaLabel,
|
|
1382
|
+
children,
|
|
1383
|
+
className,
|
|
1384
|
+
color,
|
|
1385
|
+
dangerouslySetInnerHTML: _dangerouslySetInnerHTML,
|
|
1386
|
+
disabled,
|
|
1387
|
+
iconOnly,
|
|
1388
|
+
leadingIcon,
|
|
1389
|
+
loading,
|
|
1390
|
+
rounded,
|
|
1391
|
+
size,
|
|
1392
|
+
traillingIcon,
|
|
1393
|
+
trailingIcon,
|
|
1394
|
+
variant,
|
|
1395
|
+
...props
|
|
1396
|
+
}) {
|
|
1397
|
+
const content = normalizeActionButtonContent(children);
|
|
1398
|
+
const isLoading = loading === true;
|
|
1399
|
+
const isDisabled = disabled === true;
|
|
1400
|
+
const resolvedTrailingIcon = normalizeActionButtonContent(
|
|
1401
|
+
trailingIcon ?? traillingIcon
|
|
1402
|
+
);
|
|
1403
|
+
return /* @__PURE__ */ jsx10(
|
|
1404
|
+
Button,
|
|
1405
|
+
{
|
|
1406
|
+
...props,
|
|
1407
|
+
type: "button",
|
|
1408
|
+
className: typeof className === "string" ? className : "",
|
|
1409
|
+
variant: normalizeButtonVariant(variant),
|
|
1410
|
+
color: normalizeButtonColor(color),
|
|
1411
|
+
size: normalizeButtonSize(size),
|
|
1412
|
+
loading: isLoading,
|
|
1413
|
+
disabled: isDisabled,
|
|
1414
|
+
iconOnly: iconOnly === true,
|
|
1415
|
+
leadingIcon: normalizeActionButtonContent(leadingIcon),
|
|
1416
|
+
trailingIcon: resolvedTrailingIcon,
|
|
1417
|
+
rounded: rounded === true,
|
|
1418
|
+
"aria-busy": isLoading || void 0,
|
|
1419
|
+
"aria-label": typeof ariaLabel === "string" && ariaLabel.trim() ? ariaLabel : getButtonAccessibleLabel(content),
|
|
1420
|
+
children: content
|
|
1421
|
+
}
|
|
1422
|
+
);
|
|
1423
|
+
}
|
|
1424
|
+
function normalizeButtonVariant(value) {
|
|
1425
|
+
return value === "ghost" || value === "outlined" || value === "text" ? value : "fill";
|
|
1426
|
+
}
|
|
1427
|
+
function normalizeButtonColor(value) {
|
|
1428
|
+
return value === "secondary" || value === "error" || value === "success" || value === "info" || value === "warning" ? value : "primary";
|
|
1429
|
+
}
|
|
1430
|
+
function normalizeButtonSize(value) {
|
|
1431
|
+
return value === "xs" || value === "sm" || value === "lg" ? value : "md";
|
|
1432
|
+
}
|
|
1433
|
+
function normalizeActionButtonContent(value) {
|
|
1434
|
+
if (typeof value === "string" || typeof value === "number" || isValidElement(value)) {
|
|
1435
|
+
return value;
|
|
1436
|
+
}
|
|
1437
|
+
return Array.isArray(value) ? value.map(normalizeActionButtonContent) : null;
|
|
1438
|
+
}
|
|
1439
|
+
function getButtonAccessibleLabel(content) {
|
|
1440
|
+
return typeof content === "string" || typeof content === "number" ? String(content) : void 0;
|
|
1441
|
+
}
|
|
1442
|
+
|
|
1443
|
+
// src/renderer/action-execution.ts
|
|
1444
|
+
function executeRendererAction(engine, actionId, designMode, options) {
|
|
1445
|
+
if (designMode) {
|
|
1446
|
+
return void 0;
|
|
1447
|
+
}
|
|
1448
|
+
return engine.executeAction(actionId, options);
|
|
1449
|
+
}
|
|
1450
|
+
|
|
1451
|
+
// src/renderer/action-renderer.tsx
|
|
1452
|
+
import { jsx as jsx11 } from "react/jsx-runtime";
|
|
1453
|
+
function ActionRenderer({ node }) {
|
|
1454
|
+
if (node.schema.kind !== "action") {
|
|
1455
|
+
return null;
|
|
1456
|
+
}
|
|
1457
|
+
const engine = useFormContext();
|
|
1458
|
+
const { designMode } = useConfigContext();
|
|
1459
|
+
const repeatScope = useRepeatItemScope();
|
|
1460
|
+
const show = useDesignVisible(node.state.visible);
|
|
1461
|
+
if (!show) {
|
|
1462
|
+
return null;
|
|
1463
|
+
}
|
|
1464
|
+
const schema = node.schema;
|
|
1465
|
+
const engineState = engine.getState();
|
|
1466
|
+
const stepperState = (schema.type === "stepper-next" || schema.type === "stepper-previous") && schema.stepperId ? engine.getStepperState(schema.stepperId) : void 0;
|
|
1467
|
+
const isStepperActionDisabled = schema.type === "stepper-next" ? !stepperState?.canGoNext || engineState.initializationStatus !== "ready" : schema.type === "stepper-previous" ? !stepperState?.canGoPrevious || engineState.initializationStatus !== "ready" : false;
|
|
1468
|
+
const isCustomPending = schema.type === "custom" && engineState.pendingActionIds.includes(node.id);
|
|
1469
|
+
const props = adaptAction({
|
|
1470
|
+
schema,
|
|
1471
|
+
onClick: () => {
|
|
1472
|
+
void executeRendererAction(
|
|
1473
|
+
engine,
|
|
1474
|
+
node.id,
|
|
1475
|
+
designMode === true,
|
|
1476
|
+
repeatScope !== void 0 ? {
|
|
1477
|
+
item: repeatScope.item,
|
|
1478
|
+
itemIndex: repeatScope.index,
|
|
1479
|
+
...repeatScope.valuePrefix !== void 0 ? {
|
|
1480
|
+
valuePrefix: parentValuePrefix(repeatScope.valuePrefix)
|
|
1481
|
+
} : {}
|
|
1482
|
+
} : void 0
|
|
1483
|
+
);
|
|
1484
|
+
},
|
|
1485
|
+
state: {
|
|
1486
|
+
isLoading: engineState.isLoading,
|
|
1487
|
+
pendingActionIds: engineState.pendingActionIds,
|
|
1488
|
+
resourceInFlight: engineState.resourceInFlight
|
|
1489
|
+
},
|
|
1490
|
+
loading: schema.type === "submit" && engineState.isSubmitting || isCustomPending,
|
|
1491
|
+
disabled: node.state.disabled || engine.isFormDisabled() || isStepperActionDisabled || isCustomPending
|
|
1492
|
+
});
|
|
1493
|
+
return /* @__PURE__ */ jsx11(ActionButton, { ...props, id: node.id });
|
|
1494
|
+
}
|
|
1495
|
+
function parentValuePrefix(itemValuePrefix) {
|
|
1496
|
+
const withoutIndex = itemValuePrefix.replace(/\.\d+$/, "");
|
|
1497
|
+
const lastDot = withoutIndex.lastIndexOf(".");
|
|
1498
|
+
return lastDot === -1 ? "" : withoutIndex.slice(0, lastDot);
|
|
1499
|
+
}
|
|
1500
|
+
|
|
1501
|
+
// src/renderer/display-renderer.tsx
|
|
1502
|
+
import { adaptDisplay } from "@bsm-form/core";
|
|
1503
|
+
import { useEffect as useEffect2, useState as useState2 } from "react";
|
|
1504
|
+
|
|
1505
|
+
// src/renderer/alert-display.tsx
|
|
1506
|
+
import { Alert } from "bsm-design-system";
|
|
1507
|
+
import { jsx as jsx12 } from "react/jsx-runtime";
|
|
1508
|
+
var ALERT_TYPES = [
|
|
1509
|
+
"success",
|
|
1510
|
+
"error",
|
|
1511
|
+
"warning",
|
|
1512
|
+
"info",
|
|
1513
|
+
"default"
|
|
1514
|
+
];
|
|
1515
|
+
var ALERT_VARIANTS = ["filled", "outline"];
|
|
1516
|
+
function AlertDisplay({
|
|
1517
|
+
type,
|
|
1518
|
+
variant,
|
|
1519
|
+
title,
|
|
1520
|
+
children,
|
|
1521
|
+
className,
|
|
1522
|
+
withIcon,
|
|
1523
|
+
closable,
|
|
1524
|
+
actionText,
|
|
1525
|
+
onClose,
|
|
1526
|
+
onAction
|
|
1527
|
+
}) {
|
|
1528
|
+
const normalizedTitle = normalizeAlertText(title);
|
|
1529
|
+
const normalizedContent = normalizeAlertText(children);
|
|
1530
|
+
const normalizedActionText = normalizeAlertText(actionText);
|
|
1531
|
+
const closeHandler = typeof onClose === "function" ? onClose : void 0;
|
|
1532
|
+
const actionHandler = normalizedActionText && typeof onAction === "function" ? onAction : void 0;
|
|
1533
|
+
if (!normalizedTitle && !normalizedContent) {
|
|
1534
|
+
return null;
|
|
1535
|
+
}
|
|
1536
|
+
return /* @__PURE__ */ jsx12(
|
|
1537
|
+
Alert,
|
|
1538
|
+
{
|
|
1539
|
+
type: normalizeAlertType(type),
|
|
1540
|
+
variant: normalizeAlertVariant(variant),
|
|
1541
|
+
title: normalizedTitle,
|
|
1542
|
+
className: normalizeAlertClassName(className) ?? "",
|
|
1543
|
+
withIcon: withIcon !== false,
|
|
1544
|
+
closable: closable === true,
|
|
1545
|
+
actionText: actionHandler ? normalizedActionText : void 0,
|
|
1546
|
+
onClose: closeHandler,
|
|
1547
|
+
onAction: actionHandler,
|
|
1548
|
+
children: normalizedContent
|
|
1549
|
+
}
|
|
1550
|
+
);
|
|
1551
|
+
}
|
|
1552
|
+
function normalizeAlertType(value) {
|
|
1553
|
+
return normalizeEnum(value, ALERT_TYPES, "default");
|
|
1554
|
+
}
|
|
1555
|
+
function normalizeAlertVariant(value) {
|
|
1556
|
+
return normalizeEnum(value, ALERT_VARIANTS, "filled");
|
|
1557
|
+
}
|
|
1558
|
+
function normalizeAlertText(value) {
|
|
1559
|
+
if (typeof value === "string") {
|
|
1560
|
+
const text = value.trim();
|
|
1561
|
+
return text || void 0;
|
|
1562
|
+
}
|
|
1563
|
+
if (typeof value === "number" && Number.isFinite(value)) {
|
|
1564
|
+
return String(value);
|
|
1565
|
+
}
|
|
1566
|
+
return void 0;
|
|
1567
|
+
}
|
|
1568
|
+
function normalizeAlertClassName(value) {
|
|
1569
|
+
if (typeof value !== "string") {
|
|
1570
|
+
return void 0;
|
|
1571
|
+
}
|
|
1572
|
+
const className = value.trim();
|
|
1573
|
+
return className || void 0;
|
|
1574
|
+
}
|
|
1575
|
+
function normalizeEnum(value, values, fallback) {
|
|
1576
|
+
if (typeof value !== "string") {
|
|
1577
|
+
return fallback;
|
|
1578
|
+
}
|
|
1579
|
+
const normalizedValue = value.trim().toLowerCase();
|
|
1580
|
+
return values.includes(normalizedValue) ? normalizedValue : fallback;
|
|
1581
|
+
}
|
|
1582
|
+
|
|
1583
|
+
// src/renderer/chips-display.tsx
|
|
1584
|
+
import { Chips } from "bsm-design-system";
|
|
1585
|
+
import { jsx as jsx13 } from "react/jsx-runtime";
|
|
1586
|
+
var CHIPS_VARIANTS = ["default", "secondary"];
|
|
1587
|
+
function ChipsDisplay({
|
|
1588
|
+
label,
|
|
1589
|
+
className,
|
|
1590
|
+
variant,
|
|
1591
|
+
rounded,
|
|
1592
|
+
disabled,
|
|
1593
|
+
onClose,
|
|
1594
|
+
onClick
|
|
1595
|
+
}) {
|
|
1596
|
+
const normalizedLabel = normalizeChipsLabel(label);
|
|
1597
|
+
if (normalizedLabel === void 0) {
|
|
1598
|
+
return null;
|
|
1599
|
+
}
|
|
1600
|
+
const closeHandler = typeof onClose === "function" ? () => {
|
|
1601
|
+
onClose();
|
|
1602
|
+
} : void 0;
|
|
1603
|
+
const clickHandler = typeof onClick === "function" ? () => {
|
|
1604
|
+
onClick();
|
|
1605
|
+
} : void 0;
|
|
1606
|
+
return /* @__PURE__ */ jsx13(
|
|
1607
|
+
Chips,
|
|
1608
|
+
{
|
|
1609
|
+
label: normalizedLabel,
|
|
1610
|
+
className: normalizeChipsClassName(className),
|
|
1611
|
+
variant: normalizeChipsVariant(variant),
|
|
1612
|
+
rounded: rounded === true,
|
|
1613
|
+
disabled: disabled === true,
|
|
1614
|
+
onClose: closeHandler,
|
|
1615
|
+
onClick: clickHandler
|
|
1616
|
+
}
|
|
1617
|
+
);
|
|
1618
|
+
}
|
|
1619
|
+
function normalizeChipsLabel(value) {
|
|
1620
|
+
if (typeof value === "string") {
|
|
1621
|
+
const label = value.trim();
|
|
1622
|
+
return label || void 0;
|
|
1623
|
+
}
|
|
1624
|
+
if (typeof value === "number" && Number.isFinite(value)) {
|
|
1625
|
+
return String(value);
|
|
1626
|
+
}
|
|
1627
|
+
return void 0;
|
|
1628
|
+
}
|
|
1629
|
+
function normalizeChipsVariant(value) {
|
|
1630
|
+
if (typeof value !== "string") {
|
|
1631
|
+
return "default";
|
|
1632
|
+
}
|
|
1633
|
+
const normalizedValue = value.trim().toLowerCase();
|
|
1634
|
+
return CHIPS_VARIANTS.includes(normalizedValue) ? normalizedValue : "default";
|
|
1635
|
+
}
|
|
1636
|
+
function normalizeChipsClassName(value) {
|
|
1637
|
+
if (typeof value !== "string") {
|
|
1638
|
+
return void 0;
|
|
1639
|
+
}
|
|
1640
|
+
const className = value.trim();
|
|
1641
|
+
return className || void 0;
|
|
1642
|
+
}
|
|
1643
|
+
|
|
1644
|
+
// src/renderer/tag-display.tsx
|
|
1645
|
+
import { Tag } from "bsm-design-system";
|
|
1646
|
+
import { jsx as jsx14 } from "react/jsx-runtime";
|
|
1647
|
+
var TAG_VARIANTS = [
|
|
1648
|
+
"default",
|
|
1649
|
+
"secondary",
|
|
1650
|
+
"error",
|
|
1651
|
+
"success",
|
|
1652
|
+
"warning",
|
|
1653
|
+
"info",
|
|
1654
|
+
"magenta",
|
|
1655
|
+
"cyan",
|
|
1656
|
+
"blue",
|
|
1657
|
+
"lime",
|
|
1658
|
+
"purple",
|
|
1659
|
+
"volcano"
|
|
1660
|
+
];
|
|
1661
|
+
var TAG_SIZES = ["md", "lg"];
|
|
1662
|
+
function TagDisplay({
|
|
1663
|
+
label,
|
|
1664
|
+
className,
|
|
1665
|
+
variant,
|
|
1666
|
+
size,
|
|
1667
|
+
rounded,
|
|
1668
|
+
borderLess
|
|
1669
|
+
}) {
|
|
1670
|
+
const normalizedLabel = normalizeTagLabel(label);
|
|
1671
|
+
if (normalizedLabel === void 0) {
|
|
1672
|
+
return null;
|
|
1673
|
+
}
|
|
1674
|
+
return /* @__PURE__ */ jsx14(
|
|
1675
|
+
Tag,
|
|
1676
|
+
{
|
|
1677
|
+
label: normalizedLabel,
|
|
1678
|
+
className: normalizeTagClassName(className),
|
|
1679
|
+
variant: normalizeTagVariant(variant),
|
|
1680
|
+
size: normalizeTagSize(size),
|
|
1681
|
+
rounded: rounded === true,
|
|
1682
|
+
borderLess: borderLess === true
|
|
1683
|
+
}
|
|
1684
|
+
);
|
|
1685
|
+
}
|
|
1686
|
+
function normalizeTagLabel(value) {
|
|
1687
|
+
if (typeof value === "string") {
|
|
1688
|
+
const label = value.trim();
|
|
1689
|
+
return label || void 0;
|
|
1690
|
+
}
|
|
1691
|
+
if (typeof value === "number" && Number.isFinite(value)) {
|
|
1692
|
+
return String(value);
|
|
1693
|
+
}
|
|
1694
|
+
return void 0;
|
|
1695
|
+
}
|
|
1696
|
+
function normalizeTagVariant(value) {
|
|
1697
|
+
return normalizeEnum2(value, TAG_VARIANTS, "default");
|
|
1698
|
+
}
|
|
1699
|
+
function normalizeTagSize(value) {
|
|
1700
|
+
return normalizeEnum2(value, TAG_SIZES, "md");
|
|
1701
|
+
}
|
|
1702
|
+
function normalizeTagClassName(value) {
|
|
1703
|
+
if (typeof value !== "string") {
|
|
1704
|
+
return void 0;
|
|
1705
|
+
}
|
|
1706
|
+
const className = value.trim();
|
|
1707
|
+
return className || void 0;
|
|
1708
|
+
}
|
|
1709
|
+
function normalizeEnum2(value, values, fallback) {
|
|
1710
|
+
if (typeof value !== "string") {
|
|
1711
|
+
return fallback;
|
|
1712
|
+
}
|
|
1713
|
+
const normalizedValue = value.trim().toLowerCase();
|
|
1714
|
+
return values.includes(normalizedValue) ? normalizedValue : fallback;
|
|
1715
|
+
}
|
|
1716
|
+
|
|
1717
|
+
// src/renderer/skeleton-display.tsx
|
|
1718
|
+
import { Skeleton } from "bsm-design-system";
|
|
1719
|
+
import { jsx as jsx15 } from "react/jsx-runtime";
|
|
1720
|
+
function SkeletonDisplay({
|
|
1721
|
+
ariaLabel,
|
|
1722
|
+
className
|
|
1723
|
+
}) {
|
|
1724
|
+
const normalizedAriaLabel = normalizeSkeletonAriaLabel(ariaLabel);
|
|
1725
|
+
return /* @__PURE__ */ jsx15(
|
|
1726
|
+
Skeleton,
|
|
1727
|
+
{
|
|
1728
|
+
className: normalizeSkeletonClassName(className),
|
|
1729
|
+
role: normalizedAriaLabel ? "status" : void 0,
|
|
1730
|
+
"aria-label": normalizedAriaLabel,
|
|
1731
|
+
"aria-busy": normalizedAriaLabel ? true : void 0,
|
|
1732
|
+
"aria-hidden": normalizedAriaLabel ? void 0 : true
|
|
1733
|
+
}
|
|
1734
|
+
);
|
|
1735
|
+
}
|
|
1736
|
+
function normalizeSkeletonAriaLabel(value) {
|
|
1737
|
+
if (typeof value !== "string") {
|
|
1738
|
+
return void 0;
|
|
1739
|
+
}
|
|
1740
|
+
const ariaLabel = value.trim();
|
|
1741
|
+
return ariaLabel || void 0;
|
|
1742
|
+
}
|
|
1743
|
+
function normalizeSkeletonClassName(value) {
|
|
1744
|
+
if (typeof value !== "string") {
|
|
1745
|
+
return void 0;
|
|
1746
|
+
}
|
|
1747
|
+
const className = value.trim();
|
|
1748
|
+
return className || void 0;
|
|
1749
|
+
}
|
|
1750
|
+
|
|
1751
|
+
// src/renderer/table-display.tsx
|
|
1752
|
+
import { Button as Button2, Table, Tag as Tag2 } from "bsm-design-system";
|
|
1753
|
+
import { jsx as jsx16, jsxs as jsxs8 } from "react/jsx-runtime";
|
|
1754
|
+
var TABLE_ALIGNS = ["left", "right", "center"];
|
|
1755
|
+
var ACTION_VARIANTS = ["fill", "outlined", "ghost", "text"];
|
|
1756
|
+
var ACTION_COLORS = [
|
|
1757
|
+
"primary",
|
|
1758
|
+
"secondary",
|
|
1759
|
+
"success",
|
|
1760
|
+
"error",
|
|
1761
|
+
"info",
|
|
1762
|
+
"warning"
|
|
1763
|
+
];
|
|
1764
|
+
function TableDisplay({
|
|
1765
|
+
align,
|
|
1766
|
+
bordered,
|
|
1767
|
+
caption,
|
|
1768
|
+
className,
|
|
1769
|
+
columns,
|
|
1770
|
+
onActionClick,
|
|
1771
|
+
onRowClick,
|
|
1772
|
+
pendingTableInteractions,
|
|
1773
|
+
rows,
|
|
1774
|
+
separated,
|
|
1775
|
+
tableNodeId
|
|
1776
|
+
}) {
|
|
1777
|
+
const normalizedColumns = normalizeTableColumns(columns);
|
|
1778
|
+
const normalizedRows = Array.isArray(rows) ? rows : [];
|
|
1779
|
+
const normalizedCaption = normalizeTableCaption(caption);
|
|
1780
|
+
const rowInteractive = typeof onRowClick === "function";
|
|
1781
|
+
const pending = Array.isArray(pendingTableInteractions) ? pendingTableInteractions : [];
|
|
1782
|
+
return /* @__PURE__ */ jsx16(Table.Container, { className: normalizeTableClassName(className), children: /* @__PURE__ */ jsxs8(
|
|
1783
|
+
Table,
|
|
1784
|
+
{
|
|
1785
|
+
align: normalizeTableAlign(align),
|
|
1786
|
+
bordered: bordered === true,
|
|
1787
|
+
separated: separated === true,
|
|
1788
|
+
children: [
|
|
1789
|
+
normalizedCaption ? /* @__PURE__ */ jsx16(Table.Caption, { children: normalizedCaption }) : null,
|
|
1790
|
+
/* @__PURE__ */ jsx16(Table.Header, { children: /* @__PURE__ */ jsx16(Table.Row, { children: normalizedColumns.map((column) => /* @__PURE__ */ jsx16(
|
|
1791
|
+
Table.Head,
|
|
1792
|
+
{
|
|
1793
|
+
className: column.kind === "actions" ? "text-end" : void 0,
|
|
1794
|
+
children: column.header
|
|
1795
|
+
},
|
|
1796
|
+
column.id
|
|
1797
|
+
)) }) }),
|
|
1798
|
+
/* @__PURE__ */ jsx16(Table.Body, { children: normalizedRows.map((row, rowIndex) => /* @__PURE__ */ jsx16(
|
|
1799
|
+
Table.Row,
|
|
1800
|
+
{
|
|
1801
|
+
onClick: rowInteractive ? () => {
|
|
1802
|
+
onRowClick(rowIndex);
|
|
1803
|
+
} : void 0,
|
|
1804
|
+
style: rowInteractive ? { cursor: "pointer" } : void 0,
|
|
1805
|
+
children: normalizedColumns.map((column) => /* @__PURE__ */ jsx16(
|
|
1806
|
+
Table.Cell,
|
|
1807
|
+
{
|
|
1808
|
+
className: column.kind === "actions" ? "text-end" : void 0,
|
|
1809
|
+
children: renderTableCell({
|
|
1810
|
+
column,
|
|
1811
|
+
onActionClick,
|
|
1812
|
+
pendingTableInteractions: pending,
|
|
1813
|
+
row,
|
|
1814
|
+
rowIndex,
|
|
1815
|
+
tableNodeId: typeof tableNodeId === "string" ? tableNodeId : void 0
|
|
1816
|
+
})
|
|
1817
|
+
},
|
|
1818
|
+
column.id
|
|
1819
|
+
))
|
|
1820
|
+
},
|
|
1821
|
+
rowIndex
|
|
1822
|
+
)) })
|
|
1823
|
+
]
|
|
1824
|
+
}
|
|
1825
|
+
) });
|
|
1826
|
+
}
|
|
1827
|
+
function renderTableCell({
|
|
1828
|
+
column,
|
|
1829
|
+
onActionClick,
|
|
1830
|
+
pendingTableInteractions,
|
|
1831
|
+
row,
|
|
1832
|
+
rowIndex,
|
|
1833
|
+
tableNodeId
|
|
1834
|
+
}) {
|
|
1835
|
+
if (column.kind === "actions") {
|
|
1836
|
+
return /* @__PURE__ */ jsx16("div", { className: "flex flex-wrap items-center justify-end gap-2", children: column.actions.map((action) => {
|
|
1837
|
+
const iconOnly = action.iconOnly === true;
|
|
1838
|
+
const pendingKey = tableNodeId !== void 0 ? `${tableNodeId}:${column.id}:${action.id}:${rowIndex}` : void 0;
|
|
1839
|
+
const isPending = pendingKey !== void 0 && pendingTableInteractions.includes(pendingKey);
|
|
1840
|
+
return /* @__PURE__ */ jsx16(
|
|
1841
|
+
Button2,
|
|
1842
|
+
{
|
|
1843
|
+
type: "button",
|
|
1844
|
+
size: "xs",
|
|
1845
|
+
variant: normalizeActionVariant(action.variant),
|
|
1846
|
+
color: normalizeActionColor(action.color),
|
|
1847
|
+
iconOnly,
|
|
1848
|
+
"aria-label": action.label,
|
|
1849
|
+
loading: isPending,
|
|
1850
|
+
disabled: isPending,
|
|
1851
|
+
onClick: (event) => {
|
|
1852
|
+
event.stopPropagation();
|
|
1853
|
+
onActionClick?.(column.id, action.id, rowIndex);
|
|
1854
|
+
},
|
|
1855
|
+
children: action.label
|
|
1856
|
+
},
|
|
1857
|
+
action.id
|
|
1858
|
+
);
|
|
1859
|
+
}) });
|
|
1860
|
+
}
|
|
1861
|
+
if (column.kind === "tag") {
|
|
1862
|
+
const rawValue = readTableCellValue(row, column.path);
|
|
1863
|
+
const mapped = resolveTableTagMapping(rawValue, column.map);
|
|
1864
|
+
const label = normalizeTagLabel(mapped?.label ?? rawValue);
|
|
1865
|
+
if (label === void 0) {
|
|
1866
|
+
return null;
|
|
1867
|
+
}
|
|
1868
|
+
const variantFromPath = column.variantPath !== void 0 ? readTableCellValue(row, column.variantPath) : void 0;
|
|
1869
|
+
return /* @__PURE__ */ jsx16(
|
|
1870
|
+
Tag2,
|
|
1871
|
+
{
|
|
1872
|
+
label,
|
|
1873
|
+
variant: normalizeTagVariant(
|
|
1874
|
+
mapped?.variant ?? variantFromPath ?? column.variant
|
|
1875
|
+
)
|
|
1876
|
+
}
|
|
1877
|
+
);
|
|
1878
|
+
}
|
|
1879
|
+
return formatTableCellValue(readTableCellValue(row, column.path));
|
|
1880
|
+
}
|
|
1881
|
+
function normalizeTableColumns(value) {
|
|
1882
|
+
if (!Array.isArray(value)) {
|
|
1883
|
+
return [];
|
|
1884
|
+
}
|
|
1885
|
+
return value.flatMap((column) => {
|
|
1886
|
+
const normalized = normalizeTableColumn(column);
|
|
1887
|
+
return normalized ? [normalized] : [];
|
|
1888
|
+
});
|
|
1889
|
+
}
|
|
1890
|
+
function normalizeTableColumn(value) {
|
|
1891
|
+
if (typeof value !== "object" || value === null || typeof value.id !== "string" || value.id.trim() === "" || typeof value.header !== "string" || value.header.trim() === "") {
|
|
1892
|
+
return void 0;
|
|
1893
|
+
}
|
|
1894
|
+
const column = value;
|
|
1895
|
+
const id = column.id;
|
|
1896
|
+
const header = column.header;
|
|
1897
|
+
const kind = column.kind;
|
|
1898
|
+
if (kind === "actions") {
|
|
1899
|
+
const actions = normalizeTableColumnActions(column.actions);
|
|
1900
|
+
if (actions.length === 0) {
|
|
1901
|
+
return void 0;
|
|
1902
|
+
}
|
|
1903
|
+
return {
|
|
1904
|
+
id,
|
|
1905
|
+
header,
|
|
1906
|
+
kind: "actions",
|
|
1907
|
+
actions
|
|
1908
|
+
};
|
|
1909
|
+
}
|
|
1910
|
+
if (typeof column.path !== "string" || column.path.trim() === "") {
|
|
1911
|
+
return void 0;
|
|
1912
|
+
}
|
|
1913
|
+
if (kind === "tag") {
|
|
1914
|
+
const tagColumn = {
|
|
1915
|
+
id,
|
|
1916
|
+
header,
|
|
1917
|
+
kind: "tag",
|
|
1918
|
+
path: column.path
|
|
1919
|
+
};
|
|
1920
|
+
if (typeof column.variantPath === "string" && column.variantPath.trim() !== "") {
|
|
1921
|
+
tagColumn.variantPath = column.variantPath;
|
|
1922
|
+
}
|
|
1923
|
+
const variant = normalizeOptionalTagVariant(column.variant);
|
|
1924
|
+
if (variant) {
|
|
1925
|
+
tagColumn.variant = variant;
|
|
1926
|
+
}
|
|
1927
|
+
const map = normalizeTableTagMap(column.map);
|
|
1928
|
+
if (map) {
|
|
1929
|
+
tagColumn.map = map;
|
|
1930
|
+
}
|
|
1931
|
+
return tagColumn;
|
|
1932
|
+
}
|
|
1933
|
+
if (kind !== void 0 && kind !== "text") {
|
|
1934
|
+
return void 0;
|
|
1935
|
+
}
|
|
1936
|
+
return {
|
|
1937
|
+
id,
|
|
1938
|
+
header,
|
|
1939
|
+
kind: "text",
|
|
1940
|
+
path: column.path
|
|
1941
|
+
};
|
|
1942
|
+
}
|
|
1943
|
+
function normalizeTableColumnActions(value) {
|
|
1944
|
+
if (!Array.isArray(value)) {
|
|
1945
|
+
return [];
|
|
1946
|
+
}
|
|
1947
|
+
return value.flatMap((action) => {
|
|
1948
|
+
if (typeof action !== "object" || action === null || typeof action.id !== "string" || action.id.trim() === "" || typeof action.label !== "string" || action.label.trim() === "" || !Array.isArray(action.steps)) {
|
|
1949
|
+
return [];
|
|
1950
|
+
}
|
|
1951
|
+
const normalized = {
|
|
1952
|
+
id: action.id,
|
|
1953
|
+
label: action.label,
|
|
1954
|
+
steps: action.steps
|
|
1955
|
+
};
|
|
1956
|
+
if (typeof action.variant === "string" && ACTION_VARIANTS.includes(
|
|
1957
|
+
action.variant
|
|
1958
|
+
)) {
|
|
1959
|
+
normalized.variant = action.variant;
|
|
1960
|
+
}
|
|
1961
|
+
if (typeof action.color === "string" && action.color.trim() !== "") {
|
|
1962
|
+
const color = normalizeActionColor(action.color);
|
|
1963
|
+
if (color) {
|
|
1964
|
+
normalized.color = color;
|
|
1965
|
+
}
|
|
1966
|
+
}
|
|
1967
|
+
if (action.iconOnly === true) {
|
|
1968
|
+
normalized.iconOnly = true;
|
|
1969
|
+
}
|
|
1970
|
+
return [normalized];
|
|
1971
|
+
});
|
|
1972
|
+
}
|
|
1973
|
+
function normalizeTableAlign(value) {
|
|
1974
|
+
return normalizeEnum3(value, TABLE_ALIGNS, "left");
|
|
1975
|
+
}
|
|
1976
|
+
function normalizeTableCaption(value) {
|
|
1977
|
+
if (typeof value !== "string") {
|
|
1978
|
+
return void 0;
|
|
1979
|
+
}
|
|
1980
|
+
const caption = value.trim();
|
|
1981
|
+
return caption || void 0;
|
|
1982
|
+
}
|
|
1983
|
+
function normalizeTableClassName(value) {
|
|
1984
|
+
if (typeof value !== "string") {
|
|
1985
|
+
return void 0;
|
|
1986
|
+
}
|
|
1987
|
+
const className = value.trim();
|
|
1988
|
+
return className || void 0;
|
|
1989
|
+
}
|
|
1990
|
+
function readTableCellValue(row, path) {
|
|
1991
|
+
if (!path) {
|
|
1992
|
+
return void 0;
|
|
1993
|
+
}
|
|
1994
|
+
let current = row;
|
|
1995
|
+
for (const key of path.split(".")) {
|
|
1996
|
+
if (typeof current !== "object" || current === null) {
|
|
1997
|
+
return void 0;
|
|
1998
|
+
}
|
|
1999
|
+
current = current[key];
|
|
2000
|
+
}
|
|
2001
|
+
return current;
|
|
2002
|
+
}
|
|
2003
|
+
function formatTableCellValue(value) {
|
|
2004
|
+
if (value === void 0 || value === null) {
|
|
2005
|
+
return "";
|
|
2006
|
+
}
|
|
2007
|
+
if (typeof value === "string") {
|
|
2008
|
+
return value;
|
|
2009
|
+
}
|
|
2010
|
+
if (typeof value === "number" && Number.isFinite(value)) {
|
|
2011
|
+
return String(value);
|
|
2012
|
+
}
|
|
2013
|
+
if (typeof value === "boolean") {
|
|
2014
|
+
return value ? "true" : "false";
|
|
2015
|
+
}
|
|
2016
|
+
try {
|
|
2017
|
+
return JSON.stringify(value) ?? "";
|
|
2018
|
+
} catch {
|
|
2019
|
+
return "";
|
|
2020
|
+
}
|
|
2021
|
+
}
|
|
2022
|
+
function resolveTableTagMapping(value, map) {
|
|
2023
|
+
if (!map) {
|
|
2024
|
+
return void 0;
|
|
2025
|
+
}
|
|
2026
|
+
const key = tableTagMapKey(value);
|
|
2027
|
+
if (key === void 0) {
|
|
2028
|
+
return void 0;
|
|
2029
|
+
}
|
|
2030
|
+
if (map[key]) {
|
|
2031
|
+
return map[key];
|
|
2032
|
+
}
|
|
2033
|
+
const trimmed = key.trim();
|
|
2034
|
+
if (trimmed !== key && map[trimmed]) {
|
|
2035
|
+
return map[trimmed];
|
|
2036
|
+
}
|
|
2037
|
+
for (const [mapKey, mapping] of Object.entries(map)) {
|
|
2038
|
+
if (mapKey.trim() === trimmed) {
|
|
2039
|
+
return mapping;
|
|
2040
|
+
}
|
|
2041
|
+
}
|
|
2042
|
+
return void 0;
|
|
2043
|
+
}
|
|
2044
|
+
function tableTagMapKey(value) {
|
|
2045
|
+
if (typeof value === "string") {
|
|
2046
|
+
return value;
|
|
2047
|
+
}
|
|
2048
|
+
if (typeof value === "number" && Number.isFinite(value)) {
|
|
2049
|
+
return String(value);
|
|
2050
|
+
}
|
|
2051
|
+
if (typeof value === "boolean") {
|
|
2052
|
+
return value ? "true" : "false";
|
|
2053
|
+
}
|
|
2054
|
+
return void 0;
|
|
2055
|
+
}
|
|
2056
|
+
function normalizeTableTagMap(value) {
|
|
2057
|
+
if (typeof value !== "object" || value === null || Array.isArray(value)) {
|
|
2058
|
+
return void 0;
|
|
2059
|
+
}
|
|
2060
|
+
const map = {};
|
|
2061
|
+
for (const [rawKey, entry] of Object.entries(value)) {
|
|
2062
|
+
const key = rawKey.trim();
|
|
2063
|
+
if (key === "" || typeof entry !== "object" || entry === null || Array.isArray(entry)) {
|
|
2064
|
+
continue;
|
|
2065
|
+
}
|
|
2066
|
+
const mapping = {};
|
|
2067
|
+
if (typeof entry.label === "string" && entry.label.trim() !== "") {
|
|
2068
|
+
mapping.label = entry.label.trim();
|
|
2069
|
+
}
|
|
2070
|
+
const variant = normalizeOptionalTagVariant(entry.variant);
|
|
2071
|
+
if (variant) {
|
|
2072
|
+
mapping.variant = variant;
|
|
2073
|
+
}
|
|
2074
|
+
if (mapping.label !== void 0 || mapping.variant !== void 0) {
|
|
2075
|
+
map[key] = mapping;
|
|
2076
|
+
}
|
|
2077
|
+
}
|
|
2078
|
+
return Object.keys(map).length > 0 ? map : void 0;
|
|
2079
|
+
}
|
|
2080
|
+
function normalizeOptionalTagVariant(value) {
|
|
2081
|
+
if (typeof value !== "string") {
|
|
2082
|
+
return void 0;
|
|
2083
|
+
}
|
|
2084
|
+
const normalized = value.trim().toLowerCase();
|
|
2085
|
+
return TAG_VARIANTS.includes(normalized) ? normalized : void 0;
|
|
2086
|
+
}
|
|
2087
|
+
function normalizeActionVariant(value) {
|
|
2088
|
+
return normalizeEnum3(value, ACTION_VARIANTS, "ghost");
|
|
2089
|
+
}
|
|
2090
|
+
function normalizeActionColor(value) {
|
|
2091
|
+
if (typeof value !== "string") {
|
|
2092
|
+
return void 0;
|
|
2093
|
+
}
|
|
2094
|
+
const color = value.trim().toLowerCase();
|
|
2095
|
+
return ACTION_COLORS.includes(color) ? color : void 0;
|
|
2096
|
+
}
|
|
2097
|
+
function normalizeEnum3(value, values, fallback) {
|
|
2098
|
+
if (typeof value !== "string") {
|
|
2099
|
+
return fallback;
|
|
2100
|
+
}
|
|
2101
|
+
const normalizedValue = value.trim().toLowerCase();
|
|
2102
|
+
return values.includes(normalizedValue) ? normalizedValue : fallback;
|
|
2103
|
+
}
|
|
2104
|
+
|
|
2105
|
+
// src/renderer/typography-display.tsx
|
|
2106
|
+
import { createElement } from "react";
|
|
2107
|
+
var TYPOGRAPHY_TAGS = /* @__PURE__ */ new Set([
|
|
2108
|
+
"p",
|
|
2109
|
+
"span",
|
|
2110
|
+
"h1",
|
|
2111
|
+
"h2",
|
|
2112
|
+
"h3",
|
|
2113
|
+
"h4",
|
|
2114
|
+
"h5",
|
|
2115
|
+
"h6",
|
|
2116
|
+
"label",
|
|
2117
|
+
"strong",
|
|
2118
|
+
"em"
|
|
2119
|
+
]);
|
|
2120
|
+
function TypographyDisplay({
|
|
2121
|
+
as,
|
|
2122
|
+
className,
|
|
2123
|
+
children,
|
|
2124
|
+
designPlaceholder
|
|
2125
|
+
}) {
|
|
2126
|
+
const text = normalizeTypographyChildren(children);
|
|
2127
|
+
const placeholder = normalizeTypographyPlaceholder(designPlaceholder);
|
|
2128
|
+
const Tag3 = normalizeTypographyAs(as);
|
|
2129
|
+
const baseClassName = normalizeTypographyClassName(className);
|
|
2130
|
+
if (text !== "") {
|
|
2131
|
+
return createElement(Tag3, {
|
|
2132
|
+
className: baseClassName,
|
|
2133
|
+
children: text
|
|
2134
|
+
});
|
|
2135
|
+
}
|
|
2136
|
+
if (!placeholder) {
|
|
2137
|
+
return null;
|
|
2138
|
+
}
|
|
2139
|
+
return createElement(Tag3, {
|
|
2140
|
+
className: [baseClassName, "opacity-50 italic text-gray-400"].filter(Boolean).join(" "),
|
|
2141
|
+
"data-typography-placeholder": "",
|
|
2142
|
+
children: placeholder
|
|
2143
|
+
});
|
|
2144
|
+
}
|
|
2145
|
+
function normalizeTypographyAs(value) {
|
|
2146
|
+
return typeof value === "string" && TYPOGRAPHY_TAGS.has(value) ? value : "p";
|
|
2147
|
+
}
|
|
2148
|
+
function normalizeTypographyClassName(value) {
|
|
2149
|
+
if (typeof value !== "string") {
|
|
2150
|
+
return void 0;
|
|
2151
|
+
}
|
|
2152
|
+
const className = value.trim();
|
|
2153
|
+
return className || void 0;
|
|
2154
|
+
}
|
|
2155
|
+
function normalizeTypographyChildren(value) {
|
|
2156
|
+
if (typeof value !== "string") {
|
|
2157
|
+
return "";
|
|
2158
|
+
}
|
|
2159
|
+
return value;
|
|
2160
|
+
}
|
|
2161
|
+
function normalizeTypographyPlaceholder(value) {
|
|
2162
|
+
if (typeof value !== "string") {
|
|
2163
|
+
return void 0;
|
|
2164
|
+
}
|
|
2165
|
+
const placeholder = value.trim();
|
|
2166
|
+
return placeholder || void 0;
|
|
2167
|
+
}
|
|
2168
|
+
|
|
2169
|
+
// src/renderer/slot-display.tsx
|
|
2170
|
+
import { Fragment as Fragment2, jsx as jsx17 } from "react/jsx-runtime";
|
|
2171
|
+
function SlotDisplay({
|
|
2172
|
+
className,
|
|
2173
|
+
children,
|
|
2174
|
+
designPlaceholder
|
|
2175
|
+
}) {
|
|
2176
|
+
if (children == null) {
|
|
2177
|
+
if (designPlaceholder === void 0) {
|
|
2178
|
+
return null;
|
|
2179
|
+
}
|
|
2180
|
+
return /* @__PURE__ */ jsx17(
|
|
2181
|
+
"div",
|
|
2182
|
+
{
|
|
2183
|
+
className: [
|
|
2184
|
+
"rounded border border-dashed border-stroke-secondary px-3 py-2 text-xs text-fg-tertiary",
|
|
2185
|
+
className
|
|
2186
|
+
].filter(Boolean).join(" "),
|
|
2187
|
+
"data-slot-placeholder": "",
|
|
2188
|
+
children: designPlaceholder
|
|
2189
|
+
}
|
|
2190
|
+
);
|
|
2191
|
+
}
|
|
2192
|
+
if (className) {
|
|
2193
|
+
return /* @__PURE__ */ jsx17("div", { className, children });
|
|
2194
|
+
}
|
|
2195
|
+
return /* @__PURE__ */ jsx17(Fragment2, { children });
|
|
2196
|
+
}
|
|
2197
|
+
|
|
2198
|
+
// src/registry/display-registry.ts
|
|
2199
|
+
var displayRegistry = {
|
|
2200
|
+
alert: AlertDisplay,
|
|
2201
|
+
chips: ChipsDisplay,
|
|
2202
|
+
skeleton: SkeletonDisplay,
|
|
2203
|
+
tag: TagDisplay,
|
|
2204
|
+
table: TableDisplay,
|
|
2205
|
+
typography: TypographyDisplay,
|
|
2206
|
+
slot: SlotDisplay
|
|
2207
|
+
};
|
|
2208
|
+
|
|
2209
|
+
// src/renderer/display-execution.ts
|
|
2210
|
+
function executeRendererDisplayEvent(engine, nodeId, event, designMode, options) {
|
|
2211
|
+
if (designMode) {
|
|
2212
|
+
return void 0;
|
|
2213
|
+
}
|
|
2214
|
+
return engine.executeDisplayEvent(nodeId, event, options);
|
|
2215
|
+
}
|
|
2216
|
+
function executeRendererTableInteraction(engine, nodeId, interaction, designMode) {
|
|
2217
|
+
if (designMode) {
|
|
2218
|
+
return void 0;
|
|
2219
|
+
}
|
|
2220
|
+
return engine.executeTableInteraction(nodeId, interaction);
|
|
2221
|
+
}
|
|
2222
|
+
|
|
2223
|
+
// src/renderer/display-renderer.tsx
|
|
2224
|
+
import { jsx as jsx18 } from "react/jsx-runtime";
|
|
2225
|
+
function DisplayRenderer({ node }) {
|
|
2226
|
+
const schema = node.schema;
|
|
2227
|
+
const engine = useOptionalFormContext();
|
|
2228
|
+
const { designMode, slots } = useConfigContext();
|
|
2229
|
+
const repeatItem = useRepeatItem();
|
|
2230
|
+
const show = useDesignVisible(node.state.visible);
|
|
2231
|
+
const [, forceUpdate] = useState2(0);
|
|
2232
|
+
useEffect2(() => {
|
|
2233
|
+
if (!engine) {
|
|
2234
|
+
return;
|
|
2235
|
+
}
|
|
2236
|
+
return engine.subscribe(() => {
|
|
2237
|
+
forceUpdate((value) => value + 1);
|
|
2238
|
+
});
|
|
2239
|
+
}, [engine]);
|
|
2240
|
+
if (schema.kind !== "display" || !show) {
|
|
2241
|
+
return null;
|
|
2242
|
+
}
|
|
2243
|
+
const Component = displayRegistry[schema.type];
|
|
2244
|
+
if (!Component) {
|
|
2245
|
+
return null;
|
|
2246
|
+
}
|
|
2247
|
+
const executeEvent = (event) => {
|
|
2248
|
+
if (!engine) {
|
|
2249
|
+
return;
|
|
2250
|
+
}
|
|
2251
|
+
void executeRendererDisplayEvent(
|
|
2252
|
+
engine,
|
|
2253
|
+
node.id,
|
|
2254
|
+
event,
|
|
2255
|
+
designMode === true,
|
|
2256
|
+
repeatItem !== void 0 ? { item: repeatItem } : void 0
|
|
2257
|
+
);
|
|
2258
|
+
};
|
|
2259
|
+
const props = adaptDisplay({
|
|
2260
|
+
schema,
|
|
2261
|
+
onClose: () => executeEvent("close"),
|
|
2262
|
+
onAction: () => executeEvent("action"),
|
|
2263
|
+
onClick: () => executeEvent("click"),
|
|
2264
|
+
disabled: node.state.disabled
|
|
2265
|
+
});
|
|
2266
|
+
if (schema.type === "table") {
|
|
2267
|
+
const hasRowClick = Array.isArray(schema.events?.rowClick?.steps) && schema.events.rowClick.steps.length > 0;
|
|
2268
|
+
const engineState = engine?.getState();
|
|
2269
|
+
const rows = engine?.getTableRows(
|
|
2270
|
+
node.id,
|
|
2271
|
+
repeatItem !== void 0 ? { item: repeatItem } : void 0
|
|
2272
|
+
) ?? [];
|
|
2273
|
+
return /* @__PURE__ */ jsx18(
|
|
2274
|
+
Component,
|
|
2275
|
+
{
|
|
2276
|
+
...props,
|
|
2277
|
+
columns: schema.columns,
|
|
2278
|
+
rows,
|
|
2279
|
+
tableNodeId: node.id,
|
|
2280
|
+
pendingTableInteractions: engineState?.pendingTableInteractions ?? [],
|
|
2281
|
+
onRowClick: hasRowClick && engine ? (rowIndex) => {
|
|
2282
|
+
void executeRendererTableInteraction(
|
|
2283
|
+
engine,
|
|
2284
|
+
node.id,
|
|
2285
|
+
{ kind: "rowClick", rowIndex },
|
|
2286
|
+
designMode === true
|
|
2287
|
+
);
|
|
2288
|
+
} : void 0,
|
|
2289
|
+
onActionClick: engine ? (columnId, actionId, rowIndex) => {
|
|
2290
|
+
void executeRendererTableInteraction(
|
|
2291
|
+
engine,
|
|
2292
|
+
node.id,
|
|
2293
|
+
{ kind: "action", columnId, actionId, rowIndex },
|
|
2294
|
+
designMode === true
|
|
2295
|
+
);
|
|
2296
|
+
} : void 0
|
|
2297
|
+
}
|
|
2298
|
+
);
|
|
2299
|
+
}
|
|
2300
|
+
if (schema.type === "typography") {
|
|
2301
|
+
const text = engine?.getTypographyText(
|
|
2302
|
+
node.id,
|
|
2303
|
+
repeatItem !== void 0 ? { item: repeatItem } : void 0
|
|
2304
|
+
) ?? "";
|
|
2305
|
+
const designPlaceholder = designMode === true && text === "" ? typeof schema.props.from === "string" && schema.props.from.trim() ? schema.props.from.trim() : "Typography" : void 0;
|
|
2306
|
+
return /* @__PURE__ */ jsx18(
|
|
2307
|
+
Component,
|
|
2308
|
+
{
|
|
2309
|
+
...props,
|
|
2310
|
+
as: schema.props.as,
|
|
2311
|
+
className: schema.props.className,
|
|
2312
|
+
children: text,
|
|
2313
|
+
designPlaceholder
|
|
2314
|
+
}
|
|
2315
|
+
);
|
|
2316
|
+
}
|
|
2317
|
+
if (schema.type === "tag") {
|
|
2318
|
+
const presentation = engine?.getTagPresentation(
|
|
2319
|
+
node.id,
|
|
2320
|
+
repeatItem !== void 0 ? { item: repeatItem } : void 0
|
|
2321
|
+
) ?? {
|
|
2322
|
+
label: typeof schema.props?.label === "string" || typeof schema.props?.label === "number" ? String(schema.props.label) : ""
|
|
2323
|
+
};
|
|
2324
|
+
const label = presentation.label;
|
|
2325
|
+
const designPlaceholder = designMode === true && label.trim() === "" ? typeof schema.props?.from === "string" && schema.props.from.trim() ? schema.props.from.trim() : void 0 : void 0;
|
|
2326
|
+
const resolvedLabel = label.trim() !== "" ? label : designPlaceholder !== void 0 ? designPlaceholder : label;
|
|
2327
|
+
const className = typeof schema.props?.className === "string" ? schema.props.className : void 0;
|
|
2328
|
+
return /* @__PURE__ */ jsx18(
|
|
2329
|
+
Component,
|
|
2330
|
+
{
|
|
2331
|
+
...props,
|
|
2332
|
+
from: void 0,
|
|
2333
|
+
map: void 0,
|
|
2334
|
+
label: resolvedLabel,
|
|
2335
|
+
variant: presentation.variant ?? schema.props?.variant,
|
|
2336
|
+
className: designPlaceholder !== void 0 && label.trim() === "" ? [className, "opacity-50"].filter(Boolean).join(" ") : className
|
|
2337
|
+
}
|
|
2338
|
+
);
|
|
2339
|
+
}
|
|
2340
|
+
if (schema.type === "slot") {
|
|
2341
|
+
const slotName = schema.props.name;
|
|
2342
|
+
const className = typeof schema.props.className === "string" ? schema.props.className : void 0;
|
|
2343
|
+
const renderer = slots?.[slotName];
|
|
2344
|
+
const values = engine?.getValues() ?? {};
|
|
2345
|
+
const resources = engine?.getResources() ?? {};
|
|
2346
|
+
const children = renderer?.({ values, resources });
|
|
2347
|
+
const designPlaceholder = designMode === true && children == null ? `Slot \u201C${slotName}\u201D` : void 0;
|
|
2348
|
+
return /* @__PURE__ */ jsx18(
|
|
2349
|
+
Component,
|
|
2350
|
+
{
|
|
2351
|
+
className,
|
|
2352
|
+
designPlaceholder,
|
|
2353
|
+
children
|
|
2354
|
+
}
|
|
2355
|
+
);
|
|
2356
|
+
}
|
|
2357
|
+
return /* @__PURE__ */ jsx18(Component, { ...props });
|
|
2358
|
+
}
|
|
2359
|
+
|
|
2360
|
+
// src/renderer/node-renderer.tsx
|
|
2361
|
+
import { jsx as jsx19 } from "react/jsx-runtime";
|
|
2362
|
+
function NodeRenderer({ node }) {
|
|
2363
|
+
const { renderWrapper } = useConfigContext();
|
|
2364
|
+
const schema = node.schema;
|
|
2365
|
+
const createChildren = ({
|
|
2366
|
+
node: node2,
|
|
2367
|
+
children
|
|
2368
|
+
}) => {
|
|
2369
|
+
if (renderWrapper)
|
|
2370
|
+
return renderWrapper({
|
|
2371
|
+
node: node2,
|
|
2372
|
+
children
|
|
2373
|
+
});
|
|
2374
|
+
return children;
|
|
2375
|
+
};
|
|
2376
|
+
switch (schema.kind) {
|
|
2377
|
+
case "field":
|
|
2378
|
+
return createChildren({ node, children: /* @__PURE__ */ jsx19(FieldRenderer, { node }) });
|
|
2379
|
+
case "layout":
|
|
2380
|
+
return createChildren({
|
|
2381
|
+
node,
|
|
2382
|
+
children: /* @__PURE__ */ jsx19(LayoutRenderer, { node })
|
|
2383
|
+
});
|
|
2384
|
+
case "action":
|
|
2385
|
+
return createChildren({ node, children: /* @__PURE__ */ jsx19(ActionRenderer, { node }) });
|
|
2386
|
+
case "display":
|
|
2387
|
+
return createChildren({ node, children: /* @__PURE__ */ jsx19(DisplayRenderer, { node }) });
|
|
2388
|
+
default:
|
|
2389
|
+
return null;
|
|
2390
|
+
}
|
|
2391
|
+
}
|
|
2392
|
+
|
|
2393
|
+
// src/components/layout-types.ts
|
|
2394
|
+
function normalizeLayoutClassName(value) {
|
|
2395
|
+
if (typeof value !== "string") {
|
|
2396
|
+
return void 0;
|
|
2397
|
+
}
|
|
2398
|
+
const className = value.trim();
|
|
2399
|
+
return className || void 0;
|
|
2400
|
+
}
|
|
2401
|
+
function normalizeLayoutGap(value, fallback) {
|
|
2402
|
+
const numericValue = toFiniteNumber(value);
|
|
2403
|
+
if (numericValue !== void 0) {
|
|
2404
|
+
return numericValue >= 0 ? numericValue : fallback;
|
|
2405
|
+
}
|
|
2406
|
+
if (typeof value === "string") {
|
|
2407
|
+
const cssValue = value.trim();
|
|
2408
|
+
return cssValue || fallback;
|
|
2409
|
+
}
|
|
2410
|
+
return fallback;
|
|
2411
|
+
}
|
|
2412
|
+
function toFiniteNumber(value) {
|
|
2413
|
+
if (typeof value === "number") {
|
|
2414
|
+
return Number.isFinite(value) ? value : void 0;
|
|
2415
|
+
}
|
|
2416
|
+
if (typeof value !== "string" || value.trim() === "") {
|
|
2417
|
+
return void 0;
|
|
2418
|
+
}
|
|
2419
|
+
const numericValue = Number(value);
|
|
2420
|
+
return Number.isFinite(numericValue) ? numericValue : void 0;
|
|
2421
|
+
}
|
|
2422
|
+
|
|
2423
|
+
// src/components/grid.tsx
|
|
2424
|
+
import { jsx as jsx20 } from "react/jsx-runtime";
|
|
2425
|
+
var DEFAULT_COLUMNS = 1;
|
|
2426
|
+
var DEFAULT_ROW_GAP = 48;
|
|
2427
|
+
var DEFAULT_COLUMN_GAP = 32;
|
|
2428
|
+
function Grid({
|
|
2429
|
+
columns,
|
|
2430
|
+
children,
|
|
2431
|
+
className,
|
|
2432
|
+
gap,
|
|
2433
|
+
rowGap,
|
|
2434
|
+
columnGap
|
|
2435
|
+
}) {
|
|
2436
|
+
const customClassName = normalizeLayoutClassName(className);
|
|
2437
|
+
return /* @__PURE__ */ jsx20(
|
|
2438
|
+
"div",
|
|
2439
|
+
{
|
|
2440
|
+
className: customClassName ? `grid ${customClassName}` : "grid",
|
|
2441
|
+
style: {
|
|
2442
|
+
display: "grid",
|
|
2443
|
+
gridTemplateColumns: `repeat(${normalizeGridColumns(columns)}, minmax(0,1fr))`,
|
|
2444
|
+
rowGap: normalizeLayoutGap(
|
|
2445
|
+
rowGap,
|
|
2446
|
+
normalizeLayoutGap(gap, DEFAULT_ROW_GAP)
|
|
2447
|
+
),
|
|
2448
|
+
columnGap: normalizeLayoutGap(
|
|
2449
|
+
columnGap,
|
|
2450
|
+
normalizeLayoutGap(gap, DEFAULT_COLUMN_GAP)
|
|
2451
|
+
)
|
|
2452
|
+
},
|
|
2453
|
+
children
|
|
2454
|
+
}
|
|
2455
|
+
);
|
|
2456
|
+
}
|
|
2457
|
+
function normalizeGridColumns(value) {
|
|
2458
|
+
const parsedValue = toFiniteNumber2(value);
|
|
2459
|
+
if (parsedValue === void 0 || parsedValue < 1) {
|
|
2460
|
+
return DEFAULT_COLUMNS;
|
|
2461
|
+
}
|
|
2462
|
+
return Math.floor(parsedValue);
|
|
2463
|
+
}
|
|
2464
|
+
function toFiniteNumber2(value) {
|
|
2465
|
+
if (typeof value === "number") {
|
|
2466
|
+
return Number.isFinite(value) ? value : void 0;
|
|
2467
|
+
}
|
|
2468
|
+
if (typeof value !== "string" || value.trim() === "") {
|
|
2469
|
+
return void 0;
|
|
2470
|
+
}
|
|
2471
|
+
const numericValue = Number(value);
|
|
2472
|
+
return Number.isFinite(numericValue) ? numericValue : void 0;
|
|
2473
|
+
}
|
|
2474
|
+
|
|
2475
|
+
// src/components/row.tsx
|
|
2476
|
+
import { jsx as jsx21 } from "react/jsx-runtime";
|
|
2477
|
+
var DEFAULT_GAP = 16;
|
|
2478
|
+
var ALIGN_ITEMS_VALUES = [
|
|
2479
|
+
"flex-start",
|
|
2480
|
+
"center",
|
|
2481
|
+
"flex-end",
|
|
2482
|
+
"stretch",
|
|
2483
|
+
"baseline"
|
|
2484
|
+
];
|
|
2485
|
+
var JUSTIFY_CONTENT_VALUES = [
|
|
2486
|
+
"flex-start",
|
|
2487
|
+
"center",
|
|
2488
|
+
"flex-end",
|
|
2489
|
+
"space-between",
|
|
2490
|
+
"space-around",
|
|
2491
|
+
"space-evenly"
|
|
2492
|
+
];
|
|
2493
|
+
var FLEX_WRAP_VALUES = ["nowrap", "wrap", "wrap-reverse"];
|
|
2494
|
+
var ALIGN_ITEMS_ALIASES = {
|
|
2495
|
+
start: "flex-start",
|
|
2496
|
+
end: "flex-end"
|
|
2497
|
+
};
|
|
2498
|
+
var JUSTIFY_CONTENT_ALIASES = {
|
|
2499
|
+
start: "flex-start",
|
|
2500
|
+
end: "flex-end",
|
|
2501
|
+
between: "space-between",
|
|
2502
|
+
around: "space-around",
|
|
2503
|
+
evenly: "space-evenly"
|
|
2504
|
+
};
|
|
2505
|
+
function Row({
|
|
2506
|
+
children,
|
|
2507
|
+
className,
|
|
2508
|
+
gap,
|
|
2509
|
+
rowGap,
|
|
2510
|
+
columnGap,
|
|
2511
|
+
alignItems,
|
|
2512
|
+
justifyContent,
|
|
2513
|
+
flexWrap
|
|
2514
|
+
}) {
|
|
2515
|
+
const customClassName = normalizeLayoutClassName(className);
|
|
2516
|
+
const normalizedGap = normalizeLayoutGap(gap, DEFAULT_GAP);
|
|
2517
|
+
return /* @__PURE__ */ jsx21(
|
|
2518
|
+
"div",
|
|
2519
|
+
{
|
|
2520
|
+
className: customClassName ? `form-row ${customClassName}` : "form-row",
|
|
2521
|
+
style: {
|
|
2522
|
+
display: "flex",
|
|
2523
|
+
flexDirection: "row",
|
|
2524
|
+
rowGap: normalizeLayoutGap(rowGap, normalizedGap),
|
|
2525
|
+
columnGap: normalizeLayoutGap(columnGap, normalizedGap),
|
|
2526
|
+
alignItems: normalizeRowAlignItems(alignItems),
|
|
2527
|
+
justifyContent: normalizeRowJustifyContent(justifyContent),
|
|
2528
|
+
flexWrap: normalizeRowFlexWrap(flexWrap)
|
|
2529
|
+
},
|
|
2530
|
+
children
|
|
2531
|
+
}
|
|
2532
|
+
);
|
|
2533
|
+
}
|
|
2534
|
+
function normalizeRowAlignItems(value) {
|
|
2535
|
+
return normalizeRowValue(
|
|
2536
|
+
value,
|
|
2537
|
+
ALIGN_ITEMS_VALUES,
|
|
2538
|
+
ALIGN_ITEMS_ALIASES,
|
|
2539
|
+
"flex-start"
|
|
2540
|
+
);
|
|
2541
|
+
}
|
|
2542
|
+
function normalizeRowJustifyContent(value) {
|
|
2543
|
+
return normalizeRowValue(
|
|
2544
|
+
value,
|
|
2545
|
+
JUSTIFY_CONTENT_VALUES,
|
|
2546
|
+
JUSTIFY_CONTENT_ALIASES,
|
|
2547
|
+
"flex-start"
|
|
2548
|
+
);
|
|
2549
|
+
}
|
|
2550
|
+
function normalizeRowFlexWrap(value) {
|
|
2551
|
+
if (value === true) {
|
|
2552
|
+
return "wrap";
|
|
2553
|
+
}
|
|
2554
|
+
if (value === false) {
|
|
2555
|
+
return "nowrap";
|
|
2556
|
+
}
|
|
2557
|
+
return normalizeRowValue(value, FLEX_WRAP_VALUES, {}, "wrap");
|
|
2558
|
+
}
|
|
2559
|
+
function normalizeRowValue(value, values, aliases, fallback) {
|
|
2560
|
+
if (typeof value !== "string") {
|
|
2561
|
+
return fallback;
|
|
2562
|
+
}
|
|
2563
|
+
const normalizedValue = value.trim().toLowerCase();
|
|
2564
|
+
const alias = aliases[normalizedValue];
|
|
2565
|
+
if (alias) {
|
|
2566
|
+
return alias;
|
|
2567
|
+
}
|
|
2568
|
+
return values.includes(normalizedValue) ? normalizedValue : fallback;
|
|
2569
|
+
}
|
|
2570
|
+
|
|
2571
|
+
// src/components/section.tsx
|
|
2572
|
+
import { jsx as jsx22 } from "react/jsx-runtime";
|
|
2573
|
+
function Section({ children, className }) {
|
|
2574
|
+
return /* @__PURE__ */ jsx22("section", { className: normalizeLayoutClassName(className), children: /* @__PURE__ */ jsx22("div", { className: "space-y-8", children }) });
|
|
2575
|
+
}
|
|
2576
|
+
|
|
2577
|
+
// src/components/div.tsx
|
|
2578
|
+
import { jsx as jsx23 } from "react/jsx-runtime";
|
|
2579
|
+
function Div({ children, className }) {
|
|
2580
|
+
return /* @__PURE__ */ jsx23("div", { className: normalizeLayoutClassName(className), children });
|
|
2581
|
+
}
|
|
2582
|
+
|
|
2583
|
+
// src/components/scroll-area.tsx
|
|
2584
|
+
import { ScrollArea } from "bsm-design-system";
|
|
2585
|
+
import { jsx as jsx24 } from "react/jsx-runtime";
|
|
2586
|
+
var DEFAULT_SCROLL_HIDE_DELAY = 600;
|
|
2587
|
+
function ScrollAreaLayout({
|
|
2588
|
+
ariaLabel,
|
|
2589
|
+
children,
|
|
2590
|
+
className,
|
|
2591
|
+
dir,
|
|
2592
|
+
scrollAreaType,
|
|
2593
|
+
scrollHideDelay,
|
|
2594
|
+
viewportClassName
|
|
2595
|
+
}) {
|
|
2596
|
+
const normalizedAriaLabel = normalizeScrollAreaAriaLabel(ariaLabel);
|
|
2597
|
+
return /* @__PURE__ */ jsx24(
|
|
2598
|
+
ScrollArea,
|
|
2599
|
+
{
|
|
2600
|
+
className: normalizeLayoutClassName(className),
|
|
2601
|
+
viewportClassName: normalizeLayoutClassName(viewportClassName),
|
|
2602
|
+
type: normalizeScrollAreaType(scrollAreaType),
|
|
2603
|
+
dir: normalizeScrollAreaDirection(dir),
|
|
2604
|
+
scrollHideDelay: normalizeScrollHideDelay(scrollHideDelay),
|
|
2605
|
+
role: normalizedAriaLabel ? "region" : void 0,
|
|
2606
|
+
"aria-label": normalizedAriaLabel,
|
|
2607
|
+
children
|
|
2608
|
+
}
|
|
2609
|
+
);
|
|
2610
|
+
}
|
|
2611
|
+
function normalizeScrollAreaType(value) {
|
|
2612
|
+
return value === "scroll" || value === "auto" || value === "always" ? value : "hover";
|
|
2613
|
+
}
|
|
2614
|
+
function normalizeScrollAreaDirection(value) {
|
|
2615
|
+
return value === "ltr" ? "ltr" : "rtl";
|
|
2616
|
+
}
|
|
2617
|
+
function normalizeScrollHideDelay(value) {
|
|
2618
|
+
return typeof value === "number" && Number.isFinite(value) && value >= 0 ? value : DEFAULT_SCROLL_HIDE_DELAY;
|
|
2619
|
+
}
|
|
2620
|
+
function normalizeScrollAreaAriaLabel(value) {
|
|
2621
|
+
if (typeof value !== "string") {
|
|
2622
|
+
return void 0;
|
|
2623
|
+
}
|
|
2624
|
+
const ariaLabel = value.trim();
|
|
2625
|
+
return ariaLabel || void 0;
|
|
2626
|
+
}
|
|
2627
|
+
|
|
2628
|
+
// src/components/badge.tsx
|
|
2629
|
+
import { Badge } from "bsm-design-system";
|
|
2630
|
+
import { jsx as jsx25 } from "react/jsx-runtime";
|
|
2631
|
+
function BadgeLayout({
|
|
2632
|
+
ariaLabel,
|
|
2633
|
+
badgeContent,
|
|
2634
|
+
badgeOffsetX,
|
|
2635
|
+
badgeOffsetY,
|
|
2636
|
+
badgeShow,
|
|
2637
|
+
badgeType,
|
|
2638
|
+
children,
|
|
2639
|
+
className
|
|
2640
|
+
}) {
|
|
2641
|
+
const normalizedAriaLabel = normalizeBadgeAriaLabel(ariaLabel);
|
|
2642
|
+
return /* @__PURE__ */ jsx25(
|
|
2643
|
+
Badge,
|
|
2644
|
+
{
|
|
2645
|
+
content: normalizeBadgeContent(badgeContent),
|
|
2646
|
+
show: normalizeBadgeShow(badgeShow),
|
|
2647
|
+
type: normalizeBadgeType(badgeType),
|
|
2648
|
+
offsetX: normalizeBadgeOffset(badgeOffsetX),
|
|
2649
|
+
offsetY: normalizeBadgeOffset(badgeOffsetY),
|
|
2650
|
+
className: normalizeLayoutClassName(className),
|
|
2651
|
+
role: normalizedAriaLabel ? "group" : void 0,
|
|
2652
|
+
"aria-label": normalizedAriaLabel,
|
|
2653
|
+
children
|
|
2654
|
+
}
|
|
2655
|
+
);
|
|
2656
|
+
}
|
|
2657
|
+
function normalizeBadgeContent(value) {
|
|
2658
|
+
if (typeof value === "string") {
|
|
2659
|
+
const content = value.trim();
|
|
2660
|
+
return content || void 0;
|
|
2661
|
+
}
|
|
2662
|
+
return typeof value === "number" && Number.isFinite(value) ? String(value) : void 0;
|
|
2663
|
+
}
|
|
2664
|
+
function normalizeBadgeShow(value) {
|
|
2665
|
+
return value !== false;
|
|
2666
|
+
}
|
|
2667
|
+
function normalizeBadgeType(value) {
|
|
2668
|
+
if (value === "success" || value === "error" || value === "warning") {
|
|
2669
|
+
return value;
|
|
2670
|
+
}
|
|
2671
|
+
return value === "process" || value === "proccess" ? "proccess" : "default";
|
|
2672
|
+
}
|
|
2673
|
+
function normalizeBadgeOffset(value) {
|
|
2674
|
+
return typeof value === "number" && Number.isFinite(value) ? value : 0;
|
|
2675
|
+
}
|
|
2676
|
+
function normalizeBadgeAriaLabel(value) {
|
|
2677
|
+
if (typeof value !== "string") {
|
|
2678
|
+
return void 0;
|
|
2679
|
+
}
|
|
2680
|
+
const ariaLabel = value.trim();
|
|
2681
|
+
return ariaLabel || void 0;
|
|
2682
|
+
}
|
|
2683
|
+
|
|
2684
|
+
// src/components/card.tsx
|
|
2685
|
+
import { Card } from "bsm-design-system";
|
|
2686
|
+
import { jsx as jsx26 } from "react/jsx-runtime";
|
|
2687
|
+
function CardLayout({
|
|
2688
|
+
ariaLabel,
|
|
2689
|
+
children,
|
|
2690
|
+
className
|
|
2691
|
+
}) {
|
|
2692
|
+
const normalizedAriaLabel = normalizeCardAriaLabel(ariaLabel);
|
|
2693
|
+
return /* @__PURE__ */ jsx26(
|
|
2694
|
+
Card,
|
|
2695
|
+
{
|
|
2696
|
+
className: normalizeLayoutClassName(className),
|
|
2697
|
+
role: normalizedAriaLabel ? "group" : void 0,
|
|
2698
|
+
"aria-label": normalizedAriaLabel,
|
|
2699
|
+
children
|
|
2700
|
+
}
|
|
2701
|
+
);
|
|
2702
|
+
}
|
|
2703
|
+
function CardHeaderLayout({
|
|
2704
|
+
cardDivider,
|
|
2705
|
+
children,
|
|
2706
|
+
className
|
|
2707
|
+
}) {
|
|
2708
|
+
return /* @__PURE__ */ jsx26(
|
|
2709
|
+
Card.Header,
|
|
2710
|
+
{
|
|
2711
|
+
className: normalizeCardSlotClassName(
|
|
2712
|
+
className,
|
|
2713
|
+
cardDivider,
|
|
2714
|
+
"border-b"
|
|
2715
|
+
),
|
|
2716
|
+
children
|
|
2717
|
+
}
|
|
2718
|
+
);
|
|
2719
|
+
}
|
|
2720
|
+
function CardContentLayout({
|
|
2721
|
+
children,
|
|
2722
|
+
className
|
|
2723
|
+
}) {
|
|
2724
|
+
return /* @__PURE__ */ jsx26(Card.Content, { className: normalizeLayoutClassName(className), children });
|
|
2725
|
+
}
|
|
2726
|
+
function CardFooterLayout({
|
|
2727
|
+
cardDivider,
|
|
2728
|
+
children,
|
|
2729
|
+
className
|
|
2730
|
+
}) {
|
|
2731
|
+
return /* @__PURE__ */ jsx26(
|
|
2732
|
+
Card.Footer,
|
|
2733
|
+
{
|
|
2734
|
+
className: normalizeCardSlotClassName(
|
|
2735
|
+
className,
|
|
2736
|
+
cardDivider,
|
|
2737
|
+
"border-t"
|
|
2738
|
+
),
|
|
2739
|
+
children
|
|
2740
|
+
}
|
|
2741
|
+
);
|
|
2742
|
+
}
|
|
2743
|
+
function normalizeCardAriaLabel(value) {
|
|
2744
|
+
if (typeof value !== "string") {
|
|
2745
|
+
return void 0;
|
|
2746
|
+
}
|
|
2747
|
+
const ariaLabel = value.trim();
|
|
2748
|
+
return ariaLabel || void 0;
|
|
2749
|
+
}
|
|
2750
|
+
function normalizeCardDivider(value) {
|
|
2751
|
+
return value === true;
|
|
2752
|
+
}
|
|
2753
|
+
function normalizeCardSlotClassName(value, divider, dividerClassName) {
|
|
2754
|
+
const className = normalizeLayoutClassName(value);
|
|
2755
|
+
return [className, normalizeCardDivider(divider) && dividerClassName].filter(Boolean).join(" ") || void 0;
|
|
2756
|
+
}
|
|
2757
|
+
|
|
2758
|
+
// src/registry/layout-registry.ts
|
|
2759
|
+
var layoutRegistry = {
|
|
2760
|
+
badge: BadgeLayout,
|
|
2761
|
+
card: CardLayout,
|
|
2762
|
+
"card-header": CardHeaderLayout,
|
|
2763
|
+
"card-content": CardContentLayout,
|
|
2764
|
+
"card-footer": CardFooterLayout,
|
|
2765
|
+
div: Div,
|
|
2766
|
+
grid: Grid,
|
|
2767
|
+
row: Row,
|
|
2768
|
+
"scroll-area": ScrollAreaLayout,
|
|
2769
|
+
section: Section
|
|
2770
|
+
};
|
|
2771
|
+
|
|
2772
|
+
// src/renderer/tabs-renderer.tsx
|
|
2773
|
+
import { useEffect as useEffect3, useState as useState3 } from "react";
|
|
2774
|
+
import { Tabs } from "bsm-design-system";
|
|
2775
|
+
|
|
2776
|
+
// src/renderer/legacy-container-items.ts
|
|
2777
|
+
function normalizeLegacyContainerItems(children, fallbackLabel) {
|
|
2778
|
+
const ids = /* @__PURE__ */ new Set();
|
|
2779
|
+
const items = [];
|
|
2780
|
+
children.forEach((node, index) => {
|
|
2781
|
+
if (typeof node.id !== "string" || node.id.trim() === "" || ids.has(node.id)) {
|
|
2782
|
+
return;
|
|
2783
|
+
}
|
|
2784
|
+
ids.add(node.id);
|
|
2785
|
+
const schema = readRecord(node.schema);
|
|
2786
|
+
const props = readRecord(schema?.props);
|
|
2787
|
+
items.push({
|
|
2788
|
+
disabled: node.state.disabled || schema?.disabled === true || props?.disabled === true,
|
|
2789
|
+
id: node.id,
|
|
2790
|
+
node,
|
|
2791
|
+
title: normalizeContainerTitle(
|
|
2792
|
+
schema?.title ?? props?.title,
|
|
2793
|
+
`${fallbackLabel} ${index + 1}`
|
|
2794
|
+
)
|
|
2795
|
+
});
|
|
2796
|
+
});
|
|
2797
|
+
return items;
|
|
2798
|
+
}
|
|
2799
|
+
function resolveContainerInitialValue(value, fallbackValue, items) {
|
|
2800
|
+
for (const candidate of [value, fallbackValue]) {
|
|
2801
|
+
if (typeof candidate === "string" && items.some((item) => item.id === candidate)) {
|
|
2802
|
+
return candidate;
|
|
2803
|
+
}
|
|
2804
|
+
}
|
|
2805
|
+
return items.find((item) => !item.disabled)?.id ?? items[0]?.id ?? "";
|
|
2806
|
+
}
|
|
2807
|
+
function resolveContainerInitialValues(value, fallbackValue, items) {
|
|
2808
|
+
for (const candidate of [value, fallbackValue]) {
|
|
2809
|
+
if (Array.isArray(candidate)) {
|
|
2810
|
+
const values = candidate.filter(
|
|
2811
|
+
(item, index) => typeof item === "string" && candidate.indexOf(item) === index && items.some((containerItem) => containerItem.id === item)
|
|
2812
|
+
);
|
|
2813
|
+
if (values.length > 0 || candidate.length === 0) {
|
|
2814
|
+
return values;
|
|
2815
|
+
}
|
|
2816
|
+
}
|
|
2817
|
+
}
|
|
2818
|
+
return [];
|
|
2819
|
+
}
|
|
2820
|
+
function normalizeContainerTitle(value, fallback) {
|
|
2821
|
+
if (typeof value === "string" && value.trim() !== "") {
|
|
2822
|
+
return value.trim();
|
|
2823
|
+
}
|
|
2824
|
+
return typeof value === "number" && Number.isFinite(value) ? String(value) : fallback;
|
|
2825
|
+
}
|
|
2826
|
+
function readRecord(value) {
|
|
2827
|
+
return typeof value === "object" && value !== null ? value : void 0;
|
|
2828
|
+
}
|
|
2829
|
+
|
|
2830
|
+
// src/renderer/tabs-execution.ts
|
|
2831
|
+
function executeRendererTabsChange(engine, tabsId, tabId, designMode) {
|
|
2832
|
+
if (designMode) {
|
|
2833
|
+
return;
|
|
2834
|
+
}
|
|
2835
|
+
return engine.changeTabs(tabsId, tabId);
|
|
2836
|
+
}
|
|
2837
|
+
|
|
2838
|
+
// src/renderer/tabs-renderer.tsx
|
|
2839
|
+
import { jsx as jsx27, jsxs as jsxs9 } from "react/jsx-runtime";
|
|
2840
|
+
function TabsRenderer({ node }) {
|
|
2841
|
+
if (node.schema.kind !== "layout" || node.schema.type !== "tabs") {
|
|
2842
|
+
return null;
|
|
2843
|
+
}
|
|
2844
|
+
return /* @__PURE__ */ jsx27(TabsLayout, { node });
|
|
2845
|
+
}
|
|
2846
|
+
function TabsLayout({ node }) {
|
|
2847
|
+
const engine = useOptionalFormContext();
|
|
2848
|
+
const { designMode } = useConfigContext();
|
|
2849
|
+
const props = node.schema.props;
|
|
2850
|
+
const items = normalizeLegacyContainerItems(node.children, "Tab");
|
|
2851
|
+
const initialValue = resolveContainerInitialValue(
|
|
2852
|
+
props?.value,
|
|
2853
|
+
props?.defaultValue,
|
|
2854
|
+
items
|
|
2855
|
+
);
|
|
2856
|
+
const engineActiveTabId = engine?.getTabsState(node.id)?.activeTabId;
|
|
2857
|
+
const [selectedValue, setSelectedValue] = useState3(
|
|
2858
|
+
engineActiveTabId ?? initialValue
|
|
2859
|
+
);
|
|
2860
|
+
useEffect3(() => {
|
|
2861
|
+
if (designMode === true || !engine) {
|
|
2862
|
+
setSelectedValue(initialValue);
|
|
2863
|
+
}
|
|
2864
|
+
}, [designMode, engine, initialValue]);
|
|
2865
|
+
useEffect3(() => {
|
|
2866
|
+
if (designMode === true || !engine || !engineActiveTabId) {
|
|
2867
|
+
return;
|
|
2868
|
+
}
|
|
2869
|
+
setSelectedValue(engineActiveTabId);
|
|
2870
|
+
}, [designMode, engine, engineActiveTabId]);
|
|
2871
|
+
const activeValue = items.some((item) => item.id === selectedValue) ? selectedValue : engineActiveTabId && items.some((item) => item.id === engineActiveTabId) ? engineActiveTabId : initialValue;
|
|
2872
|
+
return /* @__PURE__ */ jsxs9(
|
|
2873
|
+
Tabs,
|
|
2874
|
+
{
|
|
2875
|
+
id: node.id,
|
|
2876
|
+
className: normalizeClassName3(props?.className),
|
|
2877
|
+
value: activeValue,
|
|
2878
|
+
onChange: (nextValue) => {
|
|
2879
|
+
setSelectedValue(nextValue);
|
|
2880
|
+
if (designMode === true || !engine) {
|
|
2881
|
+
return;
|
|
2882
|
+
}
|
|
2883
|
+
void executeRendererTabsChange(engine, node.id, nextValue, false);
|
|
2884
|
+
},
|
|
2885
|
+
variant: normalizeTabsVariant(props?.variant),
|
|
2886
|
+
size: normalizeTabsSize(props?.size),
|
|
2887
|
+
fullWidth: props?.fullWidth === true,
|
|
2888
|
+
dir: normalizeDirection(props?.dir),
|
|
2889
|
+
activationMode: normalizeActivationMode(props?.activationMode),
|
|
2890
|
+
"aria-label": normalizeAriaLabel(props?.["aria-label"]),
|
|
2891
|
+
children: [
|
|
2892
|
+
/* @__PURE__ */ jsx27(
|
|
2893
|
+
Tabs.List,
|
|
2894
|
+
{
|
|
2895
|
+
loop: props?.loop !== false,
|
|
2896
|
+
className: joinClassNames2(
|
|
2897
|
+
props?.fullWidth === true ? "w-full" : void 0,
|
|
2898
|
+
designMode === true ? "pointer-events-auto" : void 0
|
|
2899
|
+
),
|
|
2900
|
+
children: items.map((item) => /* @__PURE__ */ jsx27(
|
|
2901
|
+
Tabs.Trigger,
|
|
2902
|
+
{
|
|
2903
|
+
value: item.id,
|
|
2904
|
+
disabled: item.disabled,
|
|
2905
|
+
className: props?.fullWidth === true ? "flex-1" : void 0,
|
|
2906
|
+
children: item.title
|
|
2907
|
+
},
|
|
2908
|
+
item.id
|
|
2909
|
+
))
|
|
2910
|
+
}
|
|
2911
|
+
),
|
|
2912
|
+
items.map((item) => /* @__PURE__ */ jsx27(Tabs.Content, { value: item.id, children: item.node.children.map((child) => /* @__PURE__ */ jsx27(NodeRenderer, { node: child }, child.id)) }, item.id))
|
|
2913
|
+
]
|
|
2914
|
+
}
|
|
2915
|
+
);
|
|
2916
|
+
}
|
|
2917
|
+
function normalizeTabsVariant(value) {
|
|
2918
|
+
return value === "filled" ? "filled" : "underline";
|
|
2919
|
+
}
|
|
2920
|
+
function normalizeTabsSize(value) {
|
|
2921
|
+
return value === "sm" || value === "lg" ? value : "md";
|
|
2922
|
+
}
|
|
2923
|
+
function normalizeDirection(value) {
|
|
2924
|
+
return value === "ltr" ? "ltr" : "rtl";
|
|
2925
|
+
}
|
|
2926
|
+
function normalizeActivationMode(value) {
|
|
2927
|
+
return value === "manual" || value === "automatic" ? value : void 0;
|
|
2928
|
+
}
|
|
2929
|
+
function normalizeClassName3(value) {
|
|
2930
|
+
return typeof value === "string" ? value : "";
|
|
2931
|
+
}
|
|
2932
|
+
function joinClassNames2(...parts) {
|
|
2933
|
+
return parts.filter(Boolean).join(" ") || void 0;
|
|
2934
|
+
}
|
|
2935
|
+
function normalizeAriaLabel(value) {
|
|
2936
|
+
return typeof value === "string" && value.trim() ? value : void 0;
|
|
2937
|
+
}
|
|
2938
|
+
|
|
2939
|
+
// src/renderer/accordion-renderer.tsx
|
|
2940
|
+
import { Accordion } from "bsm-design-system";
|
|
2941
|
+
|
|
2942
|
+
// src/renderer/accordion-execution.ts
|
|
2943
|
+
function executeRendererAccordionChange(engine, accordionId, nextValue, designMode) {
|
|
2944
|
+
if (designMode) {
|
|
2945
|
+
return;
|
|
2946
|
+
}
|
|
2947
|
+
return engine.changeAccordion(accordionId, nextValue);
|
|
2948
|
+
}
|
|
2949
|
+
|
|
2950
|
+
// src/renderer/accordion-renderer.tsx
|
|
2951
|
+
import { jsx as jsx28, jsxs as jsxs10 } from "react/jsx-runtime";
|
|
2952
|
+
function AccordionRenderer({ node }) {
|
|
2953
|
+
if (node.schema.kind !== "layout" || node.schema.type !== "accordion") {
|
|
2954
|
+
return null;
|
|
2955
|
+
}
|
|
2956
|
+
const engine = useOptionalFormContext();
|
|
2957
|
+
const { designMode } = useConfigContext();
|
|
2958
|
+
const props = node.schema.props;
|
|
2959
|
+
const items = normalizeLegacyContainerItems(node.children, "Section");
|
|
2960
|
+
const engineState = engine?.getAccordionState(node.id);
|
|
2961
|
+
const sharedProps = {
|
|
2962
|
+
id: node.id,
|
|
2963
|
+
className: typeof props?.className === "string" ? props.className : "",
|
|
2964
|
+
separate: props?.separate !== false,
|
|
2965
|
+
variant: normalizeAccordionVariant(props?.variant),
|
|
2966
|
+
iconPosition: normalizeAccordionIconPosition(props?.iconPosition),
|
|
2967
|
+
dir: props?.dir === "ltr" || props?.dir === "rtl" ? props.dir : void 0,
|
|
2968
|
+
"aria-label": typeof props?.["aria-label"] === "string" && props["aria-label"].trim() ? props["aria-label"] : void 0
|
|
2969
|
+
};
|
|
2970
|
+
const canDriveEngine = engine !== void 0 && engine !== null && designMode !== true;
|
|
2971
|
+
const commitAccordionChange = (nextValue) => {
|
|
2972
|
+
if (!engine || designMode === true) {
|
|
2973
|
+
return;
|
|
2974
|
+
}
|
|
2975
|
+
void executeRendererAccordionChange(engine, node.id, nextValue, false);
|
|
2976
|
+
};
|
|
2977
|
+
if (props?.type === "multiple") {
|
|
2978
|
+
const defaultValue2 = resolveContainerInitialValues(
|
|
2979
|
+
props.value,
|
|
2980
|
+
props.defaultValue,
|
|
2981
|
+
items
|
|
2982
|
+
);
|
|
2983
|
+
const value2 = engineState?.openItemIds ?? defaultValue2;
|
|
2984
|
+
return /* @__PURE__ */ jsx28(
|
|
2985
|
+
Accordion,
|
|
2986
|
+
{
|
|
2987
|
+
...sharedProps,
|
|
2988
|
+
type: "multiple",
|
|
2989
|
+
...canDriveEngine ? {
|
|
2990
|
+
value: value2,
|
|
2991
|
+
onChange: commitAccordionChange
|
|
2992
|
+
} : { defaultValue: defaultValue2 },
|
|
2993
|
+
children: /* @__PURE__ */ jsx28(AccordionItems, { items, designMode: designMode === true })
|
|
2994
|
+
}
|
|
2995
|
+
);
|
|
2996
|
+
}
|
|
2997
|
+
const defaultValue = resolveOptionalContainerInitialValue(
|
|
2998
|
+
props?.value,
|
|
2999
|
+
props?.defaultValue,
|
|
3000
|
+
items
|
|
3001
|
+
);
|
|
3002
|
+
const value = engineState !== void 0 ? engineState.openItemIds[0] : defaultValue;
|
|
3003
|
+
return /* @__PURE__ */ jsx28(
|
|
3004
|
+
Accordion,
|
|
3005
|
+
{
|
|
3006
|
+
...sharedProps,
|
|
3007
|
+
type: "single",
|
|
3008
|
+
collapsible: props?.collapsible !== false,
|
|
3009
|
+
...canDriveEngine ? {
|
|
3010
|
+
value,
|
|
3011
|
+
onChange: commitAccordionChange
|
|
3012
|
+
} : { defaultValue },
|
|
3013
|
+
children: /* @__PURE__ */ jsx28(AccordionItems, { items, designMode: designMode === true })
|
|
3014
|
+
}
|
|
3015
|
+
);
|
|
3016
|
+
}
|
|
3017
|
+
function normalizeAccordionVariant(value) {
|
|
3018
|
+
return value === "ghost" ? "ghost" : "default";
|
|
3019
|
+
}
|
|
3020
|
+
function normalizeAccordionIconPosition(value) {
|
|
3021
|
+
return value === "start" ? "start" : "end";
|
|
3022
|
+
}
|
|
3023
|
+
function AccordionItems({
|
|
3024
|
+
items,
|
|
3025
|
+
designMode
|
|
3026
|
+
}) {
|
|
3027
|
+
const engine = useOptionalFormContext();
|
|
3028
|
+
const repeatItem = useRepeatItem();
|
|
3029
|
+
return items.map((item) => {
|
|
3030
|
+
const resolvedTitle = engine?.getAccordionItemTitle(
|
|
3031
|
+
item.id,
|
|
3032
|
+
repeatItem !== void 0 ? { item: repeatItem } : void 0
|
|
3033
|
+
) ?? "";
|
|
3034
|
+
const titleFrom = item.node.schema.kind === "layout" && item.node.schema.type === "accordion-item" && typeof item.node.schema.props?.titleFrom === "string" ? item.node.schema.props.titleFrom : void 0;
|
|
3035
|
+
const title = resolvedTitle.trim() !== "" ? resolvedTitle : designMode === true && titleFrom ? titleFrom : item.title;
|
|
3036
|
+
return /* @__PURE__ */ jsxs10(
|
|
3037
|
+
Accordion.Item,
|
|
3038
|
+
{
|
|
3039
|
+
value: item.id,
|
|
3040
|
+
disabled: item.disabled,
|
|
3041
|
+
children: [
|
|
3042
|
+
/* @__PURE__ */ jsx28(
|
|
3043
|
+
Accordion.Trigger,
|
|
3044
|
+
{
|
|
3045
|
+
className: designMode ? "pointer-events-auto" : void 0,
|
|
3046
|
+
children: title
|
|
3047
|
+
}
|
|
3048
|
+
),
|
|
3049
|
+
/* @__PURE__ */ jsx28(Accordion.Content, { children: item.node.children.map((child) => /* @__PURE__ */ jsx28(NodeRenderer, { node: child }, child.id)) })
|
|
3050
|
+
]
|
|
3051
|
+
},
|
|
3052
|
+
item.id
|
|
3053
|
+
);
|
|
3054
|
+
});
|
|
3055
|
+
}
|
|
3056
|
+
function resolveOptionalContainerInitialValue(value, fallbackValue, items) {
|
|
3057
|
+
for (const candidate of [value, fallbackValue]) {
|
|
3058
|
+
if (candidate === "") {
|
|
3059
|
+
return void 0;
|
|
3060
|
+
}
|
|
3061
|
+
if (typeof candidate === "string" && items.some((item) => item.id === candidate)) {
|
|
3062
|
+
return candidate;
|
|
3063
|
+
}
|
|
3064
|
+
}
|
|
3065
|
+
return void 0;
|
|
3066
|
+
}
|
|
3067
|
+
|
|
3068
|
+
// src/renderer/stepper-renderer.tsx
|
|
3069
|
+
import { Stepper } from "bsm-design-system";
|
|
3070
|
+
import { useEffect as useEffect4, useState as useState4 } from "react";
|
|
3071
|
+
|
|
3072
|
+
// src/renderer/step-renderer.tsx
|
|
3073
|
+
import { jsx as jsx29, jsxs as jsxs11 } from "react/jsx-runtime";
|
|
3074
|
+
var DEFAULT_STEP_ACTIONS_CLASSNAME = "flex flex-wrap items-center gap-2";
|
|
3075
|
+
function StepRenderer({ node }) {
|
|
3076
|
+
const show = useDesignVisible(node.state.visible);
|
|
3077
|
+
if (node.schema.kind !== "layout" || node.schema.type !== "step" || !show) {
|
|
3078
|
+
return null;
|
|
3079
|
+
}
|
|
3080
|
+
const contentChildren = [];
|
|
3081
|
+
const actionChildren = [];
|
|
3082
|
+
for (const child of node.children) {
|
|
3083
|
+
if (child.schema.kind === "action") {
|
|
3084
|
+
actionChildren.push(child);
|
|
3085
|
+
} else {
|
|
3086
|
+
contentChildren.push(child);
|
|
3087
|
+
}
|
|
3088
|
+
}
|
|
3089
|
+
return /* @__PURE__ */ jsxs11(
|
|
3090
|
+
"div",
|
|
3091
|
+
{
|
|
3092
|
+
id: `${node.id}-content`,
|
|
3093
|
+
role: "group",
|
|
3094
|
+
"aria-label": normalizeStepLabel(node.schema.props.label),
|
|
3095
|
+
className: normalizeClassName4(node.schema.props.className),
|
|
3096
|
+
"data-step-id": node.id,
|
|
3097
|
+
children: [
|
|
3098
|
+
contentChildren.map((child) => /* @__PURE__ */ jsx29(NodeRenderer, { node: child }, child.id)),
|
|
3099
|
+
actionChildren.length > 0 ? /* @__PURE__ */ jsx29(
|
|
3100
|
+
"div",
|
|
3101
|
+
{
|
|
3102
|
+
className: joinClassNames3(
|
|
3103
|
+
DEFAULT_STEP_ACTIONS_CLASSNAME,
|
|
3104
|
+
normalizeClassName4(node.schema.props.actionsClassName)
|
|
3105
|
+
),
|
|
3106
|
+
"data-step-actions": "",
|
|
3107
|
+
children: actionChildren.map((child) => /* @__PURE__ */ jsx29(NodeRenderer, { node: child }, child.id))
|
|
3108
|
+
}
|
|
3109
|
+
) : null
|
|
3110
|
+
]
|
|
3111
|
+
}
|
|
3112
|
+
);
|
|
3113
|
+
}
|
|
3114
|
+
function normalizeStepLabel(value) {
|
|
3115
|
+
return typeof value === "string" ? value.trim() : "";
|
|
3116
|
+
}
|
|
3117
|
+
function normalizeClassName4(value) {
|
|
3118
|
+
return typeof value === "string" ? value.trim() : "";
|
|
3119
|
+
}
|
|
3120
|
+
function joinClassNames3(...parts) {
|
|
3121
|
+
return parts.filter((part) => typeof part === "string" && part.length > 0).join(" ");
|
|
3122
|
+
}
|
|
3123
|
+
|
|
3124
|
+
// src/renderer/stepper-execution.ts
|
|
3125
|
+
function executeRendererStepperNavigation(engine, stepperId, stepId, designMode) {
|
|
3126
|
+
if (designMode) {
|
|
3127
|
+
return;
|
|
3128
|
+
}
|
|
3129
|
+
return engine.goToStep(stepperId, stepId);
|
|
3130
|
+
}
|
|
3131
|
+
|
|
3132
|
+
// src/renderer/stepper-renderer.tsx
|
|
3133
|
+
import { jsx as jsx30, jsxs as jsxs12 } from "react/jsx-runtime";
|
|
3134
|
+
function StepperRenderer({ node }) {
|
|
3135
|
+
if (node.schema.kind !== "layout" || node.schema.type !== "stepper") {
|
|
3136
|
+
return null;
|
|
3137
|
+
}
|
|
3138
|
+
const engine = useFormContext();
|
|
3139
|
+
const { designMode } = useConfigContext();
|
|
3140
|
+
const props = node.schema.props;
|
|
3141
|
+
const state = engine.getStepperState(node.id);
|
|
3142
|
+
const visibleSteps = node.children.filter(
|
|
3143
|
+
(child) => child.schema.kind === "layout" && child.schema.type === "step" && (designMode === true || child.state.visible)
|
|
3144
|
+
);
|
|
3145
|
+
const items = visibleSteps.map((step, index) => ({
|
|
3146
|
+
id: index + 1,
|
|
3147
|
+
label: normalizeStepLabel(step.schema.props?.label),
|
|
3148
|
+
caption: normalizeOptionalText(step.schema.props?.caption),
|
|
3149
|
+
disabled: step.state.disabled || step.schema.props?.disabled === true,
|
|
3150
|
+
step
|
|
3151
|
+
}));
|
|
3152
|
+
const engineActiveStepId = state?.activeStepId;
|
|
3153
|
+
const [designActiveStepId, setDesignActiveStepId] = useState4(
|
|
3154
|
+
engineActiveStepId
|
|
3155
|
+
);
|
|
3156
|
+
useEffect4(() => {
|
|
3157
|
+
if (designMode === true) {
|
|
3158
|
+
setDesignActiveStepId(engineActiveStepId);
|
|
3159
|
+
}
|
|
3160
|
+
}, [designMode, engineActiveStepId]);
|
|
3161
|
+
const activeStepId = designMode === true ? designActiveStepId : engineActiveStepId;
|
|
3162
|
+
const activeItem = items.find((item) => item.step.id === activeStepId);
|
|
3163
|
+
const isReady = engine.getState().initializationStatus === "ready";
|
|
3164
|
+
return /* @__PURE__ */ jsxs12(
|
|
3165
|
+
"section",
|
|
3166
|
+
{
|
|
3167
|
+
id: node.id,
|
|
3168
|
+
"aria-label": normalizeAriaLabel2(props?.ariaLabel),
|
|
3169
|
+
children: [
|
|
3170
|
+
/* @__PURE__ */ jsx30("div", { className: designMode === true ? "pointer-events-auto" : void 0, children: /* @__PURE__ */ jsx30(
|
|
3171
|
+
Stepper,
|
|
3172
|
+
{
|
|
3173
|
+
steps: items.map(({ step: _step, ...item }) => item),
|
|
3174
|
+
activeStep: activeItem?.id ?? 0,
|
|
3175
|
+
onChange: (numericId) => {
|
|
3176
|
+
const target = items.find((item) => item.id === numericId);
|
|
3177
|
+
if (!target) return;
|
|
3178
|
+
if (designMode === true) {
|
|
3179
|
+
setDesignActiveStepId(target.step.id);
|
|
3180
|
+
return;
|
|
3181
|
+
}
|
|
3182
|
+
executeRendererStepperNavigation(
|
|
3183
|
+
engine,
|
|
3184
|
+
node.id,
|
|
3185
|
+
target.step.id,
|
|
3186
|
+
false
|
|
3187
|
+
);
|
|
3188
|
+
},
|
|
3189
|
+
orientation: normalizeStepperOrientation(props?.orientation),
|
|
3190
|
+
className: normalizeClassName5(props?.className),
|
|
3191
|
+
clickable: designMode === true || props?.clickable === true && isReady,
|
|
3192
|
+
dotStyle: props?.dotStyle === true,
|
|
3193
|
+
connector: normalizeStepperConnector(props?.connector)
|
|
3194
|
+
}
|
|
3195
|
+
) }),
|
|
3196
|
+
activeItem ? /* @__PURE__ */ jsx30("div", { className: normalizeClassName5(props?.contentClassName), children: /* @__PURE__ */ jsx30(NodeRenderer, { node: activeItem.step }) }) : null
|
|
3197
|
+
]
|
|
3198
|
+
}
|
|
3199
|
+
);
|
|
3200
|
+
}
|
|
3201
|
+
function normalizeStepperOrientation(value) {
|
|
3202
|
+
return value === "vertical" ? "vertical" : "horizontal";
|
|
3203
|
+
}
|
|
3204
|
+
function normalizeStepperConnector(value) {
|
|
3205
|
+
return value === "dashed" ? "dashed" : "solid";
|
|
3206
|
+
}
|
|
3207
|
+
function normalizeOptionalText(value) {
|
|
3208
|
+
return typeof value === "string" && value.trim() ? value.trim() : void 0;
|
|
3209
|
+
}
|
|
3210
|
+
function normalizeClassName5(value) {
|
|
3211
|
+
return typeof value === "string" ? value.trim() : "";
|
|
3212
|
+
}
|
|
3213
|
+
function normalizeAriaLabel2(value) {
|
|
3214
|
+
return typeof value === "string" && value.trim() ? value.trim() : "Form steps";
|
|
3215
|
+
}
|
|
3216
|
+
|
|
3217
|
+
// src/renderer/dialog-renderer.tsx
|
|
3218
|
+
import { Dialog } from "bsm-design-system";
|
|
3219
|
+
|
|
3220
|
+
// src/renderer/dialog-execution.ts
|
|
3221
|
+
function executeRendererDialogChange(engine, dialogId, open, designMode) {
|
|
3222
|
+
if (designMode) {
|
|
3223
|
+
return;
|
|
3224
|
+
}
|
|
3225
|
+
return open ? engine.openDialog(dialogId) : engine.closeDialog(dialogId);
|
|
3226
|
+
}
|
|
3227
|
+
|
|
3228
|
+
// src/renderer/dialog-renderer.tsx
|
|
3229
|
+
import { jsx as jsx31, jsxs as jsxs13 } from "react/jsx-runtime";
|
|
3230
|
+
function DialogRenderer({ node }) {
|
|
3231
|
+
if (node.schema.kind !== "layout" || node.schema.type !== "dialog") {
|
|
3232
|
+
return null;
|
|
3233
|
+
}
|
|
3234
|
+
const engine = useFormContext();
|
|
3235
|
+
const { designMode } = useConfigContext();
|
|
3236
|
+
if (designMode === true) {
|
|
3237
|
+
return /* @__PURE__ */ jsxs13(
|
|
3238
|
+
"div",
|
|
3239
|
+
{
|
|
3240
|
+
className: "space-y-2 rounded border border-dashed border-gray-300 p-2",
|
|
3241
|
+
"data-design-overlay": "dialog",
|
|
3242
|
+
children: [
|
|
3243
|
+
/* @__PURE__ */ jsx31("div", { className: "text-[10px] font-medium uppercase tracking-wide text-gray-500", children: "Dialog" }),
|
|
3244
|
+
node.children.map((child) => /* @__PURE__ */ jsx31(NodeRenderer, { node: child }, child.id))
|
|
3245
|
+
]
|
|
3246
|
+
}
|
|
3247
|
+
);
|
|
3248
|
+
}
|
|
3249
|
+
const state = engine.getDialogState(node.id);
|
|
3250
|
+
return /* @__PURE__ */ jsx31(
|
|
3251
|
+
Dialog,
|
|
3252
|
+
{
|
|
3253
|
+
open: state?.open === true,
|
|
3254
|
+
onClose: (open) => {
|
|
3255
|
+
void executeRendererDialogChange(
|
|
3256
|
+
engine,
|
|
3257
|
+
node.id,
|
|
3258
|
+
open,
|
|
3259
|
+
false
|
|
3260
|
+
);
|
|
3261
|
+
},
|
|
3262
|
+
size: normalizeDialogSize(node.schema.props?.size),
|
|
3263
|
+
disableCloseOutside: node.schema.props?.disableCloseOutside === true,
|
|
3264
|
+
children: node.children.map((child) => /* @__PURE__ */ jsx31(NodeRenderer, { node: child }, child.id))
|
|
3265
|
+
}
|
|
3266
|
+
);
|
|
3267
|
+
}
|
|
3268
|
+
function normalizeDialogSize(value) {
|
|
3269
|
+
return value === "sm" || value === "lg" || value === "xl" || value === "full" ? value : "md";
|
|
3270
|
+
}
|
|
3271
|
+
|
|
3272
|
+
// src/renderer/dialog-slot-renderer.tsx
|
|
3273
|
+
import { Dialog as Dialog2 } from "bsm-design-system";
|
|
3274
|
+
import { jsx as jsx32, jsxs as jsxs14 } from "react/jsx-runtime";
|
|
3275
|
+
function DialogSlotRenderer({ node }) {
|
|
3276
|
+
const show = useDesignVisible(node.state.visible);
|
|
3277
|
+
const { designMode } = useConfigContext();
|
|
3278
|
+
if (node.schema.kind !== "layout" || !show) {
|
|
3279
|
+
return null;
|
|
3280
|
+
}
|
|
3281
|
+
const children = node.children.map((child) => /* @__PURE__ */ jsx32(NodeRenderer, { node: child }, child.id));
|
|
3282
|
+
if (designMode === true) {
|
|
3283
|
+
return renderDesignModeSlot(node, children);
|
|
3284
|
+
}
|
|
3285
|
+
switch (node.schema.type) {
|
|
3286
|
+
case "dialog-header":
|
|
3287
|
+
return /* @__PURE__ */ jsx32(
|
|
3288
|
+
Dialog2.Header,
|
|
3289
|
+
{
|
|
3290
|
+
title: normalizeDialogTitle(node.schema.props.title),
|
|
3291
|
+
hideClose: node.schema.props.hideClose === true,
|
|
3292
|
+
children
|
|
3293
|
+
}
|
|
3294
|
+
);
|
|
3295
|
+
case "dialog-body":
|
|
3296
|
+
return /* @__PURE__ */ jsx32(
|
|
3297
|
+
"div",
|
|
3298
|
+
{
|
|
3299
|
+
"data-slot": "dialog-body",
|
|
3300
|
+
className: normalizeClassName6(node.schema.props?.className),
|
|
3301
|
+
children
|
|
3302
|
+
}
|
|
3303
|
+
);
|
|
3304
|
+
case "dialog-footer":
|
|
3305
|
+
return /* @__PURE__ */ jsx32(
|
|
3306
|
+
Dialog2.Footer,
|
|
3307
|
+
{
|
|
3308
|
+
className: normalizeClassName6(node.schema.props?.className),
|
|
3309
|
+
children
|
|
3310
|
+
}
|
|
3311
|
+
);
|
|
3312
|
+
default:
|
|
3313
|
+
return null;
|
|
3314
|
+
}
|
|
3315
|
+
}
|
|
3316
|
+
function renderDesignModeSlot(node, children) {
|
|
3317
|
+
const schema = node.schema;
|
|
3318
|
+
if (schema.kind !== "layout") return null;
|
|
3319
|
+
switch (schema.type) {
|
|
3320
|
+
case "dialog-header": {
|
|
3321
|
+
const title = normalizeDialogTitle(schema.props.title) || "Dialog header";
|
|
3322
|
+
return /* @__PURE__ */ jsxs14(
|
|
3323
|
+
"div",
|
|
3324
|
+
{
|
|
3325
|
+
"data-slot": "dialog-header",
|
|
3326
|
+
className: "rounded border border-dashed border-gray-200 p-2",
|
|
3327
|
+
children: [
|
|
3328
|
+
/* @__PURE__ */ jsx32("div", { className: "mb-1 text-[10px] font-medium uppercase tracking-wide text-gray-500", children: "Header" }),
|
|
3329
|
+
/* @__PURE__ */ jsx32("div", { className: "text-sm font-medium text-gray-800", children: title }),
|
|
3330
|
+
children
|
|
3331
|
+
]
|
|
3332
|
+
}
|
|
3333
|
+
);
|
|
3334
|
+
}
|
|
3335
|
+
case "dialog-body":
|
|
3336
|
+
return /* @__PURE__ */ jsxs14(
|
|
3337
|
+
"div",
|
|
3338
|
+
{
|
|
3339
|
+
"data-slot": "dialog-body",
|
|
3340
|
+
className: joinClassNames4(
|
|
3341
|
+
"min-h-16 rounded border border-dashed border-gray-200 p-2",
|
|
3342
|
+
normalizeClassName6(schema.props?.className)
|
|
3343
|
+
),
|
|
3344
|
+
children: [
|
|
3345
|
+
/* @__PURE__ */ jsx32("div", { className: "mb-1 text-[10px] font-medium uppercase tracking-wide text-gray-500", children: "Body" }),
|
|
3346
|
+
children
|
|
3347
|
+
]
|
|
3348
|
+
}
|
|
3349
|
+
);
|
|
3350
|
+
case "dialog-footer":
|
|
3351
|
+
return /* @__PURE__ */ jsxs14(
|
|
3352
|
+
"div",
|
|
3353
|
+
{
|
|
3354
|
+
"data-slot": "dialog-footer",
|
|
3355
|
+
className: joinClassNames4(
|
|
3356
|
+
"min-h-12 rounded border border-dashed border-gray-200 p-2",
|
|
3357
|
+
normalizeClassName6(schema.props?.className)
|
|
3358
|
+
),
|
|
3359
|
+
children: [
|
|
3360
|
+
/* @__PURE__ */ jsx32("div", { className: "mb-1 text-[10px] font-medium uppercase tracking-wide text-gray-500", children: "Footer" }),
|
|
3361
|
+
children
|
|
3362
|
+
]
|
|
3363
|
+
}
|
|
3364
|
+
);
|
|
3365
|
+
default:
|
|
3366
|
+
return null;
|
|
3367
|
+
}
|
|
3368
|
+
}
|
|
3369
|
+
function normalizeDialogTitle(value) {
|
|
3370
|
+
return typeof value === "string" ? value.trim() : "";
|
|
3371
|
+
}
|
|
3372
|
+
function normalizeClassName6(value) {
|
|
3373
|
+
return typeof value === "string" ? value.trim() : "";
|
|
3374
|
+
}
|
|
3375
|
+
function joinClassNames4(...parts) {
|
|
3376
|
+
return parts.filter((part) => typeof part === "string" && part.length > 0).join(" ");
|
|
3377
|
+
}
|
|
3378
|
+
|
|
3379
|
+
// src/renderer/drawer-renderer.tsx
|
|
3380
|
+
import { Drawer } from "bsm-design-system";
|
|
3381
|
+
|
|
3382
|
+
// src/renderer/drawer-execution.ts
|
|
3383
|
+
function executeRendererDrawerChange(engine, drawerId, open, designMode) {
|
|
3384
|
+
if (designMode) {
|
|
3385
|
+
return;
|
|
3386
|
+
}
|
|
3387
|
+
return open ? engine.openDrawer(drawerId) : engine.closeDrawer(drawerId);
|
|
3388
|
+
}
|
|
3389
|
+
|
|
3390
|
+
// src/renderer/drawer-renderer.tsx
|
|
3391
|
+
import { jsx as jsx33, jsxs as jsxs15 } from "react/jsx-runtime";
|
|
3392
|
+
function DrawerRenderer({ node }) {
|
|
3393
|
+
if (node.schema.kind !== "layout" || node.schema.type !== "drawer") {
|
|
3394
|
+
return null;
|
|
3395
|
+
}
|
|
3396
|
+
const engine = useFormContext();
|
|
3397
|
+
const { designMode } = useConfigContext();
|
|
3398
|
+
if (designMode === true) {
|
|
3399
|
+
const side = normalizeDrawerSide(node.schema.props?.side);
|
|
3400
|
+
return /* @__PURE__ */ jsxs15(
|
|
3401
|
+
"div",
|
|
3402
|
+
{
|
|
3403
|
+
className: "space-y-2 rounded border border-dashed border-gray-300 p-2",
|
|
3404
|
+
"data-design-overlay": "drawer",
|
|
3405
|
+
"data-side": side,
|
|
3406
|
+
children: [
|
|
3407
|
+
/* @__PURE__ */ jsxs15("div", { className: "text-[10px] font-medium uppercase tracking-wide text-gray-500", children: [
|
|
3408
|
+
"Drawer (",
|
|
3409
|
+
side,
|
|
3410
|
+
")"
|
|
3411
|
+
] }),
|
|
3412
|
+
node.children.map((child) => /* @__PURE__ */ jsx33(NodeRenderer, { node: child }, child.id))
|
|
3413
|
+
]
|
|
3414
|
+
}
|
|
3415
|
+
);
|
|
3416
|
+
}
|
|
3417
|
+
const state = engine.getDrawerState(node.id);
|
|
3418
|
+
return /* @__PURE__ */ jsx33(
|
|
3419
|
+
Drawer,
|
|
3420
|
+
{
|
|
3421
|
+
open: state?.open === true,
|
|
3422
|
+
onClose: (open) => {
|
|
3423
|
+
void executeRendererDrawerChange(
|
|
3424
|
+
engine,
|
|
3425
|
+
node.id,
|
|
3426
|
+
open,
|
|
3427
|
+
false
|
|
3428
|
+
);
|
|
3429
|
+
},
|
|
3430
|
+
side: normalizeDrawerSide(node.schema.props?.side),
|
|
3431
|
+
disableCloseOutside: node.schema.props?.disableCloseOutside === true,
|
|
3432
|
+
children: node.children.map((child) => /* @__PURE__ */ jsx33(NodeRenderer, { node: child }, child.id))
|
|
3433
|
+
}
|
|
3434
|
+
);
|
|
3435
|
+
}
|
|
3436
|
+
function normalizeDrawerSide(value) {
|
|
3437
|
+
return value === "top" || value === "right" || value === "bottom" ? value : "left";
|
|
3438
|
+
}
|
|
3439
|
+
|
|
3440
|
+
// src/renderer/drawer-slot-renderer.tsx
|
|
3441
|
+
import { Drawer as Drawer2 } from "bsm-design-system";
|
|
3442
|
+
import { jsx as jsx34, jsxs as jsxs16 } from "react/jsx-runtime";
|
|
3443
|
+
function DrawerSlotRenderer({ node }) {
|
|
3444
|
+
const show = useDesignVisible(node.state.visible);
|
|
3445
|
+
const { designMode } = useConfigContext();
|
|
3446
|
+
if (node.schema.kind !== "layout" || !show) {
|
|
3447
|
+
return null;
|
|
3448
|
+
}
|
|
3449
|
+
const children = node.children.map((child) => /* @__PURE__ */ jsx34(NodeRenderer, { node: child }, child.id));
|
|
3450
|
+
if (designMode === true) {
|
|
3451
|
+
return renderDesignModeSlot2(node, children);
|
|
3452
|
+
}
|
|
3453
|
+
switch (node.schema.type) {
|
|
3454
|
+
case "drawer-header":
|
|
3455
|
+
return /* @__PURE__ */ jsx34(
|
|
3456
|
+
Drawer2.Header,
|
|
3457
|
+
{
|
|
3458
|
+
title: normalizeDrawerTitle(node.schema.props.title),
|
|
3459
|
+
hideClose: node.schema.props.hideClose === true,
|
|
3460
|
+
children
|
|
3461
|
+
}
|
|
3462
|
+
);
|
|
3463
|
+
case "drawer-body":
|
|
3464
|
+
return /* @__PURE__ */ jsx34(
|
|
3465
|
+
"div",
|
|
3466
|
+
{
|
|
3467
|
+
"data-slot": "drawer-body",
|
|
3468
|
+
className: normalizeClassName7(node.schema.props?.className),
|
|
3469
|
+
children
|
|
3470
|
+
}
|
|
3471
|
+
);
|
|
3472
|
+
case "drawer-footer":
|
|
3473
|
+
return /* @__PURE__ */ jsx34(
|
|
3474
|
+
Drawer2.Footer,
|
|
3475
|
+
{
|
|
3476
|
+
className: normalizeClassName7(node.schema.props?.className),
|
|
3477
|
+
children
|
|
3478
|
+
}
|
|
3479
|
+
);
|
|
3480
|
+
default:
|
|
3481
|
+
return null;
|
|
3482
|
+
}
|
|
3483
|
+
}
|
|
3484
|
+
function renderDesignModeSlot2(node, children) {
|
|
3485
|
+
const schema = node.schema;
|
|
3486
|
+
if (schema.kind !== "layout") return null;
|
|
3487
|
+
switch (schema.type) {
|
|
3488
|
+
case "drawer-header": {
|
|
3489
|
+
const title = normalizeDrawerTitle(schema.props.title) || "Drawer header";
|
|
3490
|
+
return /* @__PURE__ */ jsxs16(
|
|
3491
|
+
"div",
|
|
3492
|
+
{
|
|
3493
|
+
"data-slot": "drawer-header",
|
|
3494
|
+
className: "rounded border border-dashed border-gray-200 p-2",
|
|
3495
|
+
children: [
|
|
3496
|
+
/* @__PURE__ */ jsx34("div", { className: "mb-1 text-[10px] font-medium uppercase tracking-wide text-gray-500", children: "Header" }),
|
|
3497
|
+
/* @__PURE__ */ jsx34("div", { className: "text-sm font-medium text-gray-800", children: title }),
|
|
3498
|
+
children
|
|
3499
|
+
]
|
|
3500
|
+
}
|
|
3501
|
+
);
|
|
3502
|
+
}
|
|
3503
|
+
case "drawer-body":
|
|
3504
|
+
return /* @__PURE__ */ jsxs16(
|
|
3505
|
+
"div",
|
|
3506
|
+
{
|
|
3507
|
+
"data-slot": "drawer-body",
|
|
3508
|
+
className: joinClassNames5(
|
|
3509
|
+
"min-h-16 rounded border border-dashed border-gray-200 p-2",
|
|
3510
|
+
normalizeClassName7(schema.props?.className)
|
|
3511
|
+
),
|
|
3512
|
+
children: [
|
|
3513
|
+
/* @__PURE__ */ jsx34("div", { className: "mb-1 text-[10px] font-medium uppercase tracking-wide text-gray-500", children: "Body" }),
|
|
3514
|
+
children
|
|
3515
|
+
]
|
|
3516
|
+
}
|
|
3517
|
+
);
|
|
3518
|
+
case "drawer-footer":
|
|
3519
|
+
return /* @__PURE__ */ jsxs16(
|
|
3520
|
+
"div",
|
|
3521
|
+
{
|
|
3522
|
+
"data-slot": "drawer-footer",
|
|
3523
|
+
className: joinClassNames5(
|
|
3524
|
+
"min-h-12 rounded border border-dashed border-gray-200 p-2",
|
|
3525
|
+
normalizeClassName7(schema.props?.className)
|
|
3526
|
+
),
|
|
3527
|
+
children: [
|
|
3528
|
+
/* @__PURE__ */ jsx34("div", { className: "mb-1 text-[10px] font-medium uppercase tracking-wide text-gray-500", children: "Footer" }),
|
|
3529
|
+
children
|
|
3530
|
+
]
|
|
3531
|
+
}
|
|
3532
|
+
);
|
|
3533
|
+
default:
|
|
3534
|
+
return null;
|
|
3535
|
+
}
|
|
3536
|
+
}
|
|
3537
|
+
function normalizeDrawerTitle(value) {
|
|
3538
|
+
return typeof value === "string" ? value.trim() : "";
|
|
3539
|
+
}
|
|
3540
|
+
function normalizeClassName7(value) {
|
|
3541
|
+
return typeof value === "string" ? value.trim() : "";
|
|
3542
|
+
}
|
|
3543
|
+
function joinClassNames5(...parts) {
|
|
3544
|
+
return parts.filter((part) => typeof part === "string" && part.length > 0).join(" ");
|
|
3545
|
+
}
|
|
3546
|
+
|
|
3547
|
+
// src/components/tooltip.tsx
|
|
3548
|
+
import { Tooltip } from "bsm-design-system";
|
|
3549
|
+
import { jsx as jsx35, jsxs as jsxs17 } from "react/jsx-runtime";
|
|
3550
|
+
function TooltipLayout({
|
|
3551
|
+
children,
|
|
3552
|
+
content,
|
|
3553
|
+
side,
|
|
3554
|
+
sideOffset,
|
|
3555
|
+
delayDuration,
|
|
3556
|
+
defaultOpen,
|
|
3557
|
+
className
|
|
3558
|
+
}) {
|
|
3559
|
+
return /* @__PURE__ */ jsxs17(
|
|
3560
|
+
Tooltip,
|
|
3561
|
+
{
|
|
3562
|
+
delayDuration: normalizeTooltipDelayDuration(delayDuration),
|
|
3563
|
+
defaultOpen: normalizeTooltipDefaultOpen(defaultOpen),
|
|
3564
|
+
children: [
|
|
3565
|
+
/* @__PURE__ */ jsx35(Tooltip.Trigger, { children }),
|
|
3566
|
+
/* @__PURE__ */ jsx35(
|
|
3567
|
+
Tooltip.Content,
|
|
3568
|
+
{
|
|
3569
|
+
side: normalizeTooltipSide(side),
|
|
3570
|
+
sideOffset: normalizeTooltipSideOffset(sideOffset),
|
|
3571
|
+
className: normalizeTooltipClassName(className),
|
|
3572
|
+
children: normalizeTooltipContent(content)
|
|
3573
|
+
}
|
|
3574
|
+
)
|
|
3575
|
+
]
|
|
3576
|
+
}
|
|
3577
|
+
);
|
|
3578
|
+
}
|
|
3579
|
+
function normalizeTooltipContent(value) {
|
|
3580
|
+
if (typeof value !== "string") {
|
|
3581
|
+
return "";
|
|
3582
|
+
}
|
|
3583
|
+
return value.trim();
|
|
3584
|
+
}
|
|
3585
|
+
function normalizeTooltipSide(value) {
|
|
3586
|
+
return value === "right" || value === "bottom" || value === "left" ? value : "top";
|
|
3587
|
+
}
|
|
3588
|
+
function normalizeTooltipSideOffset(value) {
|
|
3589
|
+
return normalizeNonNegativeNumber(value, 0);
|
|
3590
|
+
}
|
|
3591
|
+
function normalizeTooltipDelayDuration(value) {
|
|
3592
|
+
return normalizeNonNegativeNumber(value, 0);
|
|
3593
|
+
}
|
|
3594
|
+
function normalizeTooltipDefaultOpen(value) {
|
|
3595
|
+
return value === true;
|
|
3596
|
+
}
|
|
3597
|
+
function normalizeTooltipClassName(value) {
|
|
3598
|
+
if (typeof value !== "string") {
|
|
3599
|
+
return void 0;
|
|
3600
|
+
}
|
|
3601
|
+
const className = value.trim();
|
|
3602
|
+
return className || void 0;
|
|
3603
|
+
}
|
|
3604
|
+
function normalizeNonNegativeNumber(value, fallback) {
|
|
3605
|
+
return typeof value === "number" && Number.isFinite(value) && value >= 0 ? value : fallback;
|
|
3606
|
+
}
|
|
3607
|
+
|
|
3608
|
+
// src/components/trigger-bridge.tsx
|
|
3609
|
+
import {
|
|
3610
|
+
forwardRef,
|
|
3611
|
+
useCallback,
|
|
3612
|
+
useEffect as useEffect5,
|
|
3613
|
+
useState as useState5
|
|
3614
|
+
} from "react";
|
|
3615
|
+
import { jsx as jsx36 } from "react/jsx-runtime";
|
|
3616
|
+
var FOCUSABLE_SELECTOR = [
|
|
3617
|
+
"a[href]",
|
|
3618
|
+
"button:not([disabled])",
|
|
3619
|
+
'input:not([disabled]):not([type="hidden"])',
|
|
3620
|
+
"select:not([disabled])",
|
|
3621
|
+
"textarea:not([disabled])",
|
|
3622
|
+
'[contenteditable="true"]',
|
|
3623
|
+
'[tabindex]:not([tabindex="-1"])'
|
|
3624
|
+
].join(",");
|
|
3625
|
+
var MIRRORED_ATTRIBUTES = [
|
|
3626
|
+
"aria-controls",
|
|
3627
|
+
"aria-expanded",
|
|
3628
|
+
"aria-haspopup",
|
|
3629
|
+
"aria-label"
|
|
3630
|
+
];
|
|
3631
|
+
var TriggerBridge = forwardRef(function TriggerBridge2({
|
|
3632
|
+
activateWhenNonInteractive = false,
|
|
3633
|
+
children,
|
|
3634
|
+
className,
|
|
3635
|
+
disabled = false,
|
|
3636
|
+
onClickCapture,
|
|
3637
|
+
onKeyDown,
|
|
3638
|
+
onKeyDownCapture,
|
|
3639
|
+
onPointerDownCapture,
|
|
3640
|
+
tabIndex,
|
|
3641
|
+
...props
|
|
3642
|
+
}, forwardedRef) {
|
|
3643
|
+
const [element, setElement] = useState5(null);
|
|
3644
|
+
const [hasFocusableDescendant, setHasFocusableDescendant] = useState5(true);
|
|
3645
|
+
const assignRef = useCallback(
|
|
3646
|
+
(node) => {
|
|
3647
|
+
setElement(node);
|
|
3648
|
+
setForwardedRef(forwardedRef, node);
|
|
3649
|
+
},
|
|
3650
|
+
[forwardedRef]
|
|
3651
|
+
);
|
|
3652
|
+
useEffect5(() => {
|
|
3653
|
+
if (!element) {
|
|
3654
|
+
return;
|
|
3655
|
+
}
|
|
3656
|
+
let describedElement = null;
|
|
3657
|
+
let addedDescriptionIds = [];
|
|
3658
|
+
let attributeMirrors = [];
|
|
3659
|
+
const clearMirroredAttributes = () => {
|
|
3660
|
+
if (describedElement && addedDescriptionIds.length > 0) {
|
|
3661
|
+
const remainingIds = readDescriptionIds(describedElement).filter(
|
|
3662
|
+
(id) => !addedDescriptionIds.includes(id)
|
|
3663
|
+
);
|
|
3664
|
+
writeDescriptionIds(describedElement, remainingIds);
|
|
3665
|
+
}
|
|
3666
|
+
for (const mirror of attributeMirrors) {
|
|
3667
|
+
if (mirror.target.getAttribute(mirror.attribute) !== mirror.appliedValue) {
|
|
3668
|
+
continue;
|
|
3669
|
+
}
|
|
3670
|
+
if (mirror.previousValue === null) {
|
|
3671
|
+
mirror.target.removeAttribute(mirror.attribute);
|
|
3672
|
+
} else {
|
|
3673
|
+
mirror.target.setAttribute(
|
|
3674
|
+
mirror.attribute,
|
|
3675
|
+
mirror.previousValue
|
|
3676
|
+
);
|
|
3677
|
+
}
|
|
3678
|
+
}
|
|
3679
|
+
describedElement = null;
|
|
3680
|
+
addedDescriptionIds = [];
|
|
3681
|
+
attributeMirrors = [];
|
|
3682
|
+
};
|
|
3683
|
+
const synchronize = () => {
|
|
3684
|
+
clearMirroredAttributes();
|
|
3685
|
+
const focusableElement = element.querySelector(FOCUSABLE_SELECTOR);
|
|
3686
|
+
setHasFocusableDescendant(Boolean(focusableElement));
|
|
3687
|
+
if (!focusableElement) {
|
|
3688
|
+
return;
|
|
3689
|
+
}
|
|
3690
|
+
const descriptionIds = readDescriptionIds(element);
|
|
3691
|
+
if (descriptionIds.length > 0) {
|
|
3692
|
+
const existingIds = readDescriptionIds(focusableElement);
|
|
3693
|
+
addedDescriptionIds = descriptionIds.filter(
|
|
3694
|
+
(id) => !existingIds.includes(id)
|
|
3695
|
+
);
|
|
3696
|
+
describedElement = focusableElement;
|
|
3697
|
+
writeDescriptionIds(focusableElement, [
|
|
3698
|
+
...existingIds,
|
|
3699
|
+
...addedDescriptionIds
|
|
3700
|
+
]);
|
|
3701
|
+
}
|
|
3702
|
+
for (const attribute of MIRRORED_ATTRIBUTES) {
|
|
3703
|
+
const value = element.getAttribute(attribute);
|
|
3704
|
+
if (value === null) {
|
|
3705
|
+
continue;
|
|
3706
|
+
}
|
|
3707
|
+
attributeMirrors.push({
|
|
3708
|
+
attribute,
|
|
3709
|
+
target: focusableElement,
|
|
3710
|
+
previousValue: focusableElement.getAttribute(attribute),
|
|
3711
|
+
appliedValue: value
|
|
3712
|
+
});
|
|
3713
|
+
focusableElement.setAttribute(attribute, value);
|
|
3714
|
+
}
|
|
3715
|
+
};
|
|
3716
|
+
synchronize();
|
|
3717
|
+
if (typeof MutationObserver === "undefined") {
|
|
3718
|
+
return clearMirroredAttributes;
|
|
3719
|
+
}
|
|
3720
|
+
const rootObserver = new MutationObserver(synchronize);
|
|
3721
|
+
rootObserver.observe(element, {
|
|
3722
|
+
attributes: true,
|
|
3723
|
+
attributeFilter: ["aria-describedby", ...MIRRORED_ATTRIBUTES]
|
|
3724
|
+
});
|
|
3725
|
+
const descendantsObserver = new MutationObserver(synchronize);
|
|
3726
|
+
descendantsObserver.observe(element, {
|
|
3727
|
+
childList: true,
|
|
3728
|
+
subtree: true,
|
|
3729
|
+
attributes: true,
|
|
3730
|
+
attributeFilter: [
|
|
3731
|
+
"contenteditable",
|
|
3732
|
+
"disabled",
|
|
3733
|
+
"href",
|
|
3734
|
+
"tabindex",
|
|
3735
|
+
"type"
|
|
3736
|
+
]
|
|
3737
|
+
});
|
|
3738
|
+
return () => {
|
|
3739
|
+
rootObserver.disconnect();
|
|
3740
|
+
descendantsObserver.disconnect();
|
|
3741
|
+
clearMirroredAttributes();
|
|
3742
|
+
};
|
|
3743
|
+
}, [element]);
|
|
3744
|
+
const handleKeyDown = (event) => {
|
|
3745
|
+
onKeyDown?.(event);
|
|
3746
|
+
if (activateWhenNonInteractive && !hasFocusableDescendant && !event.defaultPrevented && event.currentTarget === event.target && (event.key === "Enter" || event.key === " ")) {
|
|
3747
|
+
event.preventDefault();
|
|
3748
|
+
event.currentTarget.click();
|
|
3749
|
+
}
|
|
3750
|
+
};
|
|
3751
|
+
const handleDisabledInteraction = (event) => {
|
|
3752
|
+
if (!disabled) {
|
|
3753
|
+
return;
|
|
3754
|
+
}
|
|
3755
|
+
event.preventDefault();
|
|
3756
|
+
event.stopPropagation();
|
|
3757
|
+
};
|
|
3758
|
+
return /* @__PURE__ */ jsx36(
|
|
3759
|
+
"span",
|
|
3760
|
+
{
|
|
3761
|
+
...props,
|
|
3762
|
+
ref: assignRef,
|
|
3763
|
+
"aria-disabled": disabled || void 0,
|
|
3764
|
+
className: ["inline-flex max-w-full", className].filter(Boolean).join(" "),
|
|
3765
|
+
inert: disabled ? true : void 0,
|
|
3766
|
+
onClickCapture: (event) => {
|
|
3767
|
+
onClickCapture?.(event);
|
|
3768
|
+
handleDisabledInteraction(event);
|
|
3769
|
+
},
|
|
3770
|
+
onKeyDown: handleKeyDown,
|
|
3771
|
+
onKeyDownCapture: (event) => {
|
|
3772
|
+
onKeyDownCapture?.(event);
|
|
3773
|
+
handleDisabledInteraction(event);
|
|
3774
|
+
},
|
|
3775
|
+
onPointerDownCapture: (event) => {
|
|
3776
|
+
onPointerDownCapture?.(event);
|
|
3777
|
+
handleDisabledInteraction(event);
|
|
3778
|
+
},
|
|
3779
|
+
tabIndex: disabled ? -1 : tabIndex ?? (hasFocusableDescendant ? void 0 : 0),
|
|
3780
|
+
children
|
|
3781
|
+
}
|
|
3782
|
+
);
|
|
3783
|
+
});
|
|
3784
|
+
function readDescriptionIds(element) {
|
|
3785
|
+
return (element.getAttribute("aria-describedby") ?? "").split(/\s+/).filter(Boolean);
|
|
3786
|
+
}
|
|
3787
|
+
function writeDescriptionIds(element, ids) {
|
|
3788
|
+
if (ids.length === 0) {
|
|
3789
|
+
element.removeAttribute("aria-describedby");
|
|
3790
|
+
return;
|
|
3791
|
+
}
|
|
3792
|
+
element.setAttribute("aria-describedby", ids.join(" "));
|
|
3793
|
+
}
|
|
3794
|
+
function setForwardedRef(ref, value) {
|
|
3795
|
+
if (typeof ref === "function") {
|
|
3796
|
+
ref(value);
|
|
3797
|
+
return;
|
|
3798
|
+
}
|
|
3799
|
+
if (ref) {
|
|
3800
|
+
ref.current = value;
|
|
3801
|
+
}
|
|
3802
|
+
}
|
|
3803
|
+
|
|
3804
|
+
// src/renderer/tooltip-renderer.tsx
|
|
3805
|
+
import { jsx as jsx37 } from "react/jsx-runtime";
|
|
3806
|
+
function TooltipRenderer({ node }) {
|
|
3807
|
+
const schema = node.schema;
|
|
3808
|
+
const { designMode } = useConfigContext();
|
|
3809
|
+
if (schema.kind !== "layout" || schema.type !== "tooltip") {
|
|
3810
|
+
return null;
|
|
3811
|
+
}
|
|
3812
|
+
const child = node.children[0];
|
|
3813
|
+
if (!child) {
|
|
3814
|
+
return null;
|
|
3815
|
+
}
|
|
3816
|
+
if (designMode === true) {
|
|
3817
|
+
return /* @__PURE__ */ jsx37(NodeRenderer, { node: child });
|
|
3818
|
+
}
|
|
3819
|
+
return /* @__PURE__ */ jsx37(
|
|
3820
|
+
TooltipLayout,
|
|
3821
|
+
{
|
|
3822
|
+
content: schema.props.content,
|
|
3823
|
+
side: schema.props.side,
|
|
3824
|
+
sideOffset: schema.props.sideOffset,
|
|
3825
|
+
delayDuration: schema.props.delayDuration,
|
|
3826
|
+
defaultOpen: schema.props.defaultOpen,
|
|
3827
|
+
className: schema.props.className,
|
|
3828
|
+
children: /* @__PURE__ */ jsx37(TriggerBridge, { children: /* @__PURE__ */ jsx37(NodeRenderer, { node: child }) })
|
|
3829
|
+
}
|
|
3830
|
+
);
|
|
3831
|
+
}
|
|
3832
|
+
|
|
3833
|
+
// src/renderer/popover-renderer.tsx
|
|
3834
|
+
import { Popover } from "bsm-design-system";
|
|
3835
|
+
import { jsx as jsx38 } from "react/jsx-runtime";
|
|
3836
|
+
function PopoverRenderer({ node }) {
|
|
3837
|
+
if (node.schema.kind !== "layout" || node.schema.type !== "popover") {
|
|
3838
|
+
return null;
|
|
3839
|
+
}
|
|
3840
|
+
const { designMode } = useConfigContext();
|
|
3841
|
+
if (designMode === true) {
|
|
3842
|
+
return /* @__PURE__ */ jsx38("div", { className: "space-y-3 rounded border border-dashed border-gray-300 p-2", children: node.children.map((child) => /* @__PURE__ */ jsx38(NodeRenderer, { node: child }, child.id)) });
|
|
3843
|
+
}
|
|
3844
|
+
const rootProps = buildPopoverRootProps(node.schema.props);
|
|
3845
|
+
return /* @__PURE__ */ jsx38(Popover, { ...rootProps, children: node.children.map((child) => /* @__PURE__ */ jsx38(NodeRenderer, { node: child }, child.id)) });
|
|
3846
|
+
}
|
|
3847
|
+
function buildPopoverRootProps(props) {
|
|
3848
|
+
const record = typeof props === "object" && props !== null ? props : void 0;
|
|
3849
|
+
return {
|
|
3850
|
+
defaultOpen: normalizePopoverDefaultOpen(record?.defaultOpen),
|
|
3851
|
+
modal: normalizePopoverModal(record?.modal)
|
|
3852
|
+
};
|
|
3853
|
+
}
|
|
3854
|
+
function normalizePopoverDefaultOpen(value) {
|
|
3855
|
+
return value === true;
|
|
3856
|
+
}
|
|
3857
|
+
function normalizePopoverModal(value) {
|
|
3858
|
+
return value === true;
|
|
3859
|
+
}
|
|
3860
|
+
|
|
3861
|
+
// src/renderer/popover-slot-renderer.tsx
|
|
3862
|
+
import { Popover as Popover2 } from "bsm-design-system";
|
|
3863
|
+
import { jsx as jsx39 } from "react/jsx-runtime";
|
|
3864
|
+
function PopoverSlotRenderer({ node }) {
|
|
3865
|
+
if (node.schema.kind !== "layout" || !node.state.visible) {
|
|
3866
|
+
return null;
|
|
3867
|
+
}
|
|
3868
|
+
const { designMode } = useConfigContext();
|
|
3869
|
+
if (node.schema.type === "popover-trigger") {
|
|
3870
|
+
const child = node.children[0];
|
|
3871
|
+
if (!child) {
|
|
3872
|
+
return null;
|
|
3873
|
+
}
|
|
3874
|
+
if (designMode === true) {
|
|
3875
|
+
return /* @__PURE__ */ jsx39(
|
|
3876
|
+
"div",
|
|
3877
|
+
{
|
|
3878
|
+
"data-slot": "popover-trigger",
|
|
3879
|
+
className: normalizePopoverClassName(node.schema.props?.className),
|
|
3880
|
+
"aria-label": normalizePopoverAriaLabel(node.schema.props?.ariaLabel),
|
|
3881
|
+
children: /* @__PURE__ */ jsx39(NodeRenderer, { node: child })
|
|
3882
|
+
}
|
|
3883
|
+
);
|
|
3884
|
+
}
|
|
3885
|
+
return /* @__PURE__ */ jsx39(Popover2.Trigger, { children: /* @__PURE__ */ jsx39(
|
|
3886
|
+
TriggerBridge,
|
|
3887
|
+
{
|
|
3888
|
+
activateWhenNonInteractive: true,
|
|
3889
|
+
className: normalizePopoverClassName(
|
|
3890
|
+
node.schema.props?.className
|
|
3891
|
+
),
|
|
3892
|
+
"aria-label": normalizePopoverAriaLabel(
|
|
3893
|
+
node.schema.props?.ariaLabel
|
|
3894
|
+
),
|
|
3895
|
+
children: /* @__PURE__ */ jsx39(NodeRenderer, { node: child })
|
|
3896
|
+
}
|
|
3897
|
+
) });
|
|
3898
|
+
}
|
|
3899
|
+
if (node.schema.type === "popover-content") {
|
|
3900
|
+
const contentProps = buildPopoverContentProps(node.schema.props);
|
|
3901
|
+
const children = node.children.map((child) => /* @__PURE__ */ jsx39(NodeRenderer, { node: child }, child.id));
|
|
3902
|
+
if (designMode === true) {
|
|
3903
|
+
return /* @__PURE__ */ jsx39(
|
|
3904
|
+
"div",
|
|
3905
|
+
{
|
|
3906
|
+
"data-slot": "popover-content",
|
|
3907
|
+
className: joinClassNames6(
|
|
3908
|
+
"min-h-12 rounded border border-dashed border-gray-200 p-2",
|
|
3909
|
+
contentProps.className
|
|
3910
|
+
),
|
|
3911
|
+
"aria-label": contentProps["aria-label"],
|
|
3912
|
+
children
|
|
3913
|
+
}
|
|
3914
|
+
);
|
|
3915
|
+
}
|
|
3916
|
+
return /* @__PURE__ */ jsx39(Popover2.Content, { ...contentProps, children });
|
|
3917
|
+
}
|
|
3918
|
+
return null;
|
|
3919
|
+
}
|
|
3920
|
+
function buildPopoverContentProps(props) {
|
|
3921
|
+
const record = typeof props === "object" && props !== null ? props : void 0;
|
|
3922
|
+
return {
|
|
3923
|
+
align: normalizePopoverAlign(record?.align),
|
|
3924
|
+
side: normalizePopoverSide(record?.side),
|
|
3925
|
+
sideOffset: normalizePopoverSideOffset(record?.sideOffset),
|
|
3926
|
+
alignOffset: normalizePopoverAlignOffset(record?.alignOffset),
|
|
3927
|
+
className: normalizePopoverClassName(record?.className),
|
|
3928
|
+
"aria-label": normalizePopoverAriaLabel(record?.ariaLabel)
|
|
3929
|
+
};
|
|
3930
|
+
}
|
|
3931
|
+
function normalizePopoverAlign(value) {
|
|
3932
|
+
return value === "start" || value === "end" ? value : "center";
|
|
3933
|
+
}
|
|
3934
|
+
function normalizePopoverSide(value) {
|
|
3935
|
+
return value === "top" || value === "right" || value === "left" ? value : "bottom";
|
|
3936
|
+
}
|
|
3937
|
+
function normalizePopoverSideOffset(value) {
|
|
3938
|
+
return typeof value === "number" && Number.isFinite(value) && value >= 0 ? value : 4;
|
|
3939
|
+
}
|
|
3940
|
+
function normalizePopoverAlignOffset(value) {
|
|
3941
|
+
return typeof value === "number" && Number.isFinite(value) ? value : 0;
|
|
3942
|
+
}
|
|
3943
|
+
function normalizePopoverClassName(value) {
|
|
3944
|
+
if (typeof value !== "string") {
|
|
3945
|
+
return void 0;
|
|
3946
|
+
}
|
|
3947
|
+
const className = value.trim();
|
|
3948
|
+
return className || void 0;
|
|
3949
|
+
}
|
|
3950
|
+
function normalizePopoverAriaLabel(value) {
|
|
3951
|
+
if (typeof value !== "string") {
|
|
3952
|
+
return void 0;
|
|
3953
|
+
}
|
|
3954
|
+
const ariaLabel = value.trim();
|
|
3955
|
+
return ariaLabel || void 0;
|
|
3956
|
+
}
|
|
3957
|
+
function joinClassNames6(...parts) {
|
|
3958
|
+
return parts.filter(Boolean).join(" ") || void 0;
|
|
3959
|
+
}
|
|
3960
|
+
|
|
3961
|
+
// src/renderer/dropdown-menu-renderer.tsx
|
|
3962
|
+
import { DropdownMenu } from "bsm-design-system";
|
|
3963
|
+
import { jsx as jsx40 } from "react/jsx-runtime";
|
|
3964
|
+
function DropdownMenuRenderer({ node }) {
|
|
3965
|
+
if (node.schema.kind !== "layout" || node.schema.type !== "dropdown-menu") {
|
|
3966
|
+
return null;
|
|
3967
|
+
}
|
|
3968
|
+
const { designMode } = useConfigContext();
|
|
3969
|
+
if (designMode === true) {
|
|
3970
|
+
return /* @__PURE__ */ jsx40("div", { className: "space-y-3 rounded border border-dashed border-gray-300 p-2", children: node.children.map((child) => /* @__PURE__ */ jsx40(NodeRenderer, { node: child }, child.id)) });
|
|
3971
|
+
}
|
|
3972
|
+
const rootProps = buildDropdownMenuRootProps(node.schema.props);
|
|
3973
|
+
return /* @__PURE__ */ jsx40(DropdownMenu, { ...rootProps, children: node.children.map((child) => /* @__PURE__ */ jsx40(NodeRenderer, { node: child }, child.id)) });
|
|
3974
|
+
}
|
|
3975
|
+
function buildDropdownMenuRootProps(props) {
|
|
3976
|
+
const record = typeof props === "object" && props !== null ? props : void 0;
|
|
3977
|
+
return {
|
|
3978
|
+
defaultOpen: normalizeDropdownMenuDefaultOpen(record?.defaultOpen),
|
|
3979
|
+
modal: normalizeDropdownMenuModal(record?.modal)
|
|
3980
|
+
};
|
|
3981
|
+
}
|
|
3982
|
+
function normalizeDropdownMenuDefaultOpen(value) {
|
|
3983
|
+
return value === true;
|
|
3984
|
+
}
|
|
3985
|
+
function normalizeDropdownMenuModal(value) {
|
|
3986
|
+
return value !== false;
|
|
3987
|
+
}
|
|
3988
|
+
|
|
3989
|
+
// src/renderer/dropdown-menu-slot-renderer.tsx
|
|
3990
|
+
import { DropdownMenu as DropdownMenu2 } from "bsm-design-system";
|
|
3991
|
+
import { jsx as jsx41, jsxs as jsxs18 } from "react/jsx-runtime";
|
|
3992
|
+
function DropdownMenuSlotRenderer({ node }) {
|
|
3993
|
+
if (node.schema.kind !== "layout" || !node.state.visible) {
|
|
3994
|
+
return null;
|
|
3995
|
+
}
|
|
3996
|
+
const { designMode } = useConfigContext();
|
|
3997
|
+
const schema = node.schema;
|
|
3998
|
+
const children = node.children.map((child) => /* @__PURE__ */ jsx41(NodeRenderer, { node: child }, child.id));
|
|
3999
|
+
if (designMode === true) {
|
|
4000
|
+
return renderDesignModeSlot3(node, children);
|
|
4001
|
+
}
|
|
4002
|
+
switch (schema.type) {
|
|
4003
|
+
case "dropdown-menu-trigger": {
|
|
4004
|
+
const child = node.children[0];
|
|
4005
|
+
if (!child) {
|
|
4006
|
+
return null;
|
|
4007
|
+
}
|
|
4008
|
+
const disabled = normalizeDropdownMenuBoolean(schema.props?.disabled) || node.state.disabled;
|
|
4009
|
+
return /* @__PURE__ */ jsx41(DropdownMenu2.Trigger, { disabled, children: /* @__PURE__ */ jsx41(
|
|
4010
|
+
TriggerBridge,
|
|
4011
|
+
{
|
|
4012
|
+
activateWhenNonInteractive: true,
|
|
4013
|
+
disabled,
|
|
4014
|
+
className: normalizeDropdownMenuClassName(
|
|
4015
|
+
schema.props?.className
|
|
4016
|
+
),
|
|
4017
|
+
"aria-label": normalizeDropdownMenuAriaLabel(
|
|
4018
|
+
schema.props?.ariaLabel
|
|
4019
|
+
),
|
|
4020
|
+
children: /* @__PURE__ */ jsx41(NodeRenderer, { node: child })
|
|
4021
|
+
}
|
|
4022
|
+
) });
|
|
4023
|
+
}
|
|
4024
|
+
case "dropdown-menu-content":
|
|
4025
|
+
return /* @__PURE__ */ jsx41(DropdownMenu2.Content, { ...buildDropdownMenuContentProps(schema.props), children });
|
|
4026
|
+
case "dropdown-menu-group":
|
|
4027
|
+
return /* @__PURE__ */ jsx41(
|
|
4028
|
+
DropdownMenu2.Group,
|
|
4029
|
+
{
|
|
4030
|
+
className: normalizeDropdownMenuClassName(
|
|
4031
|
+
schema.props?.className
|
|
4032
|
+
),
|
|
4033
|
+
children
|
|
4034
|
+
}
|
|
4035
|
+
);
|
|
4036
|
+
case "dropdown-menu-label":
|
|
4037
|
+
return /* @__PURE__ */ jsx41(
|
|
4038
|
+
DropdownMenu2.Label,
|
|
4039
|
+
{
|
|
4040
|
+
id: node.id,
|
|
4041
|
+
inset: normalizeDropdownMenuBoolean(schema.props?.inset),
|
|
4042
|
+
className: normalizeDropdownMenuClassName(
|
|
4043
|
+
schema.props?.className
|
|
4044
|
+
),
|
|
4045
|
+
children: normalizeDropdownMenuText(schema.props?.label)
|
|
4046
|
+
}
|
|
4047
|
+
);
|
|
4048
|
+
case "dropdown-menu-item":
|
|
4049
|
+
return /* @__PURE__ */ jsx41(DropdownMenuActionItem, { node });
|
|
4050
|
+
case "dropdown-menu-separator":
|
|
4051
|
+
return /* @__PURE__ */ jsx41(
|
|
4052
|
+
DropdownMenu2.Separator,
|
|
4053
|
+
{
|
|
4054
|
+
id: node.id,
|
|
4055
|
+
className: normalizeDropdownMenuClassName(
|
|
4056
|
+
schema.props?.className
|
|
4057
|
+
)
|
|
4058
|
+
}
|
|
4059
|
+
);
|
|
4060
|
+
case "dropdown-menu-sub":
|
|
4061
|
+
return /* @__PURE__ */ jsx41(
|
|
4062
|
+
DropdownMenu2.Sub,
|
|
4063
|
+
{
|
|
4064
|
+
defaultOpen: normalizeDropdownMenuDefaultOpen(
|
|
4065
|
+
schema.props?.defaultOpen
|
|
4066
|
+
),
|
|
4067
|
+
children
|
|
4068
|
+
}
|
|
4069
|
+
);
|
|
4070
|
+
case "dropdown-menu-sub-trigger":
|
|
4071
|
+
return /* @__PURE__ */ jsx41(
|
|
4072
|
+
DropdownMenu2.SubTrigger,
|
|
4073
|
+
{
|
|
4074
|
+
id: node.id,
|
|
4075
|
+
disabled: normalizeDropdownMenuBoolean(schema.props?.disabled) || node.state.disabled,
|
|
4076
|
+
inset: normalizeDropdownMenuBoolean(schema.props?.inset),
|
|
4077
|
+
className: normalizeDropdownMenuClassName(
|
|
4078
|
+
schema.props?.className
|
|
4079
|
+
),
|
|
4080
|
+
children: normalizeDropdownMenuText(schema.props?.label)
|
|
4081
|
+
}
|
|
4082
|
+
);
|
|
4083
|
+
case "dropdown-menu-sub-content":
|
|
4084
|
+
return /* @__PURE__ */ jsx41(
|
|
4085
|
+
DropdownMenu2.SubContent,
|
|
4086
|
+
{
|
|
4087
|
+
sideOffset: normalizeDropdownMenuSideOffset(
|
|
4088
|
+
schema.props?.sideOffset
|
|
4089
|
+
),
|
|
4090
|
+
className: normalizeDropdownMenuClassName(
|
|
4091
|
+
schema.props?.className
|
|
4092
|
+
),
|
|
4093
|
+
"aria-label": normalizeDropdownMenuAriaLabel(
|
|
4094
|
+
schema.props?.ariaLabel
|
|
4095
|
+
),
|
|
4096
|
+
children
|
|
4097
|
+
}
|
|
4098
|
+
);
|
|
4099
|
+
default:
|
|
4100
|
+
return null;
|
|
4101
|
+
}
|
|
4102
|
+
}
|
|
4103
|
+
function renderDesignModeSlot3(node, children) {
|
|
4104
|
+
const schema = node.schema;
|
|
4105
|
+
if (schema.kind !== "layout") {
|
|
4106
|
+
return null;
|
|
4107
|
+
}
|
|
4108
|
+
const className = normalizeDropdownMenuClassName(schema.props?.className);
|
|
4109
|
+
const ariaLabel = normalizeDropdownMenuAriaLabel(schema.props?.ariaLabel);
|
|
4110
|
+
const label = normalizeDropdownMenuText(schema.props?.label);
|
|
4111
|
+
switch (schema.type) {
|
|
4112
|
+
case "dropdown-menu-trigger": {
|
|
4113
|
+
const child = node.children[0];
|
|
4114
|
+
if (!child) {
|
|
4115
|
+
return null;
|
|
4116
|
+
}
|
|
4117
|
+
return /* @__PURE__ */ jsx41(
|
|
4118
|
+
"div",
|
|
4119
|
+
{
|
|
4120
|
+
"data-slot": "dropdown-menu-trigger",
|
|
4121
|
+
className,
|
|
4122
|
+
"aria-label": ariaLabel,
|
|
4123
|
+
children: /* @__PURE__ */ jsx41(NodeRenderer, { node: child })
|
|
4124
|
+
}
|
|
4125
|
+
);
|
|
4126
|
+
}
|
|
4127
|
+
case "dropdown-menu-content":
|
|
4128
|
+
return /* @__PURE__ */ jsx41(
|
|
4129
|
+
"div",
|
|
4130
|
+
{
|
|
4131
|
+
"data-slot": "dropdown-menu-content",
|
|
4132
|
+
className: joinClassNames7(
|
|
4133
|
+
"min-h-12 space-y-1 rounded border border-dashed border-gray-200 p-2",
|
|
4134
|
+
className
|
|
4135
|
+
),
|
|
4136
|
+
"aria-label": ariaLabel,
|
|
4137
|
+
children
|
|
4138
|
+
}
|
|
4139
|
+
);
|
|
4140
|
+
case "dropdown-menu-group":
|
|
4141
|
+
return /* @__PURE__ */ jsx41(
|
|
4142
|
+
"div",
|
|
4143
|
+
{
|
|
4144
|
+
"data-slot": "dropdown-menu-group",
|
|
4145
|
+
className: joinClassNames7(
|
|
4146
|
+
"space-y-1 rounded border border-dashed border-gray-100 p-1",
|
|
4147
|
+
className
|
|
4148
|
+
),
|
|
4149
|
+
children
|
|
4150
|
+
}
|
|
4151
|
+
);
|
|
4152
|
+
case "dropdown-menu-label":
|
|
4153
|
+
return /* @__PURE__ */ jsx41(
|
|
4154
|
+
"div",
|
|
4155
|
+
{
|
|
4156
|
+
"data-slot": "dropdown-menu-label",
|
|
4157
|
+
id: node.id,
|
|
4158
|
+
className: joinClassNames7(
|
|
4159
|
+
"px-2 py-1 text-xs font-medium text-gray-500",
|
|
4160
|
+
className
|
|
4161
|
+
),
|
|
4162
|
+
children: label || "Label"
|
|
4163
|
+
}
|
|
4164
|
+
);
|
|
4165
|
+
case "dropdown-menu-item":
|
|
4166
|
+
return /* @__PURE__ */ jsx41(DropdownMenuActionItem, { node, designMode: true });
|
|
4167
|
+
case "dropdown-menu-separator":
|
|
4168
|
+
return /* @__PURE__ */ jsx41(
|
|
4169
|
+
"div",
|
|
4170
|
+
{
|
|
4171
|
+
"data-slot": "dropdown-menu-separator",
|
|
4172
|
+
id: node.id,
|
|
4173
|
+
role: "separator",
|
|
4174
|
+
className: joinClassNames7("my-1 h-px bg-gray-200", className)
|
|
4175
|
+
}
|
|
4176
|
+
);
|
|
4177
|
+
case "dropdown-menu-sub":
|
|
4178
|
+
return /* @__PURE__ */ jsx41(
|
|
4179
|
+
"div",
|
|
4180
|
+
{
|
|
4181
|
+
"data-slot": "dropdown-menu-sub",
|
|
4182
|
+
className: "space-y-1 rounded border border-dashed border-gray-200 p-1",
|
|
4183
|
+
children
|
|
4184
|
+
}
|
|
4185
|
+
);
|
|
4186
|
+
case "dropdown-menu-sub-trigger":
|
|
4187
|
+
return /* @__PURE__ */ jsx41(
|
|
4188
|
+
"div",
|
|
4189
|
+
{
|
|
4190
|
+
"data-slot": "dropdown-menu-sub-trigger",
|
|
4191
|
+
id: node.id,
|
|
4192
|
+
className: joinClassNames7(
|
|
4193
|
+
"rounded px-2 py-1 text-sm text-gray-700",
|
|
4194
|
+
className
|
|
4195
|
+
),
|
|
4196
|
+
children: label || "Submenu"
|
|
4197
|
+
}
|
|
4198
|
+
);
|
|
4199
|
+
case "dropdown-menu-sub-content":
|
|
4200
|
+
return /* @__PURE__ */ jsx41(
|
|
4201
|
+
"div",
|
|
4202
|
+
{
|
|
4203
|
+
"data-slot": "dropdown-menu-sub-content",
|
|
4204
|
+
className: joinClassNames7(
|
|
4205
|
+
"min-h-10 space-y-1 rounded border border-dashed border-gray-200 p-2",
|
|
4206
|
+
className
|
|
4207
|
+
),
|
|
4208
|
+
"aria-label": ariaLabel,
|
|
4209
|
+
children
|
|
4210
|
+
}
|
|
4211
|
+
);
|
|
4212
|
+
default:
|
|
4213
|
+
return null;
|
|
4214
|
+
}
|
|
4215
|
+
}
|
|
4216
|
+
function DropdownMenuActionItem({
|
|
4217
|
+
node,
|
|
4218
|
+
designMode: designModeProp
|
|
4219
|
+
}) {
|
|
4220
|
+
const engine = useFormContext();
|
|
4221
|
+
const { designMode: contextDesignMode } = useConfigContext();
|
|
4222
|
+
const designMode = designModeProp ?? contextDesignMode === true;
|
|
4223
|
+
if (node.schema.kind !== "layout" || node.schema.type !== "dropdown-menu-item") {
|
|
4224
|
+
return null;
|
|
4225
|
+
}
|
|
4226
|
+
const actionNode = node.children[0];
|
|
4227
|
+
if (!actionNode || actionNode.schema.kind !== "action") {
|
|
4228
|
+
return null;
|
|
4229
|
+
}
|
|
4230
|
+
const schema = node.schema;
|
|
4231
|
+
const shortcut = normalizeDropdownMenuOptionalText(
|
|
4232
|
+
schema.props?.shortcut
|
|
4233
|
+
);
|
|
4234
|
+
const label = normalizeDropdownMenuText(schema.props?.label);
|
|
4235
|
+
const className = normalizeDropdownMenuClassName(schema.props?.className);
|
|
4236
|
+
const disabled = normalizeDropdownMenuBoolean(schema.props?.disabled) || node.state.disabled || isDropdownMenuActionDisabled(engine, actionNode);
|
|
4237
|
+
if (designMode) {
|
|
4238
|
+
return /* @__PURE__ */ jsxs18(
|
|
4239
|
+
"div",
|
|
4240
|
+
{
|
|
4241
|
+
"data-slot": "dropdown-menu-item",
|
|
4242
|
+
id: node.id,
|
|
4243
|
+
className: joinClassNames7(
|
|
4244
|
+
"flex items-center justify-between gap-2 rounded px-2 py-1 text-sm",
|
|
4245
|
+
disabled ? "opacity-50" : void 0,
|
|
4246
|
+
className
|
|
4247
|
+
),
|
|
4248
|
+
children: [
|
|
4249
|
+
/* @__PURE__ */ jsx41("span", { children: label || "Menu item" }),
|
|
4250
|
+
shortcut ? /* @__PURE__ */ jsx41("span", { className: "text-xs text-gray-400", children: shortcut }) : null
|
|
4251
|
+
]
|
|
4252
|
+
}
|
|
4253
|
+
);
|
|
4254
|
+
}
|
|
4255
|
+
return /* @__PURE__ */ jsx41(
|
|
4256
|
+
DropdownMenuItemView,
|
|
4257
|
+
{
|
|
4258
|
+
id: node.id,
|
|
4259
|
+
disabled,
|
|
4260
|
+
inset: normalizeDropdownMenuBoolean(schema.props?.inset),
|
|
4261
|
+
variant: normalizeDropdownMenuItemVariant(schema.props?.variant),
|
|
4262
|
+
className,
|
|
4263
|
+
label,
|
|
4264
|
+
shortcut,
|
|
4265
|
+
onSelect: () => {
|
|
4266
|
+
void executeRendererAction(engine, actionNode.id, false);
|
|
4267
|
+
}
|
|
4268
|
+
}
|
|
4269
|
+
);
|
|
4270
|
+
}
|
|
4271
|
+
function DropdownMenuItemView({
|
|
4272
|
+
id,
|
|
4273
|
+
label,
|
|
4274
|
+
shortcut,
|
|
4275
|
+
disabled,
|
|
4276
|
+
inset,
|
|
4277
|
+
variant,
|
|
4278
|
+
className,
|
|
4279
|
+
onSelect
|
|
4280
|
+
}) {
|
|
4281
|
+
return /* @__PURE__ */ jsxs18(
|
|
4282
|
+
DropdownMenu2.Item,
|
|
4283
|
+
{
|
|
4284
|
+
id,
|
|
4285
|
+
disabled,
|
|
4286
|
+
inset,
|
|
4287
|
+
variant,
|
|
4288
|
+
className,
|
|
4289
|
+
onSelect,
|
|
4290
|
+
children: [
|
|
4291
|
+
/* @__PURE__ */ jsx41("span", { children: label }),
|
|
4292
|
+
shortcut ? /* @__PURE__ */ jsx41(DropdownMenu2.Shortcut, { children: shortcut }) : null
|
|
4293
|
+
]
|
|
4294
|
+
}
|
|
4295
|
+
);
|
|
4296
|
+
}
|
|
4297
|
+
function buildDropdownMenuContentProps(props) {
|
|
4298
|
+
const record = typeof props === "object" && props !== null ? props : void 0;
|
|
4299
|
+
return {
|
|
4300
|
+
side: normalizeDropdownMenuSide(record?.side),
|
|
4301
|
+
sideOffset: normalizeDropdownMenuSideOffset(record?.sideOffset),
|
|
4302
|
+
align: normalizeDropdownMenuAlign(record?.align),
|
|
4303
|
+
alignOffset: normalizeDropdownMenuAlignOffset(record?.alignOffset),
|
|
4304
|
+
collisionPadding: normalizeDropdownMenuCollisionPadding(
|
|
4305
|
+
record?.collisionPadding
|
|
4306
|
+
),
|
|
4307
|
+
className: normalizeDropdownMenuClassName(record?.className),
|
|
4308
|
+
"aria-label": normalizeDropdownMenuAriaLabel(record?.ariaLabel)
|
|
4309
|
+
};
|
|
4310
|
+
}
|
|
4311
|
+
function normalizeDropdownMenuSide(value) {
|
|
4312
|
+
return value === "top" || value === "right" || value === "left" ? value : "bottom";
|
|
4313
|
+
}
|
|
4314
|
+
function normalizeDropdownMenuAlign(value) {
|
|
4315
|
+
return value === "start" || value === "end" ? value : "center";
|
|
4316
|
+
}
|
|
4317
|
+
function normalizeDropdownMenuSideOffset(value) {
|
|
4318
|
+
return normalizeNonNegativeNumber2(value, 4);
|
|
4319
|
+
}
|
|
4320
|
+
function normalizeDropdownMenuAlignOffset(value) {
|
|
4321
|
+
return typeof value === "number" && Number.isFinite(value) ? value : 0;
|
|
4322
|
+
}
|
|
4323
|
+
function normalizeDropdownMenuCollisionPadding(value) {
|
|
4324
|
+
return normalizeNonNegativeNumber2(value, 0);
|
|
4325
|
+
}
|
|
4326
|
+
function normalizeDropdownMenuItemVariant(value) {
|
|
4327
|
+
return value === "destructive" ? "destructive" : "default";
|
|
4328
|
+
}
|
|
4329
|
+
function normalizeDropdownMenuBoolean(value) {
|
|
4330
|
+
return value === true;
|
|
4331
|
+
}
|
|
4332
|
+
function normalizeDropdownMenuClassName(value) {
|
|
4333
|
+
return normalizeDropdownMenuOptionalText(value);
|
|
4334
|
+
}
|
|
4335
|
+
function normalizeDropdownMenuAriaLabel(value) {
|
|
4336
|
+
return normalizeDropdownMenuOptionalText(value);
|
|
4337
|
+
}
|
|
4338
|
+
function normalizeDropdownMenuText(value) {
|
|
4339
|
+
return typeof value === "string" ? value.trim() : "";
|
|
4340
|
+
}
|
|
4341
|
+
function normalizeDropdownMenuOptionalText(value) {
|
|
4342
|
+
const text = normalizeDropdownMenuText(value);
|
|
4343
|
+
return text || void 0;
|
|
4344
|
+
}
|
|
4345
|
+
function joinClassNames7(...parts) {
|
|
4346
|
+
return parts.filter(Boolean).join(" ") || void 0;
|
|
4347
|
+
}
|
|
4348
|
+
function normalizeNonNegativeNumber2(value, fallback) {
|
|
4349
|
+
return typeof value === "number" && Number.isFinite(value) && value >= 0 ? value : fallback;
|
|
4350
|
+
}
|
|
4351
|
+
function isDropdownMenuActionDisabled(engine, node) {
|
|
4352
|
+
if (node.schema.kind !== "action") {
|
|
4353
|
+
return true;
|
|
4354
|
+
}
|
|
4355
|
+
const schema = node.schema;
|
|
4356
|
+
const stepperState = (schema.type === "stepper-next" || schema.type === "stepper-previous") && schema.stepperId ? engine.getStepperState(schema.stepperId) : void 0;
|
|
4357
|
+
const isStepperActionDisabled = schema.type === "stepper-next" ? !stepperState?.canGoNext || engine.getState().initializationStatus !== "ready" : schema.type === "stepper-previous" ? !stepperState?.canGoPrevious || engine.getState().initializationStatus !== "ready" : false;
|
|
4358
|
+
return node.state.disabled || schema.props?.disabled === true || engine.isFormDisabled() || isStepperActionDisabled;
|
|
4359
|
+
}
|
|
4360
|
+
|
|
4361
|
+
// src/renderer/pagination-renderer.tsx
|
|
4362
|
+
import { Pagination } from "bsm-design-system";
|
|
4363
|
+
import { useEffect as useEffect6, useState as useState6 } from "react";
|
|
4364
|
+
|
|
4365
|
+
// src/renderer/pagination-execution.ts
|
|
4366
|
+
function executeRendererPaginationChange(engine, paginationId, page, pageSize, designMode) {
|
|
4367
|
+
if (designMode) {
|
|
4368
|
+
return;
|
|
4369
|
+
}
|
|
4370
|
+
return engine.changePagination(paginationId, page, pageSize);
|
|
4371
|
+
}
|
|
4372
|
+
|
|
4373
|
+
// src/renderer/pagination-renderer.tsx
|
|
4374
|
+
import { jsx as jsx42 } from "react/jsx-runtime";
|
|
4375
|
+
function PaginationRenderer({ node }) {
|
|
4376
|
+
if (node.schema.kind !== "layout" || node.schema.type !== "pagination") {
|
|
4377
|
+
return null;
|
|
4378
|
+
}
|
|
4379
|
+
const engine = useFormContext();
|
|
4380
|
+
const { designMode } = useConfigContext();
|
|
4381
|
+
const props = node.schema.props;
|
|
4382
|
+
const engineState = engine.getPaginationState(node.id) ?? {
|
|
4383
|
+
page: normalizePositiveInteger(props.initialPage, 1),
|
|
4384
|
+
pageSize: normalizePositiveInteger(props.pageSize, 10)
|
|
4385
|
+
};
|
|
4386
|
+
const [synchronized, setSynchronized] = useState6(() => ({
|
|
4387
|
+
revision: 0,
|
|
4388
|
+
page: engineState.page,
|
|
4389
|
+
pageSize: engineState.pageSize
|
|
4390
|
+
}));
|
|
4391
|
+
useEffect6(() => {
|
|
4392
|
+
if (synchronized.page === engineState.page && synchronized.pageSize === engineState.pageSize) {
|
|
4393
|
+
return;
|
|
4394
|
+
}
|
|
4395
|
+
setSynchronized((current) => ({
|
|
4396
|
+
revision: current.revision + 1,
|
|
4397
|
+
page: engineState.page,
|
|
4398
|
+
pageSize: engineState.pageSize
|
|
4399
|
+
}));
|
|
4400
|
+
}, [
|
|
4401
|
+
engineState.page,
|
|
4402
|
+
engineState.pageSize,
|
|
4403
|
+
synchronized.page,
|
|
4404
|
+
synchronized.pageSize
|
|
4405
|
+
]);
|
|
4406
|
+
return /* @__PURE__ */ jsx42(
|
|
4407
|
+
"section",
|
|
4408
|
+
{
|
|
4409
|
+
id: node.id,
|
|
4410
|
+
"aria-label": normalizeAriaLabel3(props.ariaLabel),
|
|
4411
|
+
children: /* @__PURE__ */ jsx42(
|
|
4412
|
+
Pagination,
|
|
4413
|
+
{
|
|
4414
|
+
totalItems: normalizeNonNegativeInteger(props.totalItems, 0),
|
|
4415
|
+
initialPage: synchronized.page,
|
|
4416
|
+
pageSize: synchronized.pageSize,
|
|
4417
|
+
pageSizeOptions: normalizePageSizeOptions(props.pageSizeOptions),
|
|
4418
|
+
siblings: normalizeNonNegativeInteger(props.siblings, 1),
|
|
4419
|
+
showPageSizeSelector: props.showPageSizeSelector === true,
|
|
4420
|
+
showPageInfo: props.showPageInfo === true,
|
|
4421
|
+
rounded: props.rounded === true,
|
|
4422
|
+
className: normalizeClassName8(props.className),
|
|
4423
|
+
onPageChange: (page, pageSize) => {
|
|
4424
|
+
void (async () => {
|
|
4425
|
+
const result = await executeRendererPaginationChange(
|
|
4426
|
+
engine,
|
|
4427
|
+
node.id,
|
|
4428
|
+
page,
|
|
4429
|
+
pageSize,
|
|
4430
|
+
designMode === true
|
|
4431
|
+
);
|
|
4432
|
+
if (result) {
|
|
4433
|
+
setSynchronized((current) => ({
|
|
4434
|
+
...current,
|
|
4435
|
+
page: result.page,
|
|
4436
|
+
pageSize: result.pageSize
|
|
4437
|
+
}));
|
|
4438
|
+
}
|
|
4439
|
+
})();
|
|
4440
|
+
}
|
|
4441
|
+
},
|
|
4442
|
+
synchronized.revision
|
|
4443
|
+
)
|
|
4444
|
+
}
|
|
4445
|
+
);
|
|
4446
|
+
}
|
|
4447
|
+
function normalizePageSizeOptions(value) {
|
|
4448
|
+
if (!Array.isArray(value)) {
|
|
4449
|
+
return [5, 10, 20];
|
|
4450
|
+
}
|
|
4451
|
+
const options = value.filter(
|
|
4452
|
+
(option) => Number.isInteger(option) && Number(option) > 0
|
|
4453
|
+
);
|
|
4454
|
+
return options.length > 0 ? [...new Set(options)] : [5, 10, 20];
|
|
4455
|
+
}
|
|
4456
|
+
function normalizePositiveInteger(value, fallback) {
|
|
4457
|
+
return Number.isInteger(value) && Number(value) > 0 ? Number(value) : fallback;
|
|
4458
|
+
}
|
|
4459
|
+
function normalizeNonNegativeInteger(value, fallback) {
|
|
4460
|
+
return Number.isInteger(value) && Number(value) >= 0 ? Number(value) : fallback;
|
|
4461
|
+
}
|
|
4462
|
+
function normalizeClassName8(value) {
|
|
4463
|
+
return typeof value === "string" ? value.trim() : "";
|
|
4464
|
+
}
|
|
4465
|
+
function normalizeAriaLabel3(value) {
|
|
4466
|
+
return typeof value === "string" && value.trim() ? value.trim() : "Pagination";
|
|
4467
|
+
}
|
|
4468
|
+
|
|
4469
|
+
// src/renderer/form-ref-renderer.tsx
|
|
4470
|
+
import {
|
|
4471
|
+
compileSchema,
|
|
4472
|
+
FormEngine
|
|
4473
|
+
} from "@bsm-form/core";
|
|
4474
|
+
import { useEffect as useEffect8, useMemo, useRef as useRef2, useState as useState8 } from "react";
|
|
4475
|
+
|
|
4476
|
+
// src/context/form-provider.tsx
|
|
4477
|
+
import { jsx as jsx43 } from "react/jsx-runtime";
|
|
4478
|
+
function FormProvider({
|
|
4479
|
+
engine,
|
|
4480
|
+
children
|
|
4481
|
+
}) {
|
|
4482
|
+
return /* @__PURE__ */ jsx43(FormContext.Provider, { value: engine, children });
|
|
4483
|
+
}
|
|
4484
|
+
|
|
4485
|
+
// src/context/config-provider.tsx
|
|
4486
|
+
import { useCallback as useCallback2, useEffect as useEffect7, useRef, useState as useState7 } from "react";
|
|
4487
|
+
|
|
4488
|
+
// src/renderer/embedded-form-bag.ts
|
|
4489
|
+
var EMBEDS_RESOURCE_ROOT = "embeds";
|
|
4490
|
+
function aggregateEmbeddedFormValues(parentValues, embeddedBag) {
|
|
4491
|
+
const embeddedValues = {};
|
|
4492
|
+
for (const [key, entry] of Object.entries(embeddedBag)) {
|
|
4493
|
+
embeddedValues[key] = isSnapshot(entry) ? { ...entry.values } : { ...entry };
|
|
4494
|
+
}
|
|
4495
|
+
return {
|
|
4496
|
+
...parentValues,
|
|
4497
|
+
...embeddedValues
|
|
4498
|
+
};
|
|
4499
|
+
}
|
|
4500
|
+
function aggregateEmbeddedFormPayload(parentValues, parentResources, embeddedBag) {
|
|
4501
|
+
return {
|
|
4502
|
+
values: aggregateEmbeddedFormValues(parentValues, embeddedBag),
|
|
4503
|
+
resources: parentResources,
|
|
4504
|
+
embeds: cloneBag(embeddedBag)
|
|
4505
|
+
};
|
|
4506
|
+
}
|
|
4507
|
+
function setEmbeddedFormSnapshot(bag, instanceKey, snapshot) {
|
|
4508
|
+
return {
|
|
4509
|
+
...bag,
|
|
4510
|
+
[instanceKey]: {
|
|
4511
|
+
values: { ...snapshot.values },
|
|
4512
|
+
resources: { ...snapshot.resources }
|
|
4513
|
+
}
|
|
4514
|
+
};
|
|
4515
|
+
}
|
|
4516
|
+
function setEmbeddedFormValues(bag, instanceKey, values) {
|
|
4517
|
+
return {
|
|
4518
|
+
...bag,
|
|
4519
|
+
[instanceKey]: { ...values }
|
|
4520
|
+
};
|
|
4521
|
+
}
|
|
4522
|
+
function resourcesWithoutEmbeds(resources) {
|
|
4523
|
+
if (!Object.prototype.hasOwnProperty.call(resources, EMBEDS_RESOURCE_ROOT)) {
|
|
4524
|
+
return { ...resources };
|
|
4525
|
+
}
|
|
4526
|
+
const next = { ...resources };
|
|
4527
|
+
delete next[EMBEDS_RESOURCE_ROOT];
|
|
4528
|
+
return next;
|
|
4529
|
+
}
|
|
4530
|
+
function snapshotFromEngine(parts) {
|
|
4531
|
+
return {
|
|
4532
|
+
values: { ...parts.values },
|
|
4533
|
+
resources: resourcesWithoutEmbeds(parts.resources)
|
|
4534
|
+
};
|
|
4535
|
+
}
|
|
4536
|
+
function isSnapshot(value) {
|
|
4537
|
+
return typeof value === "object" && value !== null && !Array.isArray(value) && "values" in value && "resources" in value && typeof value.values === "object" && typeof value.resources === "object";
|
|
4538
|
+
}
|
|
4539
|
+
function cloneBag(bag) {
|
|
4540
|
+
const next = {};
|
|
4541
|
+
for (const [key, snapshot] of Object.entries(bag)) {
|
|
4542
|
+
next[key] = {
|
|
4543
|
+
values: { ...snapshot.values },
|
|
4544
|
+
resources: { ...snapshot.resources }
|
|
4545
|
+
};
|
|
4546
|
+
}
|
|
4547
|
+
return next;
|
|
4548
|
+
}
|
|
4549
|
+
|
|
4550
|
+
// src/context/config-provider.tsx
|
|
4551
|
+
import { jsx as jsx44 } from "react/jsx-runtime";
|
|
4552
|
+
function ConfigProvider({
|
|
4553
|
+
designMode,
|
|
4554
|
+
children,
|
|
4555
|
+
renderWrapper,
|
|
4556
|
+
invokeCatalog,
|
|
4557
|
+
slots,
|
|
4558
|
+
slotCatalog,
|
|
4559
|
+
forms,
|
|
4560
|
+
onEmbeddedValuesChange,
|
|
4561
|
+
onEmbeddedSnapshotChange,
|
|
4562
|
+
environment,
|
|
4563
|
+
parentEngine,
|
|
4564
|
+
embeddedBag: embeddedBagProp,
|
|
4565
|
+
publishEmbeddedSnapshot: publishEmbeddedSnapshotProp
|
|
4566
|
+
}) {
|
|
4567
|
+
const isRootBagOwner = publishEmbeddedSnapshotProp === void 0;
|
|
4568
|
+
const [ownedBag, setOwnedBag] = useState7({});
|
|
4569
|
+
const lastBagSerialized = useRef("");
|
|
4570
|
+
const embeddedBag = embeddedBagProp ?? ownedBag;
|
|
4571
|
+
const publishEmbeddedSnapshot = useCallback2(
|
|
4572
|
+
(instanceKey, snapshot) => {
|
|
4573
|
+
if (publishEmbeddedSnapshotProp) {
|
|
4574
|
+
publishEmbeddedSnapshotProp(instanceKey, snapshot);
|
|
4575
|
+
return;
|
|
4576
|
+
}
|
|
4577
|
+
setOwnedBag((previous) => {
|
|
4578
|
+
const next = setEmbeddedFormSnapshot(previous, instanceKey, snapshot);
|
|
4579
|
+
const serialized = JSON.stringify(next);
|
|
4580
|
+
if (serialized === lastBagSerialized.current) {
|
|
4581
|
+
return previous;
|
|
4582
|
+
}
|
|
4583
|
+
lastBagSerialized.current = serialized;
|
|
4584
|
+
return next;
|
|
4585
|
+
});
|
|
4586
|
+
onEmbeddedSnapshotChange?.(instanceKey, snapshot);
|
|
4587
|
+
onEmbeddedValuesChange?.(instanceKey, snapshot.values);
|
|
4588
|
+
},
|
|
4589
|
+
[
|
|
4590
|
+
publishEmbeddedSnapshotProp,
|
|
4591
|
+
onEmbeddedSnapshotChange,
|
|
4592
|
+
onEmbeddedValuesChange
|
|
4593
|
+
]
|
|
4594
|
+
);
|
|
4595
|
+
useEffect7(() => {
|
|
4596
|
+
if (!isRootBagOwner || !parentEngine) {
|
|
4597
|
+
return;
|
|
4598
|
+
}
|
|
4599
|
+
parentEngine.setResource(EMBEDS_RESOURCE_ROOT, embeddedBag);
|
|
4600
|
+
}, [isRootBagOwner, parentEngine, embeddedBag]);
|
|
4601
|
+
return /* @__PURE__ */ jsx44(
|
|
4602
|
+
ConfigContext.Provider,
|
|
4603
|
+
{
|
|
4604
|
+
value: {
|
|
4605
|
+
designMode,
|
|
4606
|
+
renderWrapper,
|
|
4607
|
+
invokeCatalog,
|
|
4608
|
+
slots,
|
|
4609
|
+
slotCatalog,
|
|
4610
|
+
forms,
|
|
4611
|
+
onEmbeddedValuesChange,
|
|
4612
|
+
onEmbeddedSnapshotChange,
|
|
4613
|
+
environment,
|
|
4614
|
+
embeddedBag,
|
|
4615
|
+
publishEmbeddedSnapshot
|
|
4616
|
+
},
|
|
4617
|
+
children
|
|
4618
|
+
}
|
|
4619
|
+
);
|
|
4620
|
+
}
|
|
4621
|
+
|
|
4622
|
+
// src/renderer/sonner-notify.ts
|
|
4623
|
+
import { toast } from "sonner";
|
|
4624
|
+
function notifyWithSonner(notification) {
|
|
4625
|
+
const { message, variant, position, duration } = notification;
|
|
4626
|
+
const options = {
|
|
4627
|
+
...position ? { position } : {},
|
|
4628
|
+
...duration !== void 0 ? { duration } : {}
|
|
4629
|
+
};
|
|
4630
|
+
switch (variant) {
|
|
4631
|
+
case "success":
|
|
4632
|
+
toast.success(message, options);
|
|
4633
|
+
return;
|
|
4634
|
+
case "error":
|
|
4635
|
+
toast.error(message, options);
|
|
4636
|
+
return;
|
|
4637
|
+
case "info":
|
|
4638
|
+
toast.info(message, options);
|
|
4639
|
+
return;
|
|
4640
|
+
case "warning":
|
|
4641
|
+
toast.warning(message, options);
|
|
4642
|
+
return;
|
|
4643
|
+
default:
|
|
4644
|
+
toast(message, options);
|
|
4645
|
+
}
|
|
4646
|
+
}
|
|
4647
|
+
|
|
4648
|
+
// src/renderer/form-ref-renderer.tsx
|
|
4649
|
+
import { jsx as jsx45 } from "react/jsx-runtime";
|
|
4650
|
+
function FormRefRenderer({ node }) {
|
|
4651
|
+
const schema = node.schema;
|
|
4652
|
+
const {
|
|
4653
|
+
designMode,
|
|
4654
|
+
forms,
|
|
4655
|
+
environment,
|
|
4656
|
+
slots,
|
|
4657
|
+
slotCatalog,
|
|
4658
|
+
invokeCatalog,
|
|
4659
|
+
embeddedBag,
|
|
4660
|
+
publishEmbeddedSnapshot,
|
|
4661
|
+
onEmbeddedValuesChange,
|
|
4662
|
+
onEmbeddedSnapshotChange
|
|
4663
|
+
} = useConfigContext();
|
|
4664
|
+
const show = useDesignVisible(node.state.visible);
|
|
4665
|
+
const lastSerialized = useRef2("");
|
|
4666
|
+
const lastEmbedsSerialized = useRef2("");
|
|
4667
|
+
const [, forceUpdate] = useState8(0);
|
|
4668
|
+
const schemaId = schema.kind === "layout" && schema.type === "form-ref" ? schema.props.schemaId : "";
|
|
4669
|
+
const instanceKey = schema.kind === "layout" && schema.type === "form-ref" ? schema.props.instanceKey : "";
|
|
4670
|
+
const className = schema.kind === "layout" && schema.type === "form-ref" && typeof schema.props.className === "string" ? schema.props.className : void 0;
|
|
4671
|
+
const nestedTree = schemaId ? forms?.[schemaId] : void 0;
|
|
4672
|
+
const engine = useMemo(() => {
|
|
4673
|
+
if (!nestedTree) {
|
|
4674
|
+
return void 0;
|
|
4675
|
+
}
|
|
4676
|
+
return new FormEngine(compileSchema(nestedTree), {
|
|
4677
|
+
...environment,
|
|
4678
|
+
notify: environment?.notify ?? notifyWithSonner,
|
|
4679
|
+
invoke: environment?.invoke ?? {}
|
|
4680
|
+
});
|
|
4681
|
+
}, [nestedTree, environment, designMode]);
|
|
4682
|
+
useEffect8(() => {
|
|
4683
|
+
if (!engine) {
|
|
4684
|
+
return;
|
|
4685
|
+
}
|
|
4686
|
+
const publish = () => {
|
|
4687
|
+
if (!publishEmbeddedSnapshot || !instanceKey) {
|
|
4688
|
+
return;
|
|
4689
|
+
}
|
|
4690
|
+
const snapshot = snapshotFromEngine({
|
|
4691
|
+
values: engine.getValues(),
|
|
4692
|
+
resources: engine.getResources()
|
|
4693
|
+
});
|
|
4694
|
+
const serialized = JSON.stringify(snapshot);
|
|
4695
|
+
if (serialized === lastSerialized.current) {
|
|
4696
|
+
return;
|
|
4697
|
+
}
|
|
4698
|
+
lastSerialized.current = serialized;
|
|
4699
|
+
publishEmbeddedSnapshot(instanceKey, snapshot);
|
|
4700
|
+
};
|
|
4701
|
+
const unsubscribe = engine.subscribe(() => {
|
|
4702
|
+
forceUpdate((value) => value + 1);
|
|
4703
|
+
publish();
|
|
4704
|
+
});
|
|
4705
|
+
void engine.initialize({ skipLoadSteps: designMode === true }).then(() => {
|
|
4706
|
+
publish();
|
|
4707
|
+
}).catch(() => {
|
|
4708
|
+
});
|
|
4709
|
+
return unsubscribe;
|
|
4710
|
+
}, [engine, designMode, instanceKey, publishEmbeddedSnapshot]);
|
|
4711
|
+
useEffect8(() => {
|
|
4712
|
+
lastSerialized.current = "";
|
|
4713
|
+
}, [schemaId, instanceKey, nestedTree]);
|
|
4714
|
+
useEffect8(() => {
|
|
4715
|
+
if (!engine || embeddedBag === void 0) {
|
|
4716
|
+
return;
|
|
4717
|
+
}
|
|
4718
|
+
const serialized = JSON.stringify(embeddedBag);
|
|
4719
|
+
if (serialized === lastEmbedsSerialized.current) {
|
|
4720
|
+
return;
|
|
4721
|
+
}
|
|
4722
|
+
lastEmbedsSerialized.current = serialized;
|
|
4723
|
+
engine.setResource(EMBEDS_RESOURCE_ROOT, embeddedBag);
|
|
4724
|
+
}, [engine, embeddedBag]);
|
|
4725
|
+
if (schema.kind !== "layout" || schema.type !== "form-ref" || !show) {
|
|
4726
|
+
return null;
|
|
4727
|
+
}
|
|
4728
|
+
if (!nestedTree || !engine) {
|
|
4729
|
+
return /* @__PURE__ */ jsx45(
|
|
4730
|
+
"div",
|
|
4731
|
+
{
|
|
4732
|
+
className: [
|
|
4733
|
+
"rounded border border-dashed border-stroke-secondary px-3 py-4 text-xs text-fg-tertiary",
|
|
4734
|
+
className
|
|
4735
|
+
].filter(Boolean).join(" "),
|
|
4736
|
+
"data-form-ref-missing": schemaId || void 0,
|
|
4737
|
+
children: designMode ? `Embedded form \u201C${schemaId || "missing schemaId"}\u201D (${instanceKey || "missing key"})` : `Form \u201C${schemaId}\u201D is unavailable`
|
|
4738
|
+
}
|
|
4739
|
+
);
|
|
4740
|
+
}
|
|
4741
|
+
return /* @__PURE__ */ jsx45(
|
|
4742
|
+
"div",
|
|
4743
|
+
{
|
|
4744
|
+
className,
|
|
4745
|
+
"data-form-ref": schemaId,
|
|
4746
|
+
"data-form-ref-instance": instanceKey,
|
|
4747
|
+
children: /* @__PURE__ */ jsx45(FormProvider, { engine, children: /* @__PURE__ */ jsx45(
|
|
4748
|
+
ConfigProvider,
|
|
4749
|
+
{
|
|
4750
|
+
designMode: designMode === true,
|
|
4751
|
+
environment,
|
|
4752
|
+
forms,
|
|
4753
|
+
slots,
|
|
4754
|
+
slotCatalog,
|
|
4755
|
+
invokeCatalog,
|
|
4756
|
+
onEmbeddedValuesChange,
|
|
4757
|
+
onEmbeddedSnapshotChange,
|
|
4758
|
+
embeddedBag,
|
|
4759
|
+
publishEmbeddedSnapshot,
|
|
4760
|
+
children: /* @__PURE__ */ jsx45(NodeRenderer, { node: engine.getTree() })
|
|
4761
|
+
}
|
|
4762
|
+
) })
|
|
4763
|
+
}
|
|
4764
|
+
);
|
|
4765
|
+
}
|
|
4766
|
+
|
|
4767
|
+
// src/renderer/layout-renderer.tsx
|
|
4768
|
+
import { jsx as jsx46 } from "react/jsx-runtime";
|
|
4769
|
+
function LayoutRenderer({ node }) {
|
|
4770
|
+
const schema = node.schema;
|
|
4771
|
+
if (schema.kind !== "layout") {
|
|
4772
|
+
return null;
|
|
4773
|
+
}
|
|
4774
|
+
if (schema.type === "form-ref") {
|
|
4775
|
+
return /* @__PURE__ */ jsx46(FormRefRenderer, { node });
|
|
4776
|
+
}
|
|
4777
|
+
if (schema.type === "repeat") {
|
|
4778
|
+
return /* @__PURE__ */ jsx46(RepeatRenderer, { node });
|
|
4779
|
+
}
|
|
4780
|
+
if (schema.type === "tabs") {
|
|
4781
|
+
return /* @__PURE__ */ jsx46(TabsRenderer, { node });
|
|
4782
|
+
}
|
|
4783
|
+
if (schema.type === "accordion") {
|
|
4784
|
+
return /* @__PURE__ */ jsx46(AccordionRenderer, { node });
|
|
4785
|
+
}
|
|
4786
|
+
if (schema.type === "tooltip") {
|
|
4787
|
+
return /* @__PURE__ */ jsx46(TooltipRenderer, { node });
|
|
4788
|
+
}
|
|
4789
|
+
if (schema.type === "popover") {
|
|
4790
|
+
return /* @__PURE__ */ jsx46(PopoverRenderer, { node });
|
|
4791
|
+
}
|
|
4792
|
+
if (schema.type === "popover-trigger" || schema.type === "popover-content") {
|
|
4793
|
+
return /* @__PURE__ */ jsx46(PopoverSlotRenderer, { node });
|
|
4794
|
+
}
|
|
4795
|
+
if (schema.type === "dropdown-menu") {
|
|
4796
|
+
return /* @__PURE__ */ jsx46(DropdownMenuRenderer, { node });
|
|
4797
|
+
}
|
|
4798
|
+
if (schema.type === "dropdown-menu-trigger" || schema.type === "dropdown-menu-content" || schema.type === "dropdown-menu-group" || schema.type === "dropdown-menu-label" || schema.type === "dropdown-menu-item" || schema.type === "dropdown-menu-separator" || schema.type === "dropdown-menu-sub" || schema.type === "dropdown-menu-sub-trigger" || schema.type === "dropdown-menu-sub-content") {
|
|
4799
|
+
return /* @__PURE__ */ jsx46(DropdownMenuSlotRenderer, { node });
|
|
4800
|
+
}
|
|
4801
|
+
if (schema.type === "pagination") {
|
|
4802
|
+
return /* @__PURE__ */ jsx46(PaginationRenderer, { node });
|
|
4803
|
+
}
|
|
4804
|
+
if (schema.type === "stepper") {
|
|
4805
|
+
return /* @__PURE__ */ jsx46(StepperRenderer, { node });
|
|
4806
|
+
}
|
|
4807
|
+
if (schema.type === "step") {
|
|
4808
|
+
return /* @__PURE__ */ jsx46(StepRenderer, { node });
|
|
4809
|
+
}
|
|
4810
|
+
if (schema.type === "dialog") {
|
|
4811
|
+
return /* @__PURE__ */ jsx46(DialogRenderer, { node });
|
|
4812
|
+
}
|
|
4813
|
+
if (schema.type === "dialog-header" || schema.type === "dialog-body" || schema.type === "dialog-footer") {
|
|
4814
|
+
return /* @__PURE__ */ jsx46(DialogSlotRenderer, { node });
|
|
4815
|
+
}
|
|
4816
|
+
if (schema.type === "drawer") {
|
|
4817
|
+
return /* @__PURE__ */ jsx46(DrawerRenderer, { node });
|
|
4818
|
+
}
|
|
4819
|
+
if (schema.type === "drawer-header" || schema.type === "drawer-body" || schema.type === "drawer-footer") {
|
|
4820
|
+
return /* @__PURE__ */ jsx46(DrawerSlotRenderer, { node });
|
|
4821
|
+
}
|
|
4822
|
+
const Component = layoutRegistry[schema.type];
|
|
4823
|
+
if (!Component) {
|
|
4824
|
+
return null;
|
|
4825
|
+
}
|
|
4826
|
+
const children = node.children.map((child) => /* @__PURE__ */ jsx46(NodeRenderer, { node: child }, child.id));
|
|
4827
|
+
const props = adaptLayout({ schema, children });
|
|
4828
|
+
return /* @__PURE__ */ jsx46(Component, { ...props });
|
|
4829
|
+
}
|
|
4830
|
+
|
|
4831
|
+
// src/renderer/form-renderer.tsx
|
|
4832
|
+
import {
|
|
4833
|
+
compileSchema as compileSchema2,
|
|
4834
|
+
FormEngine as FormEngine2
|
|
4835
|
+
} from "@bsm-form/core";
|
|
4836
|
+
import { useEffect as useEffect9, useMemo as useMemo2, useRef as useRef3, useState as useState9 } from "react";
|
|
4837
|
+
import { createPortal } from "react-dom";
|
|
4838
|
+
import { Toaster } from "sonner";
|
|
4839
|
+
import { jsx as jsx47, jsxs as jsxs19 } from "react/jsx-runtime";
|
|
4840
|
+
function FormRenderer({
|
|
4841
|
+
tree,
|
|
4842
|
+
renderWrapper,
|
|
4843
|
+
designMode = false,
|
|
4844
|
+
environment,
|
|
4845
|
+
invokeCatalog,
|
|
4846
|
+
slots,
|
|
4847
|
+
slotCatalog,
|
|
4848
|
+
forms,
|
|
4849
|
+
onEmbeddedValuesChange,
|
|
4850
|
+
onEmbeddedSnapshotChange,
|
|
4851
|
+
onValuesChange,
|
|
4852
|
+
suppressToaster = false
|
|
4853
|
+
}) {
|
|
4854
|
+
const [, forceUpdate] = useState9(0);
|
|
4855
|
+
const lastSerialized = useRef3("");
|
|
4856
|
+
const engine = useMemo2(
|
|
4857
|
+
() => new FormEngine2(compileSchema2(tree), {
|
|
4858
|
+
...environment,
|
|
4859
|
+
notify: environment?.notify ?? notifyWithSonner,
|
|
4860
|
+
invoke: environment?.invoke ?? {}
|
|
4861
|
+
}),
|
|
4862
|
+
[tree, designMode, environment]
|
|
4863
|
+
);
|
|
4864
|
+
useEffect9(() => {
|
|
4865
|
+
const unsubscribe = engine.subscribe(() => {
|
|
4866
|
+
forceUpdate((x) => x + 1);
|
|
4867
|
+
if (!onValuesChange) {
|
|
4868
|
+
return;
|
|
4869
|
+
}
|
|
4870
|
+
const values = engine.getValues();
|
|
4871
|
+
const serialized = JSON.stringify(values);
|
|
4872
|
+
if (serialized === lastSerialized.current) {
|
|
4873
|
+
return;
|
|
4874
|
+
}
|
|
4875
|
+
lastSerialized.current = serialized;
|
|
4876
|
+
onValuesChange(values);
|
|
4877
|
+
});
|
|
4878
|
+
void engine.initialize({ skipLoadSteps: designMode === true }).catch(() => {
|
|
4879
|
+
});
|
|
4880
|
+
return unsubscribe;
|
|
4881
|
+
}, [engine, designMode, onValuesChange]);
|
|
4882
|
+
useEffect9(() => {
|
|
4883
|
+
lastSerialized.current = "";
|
|
4884
|
+
}, [engine]);
|
|
4885
|
+
const toaster = suppressToaster || designMode || typeof document === "undefined" ? null : createPortal(
|
|
4886
|
+
/* @__PURE__ */ jsx47(Toaster, { richColors: true, closeButton: true, position: "top-right" }),
|
|
4887
|
+
document.body
|
|
4888
|
+
);
|
|
4889
|
+
return /* @__PURE__ */ jsx47(FormProvider, { engine, children: /* @__PURE__ */ jsxs19(
|
|
4890
|
+
ConfigProvider,
|
|
4891
|
+
{
|
|
4892
|
+
designMode,
|
|
4893
|
+
renderWrapper,
|
|
4894
|
+
invokeCatalog,
|
|
4895
|
+
slots,
|
|
4896
|
+
slotCatalog,
|
|
4897
|
+
forms,
|
|
4898
|
+
onEmbeddedValuesChange,
|
|
4899
|
+
onEmbeddedSnapshotChange,
|
|
4900
|
+
environment,
|
|
4901
|
+
parentEngine: engine,
|
|
4902
|
+
children: [
|
|
4903
|
+
/* @__PURE__ */ jsx47(NodeRenderer, { node: engine.getTree() }),
|
|
4904
|
+
toaster
|
|
4905
|
+
]
|
|
4906
|
+
}
|
|
4907
|
+
) });
|
|
4908
|
+
}
|
|
4909
|
+
export {
|
|
4910
|
+
ActionRenderer,
|
|
4911
|
+
AlertDisplay,
|
|
4912
|
+
ChipsDisplay,
|
|
4913
|
+
DialogRenderer,
|
|
4914
|
+
DialogSlotRenderer,
|
|
4915
|
+
DisplayRenderer,
|
|
4916
|
+
DrawerRenderer,
|
|
4917
|
+
DrawerSlotRenderer,
|
|
4918
|
+
DropdownMenuItemView,
|
|
4919
|
+
DropdownMenuRenderer,
|
|
4920
|
+
DropdownMenuSlotRenderer,
|
|
4921
|
+
EMBEDS_RESOURCE_ROOT,
|
|
4922
|
+
FieldRenderer,
|
|
4923
|
+
FormContext,
|
|
4924
|
+
FormProvider,
|
|
4925
|
+
FormRefRenderer,
|
|
4926
|
+
FormRenderer,
|
|
4927
|
+
LayoutRenderer,
|
|
4928
|
+
NodeRenderer,
|
|
4929
|
+
PaginationRenderer,
|
|
4930
|
+
PopoverRenderer,
|
|
4931
|
+
PopoverSlotRenderer,
|
|
4932
|
+
SkeletonDisplay,
|
|
4933
|
+
SlotDisplay,
|
|
4934
|
+
StepRenderer,
|
|
4935
|
+
StepperRenderer,
|
|
4936
|
+
TooltipRenderer,
|
|
4937
|
+
TriggerBridge as TooltipTriggerBridge,
|
|
4938
|
+
aggregateEmbeddedFormPayload,
|
|
4939
|
+
aggregateEmbeddedFormValues,
|
|
4940
|
+
buildDropdownMenuContentProps,
|
|
4941
|
+
buildDropdownMenuRootProps,
|
|
4942
|
+
buildPopoverContentProps,
|
|
4943
|
+
buildPopoverRootProps,
|
|
4944
|
+
executeRendererDialogChange,
|
|
4945
|
+
executeRendererDrawerChange,
|
|
4946
|
+
executeRendererPaginationChange,
|
|
4947
|
+
executeRendererStepperNavigation,
|
|
4948
|
+
normalizeAlertText,
|
|
4949
|
+
normalizeAlertType,
|
|
4950
|
+
normalizeAlertVariant,
|
|
4951
|
+
normalizeChipsLabel,
|
|
4952
|
+
normalizeChipsVariant,
|
|
4953
|
+
normalizeDialogSize,
|
|
4954
|
+
normalizeDialogTitle,
|
|
4955
|
+
normalizeDrawerSide,
|
|
4956
|
+
normalizeDrawerTitle,
|
|
4957
|
+
normalizeDropdownMenuAlign,
|
|
4958
|
+
normalizeDropdownMenuAlignOffset,
|
|
4959
|
+
normalizeDropdownMenuAriaLabel,
|
|
4960
|
+
normalizeDropdownMenuBoolean,
|
|
4961
|
+
normalizeDropdownMenuClassName,
|
|
4962
|
+
normalizeDropdownMenuCollisionPadding,
|
|
4963
|
+
normalizeDropdownMenuDefaultOpen,
|
|
4964
|
+
normalizeDropdownMenuItemVariant,
|
|
4965
|
+
normalizeDropdownMenuModal,
|
|
4966
|
+
normalizeDropdownMenuOptionalText,
|
|
4967
|
+
normalizeDropdownMenuSide,
|
|
4968
|
+
normalizeDropdownMenuSideOffset,
|
|
4969
|
+
normalizeDropdownMenuText,
|
|
4970
|
+
normalizeNonNegativeInteger,
|
|
4971
|
+
normalizePageSizeOptions,
|
|
4972
|
+
normalizePopoverAlign,
|
|
4973
|
+
normalizePopoverAlignOffset,
|
|
4974
|
+
normalizePopoverAriaLabel,
|
|
4975
|
+
normalizePopoverClassName,
|
|
4976
|
+
normalizePopoverDefaultOpen,
|
|
4977
|
+
normalizePopoverModal,
|
|
4978
|
+
normalizePopoverSide,
|
|
4979
|
+
normalizePopoverSideOffset,
|
|
4980
|
+
normalizePositiveInteger,
|
|
4981
|
+
normalizeSkeletonAriaLabel,
|
|
4982
|
+
normalizeSkeletonClassName,
|
|
4983
|
+
normalizeStepLabel,
|
|
4984
|
+
normalizeStepperConnector,
|
|
4985
|
+
normalizeStepperOrientation,
|
|
4986
|
+
resourcesWithoutEmbeds,
|
|
4987
|
+
setEmbeddedFormSnapshot,
|
|
4988
|
+
setEmbeddedFormValues,
|
|
4989
|
+
snapshotFromEngine,
|
|
4990
|
+
useFormContext,
|
|
4991
|
+
useOptionalFormContext
|
|
4992
|
+
};
|