@djangocfg/ui-tools 2.1.126 → 2.1.129

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.
@@ -1,13 +1,21 @@
1
1
  'use client';
2
2
 
3
3
  import { ChevronDown, ChevronUp, Download } from 'lucide-react';
4
- import React, { useState } from 'react';
4
+ import React, { useState, useMemo } from 'react';
5
5
  import { CommonExternalProps, JSONTree } from 'react-json-tree';
6
6
 
7
7
  import { Button, CopyButton } from '@djangocfg/ui-core/components';
8
8
 
9
9
  export type { Language } from 'prism-react-renderer';
10
10
 
11
+ /**
12
+ * Display modes for JsonTree
13
+ * - full: With toolbar (Expand All, Copy, Download) and border
14
+ * - compact: No toolbar, with subtle border
15
+ * - inline: Minimal, no border, for embedding in other components
16
+ */
17
+ export type JsonTreeMode = 'full' | 'compact' | 'inline';
18
+
11
19
  export interface JsonTreeConfig {
12
20
  /** Maximum depth to expand automatically (default: 2) */
13
21
  maxAutoExpandDepth?: number;
@@ -34,16 +42,54 @@ export interface JsonTreeConfig {
34
42
  export interface JsonTreeComponentProps {
35
43
  title?: string;
36
44
  data: unknown;
45
+ /**
46
+ * Display mode:
47
+ * - "full" (default): With toolbar and border
48
+ * - "compact": No toolbar, subtle styling
49
+ * - "inline": Minimal, no border
50
+ */
51
+ mode?: JsonTreeMode;
37
52
  config?: JsonTreeConfig;
38
53
  /** Override for react-json-tree props */
39
54
  jsonTreeProps?: Partial<CommonExternalProps>;
40
55
  }
41
56
 
42
- const JsonTreeComponent = ({ title, data, config = {}, jsonTreeProps = {} }: JsonTreeComponentProps) => {
57
+ // Mode presets
58
+ const MODE_PRESETS: Record<JsonTreeMode, Partial<JsonTreeConfig>> = {
59
+ full: {
60
+ showExpandControls: true,
61
+ showActionButtons: true,
62
+ showCollectionInfo: true,
63
+ },
64
+ compact: {
65
+ showExpandControls: false,
66
+ showActionButtons: false,
67
+ showCollectionInfo: true,
68
+ },
69
+ inline: {
70
+ showExpandControls: false,
71
+ showActionButtons: false,
72
+ showCollectionInfo: false,
73
+ },
74
+ };
75
+
76
+ const JsonTreeComponent = ({
77
+ title,
78
+ data,
79
+ mode = 'full',
80
+ config = {},
81
+ jsonTreeProps = {}
82
+ }: JsonTreeComponentProps) => {
43
83
  // State for expand/collapse all
44
84
  const [expandAll, setExpandAll] = useState<boolean | null>(null);
45
85
  const [renderKey, setRenderKey] = useState(0);
46
-
86
+
87
+ // Merge mode presets with config (config overrides presets)
88
+ const mergedConfig = useMemo(() => ({
89
+ ...MODE_PRESETS[mode],
90
+ ...config,
91
+ }), [mode, config]);
92
+
47
93
  // Default configuration
48
94
  const {
49
95
  maxAutoExpandDepth = 2,
@@ -56,8 +102,8 @@ const JsonTreeComponent = ({ title, data, config = {}, jsonTreeProps = {} }: Jso
56
102
  showActionButtons = true,
57
103
  className = '',
58
104
  preserveKeyOrder = true,
59
- } = config;
60
-
105
+ } = mergedConfig;
106
+
61
107
  // JSON Tree theme optimized for dark theme
62
108
  const jsonTreeTheme = {
63
109
  scheme: 'djangocfg-dark',
@@ -104,7 +150,7 @@ const JsonTreeComponent = ({ title, data, config = {}, jsonTreeProps = {} }: Jso
104
150
  };
105
151
 
106
152
  // Collection info display
107
- const getItemString = showCollectionInfo
153
+ const getItemString = showCollectionInfo
108
154
  ? (nodeType: string, nodeData: unknown) => {
109
155
  if (nodeType === 'Array') {
110
156
  const length = Array.isArray(nodeData) ? nodeData.length : 0;
@@ -152,16 +198,48 @@ const JsonTreeComponent = ({ title, data, config = {}, jsonTreeProps = {} }: Jso
152
198
  URL.revokeObjectURL(url);
153
199
  };
154
200
 
201
+ // Container classes based on mode
202
+ const containerClasses = useMemo(() => {
203
+ const base = 'relative overflow-hidden';
204
+ switch (mode) {
205
+ case 'full':
206
+ return `${base} border border-border rounded-sm h-full ${className}`;
207
+ case 'compact':
208
+ return `${base} border border-border/50 rounded-md ${className}`;
209
+ case 'inline':
210
+ return `${base} ${className}`;
211
+ default:
212
+ return `${base} ${className}`;
213
+ }
214
+ }, [mode, className]);
215
+
216
+ // Content padding based on mode
217
+ const contentPadding = useMemo(() => {
218
+ switch (mode) {
219
+ case 'full':
220
+ return 'p-4';
221
+ case 'compact':
222
+ return 'p-3';
223
+ case 'inline':
224
+ return 'p-2';
225
+ default:
226
+ return 'p-4';
227
+ }
228
+ }, [mode]);
229
+
230
+ // Show header only in full mode or when title is provided
231
+ const showHeader = (title || showExpandControls || showActionButtons) && mode === 'full';
232
+
155
233
  return (
156
- <div className={`relative border border-border rounded-sm h-full overflow-hidden ${className}`}>
234
+ <div className={containerClasses}>
157
235
  {/* Header with title and controls */}
158
- {(title || showExpandControls || showActionButtons) && (
236
+ {showHeader && (
159
237
  <div className="p-4 border-b border-border bg-muted/50 rounded-t-sm">
160
238
  <div className="flex items-center justify-between">
161
239
  {title && (
162
240
  <h6 className="text-lg font-semibold text-foreground">{title}</h6>
163
241
  )}
164
-
242
+
165
243
  {(showExpandControls || showActionButtons) && (
166
244
  <div className="flex items-center space-x-2">
167
245
  {/* Expand/Collapse Controls */}
@@ -189,7 +267,7 @@ const JsonTreeComponent = ({ title, data, config = {}, jsonTreeProps = {} }: Jso
189
267
  )}
190
268
  </Button>
191
269
  )}
192
-
270
+
193
271
  {/* Action Buttons */}
194
272
  {showActionButtons && (
195
273
  <>
@@ -220,7 +298,7 @@ const JsonTreeComponent = ({ title, data, config = {}, jsonTreeProps = {} }: Jso
220
298
  )}
221
299
 
222
300
  {/* JSON Tree Content */}
223
- <div className="h-full overflow-auto p-4">
301
+ <div className={`overflow-auto ${contentPadding}`}>
224
302
  <JSONTree
225
303
  key={renderKey} // Force re-render when expand/collapse state changes
226
304
  data={data}
@@ -240,4 +318,4 @@ const JsonTreeComponent = ({ title, data, config = {}, jsonTreeProps = {} }: Jso
240
318
  );
241
319
  };
242
320
 
243
- export default JsonTreeComponent;
321
+ export default JsonTreeComponent;
@@ -11,7 +11,7 @@
11
11
  */
12
12
 
13
13
  import { createLazyComponent, LoadingFallback } from '../../components';
14
- import type { JsonTreeConfig } from './index';
14
+ import type { JsonTreeConfig, JsonTreeMode } from './index';
15
15
  import type { CommonExternalProps } from 'react-json-tree';
16
16
 
17
17
  // ============================================================================
@@ -21,11 +21,18 @@ import type { CommonExternalProps } from 'react-json-tree';
21
21
  export interface JsonTreeProps {
22
22
  title?: string;
23
23
  data: unknown;
24
+ /**
25
+ * Display mode:
26
+ * - "full" (default): With toolbar and border
27
+ * - "compact": No toolbar, subtle styling
28
+ * - "inline": Minimal, no border
29
+ */
30
+ mode?: JsonTreeMode;
24
31
  config?: JsonTreeConfig;
25
32
  jsonTreeProps?: Partial<CommonExternalProps>;
26
33
  }
27
34
 
28
- export type { JsonTreeConfig };
35
+ export type { JsonTreeConfig, JsonTreeMode };
29
36
 
30
37
  // ============================================================================
31
38
  // Lazy Component
@@ -35,6 +42,16 @@ export type { JsonTreeConfig };
35
42
  * LazyJsonTree - Lazy-loaded JSON visualization tree
36
43
  *
37
44
  * Automatically shows loading state while JsonTree loads (~100KB)
45
+ *
46
+ * @example
47
+ * // Full mode (with toolbar)
48
+ * <LazyJsonTree data={obj} mode="full" />
49
+ *
50
+ * // Compact mode (no toolbar)
51
+ * <LazyJsonTree data={obj} mode="compact" />
52
+ *
53
+ * // Inline mode (minimal, for embedding)
54
+ * <LazyJsonTree data={obj} mode="inline" />
38
55
  */
39
56
  export const LazyJsonTree = createLazyComponent<JsonTreeProps>(
40
57
  () => import('./index'),
@@ -1,4 +0,0 @@
1
- export { JsonTree_default as default } from './chunk-OYYCGIBF.mjs';
2
- import './chunk-CGILA3WO.mjs';
3
- //# sourceMappingURL=JsonTree-G2TPWQ4C.mjs.map
4
- //# sourceMappingURL=JsonTree-G2TPWQ4C.mjs.map
@@ -1,10 +0,0 @@
1
- 'use strict';
2
-
3
- var chunkEGYUND4E_cjs = require('./chunk-EGYUND4E.cjs');
4
- require('./chunk-WGEGR3DF.cjs');
5
-
6
-
7
-
8
- module.exports = chunkEGYUND4E_cjs.JsonTree_default;
9
- //# sourceMappingURL=JsonTree-TWXUBBIG.cjs.map
10
- //# sourceMappingURL=JsonTree-TWXUBBIG.cjs.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/tools/JsonTree/index.tsx"],"names":["__name","useState","jsxs","jsx","Button","Fragment","ChevronUp","ChevronDown","CopyButton","Download","JSONTree"],"mappings":"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","file":"chunk-EGYUND4E.cjs","sourcesContent":["'use client';\n\nimport { ChevronDown, ChevronUp, Download } from 'lucide-react';\nimport React, { useState } from 'react';\nimport { CommonExternalProps, JSONTree } from 'react-json-tree';\n\nimport { Button, CopyButton } from '@djangocfg/ui-core/components';\n\nexport type { Language } from 'prism-react-renderer';\n\nexport interface JsonTreeConfig {\n /** Maximum depth to expand automatically (default: 2) */\n maxAutoExpandDepth?: number;\n /** Maximum items in array to auto-expand (default: 10) */\n maxAutoExpandArrayItems?: number;\n /** Maximum object keys to auto-expand (default: 5) */\n maxAutoExpandObjectKeys?: number;\n /** Maximum string length before truncation (default: 200) */\n maxStringLength?: number;\n /** Collection limit for performance (default: 50) */\n collectionLimit?: number;\n /** Whether to show collection info (array length, object keys count) */\n showCollectionInfo?: boolean;\n /** Whether to show expand/collapse all buttons */\n showExpandControls?: boolean;\n /** Whether to show copy/download buttons */\n showActionButtons?: boolean;\n /** Custom CSS classes for the container */\n className?: string;\n /** Whether to preserve object key order (default: true) */\n preserveKeyOrder?: boolean;\n}\n\nexport interface JsonTreeComponentProps {\n title?: string;\n data: unknown;\n config?: JsonTreeConfig;\n /** Override for react-json-tree props */\n jsonTreeProps?: Partial<CommonExternalProps>;\n}\n\nconst JsonTreeComponent = ({ title, data, config = {}, jsonTreeProps = {} }: JsonTreeComponentProps) => {\n // State for expand/collapse all\n const [expandAll, setExpandAll] = useState<boolean | null>(null);\n const [renderKey, setRenderKey] = useState(0);\n \n // Default configuration\n const {\n maxAutoExpandDepth = 2,\n maxAutoExpandArrayItems = 10,\n maxAutoExpandObjectKeys = 5,\n maxStringLength = 200,\n collectionLimit = 50,\n showCollectionInfo = true,\n showExpandControls = true,\n showActionButtons = true,\n className = '',\n preserveKeyOrder = true,\n } = config;\n \n // JSON Tree theme optimized for dark theme\n const jsonTreeTheme = {\n scheme: 'djangocfg-dark',\n base00: 'transparent', // Background\n base01: '#1a1a1a', // Lighter background\n base02: '#2a2a2a', // Selection background\n base03: '#6b7280', // Comments, invisibles\n base04: '#9ca3af', // Dark foreground\n base05: '#e5e7eb', // Default foreground\n base06: '#f3f4f6', // Light foreground\n base07: '#ffffff', // Lightest foreground\n base08: '#ef4444', // Red - for null, undefined\n base09: '#f97316', // Orange - for numbers\n base0A: '#eab308', // Yellow - for strings\n base0B: '#22c55e', // Green - for booleans (true)\n base0C: '#06b6d4', // Cyan - for dates, regex\n base0D: '#3b82f6', // Blue - for keys\n base0E: '#a855f7', // Purple - for functions\n base0F: '#f43f5e', // Pink - for deprecations\n };\n\n // Smart expansion logic\n const shouldExpandNodeInitially = (keyPath: readonly (string | number)[], nodeData: unknown, level: number) => {\n // If user explicitly clicked \"Expand All\", expand everything\n if (expandAll === true) return true;\n\n // If user explicitly clicked \"Collapse All\", collapse everything\n if (expandAll === false) return false;\n\n // Default auto-expansion (expandAll === null)\n // Always expand up to maxAutoExpandDepth\n if (level <= maxAutoExpandDepth) return true;\n\n // For arrays, expand if they have less than maxAutoExpandArrayItems\n if (Array.isArray(nodeData) && nodeData.length <= maxAutoExpandArrayItems) return true;\n\n // For objects, expand if they have less than maxAutoExpandObjectKeys\n if (nodeData && typeof nodeData === 'object' && !Array.isArray(nodeData)) {\n const keys = Object.keys(nodeData);\n return keys.length <= maxAutoExpandObjectKeys;\n }\n\n return false;\n };\n\n // Collection info display\n const getItemString = showCollectionInfo \n ? (nodeType: string, nodeData: unknown) => {\n if (nodeType === 'Array') {\n const length = Array.isArray(nodeData) ? nodeData.length : 0;\n return length > 0 ? <span className=\"text-muted-foreground text-sm\">({length} items)</span> : null;\n }\n if (nodeType === 'Object') {\n const keys = nodeData && typeof nodeData === 'object' ? Object.keys(nodeData) : [];\n return keys.length > 0 ? <span className=\"text-muted-foreground text-sm\">({keys.length} keys)</span> : null;\n }\n return null;\n }\n : () => null;\n\n // Value processing for better display\n const postprocessValue = (value: unknown) => {\n // Truncate very long strings\n if (typeof value === 'string' && value.length > maxStringLength) {\n return value.substring(0, maxStringLength) + '... (truncated)';\n }\n return value;\n };\n\n // Custom node detection for special formatting\n const isCustomNode = (value: unknown) => {\n // Mark URLs as custom nodes for special styling\n if (typeof value === 'string' && (value.startsWith('http://') || value.startsWith('https://'))) {\n return true;\n }\n return false;\n };\n\n // JSON string for copy/download\n const jsonString = JSON.stringify(data, null, 2);\n\n // Action handlers\n const handleDownload = () => {\n const blob = new Blob([jsonString], { type: 'application/json' });\n const url = URL.createObjectURL(blob);\n const a = document.createElement('a');\n a.href = url;\n a.download = 'data.json';\n document.body.appendChild(a);\n a.click();\n document.body.removeChild(a);\n URL.revokeObjectURL(url);\n };\n\n return (\n <div className={`relative border border-border rounded-sm h-full overflow-hidden ${className}`}>\n {/* Header with title and controls */}\n {(title || showExpandControls || showActionButtons) && (\n <div className=\"p-4 border-b border-border bg-muted/50 rounded-t-sm\">\n <div className=\"flex items-center justify-between\">\n {title && (\n <h6 className=\"text-lg font-semibold text-foreground\">{title}</h6>\n )}\n \n {(showExpandControls || showActionButtons) && (\n <div className=\"flex items-center space-x-2\">\n {/* Expand/Collapse Controls */}\n {showExpandControls && (\n <Button\n variant={expandAll === true ? \"default\" : \"outline\"}\n size=\"sm\"\n onClick={() => {\n const newState = expandAll === true ? false : true;\n setExpandAll(newState);\n setRenderKey(prev => prev + 1);\n }}\n className=\"h-8 px-2\"\n >\n {expandAll === true ? (\n <>\n <ChevronUp className=\"h-3 w-3\" />\n <span className=\"ml-1 text-xs\">Collapse All</span>\n </>\n ) : (\n <>\n <ChevronDown className=\"h-3 w-3\" />\n <span className=\"ml-1 text-xs\">Expand All</span>\n </>\n )}\n </Button>\n )}\n \n {/* Action Buttons */}\n {showActionButtons && (\n <>\n <CopyButton\n value={jsonString}\n variant=\"outline\"\n size=\"sm\"\n className=\"h-8 px-2\"\n iconClassName=\"h-3 w-3\"\n >\n Copy\n </CopyButton>\n <Button\n variant=\"outline\"\n size=\"sm\"\n onClick={handleDownload}\n className=\"h-8 px-2\"\n >\n <Download className=\"h-3 w-3\" />\n <span className=\"ml-1 text-xs hidden sm:inline\">Download</span>\n </Button>\n </>\n )}\n </div>\n )}\n </div>\n </div>\n )}\n\n {/* JSON Tree Content */}\n <div className=\"h-full overflow-auto p-4\">\n <JSONTree\n key={renderKey} // Force re-render when expand/collapse state changes\n data={data}\n theme={jsonTreeTheme}\n invertTheme={false}\n hideRoot={true}\n shouldExpandNodeInitially={shouldExpandNodeInitially}\n getItemString={getItemString}\n postprocessValue={postprocessValue}\n isCustomNode={isCustomNode}\n collectionLimit={collectionLimit}\n sortObjectKeys={!preserveKeyOrder}\n {...jsonTreeProps}\n />\n </div>\n </div>\n );\n};\n\nexport default JsonTreeComponent; "]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/tools/JsonTree/index.tsx"],"names":[],"mappings":"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","file":"chunk-OYYCGIBF.mjs","sourcesContent":["'use client';\n\nimport { ChevronDown, ChevronUp, Download } from 'lucide-react';\nimport React, { useState } from 'react';\nimport { CommonExternalProps, JSONTree } from 'react-json-tree';\n\nimport { Button, CopyButton } from '@djangocfg/ui-core/components';\n\nexport type { Language } from 'prism-react-renderer';\n\nexport interface JsonTreeConfig {\n /** Maximum depth to expand automatically (default: 2) */\n maxAutoExpandDepth?: number;\n /** Maximum items in array to auto-expand (default: 10) */\n maxAutoExpandArrayItems?: number;\n /** Maximum object keys to auto-expand (default: 5) */\n maxAutoExpandObjectKeys?: number;\n /** Maximum string length before truncation (default: 200) */\n maxStringLength?: number;\n /** Collection limit for performance (default: 50) */\n collectionLimit?: number;\n /** Whether to show collection info (array length, object keys count) */\n showCollectionInfo?: boolean;\n /** Whether to show expand/collapse all buttons */\n showExpandControls?: boolean;\n /** Whether to show copy/download buttons */\n showActionButtons?: boolean;\n /** Custom CSS classes for the container */\n className?: string;\n /** Whether to preserve object key order (default: true) */\n preserveKeyOrder?: boolean;\n}\n\nexport interface JsonTreeComponentProps {\n title?: string;\n data: unknown;\n config?: JsonTreeConfig;\n /** Override for react-json-tree props */\n jsonTreeProps?: Partial<CommonExternalProps>;\n}\n\nconst JsonTreeComponent = ({ title, data, config = {}, jsonTreeProps = {} }: JsonTreeComponentProps) => {\n // State for expand/collapse all\n const [expandAll, setExpandAll] = useState<boolean | null>(null);\n const [renderKey, setRenderKey] = useState(0);\n \n // Default configuration\n const {\n maxAutoExpandDepth = 2,\n maxAutoExpandArrayItems = 10,\n maxAutoExpandObjectKeys = 5,\n maxStringLength = 200,\n collectionLimit = 50,\n showCollectionInfo = true,\n showExpandControls = true,\n showActionButtons = true,\n className = '',\n preserveKeyOrder = true,\n } = config;\n \n // JSON Tree theme optimized for dark theme\n const jsonTreeTheme = {\n scheme: 'djangocfg-dark',\n base00: 'transparent', // Background\n base01: '#1a1a1a', // Lighter background\n base02: '#2a2a2a', // Selection background\n base03: '#6b7280', // Comments, invisibles\n base04: '#9ca3af', // Dark foreground\n base05: '#e5e7eb', // Default foreground\n base06: '#f3f4f6', // Light foreground\n base07: '#ffffff', // Lightest foreground\n base08: '#ef4444', // Red - for null, undefined\n base09: '#f97316', // Orange - for numbers\n base0A: '#eab308', // Yellow - for strings\n base0B: '#22c55e', // Green - for booleans (true)\n base0C: '#06b6d4', // Cyan - for dates, regex\n base0D: '#3b82f6', // Blue - for keys\n base0E: '#a855f7', // Purple - for functions\n base0F: '#f43f5e', // Pink - for deprecations\n };\n\n // Smart expansion logic\n const shouldExpandNodeInitially = (keyPath: readonly (string | number)[], nodeData: unknown, level: number) => {\n // If user explicitly clicked \"Expand All\", expand everything\n if (expandAll === true) return true;\n\n // If user explicitly clicked \"Collapse All\", collapse everything\n if (expandAll === false) return false;\n\n // Default auto-expansion (expandAll === null)\n // Always expand up to maxAutoExpandDepth\n if (level <= maxAutoExpandDepth) return true;\n\n // For arrays, expand if they have less than maxAutoExpandArrayItems\n if (Array.isArray(nodeData) && nodeData.length <= maxAutoExpandArrayItems) return true;\n\n // For objects, expand if they have less than maxAutoExpandObjectKeys\n if (nodeData && typeof nodeData === 'object' && !Array.isArray(nodeData)) {\n const keys = Object.keys(nodeData);\n return keys.length <= maxAutoExpandObjectKeys;\n }\n\n return false;\n };\n\n // Collection info display\n const getItemString = showCollectionInfo \n ? (nodeType: string, nodeData: unknown) => {\n if (nodeType === 'Array') {\n const length = Array.isArray(nodeData) ? nodeData.length : 0;\n return length > 0 ? <span className=\"text-muted-foreground text-sm\">({length} items)</span> : null;\n }\n if (nodeType === 'Object') {\n const keys = nodeData && typeof nodeData === 'object' ? Object.keys(nodeData) : [];\n return keys.length > 0 ? <span className=\"text-muted-foreground text-sm\">({keys.length} keys)</span> : null;\n }\n return null;\n }\n : () => null;\n\n // Value processing for better display\n const postprocessValue = (value: unknown) => {\n // Truncate very long strings\n if (typeof value === 'string' && value.length > maxStringLength) {\n return value.substring(0, maxStringLength) + '... (truncated)';\n }\n return value;\n };\n\n // Custom node detection for special formatting\n const isCustomNode = (value: unknown) => {\n // Mark URLs as custom nodes for special styling\n if (typeof value === 'string' && (value.startsWith('http://') || value.startsWith('https://'))) {\n return true;\n }\n return false;\n };\n\n // JSON string for copy/download\n const jsonString = JSON.stringify(data, null, 2);\n\n // Action handlers\n const handleDownload = () => {\n const blob = new Blob([jsonString], { type: 'application/json' });\n const url = URL.createObjectURL(blob);\n const a = document.createElement('a');\n a.href = url;\n a.download = 'data.json';\n document.body.appendChild(a);\n a.click();\n document.body.removeChild(a);\n URL.revokeObjectURL(url);\n };\n\n return (\n <div className={`relative border border-border rounded-sm h-full overflow-hidden ${className}`}>\n {/* Header with title and controls */}\n {(title || showExpandControls || showActionButtons) && (\n <div className=\"p-4 border-b border-border bg-muted/50 rounded-t-sm\">\n <div className=\"flex items-center justify-between\">\n {title && (\n <h6 className=\"text-lg font-semibold text-foreground\">{title}</h6>\n )}\n \n {(showExpandControls || showActionButtons) && (\n <div className=\"flex items-center space-x-2\">\n {/* Expand/Collapse Controls */}\n {showExpandControls && (\n <Button\n variant={expandAll === true ? \"default\" : \"outline\"}\n size=\"sm\"\n onClick={() => {\n const newState = expandAll === true ? false : true;\n setExpandAll(newState);\n setRenderKey(prev => prev + 1);\n }}\n className=\"h-8 px-2\"\n >\n {expandAll === true ? (\n <>\n <ChevronUp className=\"h-3 w-3\" />\n <span className=\"ml-1 text-xs\">Collapse All</span>\n </>\n ) : (\n <>\n <ChevronDown className=\"h-3 w-3\" />\n <span className=\"ml-1 text-xs\">Expand All</span>\n </>\n )}\n </Button>\n )}\n \n {/* Action Buttons */}\n {showActionButtons && (\n <>\n <CopyButton\n value={jsonString}\n variant=\"outline\"\n size=\"sm\"\n className=\"h-8 px-2\"\n iconClassName=\"h-3 w-3\"\n >\n Copy\n </CopyButton>\n <Button\n variant=\"outline\"\n size=\"sm\"\n onClick={handleDownload}\n className=\"h-8 px-2\"\n >\n <Download className=\"h-3 w-3\" />\n <span className=\"ml-1 text-xs hidden sm:inline\">Download</span>\n </Button>\n </>\n )}\n </div>\n )}\n </div>\n </div>\n )}\n\n {/* JSON Tree Content */}\n <div className=\"h-full overflow-auto p-4\">\n <JSONTree\n key={renderKey} // Force re-render when expand/collapse state changes\n data={data}\n theme={jsonTreeTheme}\n invertTheme={false}\n hideRoot={true}\n shouldExpandNodeInitially={shouldExpandNodeInitially}\n getItemString={getItemString}\n postprocessValue={postprocessValue}\n isCustomNode={isCustomNode}\n collectionLimit={collectionLimit}\n sortObjectKeys={!preserveKeyOrder}\n {...jsonTreeProps}\n />\n </div>\n </div>\n );\n};\n\nexport default JsonTreeComponent; "]}