Skip to content

Commit ca1241e

Browse files
committed
feat: improve empty objects and empty arrays
1 parent a47e4e9 commit ca1241e

File tree

4 files changed

+96
-1
lines changed

4 files changed

+96
-1
lines changed

src/DataRenderer.test.tsx

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,12 @@ const testButtonsExpanded = () => {
4747
return buttons;
4848
};
4949

50+
const testButtonsIfEmpty = () => {
51+
expect(() => {
52+
screen.getAllByRole('button', { hidden: true });
53+
}).toThrow();
54+
}
55+
5056
const testClickableNodeCollapsed = () => {
5157
const buttons = screen.getAllByRole('button', { hidden: true });
5258
expect(buttons.length).toBe(4);
@@ -143,6 +149,52 @@ describe('DataRender', () => {
143149
expect(screen.getByText(/empty key/)).toBeInTheDocument();
144150
});
145151

152+
it('should render empty objects', () => {
153+
render(<DataRender {...commonProps} value={{}} />);
154+
expect(screen.getByText('{')).toBeInTheDocument();
155+
expect(screen.getByText('}')).toBeInTheDocument();
156+
});
157+
158+
it('should render nested empty objects', () => {
159+
render(<DataRender {...commonProps} value={{ nested: [] }} />);
160+
expect(screen.getByText('nested:')).toBeInTheDocument();
161+
expect(screen.getByText('{')).toBeInTheDocument();
162+
expect(screen.getByText('}')).toBeInTheDocument();
163+
});
164+
165+
it('should not expand empty objects', () => {
166+
render(<DataRender {...commonProps} value={{}} shouldExpandNode={allExpanded} />);
167+
testButtonsIfEmpty()
168+
});
169+
170+
it('should not collapse empty objects', () => {
171+
render(<DataRender {...commonProps} value={{}} shouldExpandNode={collapseAll} />);
172+
testButtonsIfEmpty()
173+
});
174+
175+
it('should render empty arrays', () => {
176+
render(<DataRender {...commonProps} value={[]} />);
177+
expect(screen.getByText('[')).toBeInTheDocument();
178+
expect(screen.getByText(']')).toBeInTheDocument();
179+
});
180+
181+
it('should render nested empty arrays', () => {
182+
render(<DataRender {...commonProps} value={{ nested: [] }} />);
183+
expect(screen.getByText('nested:')).toBeInTheDocument();
184+
expect(screen.getByText('[')).toBeInTheDocument();
185+
expect(screen.getByText(']')).toBeInTheDocument();
186+
});
187+
188+
it('should not expand empty arrays', () => {
189+
render(<DataRender {...commonProps} value={[]} shouldExpandNode={allExpanded} />);
190+
testButtonsIfEmpty()
191+
});
192+
193+
it('should not collapse empty arrays', () => {
194+
render(<DataRender {...commonProps} value={[]} shouldExpandNode={collapseAll} />);
195+
testButtonsIfEmpty()
196+
});
197+
146198
it('should render arrays', () => {
147199
render(<DataRender {...commonProps} value={[1, 2, 3]} />);
148200
expect(screen.getByText('1')).toBeInTheDocument();

src/DataRenderer.tsx

Lines changed: 38 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ export interface JsonRenderProps<T> {
3131
}
3232

3333
export interface ExpandableRenderProps {
34-
field?: string;
34+
field: string | undefined;
3535
value: Array<any> | object;
3636
data: Array<[string | undefined, any]>;
3737
openBracket: string;
@@ -144,6 +144,25 @@ function ExpandableObject({
144144
);
145145
}
146146

147+
export interface EmptyRenderProps {
148+
field: string | undefined;
149+
openBracket: string;
150+
closeBracket: string;
151+
style: StyleProps;
152+
}
153+
154+
function EmptyObject({ field, openBracket, closeBracket, style }: EmptyRenderProps) {
155+
return (
156+
<div className={style.basicChildStyle} role='listitem'>
157+
{field && (
158+
<span className={style.label}>{field}:</span>
159+
)}
160+
<span className={style.punctuation}>{openBracket}</span>
161+
<span className={style.punctuation}>{closeBracket}</span>
162+
</div>
163+
);
164+
}
165+
147166
function JsonObject({
148167
field,
149168
value,
@@ -153,6 +172,15 @@ function JsonObject({
153172
clickToExpandNode,
154173
level
155174
}: JsonRenderProps<Object>) {
175+
if (Object.keys(value).length === 0) {
176+
return EmptyObject({
177+
field,
178+
openBracket: '{',
179+
closeBracket: '}',
180+
style
181+
});
182+
}
183+
156184
return ExpandableObject({
157185
field,
158186
value,
@@ -176,6 +204,15 @@ function JsonArray({
176204
shouldExpandNode,
177205
clickToExpandNode
178206
}: JsonRenderProps<Array<any>>) {
207+
if (value.length === 0) {
208+
return EmptyObject({
209+
field,
210+
openBracket: '[',
211+
closeBracket: ']',
212+
style
213+
});
214+
}
215+
179216
return ExpandableObject({
180217
field,
181218
value,

src/stories/JsonView.stories.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,9 @@ const jsonData = {
5656
'date property': new Date(0),
5757
'boolean property': true,
5858
'null property': null,
59+
'empty array': [],
5960
'array propery': [1, 2, 3, 4, 5],
61+
'empty object': {},
6062
'nested object': {
6163
first: true,
6264
second: 'another value',

src/styles.module.css

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,10 @@
1414
font-weight: bold;
1515
}
1616

17+
.punctuation-base + .punctuation-base {
18+
margin-left: -5px;
19+
}
20+
1721
.pointer {
1822
cursor: pointer;
1923
}

0 commit comments

Comments
 (0)