Skip to content

Commit 7db251b

Browse files
authored
Merge pull request #4097 from udecode/templates/45
2 parents 32718ba + 55cbf87 commit 7db251b

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

58 files changed

+2747
-848
lines changed

templates/plate-playground-template/package.json

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -30,23 +30,23 @@
3030
"@radix-ui/react-tooltip": "^1.1.8",
3131
"@udecode/cmdk": "^0.2.0",
3232
"@udecode/cn": "44.0.1",
33-
"@udecode/plate": "44.0.1",
34-
"@udecode/plate-ai": "44.0.0",
33+
"@udecode/plate": "45.0.2",
34+
"@udecode/plate-ai": "44.0.3",
3535
"@udecode/plate-alignment": "44.0.0",
3636
"@udecode/plate-autoformat": "44.0.0",
3737
"@udecode/plate-basic-elements": "44.0.0",
38-
"@udecode/plate-basic-marks": "44.0.0",
38+
"@udecode/plate-basic-marks": "45.0.0",
3939
"@udecode/plate-block-quote": "44.0.0",
4040
"@udecode/plate-break": "44.0.0",
4141
"@udecode/plate-callout": "44.0.0",
4242
"@udecode/plate-caption": "44.0.0",
4343
"@udecode/plate-code-block": "44.0.0",
4444
"@udecode/plate-combobox": "44.0.0",
45-
"@udecode/plate-comments": "44.0.0",
45+
"@udecode/plate-comments": "45.0.0",
4646
"@udecode/plate-cursor": "44.0.0",
4747
"@udecode/plate-date": "44.0.0",
4848
"@udecode/plate-dnd": "44.0.0",
49-
"@udecode/plate-docx": "44.0.0",
49+
"@udecode/plate-docx": "45.0.0",
5050
"@udecode/plate-emoji": "44.0.0",
5151
"@udecode/plate-excalidraw": "44.0.0",
5252
"@udecode/plate-floating": "44.0.0",
@@ -55,24 +55,25 @@
5555
"@udecode/plate-highlight": "44.0.0",
5656
"@udecode/plate-horizontal-rule": "44.0.0",
5757
"@udecode/plate-indent": "44.0.0",
58-
"@udecode/plate-indent-list": "44.0.0",
58+
"@udecode/plate-indent-list": "44.0.5",
5959
"@udecode/plate-juice": "44.0.0",
6060
"@udecode/plate-kbd": "44.0.0",
6161
"@udecode/plate-layout": "44.0.0",
6262
"@udecode/plate-line-height": "44.0.0",
63-
"@udecode/plate-link": "44.0.0",
63+
"@udecode/plate-link": "44.0.4",
6464
"@udecode/plate-markdown": "44.0.0",
6565
"@udecode/plate-math": "44.0.0",
66-
"@udecode/plate-media": "44.0.0",
66+
"@udecode/plate-media": "44.0.6",
6767
"@udecode/plate-mention": "44.0.0",
6868
"@udecode/plate-node-id": "44.0.0",
6969
"@udecode/plate-reset-node": "44.0.0",
7070
"@udecode/plate-resizable": "44.0.0",
7171
"@udecode/plate-select": "44.0.0",
7272
"@udecode/plate-selection": "44.0.0",
7373
"@udecode/plate-slash-command": "44.0.0",
74+
"@udecode/plate-suggestion": "^45.0.0",
7475
"@udecode/plate-tabbable": "44.0.0",
75-
"@udecode/plate-table": "44.0.0",
76+
"@udecode/plate-table": "45.0.0",
7677
"@udecode/plate-toggle": "44.0.0",
7778
"@udecode/plate-trailing-block": "44.0.0",
7879
"@uploadthing/react": "7.1.0",

templates/plate-playground-template/pnpm-lock.yaml

Lines changed: 248 additions & 210 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

templates/plate-playground-template/src/components/editor/plate-editor.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@ import { HTML5Backend } from 'react-dnd-html5-backend';
66

77
import { Plate } from '@udecode/plate/react';
88

9-
import { SettingsDialog } from '@/components/editor/settings';
109
import { useCreateEditor } from '@/components/editor/use-create-editor';
10+
import { SettingsDialog } from '@/components/editor/settings';
1111
import { Editor, EditorContainer } from '@/components/plate-ui/editor';
1212

