From aa95c98a6c73fa1418b970524fc6192054bdcad2 Mon Sep 17 00:00:00 2001 From: Jos de Jong Date: Tue, 23 Jul 2024 11:54:52 +0200 Subject: [PATCH 1/8] chore: refactor the styling of selection and hovering in TreeMode (WIP) --- src/lib/components/JSONEditor.scss | 5 +- .../contextmenu/ContextMenuPointer.scss | 10 +- ...{JSONValue.svelte => JSONValueCell.svelte} | 0 .../components/modes/tablemode/TableMode.scss | 13 +- .../modes/tablemode/TableMode.svelte | 91 +++++++------- .../modes/tablemode/tag/InlineValue.scss | 10 +- .../modes/treemode/CollapsedItems.scss | 5 + .../components/modes/treemode/JSONKey.scss | 9 -- .../components/modes/treemode/JSONKey.svelte | 10 +- .../components/modes/treemode/JSONNode.scss | 119 ++++++------------ .../components/modes/treemode/JSONNode.svelte | 30 +++-- .../value/components/ReadonlyValue.scss | 5 - 12 files changed, 137 insertions(+), 170 deletions(-) rename src/lib/components/modes/tablemode/{JSONValue.svelte => JSONValueCell.svelte} (100%) diff --git a/src/lib/components/JSONEditor.scss b/src/lib/components/JSONEditor.scss index 8fe5e3fe..d29adde6 100644 --- a/src/lib/components/JSONEditor.scss +++ b/src/lib/components/JSONEditor.scss @@ -12,6 +12,9 @@ display: flex; flex-direction: row; - &.jse-focus { + // lighter selection color when the editor doesn't have focus + &:not(.jse-focus) { + --jse-selection-background-color: #{$selection-background-inactive-color}; + --jse-context-menu-pointer-background: #{$context-menu-pointer-hover-background}; } } diff --git a/src/lib/components/controls/contextmenu/ContextMenuPointer.scss b/src/lib/components/controls/contextmenu/ContextMenuPointer.scss index d15d5553..5b5d27b7 100644 --- a/src/lib/components/controls/contextmenu/ContextMenuPointer.scss +++ b/src/lib/components/controls/contextmenu/ContextMenuPointer.scss @@ -13,7 +13,7 @@ background: transparent; border-radius: 2px; - background: $context-menu-pointer-background; + background: $context-menu-pointer-hover-background; color: $context-menu-pointer-color; border: none; box-shadow: $controls-box-shadow; @@ -21,4 +21,12 @@ &:hover { background: $context-menu-pointer-background-highlight; } + + &.jse-selected { + background: $context-menu-pointer-background; + + &:hover { + background: $context-menu-pointer-background-highlight; + } + } } diff --git a/src/lib/components/modes/tablemode/JSONValue.svelte b/src/lib/components/modes/tablemode/JSONValueCell.svelte similarity index 100% rename from src/lib/components/modes/tablemode/JSONValue.svelte rename to src/lib/components/modes/tablemode/JSONValueCell.svelte diff --git a/src/lib/components/modes/tablemode/TableMode.scss b/src/lib/components/modes/tablemode/TableMode.scss index 444b9384..344994d1 100644 --- a/src/lib/components/modes/tablemode/TableMode.scss +++ b/src/lib/components/modes/tablemode/TableMode.scss @@ -114,8 +114,17 @@ // FIXME: border and/or border shadow? } - &.jse-selected-value > :global(.jse-value) { - background: $selection-background-color; + .jse-value-outer { + display: inline-block; + cursor: $contents-cursor; + + &:hover { + background: $hover-background-color; + } + + &.jse-selected-value { + background: $selection-background-color; + } } // FIXME: this is ugly. give JSONValue an extra class instead? diff --git a/src/lib/components/modes/tablemode/TableMode.svelte b/src/lib/components/modes/tablemode/TableMode.svelte index 3b25b321..b44b6c33 100644 --- a/src/lib/components/modes/tablemode/TableMode.svelte +++ b/src/lib/components/modes/tablemode/TableMode.svelte @@ -70,7 +70,7 @@ toTableCellPosition } from '$lib/logic/table.js' import { isEmpty, isEqual, uniqueId } from 'lodash-es' - import JSONValueComponent from './JSONValue.svelte' + import JSONValueCell from './JSONValueCell.svelte' import { activeElementIsChildOf, createNormalizationFunctions, @@ -1790,49 +1790,52 @@ isValueSelection(selection) && pathStartsWith(selection.path, path)} {@const validationErrorsByColumn = validationErrorsByRow?.columns[columnIndex]} {@const validationError = mergeValidationErrors(path, validationErrorsByColumn)} - - {#if isObjectOrArray(value)} - {@const searchResultsByCell = flattenSearchResults( - getInRecursiveState(item, searchResultByRow, column) - )} - - {@const containsActiveSearchResult = searchResultsByCell - ? searchResultsByCell.some((item) => item.active) - : false} - - {:else} - {@const searchResultItemsByCell = getInRecursiveState( - json, - searchResults, - path - )?.searchResults} - - {/if}{#if !readOnly && isSelected && !isEditingSelection(selection)} -
- -
- {/if}{#if validationError} - - {/if} + +
+ {#if isObjectOrArray(value)} + {@const searchResultsByCell = flattenSearchResults( + getInRecursiveState(item, searchResultByRow, column) + )} + + {@const containsActiveSearchResult = searchResultsByCell + ? searchResultsByCell.some((item) => item.active) + : false} + + {:else} + {@const searchResultItemsByCell = getInRecursiveState( + json, + searchResults, + path + )?.searchResults} + + {/if}{#if !readOnly && isSelected && !isEditingSelection(selection)} +
+ +
+ {/if}{#if validationError} + + {/if} +
{/each} {#if showRefreshButton} diff --git a/src/lib/components/modes/tablemode/tag/InlineValue.scss b/src/lib/components/modes/tablemode/tag/InlineValue.scss index 59bfc007..a01a6011 100644 --- a/src/lib/components/modes/tablemode/tag/InlineValue.scss +++ b/src/lib/components/modes/tablemode/tag/InlineValue.scss @@ -8,15 +8,7 @@ padding: 0 $padding-half; background: transparent; color: inherit; - cursor: pointer; - - &:hover { - background: $hover-background-color; - } - - &.jse-selected { - background: $selection-background-color; - } + cursor: inherit; &.jse-highlight { background-color: $search-match-color; diff --git a/src/lib/components/modes/treemode/CollapsedItems.scss b/src/lib/components/modes/treemode/CollapsedItems.scss index eef165f4..4c946620 100644 --- a/src/lib/components/modes/treemode/CollapsedItems.scss +++ b/src/lib/components/modes/treemode/CollapsedItems.scss @@ -39,6 +39,11 @@ div.jse-collapsed-items { display: flex; + &.jse-selected { + background-color: $selection-background-color; + --jse-collapsed-items-background-color: #{$collapsed-items-selected-background-color}; + } + div.jse-text, button.jse-expand-items { margin: 0 $padding-half; diff --git a/src/lib/components/modes/treemode/JSONKey.scss b/src/lib/components/modes/treemode/JSONKey.scss index 33f7a9c9..f842022e 100644 --- a/src/lib/components/modes/treemode/JSONKey.scss +++ b/src/lib/components/modes/treemode/JSONKey.scss @@ -9,20 +9,11 @@ border-radius: 1px; vertical-align: top; color: $key-color; - cursor: $contents-cursor; word-break: normal; overflow-wrap: normal; // not anywhere as for JSONValue white-space: pre-wrap; // important for rendering multiple consecutive spaces - &:hover { - background: $hover-background-color; - } - - &:hover { - background: $hover-background-color; - } - &.jse-empty { min-width: 3em; outline: 1px dotted $tag-background; diff --git a/src/lib/components/modes/treemode/JSONKey.svelte b/src/lib/components/modes/treemode/JSONKey.svelte index db393d43..cb33f7bf 100644 --- a/src/lib/components/modes/treemode/JSONKey.svelte +++ b/src/lib/components/modes/treemode/JSONKey.svelte @@ -16,7 +16,6 @@ import { UpdateSelectionAfterChange } from '$lib/types.js' import { type JSONPath, type JSONPointer, parseJSONPointer } from 'immutable-json-patch' import ContextMenuPointer from '../../../components/controls/contextmenu/ContextMenuPointer.svelte' - import { classnames } from '$lib/utils/cssUtils.js' export let pointer: JSONPointer export let key: string @@ -41,12 +40,6 @@ } } - function getKeyClass(key: string) { - return classnames('jse-key', { - 'jse-empty': key === '' - }) - } - function handleChangeValue(newKey: string, updateSelection: UpdateSelectionAfterChange) { const updatedKey = onUpdateKey(key, context.normalization.unescapeValue(newKey)) const updatedPath = initial(path).concat(updatedKey) @@ -82,7 +75,8 @@
{#if searchResultItems} diff --git a/src/lib/components/modes/treemode/JSONNode.scss b/src/lib/components/modes/treemode/JSONNode.scss index ce0f36f8..74ef0606 100644 --- a/src/lib/components/modes/treemode/JSONNode.scss +++ b/src/lib/components/modes/treemode/JSONNode.scss @@ -74,6 +74,7 @@ padding-bottom: $contents-padding; box-sizing: border-box; + // FIXME: move this styling inside .jse-context-menu-pointer > .jse-header-outer :global(.jse-context-menu-pointer), > .jse-contents-outer > .jse-contents :global(.jse-context-menu-pointer) { top: 0; @@ -123,6 +124,11 @@ .jse-contents { padding-left: $indent-size; + cursor: $contents-cursor; + + .jse-value-outer { + display: inline-flex; + } } .jse-footer { @@ -137,7 +143,6 @@ } .jse-insert-selection-area { - visibility: hidden; padding: 0 $padding-half; flex: 1; // must fill all left over space at the right side of the editor, so you can click there @@ -171,9 +176,9 @@ margin-right: $padding-half; outline: $height-half solid; // color depends on hovered/selected/inactive+selected + // FIXME: pass an extra class or property to the ContextMenuPointer in case of the insert after area :global(.jse-context-menu-pointer) { right: -$height-half; - background: $context-menu-pointer-hover-background; } &.jse-hovered { @@ -181,88 +186,62 @@ } } - &:hover > .jse-contents-outer .jse-insert-selection-area:not(.jse-selected), - .jse-header-outer:hover > .jse-insert-selection-area:not(.jse-selected), - .jse-footer-outer:hover .jse-insert-selection-area:not(.jse-selected) { - visibility: visible; + .jse-key-outer { + position: relative; } - &.jse-hovered { - > .jse-header-outer > .jse-header > .jse-meta, - .jse-props .jse-header, - .jse-items .jse-header, - .jse-props .jse-contents, - .jse-items .jse-contents, - .jse-footer { + .jse-key-outer, + .jse-value-outer, + .jse-meta, + .jse-footer { + &:hover { background: $hover-background-color; + cursor: $contents-cursor; } } - // TODO: simplify the styling for selected keys/values/multi (get rid of globals?) - - // entry selected (key and value) + // key and value selected &.jse-selected { - > .jse-header-outer > .jse-header > .jse-meta, - .jse-props .jse-header, - .jse-items .jse-header, - .jse-props .jse-contents, - .jse-items .jse-contents, .jse-header, .jse-contents, - .jse-footer, - :global(.jse-key), - :global(.jse-value) { + .jse-footer { background: $selection-background-color; cursor: $contents-selected-cursor; } - .jse-expand { - background: $selection-background-color; - } + // make the hovering background invisible when hovering over selected keys/values + //--jse-hover-background-color: #{$selection-background-color}; + //--jse-contents-cursor: #{$contents-selected-cursor}; + + //.jse-key-outer, + //.jse-value-outer, + //.jse-meta, + //.jse-footer { + // &:hover { + // background: inherit; + // cursor: inherit; + // } + //} } // key selected - &.jse-selected-key { - > .jse-contents-outer > .jse-contents > :global(.jse-identifier) > :global(.jse-key), - > .jse-header-outer > .jse-header > :global(.jse-identifier) > :global(.jse-key) { - background: $selection-background-color; - cursor: $contents-selected-cursor; - } - } - - // value selected (part 1) - &.jse-selected-value > .jse-contents-outer > .jse-contents > :global(.jse-value) { + .jse-key-outer.jse-selected-key { + //.jse-key-outer.jse-selected-key:hover { background: $selection-background-color; cursor: $contents-selected-cursor; } - :global(.jse-collapsed-items.jse-selected), - &.jse-selected :global(.jse-collapsed-items), - &.jse-selected-value :global(.jse-collapsed-items) { - background-color: $selection-background-color; - --jse-collapsed-items-background-color: #{$collapsed-items-selected-background-color}; - } - - // value selected (part 2) + // value selected &.jse-selected-value { + .jse-value-outer, .jse-meta, - > .jse-header-outer > .jse-header > .jse-meta, - > .jse-footer-outer > .jse-footer, - .jse-props .jse-contents, - .jse-props .jse-header, - .jse-props .jse-footer, - .jse-props .jse-expand, - .jse-items .jse-contents, .jse-items .jse-header, - .jse-items .jse-footer, - .jse-items .jse-expand { + .jse-items .jse-contents, + .jse-props .jse-header, + .jse-props .jse-contents, + .jse-footer { background: $selection-background-color; - - :global(.jse-key), - :global(.jse-value) { - background: $selection-background-color; - cursor: $contents-selected-cursor; - } + cursor: $contents-selected-cursor; } } @@ -275,24 +254,4 @@ outline-color: $context-menu-pointer-background; } } - - .jse-insert-area { - &.jse-selected { - :global(.jse-context-menu-pointer) { - background: $context-menu-pointer-background; - - &:hover { - background: $context-menu-pointer-background-highlight; - } - } - } - } -} - -// lighter selection color when the editor doesn't have focus -:global(.jse-main:not(.jse-focus)) { - .jse-json-node { - --jse-selection-background-color: #{$selection-background-inactive-color}; - --jse-context-menu-pointer-background: #{$context-menu-pointer-hover-background}; - } } diff --git a/src/lib/components/modes/treemode/JSONNode.svelte b/src/lib/components/modes/treemode/JSONNode.svelte index c21077af..ecd892e4 100644 --- a/src/lib/components/modes/treemode/JSONNode.svelte +++ b/src/lib/components/modes/treemode/JSONNode.svelte @@ -573,7 +573,6 @@ style:--level={path.length} class:jse-root={root} class:jse-selected={isNodeSelected && isMultiSelection(selection)} - class:jse-selected-key={isNodeSelected && isKeySelection(selection)} class:jse-selected-value={isNodeSelected && isValueSelection(selection)} class:jse-readonly={context.readOnly} class:jse-hovered={hover === HOVER_COLLECTION} @@ -806,10 +805,12 @@ ? validationErrors.properties[key] : undefined} + {@const nestedPath = path.concat(key)} + {@const nestedSelection = selectionIfOverlapping( context.getJson(), selection, - path.concat(key) + nestedPath )} -
+
:
{/if} - +
+ +
{#if !context.readOnly && isNodeSelected && selection && (isValueSelection(selection) || isMultiSelection(selection)) && !isEditingSelection(selection) && isEqual(getFocusPath(selection), path)}
diff --git a/src/lib/plugins/value/components/ReadonlyValue.scss b/src/lib/plugins/value/components/ReadonlyValue.scss index 9b6205f7..7ec594d8 100644 --- a/src/lib/plugins/value/components/ReadonlyValue.scss +++ b/src/lib/plugins/value/components/ReadonlyValue.scss @@ -9,16 +9,11 @@ outline: none; border-radius: 1px; vertical-align: top; - cursor: $contents-cursor; word-break: normal; overflow-wrap: anywhere; white-space: pre-wrap; // important for rendering multiple consecutive spaces - &:hover { - background: $hover-background-color; - } - &.jse-empty { min-width: 4em; outline: 1px dotted $tag-background; From b97ce3951b575e5d28e7b461668943f2c2ad3d8e Mon Sep 17 00:00:00 2001 From: Jos de Jong Date: Tue, 23 Jul 2024 12:20:41 +0200 Subject: [PATCH 2/8] fix: background when hovering selected keys and values --- .../components/modes/treemode/JSONNode.scss | 30 ++++++++++--------- 1 file changed, 16 insertions(+), 14 deletions(-) diff --git a/src/lib/components/modes/treemode/JSONNode.scss b/src/lib/components/modes/treemode/JSONNode.scss index 74ef0606..e9477827 100644 --- a/src/lib/components/modes/treemode/JSONNode.scss +++ b/src/lib/components/modes/treemode/JSONNode.scss @@ -209,24 +209,19 @@ cursor: $contents-selected-cursor; } - // make the hovering background invisible when hovering over selected keys/values - //--jse-hover-background-color: #{$selection-background-color}; - //--jse-contents-cursor: #{$contents-selected-cursor}; - - //.jse-key-outer, - //.jse-value-outer, - //.jse-meta, - //.jse-footer { - // &:hover { - // background: inherit; - // cursor: inherit; - // } - //} + .jse-key-outer, + .jse-value-outer, + .jse-meta, + .jse-footer { + &:hover { + background: inherit; + cursor: inherit; + } + } } // key selected .jse-key-outer.jse-selected-key { - //.jse-key-outer.jse-selected-key:hover { background: $selection-background-color; cursor: $contents-selected-cursor; } @@ -243,6 +238,13 @@ background: $selection-background-color; cursor: $contents-selected-cursor; } + + .jse-key-outer { + &:hover { + background: inherit; + cursor: inherit; + } + } } &.jse-readonly { From b82aec32bf3351a806acf9160565e2b5d7e91d52 Mon Sep 17 00:00:00 2001 From: Jos de Jong Date: Tue, 23 Jul 2024 12:33:12 +0200 Subject: [PATCH 3/8] fix: selection background color when editing --- src/lib/components/controls/EditableDiv.scss | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lib/components/controls/EditableDiv.scss b/src/lib/components/controls/EditableDiv.scss index d769cd2b..696536c4 100644 --- a/src/lib/components/controls/EditableDiv.scss +++ b/src/lib/components/controls/EditableDiv.scss @@ -21,7 +21,7 @@ div.jse-editable-div { &[contenteditable='true'] { outline: $edit-outline; - background: inherit !important; + background: $background-color; position: relative; border-radius: 0; z-index: 3; // must be on top of hovering the entry below it From 5a0572dec3496fb31766ebf22058ce38f5d4fe75 Mon Sep 17 00:00:00 2001 From: Jos de Jong Date: Tue, 23 Jul 2024 12:55:15 +0200 Subject: [PATCH 4/8] chore: refactor :global cases for ContextMenuPointer styling into component properties --- .../controls/contextmenu/ContextMenuPointer.scss | 9 +++++++++ .../controls/contextmenu/ContextMenuPointer.svelte | 4 ++++ src/lib/components/modes/treemode/JSONNode.scss | 12 ------------ src/lib/components/modes/treemode/JSONNode.svelte | 9 ++++++--- 4 files changed, 19 insertions(+), 15 deletions(-) diff --git a/src/lib/components/controls/contextmenu/ContextMenuPointer.scss b/src/lib/components/controls/contextmenu/ContextMenuPointer.scss index 5b5d27b7..ac26419a 100644 --- a/src/lib/components/controls/contextmenu/ContextMenuPointer.scss +++ b/src/lib/components/controls/contextmenu/ContextMenuPointer.scss @@ -18,6 +18,15 @@ border: none; box-shadow: $controls-box-shadow; + &.jse-root { + top: 0; + right: calc(-2px - $context-menu-pointer-size); + } + + &.jse-insert { + right: -1px; + } + &:hover { background: $context-menu-pointer-background-highlight; } diff --git a/src/lib/components/controls/contextmenu/ContextMenuPointer.svelte b/src/lib/components/controls/contextmenu/ContextMenuPointer.svelte index 58751d4b..6739f962 100644 --- a/src/lib/components/controls/contextmenu/ContextMenuPointer.svelte +++ b/src/lib/components/controls/contextmenu/ContextMenuPointer.svelte @@ -10,6 +10,8 @@ } from '$lib/constants.js' import type { OnContextMenu } from '$lib/types' + export let root: boolean = false + export let insert: boolean = false export let selected: boolean export let onContextMenu: OnContextMenu @@ -37,6 +39,8 @@
{#if !context.readOnly && isNodeSelected && selection && (isValueSelection(selection) || isMultiSelection(selection)) && !isEditingSelection(selection) && isEqual(getFocusPath(selection), path)}
- +
{/if}
@@ -658,6 +658,7 @@ title={INSERT_EXPLANATION} > @@ -754,7 +755,7 @@
{#if !context.readOnly && isNodeSelected && selection && (isValueSelection(selection) || isMultiSelection(selection)) && !isEditingSelection(selection) && isEqual(getFocusPath(selection), path)}
- +
{/if} @@ -789,6 +790,7 @@ title={INSERT_EXPLANATION} > @@ -874,7 +876,7 @@ {#if !context.readOnly && isNodeSelected && selection && (isValueSelection(selection) || isMultiSelection(selection)) && !isEditingSelection(selection) && isEqual(getFocusPath(selection), path)}
- +
{/if} @@ -900,6 +902,7 @@ title={INSERT_EXPLANATION} > From 06a01a4729620d9c2878bf812a719886be46427f Mon Sep 17 00:00:00 2001 From: Jos de Jong Date: Tue, 23 Jul 2024 13:08:39 +0200 Subject: [PATCH 5/8] chore: use `JSONValue` in `TableMode`, remove `JSONValueCell` --- .../modes/tablemode/JSONValueCell.svelte | 67 ------------------- .../modes/tablemode/TableMode.svelte | 25 ++++--- 2 files changed, 14 insertions(+), 78 deletions(-) delete mode 100644 src/lib/components/modes/tablemode/JSONValueCell.svelte diff --git a/src/lib/components/modes/tablemode/JSONValueCell.svelte b/src/lib/components/modes/tablemode/JSONValueCell.svelte deleted file mode 100644 index 22b1c5b1..00000000 --- a/src/lib/components/modes/tablemode/JSONValueCell.svelte +++ /dev/null @@ -1,67 +0,0 @@ - - - - -{#each renderers as renderer} - {#if isSvelteActionRenderer(renderer)} - {@const action = renderer.action} - {#key renderer.action} -
- {/key} - {:else} - {#key renderer.component} - - {/key} - {/if} -{/each} diff --git a/src/lib/components/modes/tablemode/TableMode.svelte b/src/lib/components/modes/tablemode/TableMode.svelte index b44b6c33..26ff1bea 100644 --- a/src/lib/components/modes/tablemode/TableMode.svelte +++ b/src/lib/components/modes/tablemode/TableMode.svelte @@ -70,7 +70,6 @@ toTableCellPosition } from '$lib/logic/table.js' import { isEmpty, isEqual, uniqueId } from 'lodash-es' - import JSONValueCell from './JSONValueCell.svelte' import { activeElementIsChildOf, createNormalizationFunctions, @@ -91,7 +90,10 @@ } from '$lib/logic/documentState.js' import { isObjectOrArray, isUrl, stringConvert } from '$lib/utils/typeUtils.js' import InlineValue from './tag/InlineValue.svelte' - import { revertJSONPatchWithMoveOperations } from '$lib/logic/operations.js' + import { + createNestedValueOperations, + revertJSONPatchWithMoveOperations + } from '$lib/logic/operations.js' import { createValueSelection, getAnchorPath, @@ -147,6 +149,7 @@ import createTableContextMenuItems from './contextmenu/createTableContextMenuItems' import ContextMenu from '../../controls/contextmenu/ContextMenu.svelte' import { flattenSearchResults, toRecursiveSearchResults } from '$lib/logic/search.js' + import JSONValue from '$lib/components/modes/treemode/JSONValue.svelte' const debug = createDebug('jsoneditor:TableMode') const { openAbsolutePopup, closeAbsolutePopup } = @@ -374,7 +377,12 @@ findElement, findNextInside, focus, - onPatch: handlePatch, + onPatch: (operations, afterPatch) => { + // When having flattened table columns and having inserted a new row, it is possible that + // we edit a nested value of which the parent object is not existing. Therefore, we call + // replaceNestedValue to create the parent object(s) first. + return handlePatch(createNestedValueOperations(operations, json), afterPatch) + }, onSelect: handleSelect, onFind: openFind, onPasteJson: handlePasteJson, @@ -1528,7 +1536,7 @@ json: getIn(json, path) }, path, - onPatch: context.onPatch, + onPatch: handlePatch, onClose: () => { modalOpen = false setTimeout(focus) @@ -1816,15 +1824,10 @@ path )?.searchResults} - Date: Tue, 23 Jul 2024 13:27:39 +0200 Subject: [PATCH 6/8] fix: deleting a table cell broken --- src/lib/logic/documentState.test.ts | 24 ++++++++++++++++++++++++ src/lib/logic/documentState.ts | 7 ++++++- 2 files changed, 30 insertions(+), 1 deletion(-) diff --git a/src/lib/logic/documentState.test.ts b/src/lib/logic/documentState.test.ts index e71243aa..c9af9bcf 100644 --- a/src/lib/logic/documentState.test.ts +++ b/src/lib/logic/documentState.test.ts @@ -8,6 +8,7 @@ import { createDocumentState, createObjectDocumentState, createValueDocumentState, + deleteInDocumentState, documentStateFactory, documentStatePatch, ensureRecursiveState, @@ -1892,6 +1893,29 @@ describe('documentState', () => { }) }) }) + + describe('deleteInDocumentState', () => { + const json = { value: '42' } + const documentState: DocumentState = { + type: 'object', + expanded: true, + properties: { + value: { type: 'value', enforceString: true } + } + } + + test('delete existing state', () => { + expect(deleteInDocumentState(json, documentState, ['value'])).toEqual({ + type: 'object', + expanded: true, + properties: {} + }) + }) + + test('delete non-existing state', () => { + expect(deleteInDocumentState(json, documentState, ['foo'])).toEqual(documentState) + }) + }) }) /** diff --git a/src/lib/logic/documentState.ts b/src/lib/logic/documentState.ts index 81ef91ee..0763bceb 100644 --- a/src/lib/logic/documentState.ts +++ b/src/lib/logic/documentState.ts @@ -1,6 +1,7 @@ import { compileJSONPointer, deleteIn, + existsIn, getIn, immutableJSONPatch, isJSONArray, @@ -555,7 +556,11 @@ export function deleteInDocumentState( documentState: T | undefined, path: JSONPath ): T | undefined { - return deleteIn(documentState, toRecursiveStatePath(json, path)) + const recursivePath = toRecursiveStatePath(json, path) + + return existsIn(documentState, recursivePath) + ? deleteIn(documentState, toRecursiveStatePath(json, path)) + : documentState } export function documentStateAdd( From 2bd9d6f3da94e1f9e257b1dd8da0a6fc419a4912 Mon Sep 17 00:00:00 2001 From: Jos de Jong Date: Tue, 23 Jul 2024 13:28:11 +0200 Subject: [PATCH 7/8] chore: update test snapshots --- .../__snapshots__/JSONEditor.test.ts.snap | 472 ++++++++++-------- 1 file changed, 256 insertions(+), 216 deletions(-) diff --git a/src/lib/components/__snapshots__/JSONEditor.test.ts.snap b/src/lib/components/__snapshots__/JSONEditor.test.ts.snap index c08f86bb..fb245d52 100644 --- a/src/lib/components/__snapshots__/JSONEditor.test.ts.snap +++ b/src/lib/components/__snapshots__/JSONEditor.test.ts.snap @@ -4,10 +4,10 @@ exports[`JSONEditor > render table mode 1`] = `
render table mode 1`] = `
@@ -439,7 +463,7 @@ exports[`JSONEditor > render table mode 1`] = ` class="jse-table-invisible-end-section" >
0
- 1 +
+ 1 +
+ + + + + +
- - - - - -
+
+ +
+ + + + +
- - - - - -
1
- 2 +
+ 2 +
+ + + + + +
- - - - - -
- Joe +
+ Joe +
+ + + + + +
- - - - - -
2
- 3 +
+ 3 +
+ + + + + +
- - - - - -
+
+ +
+ + + + +
- - - - - -
@@ -469,7 +493,7 @@ exports[`JSONEditor > render text mode 1`] = `
render tree mode 1`] = `
render tree mode 1`] = ` >
0
:
{
@@ -1532,36 +1556,36 @@ exports[`JSONEditor > render tree mode 1`] = `
@@ -1573,29 +1597,33 @@ exports[`JSONEditor > render tree mode 1`] = `
:
- 1 +
+ 1 +
+ + + +
- - - -
@@ -1605,21 +1633,21 @@ exports[`JSONEditor > render tree mode 1`] = `