@datenlotse/jsonjoy-builder 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (50) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +203 -0
  3. package/dist/components/SchemaEditor/AddFieldButton.js +312 -0
  4. package/dist/components/SchemaEditor/JsonSchemaEditor.js +166 -0
  5. package/dist/components/SchemaEditor/JsonSchemaVisualizer.js +96 -0
  6. package/dist/components/SchemaEditor/SchemaField.js +104 -0
  7. package/dist/components/SchemaEditor/SchemaFieldList.js +84 -0
  8. package/dist/components/SchemaEditor/SchemaPropertyEditor.js +249 -0
  9. package/dist/components/SchemaEditor/SchemaTypeSelector.js +55 -0
  10. package/dist/components/SchemaEditor/SchemaVisualEditor.js +77 -0
  11. package/dist/components/SchemaEditor/TypeDropdown.js +72 -0
  12. package/dist/components/SchemaEditor/TypeEditor.js +71 -0
  13. package/dist/components/SchemaEditor/types/ArrayEditor.js +173 -0
  14. package/dist/components/SchemaEditor/types/BooleanEditor.js +107 -0
  15. package/dist/components/SchemaEditor/types/NumberEditor.js +583 -0
  16. package/dist/components/SchemaEditor/types/ObjectEditor.js +90 -0
  17. package/dist/components/SchemaEditor/types/StringEditor.js +542 -0
  18. package/dist/components/features/JsonValidator.js +239 -0
  19. package/dist/components/features/SchemaInferencer.js +107 -0
  20. package/dist/components/ui/badge.js +25 -0
  21. package/dist/components/ui/button.js +41 -0
  22. package/dist/components/ui/dialog.js +73 -0
  23. package/dist/components/ui/input.js +11 -0
  24. package/dist/components/ui/label.js +13 -0
  25. package/dist/components/ui/select.js +90 -0
  26. package/dist/components/ui/switch.js +14 -0
  27. package/dist/components/ui/tabs.js +24 -0
  28. package/dist/components/ui/tooltip.js +15 -0
  29. package/dist/hooks/use-monaco-theme.js +197 -0
  30. package/dist/hooks/use-translation.js +14 -0
  31. package/dist/i18n/locales/de.js +143 -0
  32. package/dist/i18n/locales/en.js +143 -0
  33. package/dist/i18n/locales/es.js +143 -0
  34. package/dist/i18n/locales/fr.js +143 -0
  35. package/dist/i18n/locales/ru.js +143 -0
  36. package/dist/i18n/locales/uk.js +143 -0
  37. package/dist/i18n/locales/zh.js +143 -0
  38. package/dist/i18n/translation-context.js +4 -0
  39. package/dist/i18n/translation-keys.js +0 -0
  40. package/dist/index.css +3830 -0
  41. package/dist/index.d.ts +995 -0
  42. package/dist/index.js +10 -0
  43. package/dist/lib/schema-inference.js +266 -0
  44. package/dist/lib/schemaCompile.js +113 -0
  45. package/dist/lib/schemaEditor.js +167 -0
  46. package/dist/lib/utils.js +40 -0
  47. package/dist/types/jsonSchema.js +98 -0
  48. package/dist/types/validation.js +215 -0
  49. package/dist/utils/jsonValidator.js +162 -0
  50. package/package.json +112 -0
