From e11aad60c9dae7e3945617486e35ae4d925a08e3 Mon Sep 17 00:00:00 2001 From: Carl Smith <5456533+CarlosNZ@users.noreply.github.com> Date: Tue, 18 Feb 2025 11:31:16 +1300 Subject: [PATCH] Add viewOnly prop --- README.md | 3 ++- demo/src/App.tsx | 1 + src/JsonEditor.tsx | 27 ++++++++++++++++++++++----- src/types.ts | 1 + 4 files changed, 26 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index e39cc716..d731d49b 100644 --- a/README.md +++ b/README.md @@ -148,6 +148,7 @@ The only *required* property is `data` (although you will need to provide a `set | `restrictAdd` | `boolean\|FilterFunction` | `false` | As with `restrictEdit` but for adding new properties | | `restrictTypeSelection` | `boolean\|DataType[]\|TypeFilterFunction` | `false` | For restricting the data types the user can select. Can be a list of data types (e.g. `[ 'string', 'number', 'boolean', 'array', 'object', 'null' ]`), a boolean. or a function — see [TypeFilterFunction](#typefilterfunction) | | `restrictDrag` | `boolean\|FilterFunction` | `true` | Set to `false` to enable drag and drop functionality — see [Drag-n-drop](#drag-n-drop) | +| `viewOnly` | `boolean` | | A shorthand if you just want the component to be a viewer, with no editing. Overrides any values of the above edit restrictions. | ### Look and Feel / UI @@ -329,7 +330,7 @@ For restricting data types, the (Type) filter function is slightly more sophisti - `"object"` - `"array"` -There is no specific restriction function for editing object key names, but they must return `true` for *both* `restrictEdit` and `restrictDelete` (and `restrictAdd` for collections), since changing a key name is equivalent to deleting a property and adding a new one. +There is no specific restriction function for editing object key names, but they must return `false` for *both* `restrictEdit` and `restrictDelete` (and `restrictAdd` for collections), since changing a key name is equivalent to deleting a property and adding a new one. You can also set a dynamic default value by passing a filter function to the `defaultValue` prop -- the input is the same as the above, but also takes the new `key` value as its second parameter, so the new value can depend on the new key added. diff --git a/demo/src/App.tsx b/demo/src/App.tsx index 6fd60a17..18356b40 100644 --- a/demo/src/App.tsx +++ b/demo/src/App.tsx @@ -382,6 +382,7 @@ function App() { } : false } + // viewOnly restrictEdit={restrictEdit} // restrictEdit={(nodeData) => !(typeof nodeData.value === 'string')} restrictDelete={restrictDelete} diff --git a/src/JsonEditor.tsx b/src/JsonEditor.tsx index 0a7f44c0..26ed5d19 100644 --- a/src/JsonEditor.tsx +++ b/src/JsonEditor.tsx @@ -51,6 +51,7 @@ const Editor: React.FC = ({ restrictAdd = false, restrictTypeSelection = false, restrictDrag = true, + viewOnly, searchFilter: searchFilterInput, searchText, searchDebounceTime = 350, @@ -249,10 +250,22 @@ const Editor: React.FC = ({ }) } - const restrictEditFilter = useMemo(() => getFilterFunction(restrictEdit), [restrictEdit]) - const restrictDeleteFilter = useMemo(() => getFilterFunction(restrictDelete), [restrictDelete]) - const restrictAddFilter = useMemo(() => getFilterFunction(restrictAdd), [restrictAdd]) - const restrictDragFilter = useMemo(() => getFilterFunction(restrictDrag), [restrictDrag]) + const restrictEditFilter = useMemo( + () => getFilterFunction(restrictEdit, viewOnly), + [restrictEdit, viewOnly] + ) + const restrictDeleteFilter = useMemo( + () => getFilterFunction(restrictDelete, viewOnly), + [restrictDelete, viewOnly] + ) + const restrictAddFilter = useMemo( + () => getFilterFunction(restrictAdd, viewOnly), + [restrictAdd, viewOnly] + ) + const restrictDragFilter = useMemo( + () => getFilterFunction(restrictDrag, viewOnly), + [restrictDrag, viewOnly] + ) const searchFilter = useMemo(() => getSearchFilter(searchFilterInput), [searchFilterInput]) const fullKeyboardControls = useMemo( @@ -426,7 +439,11 @@ const updateDataObject = ( } } -const getFilterFunction = (propValue: boolean | number | FilterFunction): FilterFunction => { +const getFilterFunction = ( + propValue: boolean | number | FilterFunction, + viewOnly?: boolean +): FilterFunction => { + if (viewOnly) return () => true if (typeof propValue === 'boolean') return () => propValue if (typeof propValue === 'number') return ({ level }) => level >= propValue return propValue diff --git a/src/types.ts b/src/types.ts index 5c905811..9529bf0f 100644 --- a/src/types.ts +++ b/src/types.ts @@ -28,6 +28,7 @@ export interface JsonEditorProps { restrictAdd?: boolean | FilterFunction restrictTypeSelection?: boolean | DataType[] | TypeFilterFunction restrictDrag?: boolean | FilterFunction + viewOnly?: boolean searchText?: string searchFilter?: 'key' | 'value' | 'all' | SearchFilterFunction searchDebounceTime?: number