Skip to content

Commit

Permalink
issues#11 - adds ability to choose expand/collapse icons
Browse files Browse the repository at this point in the history
  • Loading branch information
AnyRoad committed Sep 3, 2023
1 parent 62d21f2 commit f2b78be
Show file tree
Hide file tree
Showing 7 changed files with 155 additions and 170 deletions.
8 changes: 4 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -53,12 +53,12 @@
"@storybook/builder-webpack4": "^6.5.12",
"@storybook/manager-webpack4": "^6.5.12",
"@storybook/react": "^6.5.12",
"@storybook/testing-library": "^0.0.13",
"@storybook/testing-library": "0.2.0",
"@storybook/theming": "^6.5.12",
"@testing-library/jest-dom": "5.16.5",
"@testing-library/react": "13.4.0",
"@testing-library/jest-dom": "6.1.2",
"@testing-library/react": "14.0.0",
"@testing-library/user-event": "14.4.3",
"@types/jest": "29.1.2",
"@types/jest": "29.5.4",
"@types/node": "18.8.3",
"@types/react": "18.0.21",
"@types/react-dom": "18.0.6",
Expand Down
77 changes: 51 additions & 26 deletions src/DataRenderer.test.tsx
Original file line number Diff line number Diff line change
@@ -1,16 +1,15 @@
import * as React from 'react';
import DataRender, { JsonRenderProps } from './DataRenderer';
import { allExpanded, collapseAllNested } from './index';
import { allExpanded, collapseAllNested, defaultStyles } from './index';
import { render, screen, fireEvent } from '@testing-library/react';
import '@testing-library/jest-dom/extend-expect';
import '@testing-library/jest-dom';

