From a9628fcd8d6e9a3a4eb46908eac0cc741905a397 Mon Sep 17 00:00:00 2001 From: jaywcjlove <398188662@qq.com> Date: Mon, 17 Jul 2023 16:50:32 +0800 Subject: [PATCH] feat: `onEdit event function returns `namespace`. (#6) --- core/README.md | 6 ++ core/src/editor/index.tsx | 29 ++++++---- core/src/editor/objectKey.tsx | 68 ++++++++++++++++------ core/src/editor/value.tsx | 69 +++++++++++++++------- core/src/node.tsx | 105 +++++++++++++++++++++++++--------- core/src/semicolon.tsx | 46 +++++++++------ core/src/value.tsx | 85 +++++++++++++++++---------- package.json | 4 +- 8 files changed, 284 insertions(+), 128 deletions(-) diff --git a/core/README.md b/core/README.md index 75ef363e..c5a97976 100644 --- a/core/README.md +++ b/core/README.md @@ -530,6 +530,11 @@ export default function Demo() { }} onEdit={(opts) => { console.log('opts:', opts) + // opts.namespace: ['object', 'child', 'last'] + // opts.oldValue: null + // opts.type: "value" + // opts.value: "NULL3" + return true; }} components={{ objectKey: ObjectKey @@ -756,6 +761,7 @@ export interface JsonViewEditorProps extends JsonViewProps oldValue: unknown; keyName?: string | number; parentName?: string | number; + namespace?: Array; type?: 'value' | 'key'; }) => boolean; /** diff --git a/core/src/editor/index.tsx b/core/src/editor/index.tsx index 53d87886..1b866a89 100644 --- a/core/src/editor/index.tsx +++ b/core/src/editor/index.tsx @@ -8,7 +8,7 @@ import type { CountInfoExtraProps } from './countInfoExtra'; export interface JsonViewEditorProps extends JsonViewProps { /** - * When a callback function is passed in, edit functionality is enabled. The callback is invoked before edits are completed. + * When a callback function is passed in, edit functionality is enabled. The callback is invoked before edits are completed. * @returns {boolean} Returning false from onEdit will prevent the change from being made. */ onEdit?: (option: { @@ -16,6 +16,7 @@ export interface JsonViewEditorProps extends JsonViewProps oldValue: unknown; keyName?: string | number; parentName?: string | number; + namespace?: Array; type?: 'value' | 'key'; }) => boolean; /** @@ -24,8 +25,8 @@ export interface JsonViewEditorProps extends JsonViewProps */ onAdd?: CountInfoExtraProps['onAdd']; /** - * When a callback function is passed in, delete functionality is enabled. The callback is invoked before deletions are completed. - * @returns Returning false from onDelete will prevent the change from being made. + * When a callback function is passed in, delete functionality is enabled. The callback is invoked before deletions are completed. + * @returns Returning false from onDelete will prevent the change from being made. */ onDelete?: CountInfoExtraProps['onDelete']; /** Whether enable edit feature. @default true */ @@ -37,14 +38,22 @@ const JsonViewEditor = forwardRef>(( const comps: JsonViewEditorProps['components'] = { ...components, countInfoExtra: (reprops) => , - objectKey: (reprops) => , + objectKey: (reprops) => ( + + ), value: (reprops) => { - return - } - } - return ( - - ); + return ( + + ); + }, + }; + return ; }); export default JsonViewEditor; diff --git a/core/src/editor/objectKey.tsx b/core/src/editor/objectKey.tsx index 49f48279..36b8eaac 100644 --- a/core/src/editor/objectKey.tsx +++ b/core/src/editor/objectKey.tsx @@ -10,8 +10,21 @@ export interface ObjectKeyProps extends SemicolonProps { editableValue?: boolean; } -export const ObjectKey: FC>= (props) => { - const { className, value, keyName, parentName, quotes, label, editableValue, onEdit, highlightUpdates = true, render, ...reset } = props; +export const ObjectKey: FC> = (props) => { + const { + className, + value, + keyName, + parentName, + quotes, + label, + namespace, + editableValue, + onEdit, + highlightUpdates = true, + render, + ...reset + } = props; const [editable, setEditable] = useState(false); const [curentLabel, setCurentLabel] = useState(label); useEffect(() => setCurentLabel(label), [label]); @@ -27,37 +40,50 @@ export const ObjectKey: FC>= (props) => { $edit.current!.contentEditable = 'true'; $edit.current?.focus(); } - } + }; - const blur = () => { - setEditable(false); + const blur = async () => { if ($edit.current) { + if (onEdit) { + const result = await onEdit({ + value: $edit.current.innerText, + oldValue: curentLabel as string, + namespace, + keyName, + parentName, + type: 'key', + }); + if (result) { + setCurentLabel($edit.current.innerText); + } else { + $edit.current.innerText = curentLabel as string; + } + } $edit.current.contentEditable = 'false'; $edit.current?.focus(); - setCurentLabel($edit.current.innerText); - onEdit && onEdit({ value: $edit.current.innerText, oldValue: curentLabel as string, keyName, parentName, type: 'key' }); } - } + setEditable(false); + }; const focus = () => { if ($edit.current) { $edit.current.contentEditable = 'true'; $edit.current?.focus(); } - } + }; const keyDown = (evn: React.KeyboardEvent) => { if (evn.key === 'Enter') { evn.stopPropagation(); evn.preventDefault(); $edit.current!.contentEditable = 'false'; } - } + }; useEffect(() => { if ($edit.current) { - $edit.current.addEventListener("paste", (e) => { + $edit.current.addEventListener('paste', (e) => { e.preventDefault(); // @ts-ignore - const text = e.clipboardData.getData("text/plain"); - document.execCommand("insertHTML", false, text); + const text = e.clipboardData.getData('text/plain'); + document.execCommand('insertHTML', false, text); }); } }, [$edit]); @@ -75,15 +101,21 @@ export const ObjectKey: FC>= (props) => { autoFocus: editable, suppressContentEditableWarning: true, children: editable ? curentLabel : content, - } + }; if (render) { spanProps.value = value; spanProps.keyName = keyName; spanProps.parentName = parentName; - return render({ className, ...reset, ...spanProps, parentName, label: curentLabel as string, children: editable ? curentLabel : content, ref: $edit }); + return render({ + className, + ...reset, + ...spanProps, + parentName, + label: curentLabel as string, + children: editable ? curentLabel : content, + ref: $edit, + }); } return