@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,249 @@
1
+ import { jsx, jsxs } from "react/jsx-runtime";
2
+ import { ChevronDown, ChevronRight, ChevronUp, X } from "lucide-react";
3
+ import { useEffect, useMemo, useState } from "react";
4
+ import { Input } from "../ui/input.js";
5
+ import { useTranslation } from "../../hooks/use-translation.js";
6
+ import { cn } from "../../lib/utils.js";
7
+ import { asObjectSchema, getSchemaDescription, withObjectSchema } from "../../types/jsonSchema.js";
8
+ import { Badge } from "../ui/badge.js";
9
+ import TypeDropdown from "./TypeDropdown.js";
10
+ import TypeEditor from "./TypeEditor.js";
11
+ const SchemaPropertyEditor = ({ name, schema, required, readOnly = false, parentSchema, validationNode, onDelete, onNameChange, onRequiredChange, onSchemaChange, onMoveUp, onMoveDown, depth = 0 })=>{
12
+ const t = useTranslation();
13
+ const [expanded, setExpanded] = useState(false);
14
+ const [isEditingName, setIsEditingName] = useState(false);
15
+ const [isEditingDesc, setIsEditingDesc] = useState(false);
16
+ const [tempName, setTempName] = useState(name);
17
+ const [tempDesc, setTempDesc] = useState(getSchemaDescription(schema));
18
+ const type = withObjectSchema(schema, (s)=>s.type || "object", "object");
19
+ const defaultValue = useMemo(()=>{
20
+ const objSchema = asObjectSchema(schema);
21
+ return void 0 !== objSchema.default ? String(objSchema.default) : "";
22
+ }, [
23
+ schema
24
+ ]);
25
+ const [tempDefault, setTempDefault] = useState(defaultValue);
26
+ useEffect(()=>{
27
+ setTempName(name);
28
+ setTempDesc(getSchemaDescription(schema));
29
+ setTempDefault(defaultValue);
30
+ }, [
31
+ name,
32
+ schema,
33
+ defaultValue
34
+ ]);
35
+ const handleNameSubmit = ()=>{
36
+ const trimmedName = tempName.trim();
37
+ if (trimmedName && trimmedName !== name) onNameChange(trimmedName);
38
+ else setTempName(name);
39
+ setIsEditingName(false);
40
+ };
41
+ const handleDescSubmit = ()=>{
42
+ const trimmedDesc = tempDesc.trim();
43
+ if (trimmedDesc !== getSchemaDescription(schema)) onSchemaChange({
44
+ ...asObjectSchema(schema),
45
+ description: trimmedDesc || void 0
46
+ });
47
+ else setTempDesc(getSchemaDescription(schema));
48
+ setIsEditingDesc(false);
49
+ };
50
+ const handleSchemaUpdate = (updatedSchema)=>{
51
+ const description = getSchemaDescription(schema);
52
+ const currentDefault = asObjectSchema(schema).default;
53
+ onSchemaChange({
54
+ ...updatedSchema,
55
+ description: description || void 0,
56
+ default: currentDefault
57
+ });
58
+ };
59
+ const handleDefaultSubmit = ()=>{
60
+ const trimmedDefault = tempDefault.trim();
61
+ const objSchema = asObjectSchema(schema);
62
+ const currentDefault = objSchema.default;
63
+ if ("" === trimmedDefault) {
64
+ if (void 0 !== currentDefault) {
65
+ const { default: _, ...rest } = objSchema;
66
+ onSchemaChange(rest);
67
+ }
68
+ } else {
69
+ let parsedValue = trimmedDefault;
70
+ if ("number" === type || "integer" === type) {
71
+ parsedValue = Number(trimmedDefault);
72
+ if (Number.isNaN(parsedValue)) parsedValue = trimmedDefault;
73
+ } else if ("boolean" === type) parsedValue = "true" === trimmedDefault.toLowerCase() ? true : "false" === trimmedDefault.toLowerCase() ? false : trimmedDefault;
74
+ else if ("null" === type) parsedValue = null;
75
+ if (JSON.stringify(currentDefault) !== JSON.stringify(parsedValue)) onSchemaChange({
76
+ ...objSchema,
77
+ default: parsedValue
78
+ });
79
+ }
80
+ };
81
+ return /*#__PURE__*/ jsxs("div", {
82
+ className: cn("mb-2 animate-in rounded-lg border transition-all duration-200", depth > 0 && "ml-0 sm:ml-4 border-l border-l-border/40"),
83
+ children: [
84
+ /*#__PURE__*/ jsxs("div", {
85
+ className: "relative json-field-row justify-between group",
86
+ children: [
87
+ /*#__PURE__*/ jsxs("div", {
88
+ className: "flex items-center gap-2 grow min-w-0",
89
+ children: [
90
+ /*#__PURE__*/ jsx("button", {
91
+ type: "button",
92
+ className: "text-muted-foreground hover:text-foreground transition-colors",
93
+ onClick: ()=>setExpanded(!expanded),
94
+ "aria-label": expanded ? t.collapse : t.expand,
95
+ children: expanded ? /*#__PURE__*/ jsx(ChevronDown, {
96
+ size: 18
97
+ }) : /*#__PURE__*/ jsx(ChevronRight, {
98
+ size: 18
99
+ })
100
+ }),
101
+ /*#__PURE__*/ jsxs("div", {
102
+ className: "flex items-center gap-2 grow min-w-0 overflow-visible",
103
+ children: [
104
+ /*#__PURE__*/ jsxs("div", {
105
+ className: "flex items-center gap-2 min-w-0 grow overflow-visible",
106
+ children: [
107
+ !readOnly && isEditingName ? /*#__PURE__*/ jsx(Input, {
108
+ value: tempName,
109
+ onChange: (e)=>setTempName(e.target.value),
110
+ onBlur: handleNameSubmit,
111
+ onKeyDown: (e)=>"Enter" === e.key && handleNameSubmit(),
112
+ className: "h-8 text-sm font-medium min-w-[120px] max-w-full z-10",
113
+ autoFocus: true,
114
+ onFocus: (e)=>e.target.select()
115
+ }) : /*#__PURE__*/ jsx("button", {
116
+ type: "button",
117
+ onClick: ()=>setIsEditingName(true),
118
+ onKeyDown: (e)=>"Enter" === e.key && setIsEditingName(true),
119
+ className: "json-field-label font-medium cursor-text px-2 py-0.5 -mx-0.5 rounded-sm hover:bg-secondary/30 hover:shadow-xs hover:ring-1 hover:ring-ring/20 transition-all text-left truncate min-w-[80px] max-w-[50%]",
120
+ children: name
121
+ }),
122
+ !readOnly && isEditingDesc ? /*#__PURE__*/ jsx(Input, {
123
+ value: tempDesc,
124
+ onChange: (e)=>setTempDesc(e.target.value),
125
+ onBlur: handleDescSubmit,
126
+ onKeyDown: (e)=>"Enter" === e.key && handleDescSubmit(),
127
+ placeholder: t.propertyDescriptionPlaceholder,
128
+ className: "h-8 text-xs text-muted-foreground italic flex-1 min-w-[150px] z-10",
129
+ autoFocus: true,
130
+ onFocus: (e)=>e.target.select()
131
+ }) : tempDesc ? /*#__PURE__*/ jsx("button", {
132
+ type: "button",
133
+ onClick: ()=>setIsEditingDesc(true),
134
+ onKeyDown: (e)=>"Enter" === e.key && setIsEditingDesc(true),
135
+ className: "text-xs text-muted-foreground italic cursor-text px-2 py-0.5 -mx-0.5 rounded-sm hover:bg-secondary/30 hover:shadow-xs hover:ring-1 hover:ring-ring/20 transition-all text-left truncate flex-1 max-w-[40%] mr-2",
136
+ children: tempDesc
137
+ }) : /*#__PURE__*/ jsx("button", {
138
+ type: "button",
139
+ onClick: ()=>setIsEditingDesc(true),
140
+ onKeyDown: (e)=>"Enter" === e.key && setIsEditingDesc(true),
141
+ className: "text-xs text-muted-foreground/50 italic cursor-text px-2 py-0.5 -mx-0.5 rounded-sm hover:bg-secondary/30 hover:shadow-xs hover:ring-1 hover:ring-ring/20 transition-all opacity-0 group-hover:opacity-100 text-left truncate flex-1 max-w-[40%] mr-2",
142
+ children: t.propertyDescriptionButton
143
+ })
144
+ ]
145
+ }),
146
+ /*#__PURE__*/ jsxs("div", {
147
+ className: "flex items-center gap-2 justify-end shrink-0",
148
+ children: [
149
+ /*#__PURE__*/ jsx(TypeDropdown, {
150
+ value: type,
151
+ readOnly: readOnly,
152
+ onChange: (newType)=>{
153
+ onSchemaChange({
154
+ ...asObjectSchema(schema),
155
+ type: newType
156
+ });
157
+ }
158
+ }),
159
+ /*#__PURE__*/ jsx("button", {
160
+ type: "button",
161
+ onClick: ()=>!readOnly && onRequiredChange(!required),
162
+ className: cn("text-xs px-2 py-1 rounded-md font-medium min-w-[80px] text-center cursor-pointer hover:shadow-xs hover:ring-2 hover:ring-ring/30 active:scale-95 transition-all whitespace-nowrap", required ? "bg-red-50 text-red-500" : "bg-secondary text-muted-foreground"),
163
+ children: required ? t.propertyRequired : t.propertyOptional
164
+ })
165
+ ]
166
+ })
167
+ ]
168
+ })
169
+ ]
170
+ }),
171
+ validationNode?.cumulativeChildrenErrors > 0 && /*#__PURE__*/ jsx(Badge, {
172
+ className: "h-5 min-w-5 rounded-full px-1 font-mono tabular-nums justify-center",
173
+ variant: "destructive",
174
+ children: validationNode.cumulativeChildrenErrors
175
+ }),
176
+ !readOnly && /*#__PURE__*/ jsxs("div", {
177
+ className: "flex items-center gap-1 text-muted-foreground",
178
+ children: [
179
+ onMoveUp && /*#__PURE__*/ jsx("button", {
180
+ type: "button",
181
+ onClick: onMoveUp,
182
+ className: "p-1 rounded-md hover:bg-secondary hover:text-foreground transition-colors opacity-0 group-hover:opacity-100",
183
+ "aria-label": t.propertyMoveUp,
184
+ children: /*#__PURE__*/ jsx(ChevronUp, {
185
+ size: 16
186
+ })
187
+ }),
188
+ onMoveDown && /*#__PURE__*/ jsx("button", {
189
+ type: "button",
190
+ onClick: onMoveDown,
191
+ className: "p-1 rounded-md hover:bg-secondary hover:text-foreground transition-colors opacity-0 group-hover:opacity-100",
192
+ "aria-label": t.propertyMoveDown,
193
+ children: /*#__PURE__*/ jsx(ChevronDown, {
194
+ size: 16
195
+ })
196
+ }),
197
+ /*#__PURE__*/ jsx("button", {
198
+ type: "button",
199
+ onClick: onDelete,
200
+ className: "p-1 rounded-md hover:bg-secondary hover:text-destructive transition-colors opacity-0 group-hover:opacity-100",
201
+ "aria-label": t.propertyDelete,
202
+ children: /*#__PURE__*/ jsx(X, {
203
+ size: 16
204
+ })
205
+ })
206
+ ]
207
+ })
208
+ ]
209
+ }),
210
+ expanded && /*#__PURE__*/ jsxs("div", {
211
+ className: "pt-1 pb-2 px-2 sm:px-3 animate-in space-y-3",
212
+ children: [
213
+ readOnly && tempDesc && /*#__PURE__*/ jsx("p", {
214
+ className: "pb-2",
215
+ children: tempDesc
216
+ }),
217
+ !readOnly && "object" !== type && /*#__PURE__*/ jsxs("div", {
218
+ className: "space-y-1",
219
+ children: [
220
+ /*#__PURE__*/ jsx("label", {
221
+ className: "text-xs font-medium text-muted-foreground",
222
+ children: t.propertyDefaultLabel
223
+ }),
224
+ /*#__PURE__*/ jsx(Input, {
225
+ value: tempDefault,
226
+ onChange: (e)=>setTempDefault(e.target.value),
227
+ onBlur: handleDefaultSubmit,
228
+ onKeyDown: (e)=>"Enter" === e.key && handleDefaultSubmit(),
229
+ placeholder: t.propertyDefaultPlaceholder,
230
+ className: "h-8 text-sm"
231
+ })
232
+ ]
233
+ }),
234
+ /*#__PURE__*/ jsx(TypeEditor, {
235
+ schema: schema,
236
+ readOnly: readOnly,
237
+ parentSchema: parentSchema,
238
+ propertyName: name,
239
+ validationNode: validationNode,
240
+ onChange: handleSchemaUpdate,
241
+ depth: depth + 1
242
+ })
243
+ ]
244
+ })
245
+ ]
246
+ });
247
+ };
248
+ const SchemaEditor_SchemaPropertyEditor = SchemaPropertyEditor;
249
+ export { SchemaPropertyEditor, SchemaEditor_SchemaPropertyEditor as default };
@@ -0,0 +1,55 @@
1
+ import { jsx, jsxs } from "react/jsx-runtime";
2
+ import { useTranslation } from "../../hooks/use-translation.js";
3
+ import { cn } from "../../lib/utils.js";
4
+ const typeOptions = [
5
+ {
6
+ id: "string",
7
+ label: "fieldTypeTextLabel",
8
+ description: "fieldTypeTextDescription"
9
+ },
10
+ {
11
+ id: "number",
12
+ label: "fieldTypeNumberLabel",
13
+ description: "fieldTypeNumberDescription"
14
+ },
15
+ {
16
+ id: "boolean",
17
+ label: "fieldTypeBooleanLabel",
18
+ description: "fieldTypeBooleanDescription"
19
+ },
20
+ {
21
+ id: "object",
22
+ label: "fieldTypeObjectLabel",
23
+ description: "fieldTypeObjectDescription"
24
+ },
25
+ {
26
+ id: "array",
27
+ label: "fieldTypeArrayLabel",
28
+ description: "fieldTypeArrayDescription"
29
+ }
30
+ ];
31
+ const SchemaTypeSelector = ({ id, value, onChange })=>{
32
+ const t = useTranslation();
33
+ return /*#__PURE__*/ jsx("div", {
34
+ id: id,
35
+ className: "grid grid-cols-1 xs:grid-cols-2 md:grid-cols-3 gap-2",
36
+ children: typeOptions.map((type)=>/*#__PURE__*/ jsxs("button", {
37
+ type: "button",
38
+ title: t[type.description],
39
+ className: cn("p-2.5 rounded-lg border-2 text-left transition-all duration-200", value === type.id ? "border-primary bg-primary/5 shadow-xs" : "border-border hover:border-primary/30 hover:bg-secondary"),
40
+ onClick: ()=>onChange(type.id),
41
+ children: [
42
+ /*#__PURE__*/ jsx("div", {
43
+ className: "font-medium text-sm",
44
+ children: t[type.label]
45
+ }),
46
+ /*#__PURE__*/ jsx("div", {
47
+ className: "text-xs text-muted-foreground line-clamp-1",
48
+ children: t[type.description]
49
+ })
50
+ ]
51
+ }, type.id))
52
+ });
53
+ };
54
+ const SchemaEditor_SchemaTypeSelector = SchemaTypeSelector;
55
+ export { SchemaEditor_SchemaTypeSelector as default };
@@ -0,0 +1,77 @@
1
+ import { jsx, jsxs } from "react/jsx-runtime";
2
+ import { useTranslation } from "../../hooks/use-translation.js";
3
+ import { createFieldSchema, renameObjectProperty, reorderObjectProperty, updateObjectProperty, updatePropertyRequired } from "../../lib/schemaEditor.js";
4
+ import { asObjectSchema, isBooleanSchema } from "../../types/jsonSchema.js";
5
+ import AddFieldButton from "./AddFieldButton.js";
6
+ import SchemaFieldList from "./SchemaFieldList.js";
7
+ const SchemaVisualEditor = ({ schema, onChange, readOnly = false })=>{
8
+ const t = useTranslation();
9
+ const handleAddField = (newField)=>{
10
+ const fieldSchema = createFieldSchema(newField);
11
+ let newSchema = updateObjectProperty(asObjectSchema(schema), newField.name, fieldSchema);
12
+ if (newField.required) newSchema = updatePropertyRequired(newSchema, newField.name, true);
13
+ onChange(newSchema);
14
+ };
15
+ const handleEditField = (name, updatedField)=>{
16
+ const fieldSchema = createFieldSchema(updatedField);
17
+ let newSchema = asObjectSchema(schema);
18
+ if (name !== updatedField.name) {
19
+ newSchema = renameObjectProperty(newSchema, name, updatedField.name);
20
+ newSchema = updateObjectProperty(newSchema, updatedField.name, fieldSchema);
21
+ } else newSchema = updateObjectProperty(newSchema, name, fieldSchema);
22
+ newSchema = updatePropertyRequired(newSchema, updatedField.name, updatedField.required || false);
23
+ onChange(newSchema);
24
+ };
25
+ const handleDeleteField = (name)=>{
26
+ if (isBooleanSchema(schema) || !schema.properties) return;
27
+ const { [name]: _, ...remainingProps } = schema.properties;
28
+ const newSchema = {
29
+ ...schema,
30
+ properties: remainingProps
31
+ };
32
+ if (newSchema.required) newSchema.required = newSchema.required.filter((field)=>field !== name);
33
+ if (newSchema.$propertyOrder) newSchema.$propertyOrder = newSchema.$propertyOrder.filter((field)=>field !== name);
34
+ onChange(newSchema);
35
+ };
36
+ const handleReorderField = (name, direction)=>{
37
+ const newSchema = reorderObjectProperty(asObjectSchema(schema), name, direction);
38
+ onChange(newSchema);
39
+ };
40
+ const hasFields = !isBooleanSchema(schema) && schema.properties && Object.keys(schema.properties).length > 0;
41
+ return /*#__PURE__*/ jsxs("div", {
42
+ className: "p-4 h-full flex flex-col overflow-auto jsonjoy",
43
+ children: [
44
+ !readOnly && /*#__PURE__*/ jsx("div", {
45
+ className: "mb-6 shrink-0",
46
+ children: /*#__PURE__*/ jsx(AddFieldButton, {
47
+ onAddField: handleAddField
48
+ })
49
+ }),
50
+ /*#__PURE__*/ jsx("div", {
51
+ className: "grow overflow-auto",
52
+ children: hasFields ? /*#__PURE__*/ jsx(SchemaFieldList, {
53
+ schema: schema,
54
+ readOnly: readOnly,
55
+ onAddField: handleAddField,
56
+ onEditField: handleEditField,
57
+ onDeleteField: handleDeleteField,
58
+ onReorderField: handleReorderField
59
+ }) : /*#__PURE__*/ jsxs("div", {
60
+ className: "text-center py-10 text-muted-foreground",
61
+ children: [
62
+ /*#__PURE__*/ jsx("p", {
63
+ className: "mb-3",
64
+ children: t.visualEditorNoFieldsHint1
65
+ }),
66
+ /*#__PURE__*/ jsx("p", {
67
+ className: "text-sm",
68
+ children: t.visualEditorNoFieldsHint2
69
+ })
70
+ ]
71
+ })
72
+ })
73
+ ]
74
+ });
75
+ };
76
+ const SchemaEditor_SchemaVisualEditor = SchemaVisualEditor;
77
+ export { SchemaEditor_SchemaVisualEditor as default };
@@ -0,0 +1,72 @@
1
+ import { jsx, jsxs } from "react/jsx-runtime";
2
+ import { Check, ChevronDown } from "lucide-react";
3
+ import { useEffect, useRef, useState } from "react";
4
+ import { useTranslation } from "../../hooks/use-translation.js";
5
+ import { cn, getTypeColor, getTypeLabel } from "../../lib/utils.js";
6
+ const typeOptions = [
7
+ "string",
8
+ "number",
9
+ "boolean",
10
+ "object",
11
+ "array",
12
+ "null"
13
+ ];
14
+ const TypeDropdown = ({ value, onChange, className, readOnly })=>{
15
+ const t = useTranslation();
16
+ const [isOpen, setIsOpen] = useState(false);
17
+ const dropdownRef = useRef(null);
18
+ useEffect(()=>{
19
+ const handleClickOutside = (event)=>{
20
+ if (dropdownRef.current && !dropdownRef.current.contains(event.target)) setIsOpen(false);
21
+ };
22
+ document.addEventListener("mousedown", handleClickOutside);
23
+ return ()=>{
24
+ document.removeEventListener("mousedown", handleClickOutside);
25
+ };
26
+ }, []);
27
+ return /*#__PURE__*/ jsxs("div", {
28
+ className: "relative",
29
+ ref: dropdownRef,
30
+ children: [
31
+ /*#__PURE__*/ jsxs("button", {
32
+ type: "button",
33
+ className: cn("text-xs px-3.5 py-1.5 rounded-md font-medium text-center flex items-center justify-between", getTypeColor(value), "hover:shadow-xs hover:ring-1 hover:ring-ring/30 active:scale-95 transition-all", readOnly ? "" : "w-[92px]", className),
34
+ onClick: ()=>!readOnly && setIsOpen(!isOpen),
35
+ children: [
36
+ /*#__PURE__*/ jsx("span", {
37
+ children: getTypeLabel(t, value)
38
+ }),
39
+ !readOnly && /*#__PURE__*/ jsx(ChevronDown, {
40
+ size: 14,
41
+ className: "ml-1"
42
+ })
43
+ ]
44
+ }),
45
+ isOpen && /*#__PURE__*/ jsx("div", {
46
+ className: "absolute z-50 mt-1 w-[140px] rounded-md border bg-popover shadow-lg animate-in fade-in-50 zoom-in-95",
47
+ children: /*#__PURE__*/ jsx("div", {
48
+ className: "py-1",
49
+ children: typeOptions.map((type)=>/*#__PURE__*/ jsxs("button", {
50
+ type: "button",
51
+ className: cn("w-full text-left px-3 py-1.5 text-xs flex items-center justify-between", "hover:bg-muted/50 transition-colors", value === type && "font-medium"),
52
+ onClick: ()=>{
53
+ onChange(type);
54
+ setIsOpen(false);
55
+ },
56
+ children: [
57
+ /*#__PURE__*/ jsx("span", {
58
+ className: cn("px-2 py-0.5 rounded", getTypeColor(type)),
59
+ children: getTypeLabel(t, type)
60
+ }),
61
+ value === type && /*#__PURE__*/ jsx(Check, {
62
+ size: 14
63
+ })
64
+ ]
65
+ }, type))
66
+ })
67
+ })
68
+ ]
69
+ });
70
+ };
71
+ const SchemaEditor_TypeDropdown = TypeDropdown;
72
+ export { TypeDropdown, SchemaEditor_TypeDropdown as default };
@@ -0,0 +1,71 @@
1
+ import { jsx, jsxs } from "react/jsx-runtime";
2
+ import { Suspense, lazy } from "react";
3
+ import { useTranslation } from "../../hooks/use-translation.js";
4
+ import { withObjectSchema } from "../../types/jsonSchema.js";
5
+ const StringEditor = /*#__PURE__*/ lazy(()=>import("./types/StringEditor.js"));
6
+ const NumberEditor = /*#__PURE__*/ lazy(()=>import("./types/NumberEditor.js"));
7
+ const BooleanEditor = /*#__PURE__*/ lazy(()=>import("./types/BooleanEditor.js"));
8
+ const ObjectEditor = /*#__PURE__*/ lazy(()=>import("./types/ObjectEditor.js"));
9
+ const ArrayEditor = /*#__PURE__*/ lazy(()=>import("./types/ArrayEditor.js"));
10
+ const TypeEditor = ({ schema, validationNode, onChange, depth = 0, readOnly = false, parentSchema, propertyName })=>{
11
+ const t = useTranslation();
12
+ const type = withObjectSchema(schema, (s)=>s.type || "object", "string");
13
+ return /*#__PURE__*/ jsxs(Suspense, {
14
+ fallback: /*#__PURE__*/ jsx("div", {
15
+ children: t.schemaEditorLoading
16
+ }),
17
+ children: [
18
+ "string" === type && /*#__PURE__*/ jsx(StringEditor, {
19
+ readOnly: readOnly,
20
+ schema: schema,
21
+ onChange: onChange,
22
+ depth: depth,
23
+ parentSchema: parentSchema,
24
+ propertyName: propertyName,
25
+ validationNode: validationNode
26
+ }),
27
+ "number" === type && /*#__PURE__*/ jsx(NumberEditor, {
28
+ readOnly: readOnly,
29
+ schema: schema,
30
+ onChange: onChange,
31
+ depth: depth,
32
+ parentSchema: parentSchema,
33
+ propertyName: propertyName,
34
+ validationNode: validationNode
35
+ }),
36
+ "integer" === type && /*#__PURE__*/ jsx(NumberEditor, {
37
+ readOnly: readOnly,
38
+ schema: schema,
39
+ onChange: onChange,
40
+ depth: depth,
41
+ parentSchema: parentSchema,
42
+ propertyName: propertyName,
43
+ validationNode: validationNode,
44
+ integer: true
45
+ }),
46
+ "boolean" === type && /*#__PURE__*/ jsx(BooleanEditor, {
47
+ readOnly: readOnly,
48
+ schema: schema,
49
+ onChange: onChange,
50
+ depth: depth,
51
+ validationNode: validationNode
52
+ }),
53
+ "object" === type && /*#__PURE__*/ jsx(ObjectEditor, {
54
+ readOnly: readOnly,
55
+ schema: schema,
56
+ onChange: onChange,
57
+ depth: depth,
58
+ validationNode: validationNode
59
+ }),
60
+ "array" === type && /*#__PURE__*/ jsx(ArrayEditor, {
61
+ readOnly: readOnly,
62
+ schema: schema,
63
+ onChange: onChange,
64
+ depth: depth,
65
+ validationNode: validationNode
66
+ })
67
+ ]
68
+ });
69
+ };
70
+ const SchemaEditor_TypeEditor = TypeEditor;
71
+ export { SchemaEditor_TypeEditor as default };