json-schema-builder-react 0.0.3 → 0.0.4
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 +153 -138
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -6,14 +6,13 @@ A beautiful, interactive React component for building and editing JSON schemas v
|
|
|
6
6
|
|
|
7
7
|
## Features
|
|
8
8
|
|
|
9
|
-
- 🎨 **Visual Editor** - Build JSON schemas with an intuitive
|
|
9
|
+
- 🎨 **Visual Editor** - Build JSON schemas with an intuitive interface
|
|
10
10
|
- 📝 **Full JSON Schema Support** - Support for all JSON Schema types and constraints
|
|
11
11
|
- 🎯 **Type-Safe** - Written in TypeScript with full type definitions
|
|
12
|
-
- ✅ **
|
|
12
|
+
- ✅ **Controlled Component** - Full control over state management
|
|
13
13
|
- 🎨 **Customizable** - Flexible API with extensive customization options
|
|
14
|
-
- 📦 **Headless Options** - Use just the hooks and utilities without UI
|
|
15
14
|
- 🌗 **Theme Support** - Built-in dark mode support
|
|
16
|
-
- ⚡ **Lightweight** -
|
|
15
|
+
- ⚡ **Lightweight** - Minimal bundle size with focused API
|
|
17
16
|
|
|
18
17
|
## Installation
|
|
19
18
|
|
|
@@ -84,16 +83,20 @@ Add to your main CSS file (e.g., `src/index.css`):
|
|
|
84
83
|
### Basic Example
|
|
85
84
|
|
|
86
85
|
```tsx
|
|
86
|
+
import { useState } from 'react';
|
|
87
87
|
import { JsonSchemaBuilder } from 'json-schema-builder-react';
|
|
88
88
|
|
|
89
89
|
function App() {
|
|
90
|
-
const
|
|
91
|
-
|
|
92
|
-
|
|
90
|
+
const [schema, setSchema] = useState({
|
|
91
|
+
type: 'object',
|
|
92
|
+
properties: {},
|
|
93
|
+
required: []
|
|
94
|
+
});
|
|
93
95
|
|
|
94
96
|
return (
|
|
95
97
|
<JsonSchemaBuilder
|
|
96
|
-
|
|
98
|
+
schema={schema}
|
|
99
|
+
onChange={setSchema}
|
|
97
100
|
/>
|
|
98
101
|
);
|
|
99
102
|
}
|
|
@@ -102,24 +105,35 @@ function App() {
|
|
|
102
105
|
### With Initial Schema
|
|
103
106
|
|
|
104
107
|
```tsx
|
|
108
|
+
import { useState } from 'react';
|
|
105
109
|
import { JsonSchemaBuilder } from 'json-schema-builder-react';
|
|
106
110
|
|
|
107
|
-
const initialSchema = {
|
|
108
|
-
type: 'object',
|
|
109
|
-
properties: {
|
|
110
|
-
name: { type: 'string' },
|
|
111
|
-
age: { type: 'number' }
|
|
112
|
-
},
|
|
113
|
-
required: ['name']
|
|
114
|
-
};
|
|
115
|
-
|
|
116
111
|
function App() {
|
|
112
|
+
const [schema, setSchema] = useState({
|
|
113
|
+
type: 'object',
|
|
114
|
+
title: 'User Profile',
|
|
115
|
+
properties: {
|
|
116
|
+
name: {
|
|
117
|
+
type: 'string',
|
|
118
|
+
minLength: 2,
|
|
119
|
+
maxLength: 50
|
|
120
|
+
},
|
|
121
|
+
age: {
|
|
122
|
+
type: 'integer',
|
|
123
|
+
minimum: 0,
|
|
124
|
+
maximum: 120
|
|
125
|
+
}
|
|
126
|
+
},
|
|
127
|
+
required: ['name']
|
|
128
|
+
});
|
|
129
|
+
|
|
117
130
|
return (
|
|
118
131
|
<JsonSchemaBuilder
|
|
119
|
-
|
|
120
|
-
|
|
132
|
+
schema={schema}
|
|
133
|
+
onChange={(newSchema) => {
|
|
134
|
+
setSchema(newSchema);
|
|
121
135
|
// Save to backend, localStorage, etc.
|
|
122
|
-
|
|
136
|
+
localStorage.setItem('schema', JSON.stringify(newSchema));
|
|
123
137
|
}}
|
|
124
138
|
/>
|
|
125
139
|
);
|
|
@@ -129,14 +143,21 @@ function App() {
|
|
|
129
143
|
### Customized Layout
|
|
130
144
|
|
|
131
145
|
```tsx
|
|
146
|
+
import { useState } from 'react';
|
|
132
147
|
import { JsonSchemaBuilder } from 'json-schema-builder-react';
|
|
133
148
|
|
|
134
149
|
function App() {
|
|
150
|
+
const [schema, setSchema] = useState({
|
|
151
|
+
type: 'object',
|
|
152
|
+
properties: {},
|
|
153
|
+
required: []
|
|
154
|
+
});
|
|
155
|
+
|
|
135
156
|
return (
|
|
136
157
|
<JsonSchemaBuilder
|
|
158
|
+
schema={schema}
|
|
159
|
+
onChange={setSchema}
|
|
137
160
|
showMetadata={true}
|
|
138
|
-
showImport={false}
|
|
139
|
-
showClear={true}
|
|
140
161
|
showOutput={true}
|
|
141
162
|
className="h-[600px]"
|
|
142
163
|
typeLabels={{
|
|
@@ -145,33 +166,97 @@ function App() {
|
|
|
145
166
|
object: 'Form',
|
|
146
167
|
array: 'List',
|
|
147
168
|
}}
|
|
169
|
+
propertyLabel={{
|
|
170
|
+
singular: 'field',
|
|
171
|
+
plural: 'fields'
|
|
172
|
+
}}
|
|
148
173
|
/>
|
|
149
174
|
);
|
|
150
175
|
}
|
|
151
176
|
```
|
|
152
177
|
|
|
178
|
+
### With Undo/Redo
|
|
179
|
+
|
|
180
|
+
Since the component is fully controlled, you can implement undo/redo easily:
|
|
181
|
+
|
|
182
|
+
```tsx
|
|
183
|
+
import { useState } from 'react';
|
|
184
|
+
import { JsonSchemaBuilder } from 'json-schema-builder-react';
|
|
185
|
+
|
|
186
|
+
function App() {
|
|
187
|
+
const [history, setHistory] = useState([{
|
|
188
|
+
type: 'object',
|
|
189
|
+
properties: {},
|
|
190
|
+
required: []
|
|
191
|
+
}]);
|
|
192
|
+
const [currentIndex, setCurrentIndex] = useState(0);
|
|
193
|
+
|
|
194
|
+
const currentSchema = history[currentIndex];
|
|
195
|
+
|
|
196
|
+
const handleChange = (newSchema) => {
|
|
197
|
+
const newHistory = history.slice(0, currentIndex + 1);
|
|
198
|
+
newHistory.push(newSchema);
|
|
199
|
+
setHistory(newHistory);
|
|
200
|
+
setCurrentIndex(currentIndex + 1);
|
|
201
|
+
};
|
|
202
|
+
|
|
203
|
+
const undo = () => {
|
|
204
|
+
if (currentIndex > 0) {
|
|
205
|
+
setCurrentIndex(currentIndex - 1);
|
|
206
|
+
}
|
|
207
|
+
};
|
|
208
|
+
|
|
209
|
+
const redo = () => {
|
|
210
|
+
if (currentIndex < history.length - 1) {
|
|
211
|
+
setCurrentIndex(currentIndex + 1);
|
|
212
|
+
}
|
|
213
|
+
};
|
|
214
|
+
|
|
215
|
+
return (
|
|
216
|
+
<div>
|
|
217
|
+
<div className="toolbar">
|
|
218
|
+
<button onClick={undo} disabled={currentIndex === 0}>
|
|
219
|
+
Undo
|
|
220
|
+
</button>
|
|
221
|
+
<button onClick={redo} disabled={currentIndex === history.length - 1}>
|
|
222
|
+
Redo
|
|
223
|
+
</button>
|
|
224
|
+
</div>
|
|
225
|
+
|
|
226
|
+
<JsonSchemaBuilder
|
|
227
|
+
schema={currentSchema}
|
|
228
|
+
onChange={handleChange}
|
|
229
|
+
/>
|
|
230
|
+
</div>
|
|
231
|
+
);
|
|
232
|
+
}
|
|
233
|
+
```
|
|
234
|
+
|
|
153
235
|
## API Reference
|
|
154
236
|
|
|
155
237
|
### JsonSchemaBuilder Props
|
|
156
238
|
|
|
157
239
|
| Prop | Type | Default | Description |
|
|
158
240
|
|------|------|---------|-------------|
|
|
159
|
-
| `
|
|
160
|
-
| `
|
|
161
|
-
| `showMetadata` | `boolean` | `
|
|
241
|
+
| `schema` | `object` | **Required** | The JSON schema object (controlled) |
|
|
242
|
+
| `onChange` | `(schema: any) => void` | **Required** | Callback when schema changes |
|
|
243
|
+
| `showMetadata` | `boolean` | `false` | Show metadata fields (title, description, version) |
|
|
162
244
|
| `showImport` | `boolean` | `true` | Show import button |
|
|
163
245
|
| `showClear` | `boolean` | `true` | Show clear all button |
|
|
164
246
|
| `showOutput` | `boolean` | `true` | Show JSON output panel |
|
|
165
|
-
| `
|
|
247
|
+
| `showHeader` | `boolean` | `true` | Show header with action buttons |
|
|
248
|
+
| `showSummary` | `boolean` | `false` | Show summary at bottom |
|
|
249
|
+
| `showRegex` | `boolean` | `false` | Show regex pattern field for strings |
|
|
166
250
|
| `className` | `string` | `"h-screen"` | Custom className for container |
|
|
167
|
-
| `typeLabels` | `TypeLabels` | Default labels | Custom labels for property types
|
|
168
|
-
| `propertyLabel` | `{ singular: string, plural: string }` | `{ singular: 'property', plural: 'properties' }` | Custom labels for
|
|
251
|
+
| `typeLabels` | `TypeLabels` | Default labels | Custom labels for property types |
|
|
252
|
+
| `propertyLabel` | `{ singular: string, plural: string }` | `{ singular: 'property', plural: 'properties' }` | Custom labels for properties |
|
|
169
253
|
|
|
170
254
|
### Customizing Type Labels
|
|
171
255
|
|
|
172
256
|
You can customize how property types are displayed to your users:
|
|
173
257
|
|
|
174
258
|
```tsx
|
|
259
|
+
import { useState } from 'react';
|
|
175
260
|
import { JsonSchemaBuilder } from 'json-schema-builder-react';
|
|
176
261
|
import type { TypeLabels } from 'json-schema-builder-react';
|
|
177
262
|
|
|
@@ -186,10 +271,17 @@ const customLabels: TypeLabels = {
|
|
|
186
271
|
};
|
|
187
272
|
|
|
188
273
|
function App() {
|
|
274
|
+
const [schema, setSchema] = useState({
|
|
275
|
+
type: 'object',
|
|
276
|
+
properties: {},
|
|
277
|
+
required: []
|
|
278
|
+
});
|
|
279
|
+
|
|
189
280
|
return (
|
|
190
281
|
<JsonSchemaBuilder
|
|
282
|
+
schema={schema}
|
|
283
|
+
onChange={setSchema}
|
|
191
284
|
typeLabels={customLabels}
|
|
192
|
-
onSchemaChange={(schema) => console.log(schema)}
|
|
193
285
|
/>
|
|
194
286
|
);
|
|
195
287
|
}
|
|
@@ -209,132 +301,55 @@ This affects:
|
|
|
209
301
|
- `array` - Default: "Array"
|
|
210
302
|
- `null` - Default: "Null"
|
|
211
303
|
|
|
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
304
|
## Available Exports
|
|
250
305
|
|
|
251
|
-
###
|
|
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
|
|
306
|
+
### Component
|
|
307
|
+
- `JsonSchemaBuilder` - Main builder component (controlled)
|
|
267
308
|
|
|
268
309
|
### Types
|
|
269
|
-
- `
|
|
270
|
-
- `
|
|
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`)
|
|
310
|
+
- `JsonSchemaBuilderProps` - Props for the main component
|
|
311
|
+
- `TypeLabels` - Type for customizing property type labels
|
|
274
312
|
|
|
275
|
-
|
|
313
|
+
## Advanced Usage
|
|
276
314
|
|
|
277
|
-
|
|
315
|
+
### Integration with State Management
|
|
278
316
|
|
|
279
|
-
|
|
317
|
+
The controlled component pattern makes it easy to integrate with any state management solution:
|
|
280
318
|
|
|
319
|
+
#### Redux
|
|
281
320
|
```tsx
|
|
282
|
-
import {
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
} from 'json-schema-builder-react';
|
|
321
|
+
import { useSelector, useDispatch } from 'react-redux';
|
|
322
|
+
import { JsonSchemaBuilder } from 'json-schema-builder-react';
|
|
323
|
+
import { updateSchema } from './schemaSlice';
|
|
286
324
|
|
|
287
|
-
function
|
|
288
|
-
const
|
|
325
|
+
function App() {
|
|
326
|
+
const schema = useSelector(state => state.schema);
|
|
327
|
+
const dispatch = useDispatch();
|
|
289
328
|
|
|
290
329
|
return (
|
|
291
|
-
<
|
|
292
|
-
{
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
property={property}
|
|
296
|
-
onUpdate={(updated) => updateProperty(property.id, updated)}
|
|
297
|
-
onDelete={() => deleteProperty(property.id)}
|
|
298
|
-
/>
|
|
299
|
-
))}
|
|
300
|
-
</div>
|
|
330
|
+
<JsonSchemaBuilder
|
|
331
|
+
schema={schema}
|
|
332
|
+
onChange={(newSchema) => dispatch(updateSchema(newSchema))}
|
|
333
|
+
/>
|
|
301
334
|
);
|
|
302
335
|
}
|
|
303
336
|
```
|
|
304
337
|
|
|
305
|
-
|
|
306
|
-
|
|
338
|
+
#### Zustand
|
|
307
339
|
```tsx
|
|
308
|
-
import {
|
|
309
|
-
import
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
{
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
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
|
-
);
|
|
340
|
+
import { useSchemaStore } from './store';
|
|
341
|
+
import { JsonSchemaBuilder } from 'json-schema-builder-react';
|
|
342
|
+
|
|
343
|
+
function App() {
|
|
344
|
+
const { schema, setSchema } = useSchemaStore();
|
|
345
|
+
|
|
346
|
+
return (
|
|
347
|
+
<JsonSchemaBuilder
|
|
348
|
+
schema={schema}
|
|
349
|
+
onChange={setSchema}
|
|
350
|
+
/>
|
|
351
|
+
);
|
|
352
|
+
}
|
|
338
353
|
```
|
|
339
354
|
|
|
340
355
|
## Development
|