json-schema-builder-react 0.0.7 → 0.0.9

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 CHANGED
@@ -292,7 +292,7 @@ If you only need to edit a single property without the full builder UI, you can
292
292
 
293
293
  ```tsx
294
294
  import { useState } from 'react';
295
- import { PropertyEditDialog, TypeLabelsProvider } from 'json-schema-builder-react';
295
+ import { PropertyEditDialog } from 'json-schema-builder-react';
296
296
  import type { PropertyData } from 'json-schema-builder-react';
297
297
 
298
298
  function PropertyEditor() {
@@ -308,7 +308,7 @@ function PropertyEditor() {
308
308
  });
309
309
 
310
310
  return (
311
- <TypeLabelsProvider>
311
+ <>
312
312
  <button onClick={() => setIsOpen(true)}>
313
313
  Edit Property
314
314
  </button>
@@ -324,14 +324,17 @@ function PropertyEditor() {
324
324
  }}
325
325
  isNewProperty={false}
326
326
  showRegex={true}
327
+ typeLabels={{
328
+ string: 'Text',
329
+ number: 'Number',
330
+ boolean: 'Yes/No'
331
+ }}
327
332
  />
328
- </TypeLabelsProvider>
333
+ </>
329
334
  );
330
335
  }
331
336
  ```
332
337
 
333
- **Note:** When using `PropertyEditDialog` standalone, you must wrap it with `TypeLabelsProvider`.
334
-
335
338
  ## API Reference
336
339
 
337
340
  ### JsonSchemaBuilder Props
@@ -365,6 +368,7 @@ function PropertyEditor() {
365
368
  | `propertyLabel` | `{ singular: string, plural: string }` | `{ singular: 'Property', plural: 'Properties' }` | Custom labels |
366
369
  | `showRegex` | `boolean` | `false` | Show regex pattern field for strings |
367
370
  | `keyEditable` | `boolean` | `false` | Allow editing property key |
371
+ | `typeLabels` | `TypeLabels` | Default labels | Custom labels for property types |
368
372
 
369
373
  ### Customizing Type Labels
370
374
 
@@ -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)
@@ -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,10 +1,11 @@
1
1
  import type { PropertyData } from "@/types/schema";