const commonProps: JsonRenderProps<any> = {
lastElement: false,
level: 0,
style: {
container: '',
basicChildStyle: '',
expander: '',
label: '',
nullValue: '',
undefinedValue: '',
Expand All @@ -19,7 +18,9 @@ const commonProps: JsonRenderProps<any> = {
booleanValue: '',
otherValue: '',
punctuation: '',
pointer: ''
expandIcon: defaultStyles.expandIcon,
collapseIcon: defaultStyles.collapseIcon,
collapsedContent: defaultStyles.collapsedContent
},
shouldInitiallyExpand: allExpanded,
value: undefined,
Expand Down Expand Up @@ -178,39 +179,48 @@ describe('DataRender', () => {
it('should collapse ojbects', () => {
render(<DataRender {...commonProps} value={{ test: true }} />);
expect(screen.getByText(/test/)).toBeInTheDocument();
fireEvent.click(screen.getByText('\u25BE'));
fireEvent.click(screen.getByRole('button'));
expect(screen.queryByText(/test/)).not.toBeInTheDocument();
fireEvent.click(screen.getByText('\u25B8'));
const buttons = screen.getAllByRole('button');
expect(buttons[0]).toHaveClass('expand-icon-light');
expect(buttons[1]).toHaveClass('collapsed-content-light');
fireEvent.click(buttons[0]);
expect(screen.getByText(/test/)).toBeInTheDocument();
});

it('should collapse arrays', () => {
render(<DataRender {...commonProps} value={[1, 2, 3]} />);
expect(screen.getByText('1')).toBeInTheDocument();
fireEvent.click(screen.getByText('\u25BE'));
fireEvent.click(screen.getByRole('button'));
expect(screen.queryByText('1')).not.toBeInTheDocument();
fireEvent.click(screen.getByText('\u25B8'));
const buttons = screen.getAllByRole('button');
expect(buttons[0]).toHaveClass('expand-icon-light');
expect(buttons[1]).toHaveClass('collapsed-content-light');
fireEvent.click(buttons[0]);
expect(screen.getByText('1')).toBeInTheDocument();
});

it('should expand objects by clicking on', () => {
render(
<DataRender {...commonProps} value={{ test: true }} shouldInitiallyExpand={collapseAll} />
);
expect(screen.getByText(/.../)).toBeInTheDocument();
expect(screen.queryByText(/test/)).not.toBeInTheDocument();
fireEvent.click(screen.getByText('...'));
const buttons = screen.getAllByRole('button');
expect(buttons[0]).toHaveClass('expand-icon-light');
expect(buttons[1]).toHaveClass('collapsed-content-light');
fireEvent.keyDown(buttons[0], { key: ' ', code: 'Space' });
expect(screen.getByText(/test/)).toBeInTheDocument();
});

it('should expand objects by pressing Spacebar on', () => {
render(
<DataRender {...commonProps} value={{ test: true }} shouldInitiallyExpand={collapseAll} />
);
expect(screen.getByText(/.../)).toBeInTheDocument();
expect(screen.queryByText(/test/)).not.toBeInTheDocument();

fireEvent.keyDown(screen.getByText('...'), { key: ' ', code: 'Space' });
const buttons = screen.getAllByRole('button');
expect(buttons[0]).toHaveClass('expand-icon-light');
expect(buttons[1]).toHaveClass('collapsed-content-light');
fireEvent.keyDown(buttons[1], { key: ' ', code: 'Space' });

expect(screen.getByText(/test/)).toBeInTheDocument();
});
Expand All @@ -219,23 +229,30 @@ describe('DataRender', () => {
render(
<DataRender {...commonProps} value={{ test: true }} shouldInitiallyExpand={collapseAll} />
);
expect(screen.getByText(/.../)).toBeInTheDocument();
expect(screen.queryByText(/test/)).not.toBeInTheDocument();

fireEvent.keyDown(screen.getByText('...'), { key: 'Enter', code: 'Enter' });

expect(screen.getByText(/.../)).toBeInTheDocument();
let buttons = screen.getAllByRole('button');
expect(buttons[0]).toHaveClass('expand-icon-light');
expect(buttons[1]).toHaveClass('collapsed-content-light');
fireEvent.keyDown(buttons[1], { key: 'Enter', code: 'Enter' });
buttons = screen.getAllByRole('button');
expect(buttons[0]).toHaveClass('expand-icon-light');
expect(buttons[1]).toHaveClass('collapsed-content-light');
expect(screen.queryByText(/test/)).not.toBeInTheDocument();
});

it('should expand arrays by clicking on', () => {
render(
<DataRender {...commonProps} value={['test', 'array']} shouldInitiallyExpand={collapseAll} />
);
expect(screen.getByText(/.../)).toBeInTheDocument();
let buttons = screen.getAllByRole('button');
expect(buttons[0]).toHaveClass('expand-icon-light');
expect(buttons[1]).toHaveClass('collapsed-content-light');
expect(screen.queryByText(/test/)).not.toBeInTheDocument();
expect(screen.queryByText(/array/)).not.toBeInTheDocument();
fireEvent.click(screen.getByText('...'));
fireEvent.click(buttons[0]);
buttons = screen.getAllByRole('button');
expect(buttons.length).toBe(1);
expect(buttons[0]).toHaveClass('collapse-icon-light');
expect(screen.getByText(/test/)).toBeInTheDocument();
expect(screen.getByText(/array/)).toBeInTheDocument();
});
Expand All @@ -244,12 +261,16 @@ describe('DataRender', () => {
render(
<DataRender {...commonProps} value={['test', 'array']} shouldInitiallyExpand={collapseAll} />
);
expect(screen.getByText(/.../)).toBeInTheDocument();
let buttons = screen.getAllByRole('button');
expect(buttons[0]).toHaveClass('expand-icon-light');
expect(buttons[1]).toHaveClass('collapsed-content-light');
expect(screen.queryByText(/test/)).not.toBeInTheDocument();
expect(screen.queryByText(/array/)).not.toBeInTheDocument();

fireEvent.keyDown(screen.getByText('...'), { key: ' ', code: 'Space' });

fireEvent.keyDown(buttons[1], { key: ' ', code: 'Space' });
buttons = screen.getAllByRole('button');
expect(buttons.length).toBe(1);
expect(buttons[0]).toHaveClass('collapse-icon-light');
expect(screen.getByText(/test/)).toBeInTheDocument();
expect(screen.getByText(/array/)).toBeInTheDocument();
});
Expand All @@ -258,13 +279,17 @@ describe('DataRender', () => {
render(
<DataRender {...commonProps} value={['test', 'array']} shouldInitiallyExpand={collapseAll} />
);
expect(screen.getByText(/.../)).toBeInTheDocument();
let buttons = screen.getAllByRole('button');
expect(buttons[0]).toHaveClass('expand-icon-light');
expect(buttons[1]).toHaveClass('collapsed-content-light');
expect(screen.queryByText(/test/)).not.toBeInTheDocument();
expect(screen.queryByText(/array/)).not.toBeInTheDocument();

fireEvent.keyDown(screen.getByText('...'), { key: 'Enter', code: 'Enter' });
fireEvent.keyDown(buttons[1], { key: 'Enter', code: 'Enter' });
buttons = screen.getAllByRole('button');
expect(buttons[0]).toHaveClass('expand-icon-light');
expect(buttons[1]).toHaveClass('collapsed-content-light');

expect(screen.getByText(/.../)).toBeInTheDocument();
expect(screen.queryByText(/test/)).not.toBeInTheDocument();
expect(screen.queryByText(/array/)).not.toBeInTheDocument();
});
Expand Down
26 changes: 8 additions & 18 deletions src/DataRenderer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,9 @@ import * as React from 'react';
import * as DataTypeDetection from './DataTypeDetection';
import { useBool } from './hooks';

const expandedIcon = '\u25BE';
const collapsedIcon = '\u25B8';

export interface StyleProps {
container: string;
basicChildStyle: string;
expander: string;
label: string;
nullValue: string;
undefinedValue: string;
Expand All @@ -17,7 +13,9 @@ export interface StyleProps {
booleanValue: string;
otherValue: string;
punctuation: string;
pointer: string;
expandIcon: string;
collapseIcon: string;
collapsedContent: string;
}

export interface JsonRenderProps<T> {
Expand All @@ -41,10 +39,6 @@ export interface ExpandableRenderProps {
shouldInitiallyExpand: (level: number, value: any, field?: string) => boolean;
}

function combineStyles(style1: string, style2: string): string {
return `${style1 || ''} ${style2 || ''}`;
}

function renderExpandableObject({
field,
value,
Expand All @@ -69,7 +63,7 @@ function renderExpandableObject({
}
}, [shouldInitiallyExpand]);

const expandIcon = expanded ? expandedIcon : collapsedIcon;
const expanderIconStyle = expanded ? style.collapseIcon : style.expandIcon;
const childLevel = level + 1;
const lastIndex = data.length - 1;

Expand All @@ -82,14 +76,12 @@ function renderExpandableObject({
return (
<div className={style.basicChildStyle} role='list'>
<span
className={combineStyles(style.expander, style.pointer)}
className={expanderIconStyle}
role='button'
onClick={toggleExpanded}
onKeyDown={onKeyDown}
tabIndex={0}
>
{expandIcon}
</span>
/>
{field && <span className={style.label}>{field}:</span>}
<span className={style.punctuation}>{openBracket}</span>

Expand All @@ -109,14 +101,12 @@ function renderExpandableObject({
</div>
) : (
<span
className={combineStyles(style.punctuation, style.pointer)}
className={style.collapsedContent}
role='button'
tabIndex={0}
onClick={toggleExpanded}
onKeyDown={onKeyDown}
>
...
</span>
/>
)}

<span className={style.punctuation}>{closeBracket}</span>
Expand Down
6 changes: 3 additions & 3 deletions src/index.test.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
import * as React from 'react';
import { JsonView, defaultStyles, allExpanded, collapseAllNested } from '.';
import { render, screen } from '@testing-library/react';
import '@testing-library/jest-dom/extend-expect';
import '@testing-library/jest-dom';

describe('JsonView', () => {
it('should render object', () => {
render(<JsonView style={defaultStyles} data={{ test: true }} />);
expect(screen.getByText(/test/)).toBeInTheDocument();
expect(screen.getByText('true')).toBeInTheDocument();
expect(screen.getByText(/test/)).toBeDefined();
expect(screen.getByText('true')).toBeDefined();
});

it('should render object with default styles', () => {
Expand Down
10 changes: 6 additions & 4 deletions src/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,10 @@ export const defaultStyles: StyleProps = {
booleanValue: styles['value-boolean-light'],
numberValue: styles['value-number-light'],
otherValue: styles['value-other-light'],
expander: styles['expander-light'],
punctuation: styles['punctuation-light'],
pointer: styles.pointer
collapseIcon: styles['collapse-icon-light'],
expandIcon: styles['expand-icon-light'],
collapsedContent: styles['collapsed-content-light']
};

export const darkStyles: StyleProps = {
Expand All @@ -33,9 +34,10 @@ export const darkStyles: StyleProps = {
booleanValue: styles['value-boolean-dark'],
numberValue: styles['value-number-dark'],
otherValue: styles['value-other-dark'],
expander: styles['expander-dark'],
punctuation: styles['punctuation-dark'],
pointer: styles.pointer
collapseIcon: styles['collapse-icon-dark'],
expandIcon: styles['expand-icon-dark'],
collapsedContent: styles['collapsed-content-dark']
};

export const allExpanded = () => true;
Expand Down
Loading

0 comments on commit f2b78be

Please sign in to comment.