Skip to content

Commit 10440d2

Browse files
committed
Update version to 1.0.4, enhance README with new UI visibility controls, and improve JSON viewer component with key editing and customizable UI options.
1 parent 20d7e66 commit 10440d2

File tree

17 files changed

+1171
-712
lines changed

17 files changed

+1171
-712
lines changed

README.md

Lines changed: 162 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -9,15 +9,17 @@ A modern, sleek Vue 3 component for viewing, editing, and manipulating JSON data
99
- 🌳 **Tree Mode**: Hierarchical display with expandable/collapsible nodes
1010
- 📝 **Text Mode**: Raw JSON text display with syntax highlighting
1111
- ✏️ **Inline Editing**: Edit values directly in the tree view
12+
- 🔑 **Key Editing**: Rename object keys by double-clicking on them
1213
-**Add/Remove Nodes**: Add new key-value pairs or remove existing ones
1314
- 🔍 **Search & Filter**: Search across all JSON keys and values
14-
- 📋 **Copy to Clipboard**: Easy copying of JSON content
15+
- 📋 **Copy to Clipboard**: Easy copying of JSON content with visual feedback
1516
- 💾 **Download JSON**: Save current JSON to file
16-
- 🎨 **Dark/Light Theme**: Support for both themes
17+
- 🎨 **Dark/Light Theme**: Support for both themes with dynamic icons
1718
- 📱 **Responsive Design**: Works on desktop and mobile devices
1819
- ⌨️ **Keyboard Navigation**: Full keyboard support
1920
-**Accessibility**: Screen reader support with proper ARIA labels
2021
- 🎯 **Icon-Only Mode**: Option to hide button text labels for compact interface
22+
- 🎛️ **Customizable UI**: Hide specific buttons, sections, or entire header/footer
2123
- 🚀 **Dual Build System**: Library build for npm + Demo build for preview
2224

2325
## 🚀 Installation
@@ -44,16 +46,16 @@ yarn add @ctechhindi/vue3-json-viewer
4446

4547
```typescript
4648
// Option 1: Direct CSS import (recommended)
47-
import '@ctechhindi/vue3-json-viewer/dist/index.css'
49+
import "@ctechhindi/vue3-json-viewer/dist/index.css";
4850

4951
// Option 2: Using the styles export
50-
import '@ctechhindi/vue3-json-viewer/styles'
52+
import "@ctechhindi/vue3-json-viewer/styles";
5153

5254
// Option 3: Using the css export
53-
import '@ctechhindi/vue3-json-viewer/css'
55+
import "@ctechhindi/vue3-json-viewer/css";
5456

5557
// Option 4: In your main.ts or main.js
56-
import '@ctechhindi/vue3-json-viewer/dist/index.css'
58+
import "@ctechhindi/vue3-json-viewer/dist/index.css";
5759
```
5860

