Skip to content

Commit 1f40994

Browse files
committed
feat: add shouldExpandNodeInitially props. #59
1 parent 18a9334 commit 1f40994

File tree

8 files changed

+82
-16
lines changed

8 files changed

+82
-16
lines changed

core/README.md

+39
Original file line numberDiff line numberDiff line change
@@ -710,6 +710,45 @@ export default function Demo() {
710710
}
711711
```
712712

713+
## Default Collapse/Expand
714+
715+
```tsx mdx:preview
716+
import React from 'react';
717+
import JsonView from '@uiw/react-json-view';
718+
const object = {
719+
string: 'Lorem ipsum dolor sit amet',
720+
integer: 42,
721+
float: 114.514,
722+
object: {
723+
'first-child': true,
724+
'second-child': false,
725+
'last-child': null,
726+
},
727+
nestedArray: [
728+
[1, 2],
729+
[3, 4],
730+
],
731+
}
732+
export default function Demo() {
733+
return (
734+
<JsonView
735+
value={object}
736+
collapsed={2}
737+
shouldExpandNodeInitially={(isExpanded, { value, keys, level }) => {
738+
if (keys.length > 0 && keys[0] == "object") {
739+
return true
740+
}
741+
return isExpanded
742+
}}
743+
style={{
744+
'--w-rjv-background-color': '#ffffff',
745+
}}
746+
>
747+
</JsonView>
748+
)
749+
}
750+
```
751+
713752
## Modify Icon Style
714753

715754
Use built-in default icons.

core/src/Container.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ export const Container = forwardRef(<T extends object>(props: ContainerProps<T>,
5454
parentValue={parentValue}
5555
keyName={keyName}
5656
/>
57-
<NestedClose expandKey={subkeyid} value={value} level={level} />
57+
<NestedClose expandKey={subkeyid} value={value} level={level} keys={keys} />
5858
</div>
5959
);
6060
});

core/src/comps/KeyValues.tsx

+11-4
Original file line numberDiff line numberDiff line change
@@ -20,11 +20,18 @@ interface KeyValuesProps<T extends object> extends SectionElementResult<T> {
2020
export const KeyValues = <T extends object>(props: KeyValuesProps<T>) => {
2121
const { value, expandKey = '', level, keys = [] } = props;
2222
const expands = useExpandsStore();
23-
const { objectSortKeys, indentWidth, collapsed } = useStore();
23+
const { objectSortKeys, indentWidth, collapsed, shouldExpandNodeInitially } = useStore();
2424
const isMyArray = Array.isArray(value);
25-
const isExpanded =
26-
expands[expandKey] ??
27-
(typeof collapsed === 'boolean' ? collapsed : typeof collapsed === 'number' ? level > collapsed : false);
25+
const defaultExpanded =
26+
typeof collapsed === 'boolean' ? collapsed : typeof collapsed === 'number' ? level > collapsed : false;
27+
const isExpanded = expands[expandKey] ?? defaultExpanded;
28+
if (
29+
expands[expandKey] === undefined &&
30+
shouldExpandNodeInitially &&
31+
shouldExpandNodeInitially(isExpanded, { value, keys, level })
32+
) {
33+
return null;
34+
}
2835
if (isExpanded) {
2936
return null;
3037
}

core/src/comps/NestedClose.tsx

+13-5
Original file line numberDiff line numberDiff line change
@@ -6,18 +6,26 @@ interface NestedCloseProps<T extends object> {
66
value?: T;
77
expandKey: string;
88
level: number;
9+
keys?: (string | number)[];
910
}
1011

1112
export const NestedClose = <T extends object>(props: NestedCloseProps<T>) => {
12-
const { value, expandKey, level } = props;
13+
const { value, expandKey, level, keys = [] } = props;
1314
const expands = useExpandsStore();
1415
const isArray = Array.isArray(value);
15-
const { collapsed } = useStore();
16+
const { collapsed, shouldExpandNodeInitially } = useStore();
1617
const isMySet = value instanceof Set;
17-
const isExpanded =
18-
expands[expandKey] ??
19-
(typeof collapsed === 'boolean' ? collapsed : typeof collapsed === 'number' ? level > collapsed : false);
18+
const defaultExpanded =
19+
typeof collapsed === 'boolean' ? collapsed : typeof collapsed === 'number' ? level > collapsed : false;
20+
const isExpanded = expands[expandKey] ?? defaultExpanded;
2021
const len = Object.keys(value!).length;
22+
if (
23+
expands[expandKey] === undefined &&
24+
shouldExpandNodeInitially &&
25+
shouldExpandNodeInitially(isExpanded, { value, keys, level })
26+
) {
27+
return null;
28+
}
2129
if (isExpanded || len === 0) {
2230
return null;
2331
}

core/src/comps/NestedOpen.tsx

+9-5
Original file line numberDiff line numberDiff line change
@@ -16,16 +16,20 @@ export interface NestedOpenProps<T extends object> extends SectionElementResult<
1616
}
1717

1818
export const NestedOpen = <T extends object>(props: NestedOpenProps<T>) => {
19-
const { keyName, expandKey, keys, initialValue, value, parentValue, level } = props;
19+
const { keyName, expandKey, keys = [], initialValue, value, parentValue, level } = props;
2020
const expands = useExpandsStore();
2121
const dispatchExpands = useExpandsDispatch();
22-
const { onExpand, collapsed } = useStore();
22+
const { onExpand, collapsed, shouldExpandNodeInitially } = useStore();
2323
const isArray = Array.isArray(value);
2424
const isMySet = value instanceof Set;
25-
const isExpanded =
26-
expands[expandKey] ??
27-
(typeof collapsed === 'boolean' ? collapsed : typeof collapsed === 'number' ? level > collapsed : false);
25+
const defaultExpanded =
26+
typeof collapsed === 'boolean' ? collapsed : typeof collapsed === 'number' ? level > collapsed : false;
2827
const isObject = typeof value === 'object';
28+
let isExpanded = expands[expandKey] ?? defaultExpanded;
29+
const shouldExpand = shouldExpandNodeInitially && shouldExpandNodeInitially(isExpanded, { value, keys, level });
30+
if (expands[expandKey] === undefined && shouldExpand !== undefined) {
31+
isExpanded = shouldExpand;
32+
}
2933
const click = () => {
3034
const opt = { expand: !isExpanded, value, keyid: expandKey, keyName };
3135
onExpand && onExpand(opt);

core/src/index.tsx

+7
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,11 @@ export interface JsonViewProps<T extends object>
5757
enableClipboard?: boolean;
5858
/** When set to true, all nodes will be collapsed by default. Use an integer value to collapse at a particular depth. @default false */
5959
collapsed?: boolean | number;
60+
/** Determine whether the node should be expanded on the first render, or you can use collapsed to control the level of expansion (by default, the root is expanded). */
61+
shouldExpandNodeInitially?: (
62+
isExpanded: boolean,
63+
props: { value?: T; keys: (number | string)[]; level: number },
64+
) => boolean;
6065
/** Whether to highlight updates. @default true */
6166
highlightUpdates?: boolean;
6267
/** Shorten long JSON strings, Set to `0` to disable this feature @default 30 */
@@ -107,6 +112,7 @@ const JsonView: JsonViewComponent = forwardRef<HTMLDivElement, JsonViewProps<obj
107112
value,
108113
children,
109114
collapsed,
115+
shouldExpandNodeInitially,
110116
indentWidth = 15,
111117
displayObjectSize = true,
112118
shortenTextAfterLength = 30,
@@ -133,6 +139,7 @@ const JsonView: JsonViewComponent = forwardRef<HTMLDivElement, JsonViewProps<obj
133139
value,
134140
objectSortKeys,
135141
indentWidth,
142+
shouldExpandNodeInitially,
136143
displayObjectSize,
137144
collapsed,
138145
enableClipboard,

core/src/store.tsx

+1
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ export interface InitialState<T extends object> {
1818
enableClipboard?: JsonViewProps<T>['enableClipboard'];
1919
highlightUpdates?: JsonViewProps<T>['highlightUpdates'];
2020
collapsed?: JsonViewProps<T>['collapsed'];
21+
shouldExpandNodeInitially?: JsonViewProps<T>['shouldExpandNodeInitially'];
2122
indentWidth?: number;
2223
}
2324

www/src/App.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ export default function App() {
3838
Editor
3939
</Button> */}
4040
</TabItem>
41-
{tabs === 'preview' && <Example />}
41+
{/* {tabs === 'preview' && <Example />} */}
4242
{/* {tabs === 'editor' && <ExampleEditor />} */}
4343
</ExampleWrapper>
4444
);

0 commit comments

Comments
 (0)