modern-json-react 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +243 -0
- package/dist/index.d.mts +440 -0
- package/dist/index.d.ts +440 -0
- package/dist/index.js +1691 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +1670 -0
- package/dist/index.mjs.map +1 -0
- package/package.json +67 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Dileep Pandey
|
|
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,243 @@
|
|
|
1
|
+
# modern-json-react
|
|
2
|
+
|
|
3
|
+
A production-grade, fully-featured JSON editor React component. Combines code editing, tree view navigation, JSON Schema validation, and accessibility-first design in a single, zero-config package.
|
|
4
|
+
|
|
5
|
+
## Screenshots
|
|
6
|
+
|
|
7
|
+
### Code Mode (Light)
|
|
8
|
+
|
|
9
|
+
Syntax-highlighted editor with line numbers, bracket matching, and real-time validation:
|
|
10
|
+
|
|
11
|
+

|
|
12
|
+
|
|
13
|
+
### Tree Mode (Light)
|
|
14
|
+
|
|
15
|
+
Collapsible tree view with inline editing, type badges, and hover actions:
|
|
16
|
+
|
|
17
|
+

|
|
18
|
+
|
|
19
|
+
### Code Mode (Dark)
|
|
20
|
+
|
|
21
|
+
Full dark theme support with VS Code-inspired color palette:
|
|
22
|
+
|
|
23
|
+

