diff --git a/README.md b/README.md index a17889a..fbae2fc 100644 --- a/README.md +++ b/README.md @@ -70,6 +70,7 @@ import 'react18-json-view/src/style.css' | `customizeCopy` | `(node: any) => any` | internal stringify | Customize copy behavior, only the returned non-empty string will be written to clipboard. | | `CopyComponent` \/ `DoneComponent` \/ `CancelComponent` (canary) | `React.FC` \/ `React.Component` `<{ onClick: (event: React.MouseEvent) => void; className: string ; style: React.CSSProperties}>` | - | Customize copy icon. | | `CopiedComponent` (canary) | `React.FC` \/ `React.Component` `<{ className: string; style: React.CSSProperties }>` | - | Customize copied icon. | +| `CustomOperation` | `React.FC` \/ `React.Component` `<{ node: any }>` | - | Custom Operation | ### Collapsed function ```ts diff --git a/src/components/json-node.tsx b/src/components/json-node.tsx index 066eb96..0095ca9 100644 --- a/src/components/json-node.tsx +++ b/src/components/json-node.tsx @@ -34,7 +34,7 @@ interface Props { export default function JsonNode({ node, depth, deleteHandle: _deleteHandle, indexOrName, parent, editHandle }: Props) { // prettier-ignore - const { collapseStringsAfterLength, enableClipboard, editable, src, onDelete, onChange, customizeNode, matchesURL, urlRegExp, EditComponent, DoneComponent, CancelComponent } = useContext(JsonViewContext) + const { collapseStringsAfterLength, enableClipboard, editable, src, onDelete, onChange, customizeNode, matchesURL, urlRegExp, EditComponent, DoneComponent, CancelComponent, CustomOperation } = useContext(JsonViewContext) let customReturn: ReturnType | undefined if (typeof customizeNode === 'function') customReturn = safeCall(customizeNode, [{ node, depth, indexOrName }]) @@ -124,14 +124,12 @@ export default function JsonNode({ node, depth, deleteHandle: _deleteHandle, ind ) const isEditing = editing || deleting - const ctrlClick = !isEditing && editableEdit(editable) && customEdit(customReturn as CustomizeOptions | undefined) && editHandle ? (event: React.MouseEvent) => { if (event.ctrlKey || event.metaKey) edit() } : undefined - const Icons = ( <> {isEditing && @@ -166,6 +164,7 @@ export default function JsonNode({ node, depth, deleteHandle: _deleteHandle, ind {!isEditing && editableDelete(editable) && customDelete(customReturn as CustomizeOptions | undefined) && _deleteHandle && ( setDeleting(true)} /> )} + { typeof CustomOperation === 'function' ? : null } ) diff --git a/src/components/json-view.tsx b/src/components/json-view.tsx index d3ad27a..32e8555 100644 --- a/src/components/json-view.tsx +++ b/src/components/json-view.tsx @@ -68,6 +68,10 @@ export const JsonViewContext = createContext({ | React.FC<{ onClick: (event: React.MouseEvent) => void; className: string; style: React.CSSProperties }> | React.Component<{ onClick: (event: React.MouseEvent) => void; className: string; style: React.CSSProperties }> | undefined, + CustomOperation: undefined as + | React.FC<{ node: any }> + | React.Component<{ node: any }> + | undefined, }) export interface JsonViewProps { @@ -122,6 +126,10 @@ export interface JsonViewProps { DoneComponent?: | React.FC<{ onClick: (event: React.MouseEvent) => void; className: string; style: React.CSSProperties }> | React.Component<{ onClick: (event: React.MouseEvent) => void; className: string; style: React.CSSProperties }> + + CustomOperation?: + | React.FC<{ node: any }> + | React.Component<{ node: any }> } export default function JsonView({ @@ -165,13 +173,13 @@ export default function JsonView({ EditComponent, CancelComponent, - DoneComponent + DoneComponent, + CustomOperation, }: JsonViewProps) { const [_, update] = useState(0) const forceUpdate = useCallback(() => update(state => ++state), []) const [src, setSrc] = useState(_src) useEffect(() => setSrc(_src), [_src]) - return ( } + { typeof CustomOperation === 'function' ? : null } ) diff --git a/src/components/large-array.tsx b/src/components/large-array.tsx index d1eebb7..cc409f7 100644 --- a/src/components/large-array.tsx +++ b/src/components/large-array.tsx @@ -24,7 +24,7 @@ export default function LargeArray({ node, depth, deleteHandle: _deleteSelf, ind nestCollapsedArray.push(node.slice(i, i + 100)) } - const { collapsed, enableClipboard, collapseObjectsAfterLength, editable, onDelete, src, onAdd, onEdit, onChange, forceUpdate, displaySize } = + const { collapsed, enableClipboard, collapseObjectsAfterLength, editable, onDelete, src, onAdd, CustomOperation, onChange, forceUpdate, displaySize } = useContext(JsonViewContext) const [fold, setFold] = useState(isCollapsed_largeArray(node, depth, indexOrName, collapsed, collapseObjectsAfterLength, customOptions)) @@ -89,6 +89,7 @@ export default function LargeArray({ node, depth, deleteHandle: _deleteSelf, ind {!fold && !isEditing && editableDelete(editable) && customDelete(customOptions) && _deleteSelf && ( setDeleting(true)} /> )} + { typeof CustomOperation === 'function' ? : null } ) diff --git a/src/components/object-node.tsx b/src/components/object-node.tsx index a10b35f..30c1d63 100644 --- a/src/components/object-node.tsx +++ b/src/components/object-node.tsx @@ -33,7 +33,8 @@ export default function ObjectNode({ node, depth, indexOrName, deleteHandle: _de onEdit, onChange, forceUpdate, - displaySize + displaySize, + CustomOperation, } = useContext(JsonViewContext) if (!ignoreLargeArray && Array.isArray(node) && node.length > 100) { @@ -173,6 +174,7 @@ export default function ObjectNode({ node, depth, indexOrName, deleteHandle: _de {!fold && !isEditing && editableDelete(editable) && customDelete(customOptions) && _deleteSelf && ( setDeleting(true)} /> )} + { typeof CustomOperation === 'function' ? : null } )