json-schema-builder-react 0.0.6 → 0.0.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +66 -2
- package/dist-lib/components/PropertyEditDialog.d.ts +36 -2
- package/dist-lib/hooks/useDialogManager.d.ts +1 -1
- package/dist-lib/index.cjs +1 -1
- package/dist-lib/index.cjs.map +1 -1
- package/dist-lib/index.d.ts +2 -0
- package/dist-lib/index.js +595 -534
- package/dist-lib/index.js.map +1 -1
- package/package.json +12 -13
package/README.md
CHANGED
|
@@ -66,7 +66,7 @@ Add the library to your `tailwind.config.js`:
|
|
|
66
66
|
module.exports = {
|
|
67
67
|
content: [
|
|
68
68
|
'./src/**/*.{js,jsx,ts,tsx}',
|
|
69
|
-
'./node_modules/json-schema-
|
|
69
|
+
'./node_modules/json-schema-builder-react/**/*.{js,jsx}', // Add this line
|
|
70
70
|
],
|
|
71
71
|
theme: {
|
|
72
72
|
extend: {},
|
|
@@ -286,6 +286,55 @@ function App() {
|
|
|
286
286
|
|
|
287
287
|
**⚠️ Warning:** Enabling `keyEditable` allows users to change property keys even after they've been created. This can break existing code that references these keys. Use with caution, primarily in development environments or when you have proper migration strategies in place.
|
|
288
288
|
|
|
289
|
+
### Standalone Property Editor
|
|
290
|
+
|
|
291
|
+
If you only need to edit a single property without the full builder UI, you can use the `PropertyEditDialog` component:
|
|
292
|
+
|
|
293
|
+
```tsx
|
|
294
|
+
import { useState } from 'react';
|
|
295
|
+
import { PropertyEditDialog } from 'json-schema-builder-react';
|
|
296
|
+
import type { PropertyData } from 'json-schema-builder-react';
|
|
297
|
+
|
|
298
|
+
function PropertyEditor() {
|
|
299
|
+
const [isOpen, setIsOpen] = useState(false);
|
|
300
|
+
const [property, setProperty] = useState<PropertyData>({
|
|
301
|
+
id: '1',
|
|
302
|
+
key: 'username',
|
|
303
|
+
title: 'Username',
|
|
304
|
+
type: 'string',
|
|
305
|
+
required: true,
|
|
306
|
+
minLength: 3,
|
|
307
|
+
maxLength: 50,
|
|
308
|
+
});
|
|
309
|
+
|
|
310
|
+
return (
|
|
311
|
+
<>
|
|
312
|
+
<button onClick={() => setIsOpen(true)}>
|
|
313
|
+
Edit Property
|
|
314
|
+
</button>
|
|
315
|
+
|
|
316
|
+
<PropertyEditDialog
|
|
317
|
+
property={property}
|
|
318
|
+
open={isOpen}
|
|
319
|
+
onOpenChange={setIsOpen}
|
|
320
|
+
onSave={(updated) => {
|
|
321
|
+
setProperty(updated);
|
|
322
|
+
// Save to your backend or state management
|
|
323
|
+
console.log('Updated property:', updated);
|
|
324
|
+
}}
|
|
325
|
+
isNewProperty={false}
|
|
326
|
+
showRegex={true}
|
|
327
|
+
typeLabels={{
|
|
328
|
+
string: 'Text',
|
|
329
|
+
number: 'Number',
|
|
330
|
+
boolean: 'Yes/No'
|
|
331
|
+
}}
|
|
332
|
+
/>
|
|
333
|
+
</>
|
|
334
|
+
);
|
|
335
|
+
}
|
|
336
|
+
```
|
|
337
|
+
|
|
289
338
|
## API Reference
|
|
290
339
|
|
|
291
340
|
### JsonSchemaBuilder Props
|
|
@@ -306,6 +355,21 @@ function App() {
|
|
|
306
355
|
| `typeLabels` | `TypeLabels` | Default labels | Custom labels for property types |
|
|
307
356
|
| `propertyLabel` | `{ singular: string, plural: string }` | `{ singular: 'property', plural: 'properties' }` | Custom labels for properties |
|
|
308
357
|
|
|
358
|
+
### PropertyEditDialog Props
|
|
359
|
+
|
|
360
|
+
| Prop | Type | Default | Description |
|
|
361
|
+
|------|------|---------|-------------|
|
|
362
|
+
| `property` | `PropertyData` | **Required** | The property object to edit |
|
|
363
|
+
| `open` | `boolean` | **Required** | Whether the dialog is open |
|
|
364
|
+
| `onOpenChange` | `(open: boolean) => void` | **Required** | Callback when dialog open state changes |
|
|
365
|
+
| `onSave` | `(property: PropertyData) => void` | **Required** | Callback when property is saved |
|
|
366
|
+
| `isArrayItem` | `boolean` | `false` | Whether this property is an array item |
|
|
367
|
+
| `isNewProperty` | `boolean` | `false` | Whether this is a new property (affects key editing) |
|
|
368
|
+
| `propertyLabel` | `{ singular: string, plural: string }` | `{ singular: 'Property', plural: 'Properties' }` | Custom labels |
|
|
369
|
+
| `showRegex` | `boolean` | `false` | Show regex pattern field for strings |
|
|
370
|
+
| `keyEditable` | `boolean` | `false` | Allow editing property key |
|
|
371
|
+
| `typeLabels` | `TypeLabels` | Default labels | Custom labels for property types |
|
|
372
|
+
|
|
309
373
|
### Customizing Type Labels
|
|
310
374
|
|
|
311
375
|
You can customize how property types are displayed to your users:
|
|
@@ -452,7 +516,7 @@ And verify your `tailwind.config.js` includes the library path:
|
|
|
452
516
|
module.exports = {
|
|
453
517
|
content: [
|
|
454
518
|
'./src/**/*.{js,jsx,ts,tsx}',
|
|
455
|
-
'./node_modules/json-schema-
|
|
519
|
+
'./node_modules/json-schema-builder-react/**/*.{js,jsx}',
|
|
456
520
|
],
|
|
457
521
|
// ...
|
|
458
522
|
};
|
|
@@ -1,9 +1,42 @@
|
|
|
1
1
|
import type { PropertyData } from "@/types/schema";
|
|
2
|
+
import type { TypeLabels } from "@/contexts/TypeLabelsContext";
|
|
3
|
+
/**
|
|
4
|
+
* PropertyEditDialog - A standalone dialog for editing a single JSON schema property
|
|
5
|
+
*
|
|
6
|
+
* @example
|
|
7
|
+
* ```tsx
|
|
8
|
+
* import { PropertyEditDialog } from 'json-schema-builder-react';
|
|
9
|
+
*
|
|
10
|
+
* function MyApp() {
|
|
11
|
+
* const [isOpen, setIsOpen] = useState(false);
|
|
12
|
+
* const [property, setProperty] = useState({
|
|
13
|
+
* id: '1',
|
|
14
|
+
* key: 'username',
|
|
15
|
+
* title: 'Username',
|
|
16
|
+
* type: 'string',
|
|
17
|
+
* required: true,
|
|
18
|
+
* });
|
|
19
|
+
*
|
|
20
|
+
* return (
|
|
21
|
+
* <PropertyEditDialog
|
|
22
|
+
* property={property}
|
|
23
|
+
* open={isOpen}
|
|
24
|
+
* onOpenChange={setIsOpen}
|
|
25
|
+
* onSave={(updated) => {
|
|
26
|
+
* setProperty(updated);
|
|
27
|
+
* setIsOpen(false);
|
|
28
|
+
* }}
|
|
29
|
+
* typeLabels={{ string: 'Text', number: 'Number' }}
|
|
30
|
+
* />
|
|
31
|
+
* );
|
|
32
|
+
* }
|
|
33
|
+
* ```
|
|
34
|
+
*/
|
|
2
35
|
interface PropertyEditDialogProps {
|
|
3
36
|
property: PropertyData;
|
|
4
37
|
open: boolean;
|
|
5
38
|
onOpenChange: (open: boolean) => void;
|
|
6
|
-
|
|
39
|
+
onSave: (property: PropertyData) => void;
|
|
7
40
|
isArrayItem?: boolean;
|
|
8
41
|
isNewProperty?: boolean;
|
|
9
42
|
propertyLabel?: {
|
|
@@ -12,6 +45,7 @@ interface PropertyEditDialogProps {
|
|
|
12
45
|
};
|
|
13
46
|
showRegex?: boolean;
|
|
14
47
|
keyEditable?: boolean;
|
|
48
|
+
typeLabels?: TypeLabels;
|
|
15
49
|
}
|
|
16
|
-
export default function PropertyEditDialog({ property, open, onOpenChange,
|
|
50
|
+
export default function PropertyEditDialog({ property, open, onOpenChange, onSave, isArrayItem, isNewProperty, propertyLabel, showRegex, keyEditable, typeLabels: customTypeLabels, }: PropertyEditDialogProps): import("react/jsx-runtime").JSX.Element;
|
|
17
51
|
export {};
|
package/dist-lib/index.cjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("react/jsx-runtime"),j=require("react"),ge=require("@radix-ui/react-slot"),ae=require("class-variance-authority"),je=require("clsx"),ve=require("tailwind-merge"),u=require("lucide-react"),ye=require("@radix-ui/react-tooltip"),be=require("@radix-ui/react-select"),Ne=require("@radix-ui/react-dialog"),we=require("@radix-ui/react-label"),Ce=require("@radix-ui/react-checkbox");function F(t){const a=Object.create(null,{[Symbol.toStringTag]:{value:"Module"}});if(t){for(const s in t)if(s!=="default"){const r=Object.getOwnPropertyDescriptor(t,s);Object.defineProperty(a,s,r.get?r:{enumerable:!0,get:()=>t[s]})}}return a.default=t,Object.freeze(a)}const v=F(j),E=F(ye),w=F(be),L=F(Ne),ie=F(we),K=F(Ce);function f(...t){return ve.twMerge(je.clsx(t))}const ke=ae.cva("inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-full text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0",{variants:{variant:{default:"bg-primary text-primary-foreground hover:bg-primary/90",destructive:"bg-destructive text-destructive-foreground hover:bg-destructive/90",outline:"border border-input bg-background hover:bg-accent hover:text-accent-foreground",secondary:"bg-secondary text-secondary-foreground hover:bg-secondary/80",ghost:"hover:bg-accent hover:text-accent-foreground",link:"text-primary underline-offset-4 hover:underline"},size:{default:"h-9 px-4 py-2",sm:"h-8 rounded-full px-3 text-xs",lg:"h-10 rounded-full px-8",icon:"h-9 w-9"}},defaultVariants:{variant:"default",size:"default"}}),I=v.forwardRef(({className:t,variant:a,size:s,asChild:r=!1,...i},l)=>{const n=r?ge.Slot:"button";return e.jsx(n,{className:f(ke({variant:a,size:s,className:t})),ref:l,...i})});I.displayName="Button";const D=v.forwardRef(({className:t,type:a,...s},r)=>e.jsx("input",{type:a,className:f("flex h-9 w-full rounded-md border border-input bg-transparent px-3 py-1 text-base shadow-sm transition-colors file:border-0 file:bg-transparent file:text-sm file:font-medium file:text-foreground placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50 md:text-sm",t),ref:r,...s}));D.displayName="Input";const Se=E.Provider,Ie=E.Root,Te=E.Trigger,ne=v.forwardRef(({className:t,sideOffset:a=4,...s},r)=>e.jsx(E.Portal,{children:e.jsx(E.Content,{ref:r,sideOffset:a,className:f("z-50 overflow-hidden rounded-md bg-popover px-3 py-1.5 text-xs text-popover-foreground animate-in fade-in-0 zoom-in-95 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 origin-[--radix-tooltip-content-transform-origin]",t),...s})}));ne.displayName=E.Content.displayName;const J=w.Root,V=w.Value,M=v.forwardRef(({className:t,children:a,...s},r)=>e.jsxs(w.Trigger,{ref:r,className:f("flex h-9 w-full items-center justify-between whitespace-nowrap rounded-md border border-input bg-transparent px-3 py-2 text-sm shadow-sm ring-offset-background data-[placeholder]:text-muted-foreground focus:outline-none focus:ring-1 focus:ring-ring disabled:cursor-not-allowed disabled:opacity-50 [&>span]:line-clamp-1",t),...s,children:[a,e.jsx(w.Icon,{asChild:!0,children:e.jsx(u.ChevronDown,{className:"h-4 w-4 opacity-50"})})]}));M.displayName=w.Trigger.displayName;const re=v.forwardRef(({className:t,...a},s)=>e.jsx(w.ScrollUpButton,{ref:s,className:f("flex cursor-default items-center justify-center py-1",t),...a,children:e.jsx(u.ChevronUp,{className:"h-4 w-4"})}));re.displayName=w.ScrollUpButton.displayName;const le=v.forwardRef(({className:t,...a},s)=>e.jsx(w.ScrollDownButton,{ref:s,className:f("flex cursor-default items-center justify-center py-1",t),...a,children:e.jsx(u.ChevronDown,{className:"h-4 w-4"})}));le.displayName=w.ScrollDownButton.displayName;const _=v.forwardRef(({className:t,children:a,position:s="popper",...r},i)=>e.jsx(w.Portal,{children:e.jsxs(w.Content,{ref:i,className:f("relative z-50 max-h-[--radix-select-content-available-height] min-w-[8rem] overflow-y-auto overflow-x-hidden rounded-md border bg-popover text-popover-foreground shadow-md data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 origin-[--radix-select-content-transform-origin]",s==="popper"&&"data-[side=bottom]:translate-y-1 data-[side=left]:-translate-x-1 data-[side=right]:translate-x-1 data-[side=top]:-translate-y-1",t),position:s,...r,children:[e.jsx(re,{}),e.jsx(w.Viewport,{className:f("p-1",s==="popper"&&"h-[var(--radix-select-trigger-height)] w-full min-w-[var(--radix-select-trigger-width)]"),children:a}),e.jsx(le,{})]})}));_.displayName=w.Content.displayName;const De=v.forwardRef(({className:t,...a},s)=>e.jsx(w.Label,{ref:s,className:f("px-2 py-1.5 text-sm font-semibold",t),...a}));De.displayName=w.Label.displayName;const k=v.forwardRef(({className:t,children:a,...s},r)=>e.jsxs(w.Item,{ref:r,className:f("relative flex w-full cursor-default select-none items-center rounded-sm py-1.5 pl-2 pr-8 text-sm outline-none focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50",t),...s,children:[e.jsx("span",{className:"absolute right-2 flex h-3.5 w-3.5 items-center justify-center",children:e.jsx(w.ItemIndicator,{children:e.jsx(u.Check,{className:"h-4 w-4"})})}),e.jsx(w.ItemText,{children:a})]}));k.displayName=w.Item.displayName;const qe=v.forwardRef(({className:t,...a},s)=>e.jsx(w.Separator,{ref:s,className:f("-mx-1 my-1 h-px bg-muted",t),...a}));qe.displayName=w.Separator.displayName;const Pe=L.Root,Oe=L.Portal,de=v.forwardRef(({className:t,...a},s)=>e.jsx(L.Overlay,{ref:s,className:f("fixed inset-0 z-50 bg-black/80 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0",t),...a}));de.displayName=L.Overlay.displayName;const oe=v.forwardRef(({className:t,children:a,...s},r)=>e.jsxs(Oe,{children:[e.jsx(de,{}),e.jsxs(L.Content,{ref:r,className:f("fixed left-[50%] top-[50%] z-50 grid w-full max-w-lg translate-x-[-50%] translate-y-[-50%] gap-4 border bg-background p-6 shadow-lg duration-200 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[state=closed]:slide-out-to-left-1/2 data-[state=closed]:slide-out-to-top-[48%] data-[state=open]:slide-in-from-left-1/2 data-[state=open]:slide-in-from-top-[48%] sm:rounded-lg",t),...s,children:[a,e.jsxs(L.Close,{className:"absolute right-4 top-4 rounded-sm opacity-70 ring-offset-background transition-opacity hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:pointer-events-none data-[state=open]:bg-accent data-[state=open]:text-muted-foreground",children:[e.jsx(u.X,{className:"h-4 w-4"}),e.jsx("span",{className:"sr-only",children:"Close"})]})]})]}));oe.displayName=L.Content.displayName;const ce=({className:t,...a})=>e.jsx("div",{className:f("flex flex-col space-y-1.5 text-center sm:text-left",t),...a});ce.displayName="DialogHeader";const me=({className:t,...a})=>e.jsx("div",{className:f("flex flex-col-reverse sm:flex-row sm:justify-end sm:space-x-2",t),...a});me.displayName="DialogFooter";const ue=v.forwardRef(({className:t,...a},s)=>e.jsx(L.Title,{ref:s,className:f("text-lg font-semibold leading-none tracking-tight",t),...a}));ue.displayName=L.Title.displayName;const Le=v.forwardRef(({className:t,...a},s)=>e.jsx(L.Description,{ref:s,className:f("text-sm text-muted-foreground",t),...a}));Le.displayName=L.Description.displayName;const Re=ae.cva("text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70"),N=v.forwardRef(({className:t,...a},s)=>e.jsx(ie.Root,{ref:s,className:f(Re(),t),...a}));N.displayName=ie.Root.displayName;const H=v.forwardRef(({className:t,...a},s)=>e.jsx(K.Root,{ref:s,className:f("grid place-content-center peer h-4 w-4 shrink-0 rounded-sm border border-primary shadow focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50 data-[state=checked]:bg-primary data-[state=checked]:text-primary-foreground",t),...a,children:e.jsx(K.Indicator,{className:f("grid place-content-center text-current"),children:e.jsx(u.Check,{className:"h-4 w-4"})})}));H.displayName=K.Root.displayName;const Y=v.forwardRef(({className:t,...a},s)=>e.jsx("textarea",{className:f("flex min-h-[60px] w-full rounded-md border border-input bg-transparent px-3 py-2 text-base shadow-sm placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50 md:text-sm",t),ref:s,...a}));Y.displayName="Textarea";const Ee=t=>t.trim().toLowerCase().replace(/[^\w\s]/g,"").replace(/\s+/g,"_"),Fe=(t,a,s=!1,r=!1)=>{const i=(o,d)=>{a({...t,[o]:d})};return{handleTitleChange:o=>{i("title",o)},handleTitleBlur:()=>{if(s&&t.title){const o=Ee(t.title);i("key",o)}},handleKeyChange:o=>{(s||r)&&i("key",o)},handleFieldChange:i,handleConstraintChange:(o,d)=>{a({...t,[o]:d})}}},U={string:"String",number:"Number",integer:"Integer",boolean:"Boolean",object:"Object",array:"Array",null:"Null",file:"File"},he=j.createContext({getTypeLabel:t=>U[t],typeLabels:U});function ze({children:t,customLabels:a={}}){const s={...U,...a},r=i=>s[i]||i;return e.jsx(he.Provider,{value:{getTypeLabel:r,typeLabels:s},children:t})}function xe(){return j.useContext(he)}function X({property:t,open:a,onOpenChange:s,onUpdate:r,isArrayItem:i=!1,isNewProperty:l=!1,propertyLabel:n={singular:"Property",plural:"Properties"},showRegex:m=!1,keyEditable:C=!1}){var O;const{typeLabels:o}=xe(),[d,g]=j.useState(t);j.useEffect(()=>{a&&g(t)},[t,a]);const{handleTitleChange:y,handleTitleBlur:p,handleKeyChange:x,handleFieldChange:S,handleConstraintChange:b}=Fe(d,g,l,C),P=()=>{var c;(c=d.title)!=null&&c.trim()&&(r(d),s(!1))},h=()=>{g(t),s(!1)};return e.jsx(Pe,{open:a,onOpenChange:s,children:e.jsxs(oe,{className:"max-w-2xl max-h-[80vh] flex flex-col gap-0 p-0","data-testid":"dialog-edit-property",children:[e.jsx(ce,{className:"px-6 pt-6 pb-4 shrink-0",children:e.jsx(ue,{children:l?`Add ${n.singular}`:`Edit ${n.singular}`})}),e.jsxs("div",{className:"space-y-6 px-6 pb-4 overflow-y-auto flex-1 min-h-0",children:[e.jsxs("div",{className:"space-y-2",children:[e.jsxs(N,{className:"flex items-center gap-1.5",children:[e.jsx("span",{className:"w-1.5 h-1.5 rounded-full bg-red-500"}),"Type"]}),e.jsxs(J,{value:d.type,onValueChange:c=>S("type",c),"data-testid":"select-type-dialog",children:[e.jsx(M,{children:e.jsx(V,{})}),e.jsxs(_,{children:[e.jsx(k,{value:"string",children:o.string}),e.jsx(k,{value:"number",children:o.number}),e.jsx(k,{value:"integer",children:o.integer}),e.jsx(k,{value:"boolean",children:o.boolean}),e.jsx(k,{value:"object",children:o.object}),e.jsx(k,{value:"array",children:o.array}),e.jsx(k,{value:"file",children:o.file}),e.jsx(k,{value:"null",children:o.null})]})]})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsxs(N,{className:"flex items-center gap-1.5",children:[e.jsx("span",{className:"w-1.5 h-1.5 rounded-full bg-red-500"}),"Title"]}),e.jsx(D,{value:d.title||"",onChange:c=>y(c.target.value),onBlur:p,placeholder:"Property Title","data-testid":"input-title-dialog",required:!0}),!l&&d.key&&e.jsxs("p",{className:"text-xs text-muted-foreground font-mono",children:["Key: ",d.key]})]}),(l||C)&&e.jsxs("div",{className:"space-y-2",children:[e.jsx(N,{children:"Key"}),e.jsx(D,{value:d.key,onChange:c=>x(c.target.value),placeholder:"property_key","data-testid":"input-key-dialog"}),!l&&e.jsx("p",{className:"text-xs text-yellow-600 dark:text-yellow-500",children:"⚠️ Changing the key may break existing references to this property"})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx(N,{children:"Description"}),e.jsx(Y,{placeholder:"Optional description",value:d.description||"",onChange:c=>S("description",c.target.value),rows:2,"data-testid":"input-edit-description"})]}),d.type==="array"&&e.jsxs("div",{className:"space-y-2 border-l-2 border-border pl-4 mt-2",children:[e.jsxs(N,{className:"font-semibold text-xs text-muted-foreground",children:[o.array," Items"]}),d.items?e.jsxs("div",{className:"bg-muted/40 p-2 rounded",children:[e.jsxs("div",{className:"space-y-2",children:[e.jsx(N,{children:"Item Type"}),e.jsxs(J,{value:d.items.type,onValueChange:c=>g({...d,items:{...d.items,type:c}}),children:[e.jsx(M,{children:e.jsx(V,{})}),e.jsxs(_,{children:[e.jsx(k,{value:"string",children:o.string}),e.jsx(k,{value:"number",children:o.number}),e.jsx(k,{value:"integer",children:o.integer}),e.jsx(k,{value:"boolean",children:o.boolean}),e.jsx(k,{value:"object",children:o.object}),e.jsx(k,{value:"array",children:o.array}),e.jsx(k,{value:"file",children:o.file}),e.jsx(k,{value:"null",children:o.null})]})]})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx(N,{children:"Item Title"}),e.jsx(D,{value:d.items.title||"",onChange:c=>g({...d,items:{...d.items,title:c.target.value}}),placeholder:"Item Title"})]}),e.jsxs(I,{variant:"ghost",size:"sm",className:"mt-2",onClick:()=>g({...d,items:void 0}),children:["Remove ",o.array," Item Schema"]})]}):e.jsxs(I,{variant:"outline",size:"sm",onClick:()=>{g({...d,items:{id:Date.now().toString()+Math.random(),key:"item",type:"string",required:!1}})},children:["Add ",o.array," Item Schema"]})]}),!i&&e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(H,{id:"prop-required",checked:d.required,onCheckedChange:c=>S("required",c),"data-testid":"checkbox-edit-required"}),e.jsx(N,{htmlFor:"prop-required",className:"cursor-pointer",children:"Required field"})]}),d.type==="string"&&e.jsxs("details",{className:"border rounded-md",children:[e.jsx("summary",{className:"p-4 cursor-pointer hover:bg-accent/50 transition-colors",children:e.jsxs("h4",{className:"text-sm font-medium inline",children:[o.string," Constraints"]})}),e.jsxs("div",{className:"space-y-4 p-4 pt-0",children:[e.jsxs("div",{className:"grid grid-cols-2 gap-4",children:[e.jsxs("div",{className:"space-y-2",children:[e.jsx(N,{htmlFor:"min-length",children:"Minimum Length"}),e.jsx(D,{id:"min-length",type:"number",placeholder:"0",value:d.minLength||"",onChange:c=>b("minLength",c.target.value?parseInt(c.target.value):void 0),"data-testid":"input-edit-minlength"})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx(N,{htmlFor:"max-length",children:"Maximum Length"}),e.jsx(D,{id:"max-length",type:"number",placeholder:"∞",value:d.maxLength||"",onChange:c=>b("maxLength",c.target.value?parseInt(c.target.value):void 0),"data-testid":"input-edit-maxlength"})]})]}),m&&e.jsxs("div",{className:"space-y-2",children:[e.jsx(N,{htmlFor:"pattern",children:"Pattern (regex)"}),e.jsx(D,{id:"pattern",placeholder:"^[a-z]+$",value:d.pattern||"",onChange:c=>b("pattern",c.target.value),className:"font-mono text-sm","data-testid":"input-edit-pattern"})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx(N,{children:"Enum Values"}),e.jsx("div",{className:"space-y-2",children:[...d.enum||[],""].map((c,q)=>{var B;return e.jsx(D,{placeholder:q===(((B=d.enum)==null?void 0:B.length)||0)?"Add new value...":"Enum value",value:c,onChange:$=>{const T=$.target.value,R=d.enum||[];if(q===R.length)T.trim()&&b("enum",[...R,T.trim()]);else if(T.trim()){const z=[...R];z[q]=T.trim(),b("enum",z)}else{const z=R.filter((Ye,pe)=>pe!==q);b("enum",z.length>0?z:void 0)}},"data-testid":`input-edit-enum-${q}`},q)})}),e.jsx("p",{className:"text-xs text-muted-foreground",children:"Enter allowed values (empty fields will be removed)"})]})]})]}),(d.type==="number"||d.type==="integer")&&e.jsxs("details",{className:"border rounded-md",children:[e.jsx("summary",{className:"p-4 cursor-pointer hover:bg-accent/50 transition-colors",children:e.jsx("h4",{className:"text-sm font-medium inline",children:"Numeric Constraints"})}),e.jsx("div",{className:"space-y-4 p-4 pt-0",children:e.jsxs("div",{className:"grid grid-cols-2 gap-4",children:[e.jsxs("div",{className:"space-y-2",children:[e.jsx(N,{htmlFor:"minimum",children:"Minimum Value"}),e.jsx(D,{id:"minimum",type:"number",placeholder:"-∞",value:d.minimum??"",onChange:c=>b("minimum",c.target.value?parseFloat(c.target.value):void 0),"data-testid":"input-edit-minimum"})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx(N,{htmlFor:"maximum",children:"Maximum Value"}),e.jsx(D,{id:"maximum",type:"number",placeholder:"∞",value:d.maximum??"",onChange:c=>b("maximum",c.target.value?parseFloat(c.target.value):void 0),"data-testid":"input-edit-maximum"})]})]})})]}),d.type==="array"&&e.jsxs("details",{className:"border rounded-md",children:[e.jsx("summary",{className:"p-4 cursor-pointer hover:bg-accent/50 transition-colors",children:e.jsxs("h4",{className:"text-sm font-medium inline",children:[o.array," Constraints"]})}),e.jsxs("div",{className:"space-y-4 p-4 pt-0",children:[e.jsxs("div",{className:"grid grid-cols-2 gap-4",children:[e.jsxs("div",{className:"space-y-2",children:[e.jsx(N,{htmlFor:"min-items",children:"Minimum Items"}),e.jsx(D,{id:"min-items",type:"number",placeholder:"0",value:d.minItems||"",onChange:c=>b("minItems",c.target.value?parseInt(c.target.value):void 0),"data-testid":"input-edit-minitems"})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx(N,{htmlFor:"max-items",children:"Maximum Items"}),e.jsx(D,{id:"max-items",type:"number",placeholder:"∞",value:d.maxItems||"",onChange:c=>b("maxItems",c.target.value?parseInt(c.target.value):void 0),"data-testid":"input-edit-maxitems"})]})]}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(H,{id:"unique-items",checked:d.uniqueItems||!1,onCheckedChange:c=>b("uniqueItems",c),"data-testid":"checkbox-edit-unique"}),e.jsx(N,{htmlFor:"unique-items",className:"cursor-pointer",children:"All items must be unique"})]})]})]})]}),e.jsxs(me,{className:"px-6 py-4 border-t bg-background shrink-0",children:[e.jsx(I,{variant:"outline",onClick:h,"data-testid":"button-cancel",children:"Cancel"}),e.jsx(I,{onClick:P,"data-testid":"button-save",disabled:!((O=d.title)!=null&&O.trim()),children:"Save Changes"})]})]})})}function se(t,a,s={}){const{allowEmpty:r=!1,onEditStart:i,onEditCancel:l}=s,[n,m]=j.useState(!1),[C,o]=j.useState(t);j.useEffect(()=>{n||o(t)},[t,n]);const d=()=>{o(t),m(!0),i==null||i()},g=x=>{o(x)},y=()=>{const x=C.trim();if(!r&&!x){o(t),m(!1);return}x!==t&&a(x),m(!1)};return{isEditing:n,value:C,startEdit:d,handleChange:g,handleBlur:y,handleKeyDown:x=>{x.key==="Enter"?y():x.key==="Escape"&&(o(t),m(!1),l==null||l())}}}function Be(t,a){const[s,r]=j.useState(!1);return{isChangingType:s,setIsChangingType:r,handleTypeChange:n=>{const m={...t,type:n};n!=="string"&&(delete m.minLength,delete m.maxLength,delete m.pattern,delete m.enum),n!=="number"&&n!=="integer"&&(delete m.minimum,delete m.maximum),n!=="array"&&(delete m.minItems,delete m.maxItems,delete m.uniqueItems,delete m.items),n!=="object"&&delete m.children,a(m),r(!1)},availableTypes:["string","number","integer","boolean","object","array","file"]}}const Z=()=>`${Date.now()}-${Math.random()}`;function ee(t={}){const{onConfirm:a,onCancel:s,createInitialData:r}=t,[i,l]=j.useState(!1),[n,m]=j.useState(null),C=y=>{const p=y??(r?r():null);m(p),l(!0)},o=()=>{l(!1),m(null),s==null||s()};return{isOpen:i,data:n,open:C,close:o,confirm:y=>{a==null||a(y),l(!1),m(null)},setIsOpen:y=>{y?l(!0):o()}}}function Ae(t,a){const s=ee({createInitialData:()=>({id:Z(),key:"",type:"string",required:!1}),onConfirm:l=>{a({...t,children:[...t.children||[],l]})}});return{addChild:()=>s.open(),updateChild:(l,n)=>{const m=t.children.map(C=>C.id===l?n:C);a({...t,children:m})},deleteChild:l=>{const n=t.children.filter(m=>m.id!==l);a({...t,children:n})},addChildDialog:{isOpen:s.isOpen,data:s.data,setIsOpen:s.setIsOpen,confirm:s.confirm}}}function G({property:t,onUpdate:a,onDelete:s,level:r=1,isArrayItem:i=!1,showRegex:l=!1,keyEditable:n=!1}){const{getTypeLabel:m,typeLabels:C}=xe(),o=ee(),d=se(t.title||t.key||"",h=>a({...t,title:h}),{allowEmpty:!1}),g=se(t.description||"",h=>a({...t,description:h||void 0}),{allowEmpty:!0}),y=Be(t,a),p=Ae(t,a),x=`h${Math.min(r,6)}`,S=t.type==="object",b=S&&t.children&&t.children.length>0,P={1:"text-lg font-semibold",2:"text-base",3:"text-base",4:"text-base",5:"text-sm",6:"text-sm"}[r]||"text-sm";return e.jsxs("div",{className:"group",children:[e.jsxs("div",{className:"flex gap-4 items-center rounded-md -mx-2 px-2 py-1 transition-colors hover:bg-accent/50",children:[e.jsx("div",{className:"flex-1 min-w-0",children:e.jsxs("div",{className:"flex items-start gap-3",children:[!i&&e.jsx("button",{onClick:()=>a({...t,required:!t.required}),className:"shrink-0 transition-all hover:scale-110 mt-0.5",title:t.required?"Required field - click to make optional":"Optional field - click to make required",children:t.required?e.jsx("span",{className:"block w-4 h-4 rounded-full bg-primary"}):e.jsx("span",{className:"block w-4 h-4 rounded-full border border-dashed border-gray-400"})}),d.isEditing?e.jsx(D,{value:d.value,onChange:h=>d.handleChange(h.target.value),onBlur:d.handleBlur,onKeyDown:d.handleKeyDown,autoFocus:!0,className:P,placeholder:"Enter title"}):e.jsxs("div",{className:"flex gap-2 flex-wrap flex-1",children:[e.jsxs("div",{className:"flex items-start gap-2",children:[e.jsx(x,{className:`${P} cursor-pointer hover:text-primary transition-colors leading-none`,onClick:d.startEdit,children:t.title||t.key||e.jsx("span",{className:"text-muted-foreground italic",children:"unnamed"})}),y.isChangingType?e.jsxs(J,{value:t.type,onValueChange:h=>y.handleTypeChange(h),open:y.isChangingType,onOpenChange:y.setIsChangingType,children:[e.jsx(M,{className:"w-[140px] h-7",children:e.jsx(V,{})}),e.jsx(_,{children:y.availableTypes.map(h=>e.jsx(k,{value:h,children:C[h]},h))})]}):e.jsx(Se,{children:e.jsxs(Ie,{children:[e.jsx(Te,{asChild:!0,children:e.jsxs("button",{onClick:()=>y.setIsChangingType(!0),className:"cursor-pointer hover:bg-accent rounded p-0.5 transition-colors",children:[t.type==="string"&&e.jsx(u.Type,{className:"w-5 h-5 text-muted-foreground"}),t.type==="number"&&e.jsx(u.Hash,{className:"w-5 h-5 text-muted-foreground"}),t.type==="integer"&&e.jsx(u.Hash,{className:"w-5 h-5 text-muted-foreground"}),t.type==="boolean"&&e.jsx(u.CheckSquare,{className:"w-5 h-5 text-muted-foreground"}),t.type==="object"&&e.jsx(u.Braces,{className:"w-5 h-5 text-muted-foreground"}),t.type==="array"&&e.jsx(u.List,{className:"w-5 h-5 text-muted-foreground"}),t.type==="file"&&e.jsx(u.FileText,{className:"w-5 h-5 text-muted-foreground"})]})}),e.jsxs(ne,{children:[m(t.type),t.type==="array"&&t.items?` of ${m(t.items.type)}`:"",e.jsx("div",{className:"text-xs text-muted-foreground mt-1",children:"Click to change type"})]})]})}),t.type==="object"&&e.jsx(I,{variant:"ghost",size:"icon",className:"opacity-0 group-hover:opacity-100 h-6 w-6",onClick:p.addChild,"data-testid":`button-add-child-${t.id}`,children:e.jsx(u.Plus,{className:"!w-5 !h-5"})})]}),e.jsx("div",{className:"flex-1",children:g.isEditing?e.jsx(D,{value:g.value,onChange:h=>g.handleChange(h.target.value),onBlur:g.handleBlur,onKeyDown:g.handleKeyDown,autoFocus:!0,className:"text-sm flex-1",placeholder:"Enter description"}):e.jsx(e.Fragment,{children:t.description?e.jsx("p",{className:"text-sm text-muted-foreground flex-1 min-w-[200px] cursor-pointer hover:text-foreground transition-colors","data-testid":`text-description-${t.id}`,onClick:g.startEdit,children:t.description}):e.jsx("p",{className:"text-sm text-muted-foreground/50 flex-1 min-w-[200px] cursor-pointer hover:text-muted-foreground italic transition-colors",onClick:g.startEdit,children:"Add description..."})})})]})]})}),e.jsxs("div",{className:"flex items-center gap-1 opacity-0 group-hover:opacity-100 transition-opacity shrink-0",children:[e.jsx(I,{variant:"ghost",size:"icon",className:"h-7 w-7",onClick:()=>o.open(t),"data-testid":`button-edit-${t.id}`,children:e.jsx(u.Pencil,{className:"w-3 h-3"})}),S&&t.type!=="object"&&e.jsx(I,{variant:"ghost",size:"icon",className:"h-7 w-7",onClick:p.addChild,"data-testid":`button-add-child-${t.id}`,children:e.jsx(u.Plus,{className:"w-3 h-3"})}),e.jsx(I,{variant:"ghost",size:"icon",className:"h-7 w-7 text-muted-foreground hover:text-destructive",onClick:s,"data-testid":`button-delete-${t.id}`,children:e.jsx(u.Trash2,{className:"w-3 h-3"})})]})]}),b&&e.jsx("div",{className:r===1?"ml-6 mt-1 border-l-2 border-border pl-6":"ml-4 mt-1 border-l border-border pl-4",children:t.children.map(h=>e.jsx(G,{property:h,onUpdate:O=>p.updateChild(h.id,O),onDelete:()=>p.deleteChild(h.id),level:r+1,showRegex:l,keyEditable:n},h.id))}),t.type==="array"&&t.items&&e.jsxs("div",{className:r===1?"ml-6 mt-1 border-l-2 border-border pl-6":"ml-4 mt-1 border-l border-border pl-4",children:[e.jsxs("div",{className:"mb-2 text-xs text-muted-foreground font-semibold uppercase",children:[m("array")," Items"]}),e.jsx(G,{property:t.items,onUpdate:h=>a({...t,items:h}),onDelete:()=>a({...t,items:void 0}),level:r+1,isArrayItem:!0,showRegex:l,keyEditable:n})]}),e.jsx(X,{property:o.data||t,open:o.isOpen,onOpenChange:o.setIsOpen,onUpdate:h=>{a(h),o.close()},isArrayItem:i,isNewProperty:!1,showRegex:l,keyEditable:n}),p.addChildDialog.isOpen&&p.addChildDialog.data&&e.jsx(X,{property:p.addChildDialog.data,open:p.addChildDialog.isOpen,isNewProperty:!0,onOpenChange:p.addChildDialog.setIsOpen,onUpdate:p.addChildDialog.confirm,showRegex:l,keyEditable:n})]})}const te=v.forwardRef(({className:t,...a},s)=>e.jsx("div",{ref:s,className:f("rounded-xl border bg-card text-card-foreground shadow",t),...a}));te.displayName="Card";const Me=v.forwardRef(({className:t,...a},s)=>e.jsx("div",{ref:s,className:f("flex flex-col space-y-1.5 p-6",t),...a}));Me.displayName="CardHeader";const _e=v.forwardRef(({className:t,...a},s)=>e.jsx("div",{ref:s,className:f("font-semibold leading-none tracking-tight",t),...a}));_e.displayName="CardTitle";const $e=v.forwardRef(({className:t,...a},s)=>e.jsx("div",{ref:s,className:f("text-sm text-muted-foreground",t),...a}));$e.displayName="CardDescription";const Ke=v.forwardRef(({className:t,...a},s)=>e.jsx("div",{ref:s,className:f("p-6 pt-0",t),...a}));Ke.displayName="CardContent";const Je=v.forwardRef(({className:t,...a},s)=>e.jsx("div",{ref:s,className:f("flex items-center p-6 pt-0",t),...a}));Je.displayName="CardFooter";const Ve=()=>new Promise((t,a)=>{const s=document.createElement("input");s.type="file",s.accept=".json",s.onchange=r=>{var n;const i=(n=r.target.files)==null?void 0:n[0];if(!i){a(new Error("No file selected"));return}const l=new FileReader;l.onload=m=>{var C;try{const o=JSON.parse((C=m.target)==null?void 0:C.result);t(o)}catch{a(new Error("Invalid JSON file"))}},l.onerror=()=>a(new Error("Failed to read file")),l.readAsText(i)},s.click()}),fe=(t,a="schema.json")=>{const s=JSON.stringify(t,null,2),r=new Blob([s],{type:"application/json"}),i=URL.createObjectURL(r),l=document.createElement("a");l.href=i,l.download=a,document.body.appendChild(l),l.click(),document.body.removeChild(l),URL.revokeObjectURL(i)};function He({schema:t}){const[a,s]=j.useState(!1),r=JSON.stringify(t,null,2),i=async()=>{await navigator.clipboard.writeText(r),s(!0),setTimeout(()=>s(!1),2e3)},l=()=>{fe(t,"schema.json")};return e.jsxs("div",{className:"h-full flex flex-col",children:[e.jsxs("div",{className:"flex items-center justify-between p-4 border-b",children:[e.jsx("h2",{className:"text-sm font-medium",children:"JSON Schema Output"}),e.jsxs("div",{className:"flex gap-2",children:[e.jsx(I,{variant:"outline",size:"sm",onClick:i,"data-testid":"button-copy",children:a?e.jsx(u.CheckCircle2,{className:"w-4 h-4"}):e.jsx(u.Copy,{className:"w-4 h-4"})}),e.jsx(I,{variant:"outline",size:"sm",onClick:l,"data-testid":"button-download",children:e.jsx(u.Download,{className:"w-4 h-4"})})]})]}),e.jsx("div",{className:"flex-1 overflow-auto",children:e.jsx(te,{className:"m-4 bg-muted/30",children:e.jsx("pre",{className:"p-6 text-xs font-mono overflow-auto","data-testid":"text-json-output",children:e.jsx("code",{children:r})})})})]})}function Ue({title:t,description:a,version:s,onUpdate:r}){const[i,l]=j.useState(!1);return e.jsxs(te,{className:"p-4",children:[e.jsxs(I,{variant:"ghost",onClick:()=>l(!i),className:"w-full justify-between px-2 h-auto hover:bg-transparent","data-testid":"button-toggle-metadata",children:[e.jsx("h3",{className:"text-sm font-medium",children:"Schema Metadata"}),i?e.jsx(u.ChevronDown,{className:"w-4 h-4"}):e.jsx(u.ChevronRight,{className:"w-4 h-4"})]}),i&&e.jsxs("div",{className:"mt-4 space-y-4",children:[e.jsxs("div",{className:"space-y-2",children:[e.jsx(N,{htmlFor:"schema-title",className:"text-xs text-muted-foreground",children:"Title"}),e.jsx(D,{id:"schema-title",placeholder:"My Schema",value:t,onChange:n=>r("title",n.target.value),"data-testid":"input-title"})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx(N,{htmlFor:"schema-description",className:"text-xs text-muted-foreground",children:"Description"}),e.jsx(Y,{id:"schema-description",placeholder:"Describe your schema...",value:a,onChange:n=>r("description",n.target.value),className:"resize-none",rows:3,"data-testid":"input-schema-description"})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx(N,{htmlFor:"schema-version",className:"text-xs text-muted-foreground",children:"Version"}),e.jsx(D,{id:"schema-version",placeholder:"1.0.0",value:s,onChange:n=>r("version",n.target.value),"data-testid":"input-version"})]})]})]})}const A=(t,a,s=!0)=>{const r={type:"object"};s&&a&&(a.title&&(r.title=a.title),a.description&&(r.description=a.description));const i=Q(t);Object.keys(i).length>0&&(r.properties=i);const l=t.filter(n=>n.required&&n.key).map(n=>n.key);return l.length>0&&(r.required=l),r},Q=t=>{const a={};return t.forEach(s=>{if(!s.key)return;const i={type:s.type==="file"?"string":s.type};if(s.title&&(i.title=s.title),s.description&&(i.description=s.description),s.type==="file"&&(i.format="filename"),s.type==="string"&&(s.minLength!==void 0&&(i.minLength=s.minLength),s.maxLength!==void 0&&(i.maxLength=s.maxLength),s.pattern&&(i.pattern=s.pattern),s.enum&&s.enum.length>0&&(i.enum=s.enum)),(s.type==="number"||s.type==="integer")&&(s.minimum!==void 0&&(i.minimum=s.minimum),s.maximum!==void 0&&(i.maximum=s.maximum)),s.type==="array"&&(s.minItems!==void 0&&(i.minItems=s.minItems),s.maxItems!==void 0&&(i.maxItems=s.maxItems),s.uniqueItems&&(i.uniqueItems=s.uniqueItems),s.items&&(i.items=Q([s.items])[s.items.key]||{type:s.items.type})),s.type==="object"&&s.children&&s.children.length>0){i.properties=Q(s.children);const l=s.children.filter(n=>n.required&&n.key).map(n=>n.key);l.length>0&&(i.required=l)}a[s.key]=i}),a},Xe=t=>{const a={properties:[]};return(t.title||t.description)&&(a.metadata={title:typeof t.title=="string"?t.title:"",description:typeof t.description=="string"?t.description:"",version:"1.0.0"}),t.properties&&typeof t.properties=="object"&&(a.properties=W(t.properties,Array.isArray(t.required)?t.required:[])),a},W=(t,a=[])=>t?Object.entries(t).filter(([,s])=>typeof s=="object").map(([s,r])=>{const i=r;let l=typeof i.type=="string"?i.type:"string";l==="string"&&i.format==="filename"&&(l="file");const n={id:Z(),key:s,title:typeof i.title=="string"?i.title:void 0,type:l,description:typeof i.description=="string"?i.description:void 0,required:a.includes(s)};return i.minLength!==void 0&&(n.minLength=i.minLength),i.maxLength!==void 0&&(n.maxLength=i.maxLength),i.pattern&&(n.pattern=i.pattern),i.enum&&Array.isArray(i.enum)&&(n.enum=i.enum),i.minimum!==void 0&&(n.minimum=i.minimum),i.maximum!==void 0&&(n.maximum=i.maximum),i.minItems!==void 0&&(n.minItems=i.minItems),i.maxItems!==void 0&&(n.maxItems=i.maxItems),i.uniqueItems&&(n.uniqueItems=i.uniqueItems),n.type==="array"&&i.items&&typeof i.items=="object"&&!Array.isArray(i.items)&&(n.items=W({item:i.items},[]).find(m=>m.key==="item")),i.properties&&typeof i.properties=="object"&&(n.children=W(i.properties,Array.isArray(i.required)?i.required:[])),n}):[],Ge=({schema:t,onChange:a,includeMetadata:s=!0})=>{const{properties:r,metadata:i}=j.useMemo(()=>Xe(t),[t]),l=r,n=i||{title:"",description:"",version:""},m=j.useCallback(()=>({id:Z(),key:"",type:"string",required:!1}),[]),C=j.useCallback((x,S)=>{const b=l.some(O=>O.id===x);let P;b?P=l.map(O=>O.id===x?S:O):P=[...l,S];const h=A(P,n,s);a(h)},[l,n,s,a]),o=j.useCallback(x=>{const S=l.filter(P=>P.id!==x),b=A(S,n,s);a(b)},[l,n,s,a]),d=j.useCallback(()=>{const S=A([],{title:"",description:""},s);a(S)},[s,a]),g=j.useCallback((x,S)=>{const b={...n,[x]:S},P=A(l,b,s);a(P)},[l,n,s,a]),y=j.useCallback(async()=>{const x=await Ve();a(x)},[a]),p=j.useCallback(()=>{fe(t,"schema.json")},[t]);return{properties:l,metadata:n,addProperty:m,updateProperty:C,deleteProperty:o,clearAll:d,updateMetadata:g,importSchema:y,downloadSchema:p}};function Qe(){const[t,a]=j.useState("light");j.useEffect(()=>{const i=localStorage.getItem("theme")||(window.matchMedia("(prefers-color-scheme: dark)").matches?"dark":"light");a(i),document.documentElement.classList.toggle("dark",i==="dark")},[]);const s=()=>{const r=t==="light"?"dark":"light";a(r),localStorage.setItem("theme",r),document.documentElement.classList.toggle("dark",r==="dark")};return e.jsx(I,{variant:"ghost",size:"icon",onClick:s,"data-testid":"button-theme-toggle",children:t==="light"?e.jsx(u.Moon,{className:"w-4 h-4"}):e.jsx(u.Sun,{className:"w-4 h-4"})})}function We({schema:t,onChange:a,showMetadata:s=!1,showImport:r=!0,showClear:i=!0,showOutput:l=!0,showHeader:n=!0,className:m="",showSummary:C=!1,typeLabels:o,propertyLabel:d={singular:"property",plural:"properties"},showRegex:g=!1,keyEditable:y=!1}){const{properties:p,metadata:x,addProperty:S,updateProperty:b,deleteProperty:P,clearAll:h,updateMetadata:O,importSchema:c}=Ge({schema:t,onChange:a,includeMetadata:s}),q=ee({createInitialData:()=>S(),onConfirm:T=>{b(T.id,T)}}),B=()=>{h()},$=async()=>{await c()};return e.jsx(ze,{customLabels:o,children:e.jsxs("div",{className:`${m} flex flex-col json-schema-builder-react`,children:[n&&e.jsx("header",{className:"h-16 border-b flex items-center justify-between px-6",children:e.jsxs("div",{className:"flex items-center gap-3",children:[r&&e.jsx(I,{variant:"outline",size:"sm",onClick:$,"data-testid":"button-import",children:e.jsx(u.Upload,{className:"w-4 h-4"})}),i&&e.jsx(I,{variant:"outline",size:"sm",onClick:B,disabled:p.length===0,"data-testid":"button-clear",children:e.jsx(u.Trash2,{className:"w-4 h-4"})}),e.jsx(Qe,{})]})}),e.jsxs("div",{className:"flex-1 flex overflow-hidden",children:[e.jsx("div",{className:l?"w-3/5 border-r":"w-full",children:e.jsxs("div",{className:"h-full flex flex-col",children:[e.jsxs("div",{className:"flex-1 overflow-auto p-2 space-y-4",children:[s&&e.jsx(Ue,{title:x.title,description:x.description,version:x.version,onUpdate:(T,R)=>O(T,R)}),p.length===0?e.jsxs("div",{className:"flex flex-col items-center justify-center py-16 text-center",children:[e.jsx("div",{className:"w-16 h-16 rounded-full bg-muted flex items-center justify-center mb-4",children:e.jsx(u.Plus,{className:"w-8 h-8 text-muted-foreground"})}),e.jsxs("h2",{className:"text-lg font-medium mb-2",children:["No ",d.plural," yet"]}),e.jsxs("p",{className:"text-sm text-muted-foreground mb-6 max-w-sm",children:["Start building your JSON schema by adding your first"," ",d.singular]}),e.jsxs(I,{onClick:()=>q.open(),"data-testid":"button-add-first",children:[e.jsx(u.Plus,{className:"w-4 h-4 mr-2"}),"Add ",d.singular]})]}):e.jsxs(e.Fragment,{children:[e.jsx("div",{className:"space-y-1",children:p.map(T=>e.jsx(G,{property:T,onUpdate:R=>b(T.id,R),onDelete:()=>P(T.id),showRegex:g,keyEditable:y},T.id))}),C&&e.jsxs("div",{className:"pt-4 border-t flex items-center justify-between text-sm text-muted-foreground",children:[e.jsxs("span",{children:[p.length," ",p.length===1?d.singular:d.plural]}),e.jsxs("span",{children:[p.filter(T=>T.required).length," required"]})]})]})]}),p.length>0&&e.jsx("div",{className:"border-t p-2 pt-4 bg-background",children:e.jsxs(I,{onClick:()=>q.open(),className:"w-full",variant:"outline","data-testid":"button-add-property",children:[e.jsx(u.Plus,{className:"w-4 h-4"}),"Add ",d.singular]})})]})}),l&&e.jsx("div",{className:"w-2/5",children:e.jsx(He,{schema:t})})]}),q.isOpen&&q.data&&e.jsx(X,{property:q.data,open:q.isOpen,isNewProperty:!0,onOpenChange:q.setIsOpen,propertyLabel:d,onUpdate:q.confirm,showRegex:g,keyEditable:y})]})})}exports.JsonSchemaBuilder=We;
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("react/jsx-runtime"),y=require("react"),ge=require("@radix-ui/react-slot"),ae=require("class-variance-authority"),je=require("clsx"),ve=require("tailwind-merge"),f=require("lucide-react"),ye=require("@radix-ui/react-tooltip"),be=require("@radix-ui/react-select"),Ne=require("@radix-ui/react-dialog"),Ce=require("@radix-ui/react-label"),we=require("@radix-ui/react-checkbox");function F(t){const a=Object.create(null,{[Symbol.toStringTag]:{value:"Module"}});if(t){for(const s in t)if(s!=="default"){const r=Object.getOwnPropertyDescriptor(t,s);Object.defineProperty(a,s,r.get?r:{enumerable:!0,get:()=>t[s]})}}return a.default=t,Object.freeze(a)}const b=F(y),E=F(ye),C=F(be),L=F(Ne),ie=F(Ce),J=F(we);function u(...t){return ve.twMerge(je.clsx(t))}const ke=ae.cva("inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-full text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0",{variants:{variant:{default:"bg-primary text-primary-foreground hover:bg-primary/90",destructive:"bg-destructive text-destructive-foreground hover:bg-destructive/90",outline:"border border-input bg-background hover:bg-accent hover:text-accent-foreground",secondary:"bg-secondary text-secondary-foreground hover:bg-secondary/80",ghost:"hover:bg-accent hover:text-accent-foreground",link:"text-primary underline-offset-4 hover:underline"},size:{default:"h-9 px-4 py-2",sm:"h-8 rounded-full px-3 text-xs",lg:"h-10 rounded-full px-8",icon:"h-9 w-9"}},defaultVariants:{variant:"default",size:"default"}}),S=b.forwardRef(({className:t,variant:a,size:s,asChild:r=!1,...i},l)=>{const n=r?ge.Slot:"button";return e.jsx(n,{className:u(ke({variant:a,size:s,className:t})),ref:l,...i})});S.displayName="Button";const D=b.forwardRef(({className:t,type:a,...s},r)=>e.jsx("input",{type:a,className:u("flex h-9 w-full rounded-md border border-input bg-transparent px-3 py-1 text-base shadow-sm transition-colors file:border-0 file:bg-transparent file:text-sm file:font-medium file:text-foreground placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50 md:text-sm",t),ref:r,...s}));D.displayName="Input";const Se=E.Provider,Ie=E.Root,Te=E.Trigger,ne=b.forwardRef(({className:t,sideOffset:a=4,...s},r)=>e.jsx(E.Portal,{children:e.jsx(E.Content,{ref:r,sideOffset:a,className:u("z-50 overflow-hidden rounded-md bg-popover px-3 py-1.5 text-xs text-popover-foreground animate-in fade-in-0 zoom-in-95 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 origin-[--radix-tooltip-content-transform-origin]",t),...s})}));ne.displayName=E.Content.displayName;const V=C.Root,H=C.Value,M=b.forwardRef(({className:t,children:a,...s},r)=>e.jsxs(C.Trigger,{ref:r,className:u("flex h-9 w-full items-center justify-between whitespace-nowrap rounded-md border border-input bg-transparent px-3 py-2 text-sm shadow-sm ring-offset-background data-[placeholder]:text-muted-foreground focus:outline-none focus:ring-1 focus:ring-ring disabled:cursor-not-allowed disabled:opacity-50 [&>span]:line-clamp-1",t),...s,children:[a,e.jsx(C.Icon,{asChild:!0,children:e.jsx(f.ChevronDown,{className:"h-4 w-4 opacity-50"})})]}));M.displayName=C.Trigger.displayName;const re=b.forwardRef(({className:t,...a},s)=>e.jsx(C.ScrollUpButton,{ref:s,className:u("flex cursor-default items-center justify-center py-1",t),...a,children:e.jsx(f.ChevronUp,{className:"h-4 w-4"})}));re.displayName=C.ScrollUpButton.displayName;const le=b.forwardRef(({className:t,...a},s)=>e.jsx(C.ScrollDownButton,{ref:s,className:u("flex cursor-default items-center justify-center py-1",t),...a,children:e.jsx(f.ChevronDown,{className:"h-4 w-4"})}));le.displayName=C.ScrollDownButton.displayName;const _=b.forwardRef(({className:t,children:a,position:s="popper",...r},i)=>e.jsx(C.Portal,{children:e.jsxs(C.Content,{ref:i,className:u("relative z-50 max-h-[--radix-select-content-available-height] min-w-[8rem] overflow-y-auto overflow-x-hidden rounded-md border bg-popover text-popover-foreground shadow-md data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 origin-[--radix-select-content-transform-origin]",s==="popper"&&"data-[side=bottom]:translate-y-1 data-[side=left]:-translate-x-1 data-[side=right]:translate-x-1 data-[side=top]:-translate-y-1",t),position:s,...r,children:[e.jsx(re,{}),e.jsx(C.Viewport,{className:u("p-1",s==="popper"&&"h-[var(--radix-select-trigger-height)] w-full min-w-[var(--radix-select-trigger-width)]"),children:a}),e.jsx(le,{})]})}));_.displayName=C.Content.displayName;const De=b.forwardRef(({className:t,...a},s)=>e.jsx(C.Label,{ref:s,className:u("px-2 py-1.5 text-sm font-semibold",t),...a}));De.displayName=C.Label.displayName;const w=b.forwardRef(({className:t,children:a,...s},r)=>e.jsxs(C.Item,{ref:r,className:u("relative flex w-full cursor-default select-none items-center rounded-sm py-1.5 pl-2 pr-8 text-sm outline-none focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50",t),...s,children:[e.jsx("span",{className:"absolute right-2 flex h-3.5 w-3.5 items-center justify-center",children:e.jsx(C.ItemIndicator,{children:e.jsx(f.Check,{className:"h-4 w-4"})})}),e.jsx(C.ItemText,{children:a})]}));w.displayName=C.Item.displayName;const qe=b.forwardRef(({className:t,...a},s)=>e.jsx(C.Separator,{ref:s,className:u("-mx-1 my-1 h-px bg-muted",t),...a}));qe.displayName=C.Separator.displayName;const Pe=L.Root,Le=L.Portal,de=b.forwardRef(({className:t,...a},s)=>e.jsx(L.Overlay,{ref:s,className:u("fixed inset-0 z-50 bg-black/80 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0",t),...a}));de.displayName=L.Overlay.displayName;const oe=b.forwardRef(({className:t,children:a,...s},r)=>e.jsxs(Le,{children:[e.jsx(de,{}),e.jsxs(L.Content,{ref:r,className:u("fixed left-[50%] top-[50%] z-50 grid w-full max-w-lg translate-x-[-50%] translate-y-[-50%] gap-4 border bg-background p-6 shadow-lg duration-200 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[state=closed]:slide-out-to-left-1/2 data-[state=closed]:slide-out-to-top-[48%] data-[state=open]:slide-in-from-left-1/2 data-[state=open]:slide-in-from-top-[48%] sm:rounded-lg",t),...s,children:[a,e.jsxs(L.Close,{className:"absolute right-4 top-4 rounded-sm opacity-70 ring-offset-background transition-opacity hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:pointer-events-none data-[state=open]:bg-accent data-[state=open]:text-muted-foreground",children:[e.jsx(f.X,{className:"h-4 w-4"}),e.jsx("span",{className:"sr-only",children:"Close"})]})]})]}));oe.displayName=L.Content.displayName;const ce=({className:t,...a})=>e.jsx("div",{className:u("flex flex-col space-y-1.5 text-center sm:text-left",t),...a});ce.displayName="DialogHeader";const me=({className:t,...a})=>e.jsx("div",{className:u("flex flex-col-reverse sm:flex-row sm:justify-end sm:space-x-2",t),...a});me.displayName="DialogFooter";const ue=b.forwardRef(({className:t,...a},s)=>e.jsx(L.Title,{ref:s,className:u("text-lg font-semibold leading-none tracking-tight",t),...a}));ue.displayName=L.Title.displayName;const Oe=b.forwardRef(({className:t,...a},s)=>e.jsx(L.Description,{ref:s,className:u("text-sm text-muted-foreground",t),...a}));Oe.displayName=L.Description.displayName;const Re=ae.cva("text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70"),N=b.forwardRef(({className:t,...a},s)=>e.jsx(ie.Root,{ref:s,className:u(Re(),t),...a}));N.displayName=ie.Root.displayName;const U=b.forwardRef(({className:t,...a},s)=>e.jsx(J.Root,{ref:s,className:u("grid place-content-center peer h-4 w-4 shrink-0 rounded-sm border border-primary shadow focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50 data-[state=checked]:bg-primary data-[state=checked]:text-primary-foreground",t),...a,children:e.jsx(J.Indicator,{className:u("grid place-content-center text-current"),children:e.jsx(f.Check,{className:"h-4 w-4"})})}));U.displayName=J.Root.displayName;const Y=b.forwardRef(({className:t,...a},s)=>e.jsx("textarea",{className:u("flex min-h-[60px] w-full rounded-md border border-input bg-transparent px-3 py-2 text-base shadow-sm placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50 md:text-sm",t),ref:s,...a}));Y.displayName="Textarea";const Ee=t=>t.trim().toLowerCase().replace(/[^\w\s]/g,"").replace(/\s+/g,"_"),Fe=(t,a,s=!1,r=!1)=>{const i=(p,j)=>{a({...t,[p]:j})};return{handleTitleChange:p=>{i("title",p)},handleTitleBlur:()=>{if(s&&t.title){const p=Ee(t.title);i("key",p)}},handleKeyChange:p=>{(s||r)&&i("key",p)},handleFieldChange:i,handleConstraintChange:(p,j)=>{a({...t,[p]:j})}}},X={string:"String",number:"Number",integer:"Integer",boolean:"Boolean",object:"Object",array:"Array",null:"Null",file:"File"},he=y.createContext({getTypeLabel:t=>X[t],typeLabels:X});function ze({children:t,customLabels:a={}}){const s={...X,...a},r=i=>s[i]||i;return e.jsx(he.Provider,{value:{getTypeLabel:r,typeLabels:s},children:t})}function xe(){return y.useContext(he)}function $({property:t,open:a,onOpenChange:s,onSave:r,isArrayItem:i=!1,isNewProperty:l=!1,propertyLabel:n={singular:"Property",plural:"Properties"},showRegex:c=!1,keyEditable:k=!1,typeLabels:p}){const{typeLabels:j}=xe(),m=p||j,[d,h]=y.useState(t);y.useEffect(()=>{a&&h(t)},[t,a]);const{handleTitleChange:g,handleTitleBlur:q,handleKeyChange:P,handleFieldChange:I,handleConstraintChange:v}=Fe(d,h,l,k),x=()=>{d.title?.trim()&&(r(d),s(!1))},z=()=>{h(t),s(!1)};return e.jsx(Pe,{open:a,onOpenChange:s,children:e.jsxs(oe,{className:"max-w-2xl max-h-[80vh] flex flex-col gap-0 p-0","data-testid":"dialog-edit-property",children:[e.jsx(ce,{className:"px-6 pt-6 pb-4 shrink-0",children:e.jsx(ue,{children:l?`Add ${n.singular}`:`Edit ${n.singular}`})}),e.jsxs("div",{className:"space-y-6 px-6 pb-4 overflow-y-auto flex-1 min-h-0",children:[e.jsxs("div",{className:"space-y-2",children:[e.jsxs(N,{className:"flex items-center gap-1.5",children:[e.jsx("span",{className:"w-1.5 h-1.5 rounded-full bg-red-500"}),"Type"]}),e.jsxs(V,{value:d.type,onValueChange:o=>I("type",o),"data-testid":"select-type-dialog",children:[e.jsx(M,{children:e.jsx(H,{})}),e.jsxs(_,{children:[e.jsx(w,{value:"string",children:m.string}),e.jsx(w,{value:"number",children:m.number}),e.jsx(w,{value:"integer",children:m.integer}),e.jsx(w,{value:"boolean",children:m.boolean}),e.jsx(w,{value:"object",children:m.object}),e.jsx(w,{value:"array",children:m.array}),e.jsx(w,{value:"file",children:m.file}),e.jsx(w,{value:"null",children:m.null})]})]})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsxs(N,{className:"flex items-center gap-1.5",children:[e.jsx("span",{className:"w-1.5 h-1.5 rounded-full bg-red-500"}),"Title"]}),e.jsx(D,{value:d.title||"",onChange:o=>g(o.target.value),onBlur:q,placeholder:"Property Title","data-testid":"input-title-dialog",required:!0}),!l&&d.key&&e.jsxs("p",{className:"text-xs text-muted-foreground font-mono",children:["Key: ",d.key]})]}),(l||k)&&e.jsxs("div",{className:"space-y-2",children:[e.jsx(N,{children:"Key"}),e.jsx(D,{value:d.key,onChange:o=>P(o.target.value),placeholder:"property_key","data-testid":"input-key-dialog"}),!l&&e.jsx("p",{className:"text-xs text-yellow-600 dark:text-yellow-500",children:"⚠️ Changing the key may break existing references to this property"})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx(N,{children:"Description"}),e.jsx(Y,{placeholder:"Optional description",value:d.description||"",onChange:o=>I("description",o.target.value),rows:2,"data-testid":"input-edit-description"})]}),d.type==="array"&&e.jsxs("div",{className:"space-y-2 border-l-2 border-border pl-4 mt-2",children:[e.jsxs(N,{className:"font-semibold text-xs text-muted-foreground",children:[m.array," Items"]}),d.items?e.jsxs("div",{className:"bg-muted/40 p-2 rounded",children:[e.jsxs("div",{className:"space-y-2",children:[e.jsx(N,{children:"Item Type"}),e.jsxs(V,{value:d.items.type,onValueChange:o=>h({...d,items:{...d.items,type:o}}),children:[e.jsx(M,{children:e.jsx(H,{})}),e.jsxs(_,{children:[e.jsx(w,{value:"string",children:m.string}),e.jsx(w,{value:"number",children:m.number}),e.jsx(w,{value:"integer",children:m.integer}),e.jsx(w,{value:"boolean",children:m.boolean}),e.jsx(w,{value:"object",children:m.object}),e.jsx(w,{value:"array",children:m.array}),e.jsx(w,{value:"file",children:m.file}),e.jsx(w,{value:"null",children:m.null})]})]})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx(N,{children:"Item Title"}),e.jsx(D,{value:d.items.title||"",onChange:o=>h({...d,items:{...d.items,title:o.target.value}}),placeholder:"Item Title"})]}),e.jsxs(S,{variant:"ghost",size:"sm",className:"mt-2",onClick:()=>h({...d,items:void 0}),children:["Remove ",m.array," Item Schema"]})]}):e.jsxs(S,{variant:"outline",size:"sm",onClick:()=>{h({...d,items:{id:Date.now().toString()+Math.random(),key:"item",type:"string",required:!1}})},children:["Add ",m.array," Item Schema"]})]}),!i&&e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(U,{id:"prop-required",checked:d.required,onCheckedChange:o=>I("required",o),"data-testid":"checkbox-edit-required"}),e.jsx(N,{htmlFor:"prop-required",className:"cursor-pointer",children:"Required field"})]}),d.type==="string"&&e.jsxs("details",{className:"border rounded-md",children:[e.jsx("summary",{className:"p-4 cursor-pointer hover:bg-accent/50 transition-colors",children:e.jsxs("h4",{className:"text-sm font-medium inline",children:[m.string," Constraints"]})}),e.jsxs("div",{className:"space-y-4 p-4 pt-0",children:[e.jsxs("div",{className:"grid grid-cols-2 gap-4",children:[e.jsxs("div",{className:"space-y-2",children:[e.jsx(N,{htmlFor:"min-length",children:"Minimum Length"}),e.jsx(D,{id:"min-length",type:"number",placeholder:"0",value:d.minLength||"",onChange:o=>v("minLength",o.target.value?parseInt(o.target.value):void 0),"data-testid":"input-edit-minlength"})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx(N,{htmlFor:"max-length",children:"Maximum Length"}),e.jsx(D,{id:"max-length",type:"number",placeholder:"∞",value:d.maxLength||"",onChange:o=>v("maxLength",o.target.value?parseInt(o.target.value):void 0),"data-testid":"input-edit-maxlength"})]})]}),c&&e.jsxs("div",{className:"space-y-2",children:[e.jsx(N,{htmlFor:"pattern",children:"Pattern (regex)"}),e.jsx(D,{id:"pattern",placeholder:"^[a-z]+$",value:d.pattern||"",onChange:o=>v("pattern",o.target.value),className:"font-mono text-sm","data-testid":"input-edit-pattern"})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx(N,{children:"Enum Values"}),e.jsx("div",{className:"space-y-2",children:[...d.enum||[],""].map((o,O)=>e.jsx(D,{placeholder:O===(d.enum?.length||0)?"Add new value...":"Enum value",value:o,onChange:K=>{const T=K.target.value,R=d.enum||[];if(O===R.length)T.trim()&&v("enum",[...R,T.trim()]);else if(T.trim()){const A=[...R];A[O]=T.trim(),v("enum",A)}else{const A=R.filter((Ye,pe)=>pe!==O);v("enum",A.length>0?A:void 0)}},"data-testid":`input-edit-enum-${O}`},O))}),e.jsx("p",{className:"text-xs text-muted-foreground",children:"Enter allowed values (empty fields will be removed)"})]})]})]}),(d.type==="number"||d.type==="integer")&&e.jsxs("details",{className:"border rounded-md",children:[e.jsx("summary",{className:"p-4 cursor-pointer hover:bg-accent/50 transition-colors",children:e.jsx("h4",{className:"text-sm font-medium inline",children:"Numeric Constraints"})}),e.jsx("div",{className:"space-y-4 p-4 pt-0",children:e.jsxs("div",{className:"grid grid-cols-2 gap-4",children:[e.jsxs("div",{className:"space-y-2",children:[e.jsx(N,{htmlFor:"minimum",children:"Minimum Value"}),e.jsx(D,{id:"minimum",type:"number",placeholder:"-∞",value:d.minimum??"",onChange:o=>v("minimum",o.target.value?parseFloat(o.target.value):void 0),"data-testid":"input-edit-minimum"})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx(N,{htmlFor:"maximum",children:"Maximum Value"}),e.jsx(D,{id:"maximum",type:"number",placeholder:"∞",value:d.maximum??"",onChange:o=>v("maximum",o.target.value?parseFloat(o.target.value):void 0),"data-testid":"input-edit-maximum"})]})]})})]}),d.type==="array"&&e.jsxs("details",{className:"border rounded-md",children:[e.jsx("summary",{className:"p-4 cursor-pointer hover:bg-accent/50 transition-colors",children:e.jsxs("h4",{className:"text-sm font-medium inline",children:[m.array," Constraints"]})}),e.jsxs("div",{className:"space-y-4 p-4 pt-0",children:[e.jsxs("div",{className:"grid grid-cols-2 gap-4",children:[e.jsxs("div",{className:"space-y-2",children:[e.jsx(N,{htmlFor:"min-items",children:"Minimum Items"}),e.jsx(D,{id:"min-items",type:"number",placeholder:"0",value:d.minItems||"",onChange:o=>v("minItems",o.target.value?parseInt(o.target.value):void 0),"data-testid":"input-edit-minitems"})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx(N,{htmlFor:"max-items",children:"Maximum Items"}),e.jsx(D,{id:"max-items",type:"number",placeholder:"∞",value:d.maxItems||"",onChange:o=>v("maxItems",o.target.value?parseInt(o.target.value):void 0),"data-testid":"input-edit-maxitems"})]})]}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(U,{id:"unique-items",checked:d.uniqueItems||!1,onCheckedChange:o=>v("uniqueItems",o),"data-testid":"checkbox-edit-unique"}),e.jsx(N,{htmlFor:"unique-items",className:"cursor-pointer",children:"All items must be unique"})]})]})]})]}),e.jsxs(me,{className:"px-6 py-4 border-t bg-background shrink-0",children:[e.jsx(S,{variant:"outline",onClick:z,"data-testid":"button-cancel",children:"Cancel"}),e.jsx(S,{onClick:x,"data-testid":"button-save",disabled:!d.title?.trim(),children:"Save Changes"})]})]})})}function se(t,a,s={}){const{allowEmpty:r=!1,onEditStart:i,onEditCancel:l}=s,[n,c]=y.useState(!1),[k,p]=y.useState(t);y.useEffect(()=>{n||p(t)},[t,n]);const j=()=>{p(t),c(!0),i?.()},m=g=>{p(g)},d=()=>{const g=k.trim();if(!r&&!g){p(t),c(!1);return}g!==t&&a(g),c(!1)};return{isEditing:n,value:k,startEdit:j,handleChange:m,handleBlur:d,handleKeyDown:g=>{g.key==="Enter"?d():g.key==="Escape"&&(p(t),c(!1),l?.())}}}function Ae(t,a){const[s,r]=y.useState(!1);return{isChangingType:s,setIsChangingType:r,handleTypeChange:n=>{const c={...t,type:n};n!=="string"&&(delete c.minLength,delete c.maxLength,delete c.pattern,delete c.enum),n!=="number"&&n!=="integer"&&(delete c.minimum,delete c.maximum),n!=="array"&&(delete c.minItems,delete c.maxItems,delete c.uniqueItems,delete c.items),n!=="object"&&delete c.children,a(c),r(!1)},availableTypes:["string","number","integer","boolean","object","array","file"]}}const Z=()=>`${Date.now()}-${Math.random()}`;function ee(t={}){const{onConfirm:a,onCancel:s,createInitialData:r}=t,[i,l]=y.useState(!1),[n,c]=y.useState(null),k=d=>{const h=d??(r?r():null);c(h),l(!0)},p=()=>{l(!1),c(null),s?.()};return{isOpen:i,data:n,open:k,close:p,confirm:d=>{a?.(d),l(!1),c(null)},setIsOpen:d=>{d?l(!0):p()}}}function Be(t,a){const s=ee({createInitialData:()=>({id:Z(),key:"",type:"string",required:!1}),onConfirm:l=>{a({...t,children:[...t.children||[],l]})}});return{addChild:()=>s.open(),updateChild:(l,n)=>{const c=t.children.map(k=>k.id===l?n:k);a({...t,children:c})},deleteChild:l=>{const n=t.children.filter(c=>c.id!==l);a({...t,children:n})},addChildDialog:{isOpen:s.isOpen,data:s.data,setIsOpen:s.setIsOpen,confirm:s.confirm}}}function G({property:t,onUpdate:a,onDelete:s,level:r=1,isArrayItem:i=!1,showRegex:l=!1,keyEditable:n=!1}){const{getTypeLabel:c,typeLabels:k}=xe(),p=ee(),j=se(t.title||t.key||"",x=>a({...t,title:x}),{allowEmpty:!1}),m=se(t.description||"",x=>a({...t,description:x||void 0}),{allowEmpty:!0}),d=Ae(t,a),h=Be(t,a),g=`h${Math.min(r,6)}`,q=t.type==="object",P=q&&t.children&&t.children.length>0,I={1:"text-lg font-semibold",2:"text-base",3:"text-base",4:"text-base",5:"text-sm",6:"text-sm"}[r]||"text-sm",v={1:"h-5 w-5",2:"h-4 w-4",3:"h-4 w-4",4:"h-4 w-4",5:"h-4 w-4",6:"h-4 w-4"}[r]||"h-5 w-5";return e.jsxs("div",{className:"group",children:[e.jsxs("div",{className:"flex gap-4 items-center rounded-md -mx-2 px-2 py-1 transition-colors hover:bg-accent/50",children:[e.jsx("div",{className:"flex-1 min-w-0",children:e.jsxs("div",{className:"flex items-start gap-3",children:[!i&&e.jsx("button",{onClick:()=>a({...t,required:!t.required}),className:"shrink-0 transition-all hover:scale-110 -mt-[3px]",title:t.required?"Required field - click to make optional":"Optional field - click to make required",children:t.required?e.jsx(f.Asterisk,{className:"w-6 h-6 text-primary"}):e.jsx(f.Asterisk,{className:"w-6 h-6 text-border"})}),j.isEditing?e.jsx(D,{value:j.value,onChange:x=>j.handleChange(x.target.value),onBlur:j.handleBlur,onKeyDown:j.handleKeyDown,autoFocus:!0,className:I,placeholder:"Enter title"}):e.jsxs("div",{className:"flex gap-2 flex-wrap flex-1",children:[e.jsxs("div",{className:"flex items-start gap-2",children:[e.jsx(g,{className:`${I} cursor-pointer hover:text-primary transition-colors leading-none`,onClick:j.startEdit,children:t.title||t.key||e.jsx("span",{className:"text-muted-foreground italic",children:"unnamed"})}),d.isChangingType?e.jsxs(V,{value:t.type,onValueChange:x=>d.handleTypeChange(x),open:d.isChangingType,onOpenChange:d.setIsChangingType,children:[e.jsx(M,{className:"w-[140px] h-7",children:e.jsx(H,{})}),e.jsx(_,{children:d.availableTypes.map(x=>e.jsx(w,{value:x,children:k[x]},x))})]}):e.jsx(Se,{children:e.jsxs(Ie,{children:[e.jsx(Te,{asChild:!0,children:e.jsxs("button",{onClick:()=>d.setIsChangingType(!0),className:"cursor-pointer hover:bg-accent rounded p-0.5 -mt-0.5 transition-colors",children:[t.type==="string"&&e.jsx(f.Type,{className:u(v,"text-muted-foreground")}),t.type==="number"&&e.jsx(f.Hash,{className:u(v,"text-muted-foreground")}),t.type==="integer"&&e.jsx(f.Hash,{className:u(v,"text-muted-foreground")}),t.type==="boolean"&&e.jsx(f.CheckSquare,{className:u(v,"text-muted-foreground")}),t.type==="object"&&e.jsx(f.Braces,{className:u(v,"text-muted-foreground")}),t.type==="array"&&e.jsx(f.List,{className:u(v,"text-muted-foreground")}),t.type==="file"&&e.jsx(f.FileText,{className:u(v,"text-muted-foreground")})]})}),e.jsxs(ne,{children:[c(t.type),t.type==="array"&&t.items?` of ${c(t.items.type)}`:"",e.jsx("div",{className:"text-xs text-muted-foreground mt-1",children:"Click to change type"})]})]})}),t.type==="object"&&e.jsx(S,{variant:"ghost",size:"icon",className:"h-4 w-4",onClick:h.addChild,"data-testid":`button-add-child-${t.id}`,children:e.jsx(f.Plus,{})})]}),e.jsx("div",{className:"flex-1",children:m.isEditing?e.jsx(D,{value:m.value,onChange:x=>m.handleChange(x.target.value),onBlur:m.handleBlur,onKeyDown:m.handleKeyDown,autoFocus:!0,className:"text-sm flex-1",placeholder:"Enter description"}):e.jsx(e.Fragment,{children:t.description?e.jsx("p",{className:"text-sm text-muted-foreground flex-1 min-w-[200px] cursor-pointer hover:text-foreground transition-colors","data-testid":`text-description-${t.id}`,onClick:m.startEdit,children:t.description}):e.jsx("p",{className:"text-sm text-muted-foreground/50 flex-1 min-w-[200px] cursor-pointer hover:text-muted-foreground italic transition-colors",onClick:m.startEdit,children:"Add description..."})})})]})]})}),e.jsxs("div",{className:"flex items-center gap-1 opacity-0 group-hover:opacity-100 transition-opacity shrink-0",children:[e.jsx(S,{variant:"ghost",size:"icon",className:"h-7 w-7",onClick:()=>p.open(t),"data-testid":`button-edit-${t.id}`,children:e.jsx(f.Pencil,{className:"w-3 h-3"})}),q&&t.type!=="object"&&e.jsx(S,{variant:"ghost",size:"icon",className:"h-7 w-7",onClick:h.addChild,"data-testid":`button-add-child-${t.id}`,children:e.jsx(f.Plus,{className:"w-3 h-3"})}),e.jsx(S,{variant:"ghost",size:"icon",className:"h-7 w-7 text-muted-foreground hover:text-destructive",onClick:s,"data-testid":`button-delete-${t.id}`,children:e.jsx(f.Trash2,{className:"w-3 h-3"})})]})]}),P&&e.jsx("div",{className:r===1?"ml-6 mt-1 border-l-2 border-border pl-6":"ml-4 mt-1 border-l border-border pl-4",children:t.children.map(x=>e.jsx(G,{property:x,onUpdate:z=>h.updateChild(x.id,z),onDelete:()=>h.deleteChild(x.id),level:r+1,showRegex:l,keyEditable:n},x.id))}),t.type==="array"&&t.items&&e.jsxs("div",{className:r===1?"ml-6 mt-1 border-l-2 border-border pl-6":"ml-4 mt-1 border-l border-border pl-4",children:[e.jsxs("div",{className:"mb-2 text-xs text-muted-foreground font-semibold uppercase",children:[c("array")," Items"]}),e.jsx(G,{property:t.items,onUpdate:x=>a({...t,items:x}),onDelete:()=>a({...t,items:void 0}),level:r+1,isArrayItem:!0,showRegex:l,keyEditable:n})]}),e.jsx($,{property:p.data||t,open:p.isOpen,onOpenChange:p.setIsOpen,onSave:x=>{a(x),p.close()},isArrayItem:i,isNewProperty:!1,showRegex:l,keyEditable:n}),h.addChildDialog.isOpen&&h.addChildDialog.data&&e.jsx($,{property:h.addChildDialog.data,open:h.addChildDialog.isOpen,isNewProperty:!0,onOpenChange:h.addChildDialog.setIsOpen,onSave:h.addChildDialog.confirm,showRegex:l,keyEditable:n})]})}const te=b.forwardRef(({className:t,...a},s)=>e.jsx("div",{ref:s,className:u("rounded-xl border bg-card text-card-foreground",t),...a}));te.displayName="Card";const Me=b.forwardRef(({className:t,...a},s)=>e.jsx("div",{ref:s,className:u("flex flex-col space-y-1.5 p-6",t),...a}));Me.displayName="CardHeader";const _e=b.forwardRef(({className:t,...a},s)=>e.jsx("div",{ref:s,className:u("font-semibold leading-none tracking-tight",t),...a}));_e.displayName="CardTitle";const $e=b.forwardRef(({className:t,...a},s)=>e.jsx("div",{ref:s,className:u("text-sm text-muted-foreground",t),...a}));$e.displayName="CardDescription";const Ke=b.forwardRef(({className:t,...a},s)=>e.jsx("div",{ref:s,className:u("p-6 pt-0",t),...a}));Ke.displayName="CardContent";const Je=b.forwardRef(({className:t,...a},s)=>e.jsx("div",{ref:s,className:u("flex items-center p-6 pt-0",t),...a}));Je.displayName="CardFooter";const Ve=()=>new Promise((t,a)=>{const s=document.createElement("input");s.type="file",s.accept=".json",s.onchange=r=>{const i=r.target.files?.[0];if(!i){a(new Error("No file selected"));return}const l=new FileReader;l.onload=n=>{try{const c=JSON.parse(n.target?.result);t(c)}catch{a(new Error("Invalid JSON file"))}},l.onerror=()=>a(new Error("Failed to read file")),l.readAsText(i)},s.click()}),fe=(t,a="schema.json")=>{const s=JSON.stringify(t,null,2),r=new Blob([s],{type:"application/json"}),i=URL.createObjectURL(r),l=document.createElement("a");l.href=i,l.download=a,document.body.appendChild(l),l.click(),document.body.removeChild(l),URL.revokeObjectURL(i)};function He({schema:t}){const[a,s]=y.useState(!1),r=JSON.stringify(t,null,2),i=async()=>{await navigator.clipboard.writeText(r),s(!0),setTimeout(()=>s(!1),2e3)},l=()=>{fe(t,"schema.json")};return e.jsxs("div",{className:"h-full flex flex-col",children:[e.jsxs("div",{className:"flex items-center justify-between p-4 border-b",children:[e.jsx("h2",{className:"text-sm font-medium",children:"JSON Schema Output"}),e.jsxs("div",{className:"flex gap-2",children:[e.jsx(S,{variant:"outline",size:"sm",onClick:i,"data-testid":"button-copy",children:a?e.jsx(f.CheckCircle2,{className:"w-4 h-4"}):e.jsx(f.Copy,{className:"w-4 h-4"})}),e.jsx(S,{variant:"outline",size:"sm",onClick:l,"data-testid":"button-download",children:e.jsx(f.Download,{className:"w-4 h-4"})})]})]}),e.jsx("div",{className:"flex-1 overflow-auto",children:e.jsx(te,{className:"m-4 bg-muted/30",children:e.jsx("pre",{className:"p-6 text-xs font-mono overflow-auto","data-testid":"text-json-output",children:e.jsx("code",{children:r})})})})]})}function Ue({title:t,description:a,version:s,onUpdate:r}){const[i,l]=y.useState(!1);return e.jsxs(te,{className:"p-4",children:[e.jsxs(S,{variant:"ghost",onClick:()=>l(!i),className:"w-full justify-between px-2 h-auto hover:bg-transparent","data-testid":"button-toggle-metadata",children:[e.jsx("h3",{className:"text-sm font-medium",children:"Schema Metadata"}),i?e.jsx(f.ChevronDown,{className:"w-4 h-4"}):e.jsx(f.ChevronRight,{className:"w-4 h-4"})]}),i&&e.jsxs("div",{className:"mt-4 space-y-4",children:[e.jsxs("div",{className:"space-y-2",children:[e.jsx(N,{htmlFor:"schema-title",className:"text-xs text-muted-foreground",children:"Title"}),e.jsx(D,{id:"schema-title",placeholder:"My Schema",value:t,onChange:n=>r("title",n.target.value),"data-testid":"input-title"})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx(N,{htmlFor:"schema-description",className:"text-xs text-muted-foreground",children:"Description"}),e.jsx(Y,{id:"schema-description",placeholder:"Describe your schema...",value:a,onChange:n=>r("description",n.target.value),className:"resize-none",rows:3,"data-testid":"input-schema-description"})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx(N,{htmlFor:"schema-version",className:"text-xs text-muted-foreground",children:"Version"}),e.jsx(D,{id:"schema-version",placeholder:"1.0.0",value:s,onChange:n=>r("version",n.target.value),"data-testid":"input-version"})]})]})]})}const B=(t,a,s=!0)=>{const r={type:"object"};s&&a&&(a.title&&(r.title=a.title),a.description&&(r.description=a.description));const i=Q(t);Object.keys(i).length>0&&(r.properties=i);const l=t.filter(n=>n.required&&n.key).map(n=>n.key);return l.length>0&&(r.required=l),r},Q=t=>{const a={};return t.forEach(s=>{if(!s.key)return;const i={type:s.type==="file"?"string":s.type};if(s.title&&(i.title=s.title),s.description&&(i.description=s.description),s.type==="file"&&(i.format="filename"),s.type==="string"&&(s.minLength!==void 0&&(i.minLength=s.minLength),s.maxLength!==void 0&&(i.maxLength=s.maxLength),s.pattern&&(i.pattern=s.pattern),s.enum&&s.enum.length>0&&(i.enum=s.enum)),(s.type==="number"||s.type==="integer")&&(s.minimum!==void 0&&(i.minimum=s.minimum),s.maximum!==void 0&&(i.maximum=s.maximum)),s.type==="array"&&(s.minItems!==void 0&&(i.minItems=s.minItems),s.maxItems!==void 0&&(i.maxItems=s.maxItems),s.uniqueItems&&(i.uniqueItems=s.uniqueItems),s.items&&(i.items=Q([s.items])[s.items.key]||{type:s.items.type})),s.type==="object"&&s.children&&s.children.length>0){i.properties=Q(s.children);const l=s.children.filter(n=>n.required&&n.key).map(n=>n.key);l.length>0&&(i.required=l)}a[s.key]=i}),a},Xe=t=>{const a={properties:[]};return(t.title||t.description)&&(a.metadata={title:typeof t.title=="string"?t.title:"",description:typeof t.description=="string"?t.description:"",version:"1.0.0"}),t.properties&&typeof t.properties=="object"&&(a.properties=W(t.properties,Array.isArray(t.required)?t.required:[])),a},W=(t,a=[])=>t?Object.entries(t).filter(([,s])=>typeof s=="object").map(([s,r])=>{const i=r;let l=typeof i.type=="string"?i.type:"string";l==="string"&&i.format==="filename"&&(l="file");const n={id:Z(),key:s,title:typeof i.title=="string"?i.title:void 0,type:l,description:typeof i.description=="string"?i.description:void 0,required:a.includes(s)};return i.minLength!==void 0&&(n.minLength=i.minLength),i.maxLength!==void 0&&(n.maxLength=i.maxLength),i.pattern&&(n.pattern=i.pattern),i.enum&&Array.isArray(i.enum)&&(n.enum=i.enum),i.minimum!==void 0&&(n.minimum=i.minimum),i.maximum!==void 0&&(n.maximum=i.maximum),i.minItems!==void 0&&(n.minItems=i.minItems),i.maxItems!==void 0&&(n.maxItems=i.maxItems),i.uniqueItems&&(n.uniqueItems=i.uniqueItems),n.type==="array"&&i.items&&typeof i.items=="object"&&!Array.isArray(i.items)&&(n.items=W({item:i.items},[]).find(c=>c.key==="item")),i.properties&&typeof i.properties=="object"&&(n.children=W(i.properties,Array.isArray(i.required)?i.required:[])),n}):[],Ge=({schema:t,onChange:a,includeMetadata:s=!0})=>{const{properties:r,metadata:i}=y.useMemo(()=>Xe(t),[t]),l=r,n=i||{title:"",description:"",version:""},c=y.useCallback(()=>({id:Z(),key:"",type:"string",required:!1}),[]),k=y.useCallback((g,q)=>{const P=l.some(x=>x.id===g);let I;P?I=l.map(x=>x.id===g?q:x):I=[...l,q];const v=B(I,n,s);a(v)},[l,n,s,a]),p=y.useCallback(g=>{const q=l.filter(I=>I.id!==g),P=B(q,n,s);a(P)},[l,n,s,a]),j=y.useCallback(()=>{const q=B([],{title:"",description:""},s);a(q)},[s,a]),m=y.useCallback((g,q)=>{const P={...n,[g]:q},I=B(l,P,s);a(I)},[l,n,s,a]),d=y.useCallback(async()=>{const g=await Ve();a(g)},[a]),h=y.useCallback(()=>{fe(t,"schema.json")},[t]);return{properties:l,metadata:n,addProperty:c,updateProperty:k,deleteProperty:p,clearAll:j,updateMetadata:m,importSchema:d,downloadSchema:h}};function Qe(){const[t,a]=y.useState("light");y.useEffect(()=>{const i=localStorage.getItem("theme")||(window.matchMedia("(prefers-color-scheme: dark)").matches?"dark":"light");a(i),document.documentElement.classList.toggle("dark",i==="dark")},[]);const s=()=>{const r=t==="light"?"dark":"light";a(r),localStorage.setItem("theme",r),document.documentElement.classList.toggle("dark",r==="dark")};return e.jsx(S,{variant:"ghost",size:"icon",onClick:s,"data-testid":"button-theme-toggle",children:t==="light"?e.jsx(f.Moon,{className:"w-4 h-4"}):e.jsx(f.Sun,{className:"w-4 h-4"})})}function We({schema:t,onChange:a,showMetadata:s=!1,showImport:r=!0,showClear:i=!0,showOutput:l=!0,showHeader:n=!0,className:c="",showSummary:k=!1,typeLabels:p,propertyLabel:j={singular:"property",plural:"properties"},showRegex:m=!1,keyEditable:d=!1}){const{properties:h,metadata:g,addProperty:q,updateProperty:P,deleteProperty:I,clearAll:v,updateMetadata:x,importSchema:z}=Ge({schema:t,onChange:a,includeMetadata:s}),o=ee({createInitialData:()=>q(),onConfirm:T=>{P(T.id,T)}}),O=()=>{v()},K=async()=>{await z()};return e.jsx(ze,{customLabels:p,children:e.jsxs("div",{className:`${c} flex flex-col json-schema-builder-react`,children:[n&&e.jsx("header",{className:"h-16 border-b flex items-center justify-between px-6",children:e.jsxs("div",{className:"flex items-center gap-3",children:[r&&e.jsx(S,{variant:"outline",size:"sm",onClick:K,"data-testid":"button-import",children:e.jsx(f.Upload,{className:"w-4 h-4"})}),i&&e.jsx(S,{variant:"outline",size:"sm",onClick:O,disabled:h.length===0,"data-testid":"button-clear",children:e.jsx(f.Trash2,{className:"w-4 h-4"})}),e.jsx(Qe,{})]})}),e.jsxs("div",{className:"flex-1 flex overflow-hidden",children:[e.jsx("div",{className:l?"w-3/5 border-r":"w-full",children:e.jsxs("div",{className:"h-full flex flex-col",children:[e.jsxs("div",{className:"flex-1 overflow-auto p-2 space-y-4",children:[s&&e.jsx(Ue,{title:g.title,description:g.description,version:g.version,onUpdate:(T,R)=>x(T,R)}),h.length===0?e.jsxs("div",{className:"flex flex-col items-center justify-center py-16 text-center",children:[e.jsx("div",{className:"w-16 h-16 rounded-full bg-muted flex items-center justify-center mb-4",children:e.jsx(f.Plus,{className:"w-8 h-8 text-muted-foreground"})}),e.jsxs("h2",{className:"text-lg font-medium mb-2",children:["No ",j.plural," yet"]}),e.jsxs("p",{className:"text-sm text-muted-foreground mb-6 max-w-sm",children:["Start building your JSON schema by adding your first"," ",j.singular]}),e.jsxs(S,{onClick:()=>o.open(),"data-testid":"button-add-first",children:[e.jsx(f.Plus,{className:"w-4 h-4 mr-2"}),"Add ",j.singular]})]}):e.jsxs(e.Fragment,{children:[e.jsx("div",{className:"space-y-1",children:h.map(T=>e.jsx(G,{property:T,onUpdate:R=>P(T.id,R),onDelete:()=>I(T.id),showRegex:m,keyEditable:d},T.id))}),k&&e.jsxs("div",{className:"pt-4 border-t flex items-center justify-between text-sm text-muted-foreground",children:[e.jsxs("span",{children:[h.length," ",h.length===1?j.singular:j.plural]}),e.jsxs("span",{children:[h.filter(T=>T.required).length," required"]})]})]})]}),h.length>0&&e.jsx("div",{className:"border-t p-2 pt-4 bg-background",children:e.jsxs(S,{onClick:()=>o.open(),className:"w-full",variant:"outline","data-testid":"button-add-property",children:[e.jsx(f.Plus,{className:"w-4 h-4"}),"Add ",j.singular]})})]})}),l&&e.jsx("div",{className:"w-2/5",children:e.jsx(He,{schema:t})})]}),o.isOpen&&o.data&&e.jsx($,{property:o.data,open:o.isOpen,isNewProperty:!0,onOpenChange:o.setIsOpen,propertyLabel:j,onSave:o.confirm,showRegex:m,keyEditable:d})]})})}exports.JsonSchemaBuilder=We;exports.PropertyEditDialog=$;
|
|
2
2
|
//# sourceMappingURL=index.cjs.map
|