1313
export function PlateEditor() {
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
'use client';
2+
3+
import { BlockSelectionPlugin } from '@udecode/plate-selection/react';
4+
5+
import { BlockSelection } from '@/components/plate-ui/block-selection';
6+
7+
export const blockSelectionPlugins = [
8+
BlockSelectionPlugin.configure(({ editor }) => ({
9+
options: {
10+
enableContextMenu: true,
11+
isSelectable: (element, path) => {
12+
return (
13+
!['code_line', 'column', 'td'].includes(element.type) &&
14+
!editor.api.block({ above: true, at: path, match: { type: 'tr' } })
15+
);
16+
},
17+
},
18+
render: {
19+
belowRootNodes: (props) => {
20+
if (!props.className?.includes('slate-selectable')) return null;
21+
22+
return <BlockSelection />;
23+
},
24+
},
25+
})),
26+
] as const;
27+
28+
export const blockSelectionReadOnlyPlugin = BlockSelectionPlugin.configure({
29+
api: {},
30+
extendEditor: null,
31+
handlers: {},
32+
options: {},
33+
render: {},
34+
useHooks: null,
35+
});
Lines changed: 82 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -1,65 +1,86 @@
11
'use client';
22

3-
import type { TComment } from '@udecode/plate-comments';
4-
5-
import { CommentsPlugin } from '@udecode/plate-comments/react';
6-
7-
import { CommentsPopover } from '@/components/plate-ui/comments-popover';
8-
9-
const commentsData: Record<string, TComment> = {
10-
1: {
11-
id: '1',
12-
createdAt: 1_663_453_625_129,
13-
userId: '1',
14-
value: [{ children: [{ text: 'This is a comment.' }], type: 'p' }],
15-
},
16-
2: {
17-
id: '2',
18-
createdAt: 1_663_453_729_191,
19-
userId: '1',
20-
value: [
21-
{ children: [{ text: 'Can you review this one @12joan?' }], type: 'p' },
22-
],
23-
},
24-
3: {
25-
id: '3',
26-
createdAt: 1_663_453_740_180,
27-
isResolved: true,
28-
userId: '1',
29-
value: [{ children: [{ text: 'This is a resolved comment.' }], type: 'p' }],
30-
},
31-
4: {
32-
id: '4',
33-
createdAt: 1_663_453_740_181,
34-
parentId: '2',
35-
userId: '2',
36-
value: [{ children: [{ text: 'LGTM.' }], type: 'p' }],
37-
},
38-
5: {
39-
id: '4',
40-
createdAt: 1_663_453_740_182,
41-
parentId: '2',
42-
userId: '1',
43-
value: [{ children: [{ text: 'Thanks!' }], type: 'p' }],
44-
},
45-
};
46-
47-
export const commentsPlugin = CommentsPlugin.configure({
48-
options: {
49-
comments: commentsData,
50-
myUserId: '1',
51-
users: {
52-
1: {
53-
id: '1',
54-
avatarUrl: 'https://avatars.githubusercontent.com/u/19695832?s=96&v=4',
55-
name: 'zbeyens',
56-
},
57-
2: {
58-
id: '2',
59-
avatarUrl: 'https://avatars.githubusercontent.com/u/4272090?v=4',
60-
name: '12joan',
3+
import type { ExtendConfig, Path } from '@udecode/plate';
4+
5+
import { isSlateString } from '@udecode/plate';
6+
import {
7+
type BaseCommentsConfig,
8+
BaseCommentsPlugin,
9+
} from '@udecode/plate-comments';
10+
import { toTPlatePlugin, useHotkeys } from '@udecode/plate/react';
11+
12+
export type CommentsConfig = ExtendConfig<
13+
BaseCommentsConfig,
14+
{
15+
activeId: string | null;
16+
commentingBlock: Path | null;
17+
hotkey: string[];
18+
hoverId: string | null;
19+
uniquePathMap: Map<string, Path>;
20+
}
21+
>;
22+
23+
export const commentsPlugin = toTPlatePlugin<CommentsConfig>(
24+
BaseCommentsPlugin,
25+
{
26+
handlers: {
27+
onClick: ({ api, event, setOption, type }) => {
28+
let leaf = event.target as HTMLElement;
29+
let isSet = false;
30+
31+
const unsetActiveSuggestion = () => {
32+
setOption('activeId', null);
33+
isSet = true;
34+
};
35+
36+
if (!isSlateString(leaf)) unsetActiveSuggestion();
37+
38+
while (leaf.parentElement) {
39+
if (leaf.classList.contains(`slate-${type}`)) {
40+
const commentsEntry = api.comment!.node();
41+
42+
if (!commentsEntry) {
43+
unsetActiveSuggestion();
44+
45+
break;
46+
}
47+
48+
const id = api.comment!.nodeId(commentsEntry[0]);
49+
50+
setOption('activeId', id ?? null);
51+
isSet = true;
52+
53+
break;
54+
}
55+
56+
leaf = leaf.parentElement;
57+
}
58+
59+
if (!isSet) unsetActiveSuggestion();
6160
},
6261
},
63-
},
64-
render: { afterEditable: () => <CommentsPopover /> },
65-
});
62+
options: {
63+
activeId: null,
64+
commentingBlock: null,
65+
hotkey: ['meta+shift+m', 'ctrl+shift+m'],
66+
hoverId: null,
67+
uniquePathMap: new Map(),
68+
},
69+
useHooks: ({ editor, getOptions }) => {
70+
const { hotkey } = getOptions();
71+
useHotkeys(
72+
hotkey!,
73+
(e) => {
74+
if (!editor.selection) return;
75+
76+
e.preventDefault();
77+
78+
if (!editor.api.isExpanded()) return;
79+
},
80+
{
81+
enableOnContentEditable: true,
82+
}
83+
);
84+
},
85+
}
86+
);

templates/plate-playground-template/src/components/editor/plugins/editor-plugins.tsx

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@ import { TrailingBlockPlugin } from '@udecode/plate-trailing-block';
2222

2323
import { FixedToolbarPlugin } from '@/components/editor/plugins/fixed-toolbar-plugin';
2424
import { FloatingToolbarPlugin } from '@/components/editor/plugins/floating-toolbar-plugin';
25+
import { BlockDiscussion } from '@/components/plate-ui/block-discussion';
26+
import { SuggestionBelowNodes } from '@/components/plate-ui/suggestion-line-break';
2527

2628
import { aiPlugins } from './ai-plugins';
2729
import { alignPlugin } from './align-plugin';
@@ -40,7 +42,9 @@ import { linkPlugin } from './link-plugin';
4042
import { mediaPlugins } from './media-plugins';
4143
import { mentionPlugin } from './mention-plugin';
4244
import { resetBlockTypePlugin } from './reset-block-type-plugin';
45+
import { skipMarkPlugin } from './skip-mark-plugin';
4346
import { softBreakPlugin } from './soft-break-plugin';
47+
import { suggestionPlugin } from './suggestion-plugin';
4448
import { tablePlugin } from './table-plugin';
4549
import { tocPlugin } from './toc-plugin';
4650

@@ -64,14 +68,20 @@ export const viewPlugins = [
6468
FontSizePlugin,
6569
HighlightPlugin,
6670
KbdPlugin,
71+
skipMarkPlugin,
6772

6873
// Block Style
6974
alignPlugin,
7075
...indentListPlugins,
7176
lineHeightPlugin,
7277

7378
// Collaboration
74-
commentsPlugin,
79+
commentsPlugin.configure({
80+
render: { aboveNodes: BlockDiscussion as any },
81+
}),
82+
suggestionPlugin.configure({
83+
render: { belowNodes: SuggestionBelowNodes as any },
84+
}),
7585
] as const;
7686

7787
export const editorPlugins = [
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
'use client';
2+
import { CodePlugin, SkipMarkPlugin } from '@udecode/plate-basic-marks/react';
3+
import { CommentsPlugin } from '@udecode/plate-comments/react';
4+
import { SuggestionPlugin } from '@udecode/plate-suggestion/react';
5+
6+
export const skipMarkPlugin = SkipMarkPlugin.configure({
7+
options: {
8+
query: {
9+
allow: [SuggestionPlugin.key, CodePlugin.key, CommentsPlugin.key],
10+
},
11+
},
12+
});
Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
'use client';
2+
3+
import {
4+
type ExtendConfig,
5+
type Path,
6+
isSlateEditor,
7+
isSlateElement,
8+
isSlateString,
9+
} from '@udecode/plate';
10+
import {
11+
type BaseSuggestionConfig,
12+
BaseSuggestionPlugin,
13+
} from '@udecode/plate-suggestion';
14+
import { toTPlatePlugin } from '@udecode/plate/react';
15+
16+
import { BlockSuggestion } from '@/components/plate-ui/block-suggestion';
17+
18+
export type SuggestionConfig = ExtendConfig<
19+
BaseSuggestionConfig,
20+
{
21+
activeId: string | null;
22+
currentUserId: string;
23+
hoverId: string | null;
24+
uniquePathMap: Map<string, Path>;
25+
}
26+
>;
27+
28+
export const suggestionPlugin = toTPlatePlugin<SuggestionConfig>(
29+
BaseSuggestionPlugin,
30+
{
31+
handlers: {
32+
// unset active suggestion when clicking outside of suggestion
33+
onClick: ({ api, event, setOption, type }) => {
34+
let leaf = event.target as HTMLElement;
35+
let isSet = false;
36+
37+
const unsetActiveSuggestion = () => {
38+
setOption('activeId', null);
39+
isSet = true;
40+
};
41+
42+
if (!isSlateString(leaf)) unsetActiveSuggestion();
43+
44+
while (
45+
leaf.parentElement &&
46+
!isSlateElement(leaf.parentElement) &&
47+
!isSlateEditor(leaf.parentElement)
48+
) {
49+
if (leaf.classList.contains(`slate-${type}`)) {
50+
const suggestionEntry = api.suggestion!.node({
51+
isText: true,
52+
});
53+
54+
if (!suggestionEntry) {
55+
unsetActiveSuggestion();
56+
57+
break;
58+
}
59+
60+
const id = api.suggestion!.nodeId(suggestionEntry[0]);
61+
62+
setOption('activeId', id ?? null);
63+
isSet = true;
64+
65+
break;
66+
}
67+
68+
leaf = leaf.parentElement;
69+
}
70+
71+
if (!isSet) unsetActiveSuggestion();
72+
},
73+
},
74+
options: {
75+
activeId: null,
76+
currentUserId: 'user3',
77+
hoverId: null,
78+
uniquePathMap: new Map(),
79+
},
80+
render: {
81+
belowRootNodes: ({ api, element }) => {
82+
if (!api.suggestion!.isBlockSuggestion(element)) {
83+
return null;
84+
}
85+
86+
return <BlockSuggestion element={element} />;
87+
},
88+
},
89+
}
90+
);

0 commit comments

Comments
 (0)