2
+ import type { TypeLabels } from "@/contexts/SchemaBuilderContext";
2
3
  /**
3
4
  * PropertyEditDialog - A standalone dialog for editing a single JSON schema property
4
5
  *
5
6
  * @example
6
7
  * ```tsx
7
- * import { PropertyEditDialog, TypeLabelsProvider } from 'json-schema-builder-react';
8
+ * import { PropertyEditDialog } from 'json-schema-builder-react';
8
9
  *
9
10
  * function MyApp() {
10
11
  * const [isOpen, setIsOpen] = useState(false);
@@ -17,17 +18,16 @@ import type { PropertyData } from "@/types/schema";
17
18
  * });
18
19
  *
19
20
  * return (
20
- * <TypeLabelsProvider>
21
- * <PropertyEditDialog
22
- * property={property}
23
- * open={isOpen}
24
- * onOpenChange={setIsOpen}
25
- * onSave={(updated) => {
26
- * setProperty(updated);
27
- * setIsOpen(false);
28
- * }}
29
- * />
30
- * </TypeLabelsProvider>
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
31
  * );
32
32
  * }
33
33
  * ```
@@ -45,6 +45,7 @@ interface PropertyEditDialogProps {
45
45
  };
46
46
  showRegex?: boolean;
47
47
  keyEditable?: boolean;
48
+ typeLabels?: TypeLabels;
48
49
  }
49
- export default function PropertyEditDialog({ property, open, onOpenChange, onSave, isArrayItem, isNewProperty, propertyLabel, showRegex, keyEditable, }: 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;
50
51
  export {};
@@ -0,0 +1,31 @@
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
+ }
12
+ interface SchemaBuilderContextValue {
13
+ getTypeLabel: (type: PropertyType) => string;
14
+ typeLabels: Record<PropertyType, string>;
15
+ propertyLabel: {
16
+ singular: string;
17
+ plural: string;
18
+ };
19
+ showRegex: boolean;
20
+ keyEditable: boolean;
21
+ }
22
+ export declare function SchemaBuilderProvider({ children, config, }: {
23
+ children: React.ReactNode;
24
+ config?: SchemaBuilderConfig;
25
+ }): import("react/jsx-runtime").JSX.Element;
26
+ export declare function useSchemaBuilderConfig(): SchemaBuilderContextValue;
27
+ export declare const useTypeLabels: () => {
28
+ getTypeLabel: (type: PropertyType) => string;
29
+ typeLabels: Record<PropertyType, string>;
30
+ };
31
+ 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"),j=require("react"),je=require("@radix-ui/react-slot"),ae=require("class-variance-authority"),ve=require("clsx"),ye=require("tailwind-merge"),u=require("lucide-react"),be=require("@radix-ui/react-tooltip"),Ne=require("@radix-ui/react-select"),we=require("@radix-ui/react-dialog"),Ce=require("@radix-ui/react-label"),ke=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(be),w=F(Ne),L=F(we),ie=F(Ce),J=F(ke);function f(...t){return ye.twMerge(ve.clsx(t))}const Se=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?je.Slot:"button";return e.jsx(n,{className:f(Se({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 Ie=E.Provider,Te=E.Root,De=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 V=w.Root,H=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 qe=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}));qe.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 Pe=v.forwardRef(({className:t,...a},s)=>e.jsx(w.Separator,{ref:s,className:f("-mx-1 my-1 h-px bg-muted",t),...a}));Pe.displayName=w.Separator.displayName;const Oe=L.Root,Le=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(Le,{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 Re=v.forwardRef(({className:t,...a},s)=>e.jsx(L.Description,{ref:s,className:f("text-sm text-muted-foreground",t),...a}));Re.displayName=L.Description.displayName;const Ee=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(Ee(),t),...a}));N.displayName=ie.Root.displayName;const U=v.forwardRef(({className:t,...a},s)=>e.jsx(J.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(J.Indicator,{className:f("grid place-content-center text-current"),children:e.jsx(u.Check,{className:"h-4 w-4"})})}));U.displayName=J.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 Fe=t=>t.trim().toLowerCase().replace(/[^\w\s]/g,"").replace(/\s+/g,"_"),ze=(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=Fe(t.title);i("key",o)}},handleKeyChange:o=>{(s||r)&&i("key",o)},handleFieldChange:i,handleConstraintChange:(o,d)=>{a({...t,[o]:d})}}},X={string:"String",number:"Number",integer:"Integer",boolean:"Boolean",object:"Object",array:"Array",null:"Null",file:"File"},he=j.createContext({getTypeLabel:t=>X[t],typeLabels:X});function xe({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 fe(){return j.useContext(he)}function $({property:t,open:a,onOpenChange:s,onSave:r,isArrayItem:i=!1,isNewProperty:l=!1,propertyLabel:n={singular:"Property",plural:"Properties"},showRegex:m=!1,keyEditable:C=!1}){var O;const{typeLabels:o}=fe(),[d,p]=j.useState(t);j.useEffect(()=>{a&&p(t)},[t,a]);const{handleTitleChange:y,handleTitleBlur:g,handleKeyChange:x,handleFieldChange:S,handleConstraintChange:b}=ze(d,p,l,C),P=()=>{var c;(c=d.title)!=null&&c.trim()&&(r(d),s(!1))},h=()=>{p(t),s(!1)};return e.jsx(Oe,{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:c=>S("type",c),"data-testid":"select-type-dialog",children:[e.jsx(M,{children:e.jsx(H,{})}),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:g,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(V,{value:d.items.type,onValueChange:c=>p({...d,items:{...d.items,type:c}}),children:[e.jsx(M,{children:e.jsx(H,{})}),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=>p({...d,items:{...d.items,title:c.target.value}}),placeholder:"Item Title"})]}),e.jsxs(I,{variant:"ghost",size:"sm",className:"mt-2",onClick:()=>p({...d,items:void 0}),children:["Remove ",o.array," Item Schema"]})]}):e.jsxs(I,{variant:"outline",size:"sm",onClick:()=>{p({...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(U,{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:K=>{const T=K.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(U,{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()},p=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:p,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 g=y??(r?r():null);m(g),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}=fe(),o=ee(),d=se(t.title||t.key||"",h=>a({...t,title:h}),{allowEmpty:!1}),p=se(t.description||"",h=>a({...t,description:h||void 0}),{allowEmpty:!0}),y=Be(t,a),g=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(V,{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(H,{})}),e.jsx(_,{children:y.availableTypes.map(h=>e.jsx(k,{value:h,children:C[h]},h))})]}):e.jsx(Ie,{children:e.jsxs(Te,{children:[e.jsx(De,{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:g.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:p.isEditing?e.jsx(D,{value:p.value,onChange:h=>p.handleChange(h.target.value),onBlur:p.handleBlur,onKeyDown:p.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:p.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:p.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:g.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=>g.updateChild(h.id,O),onDelete:()=>g.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($,{property:o.data||t,open:o.isOpen,onOpenChange:o.setIsOpen,onSave:h=>{a(h),o.close()},isArrayItem:i,isNewProperty:!1,showRegex:l,keyEditable:n}),g.addChildDialog.isOpen&&g.addChildDialog.data&&e.jsx($,{property:g.addChildDialog.data,open:g.addChildDialog.isOpen,isNewProperty:!0,onOpenChange:g.addChildDialog.setIsOpen,onSave:g.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()}),ge=(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=()=>{ge(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]),p=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]),g=j.useCallback(()=>{ge(t,"schema.json")},[t]);return{properties:l,metadata:n,addProperty:m,updateProperty:C,deleteProperty:o,clearAll:d,updateMetadata:p,importSchema:y,downloadSchema:g}};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:p=!1,keyEditable:y=!1}){const{properties:g,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()},K=async()=>{await c()};return e.jsx(xe,{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:K,"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:g.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)}),g.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:g.map(T=>e.jsx(G,{property:T,onUpdate:R=>b(T.id,R),onDelete:()=>P(T.id),showRegex:p,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:[g.length," ",g.length===1?d.singular:d.plural]}),e.jsxs("span",{children:[g.filter(T=>T.required).length," required"]})]})]})]}),g.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($,{property:q.data,open:q.isOpen,isNewProperty:!0,onOpenChange:q.setIsOpen,propertyLabel:d,onSave:q.confirm,showRegex:p,keyEditable:y})]})})}exports.JsonSchemaBuilder=We;exports.PropertyEditDialog=$;exports.TypeLabelsProvider=xe;
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"),re=require("class-variance-authority"),Ne=require("clsx"),we=require("tailwind-merge"),x=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 F(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=F(y),O=F(Ce),w=F(ke),R=F(Se),le=F(Ie),U=F(Te);function u(...t){return we.twMerge(Ne.clsx(t))}const De=re.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:n=!1,...i},l)=>{const r=n?be.Slot:"button";return e.jsx(r,{className:u(De({variant:a,size:s,className:t})),ref:l,...i})});I.displayName="Button";const T=v.forwardRef(({className:t,type:a,...s},n)=>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:n,...s}));T.displayName="Input";const qe=O.Provider,Ee=O.Root,Re=O.Trigger,oe=v.forwardRef(({className:t,sideOffset:a=4,...s},n)=>e.jsx(O.Portal,{children:e.jsx(O.Content,{ref:n,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})}));oe.displayName=O.Content.displayName;const X=w.Root,G=w.Value,$=v.forwardRef(({className:t,children:a,...s},n)=>e.jsxs(w.Trigger,{ref:n,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(w.Icon,{asChild:!0,children:e.jsx(x.ChevronDown,{className:"h-4 w-4 opacity-50"})})]}));$.displayName=w.Trigger.displayName;const de=v.forwardRef(({className:t,...a},s)=>e.jsx(w.ScrollUpButton,{ref:s,className:u("flex cursor-default items-center justify-center py-1",t),...a,children:e.jsx(x.ChevronUp,{className:"h-4 w-4"})}));de.displayName=w.ScrollUpButton.displayName;const ce=v.forwardRef(({className:t,...a},s)=>e.jsx(w.ScrollDownButton,{ref:s,className:u("flex cursor-default items-center justify-center py-1",t),...a,children:e.jsx(x.ChevronDown,{className:"h-4 w-4"})}));ce.displayName=w.ScrollDownButton.displayName;const K=v.forwardRef(({className:t,children:a,position:s="popper",...n},i)=>e.jsx(w.Portal,{children:e.jsxs(w.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,...n,children:[e.jsx(de,{}),e.jsx(w.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(ce,{})]})}));K.displayName=w.Content.displayName;const Pe=v.forwardRef(({className:t,...a},s)=>e.jsx(w.Label,{ref:s,className:u("px-2 py-1.5 text-sm font-semibold",t),...a}));Pe.displayName=w.Label.displayName;const S=v.forwardRef(({className:t,children:a,...s},n)=>e.jsxs(w.Item,{ref:n,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(w.ItemIndicator,{children:e.jsx(x.Check,{className:"h-4 w-4"})})}),e.jsx(w.ItemText,{children:a})]}));S.displayName=w.Item.displayName;const Le=v.forwardRef(({className:t,...a},s)=>e.jsx(w.Separator,{ref:s,className:u("-mx-1 my-1 h-px bg-muted",t),...a}));Le.displayName=w.Separator.displayName;const Oe=R.Root,Fe=R.Portal,me=v.forwardRef(({className:t,...a},s)=>e.jsx(R.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}));me.displayName=R.Overlay.displayName;const ue=v.forwardRef(({className:t,children:a,...s},n)=>e.jsxs(Fe,{children:[e.jsx(me,{}),e.jsxs(R.Content,{ref:n,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(R.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(x.X,{className:"h-4 w-4"}),e.jsx("span",{className:"sr-only",children:"Close"})]})]})]}));ue.displayName=R.Content.displayName;const he=({className:t,...a})=>e.jsx("div",{className:u("flex flex-col space-y-1.5 text-center sm:text-left",t),...a});he.displayName="DialogHeader";const xe=({className:t,...a})=>e.jsx("div",{className:u("flex flex-col-reverse sm:flex-row sm:justify-end sm:space-x-2",t),...a});xe.displayName="DialogFooter";const fe=v.forwardRef(({className:t,...a},s)=>e.jsx(R.Title,{ref:s,className:u("text-lg font-semibold leading-none tracking-tight",t),...a}));fe.displayName=R.Title.displayName;const ze=v.forwardRef(({className:t,...a},s)=>e.jsx(R.Description,{ref:s,className:u("text-sm text-muted-foreground",t),...a}));ze.displayName=R.Description.displayName;const Be=re.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(le.Root,{ref:s,className:u(Be(),t),...a}));N.displayName=le.Root.displayName;const Q=v.forwardRef(({className:t,...a},s)=>e.jsx(U.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(U.Indicator,{className:u("grid place-content-center text-current"),children:e.jsx(x.Check,{className:"h-4 w-4"})})}));Q.displayName=U.Root.displayName;const te=v.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}));te.displayName="Textarea";const Ae=t=>t.trim().toLowerCase().replace(/[^\w\s]/g,"").replace(/\s+/g,"_"),Me=(t,a,s=!1,n=!1)=>{const i=(f,p)=>{a({...t,[f]:p})};return{handleTitleChange:f=>{i("title",f)},handleTitleBlur:()=>{if(s&&t.title){const f=Ae(t.title);i("key",f)}},handleKeyChange:f=>{(s||n)&&i("key",f)},handleFieldChange:i,handleConstraintChange:(f,p)=>{a({...t,[f]:p})}}},W={string:"String",number:"Number",integer:"Integer",boolean:"Boolean",object:"Object",array:"Array",null:"Null",file:"File"},_={getTypeLabel:t=>W[t],typeLabels:W,propertyLabel:{singular:"property",plural:"properties"},showRegex:!1,keyEditable:!1},pe=y.createContext(_);function _e({children:t,config:a={}}){const s={...W,...a.typeLabels},n=a.propertyLabel||_.propertyLabel,i=a.showRegex??_.showRegex,l=a.keyEditable??_.keyEditable,r=c=>s[c]||c;return e.jsx(pe.Provider,{value:{getTypeLabel:r,typeLabels:s,propertyLabel:n,showRegex:i,keyEditable:l},children:t})}function ge(){return y.useContext(pe)}function J({property:t,open:a,onOpenChange:s,onSave:n,isArrayItem:i=!1,isNewProperty:l=!1,propertyLabel:r,showRegex:c,keyEditable:D,typeLabels:f}){const p=ge(),m=f||p.typeLabels,b=r||p.propertyLabel,j=c??p.showRegex,g=D??p.keyEditable,[o,k]=y.useState(t);y.useEffect(()=>{a&&k(t)},[t,a]);const{handleTitleChange:q,handleTitleBlur:E,handleKeyChange:h,handleFieldChange:L,handleConstraintChange:C}=Me(o,k,l,g),V=()=>{o.title?.trim()&&(n(o),s(!1))},H=()=>{k(t),s(!1)};return e.jsx(Oe,{open:a,onOpenChange:s,children:e.jsxs(ue,{className:"max-w-2xl max-h-[80vh] flex flex-col gap-0 p-0","data-testid":"dialog-edit-property",children:[e.jsx(he,{className:"px-6 pt-6 pb-4 shrink-0",children:e.jsx(fe,{children:l?`Add ${b.singular}`:`Edit ${b.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(X,{value:o.type,onValueChange:d=>L("type",d),"data-testid":"select-type-dialog",children:[e.jsx($,{children:e.jsx(G,{})}),e.jsxs(K,{children:[e.jsx(S,{value:"string",children:m.string}),e.jsx(S,{value:"number",children:m.number}),e.jsx(S,{value:"integer",children:m.integer}),e.jsx(S,{value:"boolean",children:m.boolean}),e.jsx(S,{value:"object",children:m.object}),e.jsx(S,{value:"array",children:m.array}),e.jsx(S,{value:"file",children:m.file}),e.jsx(S,{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(T,{value:o.title||"",onChange:d=>q(d.target.value),onBlur:E,placeholder:"Property Title","data-testid":"input-title-dialog",required:!0}),!l&&o.key&&e.jsxs("p",{className:"text-xs text-muted-foreground font-mono",children:["Key: ",o.key]})]}),(l||g)&&e.jsxs("div",{className:"space-y-2",children:[e.jsx(N,{children:"Key"}),e.jsx(T,{value:o.key,onChange:d=>h(d.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(te,{placeholder:"Optional description",value:o.description||"",onChange:d=>L("description",d.target.value),rows:2,"data-testid":"input-edit-description"})]}),o.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"]}),o.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(X,{value:o.items.type,onValueChange:d=>k({...o,items:{...o.items,type:d}}),children:[e.jsx($,{children:e.jsx(G,{})}),e.jsxs(K,{children:[e.jsx(S,{value:"string",children:m.string}),e.jsx(S,{value:"number",children:m.number}),e.jsx(S,{value:"integer",children:m.integer}),e.jsx(S,{value:"boolean",children:m.boolean}),e.jsx(S,{value:"object",children:m.object}),e.jsx(S,{value:"array",children:m.array}),e.jsx(S,{value:"file",children:m.file}),e.jsx(S,{value:"null",children:m.null})]})]})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx(N,{children:"Item Title"}),e.jsx(T,{value:o.items.title||"",onChange:d=>k({...o,items:{...o.items,title:d.target.value}}),placeholder:"Item Title"})]}),e.jsxs(I,{variant:"ghost",size:"sm",className:"mt-2",onClick:()=>k({...o,items:void 0}),children:["Remove ",m.array," Item Schema"]})]}):e.jsxs(I,{variant:"outline",size:"sm",onClick:()=>{k({...o,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(Q,{id:"prop-required",checked:o.required,onCheckedChange:d=>L("required",d),"data-testid":"checkbox-edit-required"}),e.jsx(N,{htmlFor:"prop-required",className:"cursor-pointer",children:"Required field"})]}),o.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(T,{id:"min-length",type:"number",placeholder:"0",value:o.minLength||"",onChange:d=>C("minLength",d.target.value?parseInt(d.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(T,{id:"max-length",type:"number",placeholder:"∞",value:o.maxLength||"",onChange:d=>C("maxLength",d.target.value?parseInt(d.target.value):void 0),"data-testid":"input-edit-maxlength"})]})]}),j&&e.jsxs("div",{className:"space-y-2",children:[e.jsx(N,{htmlFor:"pattern",children:"Pattern (regex)"}),e.jsx(T,{id:"pattern",placeholder:"^[a-z]+$",value:o.pattern||"",onChange:d=>C("pattern",d.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:[...o.enum||[],""].map((d,P)=>e.jsx(T,{placeholder:P===(o.enum?.length||0)?"Add new value...":"Enum value",value:d,onChange:ye=>{const B=ye.target.value,A=o.enum||[];if(P===A.length)B.trim()&&C("enum",[...A,B.trim()]);else if(B.trim()){const z=[...A];z[P]=B.trim(),C("enum",z)}else{const z=A.filter((st,ve)=>ve!==P);C("enum",z.length>0?z:void 0)}},"data-testid":`input-edit-enum-${P}`},P))}),e.jsx("p",{className:"text-xs text-muted-foreground",children:"Enter allowed values (empty fields will be removed)"})]})]})]}),(o.type==="number"||o.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(T,{id:"minimum",type:"number",placeholder:"-∞",value:o.minimum??"",onChange:d=>C("minimum",d.target.value?parseFloat(d.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(T,{id:"maximum",type:"number",placeholder:"∞",value:o.maximum??"",onChange:d=>C("maximum",d.target.value?parseFloat(d.target.value):void 0),"data-testid":"input-edit-maximum"})]})]})})]}),o.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(T,{id:"min-items",type:"number",placeholder:"0",value:o.minItems||"",onChange:d=>C("minItems",d.target.value?parseInt(d.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(T,{id:"max-items",type:"number",placeholder:"∞",value:o.maxItems||"",onChange:d=>C("maxItems",d.target.value?parseInt(d.target.value):void 0),"data-testid":"input-edit-maxitems"})]})]}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(Q,{id:"unique-items",checked:o.uniqueItems||!1,onCheckedChange:d=>C("uniqueItems",d),"data-testid":"checkbox-edit-unique"}),e.jsx(N,{htmlFor:"unique-items",className:"cursor-pointer",children:"All items must be unique"})]})]})]})]}),e.jsxs(xe,{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:V,"data-testid":"button-save",disabled:!o.title?.trim(),children:"Save Changes"})]})]})})}function ne(t,a,s={}){const{allowEmpty:n=!1,onEditStart:i,onEditCancel:l}=s,[r,c]=y.useState(!1),[D,f]=y.useState(t);y.useEffect(()=>{r||f(t)},[t,r]);const p=()=>{f(t),c(!0),i?.()},m=g=>{f(g)},b=()=>{const g=D.trim();if(!n&&!g){f(t),c(!1);return}g!==t&&a(g),c(!1)};return{isEditing:r,value:D,startEdit:p,handleChange:m,handleBlur:b,handleKeyDown:g=>{g.key==="Enter"?b():g.key==="Escape"&&(f(t),c(!1),l?.())}}}function $e(t,a){const[s,n]=y.useState(!1);return{isChangingType:s,setIsChangingType:n,handleTypeChange:r=>{const c={...t,type:r};r!=="string"&&(delete c.minLength,delete c.maxLength,delete c.pattern,delete c.enum),r!=="number"&&r!=="integer"&&(delete c.minimum,delete c.maximum),r!=="array"&&(delete c.minItems,delete c.maxItems,delete c.uniqueItems,delete c.items),r!=="object"&&delete c.children,a(c),n(!1)},availableTypes:["string","number","integer","boolean","object","array","file"]}}const se=()=>`${Date.now()}-${Math.random()}`;function ae(t={}){const{onConfirm:a,onCancel:s,createInitialData:n}=t,[i,l]=y.useState(!1),[r,c]=y.useState(null),D=b=>{const j=b??(n?n():null);c(j),l(!0)},f=()=>{l(!1),c(null),s?.()};return{isOpen:i,data:r,open:D,close:f,confirm:b=>{a?.(b),l(!1),c(null)},setIsOpen:b=>{b?l(!0):f()}}}function Ke(t,a){const s=ae({createInitialData:()=>({id:se(),key:"",type:"string",required:!1}),onConfirm:l=>{a({...t,children:[...t.children||[],l]})}});return{addChild:()=>s.open(),updateChild:(l,r)=>{const c=t.children.map(D=>D.id===l?r:D);a({...t,children:c})},deleteChild:l=>{const r=t.children.filter(c=>c.id!==l);a({...t,children:r})},addChildDialog:{isOpen:s.isOpen,data:s.data,setIsOpen:s.setIsOpen,confirm:s.confirm}}}function Y({property:t,onUpdate:a,onDelete:s,level:n=1,isArrayItem:i=!1}){const{getTypeLabel:l,typeLabels:r,showRegex:c,keyEditable:D}=ge(),f=ae(),p=ne(t.title||t.key||"",h=>a({...t,title:h}),{allowEmpty:!1}),m=ne(t.description||"",h=>a({...t,description:h||void 0}),{allowEmpty:!0}),b=$e(t,a),j=Ke(t,a),g=`h${Math.min(n,6)}`,o=t.type==="object",k=o&&t.children&&t.children.length>0,q={1:"text-lg font-semibold",2:"text-base",3:"text-base",4:"text-base",5:"text-sm",6:"text-sm"}[n]||"text-sm",E={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:()=>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(x.Asterisk,{className:"w-6 h-6 text-primary"}):e.jsx(x.Asterisk,{className:"w-6 h-6 text-border"})}),p.isEditing?e.jsx(T,{value:p.value,onChange:h=>p.handleChange(h.target.value),onBlur:p.handleBlur,onKeyDown:p.handleKeyDown,autoFocus:!0,className:q,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:`${q} cursor-pointer hover:text-primary transition-colors leading-none`,onClick:p.startEdit,children:t.title||t.key||e.jsx("span",{className:"text-muted-foreground italic",children:"unnamed"})}),b.isChangingType?e.jsxs(X,{value:t.type,onValueChange:h=>b.handleTypeChange(h),open:b.isChangingType,onOpenChange:b.setIsChangingType,children:[e.jsx($,{className:"w-[140px] h-7",children:e.jsx(G,{})}),e.jsx(K,{children:b.availableTypes.map(h=>e.jsx(S,{value:h,children:r[h]},h))})]}):e.jsx(qe,{children:e.jsxs(Ee,{children:[e.jsx(Re,{asChild:!0,children:e.jsxs("button",{onClick:()=>b.setIsChangingType(!0),className:"cursor-pointer hover:bg-accent rounded p-0.5 -mt-0.5 transition-colors",children:[t.type==="string"&&e.jsx(x.Type,{className:u(E,"text-muted-foreground")}),t.type==="number"&&e.jsx(x.Hash,{className:u(E,"text-muted-foreground")}),t.type==="integer"&&e.jsx(x.Hash,{className:u(E,"text-muted-foreground")}),t.type==="boolean"&&e.jsx(x.CheckSquare,{className:u(E,"text-muted-foreground")}),t.type==="object"&&e.jsx(x.Braces,{className:u(E,"text-muted-foreground")}),t.type==="array"&&e.jsx(x.List,{className:u(E,"text-muted-foreground")}),t.type==="file"&&e.jsx(x.FileText,{className:u(E,"text-muted-foreground")})]})}),e.jsxs(oe,{children:[l(t.type),t.type==="array"&&t.items?` of ${l(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:"h-4 w-4",onClick:j.addChild,"data-testid":`button-add-child-${t.id}`,children:e.jsx(x.Plus,{})})]}),e.jsx("div",{className:"flex-1",children:m.isEditing?e.jsx(T,{value:m.value,onChange:h=>m.handleChange(h.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(I,{variant:"ghost",size:"icon",className:"h-7 w-7",onClick:()=>f.open(t),"data-testid":`button-edit-${t.id}`,children:e.jsx(x.Pencil,{className:"w-3 h-3"})}),o&&t.type!=="object"&&e.jsx(I,{variant:"ghost",size:"icon",className:"h-7 w-7",onClick:j.addChild,"data-testid":`button-add-child-${t.id}`,children:e.jsx(x.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(x.Trash2,{className:"w-3 h-3"})})]})]}),k&&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(h=>e.jsx(Y,{property:h,onUpdate:L=>j.updateChild(h.id,L),onDelete:()=>j.deleteChild(h.id),level:n+1},h.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:[l("array")," Items"]}),e.jsx(Y,{property:t.items,onUpdate:h=>a({...t,items:h}),onDelete:()=>a({...t,items:void 0}),level:n+1,isArrayItem:!0})]}),e.jsx(J,{property:f.data||t,open:f.isOpen,onOpenChange:f.setIsOpen,onSave:h=>{a(h),f.close()},isArrayItem:i,isNewProperty:!1}),j.addChildDialog.isOpen&&j.addChildDialog.data&&e.jsx(J,{property:j.addChildDialog.data,open:j.addChildDialog.isOpen,isNewProperty:!0,onOpenChange:j.addChildDialog.setIsOpen,onSave:j.addChildDialog.confirm})]})}const ie=v.forwardRef(({className:t,...a},s)=>e.jsx("div",{ref:s,className:u("rounded-xl border bg-card text-card-foreground",t),...a}));ie.displayName="Card";const Je=v.forwardRef(({className:t,...a},s)=>e.jsx("div",{ref:s,className:u("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:u("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:u("text-sm text-muted-foreground",t),...a}));He.displayName="CardDescription";const Ue=v.forwardRef(({className:t,...a},s)=>e.jsx("div",{ref:s,className:u("p-6 pt-0",t),...a}));Ue.displayName="CardContent";const Xe=v.forwardRef(({className:t,...a},s)=>e.jsx("div",{ref:s,className:u("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 l=new FileReader;l.onload=r=>{try{const c=JSON.parse(r.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()}),je=(t,a="schema.json")=>{const s=JSON.stringify(t,null,2),n=new Blob([s],{type:"application/json"}),i=URL.createObjectURL(n),l=document.createElement("a");l.href=i,l.download=a,document.body.appendChild(l),l.click(),document.body.removeChild(l),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)},l=()=>{je(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(x.CheckCircle2,{className:"w-4 h-4"}):e.jsx(x.Copy,{className:"w-4 h-4"})}),e.jsx(I,{variant:"outline",size:"sm",onClick:l,"data-testid":"button-download",children:e.jsx(x.Download,{className:"w-4 h-4"})})]})]}),e.jsx("div",{className:"flex-1 overflow-auto",children:e.jsx(ie,{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}){const[i,l]=y.useState(!1);return e.jsxs(ie,{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(x.ChevronDown,{className:"w-4 h-4"}):e.jsx(x.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(T,{id:"schema-title",placeholder:"My Schema",value:t,onChange:r=>n("title",r.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(te,{id:"schema-description",placeholder:"Describe your schema...",value:a,onChange:r=>n("description",r.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(T,{id:"schema-version",placeholder:"1.0.0",value:s,onChange:r=>n("version",r.target.value),"data-testid":"input-version"})]})]})]})}const M=(t,a,s=!0)=>{const n={type:"object"};s&&a&&(a.title&&(n.title=a.title),a.description&&(n.description=a.description));const i=Z(t);Object.keys(i).length>0&&(n.properties=i);const l=t.filter(r=>r.required&&r.key).map(r=>r.key);return l.length>0&&(n.required=l),n},Z=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=Z([s.items])[s.items.key]||{type:s.items.type})),s.type==="object"&&s.children&&s.children.length>0){i.properties=Z(s.children);const l=s.children.filter(r=>r.required&&r.key).map(r=>r.key);l.length>0&&(i.required=l)}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=ee(t.properties,Array.isArray(t.required)?t.required:[])),a},ee=(t,a=[])=>t?Object.entries(t).filter(([,s])=>typeof s=="object").map(([s,n])=>{const i=n;let l=typeof i.type=="string"?i.type:"string";l==="string"&&i.format==="filename"&&(l="file");const r={id:se(),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&&(r.minLength=i.minLength),i.maxLength!==void 0&&(r.maxLength=i.maxLength),i.pattern&&(r.pattern=i.pattern),i.enum&&Array.isArray(i.enum)&&(r.enum=i.enum),i.minimum!==void 0&&(r.minimum=i.minimum),i.maximum!==void 0&&(r.maximum=i.maximum),i.minItems!==void 0&&(r.minItems=i.minItems),i.maxItems!==void 0&&(r.maxItems=i.maxItems),i.uniqueItems&&(r.uniqueItems=i.uniqueItems),r.type==="array"&&i.items&&typeof i.items=="object"&&!Array.isArray(i.items)&&(r.items=ee({item:i.items},[]).find(c=>c.key==="item")),i.properties&&typeof i.properties=="object"&&(r.children=ee(i.properties,Array.isArray(i.required)?i.required:[])),r}):[],Ze=({schema:t,onChange:a,includeMetadata:s=!0})=>{const{properties:n,metadata:i}=y.useMemo(()=>Ye(t),[t]),l=n,r=i||{title:"",description:"",version:""},c=y.useCallback(()=>({id:se(),key:"",type:"string",required:!1}),[]),D=y.useCallback((g,o)=>{const k=l.some(h=>h.id===g);let q;k?q=l.map(h=>h.id===g?o:h):q=[...l,o];const E=M(q,r,s);a(E)},[l,r,s,a]),f=y.useCallback(g=>{const o=l.filter(q=>q.id!==g),k=M(o,r,s);a(k)},[l,r,s,a]),p=y.useCallback(()=>{const o=M([],{title:"",description:""},s);a(o)},[s,a]),m=y.useCallback((g,o)=>{const k={...r,[g]:o},q=M(l,k,s);a(q)},[l,r,s,a]),b=y.useCallback(async()=>{const g=await Ge();a(g)},[a]),j=y.useCallback(()=>{je(t,"schema.json")},[t]);return{properties:l,metadata:r,addProperty:c,updateProperty:D,deleteProperty:f,clearAll:p,updateMetadata:m,importSchema:b,downloadSchema:j}};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(I,{variant:"ghost",size:"icon",onClick:s,"data-testid":"button-theme-toggle",children:t==="light"?e.jsx(x.Moon,{className:"w-4 h-4"}):e.jsx(x.Sun,{className:"w-4 h-4"})})}function tt({schema:t,onChange:a,showMetadata:s=!1,showImport:n=!0,showClear:i=!0,showOutput:l=!0,showHeader:r=!0,className:c="",showSummary:D=!1,typeLabels:f,propertyLabel:p={singular:"property",plural:"properties"},showRegex:m=!1,keyEditable:b=!1}){const{properties:j,metadata:g,addProperty:o,updateProperty:k,deleteProperty:q,clearAll:E,updateMetadata:h,importSchema:L}=Ze({schema:t,onChange:a,includeMetadata:s}),C=ae({createInitialData:()=>o(),onConfirm:d=>{k(d.id,d)}}),V=()=>{E()},H=async()=>{await L()};return e.jsx(_e,{config:{typeLabels:f,propertyLabel:p,showRegex:m,keyEditable:b},children:e.jsxs("div",{className:`${c} flex flex-col json-schema-builder-react`,children:[r&&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:[n&&e.jsx(I,{variant:"outline",size:"sm",onClick:H,"data-testid":"button-import",children:e.jsx(x.Upload,{className:"w-4 h-4"})}),i&&e.jsx(I,{variant:"outline",size:"sm",onClick:V,disabled:j.length===0,"data-testid":"button-clear",children:e.jsx(x.Trash2,{className:"w-4 h-4"})}),e.jsx(et,{})]})}),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(We,{title:g.title,description:g.description,version:g.version,onUpdate:(d,P)=>h(d,P)}),j.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(x.Plus,{className:"w-8 h-8 text-muted-foreground"})}),e.jsxs("h2",{className:"text-lg font-medium mb-2",children:["No ",p.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"," ",p.singular]}),e.jsxs(I,{onClick:()=>C.open(),"data-testid":"button-add-first",children:[e.jsx(x.Plus,{className:"w-4 h-4 mr-2"}),"Add ",p.singular]})]}):e.jsxs(e.Fragment,{children:[e.jsx("div",{className:"space-y-1",children:j.map(d=>e.jsx(Y,{property:d,onUpdate:P=>k(d.id,P),onDelete:()=>q(d.id)},d.id))}),D&&e.jsxs("div",{className:"pt-4 border-t flex items-center justify-between text-sm text-muted-foreground",children:[e.jsxs("span",{children:[j.length," ",j.length===1?p.singular:p.plural]}),e.jsxs("span",{children:[j.filter(d=>d.required).length," required"]})]})]})]}),j.length>0&&e.jsx("div",{className:"border-t p-2 pt-4 bg-background",children:e.jsxs(I,{onClick:()=>C.open(),className:"w-full",variant:"outline","data-testid":"button-add-property",children:[e.jsx(x.Plus,{className:"w-4 h-4"}),"Add ",p.singular]})})]})}),l&&e.jsx("div",{className:"w-2/5",children:e.jsx(Qe,{schema:t})})]}),C.isOpen&&C.data&&e.jsx(J,{property:C.data,open:C.isOpen,isNewProperty:!0,onOpenChange:C.setIsOpen,onSave:C.confirm})]})})}exports.JsonSchemaBuilder=tt;exports.PropertyEditDialog=J;
@@ -5,6 +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 { TypeLabelsProvider } from "./contexts/TypeLabelsContext";
9
- export type { TypeLabels } from "./contexts/TypeLabelsContext";
8
+ export type { TypeLabels } from "./contexts/SchemaBuilderContext";
10
9
  export type { PropertyData, PropertyType } from "./types/schema";