mirror of
https://github.com/reduxjs/redux-devtools.git
synced 2025-07-22 22:19:48 +03:00
add context
This commit is contained in:
parent
e664cba9fb
commit
fc0611d750
|
@ -1,8 +1,9 @@
|
||||||
import React, { useCallback, useEffect, useState } from 'react';
|
import React, { useCallback, useEffect, useState } from 'react';
|
||||||
import JSONArrow from './JSONArrow';
|
|
||||||
import getCollectionEntries from './getCollectionEntries';
|
|
||||||
import JSONNode from './JSONNode';
|
|
||||||
import ItemRange from './ItemRange';
|
import ItemRange from './ItemRange';
|
||||||
|
import JSONArrow from './JSONArrow';
|
||||||
|
import JSONNode from './JSONNode';
|
||||||
|
import { useExpandableButtonContext } from './expandableButtonsContext';
|
||||||
|
import getCollectionEntries from './getCollectionEntries';
|
||||||
import type { CircularCache, CommonInternalProps } from './types';
|
import type { CircularCache, CommonInternalProps } from './types';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -110,12 +111,12 @@ export default function JSONNestedNode(props: Props) {
|
||||||
nodeType,
|
nodeType,
|
||||||
nodeTypeIndicator,
|
nodeTypeIndicator,
|
||||||
shouldExpandNodeInitially,
|
shouldExpandNodeInitially,
|
||||||
shouldExpandNode,
|
|
||||||
setShouldExpandNode,
|
|
||||||
setEnableDefaultButton,
|
|
||||||
styling,
|
styling,
|
||||||
} = props;
|
} = props;
|
||||||
|
|
||||||
|
const { shouldExpandNode, setShouldExpandNode, setEnableDefaultButton } =
|
||||||
|
useExpandableButtonContext();
|
||||||
|
|
||||||
const [expanded, setExpanded] = useState<boolean>(
|
const [expanded, setExpanded] = useState<boolean>(
|
||||||
// calculate individual node expansion if necessary
|
// calculate individual node expansion if necessary
|
||||||
isCircular ? false : shouldExpandNodeInitially(keyPath, data, level)
|
isCircular ? false : shouldExpandNodeInitially(keyPath, data, level)
|
||||||
|
@ -125,10 +126,16 @@ export default function JSONNestedNode(props: Props) {
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
switch (shouldExpandNode) {
|
switch (shouldExpandNode) {
|
||||||
case 'expand': setExpanded(true); break;
|
case 'expand':
|
||||||
case'collapse': setExpanded(false); break;
|
setExpanded(true);
|
||||||
case'default': setExpanded(defaultExpanded); break;
|
break;
|
||||||
default:
|
case 'collapse':
|
||||||
|
setExpanded(false);
|
||||||
|
break;
|
||||||
|
case 'default':
|
||||||
|
setExpanded(defaultExpanded);
|
||||||
|
break;
|
||||||
|
default: // Do nothing
|
||||||
}
|
}
|
||||||
}, [defaultExpanded, shouldExpandNode]);
|
}, [defaultExpanded, shouldExpandNode]);
|
||||||
|
|
||||||
|
@ -136,7 +143,7 @@ export default function JSONNestedNode(props: Props) {
|
||||||
if (expandable) {
|
if (expandable) {
|
||||||
setExpanded(!expanded);
|
setExpanded(!expanded);
|
||||||
setEnableDefaultButton(true);
|
setEnableDefaultButton(true);
|
||||||
setShouldExpandNode(undefined)
|
setShouldExpandNode(undefined);
|
||||||
}
|
}
|
||||||
}, [expandable, expanded, setEnableDefaultButton, setShouldExpandNode]);
|
}, [expandable, expanded, setEnableDefaultButton, setShouldExpandNode]);
|
||||||
|
|
||||||
|
|
|
@ -1,87 +1,84 @@
|
||||||
import React, { ReactNode } from 'react'
|
import {
|
||||||
|
faArrowDown,
|
||||||
|
faArrowRight,
|
||||||
|
faUndo,
|
||||||
|
} from '@fortawesome/free-solid-svg-icons';
|
||||||
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
|
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
|
||||||
import { faArrowDown, faArrowRight, faUndo } from '@fortawesome/free-solid-svg-icons';
|
import React, { ReactNode } from 'react';
|
||||||
import { Expandable } from '.';
|
import { Expandable } from '.';
|
||||||
|
import { useExpandableButtonContext } from './expandableButtonsContext';
|
||||||
|
|
||||||
interface Props {
|
interface ExpandableButtonsProps {
|
||||||
expandable?: Expandable;
|
expandable: Expandable;
|
||||||
enableDefaultButton: boolean;
|
|
||||||
setEnableDefaultButton: any;
|
|
||||||
shouldExpandNode?: 'expand' | 'collapse' | 'default';
|
|
||||||
setShouldExpandNode: any;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
interface ExpandButtonProps {
|
interface ExpandButtonProps {
|
||||||
expandableDefaultValue?: 'expand' | 'collapse';
|
expandableDefaultValue?: 'expand' | 'collapse';
|
||||||
expandIcon?: ReactNode;
|
expandIcon?: ReactNode;
|
||||||
shouldExpandNode?: 'expand' | 'collapse' | 'default';
|
|
||||||
setShouldExpandNode: any;
|
|
||||||
setEnableDefaultButton: any;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
interface CollapseButtonProps {
|
interface CollapseButtonProps {
|
||||||
expandableDefaultValue?: 'expand' | 'collapse';
|
expandableDefaultValue?: 'expand' | 'collapse';
|
||||||
collapseIcon?: ReactNode;
|
collapseIcon?: ReactNode;
|
||||||
shouldExpandNode?: 'expand' | 'collapse' | 'default';
|
|
||||||
setShouldExpandNode: any;
|
|
||||||
setEnableDefaultButton: any;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
interface DefaultButtonProps {
|
interface DefaultButtonProps {
|
||||||
defaultIcon?: ReactNode;
|
defaultIcon?: ReactNode;
|
||||||
setShouldExpandNode: any;
|
|
||||||
setEnableDefaultButton: any;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function ExpandableButtons({
|
function ExpandableButtons({ expandable }: ExpandableButtonsProps) {
|
||||||
expandable,
|
const { enableDefaultButton } = useExpandableButtonContext();
|
||||||
enableDefaultButton,
|
|
||||||
setEnableDefaultButton,
|
|
||||||
setShouldExpandNode,
|
|
||||||
shouldExpandNode
|
|
||||||
}: Props){
|
|
||||||
if(!expandable){
|
|
||||||
return <></>
|
|
||||||
}
|
|
||||||
|
|
||||||
const expandableDefaultValue = expandable?.defaultValue || 'expand'
|
const expandableDefaultValue = expandable?.defaultValue || 'expand';
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div style={{position: 'absolute', display: 'flex', justifyContent:'center', alignItems: 'center', gap:'1rem', top: '1rem', right: '1rem', cursor: 'pointer'}}>
|
<div
|
||||||
{enableDefaultButton && <DefaultButton
|
style={{
|
||||||
defaultIcon={expandable?.defaultIcon}
|
position: 'absolute',
|
||||||
setShouldExpandNode={setShouldExpandNode}
|
display: 'flex',
|
||||||
setEnableDefaultButton={setEnableDefaultButton}
|
justifyContent: 'center',
|
||||||
/>}
|
alignItems: 'center',
|
||||||
|
gap: '1rem',
|
||||||
|
top: '1rem',
|
||||||
|
right: '1rem',
|
||||||
|
cursor: 'pointer',
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{enableDefaultButton && (
|
||||||
|
<DefaultButton defaultIcon={expandable?.defaultIcon} />
|
||||||
|
)}
|
||||||
|
|
||||||
<ExpandButton
|
<ExpandButton
|
||||||
expandableDefaultValue={expandableDefaultValue}
|
expandableDefaultValue={expandableDefaultValue}
|
||||||
expandIcon={expandable?.expandIcon}
|
expandIcon={expandable?.expandIcon}
|
||||||
setShouldExpandNode={setShouldExpandNode}
|
|
||||||
setEnableDefaultButton={setEnableDefaultButton}
|
|
||||||
shouldExpandNode={shouldExpandNode}
|
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<CollapseButton
|
<CollapseButton
|
||||||
expandableDefaultValue={expandable?.defaultValue}
|
expandableDefaultValue={expandable?.defaultValue}
|
||||||
collapseIcon={expandable?.collapseIcon}
|
collapseIcon={expandable?.collapseIcon}
|
||||||
setShouldExpandNode={setShouldExpandNode}
|
|
||||||
setEnableDefaultButton={setEnableDefaultButton}
|
|
||||||
shouldExpandNode={shouldExpandNode}
|
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
)
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
function ExpandButton({ expandableDefaultValue, expandIcon, shouldExpandNode, setEnableDefaultButton, setShouldExpandNode }: ExpandButtonProps) {
|
function ExpandButton({
|
||||||
|
expandableDefaultValue,
|
||||||
|
expandIcon,
|
||||||
|
}: ExpandButtonProps) {
|
||||||
|
const { shouldExpandNode, setShouldExpandNode, setEnableDefaultButton } =
|
||||||
|
useExpandableButtonContext();
|
||||||
|
|
||||||
const onExpand = () => {
|
const onExpand = () => {
|
||||||
setShouldExpandNode('expand');
|
setShouldExpandNode('expand');
|
||||||
setEnableDefaultButton(true);
|
setEnableDefaultButton(true);
|
||||||
}
|
};
|
||||||
|
|
||||||
const isDefault = !shouldExpandNode ||shouldExpandNode === 'default'
|
const isDefault = !shouldExpandNode || shouldExpandNode === 'default';
|
||||||
|
|
||||||
if (shouldExpandNode === 'collapse' || (isDefault && expandableDefaultValue === 'collapse')) {
|
if (
|
||||||
|
shouldExpandNode === 'collapse' ||
|
||||||
|
(isDefault && expandableDefaultValue === 'collapse')
|
||||||
|
) {
|
||||||
return (
|
return (
|
||||||
<div role="presentation" onClick={onExpand}>
|
<div role="presentation" onClick={onExpand}>
|
||||||
{expandIcon || <FontAwesomeIcon icon={faArrowRight} />}
|
{expandIcon || <FontAwesomeIcon icon={faArrowRight} />}
|
||||||
|
@ -92,15 +89,24 @@ function ExpandButton({ expandableDefaultValue, expandIcon, shouldExpandNode, se
|
||||||
return <></>;
|
return <></>;
|
||||||
}
|
}
|
||||||
|
|
||||||
function CollapseButton({ expandableDefaultValue, collapseIcon, shouldExpandNode, setEnableDefaultButton, setShouldExpandNode }: CollapseButtonProps) {
|
function CollapseButton({
|
||||||
|
expandableDefaultValue,
|
||||||
|
collapseIcon,
|
||||||
|
}: CollapseButtonProps) {
|
||||||
|
const { shouldExpandNode, setShouldExpandNode, setEnableDefaultButton } =
|
||||||
|
useExpandableButtonContext();
|
||||||
|
|
||||||
const onCollapse = () => {
|
const onCollapse = () => {
|
||||||
setShouldExpandNode('collapse');
|
setShouldExpandNode('collapse');
|
||||||
setEnableDefaultButton(true);
|
setEnableDefaultButton(true);
|
||||||
}
|
};
|
||||||
|
|
||||||
const isDefault = !shouldExpandNode ||shouldExpandNode === 'default'
|
const isDefault = !shouldExpandNode || shouldExpandNode === 'default';
|
||||||
|
|
||||||
if (shouldExpandNode === 'expand' ||(isDefault && expandableDefaultValue === 'expand')) {
|
if (
|
||||||
|
shouldExpandNode === 'expand' ||
|
||||||
|
(isDefault && expandableDefaultValue === 'expand')
|
||||||
|
) {
|
||||||
return (
|
return (
|
||||||
<div role="presentation" onClick={onCollapse}>
|
<div role="presentation" onClick={onCollapse}>
|
||||||
{collapseIcon || <FontAwesomeIcon icon={faArrowDown} />}
|
{collapseIcon || <FontAwesomeIcon icon={faArrowDown} />}
|
||||||
|
@ -111,11 +117,14 @@ function ExpandButton({ expandableDefaultValue, expandIcon, shouldExpandNode, se
|
||||||
return <></>;
|
return <></>;
|
||||||
}
|
}
|
||||||
|
|
||||||
function DefaultButton({defaultIcon, setEnableDefaultButton, setShouldExpandNode }:DefaultButtonProps) {
|
function DefaultButton({ defaultIcon }: DefaultButtonProps) {
|
||||||
|
const { setShouldExpandNode, setEnableDefaultButton } =
|
||||||
|
useExpandableButtonContext();
|
||||||
|
|
||||||
const onDefaultCollapse = () => {
|
const onDefaultCollapse = () => {
|
||||||
setShouldExpandNode('default');
|
setShouldExpandNode('default');
|
||||||
setEnableDefaultButton(false)
|
setEnableDefaultButton(false);
|
||||||
}
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div role="presentation" onClick={onDefaultCollapse}>
|
<div role="presentation" onClick={onDefaultCollapse}>
|
||||||
|
@ -126,4 +135,4 @@ function ExpandButton({ expandableDefaultValue, expandIcon, shouldExpandNode, se
|
||||||
return <></>;
|
return <></>;
|
||||||
}
|
}
|
||||||
|
|
||||||
export default ExpandableButtons
|
export default ExpandableButtons;
|
||||||
|
|
50
packages/react-json-tree/src/expandableButtonsContext.tsx
Normal file
50
packages/react-json-tree/src/expandableButtonsContext.tsx
Normal file
|
@ -0,0 +1,50 @@
|
||||||
|
import React, {
|
||||||
|
ReactNode,
|
||||||
|
createContext,
|
||||||
|
useContext,
|
||||||
|
useMemo,
|
||||||
|
useState,
|
||||||
|
} from 'react';
|
||||||
|
import { Expandable } from '.';
|
||||||
|
import ExpandableButtons from './expandableButtons';
|
||||||
|
|
||||||
|
interface Context {
|
||||||
|
enableDefaultButton: boolean;
|
||||||
|
setEnableDefaultButton: any;
|
||||||
|
shouldExpandNode?: 'expand' | 'collapse' | 'default';
|
||||||
|
setShouldExpandNode: any;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface Props {
|
||||||
|
children: ReactNode;
|
||||||
|
expandable?: Expandable;
|
||||||
|
}
|
||||||
|
|
||||||
|
const ExpandableButtonsContext = createContext<Context>({} as Context);
|
||||||
|
|
||||||
|
function ExpandableButtonsContextProvider({ expandable, children }: Props) {
|
||||||
|
const [enableDefaultButton, setEnableDefaultButton] = useState(false);
|
||||||
|
const [shouldExpandNode, setShouldExpandNode] = useState();
|
||||||
|
|
||||||
|
const value = useMemo(
|
||||||
|
() => ({
|
||||||
|
enableDefaultButton,
|
||||||
|
setEnableDefaultButton,
|
||||||
|
shouldExpandNode,
|
||||||
|
setShouldExpandNode,
|
||||||
|
}),
|
||||||
|
[enableDefaultButton, shouldExpandNode]
|
||||||
|
);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<ExpandableButtonsContext.Provider value={value}>
|
||||||
|
{children}
|
||||||
|
{expandable && <ExpandableButtons expandable={expandable} />}
|
||||||
|
</ExpandableButtonsContext.Provider>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export const useExpandableButtonContext = () =>
|
||||||
|
useContext(ExpandableButtonsContext);
|
||||||
|
|
||||||
|
export default ExpandableButtonsContextProvider;
|
|
@ -3,12 +3,13 @@
|
||||||
// Dave Vedder <veddermatic@gmail.com> http://www.eskimospy.com/
|
// Dave Vedder <veddermatic@gmail.com> http://www.eskimospy.com/
|
||||||
// port by Daniele Zannotti http://www.github.com/dzannotti <dzannotti@me.com>
|
// port by Daniele Zannotti http://www.github.com/dzannotti <dzannotti@me.com>
|
||||||
|
|
||||||
import React, { ReactNode, useMemo, useState } from 'react';
|
import React, { ReactNode, useMemo } from 'react';
|
||||||
import JSONNode from './JSONNode';
|
import JSONNode from './JSONNode';
|
||||||
import createStylingFromTheme from './createStylingFromTheme';
|
import createStylingFromTheme from './createStylingFromTheme';
|
||||||
import { invertTheme } from 'react-base16-styling';
|
import { invertTheme } from 'react-base16-styling';
|
||||||
import type { StylingValue, Theme } from 'react-base16-styling';
|
import type { StylingValue, Theme } from 'react-base16-styling';
|
||||||
import ExpandableButtons from './expandableButtons'
|
import ExpandableButtonsContext from './expandableButtonsContext';
|
||||||
|
|
||||||
import type {
|
import type {
|
||||||
CommonExternalProps,
|
CommonExternalProps,
|
||||||
GetItemString,
|
GetItemString,
|
||||||
|
@ -58,9 +59,6 @@ export function JSONTree({
|
||||||
collectionLimit = 50,
|
collectionLimit = 50,
|
||||||
sortObjectKeys = false,
|
sortObjectKeys = false,
|
||||||
}: Props) {
|
}: Props) {
|
||||||
const [enableDefaultButton, setEnableDefaultButton] = useState(false);
|
|
||||||
const [shouldExpandNode, setShouldExpandNode] = useState();
|
|
||||||
|
|
||||||
const styling = useMemo(
|
const styling = useMemo(
|
||||||
() =>
|
() =>
|
||||||
createStylingFromTheme(shouldInvertTheme ? invertTheme(theme) : theme),
|
createStylingFromTheme(shouldInvertTheme ? invertTheme(theme) : theme),
|
||||||
|
@ -69,6 +67,7 @@ export function JSONTree({
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ul {...styling('tree')}>
|
<ul {...styling('tree')}>
|
||||||
|
<ExpandableButtonsContext expandable={expandable}>
|
||||||
<JSONNode
|
<JSONNode
|
||||||
keyPath={hideRoot ? [] : keyPath}
|
keyPath={hideRoot ? [] : keyPath}
|
||||||
value={postprocessValue(value)}
|
value={postprocessValue(value)}
|
||||||
|
@ -77,23 +76,13 @@ export function JSONTree({
|
||||||
labelRenderer={labelRenderer}
|
labelRenderer={labelRenderer}
|
||||||
valueRenderer={valueRenderer}
|
valueRenderer={valueRenderer}
|
||||||
shouldExpandNodeInitially={shouldExpandNodeInitially}
|
shouldExpandNodeInitially={shouldExpandNodeInitially}
|
||||||
shouldExpandNode={shouldExpandNode}
|
|
||||||
setEnableDefaultButton={setEnableDefaultButton}
|
|
||||||
setShouldExpandNode={setShouldExpandNode}
|
|
||||||
hideRoot={hideRoot}
|
hideRoot={hideRoot}
|
||||||
getItemString={getItemString}
|
getItemString={getItemString}
|
||||||
postprocessValue={postprocessValue}
|
postprocessValue={postprocessValue}
|
||||||
collectionLimit={collectionLimit}
|
collectionLimit={collectionLimit}
|
||||||
sortObjectKeys={sortObjectKeys}
|
sortObjectKeys={sortObjectKeys}
|
||||||
/>
|
/>
|
||||||
|
</ExpandableButtonsContext>
|
||||||
<ExpandableButtons
|
|
||||||
expandable={expandable}
|
|
||||||
enableDefaultButton={enableDefaultButton}
|
|
||||||
setEnableDefaultButton={setEnableDefaultButton}
|
|
||||||
shouldExpandNode={shouldExpandNode}
|
|
||||||
setShouldExpandNode={setShouldExpandNode}
|
|
||||||
/>
|
|
||||||
</ul>
|
</ul>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -53,8 +53,6 @@ export interface CommonExternalProps {
|
||||||
isCustomNode: IsCustomNode;
|
isCustomNode: IsCustomNode;
|
||||||
collectionLimit: number;
|
collectionLimit: number;
|
||||||
sortObjectKeys: SortObjectKeys;
|
sortObjectKeys: SortObjectKeys;
|
||||||
setEnableDefaultButton: any;
|
|
||||||
setShouldExpandNode: any;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface CommonInternalProps extends CommonExternalProps {
|
export interface CommonInternalProps extends CommonExternalProps {
|
||||||
|
@ -62,5 +60,4 @@ export interface CommonInternalProps extends CommonExternalProps {
|
||||||
circularCache?: CircularCache;
|
circularCache?: CircularCache;
|
||||||
level?: number;
|
level?: number;
|
||||||
isCircular?: boolean;
|
isCircular?: boolean;
|
||||||
shouldExpandNode?: 'expand' | 'collapse' | 'default';
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user