json-schema-builder-react 0.0.8 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,4 +1,4 @@
1
- import { type TypeLabels } from "@/contexts/TypeLabelsContext";
1
+ import { type TypeLabels } from "@/contexts/SchemaBuilderContext";
2
2
  export interface JsonSchemaBuilderProps {
3
3
  /**
4
4
  * The JSON schema object (controlled)
@@ -62,8 +62,13 @@ export interface JsonSchemaBuilderProps {
62
62
  * @default false
63
63
  */
64
64
  keyEditable?: boolean;
65
+ /**
66
+ * Whether the schema is readonly (no editing allowed)
67
+ * @default false
68
+ */
69
+ readonly?: boolean;
65
70
  }
66
71
  /**
67
72
  * A visual JSON Schema builder component that allows building JSON schemas interactively
68
73
  */
69
- export declare function JsonSchemaBuilder({ schema, onChange, showMetadata, showImport, showClear, showOutput, showHeader, className, showSummary, typeLabels, propertyLabel, showRegex, keyEditable, }: JsonSchemaBuilderProps): import("react/jsx-runtime").JSX.Element;
74
+ export declare function JsonSchemaBuilder({ schema, onChange, showMetadata, showImport, showClear, showOutput, showHeader, className, showSummary, typeLabels, propertyLabel, showRegex, keyEditable, readonly, }: JsonSchemaBuilderProps): import("react/jsx-runtime").JSX.Element;
@@ -5,8 +5,6 @@ interface PropertyDocumentProps {
5
5
  onDelete: () => void;
6
6
  level?: number;
7
7
  isArrayItem?: boolean;
8
- showRegex?: boolean;
9
- keyEditable?: boolean;
10
8
  }
11
- export default function PropertyDocument({ property, onUpdate, onDelete, level, isArrayItem, showRegex, keyEditable, }: PropertyDocumentProps): import("react/jsx-runtime").JSX.Element;
9
+ export default function PropertyDocument({ property, onUpdate, onDelete, level, isArrayItem, }: PropertyDocumentProps): import("react/jsx-runtime").JSX.Element;
12
10
  export {};
@@ -1,5 +1,5 @@
1
1
  import type { PropertyData } from "@/types/schema";
