From cbf00c0a39903a857cc43a7d306df53bc57c573a Mon Sep 17 00:00:00 2001 From: Ziad Beyens Date: Wed, 24 Aug 2022 17:49:04 +0200 Subject: [PATCH] fix: `toggleList` with `validLiChildrenTypes` (#1816) * fix * fix * Create spotty-hotels-happen.md --- .changeset/spotty-hotels-happen.md | 5 + examples/apps/next/src/pages/_app.tsx | 2 +- examples/src/styles.css | 4 + packages/nodes/list/src/onKeyDownList.ts | 4 +- .../list/src/transforms/toggleList.spec.tsx | 266 ++++++++++++++---- .../nodes/list/src/transforms/toggleList.ts | 32 ++- .../nodes/list/src/transforms/unwrapList.ts | 19 +- yarn.lock | 38 +-- 8 files changed, 289 insertions(+), 81 deletions(-) create mode 100644 .changeset/spotty-hotels-happen.md diff --git a/.changeset/spotty-hotels-happen.md b/.changeset/spotty-hotels-happen.md new file mode 100644 index 0000000000..f0daf9d6a8 --- /dev/null +++ b/.changeset/spotty-hotels-happen.md @@ -0,0 +1,5 @@ +--- +"@udecode/plate-list": patch +--- + +Fixes #1817 diff --git a/examples/apps/next/src/pages/_app.tsx b/examples/apps/next/src/pages/_app.tsx index 53a187a393..917ddc31f3 100644 --- a/examples/apps/next/src/pages/_app.tsx +++ b/examples/apps/next/src/pages/_app.tsx @@ -16,7 +16,7 @@ export default function MyApp({ Component, pageProps }: any) {
-
+
diff --git a/examples/src/styles.css b/examples/src/styles.css index cbe92f7ae1..4c1491d76f 100644 --- a/examples/src/styles.css +++ b/examples/src/styles.css @@ -17,6 +17,10 @@ td { .slate-HeadingToolbar { padding: 17px 60px !important; + position: fixed !important; + background: white !important; + z-index: 1000; + width: 100%; } .tippy-box[data-theme~='tomato'] { diff --git a/packages/nodes/list/src/onKeyDownList.ts b/packages/nodes/list/src/onKeyDownList.ts index b53d05349e..0db142a327 100644 --- a/packages/nodes/list/src/onKeyDownList.ts +++ b/packages/nodes/list/src/onKeyDownList.ts @@ -13,7 +13,7 @@ import { import isHotkey from 'is-hotkey'; import { castArray } from 'lodash'; import { Range } from 'slate'; -import { ELEMENT_LIC } from './createListPlugin'; +import { ELEMENT_LI } from './createListPlugin'; import { moveListItems, toggleList } from './transforms'; import { ListPlugin } from './types'; @@ -53,7 +53,7 @@ export const onKeyDownList = < // check if we're in a list context. const listSelected = someNode(editor, { - match: { type: getPluginType(editor, ELEMENT_LIC) }, + match: { type: getPluginType(editor, ELEMENT_LI) }, }); if (workRange && listSelected) { diff --git a/packages/nodes/list/src/transforms/toggleList.spec.tsx b/packages/nodes/list/src/transforms/toggleList.spec.tsx index 272adf016f..e753ebaad6 100644 --- a/packages/nodes/list/src/transforms/toggleList.spec.tsx +++ b/packages/nodes/list/src/transforms/toggleList.spec.tsx @@ -2,6 +2,7 @@ import { createPlateUIEditor } from '@udecode/plate/src'; import { getPluginType, PlateEditor } from '@udecode/plate-core'; +import { ELEMENT_IMAGE } from '@udecode/plate-media/src/index'; import { jsx } from '@udecode/plate-test-utils'; import { createListPlugin, ELEMENT_OL, ELEMENT_UL } from '../createListPlugin'; import { toggleList } from './toggleList'; @@ -10,15 +11,15 @@ jsx; describe('toggle on', () => { it('should turn a p to list', () => { - const input = ( + const input = (( 1 - ) as any as PlateEditor; + ) as any) as PlateEditor; - const output = ( + const output = (( @@ -26,7 +27,7 @@ describe('toggle on', () => { - ) as any as PlateEditor; + ) as any) as PlateEditor; const editor = createPlateUIEditor({ editor: input, @@ -38,8 +39,51 @@ describe('toggle on', () => { expect(input.children).toEqual(output.children); }); + it('should turn validLiChildrenTypes to list', () => { + const input = (( + + + + + + + + ) as any) as PlateEditor; + + const output = (( + + + + + + + + + + ) as any) as PlateEditor; + + const editor = createPlateUIEditor({ + editor: input, + plugins: [ + createListPlugin({ + overrideByKey: { + [ELEMENT_UL]: { + options: { + validLiChildrenTypes: [ELEMENT_IMAGE], + }, + }, + }, + }), + ], + }); + + toggleList(editor, { type: getPluginType(editor, ELEMENT_UL) }); + + expect(input.children).toEqual(output.children); + }); + it('should turn a p with a selection to list', () => { - const input = ( + const input = (( Planetas @@ -47,9 +91,9 @@ describe('toggle on', () => { gandavum! - ) as any as PlateEditor; + ) as any) as PlateEditor; - const output = ( + const output = (( @@ -61,7 +105,7 @@ describe('toggle on', () => { - ) as any as PlateEditor; + ) as any) as PlateEditor; const editor = createPlateUIEditor({ editor: input, @@ -74,7 +118,7 @@ describe('toggle on', () => { }); it('should turn multiple p to list', () => { - const input = ( + const input = (( 1 @@ -84,9 +128,9 @@ describe('toggle on', () => { 3 - ) as any as PlateEditor; + ) as any) as PlateEditor; - const output = ( + const output = (( @@ -100,7 +144,7 @@ describe('toggle on', () => { - ) as any as PlateEditor; + ) as any) as PlateEditor; const editor = createPlateUIEditor({ editor: input, @@ -112,8 +156,69 @@ describe('toggle on', () => { expect(input.children).toEqual(output.children); }); + it('should turn multiple validLiChildrenTypes to list', () => { + const input = (( + + + + + + + + + + + + + + + + ) as any) as PlateEditor; + + const output = (( + + + + + + + + + + + + + + + + + + + + ) as any) as PlateEditor; + + const editor = createPlateUIEditor({ + editor: input, + plugins: [ + createListPlugin({ + overrideByKey: { + [ELEMENT_UL]: { + options: { + validLiChildrenTypes: [ELEMENT_IMAGE], + }, + }, + }, + }), + ], + }); + + toggleList(editor, { type: getPluginType(editor, ELEMENT_UL) }); + + expect(input.children).toEqual(output.children); + }); + it('should turn multiple p to list in the same order', () => { - const input = ( + const input = (( @@ -128,9 +233,9 @@ describe('toggle on', () => { - ) as any as PlateEditor; + ) as any) as PlateEditor; - const output = ( + const output = (( @@ -153,7 +258,7 @@ describe('toggle on', () => { - ) as any as PlateEditor; + ) as any) as PlateEditor; const editor = createPlateUIEditor({ editor: input, @@ -166,7 +271,7 @@ describe('toggle on', () => { }); it('should turn multiple p to list in the same order', () => { - const input = ( + const input = (( @@ -181,9 +286,9 @@ describe('toggle on', () => { - ) as any as PlateEditor; + ) as any) as PlateEditor; - const output = ( + const output = (( @@ -206,7 +311,7 @@ describe('toggle on', () => { - ) as any as PlateEditor; + ) as any) as PlateEditor; const editor = createPlateUIEditor({ editor: input, @@ -221,7 +326,7 @@ describe('toggle on', () => { describe('toggle off', () => { it('should split a simple list to two', () => { - const input = ( + const input = (( @@ -238,9 +343,9 @@ describe('toggle off', () => { - ) as any as PlateEditor; + ) as any) as PlateEditor; - const output = ( + const output = (( @@ -254,7 +359,7 @@ describe('toggle off', () => { - ) as any as PlateEditor; + ) as any) as PlateEditor; const editor = createPlateUIEditor({ editor: input, @@ -267,7 +372,7 @@ describe('toggle off', () => { }); it('should split a nested list', () => { - const input = ( + const input = (( @@ -289,9 +394,9 @@ describe('toggle off', () => { - ) as any as PlateEditor; + ) as any) as PlateEditor; - const output = ( + const output = (( @@ -310,7 +415,7 @@ describe('toggle off', () => { - ) as any as PlateEditor; + ) as any) as PlateEditor; const editor = createPlateUIEditor({ editor: input, @@ -323,7 +428,7 @@ describe('toggle off', () => { }); it('should turn a list to multiple p', () => { - const input = ( + const input = (( @@ -341,15 +446,15 @@ describe('toggle off', () => { - ) as any as PlateEditor; + ) as any) as PlateEditor; - const output = ( + const output = (( 1 2 3 - ) as any as PlateEditor; + ) as any) as PlateEditor; const editor = createPlateUIEditor({ editor: input, @@ -360,11 +465,76 @@ describe('toggle off', () => { expect(input.children).toEqual(output.children); }); + + it('should turn multiple lists to validLiChildrenTypes', () => { + const input = (( + + + + + + + + + + + + + + + + + + + + + + + + ) as any) as PlateEditor; + + const output = (( + + + + + + + + + + + + + + + + ) as any) as PlateEditor; + + const editor = createPlateUIEditor({ + editor: input, + plugins: [ + createListPlugin({ + overrideByKey: { + [ELEMENT_UL]: { + options: { + validLiChildrenTypes: [ELEMENT_IMAGE], + }, + }, + }, + }), + ], + }); + + toggleList(editor, { type: getPluginType(editor, ELEMENT_UL) }); + + expect(input.children).toEqual(output.children); + }); }); describe('toggle over', () => { it('should toggle different list types', () => { - const input = ( + const input = (( @@ -374,9 +544,9 @@ describe('toggle over', () => { - ) as any as PlateEditor; + ) as any) as PlateEditor; - const output = ( + const output = (( @@ -384,7 +554,7 @@ describe('toggle over', () => { - ) as any as PlateEditor; + ) as any) as PlateEditor; const editor = createPlateUIEditor({ editor: input, @@ -397,7 +567,7 @@ describe('toggle over', () => { }); it('should only toggle the nested list', () => { - const input = ( + const input = (( @@ -413,9 +583,9 @@ describe('toggle over', () => { - ) as any as PlateEditor; + ) as any) as PlateEditor; - const output = ( + const output = (( @@ -428,7 +598,7 @@ describe('toggle over', () => { - ) as any as PlateEditor; + ) as any) as PlateEditor; const editor = createPlateUIEditor({ editor: input, @@ -441,7 +611,7 @@ describe('toggle over', () => { }); it('should only toggle everything that is selected', () => { - const input = ( + const input = (( @@ -459,9 +629,9 @@ describe('toggle over', () => { - ) as any as PlateEditor; + ) as any) as PlateEditor; - const output = ( + const output = (( @@ -474,7 +644,7 @@ describe('toggle over', () => { - ) as any as PlateEditor; + ) as any) as PlateEditor; const editor = createPlateUIEditor({ editor: input, @@ -487,7 +657,7 @@ describe('toggle over', () => { }); it('should fully toggle a nested list when the selection contains a p', () => { - const input = ( + const input = (( @@ -506,9 +676,9 @@ describe('toggle over', () => { - ) as any as PlateEditor; + ) as any) as PlateEditor; - const output = ( + const output = (( @@ -524,7 +694,7 @@ describe('toggle over', () => { - ) as any as PlateEditor; + ) as any) as PlateEditor; const editor = createPlateUIEditor({ editor: input, diff --git a/packages/nodes/list/src/transforms/toggleList.ts b/packages/nodes/list/src/transforms/toggleList.ts index a6d035117d..9d5dd7b327 100644 --- a/packages/nodes/list/src/transforms/toggleList.ts +++ b/packages/nodes/list/src/transforms/toggleList.ts @@ -1,8 +1,10 @@ import { ELEMENT_DEFAULT, findNode, + getBlockAbove, getCommonNode, getNodeEntries, + getPluginOptions, getPluginType, isCollapsed, isElement, @@ -17,17 +19,23 @@ import { import { Range } from 'slate'; import { ELEMENT_LI, ELEMENT_LIC } from '../createListPlugin'; import { getListItemEntry, getListTypes } from '../queries'; +import { ListPlugin } from '../types'; import { unwrapList } from './unwrapList'; export const toggleList = ( editor: PlateEditor, - { type }: { type: string } + { type, pluginKey = type }: { type: string; pluginKey?: string } ) => withoutNormalizing(editor, () => { if (!editor.selection) { return; } + const { validLiChildrenTypes } = getPluginOptions( + editor, + pluginKey + ); + if (isCollapsed(editor.selection) || !isRangeAcrossBlocks(editor)) { // selection is collapsed const res = getListItemEntry(editor); @@ -56,9 +64,15 @@ export const toggleList = ( match: { type: getPluginType(editor, ELEMENT_DEFAULT) }, }); const nodes = Array.from(_nodes); - setElements(editor, { - type: getPluginType(editor, ELEMENT_LIC), + + const blockAbove = getBlockAbove(editor, { + match: { type: validLiChildrenTypes }, }); + if (!blockAbove) { + setElements(editor, { + type: getPluginType(editor, ELEMENT_LIC), + }); + } const listItem = { type: getPluginType(editor, ELEMENT_LI), @@ -137,11 +151,13 @@ export const toggleList = ( } ); } else { - setElements( - editor, - { type: getPluginType(editor, ELEMENT_LIC) }, - { at: n[1] } - ); + if (!validLiChildrenTypes?.includes(n[0].type)) { + setElements( + editor, + { type: getPluginType(editor, ELEMENT_LIC) }, + { at: n[1] } + ); + } const listItem = { type: getPluginType(editor, ELEMENT_LI), diff --git a/packages/nodes/list/src/transforms/unwrapList.ts b/packages/nodes/list/src/transforms/unwrapList.ts index 01c9eae237..cd2b6451ad 100644 --- a/packages/nodes/list/src/transforms/unwrapList.ts +++ b/packages/nodes/list/src/transforms/unwrapList.ts @@ -1,6 +1,7 @@ import { ELEMENT_DEFAULT, getAboveNode, + getBlockAbove, getCommonNode, getPluginType, isElement, @@ -11,7 +12,12 @@ import { withoutNormalizing, } from '@udecode/plate-core'; import { Path } from 'slate'; -import { ELEMENT_LI, ELEMENT_OL, ELEMENT_UL } from '../createListPlugin'; +import { + ELEMENT_LI, + ELEMENT_LIC, + ELEMENT_OL, + ELEMENT_UL, +} from '../createListPlugin'; import { getListTypes } from '../queries'; export const unwrapList = ( @@ -43,9 +49,16 @@ export const unwrapList = ( withoutNormalizing(editor, () => { do { - setElements(editor, { - type: getPluginType(editor, ELEMENT_DEFAULT), + const licEntry = getBlockAbove(editor, { + at, + match: { type: getPluginType(editor, ELEMENT_LIC) }, }); + if (licEntry) { + setElements(editor, { + at, + type: getPluginType(editor, ELEMENT_DEFAULT), + }); + } unwrapNodes(editor, { at, diff --git a/yarn.lock b/yarn.lock index fdde75b23d..f60dd98ae4 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5111,7 +5111,7 @@ __metadata: languageName: unknown linkType: soft -"@udecode/plate-headless@npm:16.3.0, @udecode/plate-headless@workspace:packages/headless": +"@udecode/plate-headless@npm:16.4.1, @udecode/plate-headless@workspace:packages/headless": version: 0.0.0-use.local resolution: "@udecode/plate-headless@workspace:packages/headless" dependencies: @@ -5132,11 +5132,11 @@ __metadata: "@udecode/plate-highlight": "npm:16.3.0" "@udecode/plate-horizontal-rule": "npm:16.3.0" "@udecode/plate-indent": "npm:16.3.0" - "@udecode/plate-indent-list": "npm:16.3.0" + "@udecode/plate-indent-list": "npm:16.4.1" "@udecode/plate-kbd": "npm:16.3.0" "@udecode/plate-line-height": "npm:16.3.0" "@udecode/plate-link": "npm:16.3.0" - "@udecode/plate-list": "npm:16.3.0" + "@udecode/plate-list": "npm:16.4.1" "@udecode/plate-media": "npm:16.3.0" "@udecode/plate-mention": "npm:16.3.0" "@udecode/plate-node-id": "npm:16.3.0" @@ -5145,9 +5145,9 @@ __metadata: "@udecode/plate-reset-node": "npm:16.3.0" "@udecode/plate-select": "npm:16.3.0" "@udecode/plate-serializer-csv": "npm:16.3.0" - "@udecode/plate-serializer-docx": "npm:16.3.0" + "@udecode/plate-serializer-docx": "npm:16.4.1" "@udecode/plate-serializer-html": "npm:16.3.0" - "@udecode/plate-serializer-md": "npm:16.3.0" + "@udecode/plate-serializer-md": "npm:16.4.1" "@udecode/plate-table": "npm:16.3.0" "@udecode/plate-trailing-block": "npm:16.3.0" peerDependencies: @@ -5200,13 +5200,13 @@ __metadata: languageName: unknown linkType: soft -"@udecode/plate-indent-list@npm:16.3.0, @udecode/plate-indent-list@workspace:packages/nodes/indent-list": +"@udecode/plate-indent-list@npm:16.4.1, @udecode/plate-indent-list@workspace:packages/nodes/indent-list": version: 0.0.0-use.local resolution: "@udecode/plate-indent-list@workspace:packages/nodes/indent-list" dependencies: "@udecode/plate-core": "npm:16.3.0" "@udecode/plate-indent": "npm:16.3.0" - "@udecode/plate-list": "npm:16.3.0" + "@udecode/plate-list": "npm:16.4.1" peerDependencies: react: ">=16.8.0" react-dom: ">=16.8.0" @@ -5289,7 +5289,7 @@ __metadata: languageName: unknown linkType: soft -"@udecode/plate-list@npm:16.3.0, @udecode/plate-list@workspace:packages/nodes/list": +"@udecode/plate-list@npm:16.4.1, @udecode/plate-list@workspace:packages/nodes/list": version: 0.0.0-use.local resolution: "@udecode/plate-list@workspace:packages/nodes/list" dependencies: @@ -5437,14 +5437,14 @@ __metadata: languageName: unknown linkType: soft -"@udecode/plate-serializer-docx@npm:16.3.0, @udecode/plate-serializer-docx@workspace:packages/serializers/docx": +"@udecode/plate-serializer-docx@npm:16.4.1, @udecode/plate-serializer-docx@workspace:packages/serializers/docx": version: 0.0.0-use.local resolution: "@udecode/plate-serializer-docx@workspace:packages/serializers/docx" dependencies: "@udecode/plate-core": "npm:16.3.0" "@udecode/plate-heading": "npm:16.3.0" "@udecode/plate-indent": "npm:16.3.0" - "@udecode/plate-indent-list": "npm:16.3.0" + "@udecode/plate-indent-list": "npm:16.4.1" "@udecode/plate-media": "npm:16.3.0" "@udecode/plate-paragraph": "npm:16.3.0" "@udecode/plate-table": "npm:16.3.0" @@ -5475,7 +5475,7 @@ __metadata: languageName: unknown linkType: soft -"@udecode/plate-serializer-md@npm:16.3.0, @udecode/plate-serializer-md@workspace:packages/serializers/md": +"@udecode/plate-serializer-md@npm:16.4.1, @udecode/plate-serializer-md@workspace:packages/serializers/md": version: 0.0.0-use.local resolution: "@udecode/plate-serializer-md@workspace:packages/serializers/md" dependencies: @@ -5484,7 +5484,7 @@ __metadata: "@udecode/plate-core": "npm:16.3.0" "@udecode/plate-heading": "npm:16.3.0" "@udecode/plate-link": "npm:16.3.0" - "@udecode/plate-list": "npm:16.3.0" + "@udecode/plate-list": "npm:16.4.1" "@udecode/plate-paragraph": "npm:16.3.0" remark-parse: "npm:^9.0.0" remark-slate: "npm:^1.8.6" @@ -5797,12 +5797,12 @@ __metadata: languageName: unknown linkType: soft -"@udecode/plate-ui-list@npm:16.3.0, @udecode/plate-ui-list@workspace:packages/ui/nodes/list": +"@udecode/plate-ui-list@npm:16.4.1, @udecode/plate-ui-list@workspace:packages/ui/nodes/list": version: 0.0.0-use.local resolution: "@udecode/plate-ui-list@workspace:packages/ui/nodes/list" dependencies: "@udecode/plate-core": "npm:16.3.0" - "@udecode/plate-list": "npm:16.3.0" + "@udecode/plate-list": "npm:16.4.1" "@udecode/plate-styled-components": "npm:16.3.0" "@udecode/plate-ui-toolbar": "npm:16.3.0" peerDependencies: @@ -5940,11 +5940,11 @@ __metadata: languageName: unknown linkType: soft -"@udecode/plate-ui@npm:16.4.0, @udecode/plate-ui@workspace:packages/ui/plate": +"@udecode/plate-ui@npm:16.4.1, @udecode/plate-ui@workspace:packages/ui/plate": version: 0.0.0-use.local resolution: "@udecode/plate-ui@workspace:packages/ui/plate" dependencies: - "@udecode/plate-headless": "npm:16.3.0" + "@udecode/plate-headless": "npm:16.4.1" "@udecode/plate-styled-components": "npm:16.3.0" "@udecode/plate-ui-alignment": "npm:16.3.0" "@udecode/plate-ui-block-quote": "npm:16.3.0" @@ -5957,7 +5957,7 @@ __metadata: "@udecode/plate-ui-font": "npm:16.3.0" "@udecode/plate-ui-line-height": "npm:16.3.0" "@udecode/plate-ui-link": "npm:16.3.0" - "@udecode/plate-ui-list": "npm:16.3.0" + "@udecode/plate-ui-list": "npm:16.4.1" "@udecode/plate-ui-media": "npm:16.3.0" "@udecode/plate-ui-mention": "npm:16.3.0" "@udecode/plate-ui-placeholder": "npm:16.3.0" @@ -5980,8 +5980,8 @@ __metadata: version: 0.0.0-use.local resolution: "@udecode/plate@workspace:packages/plate" dependencies: - "@udecode/plate-headless": "npm:16.3.0" - "@udecode/plate-ui": "npm:16.4.0" + "@udecode/plate-headless": "npm:16.4.1" + "@udecode/plate-ui": "npm:16.4.1" peerDependencies: react: ">=16.8.0" react-dom: ">=16.8.0"