From db5ae0ca7bd55b0c7d116c96f6f4980ff8609095 Mon Sep 17 00:00:00 2001 From: Carl Smith <5456533+CarlosNZ@users.noreply.github.com> Date: Fri, 12 Jan 2024 13:06:44 +1300 Subject: [PATCH 1/5] WIP --- demo/src/App.tsx | 4 ++-- src/CustomNodeWrapper.tsx | 1 + src/types.ts | 1 + 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/demo/src/App.tsx b/demo/src/App.tsx index 23fca312..f38d2a67 100644 --- a/demo/src/App.tsx +++ b/demo/src/App.tsx @@ -1,8 +1,8 @@ import React, { useEffect, useRef } from 'react' /* Local version */ -// import { JsonEditor, themes, ThemeName, Theme, ThemeInput } from './json-edit-react/src' +import { JsonEditor, themes, ThemeName, Theme, ThemeInput } from './json-edit-react/src' /* npm version */ -import { JsonEditor, themes, ThemeName, Theme, ThemeInput } from 'json-edit-react' +// import { JsonEditor, themes, ThemeName, Theme, ThemeInput } from 'json-edit-react' import { FaNpm, FaExternalLinkAlt, FaGithub } from 'react-icons/fa' import { BiReset } from 'react-icons/bi' import { AiOutlineCloudUpload } from 'react-icons/ai' diff --git a/src/CustomNodeWrapper.tsx b/src/CustomNodeWrapper.tsx index 18cedfea..270ae7e9 100644 --- a/src/CustomNodeWrapper.tsx +++ b/src/CustomNodeWrapper.tsx @@ -1,6 +1,7 @@ import React from 'react' import { CustomNodeWrapperProps } from './types' import { useTheme } from './theme' +import { EditButtons } from './ButtonPanels' export const CustomNodeWrapper: React.FC = ({ name, diff --git a/src/types.ts b/src/types.ts index 7f98e5b5..5a824f64 100644 --- a/src/types.ts +++ b/src/types.ts @@ -151,6 +151,7 @@ export interface CustomNodeDefinition { hideKey?: boolean defaultValue: unknown showInTypesSelector?: boolean + editable?: boolean } export interface InputProps { From f6111cd661a59d0afc6f9f3d98f237eb37e7c422 Mon Sep 17 00:00:00 2001 From: Carl Smith <5456533+CarlosNZ@users.noreply.github.com> Date: Thu, 25 Jan 2024 09:18:35 +1300 Subject: [PATCH 2/5] WIP --- demo/src/App.tsx | 2 +- demo/src/data.tsx | 93 ++++++++++++++++++++++++++++++++++++++++ src/ValueNodeWrapper.tsx | 14 +++--- 3 files changed, 101 insertions(+), 8 deletions(-) diff --git a/demo/src/App.tsx b/demo/src/App.tsx index f38d2a67..b595f5b1 100644 --- a/demo/src/App.tsx +++ b/demo/src/App.tsx @@ -41,7 +41,7 @@ import { FilterFunction } from './json-edit-react/src/types' import { version } from './version' function App() { - const [selectedData, setSelectedData] = useState('basic') + const [selectedData, setSelectedData] = useState('test') const [rootName, setRootName] = useState(demoData[selectedData].rootName ?? 'data') const [indent, setIndent] = useState(4) const [collapseLevel, setCollapseLevel] = useState(2) diff --git a/demo/src/data.tsx b/demo/src/data.tsx index fa39080a..8b0e5e61 100644 --- a/demo/src/data.tsx +++ b/demo/src/data.tsx @@ -2,6 +2,99 @@ import React from 'react' import { Flex, Box, Link, Text } from '@chakra-ui/react' const data = { + test: { + name: '🔧 Custom Nodes', + description: ( + + + This data set shows Custom Nodes — you can provide your own components to + present specialised data in a unique way, or provide a more complex editing mechanism for + a specialised data structure, say. + + + In this example, compare the raw JSON (edit the data root) with what is presented here. + + + See the{' '} + Custom Nodes{' '} + section of the documentation for more info. + + + ), + rootName: 'Superheroes', + collapse: 2, + data: [ + { + name: 'Steve Rogers', + aliases: ['Captain America', 'The First Avenger'], + logo: 'https://logos-world.net/wp-content/uploads/2023/05/Captain-America-Logo.png', + actor: 'Chris Evans', + publisher: 'Marvel', + }, + { + name: 'Clark Kent', + aliases: ['Superman', 'Man of Steel', 'Son of Krypton'], + logo: 'https://upload.wikimedia.org/wikipedia/commons/thumb/e/ea/Superman_shield.svg/2560px-Superman_shield.svg.png', + actor: 'Henry Cavill', + publisher: 'D.C. Comics', + }, + ], + customNodeDefinitions: [ + { + condition: ({ key, value }) => + key === 'logo' && + typeof value === 'string' && + value.startsWith('http') && + value.endsWith('.png'), + element: ({ data }) => { + const truncate = (string: string, length = 50) => + string.length < length ? string : `${string.slice(0, length - 2).trim()}...` + return ( +
+ + +

{truncate(data)}

{' '} +
+
+ ) + }, + }, + { + condition: ({ key }) => key === 'publisher', + element: ({ data }) => { + return ( +

+ Presented by: {data} +

+ ) + }, + hideKey: true, + }, + { + condition: ({ key }) => key === 'aliases', + element: ({ data }) => { + return ( +
    + {data.map((val) => ( +
  1. {val}
  2. + ))} +
+ ) + }, + hideKey: true, + }, + ], + }, basic: { name: '🔰 Basic', description: ( diff --git a/src/ValueNodeWrapper.tsx b/src/ValueNodeWrapper.tsx index 30750205..f76d0e8d 100644 --- a/src/ValueNodeWrapper.tsx +++ b/src/ValueNodeWrapper.tsx @@ -176,11 +176,7 @@ export const ValueNodeWrapper: React.FC = (props) => { return result }, [filterProps, restrictTypeSelection]) - return CustomNode ? ( - - - - ) : ( + return (
= (props) => { flexWrap: (name as string).length > 10 ? 'wrap' : 'nowrap', }} > - {showLabel && !isEditingKey && ( + {showLabel && !isEditingKey && !hideKey && (