json-schema-builder-react 0.0.1
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/LICENSE +21 -0
- package/README.md +410 -0
- package/dist-lib/about.txt +6 -0
- package/dist-lib/android-chrome-192x192.png +0 -0
- package/dist-lib/android-chrome-512x512.png +0 -0
- package/dist-lib/apple-touch-icon.png +0 -0
- package/dist-lib/favicon-16x16.png +0 -0
- package/dist-lib/favicon-32x32.png +0 -0
- package/dist-lib/favicon.ico +0 -0
- package/dist-lib/index.cjs +2 -0
- package/dist-lib/index.cjs.map +1 -0
- package/dist-lib/index.js +3803 -0
- package/dist-lib/index.js.map +1 -0
- package/dist-lib/site.webmanifest +1 -0
- package/package.json +96 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Martin Arusalu
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,410 @@
|
|
|
1
|
+
# JSON Schema Builder
|
|
2
|
+
|
|
3
|
+
A beautiful, interactive React component for building and editing JSON schemas visually. Built with TypeScript, Tailwind CSS, and Radix UI.
|
|
4
|
+
|
|
5
|
+
- 📖 [View demo](https://martin-arusalu.github.io/json-schema-editor)
|
|
6
|
+
|
|
7
|
+
## Features
|
|
8
|
+
|
|
9
|
+
- 🎨 **Visual Editor** - Build JSON schemas with an intuitive drag-and-drop interface
|
|
10
|
+
- 📝 **Full JSON Schema Support** - Support for all JSON Schema types and constraints
|
|
11
|
+
- 🎯 **Type-Safe** - Written in TypeScript with full type definitions
|
|
12
|
+
- ✅ **Official JSON Schema Types** - Uses `@types/json-schema` for spec compliance
|
|
13
|
+
- 🎨 **Customizable** - Flexible API with extensive customization options
|
|
14
|
+
- 📦 **Headless Options** - Use just the hooks and utilities without UI
|
|
15
|
+
- 🌗 **Theme Support** - Built-in dark mode support
|
|
16
|
+
- ⚡ **Lightweight** - Tree-shakeable with minimal bundle size impact
|
|
17
|
+
|
|
18
|
+
## Installation
|
|
19
|
+
|
|
20
|
+
```bash
|
|
21
|
+
npm install json-schema-builder-react
|
|
22
|
+
# or
|
|
23
|
+
yarn add json-schema-builder-react
|
|
24
|
+
# or
|
|
25
|
+
pnpm add json-schema-builder-react
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
### Styling
|
|
29
|
+
|
|
30
|
+
This library uses Tailwind CSS utility classes. You'll need Tailwind CSS configured in your project.
|
|
31
|
+
|
|
32
|
+
#### 1. Install Tailwind CSS (if not already installed)
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
npm install -D tailwindcss postcss autoprefixer
|
|
36
|
+
npx tailwindcss init -p
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
#### 2. Configure Tailwind Content Paths
|
|
40
|
+
|
|
41
|
+
Add the library to your `tailwind.config.js`:
|
|
42
|
+
|
|
43
|
+
```js
|
|
44
|
+
/** @type {import('tailwindcss').Config} */
|
|
45
|
+
module.exports = {
|
|
46
|
+
content: [
|
|
47
|
+
'./src/**/*.{js,jsx,ts,tsx}',
|
|
48
|
+
'./node_modules/json-schema-editor/**/*.{js,jsx}', // Add this line
|
|
49
|
+
],
|
|
50
|
+
theme: {
|
|
51
|
+
extend: {},
|
|
52
|
+
},
|
|
53
|
+
plugins: [],
|
|
54
|
+
};
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
#### 3. Configure PostCSS
|
|
58
|
+
|
|
59
|
+
Create or update `postcss.config.js` in your project root:
|
|
60
|
+
|
|
61
|
+
```js
|
|
62
|
+
export default {
|
|
63
|
+
plugins: {
|
|
64
|
+
tailwindcss: {},
|
|
65
|
+
autoprefixer: {},
|
|
66
|
+
},
|
|
67
|
+
};
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
#### 4. Import Tailwind in your CSS
|
|
71
|
+
|
|
72
|
+
Add to your main CSS file (e.g., `src/index.css`):
|
|
73
|
+
|
|
74
|
+
```css
|
|
75
|
+
@tailwind base;
|
|
76
|
+
@tailwind components;
|
|
77
|
+
@tailwind utilities;
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
**Note:** The library components will automatically use your project's Tailwind theme (colors, spacing, etc.).
|
|
81
|
+
|
|
82
|
+
## Usage
|
|
83
|
+
|
|
84
|
+
### Basic Example
|
|
85
|
+
|
|
86
|
+
```tsx
|
|
87
|
+
import { JsonSchemaBuilder } from 'json-schema-builder-react';
|
|
88
|
+
|
|
89
|
+
function App() {
|
|
90
|
+
const handleSchemaChange = (schema) => {
|
|
91
|
+
console.log('Schema updated:', schema);
|
|
92
|
+
};
|
|
93
|
+
|
|
94
|
+
return (
|
|
95
|
+
<JsonSchemaBuilder
|
|
96
|
+
onSchemaChange={handleSchemaChange}
|
|
97
|
+
/>
|
|
98
|
+
);
|
|
99
|
+
}
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
### With Initial Schema
|
|
103
|
+
|
|
104
|
+
```tsx
|
|
105
|
+
import { JsonSchemaBuilder } from 'json-schema-builder-react';
|
|
106
|
+
|
|
107
|
+
const initialSchema = {
|
|
108
|
+
type: 'object',
|
|
109
|
+
properties: {
|
|
110
|
+
name: { type: 'string' },
|
|
111
|
+
age: { type: 'number' }
|
|
112
|
+
},
|
|
113
|
+
required: ['name']
|
|
114
|
+
};
|
|
115
|
+
|
|
116
|
+
function App() {
|
|
117
|
+
return (
|
|
118
|
+
<JsonSchemaBuilder
|
|
119
|
+
initialSchema={initialSchema}
|
|
120
|
+
onSchemaChange={(schema) => {
|
|
121
|
+
// Save to backend, localStorage, etc.
|
|
122
|
+
console.log(schema);
|
|
123
|
+
}}
|
|
124
|
+
/>
|
|
125
|
+
);
|
|
126
|
+
}
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
### Customized Layout
|
|
130
|
+
|
|
131
|
+
```tsx
|
|
132
|
+
import { JsonSchemaBuilder } from 'json-schema-builder-react';
|
|
133
|
+
|
|
134
|
+
function App() {
|
|
135
|
+
return (
|
|
136
|
+
<JsonSchemaBuilder
|
|
137
|
+
showMetadata={true}
|
|
138
|
+
showImport={false}
|
|
139
|
+
showClear={true}
|
|
140
|
+
showOutput={true}
|
|
141
|
+
className="h-[600px]"
|
|
142
|
+
typeLabels={{
|
|
143
|
+
string: 'Text',
|
|
144
|
+
boolean: 'Yes/No',
|
|
145
|
+
object: 'Form',
|
|
146
|
+
array: 'List',
|
|
147
|
+
}}
|
|
148
|
+
/>
|
|
149
|
+
);
|
|
150
|
+
}
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
## API Reference
|
|
154
|
+
|
|
155
|
+
### JsonSchemaBuilder Props
|
|
156
|
+
|
|
157
|
+
| Prop | Type | Default | Description |
|
|
158
|
+
|------|------|---------|-------------|
|
|
159
|
+
| `initialSchema` | `object` | `undefined` | Initial JSON schema to load |
|
|
160
|
+
| `onSchemaChange` | `(schema: any) => void` | `undefined` | Callback when schema changes |
|
|
161
|
+
| `showMetadata` | `boolean` | `true` | Show metadata fields (title, description, version) |
|
|
162
|
+
| `showImport` | `boolean` | `true` | Show import button |
|
|
163
|
+
| `showClear` | `boolean` | `true` | Show clear all button |
|
|
164
|
+
| `showOutput` | `boolean` | `true` | Show JSON output panel |
|
|
165
|
+
| `headerContent` | `ReactNode` | `undefined` | Custom header content |
|
|
166
|
+
| `className` | `string` | `"h-screen"` | Custom className for container |
|
|
167
|
+
| `typeLabels` | `TypeLabels` | Default labels | Custom labels for property types (e.g., `{ string: 'Text', boolean: 'Yes/No' }`) |
|
|
168
|
+
| `propertyLabel` | `{ singular: string, plural: string }` | `{ singular: 'property', plural: 'properties' }` | Custom labels for top-level properties (e.g., `{ singular: 'input', plural: 'inputs' }`) |
|
|
169
|
+
|
|
170
|
+
### Customizing Type Labels
|
|
171
|
+
|
|
172
|
+
You can customize how property types are displayed to your users:
|
|
173
|
+
|
|
174
|
+
```tsx
|
|
175
|
+
import { JsonSchemaBuilder } from 'json-schema-builder-react';
|
|
176
|
+
import type { TypeLabels } from 'json-schema-builder-react';
|
|
177
|
+
|
|
178
|
+
const customLabels: TypeLabels = {
|
|
179
|
+
string: 'Text',
|
|
180
|
+
number: 'Number',
|
|
181
|
+
integer: 'Whole Number',
|
|
182
|
+
boolean: 'Yes/No',
|
|
183
|
+
object: 'Form',
|
|
184
|
+
array: 'List',
|
|
185
|
+
null: 'Empty'
|
|
186
|
+
};
|
|
187
|
+
|
|
188
|
+
function App() {
|
|
189
|
+
return (
|
|
190
|
+
<JsonSchemaBuilder
|
|
191
|
+
typeLabels={customLabels}
|
|
192
|
+
onSchemaChange={(schema) => console.log(schema)}
|
|
193
|
+
/>
|
|
194
|
+
);
|
|
195
|
+
}
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
This affects:
|
|
199
|
+
- The type dropdown in the property editor
|
|
200
|
+
- Type labels shown in property cards
|
|
201
|
+
- Tooltips displaying type information
|
|
202
|
+
|
|
203
|
+
**Available types to customize:**
|
|
204
|
+
- `string` - Default: "String"
|
|
205
|
+
- `number` - Default: "Number"
|
|
206
|
+
- `integer` - Default: "Integer"
|
|
207
|
+
- `boolean` - Default: "Boolean"
|
|
208
|
+
- `object` - Default: "Object"
|
|
209
|
+
- `array` - Default: "Array"
|
|
210
|
+
- `null` - Default: "Null"
|
|
211
|
+
|
|
212
|
+
## Headless Usage
|
|
213
|
+
|
|
214
|
+
Use just the hooks and utilities without the UI components:
|
|
215
|
+
|
|
216
|
+
```tsx
|
|
217
|
+
import { useSchemaBuilder, generateSchema } from 'json-schema-builder-react';
|
|
218
|
+
|
|
219
|
+
function MyCustomEditor() {
|
|
220
|
+
const {
|
|
221
|
+
properties,
|
|
222
|
+
metadata,
|
|
223
|
+
schema,
|
|
224
|
+
addProperty,
|
|
225
|
+
updateProperty,
|
|
226
|
+
deleteProperty,
|
|
227
|
+
} = useSchemaBuilder(true);
|
|
228
|
+
|
|
229
|
+
return (
|
|
230
|
+
<div>
|
|
231
|
+
{/* Build your own custom UI */}
|
|
232
|
+
<button onClick={() => {
|
|
233
|
+
const newProp = addProperty();
|
|
234
|
+
updateProperty(newProp.id, {
|
|
235
|
+
...newProp,
|
|
236
|
+
key: 'myProperty',
|
|
237
|
+
type: 'string'
|
|
238
|
+
});
|
|
239
|
+
}}>
|
|
240
|
+
Add Property
|
|
241
|
+
</button>
|
|
242
|
+
|
|
243
|
+
<pre>{JSON.stringify(schema, null, 2)}</pre>
|
|
244
|
+
</div>
|
|
245
|
+
);
|
|
246
|
+
}
|
|
247
|
+
```
|
|
248
|
+
|
|
249
|
+
## Available Exports
|
|
250
|
+
|
|
251
|
+
### Components
|
|
252
|
+
- `JsonSchemaBuilder` - Main builder component
|
|
253
|
+
- `PropertyDocument` - Individual property card
|
|
254
|
+
- `PropertyEditDialog` - Property edit modal
|
|
255
|
+
- `JsonOutput` - JSON output display
|
|
256
|
+
- `SchemaMetadataComponent` - Schema metadata fields
|
|
257
|
+
|
|
258
|
+
### Hooks
|
|
259
|
+
- `useSchemaBuilder` - Main schema builder logic
|
|
260
|
+
- `usePropertyEditor` - Property editing logic
|
|
261
|
+
|
|
262
|
+
### Utilities
|
|
263
|
+
- `generateSchema` - Generate JSON schema from properties
|
|
264
|
+
- `parseSchema` - Parse JSON schema into properties
|
|
265
|
+
- `downloadJsonFile` - Download schema as JSON file
|
|
266
|
+
- `importJsonFile` - Import schema from file
|
|
267
|
+
|
|
268
|
+
### Types
|
|
269
|
+
- `PropertyData` - Internal UI representation of a JSON Schema property (extends JSON Schema fields)
|
|
270
|
+
- `PropertyType` - JSON Schema type names (from `@types/json-schema`)
|
|
271
|
+
- `SchemaMetadata` - Schema metadata structure
|
|
272
|
+
- `JSONSchema7` - Official JSON Schema Draft 7 type (from `@types/json-schema`)
|
|
273
|
+
- `JSONSchema7TypeName` - JSON Schema type names (from `@types/json-schema`)
|
|
274
|
+
|
|
275
|
+
**Note**: This library uses official JSON Schema types from `@types/json-schema` to ensure compatibility with the JSON Schema specification.
|
|
276
|
+
|
|
277
|
+
## Examples
|
|
278
|
+
|
|
279
|
+
### Using Individual Components
|
|
280
|
+
|
|
281
|
+
```tsx
|
|
282
|
+
import {
|
|
283
|
+
PropertyDocument,
|
|
284
|
+
useSchemaBuilder
|
|
285
|
+
} from 'json-schema-builder-react';
|
|
286
|
+
|
|
287
|
+
function CustomEditor() {
|
|
288
|
+
const { properties, updateProperty, deleteProperty } = useSchemaBuilder();
|
|
289
|
+
|
|
290
|
+
return (
|
|
291
|
+
<div>
|
|
292
|
+
{properties.map(property => (
|
|
293
|
+
<PropertyDocument
|
|
294
|
+
key={property.id}
|
|
295
|
+
property={property}
|
|
296
|
+
onUpdate={(updated) => updateProperty(property.id, updated)}
|
|
297
|
+
onDelete={() => deleteProperty(property.id)}
|
|
298
|
+
/>
|
|
299
|
+
))}
|
|
300
|
+
</div>
|
|
301
|
+
);
|
|
302
|
+
}
|
|
303
|
+
```
|
|
304
|
+
|
|
305
|
+
### Programmatic Schema Generation
|
|
306
|
+
|
|
307
|
+
```tsx
|
|
308
|
+
import { generateSchema } from 'json-schema-builder-react';
|
|
309
|
+
import type { PropertyData } from 'json-schema-builder-react';
|
|
310
|
+
|
|
311
|
+
const properties: PropertyData[] = [
|
|
312
|
+
{
|
|
313
|
+
id: '1',
|
|
314
|
+
key: 'username',
|
|
315
|
+
type: 'string',
|
|
316
|
+
required: true,
|
|
317
|
+
constraints: {
|
|
318
|
+
minLength: 3,
|
|
319
|
+
maxLength: 20
|
|
320
|
+
}
|
|
321
|
+
},
|
|
322
|
+
{
|
|
323
|
+
id: '2',
|
|
324
|
+
key: 'email',
|
|
325
|
+
type: 'string',
|
|
326
|
+
required: true,
|
|
327
|
+
constraints: {
|
|
328
|
+
pattern: '^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$'
|
|
329
|
+
}
|
|
330
|
+
}
|
|
331
|
+
];
|
|
332
|
+
|
|
333
|
+
const schema = generateSchema(
|
|
334
|
+
properties,
|
|
335
|
+
{ title: 'User Schema', description: 'User registration', version: '1.0.0' },
|
|
336
|
+
true
|
|
337
|
+
);
|
|
338
|
+
```
|
|
339
|
+
|
|
340
|
+
## Development
|
|
341
|
+
|
|
342
|
+
```bash
|
|
343
|
+
# Install dependencies
|
|
344
|
+
npm install
|
|
345
|
+
|
|
346
|
+
# Run demo app in development mode
|
|
347
|
+
npm run dev
|
|
348
|
+
|
|
349
|
+
# Build the library
|
|
350
|
+
npm run build:lib
|
|
351
|
+
|
|
352
|
+
# Build the demo app
|
|
353
|
+
npm run build
|
|
354
|
+
|
|
355
|
+
# Deploy demo to GitHub Pages
|
|
356
|
+
npm run deploy
|
|
357
|
+
```
|
|
358
|
+
|
|
359
|
+
## Troubleshooting
|
|
360
|
+
|
|
361
|
+
### PostCSS Warning
|
|
362
|
+
|
|
363
|
+
If you see this warning:
|
|
364
|
+
```
|
|
365
|
+
A PostCSS plugin did not pass the `from` option to `postcss.parse`
|
|
366
|
+
```
|
|
367
|
+
|
|
368
|
+
**Solution:** Make sure you have a `postcss.config.js` file in your project root:
|
|
369
|
+
|
|
370
|
+
```js
|
|
371
|
+
export default {
|
|
372
|
+
plugins: {
|
|
373
|
+
tailwindcss: {},
|
|
374
|
+
autoprefixer: {},
|
|
375
|
+
},
|
|
376
|
+
};
|
|
377
|
+
```
|
|
378
|
+
|
|
379
|
+
And verify your `tailwind.config.js` includes the library path:
|
|
380
|
+
|
|
381
|
+
```js
|
|
382
|
+
module.exports = {
|
|
383
|
+
content: [
|
|
384
|
+
'./src/**/*.{js,jsx,ts,tsx}',
|
|
385
|
+
'./node_modules/json-schema-editor/**/*.{js,jsx}',
|
|
386
|
+
],
|
|
387
|
+
// ...
|
|
388
|
+
};
|
|
389
|
+
```
|
|
390
|
+
|
|
391
|
+
### Styles Not Appearing
|
|
392
|
+
|
|
393
|
+
Make sure you:
|
|
394
|
+
1. Have Tailwind CSS installed and configured
|
|
395
|
+
2. Added the library to your Tailwind content paths (see Styling section)
|
|
396
|
+
3. Imported Tailwind CSS in your main CSS file
|
|
397
|
+
|
|
398
|
+
## License
|
|
399
|
+
|
|
400
|
+
MIT © Martin Arusalu
|
|
401
|
+
|
|
402
|
+
## Contributing
|
|
403
|
+
|
|
404
|
+
Contributions are welcome! Please feel free to submit a Pull Request.
|
|
405
|
+
|
|
406
|
+
## Support
|
|
407
|
+
|
|
408
|
+
- 🐛 [Report a bug](https://github.com/martin-arusalu/json-schema-editor/issues)
|
|
409
|
+
- 💡 [Request a feature](https://github.com/martin-arusalu/json-schema-editor/issues)
|
|
410
|
+
- 📖 [View demo](https://martin-arusalu.github.io/json-schema-editor)
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const t=require("react/jsx-runtime"),I=require("react"),et=require("@radix-ui/react-slot"),b=require("lucide-react"),tt=require("@radix-ui/react-tooltip"),st=require("@radix-ui/react-dialog"),rt=require("@radix-ui/react-label"),nt=require("@radix-ui/react-select"),ot=require("@radix-ui/react-checkbox");function Z(e){const r=Object.create(null,{[Symbol.toStringTag]:{value:"Module"}});if(e){for(const s in e)if(s!=="default"){const o=Object.getOwnPropertyDescriptor(e,s);Object.defineProperty(r,s,o.get?o:{enumerable:!0,get:()=>e[s]})}}return r.default=e,Object.freeze(r)}const S=Z(I),se=Z(tt),B=Z(st),Ie=Z(rt),A=Z(nt),ie=Z(ot);function ze(e){var r,s,o="";if(typeof e=="string"||typeof e=="number")o+=e;else if(typeof e=="object")if(Array.isArray(e)){var n=e.length;for(r=0;r<n;r++)e[r]&&(s=ze(e[r]))&&(o&&(o+=" "),o+=s)}else for(s in e)e[s]&&(o&&(o+=" "),o+=s);return o}function Ae(){for(var e,r,s=0,o="",n=arguments.length;s<n;s++)(e=arguments[s])&&(r=ze(e))&&(o&&(o+=" "),o+=r);return o}const Ne=e=>typeof e=="boolean"?`${e}`:e===0?"0":e,Ce=Ae,Re=(e,r)=>s=>{var o;if((r==null?void 0:r.variants)==null)return Ce(e,s==null?void 0:s.class,s==null?void 0:s.className);const{variants:n,defaultVariants:a}=r,i=Object.keys(n).map(l=>{const h=s==null?void 0:s[l],N=a==null?void 0:a[l];if(h===null)return null;const y=Ne(h)||Ne(N);return n[l][y]}),d=s&&Object.entries(s).reduce((l,h)=>{let[N,y]=h;return y===void 0||(l[N]=y),l},{}),c=r==null||(o=r.compoundVariants)===null||o===void 0?void 0:o.reduce((l,h)=>{let{class:N,className:y,...P}=h;return Object.entries(P).every(g=>{let[m,p]=g;return Array.isArray(p)?p.includes({...a,...d}[m]):{...a,...d}[m]===p})?[...l,N,y]:l},[]);return Ce(e,i,c,s==null?void 0:s.class,s==null?void 0:s.className)},ge="-",at=e=>{const r=lt(e),{conflictingClassGroups:s,conflictingClassGroupModifiers:o}=e;return{getClassGroupId:i=>{const d=i.split(ge);return d[0]===""&&d.length!==1&&d.shift(),qe(d,r)||it(i)},getConflictingClassGroupIds:(i,d)=>{const c=s[i]||[];return d&&o[i]?[...c,...o[i]]:c}}},qe=(e,r)=>{var i;if(e.length===0)return r.classGroupId;const s=e[0],o=r.nextPart.get(s),n=o?qe(e.slice(1),o):void 0;if(n)return n;if(r.validators.length===0)return;const a=e.join(ge);return(i=r.validators.find(({validator:d})=>d(a)))==null?void 0:i.classGroupId},ke=/^\[(.+)\]$/,it=e=>{if(ke.test(e)){const r=ke.exec(e)[1],s=r==null?void 0:r.substring(0,r.indexOf(":"));if(s)return"arbitrary.."+s}},lt=e=>{const{theme:r,prefix:s}=e,o={nextPart:new Map,validators:[]};return ct(Object.entries(e.classGroups),s).forEach(([a,i])=>{le(i,o,a,r)}),o},le=(e,r,s,o)=>{e.forEach(n=>{if(typeof n=="string"){const a=n===""?r:Se(r,n);a.classGroupId=s;return}if(typeof n=="function"){if(dt(n)){le(n(o),r,s,o);return}r.validators.push({validator:n,classGroupId:s});return}Object.entries(n).forEach(([a,i])=>{le(i,Se(r,a),s,o)})})},Se=(e,r)=>{let s=e;return r.split(ge).forEach(o=>{s.nextPart.has(o)||s.nextPart.set(o,{nextPart:new Map,validators:[]}),s=s.nextPart.get(o)}),s},dt=e=>e.isThemeGetter,ct=(e,r)=>r?e.map(([s,o])=>{const n=o.map(a=>typeof a=="string"?r+a:typeof a=="object"?Object.fromEntries(Object.entries(a).map(([i,d])=>[r+i,d])):a);return[s,n]}):e,mt=e=>{if(e<1)return{get:()=>{},set:()=>{}};let r=0,s=new Map,o=new Map;const n=(a,i)=>{s.set(a,i),r++,r>e&&(r=0,o=s,s=new Map)};return{get(a){let i=s.get(a);if(i!==void 0)return i;if((i=o.get(a))!==void 0)return n(a,i),i},set(a,i){s.has(a)?s.set(a,i):n(a,i)}}},Ee="!",ut=e=>{const{separator:r,experimentalParseClassName:s}=e,o=r.length===1,n=r[0],a=r.length,i=d=>{const c=[];let l=0,h=0,N;for(let p=0;p<d.length;p++){let C=d[p];if(l===0){if(C===n&&(o||d.slice(p,p+a)===r)){c.push(d.slice(h,p)),h=p+a;continue}if(C==="/"){N=p;continue}}C==="["?l++:C==="]"&&l--}const y=c.length===0?d:d.substring(h),P=y.startsWith(Ee),g=P?y.substring(1):y,m=N&&N>h?N-h:void 0;return{modifiers:c,hasImportantModifier:P,baseClassName:g,maybePostfixModifierPosition:m}};return s?d=>s({className:d,parseClassName:i}):i},pt=e=>{if(e.length<=1)return e;const r=[];let s=[];return e.forEach(o=>{o[0]==="["?(r.push(...s.sort(),o),s=[]):s.push(o)}),r.push(...s.sort()),r},ht=e=>({cache:mt(e.cacheSize),parseClassName:ut(e),...at(e)}),ft=/\s+/,gt=(e,r)=>{const{parseClassName:s,getClassGroupId:o,getConflictingClassGroupIds:n}=r,a=[],i=e.trim().split(ft);let d="";for(let c=i.length-1;c>=0;c-=1){const l=i[c],{modifiers:h,hasImportantModifier:N,baseClassName:y,maybePostfixModifierPosition:P}=s(l);let g=!!P,m=o(g?y.substring(0,P):y);if(!m){if(!g){d=l+(d.length>0?" "+d:d);continue}if(m=o(y),!m){d=l+(d.length>0?" "+d:d);continue}g=!1}const p=pt(h).join(":"),C=N?p+Ee:p,j=C+m;if(a.includes(j))continue;a.push(j);const u=n(m,g);for(let R=0;R<u.length;++R){const D=u[R];a.push(C+D)}d=l+(d.length>0?" "+d:d)}return d};function xt(){let e=0,r,s,o="";for(;e<arguments.length;)(r=arguments[e++])&&(s=Le(r))&&(o&&(o+=" "),o+=s);return o}const Le=e=>{if(typeof e=="string")return e;let r,s="";for(let o=0;o<e.length;o++)e[o]&&(r=Le(e[o]))&&(s&&(s+=" "),s+=r);return s};function bt(e,...r){let s,o,n,a=i;function i(c){const l=r.reduce((h,N)=>N(h),e());return s=ht(l),o=s.cache.get,n=s.cache.set,a=d,d(c)}function d(c){const l=o(c);if(l)return l;const h=gt(c,s);return n(c,h),h}return function(){return a(xt.apply(null,arguments))}}const k=e=>{const r=s=>s[e]||[];return r.isThemeGetter=!0,r},Me=/^\[(?:([a-z-]+):)?(.+)\]$/i,yt=/^\d+\/\d+$/,vt=new Set(["px","full","screen"]),jt=/^(\d+(\.\d+)?)?(xs|sm|md|lg|xl)$/,wt=/\d+(%|px|r?em|[sdl]?v([hwib]|min|max)|pt|pc|in|cm|mm|cap|ch|ex|r?lh|cq(w|h|i|b|min|max))|\b(calc|min|max|clamp)\(.+\)|^0$/,Nt=/^(rgba?|hsla?|hwb|(ok)?(lab|lch))\(.+\)$/,Ct=/^(inset_)?-?((\d+)?\.?(\d+)[a-z]+|0)_-?((\d+)?\.?(\d+)[a-z]+|0)/,kt=/^(url|image|image-set|cross-fade|element|(repeating-)?(linear|radial|conic)-gradient)\(.+\)$/,U=e=>X(e)||vt.has(e)||yt.test(e),K=e=>Q(e,"length",qt),X=e=>!!e&&!Number.isNaN(Number(e)),ae=e=>Q(e,"number",X),ee=e=>!!e&&Number.isInteger(Number(e)),St=e=>e.endsWith("%")&&X(e.slice(0,-1)),f=e=>Me.test(e),H=e=>jt.test(e),Pt=new Set(["length","size","percentage"]),Tt=e=>Q(e,Pt,Oe),It=e=>Q(e,"position",Oe),zt=new Set(["image","url"]),At=e=>Q(e,zt,Lt),Rt=e=>Q(e,"",Et),te=()=>!0,Q=(e,r,s)=>{const o=Me.exec(e);return o?o[1]?typeof r=="string"?o[1]===r:r.has(o[1]):s(o[2]):!1},qt=e=>wt.test(e)&&!Nt.test(e),Oe=()=>!1,Et=e=>Ct.test(e),Lt=e=>kt.test(e),Mt=()=>{const e=k("colors"),r=k("spacing"),s=k("blur"),o=k("brightness"),n=k("borderColor"),a=k("borderRadius"),i=k("borderSpacing"),d=k("borderWidth"),c=k("contrast"),l=k("grayscale"),h=k("hueRotate"),N=k("invert"),y=k("gap"),P=k("gradientColorStops"),g=k("gradientColorStopPositions"),m=k("inset"),p=k("margin"),C=k("opacity"),j=k("padding"),u=k("saturate"),R=k("scale"),D=k("sepia"),W=k("skew"),O=k("space"),V=k("translate"),M=()=>["auto","contain","none"],$=()=>["auto","hidden","clip","visible","scroll"],G=()=>["auto",f,r],v=()=>[f,r],x=()=>["",U,K],F=()=>["auto",X,f],T=()=>["bottom","center","left","left-bottom","left-top","right","right-bottom","right-top","top"],_=()=>["solid","dashed","dotted","double","none"],je=()=>["normal","multiply","screen","overlay","darken","lighten","color-dodge","color-burn","hard-light","soft-light","difference","exclusion","hue","saturation","color","luminosity"],oe=()=>["start","end","center","between","around","evenly","stretch"],Y=()=>["","0",f],we=()=>["auto","avoid","all","avoid-page","page","left","right","column"],J=()=>[X,f];return{cacheSize:500,separator:":",theme:{colors:[te],spacing:[U,K],blur:["none","",H,f],brightness:J(),borderColor:[e],borderRadius:["none","","full",H,f],borderSpacing:v(),borderWidth:x(),contrast:J(),grayscale:Y(),hueRotate:J(),invert:Y(),gap:v(),gradientColorStops:[e],gradientColorStopPositions:[St,K],inset:G(),margin:G(),opacity:J(),padding:v(),saturate:J(),scale:J(),sepia:Y(),skew:J(),space:v(),translate:v()},classGroups:{aspect:[{aspect:["auto","square","video",f]}],container:["container"],columns:[{columns:[H]}],"break-after":[{"break-after":we()}],"break-before":[{"break-before":we()}],"break-inside":[{"break-inside":["auto","avoid","avoid-page","avoid-column"]}],"box-decoration":[{"box-decoration":["slice","clone"]}],box:[{box:["border","content"]}],display:["block","inline-block","inline","flex","inline-flex","table","inline-table","table-caption","table-cell","table-column","table-column-group","table-footer-group","table-header-group","table-row-group","table-row","flow-root","grid","inline-grid","contents","list-item","hidden"],float:[{float:["right","left","none","start","end"]}],clear:[{clear:["left","right","both","none","start","end"]}],isolation:["isolate","isolation-auto"],"object-fit":[{object:["contain","cover","fill","none","scale-down"]}],"object-position":[{object:[...T(),f]}],overflow:[{overflow:$()}],"overflow-x":[{"overflow-x":$()}],"overflow-y":[{"overflow-y":$()}],overscroll:[{overscroll:M()}],"overscroll-x":[{"overscroll-x":M()}],"overscroll-y":[{"overscroll-y":M()}],position:["static","fixed","absolute","relative","sticky"],inset:[{inset:[m]}],"inset-x":[{"inset-x":[m]}],"inset-y":[{"inset-y":[m]}],start:[{start:[m]}],end:[{end:[m]}],top:[{top:[m]}],right:[{right:[m]}],bottom:[{bottom:[m]}],left:[{left:[m]}],visibility:["visible","invisible","collapse"],z:[{z:["auto",ee,f]}],basis:[{basis:G()}],"flex-direction":[{flex:["row","row-reverse","col","col-reverse"]}],"flex-wrap":[{flex:["wrap","wrap-reverse","nowrap"]}],flex:[{flex:["1","auto","initial","none",f]}],grow:[{grow:Y()}],shrink:[{shrink:Y()}],order:[{order:["first","last","none",ee,f]}],"grid-cols":[{"grid-cols":[te]}],"col-start-end":[{col:["auto",{span:["full",ee,f]},f]}],"col-start":[{"col-start":F()}],"col-end":[{"col-end":F()}],"grid-rows":[{"grid-rows":[te]}],"row-start-end":[{row:["auto",{span:[ee,f]},f]}],"row-start":[{"row-start":F()}],"row-end":[{"row-end":F()}],"grid-flow":[{"grid-flow":["row","col","dense","row-dense","col-dense"]}],"auto-cols":[{"auto-cols":["auto","min","max","fr",f]}],"auto-rows":[{"auto-rows":["auto","min","max","fr",f]}],gap:[{gap:[y]}],"gap-x":[{"gap-x":[y]}],"gap-y":[{"gap-y":[y]}],"justify-content":[{justify:["normal",...oe()]}],"justify-items":[{"justify-items":["start","end","center","stretch"]}],"justify-self":[{"justify-self":["auto","start","end","center","stretch"]}],"align-content":[{content:["normal",...oe(),"baseline"]}],"align-items":[{items:["start","end","center","baseline","stretch"]}],"align-self":[{self:["auto","start","end","center","stretch","baseline"]}],"place-content":[{"place-content":[...oe(),"baseline"]}],"place-items":[{"place-items":["start","end","center","baseline","stretch"]}],"place-self":[{"place-self":["auto","start","end","center","stretch"]}],p:[{p:[j]}],px:[{px:[j]}],py:[{py:[j]}],ps:[{ps:[j]}],pe:[{pe:[j]}],pt:[{pt:[j]}],pr:[{pr:[j]}],pb:[{pb:[j]}],pl:[{pl:[j]}],m:[{m:[p]}],mx:[{mx:[p]}],my:[{my:[p]}],ms:[{ms:[p]}],me:[{me:[p]}],mt:[{mt:[p]}],mr:[{mr:[p]}],mb:[{mb:[p]}],ml:[{ml:[p]}],"space-x":[{"space-x":[O]}],"space-x-reverse":["space-x-reverse"],"space-y":[{"space-y":[O]}],"space-y-reverse":["space-y-reverse"],w:[{w:["auto","min","max","fit","svw","lvw","dvw",f,r]}],"min-w":[{"min-w":[f,r,"min","max","fit"]}],"max-w":[{"max-w":[f,r,"none","full","min","max","fit","prose",{screen:[H]},H]}],h:[{h:[f,r,"auto","min","max","fit","svh","lvh","dvh"]}],"min-h":[{"min-h":[f,r,"min","max","fit","svh","lvh","dvh"]}],"max-h":[{"max-h":[f,r,"min","max","fit","svh","lvh","dvh"]}],size:[{size:[f,r,"auto","min","max","fit"]}],"font-size":[{text:["base",H,K]}],"font-smoothing":["antialiased","subpixel-antialiased"],"font-style":["italic","not-italic"],"font-weight":[{font:["thin","extralight","light","normal","medium","semibold","bold","extrabold","black",ae]}],"font-family":[{font:[te]}],"fvn-normal":["normal-nums"],"fvn-ordinal":["ordinal"],"fvn-slashed-zero":["slashed-zero"],"fvn-figure":["lining-nums","oldstyle-nums"],"fvn-spacing":["proportional-nums","tabular-nums"],"fvn-fraction":["diagonal-fractions","stacked-fractions"],tracking:[{tracking:["tighter","tight","normal","wide","wider","widest",f]}],"line-clamp":[{"line-clamp":["none",X,ae]}],leading:[{leading:["none","tight","snug","normal","relaxed","loose",U,f]}],"list-image":[{"list-image":["none",f]}],"list-style-type":[{list:["none","disc","decimal",f]}],"list-style-position":[{list:["inside","outside"]}],"placeholder-color":[{placeholder:[e]}],"placeholder-opacity":[{"placeholder-opacity":[C]}],"text-alignment":[{text:["left","center","right","justify","start","end"]}],"text-color":[{text:[e]}],"text-opacity":[{"text-opacity":[C]}],"text-decoration":["underline","overline","line-through","no-underline"],"text-decoration-style":[{decoration:[..._(),"wavy"]}],"text-decoration-thickness":[{decoration:["auto","from-font",U,K]}],"underline-offset":[{"underline-offset":["auto",U,f]}],"text-decoration-color":[{decoration:[e]}],"text-transform":["uppercase","lowercase","capitalize","normal-case"],"text-overflow":["truncate","text-ellipsis","text-clip"],"text-wrap":[{text:["wrap","nowrap","balance","pretty"]}],indent:[{indent:v()}],"vertical-align":[{align:["baseline","top","middle","bottom","text-top","text-bottom","sub","super",f]}],whitespace:[{whitespace:["normal","nowrap","pre","pre-line","pre-wrap","break-spaces"]}],break:[{break:["normal","words","all","keep"]}],hyphens:[{hyphens:["none","manual","auto"]}],content:[{content:["none",f]}],"bg-attachment":[{bg:["fixed","local","scroll"]}],"bg-clip":[{"bg-clip":["border","padding","content","text"]}],"bg-opacity":[{"bg-opacity":[C]}],"bg-origin":[{"bg-origin":["border","padding","content"]}],"bg-position":[{bg:[...T(),It]}],"bg-repeat":[{bg:["no-repeat",{repeat:["","x","y","round","space"]}]}],"bg-size":[{bg:["auto","cover","contain",Tt]}],"bg-image":[{bg:["none",{"gradient-to":["t","tr","r","br","b","bl","l","tl"]},At]}],"bg-color":[{bg:[e]}],"gradient-from-pos":[{from:[g]}],"gradient-via-pos":[{via:[g]}],"gradient-to-pos":[{to:[g]}],"gradient-from":[{from:[P]}],"gradient-via":[{via:[P]}],"gradient-to":[{to:[P]}],rounded:[{rounded:[a]}],"rounded-s":[{"rounded-s":[a]}],"rounded-e":[{"rounded-e":[a]}],"rounded-t":[{"rounded-t":[a]}],"rounded-r":[{"rounded-r":[a]}],"rounded-b":[{"rounded-b":[a]}],"rounded-l":[{"rounded-l":[a]}],"rounded-ss":[{"rounded-ss":[a]}],"rounded-se":[{"rounded-se":[a]}],"rounded-ee":[{"rounded-ee":[a]}],"rounded-es":[{"rounded-es":[a]}],"rounded-tl":[{"rounded-tl":[a]}],"rounded-tr":[{"rounded-tr":[a]}],"rounded-br":[{"rounded-br":[a]}],"rounded-bl":[{"rounded-bl":[a]}],"border-w":[{border:[d]}],"border-w-x":[{"border-x":[d]}],"border-w-y":[{"border-y":[d]}],"border-w-s":[{"border-s":[d]}],"border-w-e":[{"border-e":[d]}],"border-w-t":[{"border-t":[d]}],"border-w-r":[{"border-r":[d]}],"border-w-b":[{"border-b":[d]}],"border-w-l":[{"border-l":[d]}],"border-opacity":[{"border-opacity":[C]}],"border-style":[{border:[..._(),"hidden"]}],"divide-x":[{"divide-x":[d]}],"divide-x-reverse":["divide-x-reverse"],"divide-y":[{"divide-y":[d]}],"divide-y-reverse":["divide-y-reverse"],"divide-opacity":[{"divide-opacity":[C]}],"divide-style":[{divide:_()}],"border-color":[{border:[n]}],"border-color-x":[{"border-x":[n]}],"border-color-y":[{"border-y":[n]}],"border-color-s":[{"border-s":[n]}],"border-color-e":[{"border-e":[n]}],"border-color-t":[{"border-t":[n]}],"border-color-r":[{"border-r":[n]}],"border-color-b":[{"border-b":[n]}],"border-color-l":[{"border-l":[n]}],"divide-color":[{divide:[n]}],"outline-style":[{outline:["",..._()]}],"outline-offset":[{"outline-offset":[U,f]}],"outline-w":[{outline:[U,K]}],"outline-color":[{outline:[e]}],"ring-w":[{ring:x()}],"ring-w-inset":["ring-inset"],"ring-color":[{ring:[e]}],"ring-opacity":[{"ring-opacity":[C]}],"ring-offset-w":[{"ring-offset":[U,K]}],"ring-offset-color":[{"ring-offset":[e]}],shadow:[{shadow:["","inner","none",H,Rt]}],"shadow-color":[{shadow:[te]}],opacity:[{opacity:[C]}],"mix-blend":[{"mix-blend":[...je(),"plus-lighter","plus-darker"]}],"bg-blend":[{"bg-blend":je()}],filter:[{filter:["","none"]}],blur:[{blur:[s]}],brightness:[{brightness:[o]}],contrast:[{contrast:[c]}],"drop-shadow":[{"drop-shadow":["","none",H,f]}],grayscale:[{grayscale:[l]}],"hue-rotate":[{"hue-rotate":[h]}],invert:[{invert:[N]}],saturate:[{saturate:[u]}],sepia:[{sepia:[D]}],"backdrop-filter":[{"backdrop-filter":["","none"]}],"backdrop-blur":[{"backdrop-blur":[s]}],"backdrop-brightness":[{"backdrop-brightness":[o]}],"backdrop-contrast":[{"backdrop-contrast":[c]}],"backdrop-grayscale":[{"backdrop-grayscale":[l]}],"backdrop-hue-rotate":[{"backdrop-hue-rotate":[h]}],"backdrop-invert":[{"backdrop-invert":[N]}],"backdrop-opacity":[{"backdrop-opacity":[C]}],"backdrop-saturate":[{"backdrop-saturate":[u]}],"backdrop-sepia":[{"backdrop-sepia":[D]}],"border-collapse":[{border:["collapse","separate"]}],"border-spacing":[{"border-spacing":[i]}],"border-spacing-x":[{"border-spacing-x":[i]}],"border-spacing-y":[{"border-spacing-y":[i]}],"table-layout":[{table:["auto","fixed"]}],caption:[{caption:["top","bottom"]}],transition:[{transition:["none","all","","colors","opacity","shadow","transform",f]}],duration:[{duration:J()}],ease:[{ease:["linear","in","out","in-out",f]}],delay:[{delay:J()}],animate:[{animate:["none","spin","ping","pulse","bounce",f]}],transform:[{transform:["","gpu","none"]}],scale:[{scale:[R]}],"scale-x":[{"scale-x":[R]}],"scale-y":[{"scale-y":[R]}],rotate:[{rotate:[ee,f]}],"translate-x":[{"translate-x":[V]}],"translate-y":[{"translate-y":[V]}],"skew-x":[{"skew-x":[W]}],"skew-y":[{"skew-y":[W]}],"transform-origin":[{origin:["center","top","top-right","right","bottom-right","bottom","bottom-left","left","top-left",f]}],accent:[{accent:["auto",e]}],appearance:[{appearance:["none","auto"]}],cursor:[{cursor:["auto","default","pointer","wait","text","move","help","not-allowed","none","context-menu","progress","cell","crosshair","vertical-text","alias","copy","no-drop","grab","grabbing","all-scroll","col-resize","row-resize","n-resize","e-resize","s-resize","w-resize","ne-resize","nw-resize","se-resize","sw-resize","ew-resize","ns-resize","nesw-resize","nwse-resize","zoom-in","zoom-out",f]}],"caret-color":[{caret:[e]}],"pointer-events":[{"pointer-events":["none","auto"]}],resize:[{resize:["none","y","x",""]}],"scroll-behavior":[{scroll:["auto","smooth"]}],"scroll-m":[{"scroll-m":v()}],"scroll-mx":[{"scroll-mx":v()}],"scroll-my":[{"scroll-my":v()}],"scroll-ms":[{"scroll-ms":v()}],"scroll-me":[{"scroll-me":v()}],"scroll-mt":[{"scroll-mt":v()}],"scroll-mr":[{"scroll-mr":v()}],"scroll-mb":[{"scroll-mb":v()}],"scroll-ml":[{"scroll-ml":v()}],"scroll-p":[{"scroll-p":v()}],"scroll-px":[{"scroll-px":v()}],"scroll-py":[{"scroll-py":v()}],"scroll-ps":[{"scroll-ps":v()}],"scroll-pe":[{"scroll-pe":v()}],"scroll-pt":[{"scroll-pt":v()}],"scroll-pr":[{"scroll-pr":v()}],"scroll-pb":[{"scroll-pb":v()}],"scroll-pl":[{"scroll-pl":v()}],"snap-align":[{snap:["start","end","center","align-none"]}],"snap-stop":[{snap:["normal","always"]}],"snap-type":[{snap:["none","x","y","both"]}],"snap-strictness":[{snap:["mandatory","proximity"]}],touch:[{touch:["auto","none","manipulation"]}],"touch-x":[{"touch-pan":["x","left","right"]}],"touch-y":[{"touch-pan":["y","up","down"]}],"touch-pz":["touch-pinch-zoom"],select:[{select:["none","text","all","auto"]}],"will-change":[{"will-change":["auto","scroll","contents","transform",f]}],fill:[{fill:[e,"none"]}],"stroke-w":[{stroke:[U,K,ae]}],stroke:[{stroke:[e,"none"]}],sr:["sr-only","not-sr-only"],"forced-color-adjust":[{"forced-color-adjust":["auto","none"]}]},conflictingClassGroups:{overflow:["overflow-x","overflow-y"],overscroll:["overscroll-x","overscroll-y"],inset:["inset-x","inset-y","start","end","top","right","bottom","left"],"inset-x":["right","left"],"inset-y":["top","bottom"],flex:["basis","grow","shrink"],gap:["gap-x","gap-y"],p:["px","py","ps","pe","pt","pr","pb","pl"],px:["pr","pl"],py:["pt","pb"],m:["mx","my","ms","me","mt","mr","mb","ml"],mx:["mr","ml"],my:["mt","mb"],size:["w","h"],"font-size":["leading"],"fvn-normal":["fvn-ordinal","fvn-slashed-zero","fvn-figure","fvn-spacing","fvn-fraction"],"fvn-ordinal":["fvn-normal"],"fvn-slashed-zero":["fvn-normal"],"fvn-figure":["fvn-normal"],"fvn-spacing":["fvn-normal"],"fvn-fraction":["fvn-normal"],"line-clamp":["display","overflow"],rounded:["rounded-s","rounded-e","rounded-t","rounded-r","rounded-b","rounded-l","rounded-ss","rounded-se","rounded-ee","rounded-es","rounded-tl","rounded-tr","rounded-br","rounded-bl"],"rounded-s":["rounded-ss","rounded-es"],"rounded-e":["rounded-se","rounded-ee"],"rounded-t":["rounded-tl","rounded-tr"],"rounded-r":["rounded-tr","rounded-br"],"rounded-b":["rounded-br","rounded-bl"],"rounded-l":["rounded-tl","rounded-bl"],"border-spacing":["border-spacing-x","border-spacing-y"],"border-w":["border-w-s","border-w-e","border-w-t","border-w-r","border-w-b","border-w-l"],"border-w-x":["border-w-r","border-w-l"],"border-w-y":["border-w-t","border-w-b"],"border-color":["border-color-s","border-color-e","border-color-t","border-color-r","border-color-b","border-color-l"],"border-color-x":["border-color-r","border-color-l"],"border-color-y":["border-color-t","border-color-b"],"scroll-m":["scroll-mx","scroll-my","scroll-ms","scroll-me","scroll-mt","scroll-mr","scroll-mb","scroll-ml"],"scroll-mx":["scroll-mr","scroll-ml"],"scroll-my":["scroll-mt","scroll-mb"],"scroll-p":["scroll-px","scroll-py","scroll-ps","scroll-pe","scroll-pt","scroll-pr","scroll-pb","scroll-pl"],"scroll-px":["scroll-pr","scroll-pl"],"scroll-py":["scroll-pt","scroll-pb"],touch:["touch-x","touch-y","touch-pz"],"touch-x":["touch"],"touch-y":["touch"],"touch-pz":["touch"]},conflictingClassGroupModifiers:{"font-size":["leading"]}}},Ot=bt(Mt);function w(...e){return Ot(Ae(e))}const Ft=Re("inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium 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 hover-elevate active-elevate-2",{variants:{variant:{default:"bg-primary text-primary-foreground border border-primary-border",destructive:"bg-destructive text-destructive-foreground border border-destructive-border",outline:" border [border-color:var(--button-outline)] shadow-xs active:shadow-none ",secondary:"border bg-secondary text-secondary-foreground border border-secondary-border ",ghost:"border border-transparent"},size:{default:"min-h-9 px-4 py-2",sm:"min-h-8 rounded-md px-3 text-xs",lg:"min-h-10 rounded-md px-8",icon:"h-9 w-9"}},defaultVariants:{variant:"default",size:"default"}}),E=S.forwardRef(({className:e,variant:r,size:s,asChild:o=!1,...n},a)=>{const i=o?et.Slot:"button";return t.jsx(i,{className:w(Ft({variant:r,size:s,className:e})),ref:a,...n})});E.displayName="Button";const L=S.forwardRef(({className:e,type:r,...s},o)=>t.jsx("input",{type:r,className:w("flex h-9 w-full rounded-md border border-input bg-background px-3 py-2 text-base ring-offset-background 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-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 md:text-sm",e),ref:o,...s}));L.displayName="Input";const Dt=se.Provider,Vt=se.Root,_t=se.Trigger,Fe=S.forwardRef(({className:e,sideOffset:r=4,...s},o)=>t.jsx(se.Content,{ref:o,sideOffset:r,className:w("z-50 overflow-hidden rounded-md border bg-popover px-3 py-1.5 text-sm text-popover-foreground shadow-md 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]",e),...s}));Fe.displayName=se.Content.displayName;const Bt=B.Root,Gt=B.Portal,De=S.forwardRef(({className:e,...r},s)=>t.jsx(B.Overlay,{ref:s,className:w("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",e),...r}));De.displayName=B.Overlay.displayName;const Ve=S.forwardRef(({className:e,children:r,...s},o)=>t.jsxs(Gt,{children:[t.jsx(De,{}),t.jsxs(B.Content,{ref:o,className:w("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",e),...s,children:[r,t.jsxs(B.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:[t.jsx(b.X,{className:"h-4 w-4"}),t.jsx("span",{className:"sr-only",children:"Close"})]})]})]}));Ve.displayName=B.Content.displayName;const _e=({className:e,...r})=>t.jsx("div",{className:w("flex flex-col space-y-1.5 text-center sm:text-left",e),...r});_e.displayName="DialogHeader";const Be=({className:e,...r})=>t.jsx("div",{className:w("flex flex-col-reverse sm:flex-row sm:justify-end sm:space-x-2",e),...r});Be.displayName="DialogFooter";const Ge=S.forwardRef(({className:e,...r},s)=>t.jsx(B.Title,{ref:s,className:w("text-lg font-semibold leading-none tracking-tight",e),...r}));Ge.displayName=B.Title.displayName;const $t=S.forwardRef(({className:e,...r},s)=>t.jsx(B.Description,{ref:s,className:w("text-sm text-muted-foreground",e),...r}));$t.displayName=B.Description.displayName;const Jt=Re("text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70"),z=S.forwardRef(({className:e,...r},s)=>t.jsx(Ie.Root,{ref:s,className:w(Jt(),e),...r}));z.displayName=Ie.Root.displayName;const Pe=A.Root,Te=A.Value,de=S.forwardRef(({className:e,children:r,...s},o)=>t.jsxs(A.Trigger,{ref:o,className:w("flex h-9 w-full items-center justify-between rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background data-[placeholder]:text-muted-foreground focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 [&>span]:line-clamp-1",e),...s,children:[r,t.jsx(A.Icon,{asChild:!0,children:t.jsx(b.ChevronDown,{className:"h-4 w-4 opacity-50"})})]}));de.displayName=A.Trigger.displayName;const $e=S.forwardRef(({className:e,...r},s)=>t.jsx(A.ScrollUpButton,{ref:s,className:w("flex cursor-default items-center justify-center py-1",e),...r,children:t.jsx(b.ChevronUp,{className:"h-4 w-4"})}));$e.displayName=A.ScrollUpButton.displayName;const Je=S.forwardRef(({className:e,...r},s)=>t.jsx(A.ScrollDownButton,{ref:s,className:w("flex cursor-default items-center justify-center py-1",e),...r,children:t.jsx(b.ChevronDown,{className:"h-4 w-4"})}));Je.displayName=A.ScrollDownButton.displayName;const ce=S.forwardRef(({className:e,children:r,position:s="popper",...o},n)=>t.jsx(A.Portal,{children:t.jsxs(A.Content,{ref:n,className:w("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",e),position:s,...o,children:[t.jsx($e,{}),t.jsx(A.Viewport,{className:w("p-1",s==="popper"&&"h-[var(--radix-select-trigger-height)] w-full min-w-[var(--radix-select-trigger-width)]"),children:r}),t.jsx(Je,{})]})}));ce.displayName=A.Content.displayName;const Ut=S.forwardRef(({className:e,...r},s)=>t.jsx(A.Label,{ref:s,className:w("py-1.5 pl-8 pr-2 text-sm font-semibold",e),...r}));Ut.displayName=A.Label.displayName;const q=S.forwardRef(({className:e,children:r,...s},o)=>t.jsxs(A.Item,{ref:o,className:w("relative flex w-full cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50",e),...s,children:[t.jsx("span",{className:"absolute left-2 flex h-3.5 w-3.5 items-center justify-center",children:t.jsx(A.ItemIndicator,{children:t.jsx(b.Check,{className:"h-4 w-4"})})}),t.jsx(A.ItemText,{children:r})]}));q.displayName=A.Item.displayName;const Wt=S.forwardRef(({className:e,...r},s)=>t.jsx(A.Separator,{ref:s,className:w("-mx-1 my-1 h-px bg-muted",e),...r}));Wt.displayName=A.Separator.displayName;const me=S.forwardRef(({className:e,...r},s)=>t.jsx(ie.Root,{ref:s,className:w("peer h-4 w-4 shrink-0 rounded-sm border border-primary ring-offset-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 data-[state=checked]:bg-primary data-[state=checked]:text-primary-foreground",e),...r,children:t.jsx(ie.Indicator,{className:w("flex items-center justify-center text-current"),children:t.jsx(b.Check,{className:"h-4 w-4"})})}));me.displayName=ie.Root.displayName;const xe=S.forwardRef(({className:e,...r},s)=>t.jsx("textarea",{className:w("flex min-h-[80px] w-full rounded-md border border-input bg-background px-3 py-2 text-base ring-offset-background placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 md:text-sm",e),ref:s,...r}));xe.displayName="Textarea";const Kt=e=>e.trim().toLowerCase().replace(/[^\w\s]/g,"").replace(/\s+/g,"_"),Ue=(e,r,s=!1)=>{const o=(c,l)=>{r({...e,[c]:l})};return{handleTitleChange:c=>{o("title",c)},handleTitleBlur:()=>{if(s&&e.title){const c=Kt(e.title);o("key",c)}},handleKeyChange:c=>{s&&o("key",c)},handleFieldChange:o,handleConstraintChange:(c,l)=>{r({...e,[c]:l})}}},ue={string:"String",number:"Number",integer:"Integer",boolean:"Boolean",object:"Object",array:"Array",null:"Null",file:"File"},We=I.createContext({getTypeLabel:e=>ue[e],typeLabels:ue});function Ht({children:e,customLabels:r={}}){const s={...ue,...r},o=n=>s[n]||n;return t.jsx(We.Provider,{value:{getTypeLabel:o,typeLabels:s},children:e})}function Ke(){return I.useContext(We)}function re({property:e,open:r,onOpenChange:s,onUpdate:o,isArrayItem:n=!1,isNewProperty:a=!1,propertyLabel:i={singular:"Property",plural:"Properties"},showRegex:d=!1}){var j;const{typeLabels:c}=Ke(),[l,h]=I.useState(e);I.useEffect(()=>{r&&h(e)},[e,r]);const{handleTitleChange:N,handleTitleBlur:y,handleKeyChange:P,handleFieldChange:g,handleConstraintChange:m}=Ue(l,h,a),p=()=>{var u;(u=l.title)!=null&&u.trim()&&(o(l),s(!1))},C=()=>{h(e),s(!1)};return t.jsx(Bt,{open:r,onOpenChange:s,children:t.jsxs(Ve,{className:"max-w-2xl max-h-[80vh] flex flex-col gap-0 p-0","data-testid":"dialog-edit-property",children:[t.jsx(_e,{className:"px-6 pt-6 pb-4 shrink-0",children:t.jsx(Ge,{children:a?`Add ${i.singular}`:`Edit ${i.singular}`})}),t.jsxs("div",{className:"space-y-6 px-6 pb-4 overflow-y-auto flex-1 min-h-0",children:[t.jsxs("div",{className:"space-y-2",children:[t.jsxs(z,{className:"flex items-center gap-1.5",children:[t.jsx("span",{className:"w-1.5 h-1.5 rounded-full bg-red-500"}),"Type"]}),t.jsxs(Pe,{value:l.type,onValueChange:u=>g("type",u),"data-testid":"select-type-dialog",children:[t.jsx(de,{children:t.jsx(Te,{})}),t.jsxs(ce,{children:[t.jsx(q,{value:"string",children:c.string}),t.jsx(q,{value:"number",children:c.number}),t.jsx(q,{value:"integer",children:c.integer}),t.jsx(q,{value:"boolean",children:c.boolean}),t.jsx(q,{value:"object",children:c.object}),t.jsx(q,{value:"array",children:c.array}),t.jsx(q,{value:"file",children:c.file}),t.jsx(q,{value:"null",children:c.null})]})]})]}),t.jsxs("div",{className:"space-y-2",children:[t.jsxs(z,{className:"flex items-center gap-1.5",children:[t.jsx("span",{className:"w-1.5 h-1.5 rounded-full bg-red-500"}),"Title"]}),t.jsx(L,{value:l.title||"",onChange:u=>N(u.target.value),onBlur:y,placeholder:"Property Title","data-testid":"input-title-dialog",required:!0}),!a&&l.key&&t.jsxs("p",{className:"text-xs text-muted-foreground font-mono",children:["Key: ",l.key]})]}),a&&t.jsxs("div",{className:"space-y-2",children:[t.jsx(z,{children:"Key"}),t.jsx(L,{value:l.key,onChange:u=>P(u.target.value),placeholder:"property_key","data-testid":"input-key-dialog"})]}),t.jsxs("div",{className:"space-y-2",children:[t.jsx(z,{children:"Description"}),t.jsx(xe,{placeholder:"Optional description",value:l.description||"",onChange:u=>g("description",u.target.value),rows:2,"data-testid":"input-edit-description"})]}),l.type==="array"&&t.jsxs("div",{className:"space-y-2 border-l-2 border-border pl-4 mt-2",children:[t.jsxs(z,{className:"font-semibold text-xs text-muted-foreground",children:[c.array," Items"]}),l.items?t.jsxs("div",{className:"bg-muted/40 p-2 rounded",children:[t.jsxs("div",{className:"space-y-2",children:[t.jsx(z,{children:"Item Type"}),t.jsxs(Pe,{value:l.items.type,onValueChange:u=>h({...l,items:{...l.items,type:u}}),children:[t.jsx(de,{children:t.jsx(Te,{})}),t.jsxs(ce,{children:[t.jsx(q,{value:"string",children:c.string}),t.jsx(q,{value:"number",children:c.number}),t.jsx(q,{value:"integer",children:c.integer}),t.jsx(q,{value:"boolean",children:c.boolean}),t.jsx(q,{value:"object",children:c.object}),t.jsx(q,{value:"array",children:c.array}),t.jsx(q,{value:"file",children:c.file}),t.jsx(q,{value:"null",children:c.null})]})]})]}),t.jsxs("div",{className:"space-y-2",children:[t.jsx(z,{children:"Item Title"}),t.jsx(L,{value:l.items.title||"",onChange:u=>h({...l,items:{...l.items,title:u.target.value}}),placeholder:"Item Title"})]}),t.jsxs(E,{variant:"ghost",size:"sm",className:"mt-2",onClick:()=>h({...l,items:void 0}),children:["Remove ",c.array," Item Schema"]})]}):t.jsxs(E,{variant:"outline",size:"sm",onClick:()=>{h({...l,items:{id:Date.now().toString()+Math.random(),key:"item",type:"string",required:!1}})},children:["Add ",c.array," Item Schema"]})]}),!n&&t.jsxs("div",{className:"flex items-center gap-2",children:[t.jsx(me,{id:"prop-required",checked:l.required,onCheckedChange:u=>g("required",u),"data-testid":"checkbox-edit-required"}),t.jsx(z,{htmlFor:"prop-required",className:"cursor-pointer",children:"Required field"})]}),l.type==="string"&&t.jsxs("details",{className:"border rounded-md",children:[t.jsx("summary",{className:"p-4 cursor-pointer hover:bg-accent/50 transition-colors",children:t.jsxs("h4",{className:"text-sm font-medium inline",children:[c.string," Constraints"]})}),t.jsxs("div",{className:"space-y-4 p-4 pt-0",children:[t.jsxs("div",{className:"grid grid-cols-2 gap-4",children:[t.jsxs("div",{className:"space-y-2",children:[t.jsx(z,{htmlFor:"min-length",children:"Minimum Length"}),t.jsx(L,{id:"min-length",type:"number",placeholder:"0",value:l.minLength||"",onChange:u=>m("minLength",u.target.value?parseInt(u.target.value):void 0),"data-testid":"input-edit-minlength"})]}),t.jsxs("div",{className:"space-y-2",children:[t.jsx(z,{htmlFor:"max-length",children:"Maximum Length"}),t.jsx(L,{id:"max-length",type:"number",placeholder:"∞",value:l.maxLength||"",onChange:u=>m("maxLength",u.target.value?parseInt(u.target.value):void 0),"data-testid":"input-edit-maxlength"})]})]}),d&&t.jsxs("div",{className:"space-y-2",children:[t.jsx(z,{htmlFor:"pattern",children:"Pattern (regex)"}),t.jsx(L,{id:"pattern",placeholder:"^[a-z]+$",value:l.pattern||"",onChange:u=>m("pattern",u.target.value),className:"font-mono text-sm","data-testid":"input-edit-pattern"})]}),t.jsxs("div",{className:"space-y-2",children:[t.jsx(z,{children:"Enum Values"}),t.jsx("div",{className:"space-y-2",children:[...l.enum||[],""].map((u,R)=>{var D;return t.jsx(L,{placeholder:R===(((D=l.enum)==null?void 0:D.length)||0)?"Add new value...":"Enum value",value:u,onChange:W=>{const O=W.target.value,V=l.enum||[];if(R===V.length)O.trim()&&m("enum",[...V,O.trim()]);else if(O.trim()){const M=[...V];M[R]=O.trim(),m("enum",M)}else{const M=V.filter(($,G)=>G!==R);m("enum",M.length>0?M:void 0)}},"data-testid":`input-edit-enum-${R}`},R)})}),t.jsx("p",{className:"text-xs text-muted-foreground",children:"Enter allowed values (empty fields will be removed)"})]})]})]}),(l.type==="number"||l.type==="integer")&&t.jsxs("details",{className:"border rounded-md",children:[t.jsx("summary",{className:"p-4 cursor-pointer hover:bg-accent/50 transition-colors",children:t.jsx("h4",{className:"text-sm font-medium inline",children:"Numeric Constraints"})}),t.jsx("div",{className:"space-y-4 p-4 pt-0",children:t.jsxs("div",{className:"grid grid-cols-2 gap-4",children:[t.jsxs("div",{className:"space-y-2",children:[t.jsx(z,{htmlFor:"minimum",children:"Minimum Value"}),t.jsx(L,{id:"minimum",type:"number",placeholder:"-∞",value:l.minimum??"",onChange:u=>m("minimum",u.target.value?parseFloat(u.target.value):void 0),"data-testid":"input-edit-minimum"})]}),t.jsxs("div",{className:"space-y-2",children:[t.jsx(z,{htmlFor:"maximum",children:"Maximum Value"}),t.jsx(L,{id:"maximum",type:"number",placeholder:"∞",value:l.maximum??"",onChange:u=>m("maximum",u.target.value?parseFloat(u.target.value):void 0),"data-testid":"input-edit-maximum"})]})]})})]}),l.type==="array"&&t.jsxs("details",{className:"border rounded-md",children:[t.jsx("summary",{className:"p-4 cursor-pointer hover:bg-accent/50 transition-colors",children:t.jsxs("h4",{className:"text-sm font-medium inline",children:[c.array," Constraints"]})}),t.jsxs("div",{className:"space-y-4 p-4 pt-0",children:[t.jsxs("div",{className:"grid grid-cols-2 gap-4",children:[t.jsxs("div",{className:"space-y-2",children:[t.jsx(z,{htmlFor:"min-items",children:"Minimum Items"}),t.jsx(L,{id:"min-items",type:"number",placeholder:"0",value:l.minItems||"",onChange:u=>m("minItems",u.target.value?parseInt(u.target.value):void 0),"data-testid":"input-edit-minitems"})]}),t.jsxs("div",{className:"space-y-2",children:[t.jsx(z,{htmlFor:"max-items",children:"Maximum Items"}),t.jsx(L,{id:"max-items",type:"number",placeholder:"∞",value:l.maxItems||"",onChange:u=>m("maxItems",u.target.value?parseInt(u.target.value):void 0),"data-testid":"input-edit-maxitems"})]})]}),t.jsxs("div",{className:"flex items-center gap-2",children:[t.jsx(me,{id:"unique-items",checked:l.uniqueItems||!1,onCheckedChange:u=>m("uniqueItems",u),"data-testid":"checkbox-edit-unique"}),t.jsx(z,{htmlFor:"unique-items",className:"cursor-pointer",children:"All items must be unique"})]})]})]})]}),t.jsxs(Be,{className:"px-6 py-4 border-t bg-background shrink-0",children:[t.jsx(E,{variant:"outline",onClick:C,"data-testid":"button-cancel",children:"Cancel"}),t.jsx(E,{onClick:p,"data-testid":"button-save",disabled:!((j=l.title)!=null&&j.trim()),children:"Save Changes"})]})]})})}const be=()=>`${Date.now()}-${Math.random()}`;function ne({property:e,onUpdate:r,onDelete:s,level:o=1,isArrayItem:n=!1,showRegex:a=!1}){const{getTypeLabel:i}=Ke(),[d,c]=I.useState(!1),[l,h]=I.useState(null),[N,y]=I.useState(!1),[P,g]=I.useState(!1),[m,p]=I.useState(e.title||"");I.useEffect(()=>{P||p(e.title||"")},[e.title,P]);const C=`h${Math.min(o,6)}`,j=e.type==="object",u=j&&e.children&&e.children.length>0,R={1:"text-xl",2:"text-base",3:"text-base",4:"text-base",5:"text-sm",6:"text-sm"}[o]||"text-sm",D=(x,F)=>{const T=e.children.map(_=>_.id===x?F:_);r({...e,children:T})},W=x=>{const F=e.children.filter(T=>T.id!==x);r({...e,children:F})},O=()=>{const x={id:be(),key:"",type:"string",required:!1};h(x),y(!0)},V=x=>{r({...e,children:[...e.children||[],x]}),y(!1),h(null)},M=()=>{y(!1),h(null)},$=()=>{const x=e.title||e.key||"";p(x),g(!0)},G=()=>{const x=m.trim();if(!x){p(e.title||""),g(!1);return}x!==e.title&&r({...e,title:x}),g(!1)},v=x=>{x.key==="Enter"?G():x.key==="Escape"&&(p(e.title||""),g(!1))};return t.jsxs("div",{className:"group",children:[t.jsxs("div",{className:"flex gap-4 items-center rounded-md -mx-2 px-2 py-1 transition-colors hover:bg-accent/50",children:[t.jsx("div",{className:"flex-1 min-w-0",children:t.jsxs("div",{className:"flex items-start gap-3",children:[!n&&t.jsx("button",{onClick:()=>r({...e,required:!e.required}),className:"shrink-0 transition-all hover:scale-110 mt-0.5",title:e.required?"Required field - click to make optional":"Optional field - click to make required",children:e.required?t.jsx("span",{className:"block w-4 h-4 rounded-full bg-primary"}):t.jsx("span",{className:"block w-4 h-4 rounded-full border border-dashed border-gray-400"})}),P?t.jsx(L,{value:m,onChange:x=>p(x.target.value),onBlur:G,onKeyDown:v,autoFocus:!0,className:R,placeholder:"Enter title"}):t.jsxs("div",{className:"flex gap-2 flex-wrap",children:[t.jsxs("div",{className:"flex items-start gap-2",children:[t.jsx(C,{className:`${R} font-medium cursor-pointer hover:text-primary transition-colors leading-none`,onClick:$,children:e.title||e.key||t.jsx("span",{className:"text-muted-foreground italic",children:"unnamed"})}),t.jsx(Dt,{children:t.jsxs(Vt,{children:[t.jsx(_t,{asChild:!0,children:t.jsxs("span",{children:[e.type==="string"&&t.jsx(b.Type,{className:"w-5 h-5 text-muted-foreground"}),e.type==="number"&&t.jsx(b.Hash,{className:"w-5 h-5 text-muted-foreground"}),e.type==="integer"&&t.jsx(b.Hash,{className:"w-5 h-5 text-muted-foreground"}),e.type==="boolean"&&t.jsx(b.CheckSquare,{className:"w-5 h-5 text-muted-foreground"}),e.type==="object"&&t.jsx(b.Braces,{className:"w-5 h-5 text-muted-foreground"}),e.type==="array"&&t.jsx(b.List,{className:"w-5 h-5 text-muted-foreground"}),e.type==="file"&&t.jsx(b.FileText,{className:"w-5 h-5 text-muted-foreground"})]})}),t.jsxs(Fe,{side:"top",children:[i(e.type),e.type==="array"&&e.items?` of ${i(e.items.type)}`:""]})]})}),e.type==="object"&&t.jsx(E,{variant:"ghost",size:"icon",className:"opacity-0 group-hover:opacity-100 h-6 w-6",onClick:O,"data-testid":`button-add-child-${e.id}`,children:t.jsx(b.Plus,{className:"!w-5 !h-5"})})]}),e.description&&t.jsx("p",{className:"text-sm text-muted-foreground flex-1 min-w-[200px]","data-testid":`text-description-${e.id}`,children:e.description})]})]})}),t.jsxs("div",{className:"flex items-center gap-1 opacity-0 group-hover:opacity-100 transition-opacity shrink-0",children:[t.jsx(E,{variant:"ghost",size:"icon",className:"h-7 w-7",onClick:()=>c(!0),"data-testid":`button-edit-${e.id}`,children:t.jsx(b.Pencil,{className:"w-3 h-3"})}),j&&e.type!=="object"&&t.jsx(E,{variant:"ghost",size:"icon",className:"h-7 w-7",onClick:O,"data-testid":`button-add-child-${e.id}`,children:t.jsx(b.Plus,{className:"w-3 h-3"})}),t.jsx(E,{variant:"ghost",size:"icon",className:"h-7 w-7 text-muted-foreground hover:text-destructive",onClick:s,"data-testid":`button-delete-${e.id}`,children:t.jsx(b.Trash2,{className:"w-3 h-3"})})]})]}),u&&t.jsx("div",{className:o===1?"ml-6 mt-1 border-l-2 border-border pl-6":"ml-4 mt-1 border-l border-border pl-4",children:e.children.map(x=>t.jsx(ne,{property:x,onUpdate:F=>D(x.id,F),onDelete:()=>W(x.id),level:o+1,showRegex:a},x.id))}),e.type==="array"&&e.items&&t.jsxs("div",{className:o===1?"ml-6 mt-1 border-l-2 border-border pl-6":"ml-4 mt-1 border-l border-border pl-4",children:[t.jsxs("div",{className:"mb-2 text-xs text-muted-foreground font-semibold uppercase",children:[i("array")," Items"]}),t.jsx(ne,{property:e.items,onUpdate:x=>r({...e,items:x}),onDelete:()=>r({...e,items:void 0}),level:o+1,isArrayItem:!0,showRegex:a})]}),t.jsx(re,{property:e,open:d,onOpenChange:c,onUpdate:r,isArrayItem:n,isNewProperty:!1,showRegex:a}),N&&l&&t.jsx(re,{property:l,open:N,isNewProperty:!0,onOpenChange:x=>{x||M()},onUpdate:V,showRegex:a})]})}const ye=S.forwardRef(({className:e,...r},s)=>t.jsx("div",{ref:s,className:w("shadcn-card rounded-xl border bg-card border-card-border text-card-foreground shadow-sm",e),...r}));ye.displayName="Card";const Xt=S.forwardRef(({className:e,...r},s)=>t.jsx("div",{ref:s,className:w("flex flex-col space-y-1.5 p-6",e),...r}));Xt.displayName="CardHeader";const Zt=S.forwardRef(({className:e,...r},s)=>t.jsx("div",{ref:s,className:w("text-2xl font-semibold leading-none tracking-tight",e),...r}));Zt.displayName="CardTitle";const Qt=S.forwardRef(({className:e,...r},s)=>t.jsx("div",{ref:s,className:w("text-sm text-muted-foreground",e),...r}));Qt.displayName="CardDescription";const Yt=S.forwardRef(({className:e,...r},s)=>t.jsx("div",{ref:s,className:w("p-6 pt-0",e),...r}));Yt.displayName="CardContent";const es=S.forwardRef(({className:e,...r},s)=>t.jsx("div",{ref:s,className:w("flex items-center p-6 pt-0",e),...r}));es.displayName="CardFooter";const He=()=>new Promise((e,r)=>{const s=document.createElement("input");s.type="file",s.accept=".json",s.onchange=o=>{var i;const n=(i=o.target.files)==null?void 0:i[0];if(!n){r(new Error("No file selected"));return}const a=new FileReader;a.onload=d=>{var c;try{const l=JSON.parse((c=d.target)==null?void 0:c.result);e(l)}catch{r(new Error("Invalid JSON file"))}},a.onerror=()=>r(new Error("Failed to read file")),a.readAsText(n)},s.click()}),ve=(e,r="schema.json")=>{const s=JSON.stringify(e,null,2),o=new Blob([s],{type:"application/json"}),n=URL.createObjectURL(o),a=document.createElement("a");a.href=n,a.download=r,document.body.appendChild(a),a.click(),document.body.removeChild(a),URL.revokeObjectURL(n)};function Xe({schema:e}){const[r,s]=I.useState(!1),o=JSON.stringify(e,null,2),n=async()=>{await navigator.clipboard.writeText(o),s(!0),setTimeout(()=>s(!1),2e3)},a=()=>{ve(e,"schema.json")};return t.jsxs("div",{className:"h-full flex flex-col",children:[t.jsxs("div",{className:"flex items-center justify-between p-4 border-b",children:[t.jsx("h2",{className:"text-sm font-medium",children:"JSON Schema Output"}),t.jsxs("div",{className:"flex gap-2",children:[t.jsx(E,{variant:"outline",size:"sm",onClick:n,"data-testid":"button-copy",children:r?t.jsx(b.CheckCircle2,{className:"w-4 h-4"}):t.jsx(b.Copy,{className:"w-4 h-4"})}),t.jsx(E,{variant:"outline",size:"sm",onClick:a,"data-testid":"button-download",children:t.jsx(b.Download,{className:"w-4 h-4"})})]})]}),t.jsx("div",{className:"flex-1 overflow-auto",children:t.jsx(ye,{className:"m-4 bg-muted/30",children:t.jsx("pre",{className:"p-6 text-xs font-mono overflow-auto","data-testid":"text-json-output",children:t.jsx("code",{children:o})})})})]})}function Ze({title:e,description:r,version:s,onUpdate:o}){const[n,a]=I.useState(!1);return t.jsxs(ye,{className:"p-4",children:[t.jsxs(E,{variant:"ghost",onClick:()=>a(!n),className:"w-full justify-between px-2 h-auto hover:bg-transparent","data-testid":"button-toggle-metadata",children:[t.jsx("h3",{className:"text-sm font-medium",children:"Schema Metadata"}),n?t.jsx(b.ChevronDown,{className:"w-4 h-4"}):t.jsx(b.ChevronRight,{className:"w-4 h-4"})]}),n&&t.jsxs("div",{className:"mt-4 space-y-4",children:[t.jsxs("div",{className:"space-y-2",children:[t.jsx(z,{htmlFor:"schema-title",className:"text-xs text-muted-foreground",children:"Title"}),t.jsx(L,{id:"schema-title",placeholder:"My Schema",value:e,onChange:i=>o("title",i.target.value),"data-testid":"input-title"})]}),t.jsxs("div",{className:"space-y-2",children:[t.jsx(z,{htmlFor:"schema-description",className:"text-xs text-muted-foreground",children:"Description"}),t.jsx(xe,{id:"schema-description",placeholder:"Describe your schema...",value:r,onChange:i=>o("description",i.target.value),className:"resize-none",rows:3,"data-testid":"input-schema-description"})]}),t.jsxs("div",{className:"space-y-2",children:[t.jsx(z,{htmlFor:"schema-version",className:"text-xs text-muted-foreground",children:"Version"}),t.jsx(L,{id:"schema-version",placeholder:"1.0.0",value:s,onChange:i=>o("version",i.target.value),"data-testid":"input-version"})]})]})]})}const Qe=(e,r,s=!0)=>{const o={type:"object"};s&&r&&(r.title&&(o.title=r.title),r.description&&(o.description=r.description));const n=pe(e);Object.keys(n).length>0&&(o.properties=n);const a=e.filter(i=>i.required&&i.key).map(i=>i.key);return a.length>0&&(o.required=a),o},pe=e=>{const r={};return e.forEach(s=>{if(!s.key)return;const n={type:s.type==="file"?"string":s.type};if(s.title&&(n.title=s.title),s.description&&(n.description=s.description),s.type==="file"&&(n.format="filename"),s.type==="string"&&(s.minLength!==void 0&&(n.minLength=s.minLength),s.maxLength!==void 0&&(n.maxLength=s.maxLength),s.pattern&&(n.pattern=s.pattern),s.enum&&s.enum.length>0&&(n.enum=s.enum)),(s.type==="number"||s.type==="integer")&&(s.minimum!==void 0&&(n.minimum=s.minimum),s.maximum!==void 0&&(n.maximum=s.maximum)),s.type==="array"&&(s.minItems!==void 0&&(n.minItems=s.minItems),s.maxItems!==void 0&&(n.maxItems=s.maxItems),s.uniqueItems&&(n.uniqueItems=s.uniqueItems),s.items&&(n.items=pe([s.items])[s.items.key]||{type:s.items.type})),s.type==="object"&&s.children&&s.children.length>0){n.properties=pe(s.children);const a=s.children.filter(i=>i.required&&i.key).map(i=>i.key);a.length>0&&(n.required=a)}r[s.key]=n}),r},he=e=>{const r={properties:[]};return(e.title||e.description)&&(r.metadata={title:typeof e.title=="string"?e.title:"",description:typeof e.description=="string"?e.description:"",version:"1.0.0"}),e.properties&&typeof e.properties=="object"&&(r.properties=fe(e.properties,Array.isArray(e.required)?e.required:[])),r},fe=(e,r=[])=>e?Object.entries(e).filter(([,s])=>typeof s=="object").map(([s,o])=>{const n=o;let a=typeof n.type=="string"?n.type:"string";a==="string"&&n.format==="filename"&&(a="file");const i={id:be(),key:s,title:typeof n.title=="string"?n.title:void 0,type:a,description:typeof n.description=="string"?n.description:void 0,required:r.includes(s)};return n.minLength!==void 0&&(i.minLength=n.minLength),n.maxLength!==void 0&&(i.maxLength=n.maxLength),n.pattern&&(i.pattern=n.pattern),n.enum&&Array.isArray(n.enum)&&(i.enum=n.enum),n.minimum!==void 0&&(i.minimum=n.minimum),n.maximum!==void 0&&(i.maximum=n.maximum),n.minItems!==void 0&&(i.minItems=n.minItems),n.maxItems!==void 0&&(i.maxItems=n.maxItems),n.uniqueItems&&(i.uniqueItems=n.uniqueItems),i.type==="array"&&n.items&&typeof n.items=="object"&&!Array.isArray(n.items)&&(i.items=fe({item:n.items},[]).find(d=>d.key==="item")),n.properties&&typeof n.properties=="object"&&(i.children=fe(n.properties,Array.isArray(n.required)?n.required:[])),i}):[],Ye=(e=!0)=>{const[r,s]=I.useState([]),[o,n]=I.useState({title:"",description:"",version:""}),a=I.useMemo(()=>Qe(r,o,e),[r,o,e]);return{properties:r,metadata:o,schema:a,addProperty:()=>({id:be(),key:"",type:"string",required:!1}),updateProperty:(g,m)=>{s(p=>p.some(j=>j.id===g)?p.map(j=>j.id===g?m:j):[...p,m])},deleteProperty:g=>{s(m=>m.filter(p=>p.id!==g))},clearAll:()=>{s([]),n({title:"",description:"",version:""})},updateMetadata:(g,m)=>{n(p=>({...p,[g]:m}))},importSchema:async()=>{const g=await He(),m=he(g);s(m.properties),m.metadata&&e&&n(m.metadata)},downloadSchema:()=>{ve(a,"schema.json")},loadSchema:g=>{const m=he(g);s(m.properties),m.metadata&&e&&n(m.metadata)}}};function ts(){const[e,r]=I.useState("light");I.useEffect(()=>{const n=localStorage.getItem("theme")||(window.matchMedia("(prefers-color-scheme: dark)").matches?"dark":"light");r(n),document.documentElement.classList.toggle("dark",n==="dark")},[]);const s=()=>{const o=e==="light"?"dark":"light";r(o),localStorage.setItem("theme",o),document.documentElement.classList.toggle("dark",o==="dark")};return t.jsx(E,{variant:"ghost",size:"icon",onClick:s,"data-testid":"button-theme-toggle",children:e==="light"?t.jsx(b.Moon,{className:"w-4 h-4"}):t.jsx(b.Sun,{className:"w-4 h-4"})})}function ss({initialSchema:e,onSchemaChange:r,showMetadata:s=!1,showImport:o=!0,showClear:n=!0,showOutput:a=!0,showHeader:i=!0,className:d="h-screen",showSummary:c=!1,typeLabels:l,propertyLabel:h={singular:"property",plural:"properties"},showRegex:N=!1}){const[y,P]=I.useState(null),[g,m]=I.useState(!1),{properties:p,metadata:C,schema:j,addProperty:u,updateProperty:R,deleteProperty:D,clearAll:W,updateMetadata:O,importSchema:V,loadSchema:M}=Ye(s);I.useEffect(()=>{r&&r(j)},[j]),I.useEffect(()=>{e&&M(e)},[e]);const $=()=>{const T=u();P(T),m(!0)},G=T=>{R(T.id,T),m(!1),P(null)},v=()=>{m(!1),P(null)},x=()=>{W()},F=async()=>{await V()};return t.jsx(Ht,{customLabels:l,children:t.jsxs("div",{className:`${d} flex flex-col`,children:[i&&t.jsx("header",{className:"h-16 border-b flex items-center justify-between px-6",children:t.jsxs("div",{className:"flex items-center gap-3",children:[o&&t.jsx(E,{variant:"outline",size:"sm",onClick:F,"data-testid":"button-import",children:t.jsx(b.Upload,{className:"w-4 h-4"})}),n&&t.jsx(E,{variant:"outline",size:"sm",onClick:x,disabled:p.length===0,"data-testid":"button-clear",children:t.jsx(b.Trash2,{className:"w-4 h-4"})}),t.jsx(ts,{})]})}),t.jsxs("div",{className:"flex-1 flex overflow-hidden",children:[t.jsx("div",{className:a?"w-3/5 border-r":"w-full",children:t.jsxs("div",{className:"h-full overflow-auto p-6 space-y-4",children:[s&&t.jsx(Ze,{title:C.title,description:C.description,version:C.version,onUpdate:(T,_)=>O(T,_)}),p.length===0?t.jsxs("div",{className:"flex flex-col items-center justify-center py-16 text-center",children:[t.jsx("div",{className:"w-16 h-16 rounded-full bg-muted flex items-center justify-center mb-4",children:t.jsx(b.Plus,{className:"w-8 h-8 text-muted-foreground"})}),t.jsxs("h2",{className:"text-lg font-medium mb-2",children:["No ",h.plural," yet"]}),t.jsxs("p",{className:"text-sm text-muted-foreground mb-6 max-w-sm",children:["Start building your JSON schema by adding your first"," ",h.singular]}),t.jsxs(E,{onClick:$,"data-testid":"button-add-first",children:[t.jsx(b.Plus,{className:"w-4 h-4 mr-2"}),"Add ",h.singular]})]}):t.jsxs(t.Fragment,{children:[t.jsx("div",{className:"space-y-1",children:p.map(T=>t.jsx(ne,{property:T,onUpdate:_=>R(T.id,_),onDelete:()=>D(T.id),showRegex:N},T.id))}),t.jsx("div",{className:"pt-6",children:t.jsxs(E,{onClick:$,className:"w-full",variant:"outline","data-testid":"button-add-property",children:[t.jsx(b.Plus,{className:"w-4 h-4 mr-2"}),"Add ",h.singular]})}),c&&t.jsxs("div",{className:"pt-4 border-t flex items-center justify-between text-sm text-muted-foreground",children:[t.jsxs("span",{children:[p.length," ",p.length===1?h.singular:h.plural]}),t.jsxs("span",{children:[p.filter(T=>T.required).length," required"]})]})]})]})}),a&&t.jsx("div",{className:"w-2/5",children:t.jsx(Xe,{schema:j})})]}),g&&y&&t.jsx(re,{property:y,open:g,isNewProperty:!0,onOpenChange:T=>{T||v()},propertyLabel:h,onUpdate:G,showRegex:N})]})})}exports.JsonOutput=Xe;exports.JsonSchemaBuilder=ss;exports.PropertyDocument=ne;exports.PropertyEditDialog=re;exports.SchemaMetadataComponent=Ze;exports.downloadJsonFile=ve;exports.generateSchema=Qe;exports.importJsonFile=He;exports.parseSchema=he;exports.usePropertyEditor=Ue;exports.useSchemaBuilder=Ye;
|
|
2
|
+
//# sourceMappingURL=index.cjs.map
|