Skip to content

Commit 2e1d1ea

Browse files
committed
feat(Row): render returns the index of the parent keys. #27
1 parent 8bec4dd commit 2e1d1ea

File tree

6 files changed

+59
-44
lines changed

6 files changed

+59
-44
lines changed

core/src/Container.tsx

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,22 @@ export interface ContainerProps<T extends object> extends React.HTMLAttributes<H
1111
level?: number;
1212
value?: T;
1313
initialValue?: T;
14+
/** Index of the parent `keyName` */
15+
keys?: (string | number)[];
1416
}
1517
export const Container = forwardRef(<T extends object>(props: ContainerProps<T>, ref: React.Ref<HTMLDivElement>) => {
16-
const { className = '', children, parentValue, keyid, level = 1, value, initialValue, keyName, ...elmProps } = props;
18+
const {
19+
className = '',
20+
children,
21+
parentValue,
22+
keyid,
23+
level = 1,
24+
value,
25+
initialValue,
26+
keys,
27+
keyName,
28+
...elmProps
29+
} = props;
1730
const dispatch = useShowToolsDispatch();
1831
const subkeyid = useId();
1932
const defaultClassNames = [className, 'w-rjv-inner'].filter(Boolean).join(' ');
@@ -24,7 +37,7 @@ export const Container = forwardRef(<T extends object>(props: ContainerProps<T>,
2437
return (
2538
<div className={defaultClassNames} ref={ref} {...elmProps} {...reset}>
2639
<NestedOpen expandKey={subkeyid} value={value} level={level} keyName={keyName} initialValue={initialValue} />
27-
<KeyValues expandKey={subkeyid} value={value} level={level} />
40+
<KeyValues expandKey={subkeyid} value={value} level={level} keys={keys} />
2841
<NestedClose expandKey={subkeyid} value={value} level={level} />
2942
</div>
3043
);

core/src/comps/KeyValues.tsx

Lines changed: 17 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -5,20 +5,18 @@ import { useShowToolsDispatch } from '../store/ShowTools';
55
import { Value } from './Value';
66
import { KeyNameComp } from '../section/KeyName';
77
import { RowComp } from '../section/Row';
8-
import { Container } from '../Container';
8+
import { Container, type ContainerProps } from '../Container';
99
import { Quote, Colon } from '../symbol';
1010
import { useHighlight } from '../utils/useHighlight';
11+
import { type SectionElementResult } from '../store/Section';
1112

12-
interface KeyValuesProps<T extends object> {
13-
keyName?: string | number;
14-
value?: T;
15-
parentValue?: T;
13+
interface KeyValuesProps<T extends object> extends SectionElementResult<T> {
1614
expandKey?: string;
1715
level: number;
1816
}
1917

2018
export const KeyValues = <T extends object>(props: KeyValuesProps<T>) => {
21-
const { value, expandKey = '', level } = props;
19+
const { value, expandKey = '', level, keys = [] } = props;
2220
const expands = useExpandsStore();
2321
const { objectSortKeys, indentWidth, collapsed } = useStore();
2422
const isMyArray = Array.isArray(value);
@@ -49,7 +47,9 @@ export const KeyValues = <T extends object>(props: KeyValuesProps<T>) => {
4947
return (
5048
<div className="w-rjv-wrap" style={style}>
5149
{entries.map(([key, val], idx) => {
52-
return <KeyValuesItem parentValue={value} keyName={key} value={val} key={idx} level={level} />;
50+
return (
51+
<KeyValuesItem parentValue={value} keyName={key} keys={[...keys, key]} value={val} key={idx} level={level} />
52+
);
5353
})}
5454
</div>
5555
);
@@ -81,7 +81,7 @@ export const KayName = <T extends object>(props: KayNameProps<T>) => {
8181
KayName.displayName = 'JVR.KayName';
8282

8383
export const KeyValuesItem = <T extends object>(props: KeyValuesProps<T>) => {
84-
const { keyName, value, parentValue, level = 0 } = props;
84+
const { keyName, value, parentValue, level = 0, keys = [] } = props;
8585
const dispatch = useShowToolsDispatch();
8686
const subkeyid = useId();
8787
const isMyArray = Array.isArray(value);
@@ -94,15 +94,22 @@ export const KeyValuesItem = <T extends object>(props: KeyValuesProps<T>) => {
9494
if (isNested) {
9595
const myValue = isMySet ? Array.from(value as Set<any>) : isMyMap ? Object.fromEntries(value) : value;
9696
return (
97-
<Container keyName={keyName} value={myValue} parentValue={parentValue} initialValue={value} level={level + 1} />
97+
<Container
98+
keyName={keyName}
99+
value={myValue}
100+
parentValue={parentValue}
101+
initialValue={value}
102+
keys={keys}
103+
level={level + 1}
104+
/>
98105
);
99106
}
100107
const reset: React.HTMLAttributes<HTMLDivElement> = {
101108
onMouseEnter: () => dispatch({ [subkeyid]: true }),
102109
onMouseLeave: () => dispatch({ [subkeyid]: false }),
103110
};
104111
return (
105-
<RowComp className="w-rjv-line" value={value} keyName={keyName} parentValue={parentValue} {...reset}>
112+
<RowComp className="w-rjv-line" value={value} keyName={keyName} keys={keys} parentValue={parentValue} {...reset}>
106113
<KayName keyName={keyName} value={value} parentValue={parentValue} />
107114
<Value keyName={keyName!} value={value} expandKey={subkeyid} />
108115
</RowComp>

core/src/editor/KeyName.tsx

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { FC, useRef, useState } from 'react';
22
import { SectionElementProps } from '../store/Section';
33
import { useStore } from './store';
4+
import { type SectionElementResult } from '../store/Section';
45

56
export const KeyNameRender: SectionElementProps['render'] = (
67
{ children, ...reset },
@@ -16,13 +17,9 @@ export const KeyNameRender: SectionElementProps['render'] = (
1617
);
1718
};
1819

19-
interface ChildProps extends React.HTMLAttributes<HTMLSpanElement> {
20-
value: unknown;
21-
parentValue?: unknown;
22-
keyName: string | number;
23-
}
20+
interface ChildProps<T extends object> extends React.HTMLAttributes<HTMLSpanElement>, SectionElementResult<T> {}
2421

25-
const Child: FC<ChildProps> = (props) => {
22+
const Child = <T extends object>(props: ChildProps<T>) => {
2623
const { value, parentValue, keyName, ...reset } = props;
2724
const $dom = useRef<HTMLElement>(null);
2825
const [currentValue, setCurrentValue] = useState(props.children);

core/src/section/KeyName.tsx

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
1-
import { type FC, type PropsWithChildren } from 'react';
1+
import { type PropsWithChildren } from 'react';
22
import { type TagType } from '../store/Types';
33
import { type SectionElement, useSectionStore } from '../store/Section';
44
import { useSectionRender } from '../utils/useRender';
5+
import { type SectionElementResult } from '../store/Section';
56

67
export const KeyName = <K extends TagType>(props: SectionElement<K>) => {
78
const { KeyName: Comp = {} } = useSectionStore();
@@ -11,14 +12,12 @@ export const KeyName = <K extends TagType>(props: SectionElement<K>) => {
1112

1213
KeyName.displayName = 'JVR.KeyName';
1314

14-
type KeyNameCompProps = {
15-
keyName: string | number;
16-
value?: unknown;
17-
parentValue?: unknown;
18-
};
15+
export interface KeyNameCompProps<T extends object>
16+
extends React.HTMLAttributes<HTMLSpanElement>,
17+
SectionElementResult<T> {}
1918

20-
export const KeyNameComp: FC<PropsWithChildren<KeyNameCompProps>> = (props) => {
21-
const { children, value, parentValue, keyName } = props;
19+
export const KeyNameComp = <T extends object>(props: PropsWithChildren<KeyNameCompProps<T>>) => {
20+
const { children, value, parentValue, keyName, keys } = props;
2221
const isNumber = typeof children === 'number';
2322
const style: React.CSSProperties = {
2423
color: isNumber ? 'var(--w-rjv-key-number, #268bd2)' : 'var(--w-rjv-key-string, #002b36)',
@@ -28,7 +27,7 @@ export const KeyNameComp: FC<PropsWithChildren<KeyNameCompProps>> = (props) => {
2827
reset.style = { ...reset.style, ...style };
2928
const Elm = as || 'span';
3029
const child =
31-
render && typeof render === 'function' && render({ ...reset, children }, { value, parentValue, keyName });
30+
render && typeof render === 'function' && render({ ...reset, children }, { value, parentValue, keyName, keys });
3231
if (child) return child;
3332
return <Elm {...reset}>{children}</Elm>;
3433
};

core/src/section/Row.tsx

Lines changed: 7 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { type TagType } from '../store/Types';
22
import { type SectionElement, useSectionStore } from '../store/Section';
33
import { useSectionRender } from '../utils/useRender';
4+
import { type SectionElementResult } from '../store/Section';
45

56
export const Row = <K extends TagType>(props: SectionElement<K>) => {
67
const { Row: Comp = {} } = useSectionStore();
@@ -10,24 +11,17 @@ export const Row = <K extends TagType>(props: SectionElement<K>) => {
1011

1112
Row.displayName = 'JVR.Row';
1213

13-
export interface RowCompProps<T extends object> extends React.HTMLAttributes<HTMLDivElement> {
14-
value?: T;
15-
keyName?: string | number;
16-
parentValue?: unknown;
17-
}
14+
export interface RowCompProps<T extends object> extends React.HTMLAttributes<HTMLDivElement>, SectionElementResult<T> {}
1815

19-
export const RowComp = <T extends object>({
20-
children,
21-
value,
22-
keyName = '',
23-
parentValue,
24-
...other
25-
}: React.PropsWithChildren<RowCompProps<T>>) => {
16+
export const RowComp = <T extends object>(props: React.PropsWithChildren<RowCompProps<T>>) => {
17+
const { children, value, parentValue, keyName, keys, ...other } = props;
2618
const { Row: Comp = {} } = useSectionStore();
2719
const { as, render, children: _, ...reset } = Comp;
2820
const Elm = as || 'div';
2921
const child =
30-
render && typeof render === 'function' && render({ ...other, ...reset, children }, { value, keyName, parentValue });
22+
render &&
23+
typeof render === 'function' &&
24+
render({ ...other, ...reset, children }, { value, keyName, parentValue, keys });
3125
if (child) return child;
3226
return (
3327
<Elm {...other} {...reset}>

core/src/store/Section.tsx

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,17 @@
11
import React, { FC, PropsWithChildren, ComponentPropsWithoutRef, createContext, useContext, useReducer } from 'react';
22
import { type TagType } from './Types';
33

4+
export interface SectionElementResult<T extends object, K = string | number> {
5+
value?: T;
6+
parentValue?: T;
7+
keyName?: K;
8+
/** Index of the parent `keyName` */
9+
keys?: K[];
10+
}
11+
412
export type SectionElementProps<T extends TagType = 'span'> = {
513
as?: T;
6-
render?: (
7-
props: SectionElement<T>,
8-
result: { value: unknown; parentValue?: unknown; keyName: string | number },
9-
) => React.ReactNode;
14+
render?: (props: SectionElement<T>, result: SectionElementResult<object>) => React.ReactNode;
1015
};
1116

1217
export type SectionElement<T extends TagType = 'span'> = SectionElementProps<T> & ComponentPropsWithoutRef<T>;

0 commit comments

Comments
 (0)