From a68d03185bc4ad0d38f503b8ce134d4d0652e398 Mon Sep 17 00:00:00 2001 From: Carl Smith <5456533+CarlosNZ@users.noreply.github.com> Date: Fri, 6 Jun 2025 22:09:51 +1200 Subject: [PATCH 1/6] Evaluate custom nodes in parent, create "Enhanced Link" component --- .../components/DateObject/definition.ts | 1 + .../components/EnhancedLink/component.tsx | 97 +++++++++++++++++++ .../components/EnhancedLink/definition.ts | 19 ++++ .../components/EnhancedLink/index.ts | 1 + custom-component-library/components/data.ts | 6 +- custom-component-library/components/index.ts | 1 + custom-component-library/src/App.tsx | 6 ++ src/CollectionNode.tsx | 19 ++-- src/CustomNode.ts | 1 + src/JsonEditor.tsx | 3 + src/ValueNodeWrapper.tsx | 3 +- src/helpers.ts | 2 +- src/types.ts | 3 + 13 files changed, 153 insertions(+), 9 deletions(-) create mode 100644 custom-component-library/components/EnhancedLink/component.tsx create mode 100644 custom-component-library/components/EnhancedLink/definition.ts create mode 100644 custom-component-library/components/EnhancedLink/index.ts diff --git a/custom-component-library/components/DateObject/definition.ts b/custom-component-library/components/DateObject/definition.ts index 2606f3cd..7e90ca1f 100644 --- a/custom-component-library/components/DateObject/definition.ts +++ b/custom-component-library/components/DateObject/definition.ts @@ -9,6 +9,7 @@ export const DateObjectDefinition: CustomNodeDefinition = { name: 'Date Object', // shown in the Type selector menu showInTypesSelector: true, defaultValue: new Date(), + isCollection: false, // IMPORTANT: This component can't be used in conjunction with a ISO string // matcher (such as the DatePicker in this repo) -- because JSON.stringify // automatically serializes Date objects to ISO Strings, there's no way to diff --git a/custom-component-library/components/EnhancedLink/component.tsx b/custom-component-library/components/EnhancedLink/component.tsx new file mode 100644 index 00000000..e3217ddc --- /dev/null +++ b/custom-component-library/components/EnhancedLink/component.tsx @@ -0,0 +1,97 @@ +/** + * An URL display Custom Component + * + * A simple custom node which detects urls in data and makes them active + * hyperlinks. + */ + +import React, { useState } from 'react' +import { toPathString, StringDisplay, StringEdit, type CustomNodeProps } from '@json-edit-react' + +export interface EnhancedLinkProps { + linkStyles?: React.CSSProperties + propertyStyles?: React.CSSProperties + labels?: { text: string; url: string } + fieldNames?: { text: string; url: string } + stringTruncate?: number + [key: string]: unknown +} + +type EnhancedLink = { + [key: string]: string + // url: string +} + +export const EnhancedLinkCustomComponent: React.FC> = ( + props +) => { + const { setIsEditing, getStyles, nodeData, customNodeProps = {}, isEditing, handleEdit } = props + const { + linkStyles = { fontWeight: 'bold', textDecoration: 'underline' }, + propertyStyles = {}, + labels: { text: textLabel, url: urlLabel } = { text: 'Text', url: 'Link' }, + fieldNames: { text: textField, url: urlField } = { text: 'text', url: 'url' }, + stringTruncate = 120, + } = customNodeProps + const [text, setText] = useState((nodeData.value as EnhancedLink)[textField]) + const [url, setUrl] = useState((nodeData.value as EnhancedLink)[urlField]) + + const styles = getStyles('string', nodeData) + + return ( +
{ + if (e.getModifierState('Control') || e.getModifierState('Meta')) setIsEditing(true) + }} + style={styles} + > + {isEditing ? ( +
+
+ {textLabel}: + setText(val)} + /> +
+
+ {urlLabel}: + setUrl(val)} + handleEdit={() => { + handleEdit({ [textField]: text, [urlField]: url }) + }} + /> +
+
+ ) : ( + { + return ( + + {children} + + ) + }} + /> + )} +
+ ) +} diff --git a/custom-component-library/components/EnhancedLink/definition.ts b/custom-component-library/components/EnhancedLink/definition.ts new file mode 100644 index 00000000..79f8d591 --- /dev/null +++ b/custom-component-library/components/EnhancedLink/definition.ts @@ -0,0 +1,19 @@ +import { isCollection, type CustomNodeDefinition } from '@json-edit-react' +import { EnhancedLinkCustomComponent, EnhancedLinkProps } from './component' + +const TEXT_FIELD = 'text' +const URL_FIELD = 'url' + +export const EnhancedLinkCustomNodeDefinition: CustomNodeDefinition = { + condition: ({ value }) => isCollection(value) && TEXT_FIELD in value && URL_FIELD in value, + element: EnhancedLinkCustomComponent, + name: 'Enhanced Link', // shown in the Type selector menu + showInTypesSelector: true, + defaultValue: { + [TEXT_FIELD]: 'This is the text that is displayed', + [URL_FIELD]: 'https://link.goes.here', + }, + customNodeProps: { fieldNames: { text: TEXT_FIELD, url: URL_FIELD } }, + showOnEdit: true, + isCollection: false, +} diff --git a/custom-component-library/components/EnhancedLink/index.ts b/custom-component-library/components/EnhancedLink/index.ts new file mode 100644 index 00000000..75c618f1 --- /dev/null +++ b/custom-component-library/components/EnhancedLink/index.ts @@ -0,0 +1 @@ +export * from './definition' diff --git a/custom-component-library/components/data.ts b/custom-component-library/components/data.ts index 1e49153e..44f4c759 100644 --- a/custom-component-library/components/data.ts +++ b/custom-component-library/components/data.ts @@ -25,11 +25,15 @@ export const testData = { url: 'https://carlosnz.github.io/json-edit-react/', longUrl: 'https://www.google.com/maps/place/Sky+Tower/@-36.8465603,174.7609398,818m/data=!3m1!1e3!4m6!3m5!1s0x6d0d47f06d4bdc25:0x2d1b5c380ad9387!8m2!3d-36.848448!4d174.762191!16zL20vMDFuNXM2?entry=ttu&g_ep=EgoyMDI1MDQwOS4wIKXMDSoASAFQAw%3D%3D', + enhancedLink: { + text: 'This link displays custom text', + url: 'https://github.com/CarlosNZ/json-edit-react/tree/main/custom-component-library#custom-component-library', + }, }, 'Date & Time': { Date: new Date().toISOString(), 'Show Time in Date?': true, - info: 'Date is stored as ISO string. To use JS Date objects, set STORE_DATE_AS_DATE_OBJECT to true in App.tsx.', + info: 'Replaced in App.tsx', }, 'Non-JSON types': { diff --git a/custom-component-library/components/index.ts b/custom-component-library/components/index.ts index 4afae555..e1933a4c 100644 --- a/custom-component-library/components/index.ts +++ b/custom-component-library/components/index.ts @@ -1,4 +1,5 @@ export * from './Hyperlink' +export * from './EnhancedLink' export * from './DateObject' export * from './Undefined' export * from './DatePicker' diff --git a/custom-component-library/src/App.tsx b/custom-component-library/src/App.tsx index 4be3246d..d72837d0 100644 --- a/custom-component-library/src/App.tsx +++ b/custom-component-library/src/App.tsx @@ -12,6 +12,7 @@ import { SymbolDefinition, BigIntDefinition, MarkdownNodeDefinition, + EnhancedLinkCustomNodeDefinition, } from '../components' import { testData } from '../components/data' import { JsonData, JsonEditor } from '@json-edit-react' @@ -19,6 +20,10 @@ import { JsonData, JsonEditor } from '@json-edit-react' // @ts-expect-error redefine after initialisation testData['Date & Time'].Date = STORE_DATE_AS_DATE_OBJECT ? new Date() : new Date().toISOString() +testData['Date & Time'].info = STORE_DATE_AS_DATE_OBJECT + ? 'Date is stored a JS Date object. To use ISO string, set STORE_DATE_AS_DATE_OBJECT to false in App.tsx.' + : 'Date is stored as ISO string. To use JS Date objects, set STORE_DATE_AS_DATE_OBJECT to true in App.tsx.' + type TestData = typeof testData function App() { @@ -38,6 +43,7 @@ function App() { ...(STORE_DATE_AS_DATE_OBJECT ? DateObjectDefinition : DatePickerDefinition), customNodeProps: { showTime: (data as TestData)['Date & Time']['Show Time in Date?'] }, }, + EnhancedLinkCustomNodeDefinition, UndefinedDefinition, BooleanToggleDefinition, NanDefinition, diff --git a/src/CollectionNode.tsx b/src/CollectionNode.tsx index 0712af46..ca5c07d9 100644 --- a/src/CollectionNode.tsx +++ b/src/CollectionNode.tsx @@ -1,4 +1,4 @@ -import React, { useEffect, useState, useMemo, useRef, useCallback } from 'react' +import React, { useEffect, useState, useRef, useCallback } from 'react' import { ValueNodeWrapper } from './ValueNodeWrapper' import { EditButtons, InputButtons } from './ButtonPanels' import { getCustomNode } from './CustomNode' @@ -56,6 +56,7 @@ export const CollectionNode: React.FC = (props) => { newKeyOptions, translate, customNodeDefinitions, + customNodeData, jsonParse, jsonStringify, TextEditor, @@ -163,10 +164,11 @@ export const CollectionNode: React.FC = (props) => { showOnEdit, showOnView, showCollectionWrapper = true, - } = useMemo( - () => getCustomNode(customNodeDefinitions, nodeData), - [nodeData, customNodeDefinitions] - ) + } = customNodeData + // useMemo( + // () => getCustomNode(customNodeDefinitions, nodeData), + // [nodeData, customNodeDefinitions] + // ) const childrenEditing = areChildrenBeingEdited(pathString) @@ -304,13 +306,16 @@ export const CollectionNode: React.FC = (props) => { parentData: data, fullData: nodeData.fullData, } + + const childCustomNodeData = getCustomNode(customNodeDefinitions, childNodeData) + return (
- {isCollection(value) ? ( + {isCollection(value) && childCustomNodeData?.isCollection !== false ? ( = (props) => { nodeData={childNodeData} showCollectionCount={showCollectionCount} canDragOnto={canEdit} + customNodeData={childCustomNodeData} /> ) : ( = (props) => { nodeData={childNodeData} canDragOnto={canEdit} showLabel={collectionType === 'object' ? true : showArrayIndices} + customNodeData={childCustomNodeData} /> )}
diff --git a/src/CustomNode.ts b/src/CustomNode.ts index b266b630..69a821b8 100644 --- a/src/CustomNode.ts +++ b/src/CustomNode.ts @@ -14,6 +14,7 @@ export interface CustomNodeData { showEditTools?: boolean showCollectionWrapper?: boolean passOriginalNode?: boolean + isCollection?: false } // Fetches matching custom nodes (based on condition filter) from custom node diff --git a/src/JsonEditor.tsx b/src/JsonEditor.tsx index 540ab76f..6443e118 100644 --- a/src/JsonEditor.tsx +++ b/src/JsonEditor.tsx @@ -33,6 +33,7 @@ import { getTranslateFunction } from './localisation' import { ValueNodeWrapper } from './ValueNodeWrapper' import './style.css' +import { getCustomNode } from './CustomNode' const Editor: React.FC = ({ data: srcData, @@ -369,6 +370,8 @@ const Editor: React.FC = ({ stringTruncate, translate, customNodeDefinitions, + customNodeData: {}, + // getCustomNode(customNodeDefinitions, nodeData), customButtons, parentData: null, jsonParse: jsonParseReplacement, diff --git a/src/ValueNodeWrapper.tsx b/src/ValueNodeWrapper.tsx index b484f464..abd3855b 100644 --- a/src/ValueNodeWrapper.tsx +++ b/src/ValueNodeWrapper.tsx @@ -43,6 +43,7 @@ export const ValueNodeWrapper: React.FC = (props) => { indent, translate, customNodeDefinitions, + customNodeData, handleKeyboard, keyboardControls, sort, @@ -83,7 +84,7 @@ export const ValueNodeWrapper: React.FC = (props) => { { canDrag, canDragOnto, path, nodeData, onMove, onError, translate } ) - const customNodeData = getCustomNode(customNodeDefinitions, nodeData) + // const customNodeData = getCustomNode(customNodeDefinitions, nodeData) const [dataType, setDataType] = useState(getDataType(data, customNodeData)) const updateValue = useCallback( diff --git a/src/helpers.ts b/src/helpers.ts index 3061e91a..3ef0ec72 100644 --- a/src/helpers.ts +++ b/src/helpers.ts @@ -17,7 +17,7 @@ import { } from './types' export const isCollection = (value: unknown): value is Record | unknown[] => - value !== null && typeof value === 'object' && !(value instanceof Date) + value !== null && typeof value === 'object' export const isJsEvent = (value: unknown) => { return ( diff --git a/src/types.ts b/src/types.ts index db4612f2..b487a43f 100644 --- a/src/types.ts +++ b/src/types.ts @@ -2,6 +2,7 @@ import { type JSX } from 'react' import { type Options as AssignOptions } from 'object-property-assigner' import { type LocalisedStrings, type TranslateFunction } from './localisation' import { type ExternalTriggers } from './hooks' +import { CustomNodeData } from './CustomNode' export type JsonData = Record | Array | unknown @@ -271,6 +272,7 @@ interface BaseNodeProps { sort: SortFunction translate: TranslateFunction customNodeDefinitions: CustomNodeDefinition[] + customNodeData: CustomNodeData customButtons: CustomButtonDefinition[] errorMessageTimeout: number keyboardControls: KeyboardControlsFull @@ -353,6 +355,7 @@ export interface CustomNodeDefinition, U = Record> wrapperProps?: Record + isCollection?: false // For JSON stringify/parse stringifyReplacer?: (value: unknown) => unknown From 3675c3dc0c87a1396abb753a3da2430dcb6706a2 Mon Sep 17 00:00:00 2001 From: Carl Smith <5456533+CarlosNZ@users.noreply.github.com> Date: Fri, 6 Jun 2025 22:38:26 +1200 Subject: [PATCH 2/6] Change prop name to renderCollectionAsValue --- .../components/DateObject/definition.ts | 2 +- .../components/EnhancedLink/definition.ts | 2 +- custom-component-library/src/App.tsx | 16 ++++++++++------ src/CollectionNode.tsx | 2 +- src/CustomNode.ts | 2 +- src/JsonEditor.tsx | 7 ++++--- src/KeyDisplay.tsx | 7 +++++-- src/ValueNodeWrapper.tsx | 2 +- src/types.ts | 2 +- 9 files changed, 25 insertions(+), 17 deletions(-) diff --git a/custom-component-library/components/DateObject/definition.ts b/custom-component-library/components/DateObject/definition.ts index 7e90ca1f..31ed4346 100644 --- a/custom-component-library/components/DateObject/definition.ts +++ b/custom-component-library/components/DateObject/definition.ts @@ -9,7 +9,7 @@ export const DateObjectDefinition: CustomNodeDefinition = { name: 'Date Object', // shown in the Type selector menu showInTypesSelector: true, defaultValue: new Date(), - isCollection: false, + renderCollectionAsValue: true, // IMPORTANT: This component can't be used in conjunction with a ISO string // matcher (such as the DatePicker in this repo) -- because JSON.stringify // automatically serializes Date objects to ISO Strings, there's no way to diff --git a/custom-component-library/components/EnhancedLink/definition.ts b/custom-component-library/components/EnhancedLink/definition.ts index 79f8d591..72e5b20d 100644 --- a/custom-component-library/components/EnhancedLink/definition.ts +++ b/custom-component-library/components/EnhancedLink/definition.ts @@ -15,5 +15,5 @@ export const EnhancedLinkCustomNodeDefinition: CustomNodeDefinition = (props) => { key={key} style={getStyles('collectionElement', childNodeData)} > - {isCollection(value) && childCustomNodeData?.isCollection !== false ? ( + {isCollection(value) && !childCustomNodeData?.renderCollectionAsValue ? ( = ({ [keySort] ) + const customNodeData = getCustomNode(customNodeDefinitions, nodeData) + const otherProps = { mainContainerRef: mainContainerRef as React.MutableRefObject, name: rootName, @@ -370,8 +372,7 @@ const Editor: React.FC = ({ stringTruncate, translate, customNodeDefinitions, - customNodeData: {}, - // getCustomNode(customNodeDefinitions, nodeData), + customNodeData, customButtons, parentData: null, jsonParse: jsonParseReplacement, @@ -404,7 +405,7 @@ const Editor: React.FC = ({ className={`jer-editor-container ${className ?? ''}`} style={mainContainerStyles} > - {isCollection(data) ? ( + {isCollection(data) && !customNodeData.renderCollectionAsValue ? ( ) : ( diff --git a/src/KeyDisplay.tsx b/src/KeyDisplay.tsx index 7b3f1f26..389d48db 100644 --- a/src/KeyDisplay.tsx +++ b/src/KeyDisplay.tsx @@ -40,6 +40,9 @@ export const KeyDisplay: React.FC = ({ }) => { const { setCurrentlyEditingElement } = useTreeState() + const displayEmptyStringText = name === '' && path.length > 0 + const displayColon = name !== '' || path.length > 0 + if (!isEditingKey) return ( = ({ onDoubleClick={() => canEditKey && setCurrentlyEditingElement(path, 'key')} onClick={handleClick} > - {name === '' ? ( + {displayEmptyStringText ? ( 0 ? 'jer-empty-string' : undefined}> {/* display "" using pseudo class CSS */} ) : ( `${name}` )} - : + {displayColon ? : : null} ) diff --git a/src/ValueNodeWrapper.tsx b/src/ValueNodeWrapper.tsx index abd3855b..3e31ba2a 100644 --- a/src/ValueNodeWrapper.tsx +++ b/src/ValueNodeWrapper.tsx @@ -19,7 +19,7 @@ import { type EnumDefinition, } from './types' import { useTheme, useTreeState } from './contexts' -import { getCustomNode, type CustomNodeData } from './CustomNode' +import { type CustomNodeData } from './CustomNode' import { filterNode, getNextOrPrevious, isJsEvent, matchEnumType } from './helpers' import { useCommon, useDragNDrop } from './hooks' import { KeyDisplay } from './KeyDisplay' diff --git a/src/types.ts b/src/types.ts index b487a43f..27c423ab 100644 --- a/src/types.ts +++ b/src/types.ts @@ -355,7 +355,7 @@ export interface CustomNodeDefinition, U = Record> wrapperProps?: Record - isCollection?: false + renderCollectionAsValue?: boolean // For JSON stringify/parse stringifyReplacer?: (value: unknown) => unknown From f18b0d8cef109d7c2dbb769ce27f5cf542ef33b0 Mon Sep 17 00:00:00 2001 From: Carl Smith <5456533+CarlosNZ@users.noreply.github.com> Date: Sat, 7 Jun 2025 12:02:02 +1200 Subject: [PATCH 3/6] Update README.md --- README.md | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 39524846..b486b195 100644 --- a/README.md +++ b/README.md @@ -75,6 +75,7 @@ A highly-configurable [React](https://github.com/facebook/react) component for e - [Active hyperlinks](#active-hyperlinks) - [Handling JSON](#handling-json) - [Custom Collection nodes](#custom-collection-nodes) + - [Displaying Collections as Values](#displaying-collections-as-values) - [Custom Text](#custom-text) - [Custom Buttons](#custom-buttons) - [Keyboard customisation](#keyboard-customisation) @@ -946,6 +947,7 @@ Custom nodes are provided in the `customNodeDefinitions` prop, as an array of ob showCollectionWrapper // boolean (optional), default true wrapperElement // React component (optional) to wrap *outside* the normal collection wrapper wrapperProps // object (optional) -- props for the above wrapper component + renderCollectionAsValue // For special "object" data that should be treated like a "Value" node // For JSON conversion -- only needed if editing as JSON text stringifyReplacer // function for stringifying to JSON (if non-JSON data type) @@ -963,7 +965,7 @@ By default, your component will be presented to the right of the property key it Also, by default, your component will be treated as a "display" element, i.e. it will appear in the JSON viewer, but when editing, it will revert to the standard editing interface. This can be changed, however, with the `showOnEdit`, `showOnView` and `showEditTools` props. For example, a Date picker might only be required when *editing* and left as-is for display. The `showEditTools` prop refers to the editing icons (copy, add, edit, delete) that appear to the right of each value on hover. If you choose to disable these but you still want to your component to have an "edit" mode, you'll have to provide your own UI mechanism to toggle editing. -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.) +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.) ### Active hyperlinks @@ -1002,6 +1004,15 @@ In most cases it will be preferable (and simpler) to create custom nodes to matc custom node levels - There is one additional prop, `showCollectionWrapper` (default `true`), which, when set to `false`, hides the surrounding collection elements (namely the hide/show chevron and the brackets). In this case, you would have to provide your own hide/show mechanism in your component should you want it. +### Displaying Collections as Values + +If you have a specialised `object` that you would like to display as though it were a regular "value" -- for example, a JavaScript [`Date` object](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date) -- you can set the `renderCollectionAsValue` to `true`. This passes the entire object as a value rather than being rendered as a "collection" of key-value pairs, but you'll have to make sure your custom component handles it appropriately. + +There are two examples in the [Custom Component Library](https://github.com/CarlosNZ/json-edit-react/blob/main/custom-component-library/README.md): + +- [Date Object](#add-link) +- ["Enhanced" link](#add-link) (object with "url" and "text" fields, displayed as clickable string) + ## Custom Text From 47bda01814ffe1207d08f2823cac4b778803c546 Mon Sep 17 00:00:00 2001 From: Carl Smith <5456533+CarlosNZ@users.noreply.github.com> Date: Sat, 7 Jun 2025 12:05:49 +1200 Subject: [PATCH 4/6] Update component.tsx --- .../components/EnhancedLink/component.tsx | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/custom-component-library/components/EnhancedLink/component.tsx b/custom-component-library/components/EnhancedLink/component.tsx index e3217ddc..7d7f7426 100644 --- a/custom-component-library/components/EnhancedLink/component.tsx +++ b/custom-component-library/components/EnhancedLink/component.tsx @@ -1,8 +1,6 @@ /** - * An URL display Custom Component - * - * A simple custom node which detects urls in data and makes them active - * hyperlinks. + * A custom "URL" renderer -- an object that has "text" and "url" properties, + * but is displayed as a clickable string */ import React, { useState } from 'react' @@ -19,7 +17,6 @@ export interface EnhancedLinkProps { type EnhancedLink = { [key: string]: string - // url: string } export const EnhancedLinkCustomComponent: React.FC> = ( From 0043406ec49735d55e1b0e51447eeeaf56564156 Mon Sep 17 00:00:00 2001 From: Carl Smith <5456533+CarlosNZ@users.noreply.github.com> Date: Sat, 7 Jun 2025 12:09:08 +1200 Subject: [PATCH 5/6] Tidy demo data --- custom-component-library/components/data.ts | 8 ++++---- custom-component-library/src/App.tsx | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/custom-component-library/components/data.ts b/custom-component-library/components/data.ts index 44f4c759..dda0e896 100644 --- a/custom-component-library/components/data.ts +++ b/custom-component-library/components/data.ts @@ -4,7 +4,7 @@ */ export const testData = { - intro: `# json-edit-react + Intro: `# json-edit-react ## Custom Component library @@ -22,10 +22,10 @@ export const testData = { Click [here](https://github.com/CarlosNZ/json-edit-react/blob/main/custom-component-library/README.md) for more info `, 'Active Links': { - url: 'https://carlosnz.github.io/json-edit-react/', - longUrl: + Url: 'https://carlosnz.github.io/json-edit-react/', + 'Long URL': 'https://www.google.com/maps/place/Sky+Tower/@-36.8465603,174.7609398,818m/data=!3m1!1e3!4m6!3m5!1s0x6d0d47f06d4bdc25:0x2d1b5c380ad9387!8m2!3d-36.848448!4d174.762191!16zL20vMDFuNXM2?entry=ttu&g_ep=EgoyMDI1MDQwOS4wIKXMDSoASAFQAw%3D%3D', - enhancedLink: { + 'Enhanced Link': { text: 'This link displays custom text', url: 'https://github.com/CarlosNZ/json-edit-react/tree/main/custom-component-library#custom-component-library', }, diff --git a/custom-component-library/src/App.tsx b/custom-component-library/src/App.tsx index f299986d..497fead0 100644 --- a/custom-component-library/src/App.tsx +++ b/custom-component-library/src/App.tsx @@ -59,7 +59,7 @@ function App() { }, { ...MarkdownNodeDefinition, - condition: ({ key }) => key === 'intro', + condition: ({ key }) => key === 'Intro', hideKey: true, }, ]} From 72e39d4710bbfaaa3c4b741d3603165bc3b611c6 Mon Sep 17 00:00:00 2001 From: Carl Smith <5456533+CarlosNZ@users.noreply.github.com> Date: Sat, 7 Jun 2025 12:12:48 +1200 Subject: [PATCH 6/6] Remove commented out code --- src/CollectionNode.tsx | 4 ---- src/ValueNodeWrapper.tsx | 1 - 2 files changed, 5 deletions(-) diff --git a/src/CollectionNode.tsx b/src/CollectionNode.tsx index bc2fd263..878ea783 100644 --- a/src/CollectionNode.tsx +++ b/src/CollectionNode.tsx @@ -165,10 +165,6 @@ export const CollectionNode: React.FC = (props) => { showOnView, showCollectionWrapper = true, } = customNodeData - // useMemo( - // () => getCustomNode(customNodeDefinitions, nodeData), - // [nodeData, customNodeDefinitions] - // ) const childrenEditing = areChildrenBeingEdited(pathString) diff --git a/src/ValueNodeWrapper.tsx b/src/ValueNodeWrapper.tsx index 3e31ba2a..a2fb04d0 100644 --- a/src/ValueNodeWrapper.tsx +++ b/src/ValueNodeWrapper.tsx @@ -84,7 +84,6 @@ export const ValueNodeWrapper: React.FC = (props) => { { canDrag, canDragOnto, path, nodeData, onMove, onError, translate } ) - // const customNodeData = getCustomNode(customNodeDefinitions, nodeData) const [dataType, setDataType] = useState(getDataType(data, customNodeData)) const updateValue = useCallback(