|
|
24
|
+
|
|
25
|
+
## Features
|
|
26
|
+
|
|
27
|
+
- **Dual editing modes** — Syntax-highlighted code editor, collapsible tree view, or side-by-side split mode
|
|
28
|
+
- **JSON Schema validation** — Built-in Draft-07 support with real-time error markers and human-readable messages
|
|
29
|
+
- **Tree view editing** — Inline value editing, type changing, key renaming, drag-drop reordering, and node deletion
|
|
30
|
+
- **Undo / Redo** — Full history stack with time-based action grouping and keyboard shortcuts
|
|
31
|
+
- **Search** — Full-text search across keys and values with regex support and match highlighting
|
|
32
|
+
- **Theming** — Light and dark presets with 22 CSS custom properties for full customization
|
|
33
|
+
- **Formatting** — Pretty-print, minify, sort keys (ascending, descending, or custom comparator)
|
|
34
|
+
- **Accessibility** — WCAG 2.1 AA compliant with full keyboard navigation, ARIA roles, and screen reader announcements
|
|
35
|
+
- **TypeScript** — Complete type definitions with JSDoc comments
|
|
36
|
+
- **Zero peer dependencies** — Only requires React 18+
|
|
37
|
+
|
|
38
|
+
## Installation
|
|
39
|
+
|
|
40
|
+
```bash
|
|
41
|
+
npm install modern-json-react
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
## Quick Start
|
|
45
|
+
|
|
46
|
+
```tsx
|
|
47
|
+
import { JsonEditor } from 'modern-json-react';
|
|
48
|
+
|
|
49
|
+
function App() {
|
|
50
|
+
const [data, setData] = useState({ name: "John", age: 30 });
|
|
51
|
+
|
|
52
|
+
return (
|
|
53
|
+
<JsonEditor
|
|
54
|
+
value={data}
|
|
55
|
+
onChange={(value) => setData(value)}
|
|
56
|
+
height={500}
|
|
57
|
+
/>
|
|
58
|
+
);
|
|
59
|
+
}
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
## Props
|
|
63
|
+
|
|
64
|
+
| Prop | Type | Default | Description |
|
|
65
|
+
|------|------|---------|-------------|
|
|
66
|
+
| `value` | `unknown` | — | JSON value (object, array, string, etc.) or raw JSON string |
|
|
67
|
+
| `onChange` | `(value, rawText) => void` | — | Called when the JSON value changes |
|
|
68
|
+
| `mode` | `'code' \| 'tree' \| 'split'` | `'code'` | Active editing mode |
|
|
69
|
+
| `onModeChange` | `(mode) => void` | — | Called when the user switches modes |
|
|
70
|
+
| `schema` | `JSONSchema` | — | JSON Schema for validation (Draft-07, 2019-09, 2020-12) |
|
|
71
|
+
| `validators` | `CustomValidator[]` | — | Custom validation functions |
|
|
72
|
+
| `validationMode` | `'onChange' \| 'onBlur' \| 'onSubmit' \| 'manual'` | `'onChange'` | When to trigger validation |
|
|
73
|
+
| `onValidate` | `(errors) => void` | — | Called when validation completes |
|
|
74
|
+
| `theme` | `'light' \| 'dark' \| 'auto' \| ThemeConfig` | `'light'` | Theme preset or custom config |
|
|
75
|
+
| `height` | `string \| number` | `400` | Editor height (CSS value or pixels) |
|
|
76
|
+
| `readOnly` | `boolean` | `false` | Disable editing |
|
|
77
|
+
| `searchable` | `boolean` | `true` | Show search bar |
|
|
78
|
+
| `sortable` | `boolean` | `true` | Enable key sorting |
|
|
79
|
+
| `indentation` | `2 \| 4 \| 'tab'` | `2` | Indentation style |
|
|
80
|
+
| `lineNumbers` | `boolean` | `true` | Show line numbers in code mode |
|
|
81
|
+
| `className` | `string` | — | Additional CSS class |
|
|
82
|
+
|
|
83
|
+
## Schema Validation
|
|
84
|
+
|
|
85
|
+
Pass a JSON Schema to get real-time validation with inline error markers:
|
|
86
|
+
|
|
87
|
+
```tsx
|
|
88
|
+
const schema = {
|
|
89
|
+
type: 'object',
|
|
90
|
+
properties: {
|
|
91
|
+
name: { type: 'string', minLength: 1 },
|
|
92
|
+
age: { type: 'number', minimum: 0 },
|
|
93
|
+
email: { type: 'string', format: 'email' },
|
|
94
|
+
},
|
|
95
|
+
required: ['name', 'email'],
|
|
96
|
+
};
|
|
97
|
+
|
|
98
|
+
<JsonEditor
|
|
99
|
+
value={data}
|
|
100
|
+
onChange={setData}
|
|
101
|
+
schema={schema}
|
|
102
|
+
onValidate={(errors) => console.log(errors)}
|
|
103
|
+
/>
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
## Custom Validators
|
|
107
|
+
|
|
108
|
+
Add your own validation rules alongside schema validation:
|
|
109
|
+
|
|
110
|
+
```tsx
|
|
111
|
+
const noEmptyArrays = (value, path) => {
|
|
112
|
+
if (Array.isArray(value) && value.length === 0) {
|
|
113
|
+
return [{ message: 'Array must not be empty', path, severity: 'warning' }];
|
|
114
|
+
}
|
|
115
|
+
return [];
|
|
116
|
+
};
|
|
117
|
+
|
|
118
|
+
<JsonEditor value={data} validators={[noEmptyArrays]} />
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
## Theming
|
|
122
|
+
|
|
123
|
+
Use a preset or provide a full custom theme:
|
|
124
|
+
|
|
125
|
+
```tsx
|
|
126
|
+
// Preset
|
|
127
|
+
<JsonEditor theme="dark" />
|
|
128
|
+
|
|
129
|
+
// Auto (follows OS preference)
|
|
130
|
+
<JsonEditor theme="auto" />
|
|
131
|
+
|
|
132
|
+
// Custom theme
|
|
133
|
+
<JsonEditor theme={{
|
|
134
|
+
name: 'ocean',
|
|
135
|
+
bg: '#0d1b2a',
|
|
136
|
+
fg: '#e0e1dd',
|
|
137
|
+
border: '#1b263b',
|
|
138
|
+
keyColor: '#48cae4',
|
|
139
|
+
stringColor: '#90e0ef',
|
|
140
|
+
numberColor: '#ade8f4',
|
|
141
|
+
// ... see ThemeConfig for all 22 properties
|
|
142
|
+
}} />
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
Override individual tokens with CSS custom properties:
|
|
146
|
+
|
|
147
|
+
```css
|
|
148
|
+
.my-editor {
|
|
149
|
+
--mjr-bg: #fafafa;
|
|
150
|
+
--mjr-key: #d63384;
|
|
151
|
+
--mjr-string: #198754;
|
|
152
|
+
}
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
## Exported Utilities
|
|
156
|
+
|
|
157
|
+
The package also exports core utilities for advanced use cases:
|
|
158
|
+
|
|
159
|
+
```tsx
|
|
160
|
+
import {
|
|
161
|
+
// Parsing
|
|
162
|
+
parseJson, stringifyJson, isValidJson,
|
|
163
|
+
|
|
164
|
+
// Validation
|
|
165
|
+
validateSchema, runCustomValidators,
|
|
166
|
+
|
|
167
|
+
// Formatting
|
|
168
|
+
formatJson, minifyJson, sortJsonKeys, computeStats,
|
|
169
|
+
|
|
170
|
+
// Path operations (immutable)
|
|
171
|
+
getByPath, setByPath, deleteByPath, parsePath,
|
|
172
|
+
|
|
173
|
+
// Hooks (for building custom editors)
|
|
174
|
+
useJsonParser, useUndoRedo, useSearch,
|
|
175
|
+
|
|
176
|
+
// Themes
|
|
177
|
+
lightTheme, darkTheme,
|
|
178
|
+
} from 'modern-json-react';
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
## Keyboard Shortcuts
|
|
182
|
+
|
|
183
|
+
| Shortcut | Action |
|
|
184
|
+
|----------|--------|
|
|
185
|
+
| `Ctrl/Cmd + Z` | Undo |
|
|
186
|
+
| `Ctrl/Cmd + Shift + Z` | Redo |
|
|
187
|
+
| `Ctrl/Cmd + F` | Open search |
|
|
188
|
+
| `Escape` | Close search |
|
|
189
|
+
| `Tab` | Indent (code mode) |
|
|
190
|
+
| `Enter` | Edit selected node (tree mode) |
|
|
191
|
+
| `Delete` | Delete selected node (tree mode) |
|
|
192
|
+
| Arrow keys | Navigate tree nodes |
|
|
193
|
+
|
|
194
|
+
## Browser Support
|
|
195
|
+
|
|
196
|
+
Chrome/Edge 90+, Firefox 90+, Safari 15+. Requires React 18 or later.
|
|
197
|
+
|
|
198
|
+
## Development
|
|
199
|
+
|
|
200
|
+
```bash
|
|
201
|
+
# Install dependencies
|
|
202
|
+
npm install
|
|
203
|
+
|
|
204
|
+
# Run tests
|
|
205
|
+
npm test
|
|
206
|
+
|
|
207
|
+
# Type checking
|
|
208
|
+
npm run typecheck
|
|
209
|
+
|
|
210
|
+
# Build for production
|
|
211
|
+
npm run build
|
|
212
|
+
|
|
213
|
+
# Open interactive demo
|
|
214
|
+
open demo/index.html
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
## Project Structure
|
|
218
|
+
|
|
219
|
+
```
|
|
220
|
+
src/
|
|
221
|
+
├── index.ts # Public API exports
|
|
222
|
+
├── JsonEditor.tsx # Root component
|
|
223
|
+
├── components/
|
|
224
|
+
│ ├── CodeEditor/ # Syntax-highlighted text editor
|
|
225
|
+
│ ├── TreeEditor/ # Collapsible tree with inline editing
|
|
226
|
+
│ ├── Toolbar/ # Mode switcher, search, actions
|
|
227
|
+
│ └── StatusBar/ # Validation status, cursor position, stats
|
|
228
|
+
├── hooks/
|
|
229
|
+
│ ├── useJsonParser.ts # Parse + validate
|
|
230
|
+
│ ├── useUndoRedo.ts # History management
|
|
231
|
+
│ └── useSearch.ts # Search state + matching
|
|
232
|
+
├── core/
|
|
233
|
+
│ ├── parser.ts # JSON parsing with error locations
|
|
234
|
+
│ ├── validator.ts # JSON Schema validation engine
|
|
235
|
+
│ ├── formatter.ts # Format, minify, sort, stats
|
|
236
|
+
│ └── path.ts # JSONPath get/set/delete (immutable)
|
|
237
|
+
├── themes/ # Light + dark presets
|
|
238
|
+
└── types/ # TypeScript interfaces
|
|
239
|
+
```
|
|
240
|
+
|
|
241
|
+
## License
|
|
242
|
+
|
|
243
|
+
MIT
|
package/dist/index.d.mts
ADDED
|
@@ -0,0 +1,440 @@
|
|
|
1
|
+
import React$1 from 'react';
|
|
2
|
+
|
|
3
|
+
/** Severity level for validation messages */
|
|
4
|
+
type ValidationSeverity = 'error' | 'warning' | 'info';
|
|
5
|
+
/** A validation error/warning with location and context */
|
|
6
|
+
interface ValidationError {
|
|
7
|
+
/** Human-readable error message */
|
|
8
|
+
message: string;
|
|
9
|
+
/** JSONPath to the offending value (e.g., "$.address.zip") */
|
|
10
|
+
path: string;
|
|
11
|
+
/** Severity level */
|
|
12
|
+
severity: ValidationSeverity;
|
|
13
|
+
/** Line number in the raw text (1-based, if available) */
|
|
14
|
+
line?: number;
|
|
15
|
+
/** Column number in the raw text (1-based, if available) */
|
|
16
|
+
column?: number;
|
|
17
|
+
/** The JSON Schema keyword that failed (e.g., "minimum", "required") */
|
|
18
|
+
schemaKeyword?: string;
|
|
19
|
+
/** The schema rule that was violated */
|
|
20
|
+
schemaRule?: unknown;
|
|
21
|
+
/** The actual value that failed validation */
|
|
22
|
+
actualValue?: unknown;
|
|
23
|
+
}
|
|
24
|
+
/** JSON Schema type — kept intentionally loose for broad draft support */
|
|
25
|
+
type JSONSchema = Record<string, unknown> & {
|
|
26
|
+
type?: string | string[];
|
|
27
|
+
properties?: Record<string, JSONSchema>;
|
|
28
|
+
items?: JSONSchema | JSONSchema[];
|
|
29
|
+
required?: string[];
|
|
30
|
+
$ref?: string;
|
|
31
|
+
$schema?: string;
|
|
32
|
+
};
|
|
33
|
+
/** Custom validator function — returns an array of errors (empty = valid) */
|
|
34
|
+
type CustomValidator = (value: unknown, path: string) => ValidationError[] | Promise<ValidationError[]>;
|
|
35
|
+
/** Result from the validation engine */
|
|
36
|
+
interface ValidationResult {
|
|
37
|
+
valid: boolean;
|
|
38
|
+
errors: ValidationError[];
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/** Full theme configuration using CSS custom property values */
|
|
42
|
+
interface ThemeConfig {
|
|
43
|
+
/** Theme name identifier */
|
|
44
|
+
name: string;
|
|
45
|
+
/** Editor background */
|
|
46
|
+
bg: string;
|
|
47
|
+
/** Default text color */
|
|
48
|
+
fg: string;
|
|
49
|
+
/** Borders and dividers */
|
|
50
|
+
border: string;
|
|
51
|
+
/** Line number gutter background */
|
|
52
|
+
gutterBg: string;
|
|
53
|
+
/** Line number text */
|
|
54
|
+
gutterFg: string;
|
|
55
|
+
/** Text selection background */
|
|
56
|
+
selection: string;
|
|
57
|
+
/** Cursor color */
|
|
58
|
+
cursor: string;
|
|
59
|
+
/** Syntax: object keys */
|
|
60
|
+
keyColor: string;
|
|
61
|
+
/** Syntax: string values */
|
|
62
|
+
stringColor: string;
|
|
63
|
+
/** Syntax: number values */
|
|
64
|
+
numberColor: string;
|
|
65
|
+
/** Syntax: booleans */
|
|
66
|
+
booleanColor: string;
|
|
67
|
+
/** Syntax: null */
|
|
68
|
+
nullColor: string;
|
|
69
|
+
/** Syntax: brackets and braces */
|
|
70
|
+
bracketColor: string;
|
|
71
|
+
/** Matching bracket highlight */
|
|
72
|
+
bracketMatchBg: string;
|
|
73
|
+
/** Error indicator color */
|
|
74
|
+
errorColor: string;
|
|
75
|
+
/** Warning indicator color */
|
|
76
|
+
warningColor: string;
|
|
77
|
+
/** Success indicator color */
|
|
78
|
+
successColor: string;
|
|
79
|
+
/** Tree connector lines */
|
|
80
|
+
treeLine: string;
|
|
81
|
+
/** Tree hovered node background */
|
|
82
|
+
treeHover: string;
|
|
83
|
+
/** Tree selected node background */
|
|
84
|
+
treeSelected: string;
|
|
85
|
+
/** Type badge background */
|
|
86
|
+
typeBadgeBg: string;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
/** Editing mode for the JSON editor */
|
|
90
|
+
type EditorMode = 'code' | 'tree' | 'split';
|
|
91
|
+
/** When to trigger validation */
|
|
92
|
+
type ValidationMode = 'onChange' | 'onBlur' | 'onSubmit' | 'manual';
|
|
93
|
+
/** Indentation configuration */
|
|
94
|
+
type IndentationType = 2 | 4 | 'tab';
|
|
95
|
+
/** Props for the root JsonEditor component */
|
|
96
|
+
interface JsonEditorProps {
|
|
97
|
+
/** The JSON value — can be a parsed object or a raw JSON string */
|
|
98
|
+
value?: unknown;
|
|
99
|
+
/** Called when the JSON value changes */
|
|
100
|
+
onChange?: (value: unknown, rawText: string) => void;
|
|
101
|
+
/** Active editing mode */
|
|
102
|
+
mode?: EditorMode;
|
|
103
|
+
/** Called when the user switches modes */
|
|
104
|
+
onModeChange?: (mode: EditorMode) => void;
|
|
105
|
+
/** JSON Schema for validation (Draft-07, 2019-09, 2020-12) */
|
|
106
|
+
schema?: JSONSchema;
|
|
107
|
+
/** Custom validator functions */
|
|
108
|
+
validators?: CustomValidator[];
|
|
109
|
+
/** When to run validation */
|
|
110
|
+
validationMode?: ValidationMode;
|
|
111
|
+
/** Called when validation completes */
|
|
112
|
+
onValidate?: (errors: ValidationError[]) => void;
|
|
113
|
+
/** Theme: preset name, "auto" (follows OS), or custom config */
|
|
114
|
+
theme?: 'light' | 'dark' | 'auto' | ThemeConfig;
|
|
115
|
+
/** Editor height — CSS value or pixel number */
|
|
116
|
+
height?: string | number;
|
|
117
|
+
/** If true, editor is read-only */
|
|
118
|
+
readOnly?: boolean;
|
|
119
|
+
/** Enable search bar */
|
|
120
|
+
searchable?: boolean;
|
|
121
|
+
/** Enable key sorting */
|
|
122
|
+
sortable?: boolean;
|
|
123
|
+
/** Indentation style */
|
|
124
|
+
indentation?: IndentationType;
|
|
125
|
+
/** Show line numbers in code mode */
|
|
126
|
+
lineNumbers?: boolean;
|
|
127
|
+
/** Enable bracket matching */
|
|
128
|
+
bracketMatching?: boolean;
|
|
129
|
+
/** Max document size in bytes — shows warning above this */
|
|
130
|
+
maxSize?: number;
|
|
131
|
+
/** Enable virtual scrolling ("auto" enables for large docs) */
|
|
132
|
+
virtualize?: boolean | 'auto';
|
|
133
|
+
/** Called on parse/render errors */
|
|
134
|
+
onError?: (error: Error) => void;
|
|
135
|
+
/** Called when editor gains focus */
|
|
136
|
+
onFocus?: () => void;
|
|
137
|
+
/** Called when editor loses focus */
|
|
138
|
+
onBlur?: () => void;
|
|
139
|
+
/** Additional CSS class on the root element */
|
|
140
|
+
className?: string;
|
|
141
|
+
/** Inline styles on the root element */
|
|
142
|
+
style?: React.CSSProperties;
|
|
143
|
+
/** Accessible label for the editor */
|
|
144
|
+
'aria-label'?: string;
|
|
145
|
+
}
|
|
146
|
+
/** Internal editor state shared across sub-components */
|
|
147
|
+
interface EditorState {
|
|
148
|
+
/** The raw JSON text */
|
|
149
|
+
text: string;
|
|
150
|
+
/** The parsed value (undefined if parse error) */
|
|
151
|
+
parsedValue: unknown;
|
|
152
|
+
/** Current parse error, if any */
|
|
153
|
+
parseError: ParseError | null;
|
|
154
|
+
/** Schema validation errors */
|
|
155
|
+
validationErrors: ValidationError[];
|
|
156
|
+
/** Current cursor position */
|
|
157
|
+
cursor: CursorPosition;
|
|
158
|
+
/** Current selection range */
|
|
159
|
+
selection: SelectionRange | null;
|
|
160
|
+
/** Whether the document has been modified */
|
|
161
|
+
isDirty: boolean;
|
|
162
|
+
}
|
|
163
|
+
/** Position in the text */
|
|
164
|
+
interface CursorPosition {
|
|
165
|
+
line: number;
|
|
166
|
+
column: number;
|
|
167
|
+
offset: number;
|
|
168
|
+
}
|
|
169
|
+
/** A range of selected text */
|
|
170
|
+
interface SelectionRange {
|
|
171
|
+
start: CursorPosition;
|
|
172
|
+
end: CursorPosition;
|
|
173
|
+
}
|
|
174
|
+
/** A JSON parse error with location info */
|
|
175
|
+
interface ParseError {
|
|
176
|
+
message: string;
|
|
177
|
+
line: number;
|
|
178
|
+
column: number;
|
|
179
|
+
offset: number;
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
/**
|
|
183
|
+
* A production-grade JSON editor React component.
|
|
184
|
+
*
|
|
185
|
+
* Supports code editing, tree editing, split view, JSON Schema validation,
|
|
186
|
+
* undo/redo, search, theming, and full keyboard accessibility.
|
|
187
|
+
*/
|
|
188
|
+
declare const JsonEditor: React$1.FC<JsonEditorProps>;
|
|
189
|
+
|
|
190
|
+
/** The type of a JSON value node */
|
|
191
|
+
type JsonNodeType = 'string' | 'number' | 'boolean' | 'null' | 'object' | 'array';
|
|
192
|
+
/** A node in the JSON tree representation */
|
|
193
|
+
interface TreeNode {
|
|
194
|
+
/** Unique identifier for this node */
|
|
195
|
+
id: string;
|
|
196
|
+
/** The key name (for object properties) or index (for array items) */
|
|
197
|
+
key: string | number;
|
|
198
|
+
/** The value at this node */
|
|
199
|
+
value: unknown;
|
|
200
|
+
/** The type of the value */
|
|
201
|
+
type: JsonNodeType;
|
|
202
|
+
/** JSONPath from root (e.g., "$.address.city") */
|
|
203
|
+
path: string;
|
|
204
|
+
/** Depth in the tree (0 = root) */
|
|
205
|
+
depth: number;
|
|
206
|
+
/** Whether this node is expanded (for objects/arrays) */
|
|
207
|
+
expanded: boolean;
|
|
208
|
+
/** Child nodes (for objects/arrays) */
|
|
209
|
+
children: TreeNode[];
|
|
210
|
+
/** Number of descendant nodes (for display purposes) */
|
|
211
|
+
descendantCount: number;
|
|
212
|
+
/** Parent node ID (null for root) */
|
|
213
|
+
parentId: string | null;
|
|
214
|
+
}
|
|
215
|
+
/** Action types for tree editing operations */
|
|
216
|
+
type TreeAction = {
|
|
217
|
+
type: 'SET_VALUE';
|
|
218
|
+
nodeId: string;
|
|
219
|
+
value: unknown;
|
|
220
|
+
} | {
|
|
221
|
+
type: 'SET_KEY';
|
|
222
|
+
nodeId: string;
|
|
223
|
+
key: string;
|
|
224
|
+
} | {
|
|
225
|
+
type: 'SET_TYPE';
|
|
226
|
+
nodeId: string;
|
|
227
|
+
newType: JsonNodeType;
|
|
228
|
+
} | {
|
|
229
|
+
type: 'DELETE_NODE';
|
|
230
|
+
nodeId: string;
|
|
231
|
+
} | {
|
|
232
|
+
type: 'ADD_CHILD';
|
|
233
|
+
parentId: string;
|
|
234
|
+
key: string;
|
|
235
|
+
value: unknown;
|
|
236
|
+
} | {
|
|
237
|
+
type: 'MOVE_NODE';
|
|
238
|
+
nodeId: string;
|
|
239
|
+
targetParentId: string;
|
|
240
|
+
targetIndex: number;
|
|
241
|
+
} | {
|
|
242
|
+
type: 'DUPLICATE_NODE';
|
|
243
|
+
nodeId: string;
|
|
244
|
+
} | {
|
|
245
|
+
type: 'TOGGLE_EXPAND';
|
|
246
|
+
nodeId: string;
|
|
247
|
+
} | {
|
|
248
|
+
type: 'EXPAND_ALL';
|
|
249
|
+
} | {
|
|
250
|
+
type: 'COLLAPSE_ALL';
|
|
251
|
+
};
|
|
252
|
+
/** Context menu item definition */
|
|
253
|
+
interface ContextMenuItem {
|
|
254
|
+
label: string;
|
|
255
|
+
icon?: string;
|
|
256
|
+
shortcut?: string;
|
|
257
|
+
action: () => void;
|
|
258
|
+
disabled?: boolean;
|
|
259
|
+
separator?: boolean;
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
declare const lightTheme: ThemeConfig;
|
|
263
|
+
|
|
264
|
+
declare const darkTheme: ThemeConfig;
|
|
265
|
+
|
|
266
|
+
/** Result of a JSON parse attempt */
|
|
267
|
+
interface ParseResult {
|
|
268
|
+
value: unknown;
|
|
269
|
+
error: ParseError | null;
|
|
270
|
+
}
|
|
271
|
+
/**
|
|
272
|
+
* Parse a JSON string with detailed error location info.
|
|
273
|
+
* Uses native JSON.parse but enhances error messages with line/column.
|
|
274
|
+
*/
|
|
275
|
+
declare function parseJson(text: string): ParseResult;
|
|
276
|
+
/**
|
|
277
|
+
* Stringify a value to formatted JSON text.
|
|
278
|
+
*/
|
|
279
|
+
declare function stringifyJson(value: unknown, indent?: number | string): string;
|
|
280
|
+
/**
|
|
281
|
+
* Check if a string is valid JSON without returning the parsed value.
|
|
282
|
+
*/
|
|
283
|
+
declare function isValidJson(text: string): boolean;
|
|
284
|
+
|
|
285
|
+
/**
|
|
286
|
+
* Validate a parsed JSON value against a JSON Schema (Draft-07 compatible subset).
|
|
287
|
+
* This is a built-in lightweight validator — for full draft support, users can
|
|
288
|
+
* supply an Ajv-based CustomValidator.
|
|
289
|
+
*/
|
|
290
|
+
declare function validateSchema(value: unknown, schema: JSONSchema, path?: string): ValidationResult;
|
|
291
|
+
/**
|
|
292
|
+
* Run custom validators on a value.
|
|
293
|
+
*/
|
|
294
|
+
declare function runCustomValidators(value: unknown, validators: CustomValidator[], path?: string): Promise<ValidationError[]>;
|
|
295
|
+
|
|
296
|
+
/**
|
|
297
|
+
* Pretty-print JSON text with the given indentation.
|
|
298
|
+
* Returns the original text if it cannot be parsed.
|
|
299
|
+
*/
|
|
300
|
+
declare function formatJson(text: string, indent?: IndentationType): string;
|
|
301
|
+
/**
|
|
302
|
+
* Minify JSON text (remove all whitespace).
|
|
303
|
+
*/
|
|
304
|
+
declare function minifyJson(text: string): string;
|
|
305
|
+
/**
|
|
306
|
+
* Sort object keys in JSON text.
|
|
307
|
+
* @param order - "asc" for ascending, "desc" for descending, or a custom comparator.
|
|
308
|
+
*/
|
|
309
|
+
declare function sortJsonKeys(text: string, order?: 'asc' | 'desc' | ((a: string, b: string) => number), indent?: IndentationType): string;
|
|
310
|
+
/**
|
|
311
|
+
* Compute document statistics from a JSON value.
|
|
312
|
+
*/
|
|
313
|
+
interface JsonStats {
|
|
314
|
+
properties: number;
|
|
315
|
+
arrays: number;
|
|
316
|
+
totalNodes: number;
|
|
317
|
+
maxDepth: number;
|
|
318
|
+
byteSize: number;
|
|
319
|
+
}
|
|
320
|
+
declare function computeStats(value: unknown, text?: string): JsonStats;
|
|
321
|
+
|
|
322
|
+
/**
|
|
323
|
+
* JSONPath and dot-notation utilities.
|
|
324
|
+
*/
|
|
325
|
+
/**
|
|
326
|
+
* Get a value from a nested object using a dot-notation path.
|
|
327
|
+
* Supports array indexing: "items[0].name" or "items.0.name"
|
|
328
|
+
*/
|
|
329
|
+
declare function getByPath(obj: unknown, path: string): unknown;
|
|
330
|
+
/**
|
|
331
|
+
* Set a value in a nested object using a dot-notation path.
|
|
332
|
+
* Returns a new object (immutable operation).
|
|
333
|
+
*/
|
|
334
|
+
declare function setByPath(obj: unknown, path: string, value: unknown): unknown;
|
|
335
|
+
/**
|
|
336
|
+
* Delete a key from a nested object by path.
|
|
337
|
+
* Returns a new object (immutable operation).
|
|
338
|
+
*/
|
|
339
|
+
declare function deleteByPath(obj: unknown, path: string): unknown;
|
|
340
|
+
/**
|
|
341
|
+
* Parse a JSONPath or dot-notation string into segments.
|
|
342
|
+
* "$." prefix is stripped. Brackets are converted to dot notation.
|
|
343
|
+
* E.g., "$.store.book[0].author" → ["store", "book", "0", "author"]
|
|
344
|
+
*/
|
|
345
|
+
declare function parsePath(path: string): string[];
|
|
346
|
+
/**
|
|
347
|
+
* Build a JSONPath string from segments.
|
|
348
|
+
*/
|
|
349
|
+
declare function buildPath(segments: (string | number)[]): string;
|
|
350
|
+
|
|
351
|
+
interface UseJsonParserOptions {
|
|
352
|
+
/** JSON Schema for validation */
|
|
353
|
+
schema?: JSONSchema;
|
|
354
|
+
/** Custom validators */
|
|
355
|
+
validators?: CustomValidator[];
|
|
356
|
+
/** Debounce interval in ms */
|
|
357
|
+
debounce?: number;
|
|
358
|
+
}
|
|
359
|
+
interface UseJsonParserResult {
|
|
360
|
+
/** The current raw text */
|
|
361
|
+
text: string;
|
|
362
|
+
/** The parsed value (undefined if invalid) */
|
|
363
|
+
parsedValue: unknown;
|
|
364
|
+
/** Parse error, if any */
|
|
365
|
+
parseError: ParseError | null;
|
|
366
|
+
/** Validation errors from schema + custom validators */
|
|
367
|
+
validationErrors: ValidationError[];
|
|
368
|
+
/** Whether the text is valid JSON */
|
|
369
|
+
isValid: boolean;
|
|
370
|
+
/** Update the raw text */
|
|
371
|
+
setText: (text: string) => void;
|
|
372
|
+
/** Update from a parsed value */
|
|
373
|
+
setValue: (value: unknown) => void;
|
|
374
|
+
/** Format the current text */
|
|
375
|
+
format: (indent?: number | string) => void;
|
|
376
|
+
}
|
|
377
|
+
/**
|
|
378
|
+
* Hook that manages JSON parsing and validation state.
|
|
379
|
+
*/
|
|
380
|
+
declare function useJsonParser(initialValue?: unknown, options?: UseJsonParserOptions): UseJsonParserResult;
|
|
381
|
+
|
|
382
|
+
interface UndoRedoOptions {
|
|
383
|
+
/** Maximum number of history entries */
|
|
384
|
+
maxHistory?: number;
|
|
385
|
+
/** Time window (ms) for grouping consecutive actions */
|
|
386
|
+
groupingInterval?: number;
|
|
387
|
+
}
|
|
388
|
+
interface UndoRedoState<T> {
|
|
389
|
+
current: T;
|
|
390
|
+
canUndo: boolean;
|
|
391
|
+
canRedo: boolean;
|
|
392
|
+
historyLength: number;
|
|
393
|
+
set: (value: T) => void;
|
|
394
|
+
undo: () => void;
|
|
395
|
+
redo: () => void;
|
|
396
|
+
reset: (value: T) => void;
|
|
397
|
+
}
|
|
398
|
+
/**
|
|
399
|
+
* A hook providing undo/redo history management with time-based grouping.
|
|
400
|
+
*/
|
|
401
|
+
declare function useUndoRedo<T>(initialValue: T, options?: UndoRedoOptions): UndoRedoState<T>;
|
|
402
|
+
|
|
403
|
+
interface SearchMatch {
|
|
404
|
+
/** Line number (1-based) */
|
|
405
|
+
line: number;
|
|
406
|
+
/** Column start (0-based) */
|
|
407
|
+
columnStart: number;
|
|
408
|
+
/** Column end (0-based) */
|
|
409
|
+
columnEnd: number;
|
|
410
|
+
/** The matched text */
|
|
411
|
+
matchText: string;
|
|
412
|
+
/** JSONPath if in tree mode */
|
|
413
|
+
path?: string;
|
|
414
|
+
}
|
|
415
|
+
interface UseSearchOptions {
|
|
416
|
+
caseSensitive?: boolean;
|
|
417
|
+
useRegex?: boolean;
|
|
418
|
+
searchKeys?: boolean;
|
|
419
|
+
searchValues?: boolean;
|
|
420
|
+
}
|
|
421
|
+
interface UseSearchResult {
|
|
422
|
+
query: string;
|
|
423
|
+
setQuery: (q: string) => void;
|
|
424
|
+
matches: SearchMatch[];
|
|
425
|
+
currentMatchIndex: number;
|
|
426
|
+
totalMatches: number;
|
|
427
|
+
goToNext: () => void;
|
|
428
|
+
goToPrevious: () => void;
|
|
429
|
+
options: UseSearchOptions;
|
|
430
|
+
setOptions: (opts: Partial<UseSearchOptions>) => void;
|
|
431
|
+
isActive: boolean;
|
|
432
|
+
open: () => void;
|
|
433
|
+
close: () => void;
|
|
434
|
+
}
|
|
435
|
+
/**
|
|
436
|
+
* Hook for managing search state across the editor.
|
|
437
|
+
*/
|
|
438
|
+
declare function useSearch(text: string): UseSearchResult;
|
|
439
|
+
|
|
440
|
+
export { type ContextMenuItem, type CursorPosition, type CustomValidator, type EditorMode, type EditorState, type IndentationType, type JSONSchema, JsonEditor, type JsonEditorProps, type JsonNodeType, type ParseError, type SelectionRange, type ThemeConfig, type TreeAction, type TreeNode, type ValidationError, type ValidationMode, type ValidationResult, type ValidationSeverity, buildPath, computeStats, darkTheme, deleteByPath, formatJson, getByPath, isValidJson, lightTheme, minifyJson, parseJson, parsePath, runCustomValidators, setByPath, sortJsonKeys, stringifyJson, useJsonParser, useSearch, useUndoRedo, validateSchema };
|