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.
@@ -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 };