diff --git a/apps/www/package.json b/apps/www/package.json index f3666d9468..ded08ae726 100644 --- a/apps/www/package.json +++ b/apps/www/package.json @@ -50,7 +50,6 @@ "@radix-ui/react-toolbar": "^1.0.4", "@radix-ui/react-tooltip": "^1.0.7", "@udecode/cn": "workspace:^", - "@udecode/plate-affinity-marks": "workspace:^", "@udecode/plate-alignment": "workspace:^", "@udecode/plate-autoformat": "workspace:^", "@udecode/plate-basic-elements": "workspace:^", @@ -83,6 +82,7 @@ "@udecode/plate-line-height": "workspace:^", "@udecode/plate-link": "workspace:^", "@udecode/plate-list": "workspace:^", + "@udecode/plate-marks-affinity": "workspace:^", "@udecode/plate-media": "workspace:^", "@udecode/plate-mention": "workspace:^", "@udecode/plate-node-id": "workspace:^", diff --git a/apps/www/src/registry/default/example/playground-demo.tsx b/apps/www/src/registry/default/example/playground-demo.tsx index cfd5f52edb..3ba32f0c13 100644 --- a/apps/www/src/registry/default/example/playground-demo.tsx +++ b/apps/www/src/registry/default/example/playground-demo.tsx @@ -23,7 +23,6 @@ import { trailingBlockPlugin } from '@/plate/demo/plugins/trailingBlockPlugin'; import { MENTIONABLES } from '@/plate/demo/values/mentionables'; import { usePlaygroundValue } from '@/plate/demo/values/usePlaygroundValue'; import { cn } from '@udecode/cn'; -import { createMarkAffinityPlugin } from '@udecode/plate-affinity-marks'; import { createAlignPlugin } from '@udecode/plate-alignment'; import { createAutoformatPlugin } from '@udecode/plate-autoformat'; import { @@ -34,6 +33,10 @@ import { createSubscriptPlugin, createSuperscriptPlugin, createUnderlinePlugin, + MARK_BOLD, + MARK_ITALIC, + MARK_STRIKETHROUGH, + MARK_UNDERLINE, } from '@udecode/plate-basic-marks'; import { createBlockquotePlugin, @@ -50,7 +53,7 @@ import { ELEMENT_CODE_BLOCK, } from '@udecode/plate-code-block'; import { createComboboxPlugin } from '@udecode/plate-combobox'; -import { createCommentsPlugin } from '@udecode/plate-comments'; +import { createCommentsPlugin, MARK_COMMENT } from '@udecode/plate-comments'; import { createPlugins, Plate, @@ -64,6 +67,11 @@ import { createFontBackgroundColorPlugin, createFontColorPlugin, createFontSizePlugin, + MARK_BG_COLOR, + MARK_COLOR, + MARK_FONT_FAMILY, + MARK_FONT_SIZE, + MARK_FONT_WEIGHT, } from '@udecode/plate-font'; import { createHeadingPlugin, @@ -84,6 +92,7 @@ import { createColumnPlugin } from '@udecode/plate-layout'; import { createLineHeightPlugin } from '@udecode/plate-line-height'; import { createLinkPlugin } from '@udecode/plate-link'; import { createListPlugin, createTodoListPlugin } from '@udecode/plate-list'; +import { createMarkAffinityPlugin } from '@udecode/plate-marks-affinity'; import { createImagePlugin, createMediaEmbedPlugin, @@ -194,13 +203,18 @@ export const usePlaygroundPlugins = ({ createStrikethroughPlugin({ enabled: !!enabled.strikethrough }), createMarkAffinityPlugin({ options: { - pressRightArrowAtBoundary: ( - editor, - currentEndLeafEntry, - nextLeafEntry - ) => { - console.log(editor, 'fj'); - }, + validMarks: [ + MARK_BG_COLOR, + MARK_BOLD, + MARK_COLOR, + MARK_UNDERLINE, + MARK_FONT_FAMILY, + MARK_FONT_SIZE, + MARK_FONT_WEIGHT, + MARK_ITALIC, + MARK_STRIKETHROUGH, + MARK_COMMENT, + ], }, }), createCodePlugin({ enabled: !!enabled.code }), diff --git a/packages/affinity-mark/src/createMarkAffinityPlugin.ts b/packages/affinity-mark/src/createMarkAffinityPlugin.ts deleted file mode 100644 index 951871d0e6..0000000000 --- a/packages/affinity-mark/src/createMarkAffinityPlugin.ts +++ /dev/null @@ -1,133 +0,0 @@ -import { - createPluginFactory, - getPluginOptions, - isSelectionExpanded, -} from '@udecode/plate-common'; - -import { getMarkBoundary } from './getMarkBoundary'; -import { setMarkBoundaryAffinity } from './setMarkBoundaryAffinity'; -import { MarkAffinityPlugin, MarkBoundary } from './types'; - -const MARK_CODE = 'code'; - -const markBoundaryHasMark = (markBoundary: MarkBoundary, mark: string) => { - const [backwardLeafEntry, forwardLeafEntry] = markBoundary; - return ( - (backwardLeafEntry && backwardLeafEntry[0][mark]) || - (forwardLeafEntry && forwardLeafEntry[0][mark]) - ); -}; - -export const KEY_MARK_AFFINITY = 'mark-affinity'; - -export const createMarkAffinityPlugin = createPluginFactory( - { - key: KEY_MARK_AFFINITY, - withOverrides: (editor) => { - const { deleteBackward, move } = editor; - - /** - * On backspace, if the deletion results in the cursor being at a mark - * boundary, then the affinity should be forward. If the deletion removes - * a character from the left mark, then the affinity should be backward. - */ - editor.deleteBackward = (unit) => { - if ( - unit === 'character' && - editor.selection && - !isSelectionExpanded(editor) - ) { - const [leftMarkEntryBefore] = getMarkBoundary(editor) ?? [null]; - - const removingFromLeftMark = - leftMarkEntryBefore && leftMarkEntryBefore[0].text.length > 1; - - deleteBackward(unit); - - const afterMarkBoundary = getMarkBoundary(editor); - - if (afterMarkBoundary) { - setMarkBoundaryAffinity( - editor, - afterMarkBoundary, - removingFromLeftMark ? 'backward' : 'forward' - ); - } - return; - } - - deleteBackward(unit); - }; - - editor.move = (options) => { - const { - unit = 'character', - distance = 1, - reverse = false, - } = options || {}; - if ( - unit === 'character' && - distance === 1 && - editor.selection && - !isSelectionExpanded(editor) - ) { - // const beforeMarkBoundary = getMarkBoundary(editor); - - // /** - // * If the cursor is at the start or end of a list of text nodes and - // * inside a code mark, then moving outside the mark should set the - // * affinity accordingly. - // */ - // if ( - // beforeMarkBoundary && - // markBoundaryHasMark(beforeMarkBoundary, MARK_CODE) && - // beforeMarkBoundary[reverse ? 0 : 1] === null && - // getMarkBoundaryAffinity(editor, beforeMarkBoundary) === - // (reverse ? 'forward' : 'backward') - // ) { - // setMarkBoundaryAffinity( - // editor, - // beforeMarkBoundary, - // reverse ? 'backward' : 'forward' - // ); - // return; - // } - - // move(options); - - const afterMarkBoundary = getMarkBoundary(editor); - - if (!afterMarkBoundary) return move(options); - - console.log('🚀 ~ afterMarkBoundary:', afterMarkBoundary); - - /** - * If the move places the cursor at a mark boundary, then the affinity - * should be set to the direction the cursor came from. - */ - const currentEndLeafEntry = afterMarkBoundary[0]; - const nextLeafEntry = afterMarkBoundary[1]; - const { pressRightArrowAtBoundary } = - getPluginOptions(editor, KEY_MARK_AFFINITY); - - pressRightArrowAtBoundary && - pressRightArrowAtBoundary( - editor, - currentEndLeafEntry!, - nextLeafEntry! - ); - - // setMarkBoundaryAffinity( - // editor, - // afterMarkBoundary, - // reverse ? 'forward' : 'backward' - // ); - } - - move(options); - }; - - return editor; - }, - } -); diff --git a/packages/affinity-mark/.npmignore b/packages/mark-affinity/.npmignore similarity index 100% rename from packages/affinity-mark/.npmignore rename to packages/mark-affinity/.npmignore diff --git a/packages/affinity-mark/CHANGELOG.md b/packages/mark-affinity/CHANGELOG.md similarity index 100% rename from packages/affinity-mark/CHANGELOG.md rename to packages/mark-affinity/CHANGELOG.md diff --git a/packages/affinity-mark/README.md b/packages/mark-affinity/README.md similarity index 100% rename from packages/affinity-mark/README.md rename to packages/mark-affinity/README.md diff --git a/packages/affinity-mark/package.json b/packages/mark-affinity/package.json similarity index 97% rename from packages/affinity-mark/package.json rename to packages/mark-affinity/package.json index 6b8d3a5ef7..06ea41432c 100644 --- a/packages/affinity-mark/package.json +++ b/packages/mark-affinity/package.json @@ -1,5 +1,5 @@ { - "name": "@udecode/plate-affinity-marks", + "name": "@udecode/plate-marks-affinity", "version": "31.0.0", "description": "Basic marks plugin for Plate", "license": "MIT", diff --git a/packages/mark-affinity/src/createMarkAffinityPlugin.ts b/packages/mark-affinity/src/createMarkAffinityPlugin.ts new file mode 100644 index 0000000000..e2d684ee7f --- /dev/null +++ b/packages/mark-affinity/src/createMarkAffinityPlugin.ts @@ -0,0 +1,13 @@ +import { createPluginFactory } from '@udecode/plate-common'; + +import { MarkAffinityPlugin } from './types'; +import { withMarkAffinity } from './withMarkAffinity'; + +export const KEY_MARK_AFFINITY = 'mark-affinity'; + +export const createMarkAffinityPlugin = createPluginFactory( + { + key: KEY_MARK_AFFINITY, + withOverrides: withMarkAffinity, + } +); diff --git a/packages/mark-affinity/src/index.ts b/packages/mark-affinity/src/index.ts new file mode 100644 index 0000000000..6eb6f4ba5e --- /dev/null +++ b/packages/mark-affinity/src/index.ts @@ -0,0 +1,9 @@ +/** + * @file Automatically generated by barrelsby. + */ + +export * from './createMarkAffinityPlugin'; +export * from './types'; +export * from './withMarkAffinity'; +export * from './queries/index'; +export * from './transforms/index'; diff --git a/packages/affinity-mark/src/getMarkBoundary.ts b/packages/mark-affinity/src/queries/getMarkBoundary.ts similarity index 97% rename from packages/affinity-mark/src/getMarkBoundary.ts rename to packages/mark-affinity/src/queries/getMarkBoundary.ts index 34dbd183d5..022279da0d 100644 --- a/packages/affinity-mark/src/getMarkBoundary.ts +++ b/packages/mark-affinity/src/queries/getMarkBoundary.ts @@ -10,7 +10,7 @@ import { } from '@udecode/plate-common'; import { NodeEntry, Path } from 'slate'; -import { MarkBoundary } from './types'; +import { MarkBoundary } from '../types'; export const getMarkBoundary = (editor: PlateEditor): MarkBoundary | null => { const { selection } = editor; diff --git a/packages/affinity-mark/src/getMarkBoundaryAffinity.ts b/packages/mark-affinity/src/queries/getMarkBoundaryAffinity.ts similarity index 97% rename from packages/affinity-mark/src/getMarkBoundaryAffinity.ts rename to packages/mark-affinity/src/queries/getMarkBoundaryAffinity.ts index 9203b2fdd1..ebcbb0a216 100644 --- a/packages/affinity-mark/src/getMarkBoundaryAffinity.ts +++ b/packages/mark-affinity/src/queries/getMarkBoundaryAffinity.ts @@ -1,7 +1,7 @@ import { getNodeProps, PlateEditor, TText } from '@udecode/plate-common'; import isEqual from 'lodash/isEqual'; -import { MarkBoundary } from './types'; +import { MarkBoundary } from '../types'; const IS_FIREFOX = false; diff --git a/packages/affinity-mark/src/index.ts b/packages/mark-affinity/src/queries/index.ts similarity index 54% rename from packages/affinity-mark/src/index.ts rename to packages/mark-affinity/src/queries/index.ts index ca9c1a0328..95ad6c2bd2 100644 --- a/packages/affinity-mark/src/index.ts +++ b/packages/mark-affinity/src/queries/index.ts @@ -2,8 +2,5 @@ * @file Automatically generated by barrelsby. */ -export * from './createMarkAffinityPlugin'; export * from './getMarkBoundary'; export * from './getMarkBoundaryAffinity'; -export * from './setMarkBoundaryAffinity'; -export * from './types'; diff --git a/packages/mark-affinity/src/transforms/index.ts b/packages/mark-affinity/src/transforms/index.ts new file mode 100644 index 0000000000..cc9ffc3ed9 --- /dev/null +++ b/packages/mark-affinity/src/transforms/index.ts @@ -0,0 +1,5 @@ +/** + * @file Automatically generated by barrelsby. + */ + +export * from './setMarkBoundaryAffinity'; diff --git a/packages/affinity-mark/src/setMarkBoundaryAffinity.ts b/packages/mark-affinity/src/transforms/setMarkBoundaryAffinity.ts similarity index 96% rename from packages/affinity-mark/src/setMarkBoundaryAffinity.ts rename to packages/mark-affinity/src/transforms/setMarkBoundaryAffinity.ts index 95e53a9578..c0b433ed25 100644 --- a/packages/affinity-mark/src/setMarkBoundaryAffinity.ts +++ b/packages/mark-affinity/src/transforms/setMarkBoundaryAffinity.ts @@ -1,7 +1,7 @@ import { getEndPoint, getNodeProps, PlateEditor } from '@udecode/plate-common'; import { Point } from 'slate'; -import { MarkBoundary } from './types'; +import { MarkBoundary } from '../types'; export const setMarkBoundaryAffinity = ( editor: PlateEditor, diff --git a/packages/affinity-mark/src/types.ts b/packages/mark-affinity/src/types.ts similarity index 63% rename from packages/affinity-mark/src/types.ts rename to packages/mark-affinity/src/types.ts index 7bc6a0df94..11262bc3be 100644 --- a/packages/affinity-mark/src/types.ts +++ b/packages/mark-affinity/src/types.ts @@ -2,11 +2,7 @@ import { TText } from '@udecode/plate-common'; import { NodeEntry } from 'slate'; export interface MarkAffinityPlugin { - pressRightArrowAtBoundary?: ( - editor: any, - currentEndLeafEntry?: NodeEntry, - nextLeafEntry?: NodeEntry - ) => void; + validMarks?: string[]; } export type MarkBoundary = diff --git a/packages/mark-affinity/src/withMarkAffinity.ts b/packages/mark-affinity/src/withMarkAffinity.ts new file mode 100644 index 0000000000..52214402ae --- /dev/null +++ b/packages/mark-affinity/src/withMarkAffinity.ts @@ -0,0 +1,116 @@ +import { + getMarks, + getPluginOptions, + isSelectionExpanded, + PlateEditor, +} from '@udecode/plate-common'; + +import { KEY_MARK_AFFINITY } from './createMarkAffinityPlugin'; +import { getMarkBoundary } from './queries/getMarkBoundary'; +import { getMarkBoundaryAffinity } from './queries/getMarkBoundaryAffinity'; +import { setMarkBoundaryAffinity } from './transforms/setMarkBoundaryAffinity'; +import { MarkAffinityPlugin } from './types'; + +export const withMarkAffinity = (editor: PlateEditor) => { + const { deleteBackward, move } = editor; + + /** + * On backspace, if the deletion results in the cursor being at a mark + * boundary, then the affinity should be forward. If the deletion removes + * a character from the left mark, then the affinity should be backward. + */ + editor.deleteBackward = (unit) => { + if ( + unit === 'character' && + editor.selection && + !isSelectionExpanded(editor) + ) { + const [leftMarkEntryBefore] = getMarkBoundary(editor) ?? [null]; + const removingFromLeftMark = + leftMarkEntryBefore && leftMarkEntryBefore[0].text.length > 1; + + deleteBackward(unit); + + const afterMarkBoundary = getMarkBoundary(editor); + + if (afterMarkBoundary) { + setMarkBoundaryAffinity( + editor, + afterMarkBoundary, + removingFromLeftMark ? 'backward' : 'forward' + ); + } + return; + } + + deleteBackward(unit); + }; + + editor.move = (options) => { + const { unit = 'character', distance = 1, reverse = false } = options || {}; + if ( + unit === 'character' && + distance === 1 && + editor.selection && + !isSelectionExpanded(editor) + ) { + const { validMarks } = getPluginOptions( + editor, + KEY_MARK_AFFINITY + ); + + const _marks = getMarks(editor); + const marks = _marks ? Object.keys(_marks) : []; + + //TODO: note the comment_x + if (!validMarks) return move(options); + if (marks.length > 0) { + for (const mark of marks) { + if (!validMarks.includes(mark)) return move(options); + } + } + + const beforeMarkBoundary = getMarkBoundary(editor); + + /** + * If the cursor is at the start or end of a list of text nodes + * then moving outside the mark should set the + * affinity accordingly. + */ + if ( + beforeMarkBoundary && + beforeMarkBoundary[reverse ? 0 : 1] === null && + getMarkBoundaryAffinity(editor, beforeMarkBoundary) === + (reverse ? 'forward' : 'backward') + ) { + setMarkBoundaryAffinity( + editor, + beforeMarkBoundary, + reverse ? 'backward' : 'forward' + ); + return; + } + + move(options); + + const afterMarkBoundary = getMarkBoundary(editor); + + /** + * If the move places the cursor at a mark boundary, then the affinity + * should be set to the direction the cursor came from. + */ + if (afterMarkBoundary) { + setMarkBoundaryAffinity( + editor, + afterMarkBoundary, + reverse ? 'forward' : 'backward' + ); + } + return; + } + + move(options); + }; + + return editor; +}; diff --git a/packages/affinity-mark/tsconfig.json b/packages/mark-affinity/tsconfig.json similarity index 100% rename from packages/affinity-mark/tsconfig.json rename to packages/mark-affinity/tsconfig.json diff --git a/yarn.lock b/yarn.lock index c1415460e5..81e1cb55a0 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5475,23 +5475,6 @@ __metadata: languageName: unknown linkType: soft -"@udecode/plate-affinity-marks@workspace:^, @udecode/plate-affinity-marks@workspace:packages/affinity-mark": - version: 0.0.0-use.local - resolution: "@udecode/plate-affinity-marks@workspace:packages/affinity-mark" - dependencies: - "@udecode/plate-common": "workspace:^" - lodash: "npm:^4.17.21" - peerDependencies: - "@udecode/plate-common": ">=31.3.2" - react: ">=16.8.0" - react-dom: ">=16.8.0" - slate: ">=0.94.0" - slate-history: ">=0.93.0" - slate-hyperscript: ">=0.66.0" - slate-react: ">=0.99.0" - languageName: unknown - linkType: soft - "@udecode/plate-alignment@npm:31.0.0, @udecode/plate-alignment@workspace:^, @udecode/plate-alignment@workspace:packages/alignment": version: 0.0.0-use.local resolution: "@udecode/plate-alignment@workspace:packages/alignment" @@ -6054,6 +6037,23 @@ __metadata: languageName: unknown linkType: soft +"@udecode/plate-marks-affinity@workspace:^, @udecode/plate-marks-affinity@workspace:packages/mark-affinity": + version: 0.0.0-use.local + resolution: "@udecode/plate-marks-affinity@workspace:packages/mark-affinity" + dependencies: + "@udecode/plate-common": "workspace:^" + lodash: "npm:^4.17.21" + peerDependencies: + "@udecode/plate-common": ">=31.3.2" + react: ">=16.8.0" + react-dom: ">=16.8.0" + slate: ">=0.94.0" + slate-history: ">=0.93.0" + slate-hyperscript: ">=0.66.0" + slate-react: ">=0.99.0" + languageName: unknown + linkType: soft + "@udecode/plate-media@npm:31.0.0, @udecode/plate-media@workspace:^, @udecode/plate-media@workspace:packages/media": version: 0.0.0-use.local resolution: "@udecode/plate-media@workspace:packages/media" @@ -21325,7 +21325,6 @@ __metadata: "@types/react-color": "npm:^3.0.12" "@types/react-syntax-highlighter": "npm:^15.5.11" "@udecode/cn": "workspace:^" - "@udecode/plate-affinity-marks": "workspace:^" "@udecode/plate-alignment": "workspace:^" "@udecode/plate-autoformat": "workspace:^" "@udecode/plate-basic-elements": "workspace:^" @@ -21358,6 +21357,7 @@ __metadata: "@udecode/plate-line-height": "workspace:^" "@udecode/plate-link": "workspace:^" "@udecode/plate-list": "workspace:^" + "@udecode/plate-marks-affinity": "workspace:^" "@udecode/plate-media": "workspace:^" "@udecode/plate-mention": "workspace:^" "@udecode/plate-node-id": "workspace:^"