From 06956498187cee99b8eb41613d780b7ef65e45e0 Mon Sep 17 00:00:00 2001 From: Carl Smith <5456533+CarlosNZ@users.noreply.github.com> Date: Thu, 10 Jul 2025 22:46:37 +1200 Subject: [PATCH 1/7] Call `onEditEvent` when adding key --- demo/src/App.tsx | 1 + src/ButtonPanels.tsx | 8 ++++++++ src/CollectionNode.tsx | 2 ++ src/JsonEditor.tsx | 2 ++ src/types.ts | 6 +++++- 5 files changed, 18 insertions(+), 1 deletion(-) diff --git a/demo/src/App.tsx b/demo/src/App.tsx index b7ab2f4..bbb9f24 100644 --- a/demo/src/App.tsx +++ b/demo/src/App.tsx @@ -586,6 +586,7 @@ function App() { : undefined } // collapseClickZones={['property', 'header']} + // onEditEvent={(...args) => console.log('onEditEvent', ...args)} // onEditEvent={(path) => { // console.log(path) // setIsEditing(path ? true : false) diff --git a/src/ButtonPanels.tsx b/src/ButtonPanels.tsx index 98e2c8f..27420f9 100644 --- a/src/ButtonPanels.tsx +++ b/src/ButtonPanels.tsx @@ -12,8 +12,10 @@ import { type CustomButtonDefinition, type KeyboardControlsFull, JsonData, + OnEditEventFunction, } from './types' import { getModifier } from './helpers' +import { on } from 'events' interface EditButtonProps { startEdit?: () => void @@ -36,6 +38,7 @@ interface EditButtonProps { // eslint-disable-next-line replacer?: (this: any, key: string, value: unknown) => string ) => string + onEditEvent?: OnEditEventFunction } export const EditButtons: React.FC = ({ @@ -52,6 +55,7 @@ export const EditButtons: React.FC = ({ editConfirmRef, getNewKeyOptions, jsonStringify, + onEditEvent, }) => { const { getStyles } = useTheme() const NEW_KEY_PROMPT = translate('KEY_NEW', nodeData) @@ -69,6 +73,10 @@ export const EditButtons: React.FC = ({ const hasKeyOptionsList = Array.isArray(addingKeyState) const updateAddingState = (active: boolean) => { + // Add 'null' to the path to indicate that the actual path of where the new + // key will go is not yet known. + if (onEditEvent) onEditEvent([...path, null], active) + if (!active) { setAddingKeyState(false) return diff --git a/src/CollectionNode.tsx b/src/CollectionNode.tsx index 02b01cb..4071318 100644 --- a/src/CollectionNode.tsx +++ b/src/CollectionNode.tsx @@ -47,6 +47,7 @@ export const CollectionNode: React.FC = (props) => { collapseAnimationTime, onMove, enableClipboard, + onEditEvent, searchFilter, searchText, indent, @@ -432,6 +433,7 @@ export const CollectionNode: React.FC = (props) => { getNewKeyOptions={getNewKeyOptions} editConfirmRef={editConfirmRef} jsonStringify={jsonStringify} + onEditEvent={onEditEvent} /> ) diff --git a/src/JsonEditor.tsx b/src/JsonEditor.tsx index 84a10cd..04b2420 100644 --- a/src/JsonEditor.tsx +++ b/src/JsonEditor.tsx @@ -45,6 +45,7 @@ const Editor: React.FC = ({ onAdd: srcAdd = onUpdate, onChange, onError, + onEditEvent, showErrorMessages = true, enableClipboard = true, indent = 2, @@ -348,6 +349,7 @@ const Editor: React.FC = ({ onAdd, onChange, onError, + onEditEvent, showErrorMessages, onMove, showCollectionCount, diff --git a/src/types.ts b/src/types.ts index 27c423a..247a9aa 100644 --- a/src/types.ts +++ b/src/types.ts @@ -177,7 +177,10 @@ export type CompareFunction = ( export type SortFunction = (arr: T[], nodeMap: (input: T) => [string | number, unknown]) => void -export type OnEditEventFunction = (path: CollectionKey[] | string | null, isKey: boolean) => void +export type OnEditEventFunction = ( + path: (CollectionKey | null)[] | string | null, + isKey: boolean +) => void // Definition to externally set Collapse state -- also passed to OnCollapse // function @@ -259,6 +262,7 @@ interface BaseNodeProps { showErrorMessages: boolean onMove: InternalMoveFunction enableClipboard: boolean | CopyFunction + onEditEvent?: OnEditEventFunction restrictEditFilter: FilterFunction restrictDeleteFilter: FilterFunction restrictAddFilter: FilterFunction From 89434827eb315332bd66475cf67d797cc8b3c466 Mon Sep 17 00:00:00 2001 From: Carl Smith <5456533+CarlosNZ@users.noreply.github.com> Date: Thu, 10 Jul 2025 22:49:13 +1200 Subject: [PATCH 2/7] Update ButtonPanels.tsx --- src/ButtonPanels.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/src/ButtonPanels.tsx b/src/ButtonPanels.tsx index 27420f9..8fa9bc1 100644 --- a/src/ButtonPanels.tsx +++ b/src/ButtonPanels.tsx @@ -15,7 +15,6 @@ import { OnEditEventFunction, } from './types' import { getModifier } from './helpers' -import { on } from 'events' interface EditButtonProps { startEdit?: () => void From e35797f9fb671ba4bdb04e6d90487470d6bf375f Mon Sep 17 00:00:00 2001 From: Carl Smith <5456533+CarlosNZ@users.noreply.github.com> Date: Thu, 10 Jul 2025 22:53:31 +1200 Subject: [PATCH 3/7] Update README.md --- README.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 37cc619..b40139b 100644 --- a/README.md +++ b/README.md @@ -1115,11 +1115,14 @@ The `onEditEvent` callback is executed whenever the user starts or stops editing ```ts type OnEditEventFunction = - (path: CollectionKey[] | null, isKey: boolean) => void + (path: (CollectionKey | null)[] | null, isKey: boolean) => void ``` The `path` will be an array representing the path components when starting to edit, and `null` when ending the edit. The `isKey` indicates whether the edit is for the property `key` rather than `value`. +> [!NOTE] +> After clicking the "Add key" button, the `path` in the `onEditEvent` callback will end with a `null` value, indicating that the final path where this key will end up is not yet known. + The `onCollapse` callback is executed when user opens or collapses a node, and has the following signature: ```ts From 8f53dedafd56e6b0187319be3e1bdcc6d8804d86 Mon Sep 17 00:00:00 2001 From: Carl Smith <5456533+CarlosNZ@users.noreply.github.com> Date: Fri, 11 Jul 2025 00:14:31 +1200 Subject: [PATCH 4/7] Update ButtonPanels.tsx --- src/ButtonPanels.tsx | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/ButtonPanels.tsx b/src/ButtonPanels.tsx index 488a4c1..46194a4 100644 --- a/src/ButtonPanels.tsx +++ b/src/ButtonPanels.tsx @@ -76,6 +76,8 @@ export const EditButtons: React.FC = ({ const updateAddingState = (active: boolean) => { // Add 'null' to the path to indicate that the actual path of where the new // key will go is not yet known. + // Also, "active" matches the second "isKey" parameter here, even though it + // describes a different thing. if (onEditEvent) onEditEvent([...path, null], active) if (!active) { From f7a2fb3ae2c71db414e559aa15e4bd1b77ce93b1 Mon Sep 17 00:00:00 2001 From: Carl Smith <5456533+CarlosNZ@users.noreply.github.com> Date: Fri, 11 Jul 2025 00:19:42 +1200 Subject: [PATCH 5/7] Update OnEditEventFunction type signature --- src/contexts/TreeStateProvider.tsx | 2 +- src/types.ts | 5 +---- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/src/contexts/TreeStateProvider.tsx b/src/contexts/TreeStateProvider.tsx index efcf2d8..b54ad3d 100644 --- a/src/contexts/TreeStateProvider.tsx +++ b/src/contexts/TreeStateProvider.tsx @@ -90,7 +90,7 @@ export const TreeStateProvider = ({ children, onEditEvent, onCollapse }: TreeSta cancelOp.current() } setCurrentlyEditingElement(pathString) - if (onEditEvent) onEditEvent(path, newCancelOrKey === 'key') + if (onEditEvent) onEditEvent(path as CollectionKey[], newCancelOrKey === 'key') cancelOp.current = typeof newCancelOrKey === 'function' ? newCancelOrKey : null } diff --git a/src/types.ts b/src/types.ts index db90baf..5ed8fdf 100644 --- a/src/types.ts +++ b/src/types.ts @@ -178,10 +178,7 @@ export type CompareFunction = ( export type SortFunction = (arr: T[], nodeMap: (input: T) => [string | number, unknown]) => void -export type OnEditEventFunction = ( - path: (CollectionKey | null)[] | string | null, - isKey: boolean -) => void +export type OnEditEventFunction = (path: (CollectionKey | null)[] | null, isKey: boolean) => void // Definition to externally set Collapse state -- also passed to OnCollapse // function From ab689370e608207be271fd400848fb220fd36833 Mon Sep 17 00:00:00 2001 From: Carl Smith <5456533+CarlosNZ@users.noreply.github.com> Date: Fri, 11 Jul 2025 00:25:15 +1200 Subject: [PATCH 6/7] Fix "path" when submitting key --- src/ButtonPanels.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ButtonPanels.tsx b/src/ButtonPanels.tsx index 46194a4..48916ce 100644 --- a/src/ButtonPanels.tsx +++ b/src/ButtonPanels.tsx @@ -78,7 +78,7 @@ export const EditButtons: React.FC = ({ // key will go is not yet known. // Also, "active" matches the second "isKey" parameter here, even though it // describes a different thing. - if (onEditEvent) onEditEvent([...path, null], active) + if (onEditEvent) onEditEvent(active ? [...path, null] : null, active) if (!active) { setAddingKeyState(false) From 1fc78ed7bf06a8da012333278beb280b627d4b43 Mon Sep 17 00:00:00 2001 From: Carl Smith <5456533+CarlosNZ@users.noreply.github.com> Date: Fri, 11 Jul 2025 00:30:28 +1200 Subject: [PATCH 7/7] Update TreeStateProvider.tsx --- src/contexts/TreeStateProvider.tsx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/contexts/TreeStateProvider.tsx b/src/contexts/TreeStateProvider.tsx index b54ad3d..736ce01 100644 --- a/src/contexts/TreeStateProvider.tsx +++ b/src/contexts/TreeStateProvider.tsx @@ -90,7 +90,8 @@ export const TreeStateProvider = ({ children, onEditEvent, onCollapse }: TreeSta cancelOp.current() } setCurrentlyEditingElement(pathString) - if (onEditEvent) onEditEvent(path as CollectionKey[], newCancelOrKey === 'key') + if (onEditEvent && (Array.isArray(path) || path === null)) + onEditEvent(path, newCancelOrKey === 'key') cancelOp.current = typeof newCancelOrKey === 'function' ? newCancelOrKey : null }