Skip to content

Commit 084a3cd

Browse files
authored
Merge pull request #1 from ht-rnd/feature/RND-1686
2 parents 4009158 + b0e6c72 commit 084a3cd

55 files changed

Lines changed: 11594 additions & 0 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.gitignore

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
# Logs
2+
logs
3+
*.log
4+
npm-debug.log*
5+
yarn-debug.log*
6+
yarn-error.log*
7+
pnpm-debug.log*
8+
lerna-debug.log*
9+
10+
node_modules
11+
dist
12+
dist-ssr
13+
*.local
14+
15+
# Editor directories and files
16+
.vscode/*
17+
!.vscode/extensions.json
18+
.idea
19+
.DS_Store
20+
*.suo
21+
*.ntvs*
22+
*.njsproj
23+
*.sln
24+
*.sw?

README.md

Lines changed: 227 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,227 @@
1+
# @ht-rnd/json-schema-editor
2+
3+
A modern, highly customizable, and themeable JSON Schema editor built with React, TypeScript, and shadcn/ui.
4+
5+
This component provides a clean, intuitive interface for visually building and editing JSON Schemas. It features real-time JSON output and live validation against the official JSON Schema specification, powered by AJV.
6+
7+
## Features
8+
9+
- **Modern Stack:** Built with React, TypeScript, Tailwind CSS, and `shadcn/ui`.
10+
- **Visual Editing:** Add, remove, and configure schema properties in a clear, row-based UI.
11+
- **Deeply Nested Schemas:** Full support for nested `object` and `array` types with recursion.
12+
- **Advanced Settings:** A detailed settings dialog for each property type (string, number, boolean, object, array).
13+
- **Real-time Output:** Instantly see the generated JSON Schema as you build.
14+
- **Live Schema Validation:** Integrated `ajv` validator provides real-time feedback and inline errors if your schema violates the JSON Schema specification.
15+
- **Highly Configurable:** Control the root type (`object` or `array`) and layout via props.
16+
- **Themeable:** Supports dark/light themes and custom styling.
17+
- **Read-Only Mode:** A prop to disable all interactions for display purposes.
18+
19+
## Installation
20+
21+
```bash
22+
npm install @ht-rnd/json-schema-editor
23+
```
24+
25+
## Usage and Setup
26+
27+
Integration requires two simple steps: configuring Tailwind and then using the component.
28+
29+
### Step 1: Configure Tailwind CSS
30+
31+
Because this library is built with Tailwind, your project's Tailwind process needs to know to scan this library's files for class names.
32+
33+
In your project's tailwind.config.js (or .cjs), add the path to the library within your content array:
34+
35+
```ts
36+
/** @type {import('tailwindcss').Config} */
37+
module.exports = {
38+
content: [
39+
"./src/**/*.{js,ts,jsx,tsx}", // Your app's files
40+
41+
// Add this line
42+
"./node_modules/@ht-rnd/json-schema-editor/dist/**/*.{js,ts,jsx,tsx}",
43+
],
44+
theme: {
45+
// ...
46+
},
47+
plugins: [],
48+
};
49+
```
50+
51+
### Step 2: Use the Component
52+
53+
```tsx
54+
import { JsonSchemaEditor } from "@ht-rnd/json-schema-editor";
55+
function MySchema() {
56+
const existingSchema: any = {
57+
type: "object",
58+
title: "Existing User Schema",
59+
properties: {
60+
name: { type: "string" },
61+
age: { type: "number", minimum: 0 },
62+
},
63+
required: ["name"],
64+
};
65+
66+
return (
67+
<div className="p-8">
68+
<JsonSchemaEditor
69+
rootType="object"
70+
theme="light"
71+
readOnly={false}
72+
defaultValue={existingSchema}
73+
onChange={(jsonSchema) => {
74+
console.log(jsonSchema);
75+
}}
76+
/>
77+
</div>
78+
);
79+
}
80+
export default MySchema;
81+
```
82+
83+
## Theming and Customization
84+
85+
This library is built on the `shadcn/ui` theming architecture, which relies on CSS variables for colors, borders, spacing, and radius. You can easily override these variables in your own project to match your application's design system.
86+
87+
1. In your project's global CSS file (e.g., `src/index.css`), define your custom theme variables inside a `@layer base` block.
88+
2. Your definitions will automatically override the library's default theme.
89+
90+
When you pass the `theme="dark"` prop to the JsonSchemaEditor, it will apply a `.dark` class to its root element, causing the browser to use the variables defined in your `.dark { ... }` block.
91+
92+
### Example `index.css`:
93+
94+
```css
95+
@tailwind base;
96+
@tailwind components;
97+
@tailwind utilities;
98+
99+
@layer base {
100+
:root {
101+
--background: 0 0% 100%;
102+
--foreground: 240 10% 3.9%;
103+
--primary: 329 100% 44%;
104+
--primary-hover: 329 100% 38%;
105+
--primary-pressed: 329 100% 31%;
106+
--primary-foreground: 0 0% 100%;
107+
--secondary: 240 4.8% 95.9%;
108+
--secondary-foreground: 240 5.9% 10%;
109+
--muted: 240 3.8% 80%;
110+
--muted-foreground: 240 3.8% 46.1%;
111+
--accent: 240 4.8% 95.9%;
112+
--accent-foreground: 240 5.9% 10%;
113+
--destructive: 0 100% 50%;
114+
--destructive-foreground: 0 0% 98%;
115+
--border: 240 5.9% 90%;
116+
--input: 240 5.9% 90%;
117+
--radius: 0.75rem;
118+
}
119+
120+
.dark {
121+
--background: 240 5.9% 10%;
122+
--foreground: 0 0% 92%;
123+
--primary: 330 96% 35%;
124+
--primary-hover: 330 96% 41%;
125+
--primary-pressed: 330 96% 48%;
126+
--primary-foreground: 240 17.1% 92%;
127+
--secondary: 240 3.7% 15.9%;
128+
--secondary-foreground: 0 0% 92%;
129+
--muted: 240 3.8% 40%;
130+
--muted-foreground: 240 5% 64.9%;
131+
--accent: 240 3.7% 15.9%;
132+
--accent-foreground: 0 0% 92%;
133+
--destructive: 0 100% 60%;
134+
--destructive-foreground: 0 0% 98%;
135+
--border: 240 3.7% 30%;
136+
--input: 240 3.7% 30%;<>
137+
}
138+
}
139+
140+
/* You can also add global styles like scrollbar theming */
141+
* {
142+
scrollbar-color: hsl(var(--muted)) hsl(var(--background));
143+
}
144+
```
145+
146+
## API Reference
147+
148+
### `<JsonSchemaEditor />` Props
149+
150+
| Prop | Type | Default | Description |
151+
| :------------- | :------------------------------ | :--------- | :----------------------------------------------------------------------------------------------------------- |
152+
| `rootType` | `'object'` \| `'array'` | `'object'` | Sets the root type of the schema. |
153+
| `readOnly` | `boolean` | `false` | Disables all user interactions, making the editor a display-only component. |
154+
| `theme` | `string` (e.g., `'dark'`) | `''` | A class name to apply for theming (e.g., pass `"dark"` for dark mode). |
155+
| `styles` | `Styles` | `{...}` | An object to control the layout, width, and spacing of the editor panels. |
156+
| `onChange` | `(schema: JSONSchema) => void` | `none` | A callback function that is invoked with the final schema object on any change. |
157+
| `defaultValue` | `JSONSchema` | `none` | An existing JSON Schema object to load into the editor. When provided, this will override the rootType prop. |
158+
159+
### The `styles` Prop
160+
161+
You can customize the layout and dimensions of the editor using the `styles` prop. You only need to provide the properties you wish to override.
162+
163+
**Type Definition:**
164+
165+
```ts
166+
interface Styles {
167+
form: {
168+
width: "sm" | "md" | "lg" | "full";
169+
height: "sm" | "md" | "lg" | "full";
170+
};
171+
output: {
172+
position: "top" | "bottom" | "left" | "right";
173+
showJson: boolean;
174+
width: "sm" | "md" | "lg" | "full";
175+
height: "sm" | "md" | "lg" | "full";
176+
};
177+
settings: {
178+
width: "sm" | "md" | "lg" | "full";
179+
};
180+
spacing: "sm" | "md" | "lg";
181+
}
182+
```
183+
184+
**Example Usage:**
185+
186+
```tsx
187+
// Example 1: Move the JSON output to the right side
188+
<JsonSchemaEditor
189+
styles={{
190+
output: { position: "right" },
191+
}}
192+
/>
193+
```
194+
195+
```tsx
196+
// Example 2: Make the form wider and use less spacing
197+
<JsonSchemaEditor
198+
styles={{
199+
form: { width: "lg" },
200+
spacing: "sm",
201+
}}
202+
/>
203+
```
204+
205+
```tsx
206+
// Example 3: Hide the JSON output entirely
207+
<JsonSchemaEditor
208+
styles={{
209+
output: { showJson: false },
210+
}}
211+
/>
212+
```
213+
214+
## Technology Stack
215+
216+
- React
217+
- TypeScript
218+
- React Hook Form for powerful and performant form state management.
219+
- Zod for schema validation and type inference.
220+
- AJV for real-time validation against the JSON Schema specification.
221+
- Tailwind CSS for utility-first styling.
222+
- shadcn/ui for the base component primitives.
223+
- Vite for the build tooling.
224+
225+
## License
226+
227+
Licensed under the Apache License 2.0

components.json

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
{
2+
"$schema": "https://ui.shadcn.com/schema.json",
3+
"style": "default",
4+
"rsc": true,
5+
"tsx": true,
6+
"tailwind": {
7+
"config": "tailwind.config.js",
8+
"css": "src/index.css",
9+
"baseColor": "zinc",
10+
"cssVariables": true,
11+
"prefix": ""
12+
},
13+
"aliases": {
14+
"components": "@/components",
15+
"utils": "@/lib/utils"
16+
},
17+
"iconLibrary": "lucide"
18+
}

eslint.config.js

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
import js from '@eslint/js'
2+
import globals from 'globals'
3+
import reactHooks from 'eslint-plugin-react-hooks'
4+
import reactRefresh from 'eslint-plugin-react-refresh'
5+
import tseslint from 'typescript-eslint'
6+
7+
export default tseslint.config(
8+
{ ignores: ['dist'] },
9+
{
10+
extends: [js.configs.recommended, ...tseslint.configs.recommended],
11+
files: ['**/*.{ts,tsx}'],
12+
languageOptions: {
13+
ecmaVersion: 2020,
14+
globals: globals.browser,
15+
},
16+
plugins: {
17+
'react-hooks': reactHooks,
18+
'react-refresh': reactRefresh,
19+
},
20+
rules: {
21+
...reactHooks.configs.recommended.rules,
22+
'react-refresh/only-export-components': [
23+
'warn',
24+
{ allowConstantExport: true },
25+
],
26+
},
27+
},
28+
)

index.html

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
<!DOCTYPE html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="UTF-8" />
5+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
6+
<title>Json Schema Editor</title>
7+
</head>
8+
<body>
9+
<div id="root"></div>
10+
<script type="module" src="/src/main.tsx"></script>
11+
</body>
12+
</html>

0 commit comments

Comments
 (0)