@@ -0,0 +1,90 @@
1
+ import { jsx, jsxs } from "react/jsx-runtime";
2
+ import { useTranslation } from "../../../hooks/use-translation.js";
3
+ import { getSchemaProperties, removeObjectProperty, reorderObjectProperty, updateObjectProperty, updatePropertyRequired } from "../../../lib/schemaEditor.js";
4
+ import { asObjectSchema, isBooleanSchema } from "../../../types/jsonSchema.js";
5
+ import AddFieldButton from "../AddFieldButton.js";
6
+ import SchemaPropertyEditor from "../SchemaPropertyEditor.js";
7
+ const ObjectEditor = ({ schema, validationNode, onChange, depth = 0, readOnly = false })=>{
8
+ const t = useTranslation();
9
+ const properties = getSchemaProperties(schema);
10
+ const normalizedSchema = isBooleanSchema(schema) ? {
11
+ type: "object",
12
+ properties: {}
13
+ } : {
14
+ ...schema,
15
+ type: "object",
16
+ properties: schema.properties || {}
17
+ };
18
+ const handleAddProperty = (newField)=>{
19
+ const fieldSchema = {
20
+ type: newField.type,
21
+ description: newField.description || void 0,
22
+ ...newField.validation || {}
23
+ };
24
+ if (void 0 !== newField.default) fieldSchema.default = newField.default;
25
+ let newSchema = updateObjectProperty(normalizedSchema, newField.name, fieldSchema);
26
+ if (newField.required) newSchema = updatePropertyRequired(newSchema, newField.name, true);
27
+ onChange(newSchema);
28
+ };
29
+ const handleDeleteProperty = (propertyName)=>{
30
+ const newSchema = removeObjectProperty(normalizedSchema, propertyName);
31
+ onChange(newSchema);
32
+ };
33
+ const handlePropertyNameChange = (oldName, newName)=>{
34
+ if (oldName === newName) return;
35
+ const property = properties.find((p)=>p.name === oldName);
36
+ if (!property) return;
37
+ const propertySchemaObj = asObjectSchema(property.schema);
38
+ let newSchema = updateObjectProperty(normalizedSchema, newName, propertySchemaObj);
39
+ if (property.required) newSchema = updatePropertyRequired(newSchema, newName, true);
40
+ newSchema = removeObjectProperty(newSchema, oldName);
41
+ onChange(newSchema);
42
+ };
43
+ const handlePropertyRequiredChange = (propertyName, required)=>{
44
+ const newSchema = updatePropertyRequired(normalizedSchema, propertyName, required);
45
+ onChange(newSchema);
46
+ };
47
+ const handlePropertySchemaChange = (propertyName, propertySchema)=>{
48
+ const newSchema = updateObjectProperty(normalizedSchema, propertyName, propertySchema);
49
+ onChange(newSchema);
50
+ };
51
+ const handleReorderProperty = (propertyName, direction)=>{
52
+ const newSchema = reorderObjectProperty(normalizedSchema, propertyName, direction);
53
+ onChange(newSchema);
54
+ };
55
+ return /*#__PURE__*/ jsxs("div", {
56
+ className: "space-y-4",
57
+ children: [
58
+ properties.length > 0 ? /*#__PURE__*/ jsx("div", {
59
+ className: "space-y-2",
60
+ children: properties.map((property, index)=>/*#__PURE__*/ jsx(SchemaPropertyEditor, {
61
+ readOnly: readOnly,
62
+ name: property.name,
63
+ schema: property.schema,
64
+ required: property.required,
65
+ parentSchema: normalizedSchema,
66
+ validationNode: validationNode?.children[property.name],
67
+ onDelete: ()=>handleDeleteProperty(property.name),
68
+ onNameChange: (newName)=>handlePropertyNameChange(property.name, newName),
69
+ onRequiredChange: (required)=>handlePropertyRequiredChange(property.name, required),
70
+ onSchemaChange: (schema)=>handlePropertySchemaChange(property.name, schema),
71
+ onMoveUp: index > 0 ? ()=>handleReorderProperty(property.name, "up") : void 0,
72
+ onMoveDown: index < properties.length - 1 ? ()=>handleReorderProperty(property.name, "down") : void 0,
73
+ depth: depth
74
+ }, property.name))
75
+ }) : /*#__PURE__*/ jsx("div", {
76
+ className: "text-sm text-muted-foreground italic p-2 text-center border rounded-md",
77
+ children: t.objectPropertiesNone
78
+ }),
79
+ !readOnly && /*#__PURE__*/ jsx("div", {
80
+ className: "mt-4",
81
+ children: /*#__PURE__*/ jsx(AddFieldButton, {
82
+ onAddField: handleAddProperty,
83
+ variant: "secondary"
84
+ })
85
+ })
86
+ ]
87
+ });
88
+ };
89
+ const types_ObjectEditor = ObjectEditor;
90
+ export { types_ObjectEditor as default };
@@ -0,0 +1,542 @@
1
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
2
+ import { X } from "lucide-react";
3
+ import { useEffect, useId, useMemo, useState } from "react";
4
+ import { Input } from "../../ui/input.js";
5
+ import { Label } from "../../ui/label.js";
6
+ import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "../../ui/select.js";
7
+ import { useTranslation } from "../../../hooks/use-translation.js";
8
+ import { getEligibleEnumControllingProperties } from "../../../lib/schemaEditor.js";
9
+ import { cn } from "../../../lib/utils.js";
10
+ import { isBooleanSchema, withObjectSchema } from "../../../types/jsonSchema.js";
11
+ const StringEditor = ({ schema, validationNode, onChange, readOnly = false, parentSchema, propertyName })=>{
12
+ const t = useTranslation();
13
+ const [enumValue, setEnumValue] = useState("");
14
+ const [dependentEnumValue, setDependentEnumValue] = useState({});
15
+ const [selectedControllingValue, setSelectedControllingValue] = useState("");
16
+ const eligibleControllers = useMemo(()=>parentSchema && propertyName ? getEligibleEnumControllingProperties(parentSchema, propertyName) : [], [
17
+ parentSchema,
18
+ propertyName
19
+ ]);
20
+ const dependentEnum = withObjectSchema(schema, (s)=>s.$dependentEnum, void 0);
21
+ const enumMode = null != dependentEnum ? "depends" : "static";
22
+ const controllingProperty = dependentEnum?.property;
23
+ const dependentValuesMap = dependentEnum?.values ?? {};
24
+ const currentController = useMemo(()=>eligibleControllers.find((c)=>c.name === controllingProperty), [
25
+ eligibleControllers,
26
+ controllingProperty
27
+ ]);
28
+ const controllingValues = currentController?.values ?? [];
29
+ const activeKey = useMemo(()=>{
30
+ if (0 === controllingValues.length) return "";
31
+ const first = String(controllingValues[0]);
32
+ if (selectedControllingValue && controllingValues.some((v)=>String(v) === selectedControllingValue)) return selectedControllingValue;
33
+ return first;
34
+ }, [
35
+ controllingValues,
36
+ selectedControllingValue
37
+ ]);
38
+ useEffect(()=>{
39
+ if ("depends" === enumMode && controllingValues.length > 0) {
40
+ const valid = selectedControllingValue && controllingValues.some((v)=>String(v) === selectedControllingValue);
41
+ if (!valid) setSelectedControllingValue(String(controllingValues[0]));
42
+ }
43
+ }, [
44
+ enumMode,
45
+ controllingProperty,
46
+ controllingValues,
47
+ selectedControllingValue
48
+ ]);
49
+ const minLengthId = useId();
50
+ const maxLengthId = useId();
51
+ const patternId = useId();
52
+ const formatId = useId();
53
+ const minLength = withObjectSchema(schema, (s)=>s.minLength, void 0);
54
+ const maxLength = withObjectSchema(schema, (s)=>s.maxLength, void 0);
55
+ const pattern = withObjectSchema(schema, (s)=>s.pattern, void 0);
56
+ const format = withObjectSchema(schema, (s)=>s.format, void 0);
57
+ const enumValues = withObjectSchema(schema, (s)=>s.enum || [], []);
58
+ const baseSchemaForValidation = useMemo(()=>isBooleanSchema(schema) ? {
59
+ type: "string"
60
+ } : (()=>{
61
+ const { enum: _e, $dependentEnum: _d, ...rest } = schema;
62
+ return {
63
+ ...rest,
64
+ type: "string"
65
+ };
66
+ })(), [
67
+ schema
68
+ ]);
69
+ const handleValidationChange = (property, value)=>{
70
+ const updated = {
71
+ ...baseSchemaForValidation
72
+ };
73
+ if ("enum" === property) {
74
+ updated.enum = value;
75
+ if ("$dependentEnum" in updated) delete updated.$dependentEnum;
76
+ } else if ("$dependentEnum" === property) if (null != value) {
77
+ updated.$dependentEnum = value;
78
+ if ("enum" in updated) delete updated.enum;
79
+ } else delete updated.$dependentEnum;
80
+ else updated[property] = value;
81
+ onChange(updated);
82
+ };
83
+ const handleSetEnumMode = (mode, controllerName)=>{
84
+ if ("static" === mode) {
85
+ const rest = {
86
+ ...baseSchemaForValidation
87
+ };
88
+ delete rest.$dependentEnum;
89
+ onChange({
90
+ ...rest,
91
+ type: "string"
92
+ });
93
+ } else if (controllerName && eligibleControllers.some((c)=>c.name === controllerName)) {
94
+ const controller = eligibleControllers.find((c)=>c.name === controllerName);
95
+ const values = {};
96
+ for (const v of controller.values){
97
+ const key = String(v);
98
+ values[key] = dependentValuesMap[key] ?? [];
99
+ }
100
+ handleValidationChange("$dependentEnum", {
101
+ property: controllerName,
102
+ values
103
+ });
104
+ }
105
+ };
106
+ const handleDependentEnumValuesChange = (controllingValue, newList)=>{
107
+ const prop = dependentEnum?.property;
108
+ if (!prop) return;
109
+ const next = {
110
+ ...dependentValuesMap,
111
+ [controllingValue]: newList
112
+ };
113
+ if (0 === newList.length) {
114
+ const { [controllingValue]: _, ...rest } = next;
115
+ if (0 === Object.keys(rest).length) return void handleValidationChange("$dependentEnum", void 0);
116
+ handleValidationChange("$dependentEnum", {
117
+ property: prop,
118
+ values: rest
119
+ });
120
+ } else handleValidationChange("$dependentEnum", {
121
+ property: prop,
122
+ values: next
123
+ });
124
+ };
125
+ const handleAddEnumValue = ()=>{
126
+ if (!enumValue.trim()) return;
127
+ if (!enumValues.includes(enumValue)) handleValidationChange("enum", [
128
+ ...enumValues,
129
+ enumValue
130
+ ]);
131
+ setEnumValue("");
132
+ };
133
+ const handleRemoveEnumValue = (index)=>{
134
+ const newEnumValues = [
135
+ ...enumValues
136
+ ];
137
+ newEnumValues.splice(index, 1);
138
+ if (0 === newEnumValues.length) {
139
+ const baseSchema = isBooleanSchema(schema) ? {
140
+ type: "string"
141
+ } : {
142
+ ...schema
143
+ };
144
+ if (!isBooleanSchema(baseSchema) && "enum" in baseSchema) {
145
+ const { enum: _, ...rest } = baseSchema;
146
+ onChange(rest);
147
+ } else onChange(baseSchema);
148
+ } else handleValidationChange("enum", newEnumValues);
149
+ };
150
+ const minMaxError = useMemo(()=>validationNode?.validation.errors?.find((err)=>"length" === err.path[0])?.message, [
151
+ validationNode
152
+ ]);
153
+ const minLengthError = useMemo(()=>validationNode?.validation.errors?.find((err)=>"minLength" === err.path[0])?.message, [
154
+ validationNode
155
+ ]);
156
+ const maxLengthError = useMemo(()=>validationNode?.validation.errors?.find((err)=>"maxLength" === err.path[0])?.message, [
157
+ validationNode
158
+ ]);
159
+ const patternError = useMemo(()=>validationNode?.validation.errors?.find((err)=>"pattern" === err.path[0])?.message, [
160
+ validationNode
161
+ ]);
162
+ const formatError = useMemo(()=>validationNode?.validation.errors?.find((err)=>"format" === err.path[0])?.message, [
163
+ validationNode
164
+ ]);
165
+ const minLengthValue = minLength ?? "";
166
+ const maxLengthValue = maxLength ?? "";
167
+ const patternValue = pattern ?? "";
168
+ const formatValue = format || "none";
169
+ const needsDetail = !readOnly || "" !== minLengthValue || "" !== maxLengthValue || "" !== patternValue || "none" !== formatValue || enumValues.length > 0 || null != dependentEnum && Object.keys(dependentValuesMap).length > 0;
170
+ return /*#__PURE__*/ jsxs("div", {
171
+ className: "space-y-4",
172
+ children: [
173
+ /*#__PURE__*/ jsxs("div", {
174
+ className: "grid grid-cols-1 md:grid-cols-2 gap-4 items-start",
175
+ children: [
176
+ readOnly && !needsDetail && /*#__PURE__*/ jsx("p", {
177
+ className: "text-sm text-muted-foreground italic",
178
+ children: t.stringNoConstraint
179
+ }),
180
+ (!readOnly || "" !== minLengthValue) && /*#__PURE__*/ jsxs("div", {
181
+ className: "space-y-2",
182
+ children: [
183
+ /*#__PURE__*/ jsx(Label, {
184
+ htmlFor: minLengthId,
185
+ className: (!!minMaxError || !!minLengthError) && "text-destructive",
186
+ children: t.stringMinimumLengthLabel
187
+ }),
188
+ /*#__PURE__*/ jsx(Input, {
189
+ id: minLengthId,
190
+ type: "number",
191
+ min: 0,
192
+ value: minLengthValue,
193
+ disabled: readOnly,
194
+ onChange: (e)=>{
195
+ const value = e.target.value ? Number(e.target.value) : void 0;
196
+ handleValidationChange("minLength", value);
197
+ },
198
+ placeholder: t.stringMinimumLengthPlaceholder,
199
+ className: cn("h-8", (!!minMaxError || !!minLengthError) && "border-destructive")
200
+ })
201
+ ]
202
+ }),
203
+ (!readOnly || "" !== maxLengthValue) && /*#__PURE__*/ jsxs("div", {
204
+ className: "space-y-2",
205
+ children: [
206
+ /*#__PURE__*/ jsx(Label, {
207
+ htmlFor: maxLengthId,
208
+ className: (!!minMaxError || !!maxLengthError) && "text-destructive",
209
+ children: t.stringMaximumLengthLabel
210
+ }),
211
+ /*#__PURE__*/ jsx(Input, {
212
+ id: maxLengthId,
213
+ type: "number",
214
+ min: 0,
215
+ disabled: readOnly,
216
+ value: maxLengthValue,
217
+ onChange: (e)=>{
218
+ const value = e.target.value ? Number(e.target.value) : void 0;
219
+ handleValidationChange("maxLength", value);
220
+ },
221
+ placeholder: t.stringMaximumLengthPlaceholder,
222
+ className: cn("h-8", (!!minMaxError || !!maxLengthError) && "border-destructive")
223
+ })
224
+ ]
225
+ }),
226
+ (!!minMaxError || !!minLengthError || !!maxLengthError) && /*#__PURE__*/ jsx("div", {
227
+ className: "text-xs text-destructive italic md:col-span-2 whitespace-pre-line",
228
+ children: [
229
+ minMaxError,
230
+ minLengthError ?? maxLengthError
231
+ ].filter(Boolean).join("\n")
232
+ })
233
+ ]
234
+ }),
235
+ (!readOnly || "" !== patternValue) && /*#__PURE__*/ jsxs("div", {
236
+ className: "space-y-2",
237
+ children: [
238
+ /*#__PURE__*/ jsx(Label, {
239
+ htmlFor: patternId,
240
+ className: !!patternError && "text-destructive",
241
+ children: t.stringPatternLabel
242
+ }),
243
+ /*#__PURE__*/ jsx(Input, {
244
+ id: patternId,
245
+ type: "text",
246
+ value: patternValue,
247
+ onChange: (e)=>{
248
+ const value = e.target.value || void 0;
249
+ handleValidationChange("pattern", value);
250
+ },
251
+ placeholder: t.stringPatternPlaceholder,
252
+ className: "h-8"
253
+ })
254
+ ]
255
+ }),
256
+ (!readOnly || "none" !== formatValue) && /*#__PURE__*/ jsxs("div", {
257
+ className: "space-y-2",
258
+ children: [
259
+ /*#__PURE__*/ jsx(Label, {
260
+ htmlFor: formatId,
261
+ className: !!formatError && "text-destructive",
262
+ children: t.stringFormatLabel
263
+ }),
264
+ /*#__PURE__*/ jsxs(Select, {
265
+ value: formatValue,
266
+ onValueChange: (value)=>{
267
+ handleValidationChange("format", "none" === value ? void 0 : value);
268
+ },
269
+ children: [
270
+ /*#__PURE__*/ jsx(SelectTrigger, {
271
+ id: formatId,
272
+ className: "h-8",
273
+ children: /*#__PURE__*/ jsx(SelectValue, {
274
+ placeholder: t.stringFormatSelectPlaceholder
275
+ })
276
+ }),
277
+ /*#__PURE__*/ jsxs(SelectContent, {
278
+ children: [
279
+ /*#__PURE__*/ jsx(SelectItem, {
280
+ value: "none",
281
+ children: t.stringFormatNone
282
+ }),
283
+ /*#__PURE__*/ jsx(SelectItem, {
284
+ value: "date-time",
285
+ children: t.stringFormatDateTime
286
+ }),
287
+ /*#__PURE__*/ jsx(SelectItem, {
288
+ value: "date",
289
+ children: t.stringFormatDate
290
+ }),
291
+ /*#__PURE__*/ jsx(SelectItem, {
292
+ value: "time",
293
+ children: t.stringFormatTime
294
+ }),
295
+ /*#__PURE__*/ jsx(SelectItem, {
296
+ value: "email",
297
+ children: t.stringFormatEmail
298
+ }),
299
+ /*#__PURE__*/ jsx(SelectItem, {
300
+ value: "uri",
301
+ children: t.stringFormatUri
302
+ }),
303
+ /*#__PURE__*/ jsx(SelectItem, {
304
+ value: "uuid",
305
+ children: t.stringFormatUuid
306
+ }),
307
+ /*#__PURE__*/ jsx(SelectItem, {
308
+ value: "hostname",
309
+ children: t.stringFormatHostname
310
+ }),
311
+ /*#__PURE__*/ jsx(SelectItem, {
312
+ value: "ipv4",
313
+ children: t.stringFormatIpv4
314
+ }),
315
+ /*#__PURE__*/ jsx(SelectItem, {
316
+ value: "ipv6",
317
+ children: t.stringFormatIpv6
318
+ })
319
+ ]
320
+ })
321
+ ]
322
+ })
323
+ ]
324
+ }),
325
+ (!readOnly || enumValues.length > 0 || null != dependentEnum) && /*#__PURE__*/ jsxs("div", {
326
+ className: "space-y-2 pt-2 border-t border-border/40",
327
+ children: [
328
+ /*#__PURE__*/ jsx(Label, {
329
+ children: t.stringAllowedValuesEnumLabel
330
+ }),
331
+ eligibleControllers.length > 0 && !readOnly && /*#__PURE__*/ jsxs("div", {
332
+ className: "flex flex-wrap items-center gap-2 mb-2",
333
+ children: [
334
+ /*#__PURE__*/ jsxs(Label, {
335
+ className: "text-xs text-muted-foreground",
336
+ children: [
337
+ t.enumModeDependsOn,
338
+ ":"
339
+ ]
340
+ }),
341
+ /*#__PURE__*/ jsxs(Select, {
342
+ value: "depends" === enumMode ? controllingProperty ?? "" : "__static__",
343
+ onValueChange: (v)=>{
344
+ "__static__" === v ? handleSetEnumMode("static") : handleSetEnumMode("depends", v);
345
+ },
346
+ children: [
347
+ /*#__PURE__*/ jsx(SelectTrigger, {
348
+ className: "h-8 w-[180px]",
349
+ children: /*#__PURE__*/ jsx(SelectValue, {
350
+ placeholder: t.enumDependsOnPlaceholder
351
+ })
352
+ }),
353
+ /*#__PURE__*/ jsxs(SelectContent, {
354
+ children: [
355
+ /*#__PURE__*/ jsx(SelectItem, {
356
+ value: "__static__",
357
+ children: t.enumModeStatic
358
+ }),
359
+ eligibleControllers.map((c)=>/*#__PURE__*/ jsx(SelectItem, {
360
+ value: c.name,
361
+ children: c.name
362
+ }, c.name))
363
+ ]
364
+ })
365
+ ]
366
+ })
367
+ ]
368
+ }),
369
+ "static" === enumMode && /*#__PURE__*/ jsxs(Fragment, {
370
+ children: [
371
+ /*#__PURE__*/ jsx("div", {
372
+ className: "flex flex-wrap gap-2 mb-4",
373
+ children: enumValues.length > 0 ? enumValues.map((value)=>/*#__PURE__*/ jsxs("div", {
374
+ className: "flex items-center bg-muted/40 border rounded-md px-2 py-1 text-xs",
375
+ children: [
376
+ /*#__PURE__*/ jsx("span", {
377
+ className: "mr-1",
378
+ children: value
379
+ }),
380
+ !readOnly && /*#__PURE__*/ jsx("button", {
381
+ type: "button",
382
+ onClick: ()=>handleRemoveEnumValue(enumValues.indexOf(value)),
383
+ className: "text-muted-foreground hover:text-destructive",
384
+ children: /*#__PURE__*/ jsx(X, {
385
+ size: 12
386
+ })
387
+ })
388
+ ]
389
+ }, `enum-string-${value}`)) : /*#__PURE__*/ jsx("p", {
390
+ className: "text-xs text-muted-foreground italic",
391
+ children: t.stringAllowedValuesEnumNone
392
+ })
393
+ }),
394
+ !readOnly && /*#__PURE__*/ jsxs("div", {
395
+ className: "flex items-center gap-2",
396
+ children: [
397
+ /*#__PURE__*/ jsx(Input, {
398
+ type: "text",
399
+ value: enumValue,
400
+ onChange: (e)=>setEnumValue(e.target.value),
401
+ placeholder: t.stringAllowedValuesEnumAddPlaceholder,
402
+ className: "h-8 text-xs flex-1",
403
+ onKeyDown: (e)=>"Enter" === e.key && handleAddEnumValue()
404
+ }),
405
+ /*#__PURE__*/ jsx("button", {
406
+ type: "button",
407
+ onClick: handleAddEnumValue,
408
+ className: "px-3 py-1 h-8 rounded-md bg-secondary text-xs font-medium hover:bg-secondary/80",
409
+ children: t.stringAllowedValuesEnumAddLabel
410
+ })
411
+ ]
412
+ })
413
+ ]
414
+ }),
415
+ "depends" === enumMode && controllingProperty && currentController && controllingValues.length > 0 && /*#__PURE__*/ jsxs("div", {
416
+ className: "space-y-3",
417
+ children: [
418
+ /*#__PURE__*/ jsxs("div", {
419
+ className: "flex flex-wrap items-center gap-2",
420
+ children: [
421
+ /*#__PURE__*/ jsx(Label, {
422
+ className: "text-xs text-muted-foreground",
423
+ children: t.whenPropertyEquals.replace("{property}", controllingProperty).replace("{value}", "")
424
+ }),
425
+ /*#__PURE__*/ jsxs(Select, {
426
+ value: activeKey || void 0,
427
+ onValueChange: (value)=>setSelectedControllingValue(value ?? ""),
428
+ children: [
429
+ /*#__PURE__*/ jsx(SelectTrigger, {
430
+ className: "h-8 w-[160px] text-xs",
431
+ children: /*#__PURE__*/ jsx(SelectValue, {
432
+ placeholder: t.whenPropertyEquals.replace("{property}", controllingProperty).replace("{value}", "")
433
+ })
434
+ }),
435
+ /*#__PURE__*/ jsx(SelectContent, {
436
+ children: controllingValues.map((v)=>/*#__PURE__*/ jsx(SelectItem, {
437
+ value: String(v),
438
+ children: String(v)
439
+ }, String(v)))
440
+ })
441
+ ]
442
+ })
443
+ ]
444
+ }),
445
+ activeKey && /*#__PURE__*/ jsxs("div", {
446
+ className: "space-y-1",
447
+ children: [
448
+ /*#__PURE__*/ jsx("span", {
449
+ className: "text-xs font-medium text-muted-foreground",
450
+ children: t.whenPropertyEquals.replace("{property}", controllingProperty).replace("{value}", activeKey)
451
+ }),
452
+ /*#__PURE__*/ jsxs("div", {
453
+ className: "flex flex-wrap gap-2",
454
+ children: [
455
+ (dependentValuesMap[activeKey] ?? []).map((v)=>/*#__PURE__*/ jsxs("div", {
456
+ className: "flex items-center bg-muted/40 border rounded-md px-2 py-1 text-xs",
457
+ children: [
458
+ /*#__PURE__*/ jsx("span", {
459
+ className: "mr-1",
460
+ children: v
461
+ }),
462
+ !readOnly && /*#__PURE__*/ jsx("button", {
463
+ type: "button",
464
+ onClick: ()=>{
465
+ const list = dependentValuesMap[activeKey] ?? [];
466
+ const next = list.filter((x)=>x !== v);
467
+ handleDependentEnumValuesChange(activeKey, next);
468
+ },
469
+ className: "text-muted-foreground hover:text-destructive",
470
+ children: /*#__PURE__*/ jsx(X, {
471
+ size: 12
472
+ })
473
+ })
474
+ ]
475
+ }, v)),
476
+ 0 === (dependentValuesMap[activeKey] ?? []).length && readOnly && /*#__PURE__*/ jsx("p", {
477
+ className: "text-xs text-muted-foreground italic",
478
+ children: t.stringAllowedValuesEnumNone
479
+ })
480
+ ]
481
+ }),
482
+ !readOnly && /*#__PURE__*/ jsxs("div", {
483
+ className: "flex items-center gap-2",
484
+ children: [
485
+ /*#__PURE__*/ jsx(Input, {
486
+ type: "text",
487
+ value: dependentEnumValue[activeKey] ?? "",
488
+ onChange: (e)=>setDependentEnumValue((prev)=>({
489
+ ...prev,
490
+ [activeKey]: e.target.value
491
+ })),
492
+ placeholder: t.stringAllowedValuesEnumAddPlaceholder,
493
+ className: "h-8 text-xs flex-1",
494
+ onKeyDown: (e)=>{
495
+ if ("Enter" === e.key) {
496
+ const list = dependentValuesMap[activeKey] ?? [];
497
+ const val = (dependentEnumValue[activeKey] ?? "").trim();
498
+ if (val && !list.includes(val)) {
499
+ handleDependentEnumValuesChange(activeKey, [
500
+ ...list,
501
+ val
502
+ ]);
503
+ setDependentEnumValue((prev)=>({
504
+ ...prev,
505
+ [activeKey]: ""
506
+ }));
507
+ }
508
+ }
509
+ }
510
+ }),
511
+ /*#__PURE__*/ jsx("button", {
512
+ type: "button",
513
+ onClick: ()=>{
514
+ const list = dependentValuesMap[activeKey] ?? [];
515
+ const val = (dependentEnumValue[activeKey] ?? "").trim();
516
+ if (val && !list.includes(val)) {
517
+ handleDependentEnumValuesChange(activeKey, [
518
+ ...list,
519
+ val
520
+ ]);
521
+ setDependentEnumValue((prev)=>({
522
+ ...prev,
523
+ [activeKey]: ""
524
+ }));
525
+ }
526
+ },
527
+ className: "px-3 py-1 h-8 rounded-md bg-secondary text-xs font-medium hover:bg-secondary/80",
528
+ children: t.stringAllowedValuesEnumAddLabel
529
+ })
530
+ ]
531
+ })
532
+ ]
533
+ })
534
+ ]
535
+ })
536
+ ]
537
+ })
538
+ ]
539
+ });
540
+ };
541
+ const types_StringEditor = StringEditor;
542
+ export { types_StringEditor as default };