5961
### Basic Usage
@@ -155,6 +157,47 @@ const handleEditCancel = () => {
155157
</script>
156158
```
157159

160+
### Customizing UI Elements
161+
162+
You can hide specific UI elements using the visibility props:
163+
164+
```vue
165+
<template>
166+
<JsonViewer
167+
v-model:data="jsonData"
168+
:hide-header="false"
169+
:hide-footer="true"
170+
:hide-mode-switcher="false"
171+
:hide-tree-controls="false"
172+
:hide-edit-controls="false"
173+
:hide-search-button="true"
174+
:hide-copy-button="false"
175+
:hide-download-button="true"
176+
:hide-theme-button="false"
177+
/>
178+
</template>
179+
```
180+
181+
### Minimal Configuration
182+
183+
For a minimal, read-only viewer:
184+
185+
```vue
186+
<template>
187+
<JsonViewer
188+
v-model:data="jsonData"
189+
:editable="false"
190+
:hide-header="false"
191+
:hide-footer="true"
192+
:hide-edit-controls="true"
193+
:hide-search-button="true"
194+
:hide-copy-button="false"
195+
:hide-download-button="true"
196+
:hide-theme-button="false"
197+
/>
198+
</template>
199+
```
200+
158201
## 📋 Props
159202

160203
| Prop | Type | Default | Description |
@@ -167,17 +210,33 @@ const handleEditCancel = () => {
167210
| `maxDepth` | `number` | `3` | Maximum depth to expand by default |
168211
| `hideActionText` | `boolean` | `false` | Hide button text labels (icons only) |
169212

213+
### UI Visibility Props
214+
215+
| Prop | Type | Default | Description |
216+
| -------------------- | --------- | ------- | ---------------------------------------- |
217+
| `hideHeader` | `boolean` | `false` | Hide the entire menu bar (header) |
218+
| `hideFooter` | `boolean` | `false` | Hide the entire footer |
219+
| `hideModeSwitcher` | `boolean` | `false` | Hide the Tree/Text mode switcher |
220+
| `hideTreeControls` | `boolean` | `false` | Hide the Expand All/Collapse All buttons |
221+
| `hideEditControls` | `boolean` | `false` | Hide the Edit/Save/Cancel buttons |
222+
| `hideSearchButton` | `boolean` | `false` | Hide the Search button |
223+
| `hideCopyButton` | `boolean` | `false` | Hide the Copy button |
224+
| `hideDownloadButton` | `boolean` | `false` | Hide the Download button |
225+
| `hideThemeButton` | `boolean` | `false` | Hide the Theme toggle button |
226+
170227
## 🎭 Events
171228

172-
| Event | Payload | Description |
173-
| --------------- | ---------------- | -------------------- |
174-
| `update:data` | `newData: any` | Data changed event |
175-
| `node-click` | `node: JsonNode` | Node clicked event |
176-
| `node-expand` | `node: JsonNode` | Node expanded event |
177-
| `node-collapse` | `node: JsonNode` | Node collapsed event |
178-
| `edit-start` | - | Edit mode started |
179-
| `edit-save` | `data: any` | Changes saved |
180-
| `edit-cancel` | - | Edit mode cancelled |
229+
| Event | Payload | Description |
230+
| --------------- | ----------------------------------------------------------- | -------------------- |
231+
| `update:data` | `newData: any` | Data changed event |
232+
| `node-click` | `node: JsonNode` | Node clicked event |
233+
| `node-expand` | `node: JsonNode` | Node expanded event |
234+
| `node-collapse` | `node: JsonNode` | Node collapsed event |
235+
| `edit-start` | - | Edit mode started |
236+
| `edit-save` | `data: any` | Changes saved |
237+
| `edit-cancel` | - | Edit mode cancelled |
238+
| `key-change` | `event: { node: JsonNode, oldKey: string, newKey: string }` | Key name changed |
239+
| `theme-change` | `theme: 'light' \| 'dark'` | Theme changed |
181240

182241
## 🏗️ Data Structure
183242

@@ -193,9 +252,30 @@ interface JsonNode {
193252
}
194253
```
195254

196-
## 🎨 Styling
255+
## 🎨 Styling & Theming
256+
257+
The component uses **component-scoped CSS custom properties** for theming, ensuring that theme changes only affect the JsonViewer component and do not interfere with your parent application's styling.
258+
259+
### Component-Only Theming
260+
261+
The theme is completely self-contained within the component:
262+
263+
**Dynamic Theme Icons**: The theme button automatically shows:
264+
- 🌙 **Moon icon** when in light theme (click to switch to dark)
265+
- ☀️ **Sun icon** when in dark theme (click to switch to light)
266+
267+
```vue
268+
<template>
269+
<JsonViewer
270+
:theme="'dark'" <!-- Theme only affects this component -->
271+
v-model:data="jsonData"
272+
/>
273+
</template>
274+
```
275+
276+
### CSS Custom Properties
197277

198-
The component uses CSS custom properties for theming. You can customize the appearance by overriding these variables:
278+
You can customize the appearance by overriding these CSS variables within the component scope:
199279

200280
```css
201281
.json-viewer {
@@ -213,6 +293,49 @@ The component uses CSS custom properties for theming. You can customize the appe
213293
}
214294
```
215295

296+
### Using in Other Projects
297+
298+
When you use this component in other projects, the theme will **only affect the component itself**:
299+
300+
```vue
301+
<template>
302+
<div>
303+
<!-- This header won't be affected by theme changes -->
304+
<header class="my-app-header">
305+
<h1>My Application</h1>
306+
</header>
307+
308+
<!-- Only this component will change theme -->
309+
<JsonViewer
310+
:theme="componentTheme"
311+
v-model:data="jsonData"
312+
@theme-change="handleThemeChange"
313+
/>
314+
315+
<!-- This footer also won't be affected -->
316+
<footer class="my-app-footer">
317+
<p>My Application Footer</p>
318+
</footer>
319+
</div>
320+
</template>
321+
322+
<script setup>
323+
const componentTheme = ref('light');
324+
325+
const handleThemeChange = (newTheme) => {
326+
componentTheme.value = newTheme;
327+
// Theme only affects the JsonViewer component
328+
// Your app's global styling remains unchanged
329+
};
330+
</script>
331+
```
332+
333+
**Benefits:**
334+
-**No Global Side Effects** - Theme changes only affect the component
335+
-**Better Encapsulation** - Component manages its own appearance
336+
-**Easier Integration** - No conflicts with parent project's theme system
337+
-**Reusable** - Can be used in any project without affecting global styles
338+
216339
## 🛠️ Development
217340

218341
### Setup
@@ -308,6 +431,28 @@ This project is licensed under the MIT License - see the [LICENSE](LICENSE) file
308431
- Font families: [Inter](https://rsms.me/inter/) and [Fira Code](https://github.com/tonsky/FiraCode)
309432
- Built with [Vue 3](https://vuejs.org/) and [Vite](https://vitejs.dev/)
310433

434+
## 🔧 Troubleshooting
435+
436+
### Theme Not Working?
437+
438+
**Problem**: Theme changes not visible in your project
439+
440+
**Solution**: The component now uses component-only theming. Make sure you're passing the theme prop correctly:
441+
442+
```vue
443+
<!-- ✅ Correct - Theme will work -->
444+
<JsonViewer :theme="'dark'" v-model:data="jsonData" />
445+
446+
<!-- ❌ Incorrect - No theme prop -->
447+
<JsonViewer v-model:data="jsonData" />
448+
```
449+
450+
### Theme Affecting Other Elements?
451+
452+
**Problem**: Theme changes affecting your entire application
453+
454+
**Solution**: This shouldn't happen anymore! The component is now completely self-contained. If you're still experiencing issues, make sure you're using the latest version.
455+
311456
## 📞 Support
312457

313458
If you have any questions or need help, please:

dist/components/JsonNode.vue.d.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,11 @@ declare const _default: import("vue").DefineComponent<import("vue").ExtractPropT
2323
node: JsonNodeType;
2424
value: any;
2525
}) => void;
26+
"key-change": (event: {
27+
node: JsonNodeType;
28+
oldKey: string;
29+
newKey: string;
30+
}) => void;
2631
"node-delete": (node: JsonNodeType) => void;
2732
"node-add": (event: {
2833
parent: JsonNodeType;
@@ -40,6 +45,11 @@ declare const _default: import("vue").DefineComponent<import("vue").ExtractPropT
4045
node: JsonNodeType;
4146
value: any;
4247
}) => any) | undefined;
48+
"onKey-change"?: ((event: {
49+
node: JsonNodeType;
50+
oldKey: string;
51+
newKey: string;
52+
}) => any) | undefined;
4353
"onNode-delete"?: ((node: JsonNodeType) => any) | undefined;
4454
"onNode-add"?: ((event: {
4555
parent: JsonNodeType;

dist/components/JsonViewer.vue.d.ts

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,15 @@ export interface Props {
1515
showLineNumbers?: boolean;
1616
maxDepth?: number;
1717
hideActionText?: boolean;
18+
hideHeader?: boolean;
19+
hideFooter?: boolean;
20+
hideModeSwitcher?: boolean;
21+
hideTreeControls?: boolean;
22+
hideEditControls?: boolean;
23+
hideSearchButton?: boolean;
24+
hideCopyButton?: boolean;
25+
hideDownloadButton?: boolean;
26+
hideThemeButton?: boolean;
1827
}
1928
declare const _default: import("vue").DefineComponent<import("vue").ExtractPropTypes<__VLS_WithDefaults<__VLS_TypePropsToRuntimeProps<Props>, {
2029
editable: boolean;
@@ -23,10 +32,24 @@ declare const _default: import("vue").DefineComponent<import("vue").ExtractPropT
2332
showLineNumbers: boolean;
2433
maxDepth: number;
2534
hideActionText: boolean;
35+
hideHeader: boolean;
36+
hideFooter: boolean;
37+
hideModeSwitcher: boolean;
38+
hideTreeControls: boolean;
39+
hideEditControls: boolean;
40+
hideSearchButton: boolean;
41+
hideCopyButton: boolean;
42+
hideDownloadButton: boolean;
43+
hideThemeButton: boolean;
2644
}>>, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
2745
"node-click": (node: JsonNodeType) => void;
2846
"node-expand": (node: JsonNodeType) => void;
2947
"node-collapse": (node: JsonNodeType) => void;
48+
"key-change": (event: {
49+
node: JsonNodeType;
50+
oldKey: string;
51+
newKey: string;
52+
}) => void;
3053
"update:data": (newData: any) => void;
3154
"edit-start": () => void;
3255
"edit-save": (data: any) => void;
@@ -39,10 +62,24 @@ declare const _default: import("vue").DefineComponent<import("vue").ExtractPropT
3962
showLineNumbers: boolean;
4063
maxDepth: number;
4164
hideActionText: boolean;
65+
hideHeader: boolean;
66+
hideFooter: boolean;
67+
hideModeSwitcher: boolean;
68+
hideTreeControls: boolean;
69+
hideEditControls: boolean;
70+
hideSearchButton: boolean;
71+
hideCopyButton: boolean;
72+
hideDownloadButton: boolean;
73+
hideThemeButton: boolean;
4274
}>>> & Readonly<{
4375
"onNode-click"?: ((node: JsonNodeType) => any) | undefined;
4476
"onNode-expand"?: ((node: JsonNodeType) => any) | undefined;
4577
"onNode-collapse"?: ((node: JsonNodeType) => any) | undefined;
78+
"onKey-change"?: ((event: {
79+
node: JsonNodeType;
80+
oldKey: string;
81+
newKey: string;
82+
}) => any) | undefined;
4683
"onUpdate:data"?: ((newData: any) => any) | undefined;
4784
"onEdit-start"?: (() => any) | undefined;
4885
"onEdit-save"?: ((data: any) => any) | undefined;
@@ -55,6 +92,15 @@ declare const _default: import("vue").DefineComponent<import("vue").ExtractPropT
5592
showLineNumbers: boolean;
5693
maxDepth: number;
5794
hideActionText: boolean;
95+
hideHeader: boolean;
96+
hideFooter: boolean;
97+
hideModeSwitcher: boolean;
98+
hideTreeControls: boolean;
99+
hideEditControls: boolean;
100+
hideSearchButton: boolean;
101+
hideCopyButton: boolean;
102+
hideDownloadButton: boolean;
103+
hideThemeButton: boolean;
58104
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
59105
export default _default;
60106
type __VLS_NonUndefinedable<T> = T extends undefined ? never : T;
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
declare const _default: import("vue").DefineComponent<{}, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
2+
export default _default;
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
declare const _default: import("vue").DefineComponent<{}, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
2+
export default _default;

dist/components/icons/index.d.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,3 +16,5 @@ export { default as PlusIcon } from './PlusIcon.vue';
1616
export { default as TrashIcon } from './TrashIcon.vue';
1717
export { default as CheckIcon } from './CheckIcon.vue';
1818
export { default as XIcon } from './XIcon.vue';
19+
export { default as MoonIcon } from './MoonIcon.vue';
20+
export { default as SunIcon } from './SunIcon.vue';

0 commit comments

Comments
 (0)