Skip to content

Commit 833ce61

Browse files
authored
#23 Editable Custom nodes (#25)
1 parent 52a83a1 commit 833ce61

File tree

7 files changed

+257
-199
lines changed

7 files changed

+257
-199
lines changed

README.md

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -366,8 +366,9 @@ Custom nodes are provided in the `customNodeDefinitions` prop, as an array of ob
366366
props, // object (optional)
367367
hideKey, // boolean (optional)
368368
showInTypesSelector, // boolean (optional)
369+
name // string (appears in Types selector)
369370
defaultValue, // JSON value for a new instance of your component
370-
name // string
371+
editable // boolean (optional)
371372
}
372373
```
373374

@@ -378,6 +379,8 @@ The component will receive *all* the same props as a standard node component (se
378379
By default, your component will be presented to the right of the property key it belongs to, like any other value. However, you can hide the key itself by setting `hideKey: true`, and the custom component will take the whole row. (See the "Presented by" box in the "Custom Nodes" data set for an example.)
379380

380381
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.)
382+
383+
Lastly, you can specify whether or not the data inside the node can be edited using the standard editor, with the `editable` prop (default: `true`). If your component includes its own editing interface (e.g. a Date Picker), you might want to disable the standard editor.
381384

382385
## Undo functionality
383386

@@ -403,6 +406,7 @@ This component is heavily inspired by [react-json-view](https://github.com/mac-s
403406

404407
## Changelog
405408

409+
- **1.2.0**: Allow editing of Custom nodes
406410
- **1.1.0**: Don't manage data state within component
407411
- **1.0.0**:
408412
- [Custom nodes](#custom-nodes)

demo/src/data.tsx

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1901,6 +1901,101 @@ const data = {
19011901
},
19021902
],
19031903
},
1904+
// Enable to test more complex features of Custom nodes
1905+
// testCustomNodes: {
1906+
// name: '🔧 Custom Nodes',
1907+
// description: (
1908+
// <Flex flexDir="column" gap={2}>
1909+
// <Text>
1910+
// This data set shows <strong>Custom Nodes</strong> — you can provide your own components to
1911+
// present specialised data in a unique way, or provide a more complex editing mechanism for
1912+
// a specialised data structure, say.
1913+
// </Text>
1914+
// <Text>
1915+
// In this example, compare the raw JSON (edit the data root) with what is presented here.
1916+
// </Text>
1917+
// <Text>
1918+
// See the{' '}
1919+
// <a href="https://github.com/CarlosNZ/json-edit-react#custom-nodes">Custom Nodes</a>{' '}
1920+
// section of the documentation for more info.
1921+
// </Text>
1922+
// </Flex>
1923+
// ),
1924+
// rootName: 'Superheroes',
1925+
// collapse: 2,
1926+
// data: [
1927+
// {
1928+
// name: 'Steve Rogers',
1929+
// aliases: ['Captain America', 'The First Avenger'],
1930+
// logo: 'https://logos-world.net/wp-content/uploads/2023/05/Captain-America-Logo.png',
1931+
// actor: 'Chris Evans',
1932+
// publisher: 'Marvel',
1933+
// },
1934+
// {
1935+
// name: 'Clark Kent',
1936+
// aliases: ['Superman', 'Man of Steel', 'Son of Krypton'],
1937+
// logo: 'https://upload.wikimedia.org/wikipedia/commons/thumb/e/ea/Superman_shield.svg/2560px-Superman_shield.svg.png',
1938+
// actor: 'Henry Cavill',
1939+
// publisher: 'D.C. Comics',
1940+
// },
1941+
// ],
1942+
// customNodeDefinitions: [
1943+
// {
1944+
// condition: ({ key, value }) =>
1945+
// key === 'logo' &&
1946+
// typeof value === 'string' &&
1947+
// value.startsWith('http') &&
1948+
// value.endsWith('.png'),
1949+
// element: ({ data }) => {
1950+
// const truncate = (string: string, length = 50) =>
1951+
// string.length < length ? string : `${string.slice(0, length - 2).trim()}...`
1952+
// return (
1953+
// <div style={{ maxWidth: 250 }}>
1954+
// <a href={data} target="_blank">
1955+
// <img src={data} style={{ maxHeight: 75 }} />
1956+
// <p style={{ fontSize: '0.75em' }}>{truncate(data)}</p>{' '}
1957+
// </a>
1958+
// </div>
1959+
// )
1960+
// },
1961+
// },
1962+
// {
1963+
// condition: ({ key }) => key === 'publisher',
1964+
// element: ({ data }) => {
1965+
// return (
1966+
// <p
1967+
// style={{
1968+
// padding: '0.5em 1em',
1969+
// border: '2px solid red',
1970+
// borderRadius: '1.5em',
1971+
// backgroundColor: 'yellow',
1972+
// marginTop: '0.5em',
1973+
// marginRight: '1em',
1974+
// fontFamily: 'sans-serif',
1975+
// }}
1976+
// >
1977+
// Presented by: <strong>{data}</strong>
1978+
// </p>
1979+
// )
1980+
// },
1981+
// hideKey: true,
1982+
// editable: false,
1983+
// },
1984+
// {
1985+
// condition: ({ key }) => key === 'aliases',
1986+
// element: ({ data }) => {
1987+
// return (
1988+
// <ol style={{ paddingLeft: 50, color: 'orange' }}>
1989+
// {data.map((val) => (
1990+
// <li>{val}</li>
1991+
// ))}
1992+
// </ol>
1993+
// )
1994+
// },
1995+
// // hideKey: true,
1996+
// },
1997+
// ],
1998+
// },
19041999
}
19052000

19062001
export default data

0 commit comments

Comments
 (0)