2
- import type { TypeLabels } from "@/contexts/TypeLabelsContext";
2
+ import type { TypeLabels } from "@/contexts/SchemaBuilderContext";
3
3
  /**
4
4
  * PropertyEditDialog - A standalone dialog for editing a single JSON schema property
5
5
  *
@@ -47,5 +47,5 @@ interface PropertyEditDialogProps {
47
47
  keyEditable?: boolean;
48
48
  typeLabels?: TypeLabels;
49
49
  }
50
- export default function PropertyEditDialog({ property, open, onOpenChange, onSave, isArrayItem, isNewProperty, propertyLabel, showRegex, keyEditable, typeLabels: customTypeLabels, }: PropertyEditDialogProps): import("react/jsx-runtime").JSX.Element;
50
+ export default function PropertyEditDialog({ property, open, onOpenChange, onSave, isArrayItem, isNewProperty, propertyLabel: customPropertyLabel, showRegex: customShowRegex, keyEditable: customKeyEditable, typeLabels: customTypeLabels, }: PropertyEditDialogProps): import("react/jsx-runtime").JSX.Element;
51
51
  export {};
@@ -3,6 +3,7 @@ interface SchemaMetadataProps {
3
3
  description: string;
4
4
  version: string;
5
5
  onUpdate: (field: string, value: string) => void;
6
+ readonly?: boolean;
6
7
  }
7
- export default function SchemaMetadata({ title, description, version, onUpdate, }: SchemaMetadataProps): import("react/jsx-runtime").JSX.Element;
8
+ export default function SchemaMetadata({ title, description, version, onUpdate, readonly, }: SchemaMetadataProps): import("react/jsx-runtime").JSX.Element;
8
9
  export {};
@@ -0,0 +1,33 @@
1
+ import type { PropertyType } from "@/types/schema";
2
+ export type TypeLabels = Partial<Record<PropertyType, string>>;
3
+ interface SchemaBuilderConfig {
4
+ typeLabels?: TypeLabels;
5
+ propertyLabel?: {
6
+ singular: string;
7
+ plural: string;
8
+ };
9
+ showRegex?: boolean;
10
+ keyEditable?: boolean;
11
+ readonly?: boolean;
12
+ }
13
+ interface SchemaBuilderContextValue {
14
+ getTypeLabel: (type: PropertyType) => string;
15
+ typeLabels: Record<PropertyType, string>;
16
+ propertyLabel: {
17
+ singular: string;
18
+ plural: string;
19
+ };
20
+ showRegex: boolean;
21
+ keyEditable: boolean;
22
+ readonly: boolean;
23
+ }
24
+ export declare function SchemaBuilderProvider({ children, config, }: {
25
+ children: React.ReactNode;
26
+ config?: SchemaBuilderConfig;
27
+ }): import("react/jsx-runtime").JSX.Element;
28
+ export declare function useSchemaBuilderConfig(): SchemaBuilderContextValue;
29
+ export declare const useTypeLabels: () => {
30
+ getTypeLabel: (type: PropertyType) => string;
31
+ typeLabels: Record<PropertyType, string>;
32
+ };
33
+ export {};
@@ -3,7 +3,7 @@ export interface UsePropertyEditorReturn {
3
3
  handleTitleChange: (title: string) => void;
4
4
  handleTitleBlur: () => void;
5
5
  handleKeyChange: (key: string) => void;
6
- handleFieldChange: (field: keyof PropertyData, value: any) => void;
7
- handleConstraintChange: (field: string, value: any) => void;
6
+ handleFieldChange: (field: keyof PropertyData, value: unknown) => void;
7
+ handleConstraintChange: (field: string, value: unknown) => void;
8
8
  }
9
9
  export declare const usePropertyEditor: (property: PropertyData, onUpdate: (property: PropertyData) => void, isNewProperty?: boolean, keyEditable?: boolean) => UsePropertyEditorReturn;
@@ -1,2 +1 @@
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
- //# sourceMappingURL=index.cjs.map
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("react/jsx-runtime"),y=require("react"),be=require("@radix-ui/react-slot"),le=require("class-variance-authority"),Ne=require("clsx"),we=require("tailwind-merge"),f=require("lucide-react"),Ce=require("@radix-ui/react-tooltip"),ke=require("@radix-ui/react-select"),Se=require("@radix-ui/react-dialog"),Ie=require("@radix-ui/react-label"),Te=require("@radix-ui/react-checkbox");function z(t){const a=Object.create(null,{[Symbol.toStringTag]:{value:"Module"}});if(t){for(const s in t)if(s!=="default"){const n=Object.getOwnPropertyDescriptor(t,s);Object.defineProperty(a,s,n.get?n:{enumerable:!0,get:()=>t[s]})}}return a.default=t,Object.freeze(a)}const v=z(y),F=z(Ce),N=z(ke),P=z(Se),de=z(Ie),X=z(Te);function x(...t){return we.twMerge(Ne.clsx(t))}const De=le.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"}}),T=v.forwardRef(({className:t,variant:a,size:s,asChild:n=!1,...i},r)=>{const l=n?be.Slot:"button";return e.jsx(l,{className:x(De({variant:a,size:s,className:t})),ref:r,...i})});T.displayName="Button";const q=v.forwardRef(({className:t,type:a,...s},n)=>e.jsx("input",{type:a,className:x("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:n,...s}));q.displayName="Input";const qe=F.Provider,Re=F.Root,Ee=F.Trigger,oe=v.forwardRef(({className:t,sideOffset:a=4,...s},n)=>e.jsx(F.Portal,{children:e.jsx(F.Content,{ref:n,sideOffset:a,className:x("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})}));oe.displayName=F.Content.displayName;const G=N.Root,Q=N.Value,J=v.forwardRef(({className:t,children:a,...s},n)=>e.jsxs(N.Trigger,{ref:n,className:x("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(N.Icon,{asChild:!0,children:e.jsx(f.ChevronDown,{className:"h-4 w-4 opacity-50"})})]}));J.displayName=N.Trigger.displayName;const ce=v.forwardRef(({className:t,...a},s)=>e.jsx(N.ScrollUpButton,{ref:s,className:x("flex cursor-default items-center justify-center py-1",t),...a,children:e.jsx(f.ChevronUp,{className:"h-4 w-4"})}));ce.displayName=N.ScrollUpButton.displayName;const me=v.forwardRef(({className:t,...a},s)=>e.jsx(N.ScrollDownButton,{ref:s,className:x("flex cursor-default items-center justify-center py-1",t),...a,children:e.jsx(f.ChevronDown,{className:"h-4 w-4"})}));me.displayName=N.ScrollDownButton.displayName;const V=v.forwardRef(({className:t,children:a,position:s="popper",...n},i)=>e.jsx(N.Portal,{children:e.jsxs(N.Content,{ref:i,className:x("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,...n,children:[e.jsx(ce,{}),e.jsx(N.Viewport,{className:x("p-1",s==="popper"&&"h-[var(--radix-select-trigger-height)] w-full min-w-[var(--radix-select-trigger-width)]"),children:a}),e.jsx(me,{})]})}));V.displayName=N.Content.displayName;const Pe=v.forwardRef(({className:t,...a},s)=>e.jsx(N.Label,{ref:s,className:x("px-2 py-1.5 text-sm font-semibold",t),...a}));Pe.displayName=N.Label.displayName;const I=v.forwardRef(({className:t,children:a,...s},n)=>e.jsxs(N.Item,{ref:n,className:x("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(N.ItemIndicator,{children:e.jsx(f.Check,{className:"h-4 w-4"})})}),e.jsx(N.ItemText,{children:a})]}));I.displayName=N.Item.displayName;const Le=v.forwardRef(({className:t,...a},s)=>e.jsx(N.Separator,{ref:s,className:x("-mx-1 my-1 h-px bg-muted",t),...a}));Le.displayName=N.Separator.displayName;const Oe=P.Root,Fe=P.Portal,ue=v.forwardRef(({className:t,...a},s)=>e.jsx(P.Overlay,{ref:s,className:x("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}));ue.displayName=P.Overlay.displayName;const he=v.forwardRef(({className:t,children:a,...s},n)=>e.jsxs(Fe,{children:[e.jsx(ue,{}),e.jsxs(P.Content,{ref:n,className:x("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(P.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"})]})]})]}));he.displayName=P.Content.displayName;const xe=({className:t,...a})=>e.jsx("div",{className:x("flex flex-col space-y-1.5 text-center sm:text-left",t),...a});xe.displayName="DialogHeader";const fe=({className:t,...a})=>e.jsx("div",{className:x("flex flex-col-reverse sm:flex-row sm:justify-end sm:space-x-2",t),...a});fe.displayName="DialogFooter";const pe=v.forwardRef(({className:t,...a},s)=>e.jsx(P.Title,{ref:s,className:x("text-lg font-semibold leading-none tracking-tight",t),...a}));pe.displayName=P.Title.displayName;const ze=v.forwardRef(({className:t,...a},s)=>e.jsx(P.Description,{ref:s,className:x("text-sm text-muted-foreground",t),...a}));ze.displayName=P.Description.displayName;const Be=le.cva("text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70"),b=v.forwardRef(({className:t,...a},s)=>e.jsx(de.Root,{ref:s,className:x(Be(),t),...a}));b.displayName=de.Root.displayName;const W=v.forwardRef(({className:t,...a},s)=>e.jsx(X.Root,{ref:s,className:x("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(X.Indicator,{className:x("grid place-content-center text-current"),children:e.jsx(f.Check,{className:"h-4 w-4"})})}));W.displayName=X.Root.displayName;const se=v.forwardRef(({className:t,...a},s)=>e.jsx("textarea",{className:x("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}));se.displayName="Textarea";const Ae=t=>t.trim().toLowerCase().replace(/[^\w\s]/g,"").replace(/\s+/g,"_"),Me=(t,a,s=!1,n=!1)=>{const i=(u,g)=>{a({...t,[u]:g})};return{handleTitleChange:u=>{i("title",u)},handleTitleBlur:()=>{if(s&&t.title){const u=Ae(t.title);i("key",u)}},handleKeyChange:u=>{(s||n)&&i("key",u)},handleFieldChange:i,handleConstraintChange:(u,g)=>{a({...t,[u]:g})}}},Y={string:"String",number:"Number",integer:"Integer",boolean:"Boolean",object:"Object",array:"Array",null:"Null",file:"File"},M={getTypeLabel:t=>Y[t],typeLabels:Y,propertyLabel:{singular:"property",plural:"properties"},showRegex:!1,keyEditable:!1,readonly:!1},ge=y.createContext(M);function _e({children:t,config:a={}}){const s={...Y,...a.typeLabels},n=a.propertyLabel||M.propertyLabel,i=a.showRegex??M.showRegex,r=a.keyEditable??M.keyEditable,l=a.readonly??M.readonly,o=C=>s[C]||C;return e.jsx(ge.Provider,{value:{getTypeLabel:o,typeLabels:s,propertyLabel:n,showRegex:i,keyEditable:r,readonly:l},children:t})}function je(){return y.useContext(ge)}function H({property:t,open:a,onOpenChange:s,onSave:n,isArrayItem:i=!1,isNewProperty:r=!1,propertyLabel:l,showRegex:o,keyEditable:C,typeLabels:u}){const g=je(),h=u||g.typeLabels,j=l||g.propertyLabel,w=o??g.showRegex,c=C??g.keyEditable,[d,k]=y.useState(t);y.useEffect(()=>{a&&k(t)},[t,a]);const{handleTitleChange:E,handleTitleBlur:O,handleKeyChange:D,handleFieldChange:p,handleConstraintChange:R}=Me(d,k,r,c),L=()=>{d.title?.trim()&&(n(d),s(!1))},U=()=>{k(t),s(!1)};return e.jsx(Oe,{open:a,onOpenChange:s,children:e.jsxs(he,{className:"max-w-2xl max-h-[80vh] flex flex-col gap-0 p-0","data-testid":"dialog-edit-property",children:[e.jsx(xe,{className:"px-6 pt-6 pb-4 shrink-0",children:e.jsx(pe,{children:r?`Add ${j.singular}`:`Edit ${j.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(b,{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(G,{value:d.type,onValueChange:m=>p("type",m),"data-testid":"select-type-dialog",children:[e.jsx(J,{children:e.jsx(Q,{})}),e.jsxs(V,{children:[e.jsx(I,{value:"string",children:h.string}),e.jsx(I,{value:"number",children:h.number}),e.jsx(I,{value:"integer",children:h.integer}),e.jsx(I,{value:"boolean",children:h.boolean}),e.jsx(I,{value:"object",children:h.object}),e.jsx(I,{value:"array",children:h.array}),e.jsx(I,{value:"file",children:h.file}),e.jsx(I,{value:"null",children:h.null})]})]})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsxs(b,{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(q,{value:d.title||"",onChange:m=>E(m.target.value),onBlur:O,placeholder:"Property Title","data-testid":"input-title-dialog",required:!0}),!r&&d.key&&e.jsxs("p",{className:"text-xs text-muted-foreground font-mono",children:["Key: ",d.key]})]}),(r||c)&&e.jsxs("div",{className:"space-y-2",children:[e.jsx(b,{children:"Key"}),e.jsx(q,{value:d.key,onChange:m=>D(m.target.value),placeholder:"property_key","data-testid":"input-key-dialog"}),!r&&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(b,{children:"Description"}),e.jsx(se,{placeholder:"Optional description",value:d.description||"",onChange:m=>p("description",m.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(b,{className:"font-semibold text-xs text-muted-foreground",children:[h.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(b,{children:"Item Type"}),e.jsxs(G,{value:d.items.type,onValueChange:m=>k({...d,items:{...d.items,type:m}}),children:[e.jsx(J,{children:e.jsx(Q,{})}),e.jsxs(V,{children:[e.jsx(I,{value:"string",children:h.string}),e.jsx(I,{value:"number",children:h.number}),e.jsx(I,{value:"integer",children:h.integer}),e.jsx(I,{value:"boolean",children:h.boolean}),e.jsx(I,{value:"object",children:h.object}),e.jsx(I,{value:"array",children:h.array}),e.jsx(I,{value:"file",children:h.file}),e.jsx(I,{value:"null",children:h.null})]})]})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx(b,{children:"Item Title"}),e.jsx(q,{value:d.items.title||"",onChange:m=>k({...d,items:{...d.items,title:m.target.value}}),placeholder:"Item Title"})]}),e.jsxs(T,{variant:"ghost",size:"sm",className:"mt-2",onClick:()=>k({...d,items:void 0}),children:["Remove ",h.array," Item Schema"]})]}):e.jsxs(T,{variant:"outline",size:"sm",onClick:()=>{k({...d,items:{id:Date.now().toString()+Math.random(),key:"item",type:"string",required:!1}})},children:["Add ",h.array," Item Schema"]})]}),!i&&e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(W,{id:"prop-required",checked:d.required,onCheckedChange:m=>p("required",m),"data-testid":"checkbox-edit-required"}),e.jsx(b,{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:[h.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(b,{htmlFor:"min-length",children:"Minimum Length"}),e.jsx(q,{id:"min-length",type:"number",placeholder:"0",value:d.minLength||"",onChange:m=>R("minLength",m.target.value?parseInt(m.target.value):void 0),"data-testid":"input-edit-minlength"})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx(b,{htmlFor:"max-length",children:"Maximum Length"}),e.jsx(q,{id:"max-length",type:"number",placeholder:"∞",value:d.maxLength||"",onChange:m=>R("maxLength",m.target.value?parseInt(m.target.value):void 0),"data-testid":"input-edit-maxlength"})]})]}),w&&e.jsxs("div",{className:"space-y-2",children:[e.jsx(b,{htmlFor:"pattern",children:"Pattern (regex)"}),e.jsx(q,{id:"pattern",placeholder:"^[a-z]+$",value:d.pattern||"",onChange:m=>R("pattern",m.target.value),className:"font-mono text-sm","data-testid":"input-edit-pattern"})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx(b,{children:"Enum Values"}),e.jsx("div",{className:"space-y-2",children:[...d.enum||[],""].map((m,S)=>e.jsx(q,{placeholder:S===(d.enum?.length||0)?"Add new value...":"Enum value",value:m,onChange:B=>{const _=B.target.value,$=d.enum||[];if(S===$.length)_.trim()&&R("enum",[...$,_.trim()]);else if(_.trim()){const A=[...$];A[S]=_.trim(),R("enum",A)}else{const A=$.filter((st,ve)=>ve!==S);R("enum",A.length>0?A:void 0)}},"data-testid":`input-edit-enum-${S}`},S))}),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(b,{htmlFor:"minimum",children:"Minimum Value"}),e.jsx(q,{id:"minimum",type:"number",placeholder:"-∞",value:d.minimum??"",onChange:m=>R("minimum",m.target.value?parseFloat(m.target.value):void 0),"data-testid":"input-edit-minimum"})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx(b,{htmlFor:"maximum",children:"Maximum Value"}),e.jsx(q,{id:"maximum",type:"number",placeholder:"∞",value:d.maximum??"",onChange:m=>R("maximum",m.target.value?parseFloat(m.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:[h.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(b,{htmlFor:"min-items",children:"Minimum Items"}),e.jsx(q,{id:"min-items",type:"number",placeholder:"0",value:d.minItems||"",onChange:m=>R("minItems",m.target.value?parseInt(m.target.value):void 0),"data-testid":"input-edit-minitems"})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx(b,{htmlFor:"max-items",children:"Maximum Items"}),e.jsx(q,{id:"max-items",type:"number",placeholder:"∞",value:d.maxItems||"",onChange:m=>R("maxItems",m.target.value?parseInt(m.target.value):void 0),"data-testid":"input-edit-maxitems"})]})]}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(W,{id:"unique-items",checked:d.uniqueItems||!1,onCheckedChange:m=>R("uniqueItems",m),"data-testid":"checkbox-edit-unique"}),e.jsx(b,{htmlFor:"unique-items",className:"cursor-pointer",children:"All items must be unique"})]})]})]})]}),e.jsxs(fe,{className:"px-6 py-4 border-t bg-background shrink-0",children:[e.jsx(T,{variant:"outline",onClick:U,"data-testid":"button-cancel",children:"Cancel"}),e.jsx(T,{onClick:L,"data-testid":"button-save",disabled:!d.title?.trim(),children:"Save Changes"})]})]})})}function re(t,a,s={}){const{allowEmpty:n=!1,onEditStart:i,onEditCancel:r}=s,[l,o]=y.useState(!1),[C,u]=y.useState(t);y.useEffect(()=>{l||u(t)},[t,l]);const g=()=>{u(t),o(!0),i?.()},h=c=>{u(c)},j=()=>{const c=C.trim();if(!n&&!c){u(t),o(!1);return}c!==t&&a(c),o(!1)};return{isEditing:l,value:C,startEdit:g,handleChange:h,handleBlur:j,handleKeyDown:c=>{c.key==="Enter"?j():c.key==="Escape"&&(u(t),o(!1),r?.())}}}function $e(t,a){const[s,n]=y.useState(!1);return{isChangingType:s,setIsChangingType:n,handleTypeChange:l=>{const o={...t,type:l};l!=="string"&&(delete o.minLength,delete o.maxLength,delete o.pattern,delete o.enum),l!=="number"&&l!=="integer"&&(delete o.minimum,delete o.maximum),l!=="array"&&(delete o.minItems,delete o.maxItems,delete o.uniqueItems,delete o.items),l!=="object"&&delete o.children,a(o),n(!1)},availableTypes:["string","number","integer","boolean","object","array","file"]}}const ae=()=>`${Date.now()}-${Math.random()}`;function ie(t={}){const{onConfirm:a,onCancel:s,createInitialData:n}=t,[i,r]=y.useState(!1),[l,o]=y.useState(null),C=j=>{const w=j??(n?n():null);o(w),r(!0)},u=()=>{r(!1),o(null),s?.()};return{isOpen:i,data:l,open:C,close:u,confirm:j=>{a?.(j),r(!1),o(null)},setIsOpen:j=>{j?r(!0):u()}}}function Ke(t,a){const s=ie({createInitialData:()=>({id:ae(),key:"",type:"string",required:!1}),onConfirm:r=>{a({...t,children:[...t.children||[],r]})}});return{addChild:()=>s.open(),updateChild:(r,l)=>{const o=t.children.map(C=>C.id===r?l:C);a({...t,children:o})},deleteChild:r=>{const l=t.children.filter(o=>o.id!==r);a({...t,children:l})},addChildDialog:{isOpen:s.isOpen,data:s.data,setIsOpen:s.setIsOpen,confirm:s.confirm}}}function Z({property:t,onUpdate:a,onDelete:s,level:n=1,isArrayItem:i=!1}){const{getTypeLabel:r,typeLabels:l,showRegex:o,keyEditable:C,readonly:u}=je(),g=ie(),h=re(t.title||t.key||"",p=>a({...t,title:p}),{allowEmpty:!1}),j=re(t.description||"",p=>a({...t,description:p||void 0}),{allowEmpty:!0}),w=$e(t,a),c=Ke(t,a),d=`h${Math.min(n,6)}`,k=t.type==="object",E=k&&t.children&&t.children.length>0,O={1:"text-lg font-semibold",2:"text-base",3:"text-base",4:"text-base",5:"text-sm",6:"text-sm"}[n]||"text-sm",D={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"}[n]||"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:()=>!u&&a({...t,required:!t.required}),className:u?"shrink-0 -mt-[3px] cursor-default":"shrink-0 transition-all hover:scale-110 -mt-[3px]",title:u?t.required?"Required field":"Optional field":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"})}),h.isEditing?e.jsx(q,{value:h.value,onChange:p=>h.handleChange(p.target.value),onBlur:h.handleBlur,onKeyDown:h.handleKeyDown,autoFocus:!0,className:O,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(d,{className:u?`${O} leading-none`:`${O} cursor-pointer hover:text-primary transition-colors leading-none`,onClick:u?void 0:h.startEdit,children:t.title||t.key||e.jsx("span",{className:"text-muted-foreground italic",children:"unnamed"})}),w.isChangingType?e.jsxs(G,{value:t.type,onValueChange:p=>w.handleTypeChange(p),open:w.isChangingType,onOpenChange:w.setIsChangingType,children:[e.jsx(J,{className:"w-[140px] h-7",children:e.jsx(Q,{})}),e.jsx(V,{children:w.availableTypes.map(p=>e.jsx(I,{value:p,children:l[p]},p))})]}):e.jsx(qe,{children:e.jsxs(Re,{children:[e.jsx(Ee,{asChild:!0,children:e.jsxs("button",{onClick:()=>!u&&w.setIsChangingType(!0),className:u?"rounded p-0.5 -mt-0.5 cursor-default":"cursor-pointer hover:bg-accent rounded p-0.5 -mt-0.5 transition-colors",children:[t.type==="string"&&e.jsx(f.Type,{className:x(D,"text-muted-foreground")}),t.type==="number"&&e.jsx(f.Hash,{className:x(D,"text-muted-foreground")}),t.type==="integer"&&e.jsx(f.Hash,{className:x(D,"text-muted-foreground")}),t.type==="boolean"&&e.jsx(f.CheckSquare,{className:x(D,"text-muted-foreground")}),t.type==="object"&&e.jsx(f.Braces,{className:x(D,"text-muted-foreground")}),t.type==="array"&&e.jsx(f.List,{className:x(D,"text-muted-foreground")}),t.type==="file"&&e.jsx(f.FileText,{className:x(D,"text-muted-foreground")})]})}),e.jsxs(oe,{children:[r(t.type),t.type==="array"&&t.items?` of ${r(t.items.type)}`:"",!u&&e.jsx("div",{className:"text-xs text-muted-foreground mt-1",children:"Click to change type"})]})]})}),t.type==="object"&&!u&&e.jsx(T,{variant:"ghost",size:"icon",className:"h-4 w-4",onClick:c.addChild,"data-testid":`button-add-child-${t.id}`,children:e.jsx(f.Plus,{})})]}),e.jsx("div",{className:"flex-1",children:j.isEditing?e.jsx(q,{value:j.value,onChange:p=>j.handleChange(p.target.value),onBlur:j.handleBlur,onKeyDown:j.handleKeyDown,autoFocus:!0,className:"text-sm flex-1",placeholder:"Enter description"}):e.jsx(e.Fragment,{children:t.description?e.jsx("p",{className:u?"text-sm text-muted-foreground flex-1 min-w-[200px]":"text-sm text-muted-foreground flex-1 min-w-[200px] cursor-pointer hover:text-foreground transition-colors","data-testid":`text-description-${t.id}`,onClick:u?void 0:j.startEdit,children:t.description}):!u&&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:j.startEdit,children:"Add description..."})})})]})]})}),!u&&e.jsxs("div",{className:"flex items-center gap-1 opacity-0 group-hover:opacity-100 transition-opacity shrink-0",children:[e.jsx(T,{variant:"ghost",size:"icon",className:"h-7 w-7",onClick:()=>g.open(t),"data-testid":`button-edit-${t.id}`,children:e.jsx(f.Pencil,{className:"w-3 h-3"})}),k&&t.type!=="object"&&e.jsx(T,{variant:"ghost",size:"icon",className:"h-7 w-7",onClick:c.addChild,"data-testid":`button-add-child-${t.id}`,children:e.jsx(f.Plus,{className:"w-3 h-3"})}),e.jsx(T,{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"})})]})]}),E&&e.jsx("div",{className:n===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(p=>e.jsx(Z,{property:p,onUpdate:R=>c.updateChild(p.id,R),onDelete:()=>c.deleteChild(p.id),level:n+1},p.id))}),t.type==="array"&&t.items&&e.jsxs("div",{className:n===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:[r("array")," Items"]}),e.jsx(Z,{property:t.items,onUpdate:p=>a({...t,items:p}),onDelete:()=>a({...t,items:void 0}),level:n+1,isArrayItem:!0})]}),e.jsx(H,{property:g.data||t,open:g.isOpen,onOpenChange:g.setIsOpen,onSave:p=>{a(p),g.close()},isArrayItem:i,isNewProperty:!1}),c.addChildDialog.isOpen&&c.addChildDialog.data&&e.jsx(H,{property:c.addChildDialog.data,open:c.addChildDialog.isOpen,isNewProperty:!0,onOpenChange:c.addChildDialog.setIsOpen,onSave:c.addChildDialog.confirm})]})}const ne=v.forwardRef(({className:t,...a},s)=>e.jsx("div",{ref:s,className:x("rounded-xl border bg-card text-card-foreground",t),...a}));ne.displayName="Card";const Je=v.forwardRef(({className:t,...a},s)=>e.jsx("div",{ref:s,className:x("flex flex-col space-y-1.5 p-6",t),...a}));Je.displayName="CardHeader";const Ve=v.forwardRef(({className:t,...a},s)=>e.jsx("div",{ref:s,className:x("font-semibold leading-none tracking-tight",t),...a}));Ve.displayName="CardTitle";const He=v.forwardRef(({className:t,...a},s)=>e.jsx("div",{ref:s,className:x("text-sm text-muted-foreground",t),...a}));He.displayName="CardDescription";const Ue=v.forwardRef(({className:t,...a},s)=>e.jsx("div",{ref:s,className:x("p-6 pt-0",t),...a}));Ue.displayName="CardContent";const Xe=v.forwardRef(({className:t,...a},s)=>e.jsx("div",{ref:s,className:x("flex items-center p-6 pt-0",t),...a}));Xe.displayName="CardFooter";const Ge=()=>new Promise((t,a)=>{const s=document.createElement("input");s.type="file",s.accept=".json",s.onchange=n=>{const i=n.target.files?.[0];if(!i){a(new Error("No file selected"));return}const r=new FileReader;r.onload=l=>{try{const o=JSON.parse(l.target?.result);t(o)}catch{a(new Error("Invalid JSON file"))}},r.onerror=()=>a(new Error("Failed to read file")),r.readAsText(i)},s.click()}),ye=(t,a="schema.json")=>{const s=JSON.stringify(t,null,2),n=new Blob([s],{type:"application/json"}),i=URL.createObjectURL(n),r=document.createElement("a");r.href=i,r.download=a,document.body.appendChild(r),r.click(),document.body.removeChild(r),URL.revokeObjectURL(i)};function Qe({schema:t}){const[a,s]=y.useState(!1),n=JSON.stringify(t,null,2),i=async()=>{await navigator.clipboard.writeText(n),s(!0),setTimeout(()=>s(!1),2e3)},r=()=>{ye(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(T,{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(T,{variant:"outline",size:"sm",onClick:r,"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(ne,{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:n})})})})]})}function We({title:t,description:a,version:s,onUpdate:n,readonly:i=!1}){const[r,l]=y.useState(!1);return e.jsxs(ne,{className:"p-4",children:[e.jsxs(T,{variant:"ghost",onClick:()=>l(!r),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"}),r?e.jsx(f.ChevronDown,{className:"w-4 h-4"}):e.jsx(f.ChevronRight,{className:"w-4 h-4"})]}),r&&e.jsxs("div",{className:"mt-4 space-y-4",children:[e.jsxs("div",{className:"space-y-2",children:[e.jsx(b,{htmlFor:"schema-title",className:"text-xs text-muted-foreground",children:"Title"}),e.jsx(q,{id:"schema-title",placeholder:"My Schema",value:t,onChange:o=>n("title",o.target.value),"data-testid":"input-title",disabled:i})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx(b,{htmlFor:"schema-description",className:"text-xs text-muted-foreground",children:"Description"}),e.jsx(se,{id:"schema-description",placeholder:"Describe your schema...",value:a,onChange:o=>n("description",o.target.value),className:"resize-none",rows:3,"data-testid":"input-schema-description",disabled:i})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx(b,{htmlFor:"schema-version",className:"text-xs text-muted-foreground",children:"Version"}),e.jsx(q,{id:"schema-version",placeholder:"1.0.0",value:s,onChange:o=>n("version",o.target.value),"data-testid":"input-version",disabled:i})]})]})]})}const K=(t,a,s=!0)=>{const n={type:"object"};s&&a&&(a.title&&(n.title=a.title),a.description&&(n.description=a.description));const i=ee(t);Object.keys(i).length>0&&(n.properties=i);const r=t.filter(l=>l.required&&l.key).map(l=>l.key);return r.length>0&&(n.required=r),n},ee=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=ee([s.items])[s.items.key]||{type:s.items.type})),s.type==="object"&&s.children&&s.children.length>0){i.properties=ee(s.children);const r=s.children.filter(l=>l.required&&l.key).map(l=>l.key);r.length>0&&(i.required=r)}a[s.key]=i}),a},Ye=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=te(t.properties,Array.isArray(t.required)?t.required:[])),a},te=(t,a=[])=>t?Object.entries(t).filter(([,s])=>typeof s=="object").map(([s,n])=>{const i=n;let r=typeof i.type=="string"?i.type:"string";r==="string"&&i.format==="filename"&&(r="file");const l={id:ae(),key:s,title:typeof i.title=="string"?i.title:void 0,type:r,description:typeof i.description=="string"?i.description:void 0,required:a.includes(s)};return i.minLength!==void 0&&(l.minLength=i.minLength),i.maxLength!==void 0&&(l.maxLength=i.maxLength),i.pattern&&(l.pattern=i.pattern),i.enum&&Array.isArray(i.enum)&&(l.enum=i.enum),i.minimum!==void 0&&(l.minimum=i.minimum),i.maximum!==void 0&&(l.maximum=i.maximum),i.minItems!==void 0&&(l.minItems=i.minItems),i.maxItems!==void 0&&(l.maxItems=i.maxItems),i.uniqueItems&&(l.uniqueItems=i.uniqueItems),l.type==="array"&&i.items&&typeof i.items=="object"&&!Array.isArray(i.items)&&(l.items=te({item:i.items},[]).find(o=>o.key==="item")),i.properties&&typeof i.properties=="object"&&(l.children=te(i.properties,Array.isArray(i.required)?i.required:[])),l}):[],Ze=({schema:t,onChange:a,includeMetadata:s=!0})=>{const{properties:n,metadata:i}=y.useMemo(()=>Ye(t),[t]),r=n,l=i||{title:"",description:"",version:""},o=y.useCallback(()=>({id:ae(),key:"",type:"string",required:!1}),[]),C=y.useCallback((c,d)=>{const k=r.some(D=>D.id===c);let E;k?E=r.map(D=>D.id===c?d:D):E=[...r,d];const O=K(E,l,s);a(O)},[r,l,s,a]),u=y.useCallback(c=>{const d=r.filter(E=>E.id!==c),k=K(d,l,s);a(k)},[r,l,s,a]),g=y.useCallback(()=>{const d=K([],{title:"",description:""},s);a(d)},[s,a]),h=y.useCallback((c,d)=>{const k={...l,[c]:d},E=K(r,k,s);a(E)},[r,l,s,a]),j=y.useCallback(async()=>{const c=await Ge();a(c)},[a]),w=y.useCallback(()=>{ye(t,"schema.json")},[t]);return{properties:r,metadata:l,addProperty:o,updateProperty:C,deleteProperty:u,clearAll:g,updateMetadata:h,importSchema:j,downloadSchema:w}};function et(){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 n=t==="light"?"dark":"light";a(n),localStorage.setItem("theme",n),document.documentElement.classList.toggle("dark",n==="dark")};return e.jsx(T,{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 tt({schema:t,onChange:a,showMetadata:s=!1,showImport:n=!0,showClear:i=!0,showOutput:r=!0,showHeader:l=!0,className:o="",showSummary:C=!1,typeLabels:u,propertyLabel:g={singular:"property",plural:"properties"},showRegex:h=!1,keyEditable:j=!1,readonly:w=!1}){const{properties:c,metadata:d,addProperty:k,updateProperty:E,deleteProperty:O,clearAll:D,updateMetadata:p,importSchema:R}=Ze({schema:t,onChange:a,includeMetadata:s}),L=ie({createInitialData:()=>k(),onConfirm:S=>{E(S.id,S)}}),U=()=>{D()},m=async()=>{await R()};return e.jsx(_e,{config:{typeLabels:u,propertyLabel:g,showRegex:h,keyEditable:j,readonly:w},children:e.jsxs("div",{className:`${o} flex flex-col json-schema-builder-react`,children:[l&&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:[!w&&n&&e.jsx(T,{variant:"outline",size:"sm",onClick:m,"data-testid":"button-import",children:e.jsx(f.Upload,{className:"w-4 h-4"})}),!w&&i&&e.jsx(T,{variant:"outline",size:"sm",onClick:U,disabled:c.length===0,"data-testid":"button-clear",children:e.jsx(f.Trash2,{className:"w-4 h-4"})}),e.jsx(et,{})]})}),e.jsxs("div",{className:"flex-1 flex overflow-hidden",children:[e.jsx("div",{className:r?"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(We,{title:d.title,description:d.description,version:d.version,onUpdate:(S,B)=>p(S,B),readonly:w}),c.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 ",g.plural," yet"]}),!w&&e.jsxs(e.Fragment,{children:[e.jsxs("p",{className:"text-sm text-muted-foreground mb-6 max-w-sm",children:["Start building your JSON schema by adding your first"," ",g.singular]}),e.jsxs(T,{onClick:()=>L.open(),"data-testid":"button-add-first",children:[e.jsx(f.Plus,{className:"w-4 h-4 mr-2"}),"Add ",g.singular]})]})]}):e.jsxs(e.Fragment,{children:[e.jsx("div",{className:"space-y-1",children:c.map(S=>e.jsx(Z,{property:S,onUpdate:B=>E(S.id,B),onDelete:()=>O(S.id)},S.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:[c.length," ",c.length===1?g.singular:g.plural]}),e.jsxs("span",{children:[c.filter(S=>S.required).length," required"]})]})]})]}),c.length>0&&!w&&e.jsx("div",{className:"border-t p-2 pt-4 bg-background",children:e.jsxs(T,{onClick:()=>L.open(),className:"w-full",variant:"outline","data-testid":"button-add-property",children:[e.jsx(f.Plus,{className:"w-4 h-4"}),"Add ",g.singular]})})]})}),r&&e.jsx("div",{className:"w-2/5",children:e.jsx(Qe,{schema:t})})]}),L.isOpen&&L.data&&e.jsx(H,{property:L.data,open:L.isOpen,isNewProperty:!0,onOpenChange:L.setIsOpen,onSave:L.confirm})]})})}exports.JsonSchemaBuilder=tt;exports.PropertyEditDialog=H;
@@ -5,5 +5,5 @@
5
5
  export { JsonSchemaBuilder } from "./components/JsonSchemaBuilder";
6
6
  export type { JsonSchemaBuilderProps } from "./components/JsonSchemaBuilder";
7
7
  export { default as PropertyEditDialog } from "./components/PropertyEditDialog";
8
- export type { TypeLabels } from "./contexts/TypeLabelsContext";
8
+ export type { TypeLabels } from "./contexts/SchemaBuilderContext";
9
9
  export type { PropertyData, PropertyType } from "./types/schema";