{error && (
diff --git a/src/CustomNode.ts b/src/CustomNode.ts
index fd051d0a..082ae89e 100644
--- a/src/CustomNode.ts
+++ b/src/CustomNode.ts
@@ -30,7 +30,7 @@ export const getCustomNode = (
showEditTools = true,
showOnEdit = false,
showOnView = true,
- showCollectionWrapper = false,
+ showCollectionWrapper = true,
...rest
} = matchingDefinitions[0]
diff --git a/src/ValueNodeWrapper.tsx b/src/ValueNodeWrapper.tsx
index 50b29dfe..2332c959 100644
--- a/src/ValueNodeWrapper.tsx
+++ b/src/ValueNodeWrapper.tsx
@@ -173,8 +173,6 @@ export const ValueNodeWrapper: React.FC = (props) => {
showOnView,
} = customNodeData
- console.log('Value custom', CustomNode)
-
// Include custom node options in dataType list
const allDataTypes = [
...DataTypes,
From 1d6fe9fce9dbaaa0dac28558e2ae28cef30f8970 Mon Sep 17 00:00:00 2001
From: Carl Smith <5456533+CarlosNZ@users.noreply.github.com>
Date: Wed, 6 Mar 2024 15:58:20 +1300
Subject: [PATCH 3/6] Update docs
---
README.md | 11 ++++++++++-
src/CollectionNode.tsx | 6 +++---
src/types.ts | 2 +-
3 files changed, 14 insertions(+), 5 deletions(-)
diff --git a/README.md b/README.md
index f84e04c6..2b41bbf2 100644
--- a/README.md
+++ b/README.md
@@ -32,6 +32,7 @@ Features include:
- [Icons](#icons)
- [Localisation](#localisation)
- [Custom Nodes](#custom-nodes)
+ - [Custom Collection nodes](#custom-collection-nodes)
- [Active hyperlinks](#active-hyperlinks)
- [Custom Text](#custom-text)
- [Undo functionality](#undo-functionality)
@@ -423,10 +424,12 @@ Custom nodes are provided in the `customNodeDefinitions` prop, as an array of ob
showEditTools // boolean, default true
name // string (appears in Types selector)
showInTypesSelector, // boolean (optional), default false
+ // Only affects Collection nodes:
+ showCollectionWrapper // boolean (optional), default true
}
```
-The `condition` is just a [Filter function](#filter-functions), with the same input parameters (`key`, `path`, `level`, `value`, `size`), and `element` is a React component. Every node in the data structure will be run through each condition function, and any that match will be replaced by your custom component. Note that if a node matches more than one custom definition conditions (from multiple components), the *first* one will be used, so place them in the array in priority order.
+The `condition` is just a [Filter function](#filter-functions), with the same input parameters (`key`, `path`, `value`, etc.), and `element` is a React component. Every node in the data structure will be run through each condition function, and any that match will be replaced by your custom component. Note that if a node matches more than one custom definition conditions (from multiple components), the *first* one will be used, so place them in the array in priority order.
The component will receive *all* the same props as a standard node component (see codebase), but you can pass additional props to your component if required through the `customNodeProps` object. A thorough example of a custom Date picker is used in the demo (along with a couple of other more basic presentational ones), which you can inspect to see how to utilise the standard props and a couple of custom props. View the source code [here](https://github.com/CarlosNZ/json-edit-react/blob/main/demo/src/customComponents/DateTimePicker.tsx)
@@ -436,6 +439,12 @@ Also, by default, your component will be treated as a "display" element, i.e. it
You can allow users to create new instances of your special nodes by selecting them as a "Type" in the types selector when editing/adding values. Set `showInTypesSelector: true` to enable this. However, if this is enabled you need to also provide a `name` (which is what the user will see in the selector) and a `defaultValue` which is the data that is inserted when the user selects this "type". (The `defaultValue` must return `true` if passed through the `condition` function in order for it to be immediately displayed using your custom component.)
+### Custom Collection nodes
+
+In most cases it will be preferable to create custom nodes to match *value* nodes (i.e. not `array` or `object` *collection* nodes). However, if you do wish to replace a whole collection, there are a couple of other things to know:
+- The descendants of this node can still be displayed using the [React `children`](https://react.dev/learn/passing-props-to-a-component#passing-jsx-as-children) property, it just becomes your component's responsibility to handle it.
+- There is one additional prop, `showCollectionWrapper` (default `true`), which, when set to `false` hides the surrounding "wrapper", namely the hide/show chevron and the brackets. In this case, you would have to provide your own hide/show mechanism in your component.
+
### Active hyperlinks
A simple custom component and definition to turn url strings into clickable links is provided with the main package for you to use out of the box. Just import and use like so:
diff --git a/src/CollectionNode.tsx b/src/CollectionNode.tsx
index 63bf022b..e4845095 100644
--- a/src/CollectionNode.tsx
+++ b/src/CollectionNode.tsx
@@ -267,9 +267,9 @@ export const CollectionNode: React.FC = ({
showCollectionWrapper = true,
} = getCustomNode(customNodeDefinitions, nodeData)
- // If the collection wrapper (expand icon, brackets) are hidden, there's no
- // way to open a collapsed custom node, so this ensures it will stay open. It
- // can still be displayed collapsed by handling it internally if this is
+ // If the collection wrapper (expand icon, brackets, etc) is hidden, there's
+ // no way to open a collapsed custom node, so this ensures it will stay open.
+ // It can still be displayed collapsed by handling it internally if this is
// desired.
const isCollapsed = !showCollectionWrapper ? false : collapsed
diff --git a/src/types.ts b/src/types.ts
index 71a6bf59..85c60cc4 100644
--- a/src/types.ts
+++ b/src/types.ts
@@ -155,7 +155,7 @@ export interface CustomNodeProps> extends BaseNodePr
isEditing: boolean
setIsEditing: React.Dispatch>
getStyles: (element: ThemeableElement, nodeData: NodeData) => React.CSSProperties
- children: React.ReactElement[] | null
+ children?: JSX.Element[] | null
}
export interface CustomNodeDefinition> {
From 8e366dfcca364dd1450c49f3e67edf6d02a59af4 Mon Sep 17 00:00:00 2001
From: Carl Smith <5456533+CarlosNZ@users.noreply.github.com>
Date: Wed, 6 Mar 2024 18:48:38 +1300
Subject: [PATCH 4/6] Tweak demo
---
demo/src/App.tsx | 24 +++++++++++++++++++-----
demo/src/demoData/dataDefinitions.tsx | 9 ++++++---
src/Icons.tsx | 3 ++-
3 files changed, 27 insertions(+), 9 deletions(-)
diff --git a/demo/src/App.tsx b/demo/src/App.tsx
index cce935b7..e7656044 100644
--- a/demo/src/App.tsx
+++ b/demo/src/App.tsx
@@ -87,19 +87,25 @@ function App() {
const restrictEdit: FilterFunction | boolean = (() => {
const customRestrictor = demoData[selectedData]?.restrictEdit
- if (customRestrictor) return (input) => !allowEdit || customRestrictor(input)
+ if (typeof customRestrictor === 'function')
+ return (input) => !allowEdit || customRestrictor(input)
+ if (customRestrictor !== undefined) return customRestrictor
return !allowEdit
})()
const restrictDelete: FilterFunction | boolean = (() => {
const customRestrictor = demoData[selectedData]?.restrictDelete
- if (customRestrictor) return (input) => !allowDelete || customRestrictor(input)
+ if (typeof customRestrictor === 'function')
+ return (input) => !allowDelete || customRestrictor(input)
+ if (customRestrictor !== undefined) return customRestrictor
return !allowDelete
})()
const restrictAdd: FilterFunction | boolean = (() => {
const customRestrictor = demoData[selectedData]?.restrictAdd
- if (customRestrictor) return (input) => !allowAdd || customRestrictor(input)
+ if (typeof customRestrictor === 'function')
+ return (input) => !allowAdd || customRestrictor(input)
+ if (customRestrictor !== undefined) return customRestrictor
return !allowAdd
})()
@@ -277,7 +283,7 @@ function App() {
keySort={sortKeys}
defaultValue={demoData[selectedData]?.defaultValue ?? defaultNewValue}
showArrayIndices={showIndices}
- minWidth={450}
+ minWidth={'min(500px, 95vw)'}
maxWidth="min(650px, 90vw)"
className="block-shadow"
stringTruncate={90}
@@ -434,6 +440,7 @@ function App() {
setAllowEdit(!allowEdit)}
w="50%"
>
@@ -441,6 +448,7 @@ function App() {
setAllowDelete(!allowDelete)}
w="50%"
>
@@ -448,7 +456,12 @@ function App() {
- setAllowAdd(!allowAdd)} w="50%">
+ setAllowAdd(!allowAdd)}
+ w="50%"
+ >
Allow Add
setDefaultNewValue(e.target.value)}
diff --git a/demo/src/demoData/dataDefinitions.tsx b/demo/src/demoData/dataDefinitions.tsx
index c6dfbe01..d00644cf 100644
--- a/demo/src/demoData/dataDefinitions.tsx
+++ b/demo/src/demoData/dataDefinitions.tsx
@@ -26,9 +26,9 @@ interface DemoData {
data: object
rootName?: string
collapse?: number
- restrictEdit?: FilterFunction
- restrictDelete?: FilterFunction
- restrictAdd?: FilterFunction
+ restrictEdit?: boolean | FilterFunction
+ restrictDelete?: boolean | FilterFunction
+ restrictAdd?: boolean | FilterFunction
restrictTypeSelection?: boolean | DataType[]
searchFilter?: 'key' | 'value' | 'all' | SearchFilterFunction
searchPlaceholder?: string
@@ -438,6 +438,9 @@ export const demoData: Record = {
},
searchPlaceholder: 'Search by character name',
data: data.customNodes,
+ restrictEdit: ({ level }) => level > 0,
+ restrictAdd: true,
+ restrictDelete: true,
customNodeDefinitions: [
{
condition: ({ key, value }) =>
diff --git a/src/Icons.tsx b/src/Icons.tsx
index 71cd2c8d..06278594 100644
--- a/src/Icons.tsx
+++ b/src/Icons.tsx
@@ -34,6 +34,7 @@ export const IconEdit: React.FC = ({ size, style, className }): JSX.E
height={size}
className={className}
style={style}
+ transform="translate(0, 0.5)"
>
@@ -143,7 +144,7 @@ export const Icon: React.FC = ({ name, nodeData, rotate }): JSX
case 'delete':
return (
icons?.delete ?? (
-
+
)
)
case 'copy':
From 4d2b38c7c5d46da91d18a6039707b38df3845f75 Mon Sep 17 00:00:00 2001
From: Carl Smith <5456533+CarlosNZ@users.noreply.github.com>
Date: Wed, 6 Mar 2024 18:51:59 +1300
Subject: [PATCH 5/6] Update README.md
---
README.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/README.md b/README.md
index 2b41bbf2..4f353d4f 100644
--- a/README.md
+++ b/README.md
@@ -443,7 +443,7 @@ You can allow users to create new instances of your special nodes by selecting t
In most cases it will be preferable to create custom nodes to match *value* nodes (i.e. not `array` or `object` *collection* nodes). However, if you do wish to replace a whole collection, there are a couple of other things to know:
- The descendants of this node can still be displayed using the [React `children`](https://react.dev/learn/passing-props-to-a-component#passing-jsx-as-children) property, it just becomes your component's responsibility to handle it.
-- There is one additional prop, `showCollectionWrapper` (default `true`), which, when set to `false` hides the surrounding "wrapper", namely the hide/show chevron and the brackets. In this case, you would have to provide your own hide/show mechanism in your component.
+- There is one additional prop, `showCollectionWrapper` (default `true`), which, when set to `false`, hides the surrounding "wrapper", namely the hide/show chevron and the brackets. In this case, you would have to provide your own hide/show mechanism in your component.
### Active hyperlinks
From a435827d8297792c65ebf48f5c57041da67b81e5 Mon Sep 17 00:00:00 2001
From: Carl Smith <5456533+CarlosNZ@users.noreply.github.com>
Date: Wed, 6 Mar 2024 18:54:52 +1300
Subject: [PATCH 6/6] Update JsonEditImport.ts
---
demo/src/JsonEditImport.ts | 43 ++++++++++----------------------------
1 file changed, 11 insertions(+), 32 deletions(-)
diff --git a/demo/src/JsonEditImport.ts b/demo/src/JsonEditImport.ts
index 3389e0d9..233596c8 100644
--- a/demo/src/JsonEditImport.ts
+++ b/demo/src/JsonEditImport.ts
@@ -1,33 +1,12 @@
-import {
- JsonEditor,
- themes,
- Theme,
- ThemeName,
- ThemeInput,
- CustomNodeProps,
- CustomNodeDefinition,
- CustomTextDefinitions,
- FilterFunction,
- LinkCustomComponent,
- LinkCustomNodeDefinition,
- matchNode,
- assign,
-} from './json-edit-react/src'
-// } from 'json-edit-react'
-// } from './package'
+/**
+ * Quickly switch between importing from local src or installed package
+ */
-export {
- JsonEditor,
- themes,
- type Theme,
- type ThemeName,
- type ThemeInput,
- type CustomNodeProps,
- type CustomNodeDefinition,
- type CustomTextDefinitions,
- type FilterFunction,
- LinkCustomComponent,
- LinkCustomNodeDefinition,
- matchNode,
- assign,
-}
+/* Installed package */
+// export * from 'json-edit-react'
+
+/* Local src */
+export * from './json-edit-react/src'
+
+/* Compiled local package */
+// export * from './package'