Skip to content

Commit

Permalink
feat(Row): render returns the index of the parent keys. #27
Browse files Browse the repository at this point in the history
  • Loading branch information
jaywcjlove committed Feb 24, 2024
1 parent 8bec4dd commit 2e1d1ea
Show file tree
Hide file tree
Showing 6 changed files with 59 additions and 44 deletions.
17 changes: 15 additions & 2 deletions core/src/Container.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,22 @@ export interface ContainerProps<T extends object> extends React.HTMLAttributes<H
level?: number;
value?: T;
initialValue?: T;
/** Index of the parent `keyName` */
keys?: (string | number)[];
}
export const Container = forwardRef(<T extends object>(props: ContainerProps<T>, ref: React.Ref<HTMLDivElement>) => {
const { className = '', children, parentValue, keyid, level = 1, value, initialValue, keyName, ...elmProps } = props;
const {
className = '',
children,
parentValue,
keyid,
level = 1,
value,
initialValue,
keys,
keyName,
...elmProps
} = props;
const dispatch = useShowToolsDispatch();
const subkeyid = useId();
const defaultClassNames = [className, 'w-rjv-inner'].filter(Boolean).join(' ');
Expand All @@ -24,7 +37,7 @@ export const Container = forwardRef(<T extends object>(props: ContainerProps<T>,
return (
<div className={defaultClassNames} ref={ref} {...elmProps} {...reset}>
<NestedOpen expandKey={subkeyid} value={value} level={level} keyName={keyName} initialValue={initialValue} />
<KeyValues expandKey={subkeyid} value={value} level={level} />
<KeyValues expandKey={subkeyid} value={value} level={level} keys={keys} />
<NestedClose expandKey={subkeyid} value={value} level={level} />
</div>
);
Expand Down
27 changes: 17 additions & 10 deletions core/src/comps/KeyValues.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,20 +5,18 @@ import { useShowToolsDispatch } from '../store/ShowTools';
import { Value } from './Value';
import { KeyNameComp } from '../section/KeyName';
import { RowComp } from '../section/Row';
import { Container } from '../Container';
import { Container, type ContainerProps } from '../Container';
import { Quote, Colon } from '../symbol';
import { useHighlight } from '../utils/useHighlight';
import { type SectionElementResult } from '../store/Section';

interface KeyValuesProps<T extends object> {
keyName?: string | number;
value?: T;
parentValue?: T;
interface KeyValuesProps<T extends object> extends SectionElementResult<T> {
expandKey?: string;
level: number;
}

export const KeyValues = <T extends object>(props: KeyValuesProps<T>) => {
const { value, expandKey = '', level } = props;
const { value, expandKey = '', level, keys = [] } = props;
const expands = useExpandsStore();
const { objectSortKeys, indentWidth, collapsed } = useStore();
const isMyArray = Array.isArray(value);
Expand Down Expand Up @@ -49,7 +47,9 @@ export const KeyValues = <T extends object>(props: KeyValuesProps<T>) => {
return (
<div className="w-rjv-wrap" style={style}>
{entries.map(([key, val], idx) => {
return <KeyValuesItem parentValue={value} keyName={key} value={val} key={idx} level={level} />;
return (
<KeyValuesItem parentValue={value} keyName={key} keys={[...keys, key]} value={val} key={idx} level={level} />
);
})}
</div>
);
Expand Down Expand Up @@ -81,7 +81,7 @@ export const KayName = <T extends object>(props: KayNameProps<T>) => {
KayName.displayName = 'JVR.KayName';

export const KeyValuesItem = <T extends object>(props: KeyValuesProps<T>) => {
const { keyName, value, parentValue, level = 0 } = props;
const { keyName, value, parentValue, level = 0, keys = [] } = props;
const dispatch = useShowToolsDispatch();
const subkeyid = useId();
const isMyArray = Array.isArray(value);
Expand All @@ -94,15 +94,22 @@ export const KeyValuesItem = <T extends object>(props: KeyValuesProps<T>) => {
if (isNested) {
const myValue = isMySet ? Array.from(value as Set<any>) : isMyMap ? Object.fromEntries(value) : value;
return (
<Container keyName={keyName} value={myValue} parentValue={parentValue} initialValue={value} level={level + 1} />
<Container
keyName={keyName}
value={myValue}
parentValue={parentValue}
initialValue={value}
keys={keys}
level={level + 1}
/>
);
}
const reset: React.HTMLAttributes<HTMLDivElement> = {
onMouseEnter: () => dispatch({ [subkeyid]: true }),
onMouseLeave: () => dispatch({ [subkeyid]: false }),
};
return (
<RowComp className="w-rjv-line" value={value} keyName={keyName} parentValue={parentValue} {...reset}>
<RowComp className="w-rjv-line" value={value} keyName={keyName} keys={keys} parentValue={parentValue} {...reset}>
<KayName keyName={keyName} value={value} parentValue={parentValue} />
<Value keyName={keyName!} value={value} expandKey={subkeyid} />
</RowComp>
Expand Down
9 changes: 3 additions & 6 deletions core/src/editor/KeyName.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { FC, useRef, useState } from 'react';
import { SectionElementProps } from '../store/Section';
import { useStore } from './store';
import { type SectionElementResult } from '../store/Section';

export const KeyNameRender: SectionElementProps['render'] = (
{ children, ...reset },
Expand All @@ -16,13 +17,9 @@ export const KeyNameRender: SectionElementProps['render'] = (
);
};

interface ChildProps extends React.HTMLAttributes<HTMLSpanElement> {
value: unknown;
parentValue?: unknown;
keyName: string | number;
}
interface ChildProps<T extends object> extends React.HTMLAttributes<HTMLSpanElement>, SectionElementResult<T> {}

const Child: FC<ChildProps> = (props) => {
const Child = <T extends object>(props: ChildProps<T>) => {
const { value, parentValue, keyName, ...reset } = props;
const $dom = useRef<HTMLElement>(null);
const [currentValue, setCurrentValue] = useState(props.children);
Expand Down
17 changes: 8 additions & 9 deletions core/src/section/KeyName.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import { type FC, type PropsWithChildren } from 'react';
import { type PropsWithChildren } from 'react';
import { type TagType } from '../store/Types';
import { type SectionElement, useSectionStore } from '../store/Section';
import { useSectionRender } from '../utils/useRender';
import { type SectionElementResult } from '../store/Section';

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

KeyName.displayName = 'JVR.KeyName';

type KeyNameCompProps = {
keyName: string | number;
value?: unknown;
parentValue?: unknown;
};
export interface KeyNameCompProps<T extends object>
extends React.HTMLAttributes<HTMLSpanElement>,
SectionElementResult<T> {}

export const KeyNameComp: FC<PropsWithChildren<KeyNameCompProps>> = (props) => {
const { children, value, parentValue, keyName } = props;
export const KeyNameComp = <T extends object>(props: PropsWithChildren<KeyNameCompProps<T>>) => {
const { children, value, parentValue, keyName, keys } = props;
const isNumber = typeof children === 'number';
const style: React.CSSProperties = {
color: isNumber ? 'var(--w-rjv-key-number, #268bd2)' : 'var(--w-rjv-key-string, #002b36)',
Expand All @@ -28,7 +27,7 @@ export const KeyNameComp: FC<PropsWithChildren<KeyNameCompProps>> = (props) => {
reset.style = { ...reset.style, ...style };
const Elm = as || 'span';
const child =
render && typeof render === 'function' && render({ ...reset, children }, { value, parentValue, keyName });
render && typeof render === 'function' && render({ ...reset, children }, { value, parentValue, keyName, keys });
if (child) return child;
return <Elm {...reset}>{children}</Elm>;
};
Expand Down
20 changes: 7 additions & 13 deletions core/src/section/Row.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { type TagType } from '../store/Types';
import { type SectionElement, useSectionStore } from '../store/Section';
import { useSectionRender } from '../utils/useRender';
import { type SectionElementResult } from '../store/Section';

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

Row.displayName = 'JVR.Row';

export interface RowCompProps<T extends object> extends React.HTMLAttributes<HTMLDivElement> {
value?: T;
keyName?: string | number;
parentValue?: unknown;
}
export interface RowCompProps<T extends object> extends React.HTMLAttributes<HTMLDivElement>, SectionElementResult<T> {}

export const RowComp = <T extends object>({
children,
value,
keyName = '',
parentValue,
...other
}: React.PropsWithChildren<RowCompProps<T>>) => {
export const RowComp = <T extends object>(props: React.PropsWithChildren<RowCompProps<T>>) => {
const { children, value, parentValue, keyName, keys, ...other } = props;
const { Row: Comp = {} } = useSectionStore();
const { as, render, children: _, ...reset } = Comp;
const Elm = as || 'div';
const child =
render && typeof render === 'function' && render({ ...other, ...reset, children }, { value, keyName, parentValue });
render &&
typeof render === 'function' &&
render({ ...other, ...reset, children }, { value, keyName, parentValue, keys });
if (child) return child;
return (
<Elm {...other} {...reset}>
Expand Down
13 changes: 9 additions & 4 deletions core/src/store/Section.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,17 @@
import React, { FC, PropsWithChildren, ComponentPropsWithoutRef, createContext, useContext, useReducer } from 'react';
import { type TagType } from './Types';

export interface SectionElementResult<T extends object, K = string | number> {
value?: T;
parentValue?: T;
keyName?: K;
/** Index of the parent `keyName` */
keys?: K[];
}

export type SectionElementProps<T extends TagType = 'span'> = {
as?: T;
render?: (
props: SectionElement<T>,
result: { value: unknown; parentValue?: unknown; keyName: string | number },
) => React.ReactNode;
render?: (props: SectionElement<T>, result: SectionElementResult<object>) => React.ReactNode;
};

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

0 comments on commit 2e1d1ea

Please sign in to comment.