From 202b8be4a4aa900458df5cbd5b012b5bf8457c6c Mon Sep 17 00:00:00 2001 From: Felix Feng Date: Sat, 2 Nov 2024 20:47:49 +0800 Subject: [PATCH 01/25] fix --- packages/media/src/lib/image/BaseImagePlugin.ts | 5 ++++- packages/media/src/lib/media/types.ts | 1 + .../media/src/lib/placeholder/transforms/setMediaNode.ts | 3 +++ packages/media/src/react/placeholder/placeholderStore.ts | 5 +++++ .../media/src/react/placeholder/usePlaceholderElement.ts | 2 ++ .../media/src/react/placeholder/usePlaceholderPopover.ts | 4 +++- 6 files changed, 18 insertions(+), 2 deletions(-) diff --git a/packages/media/src/lib/image/BaseImagePlugin.ts b/packages/media/src/lib/image/BaseImagePlugin.ts index b461f12bae..99b8bf98c3 100644 --- a/packages/media/src/lib/image/BaseImagePlugin.ts +++ b/packages/media/src/lib/image/BaseImagePlugin.ts @@ -4,7 +4,10 @@ import type { MediaPluginOptions, TMediaElement } from '../media'; import { withImage } from './withImage'; -export interface TImageElement extends TMediaElement {} +export interface TImageElement extends TMediaElement { + initialHeight?: number; + initialWidth?: number; +} export type ImageConfig = PluginConfig< 'img', diff --git a/packages/media/src/lib/media/types.ts b/packages/media/src/lib/media/types.ts index 53fc5b6956..386d72aa1f 100644 --- a/packages/media/src/lib/media/types.ts +++ b/packages/media/src/lib/media/types.ts @@ -4,6 +4,7 @@ export interface TMediaElement extends TElement { url: string; id?: string; align?: 'center' | 'left' | 'right'; + fromPlaceholderId?: string; isUpload?: boolean; name?: string; } diff --git a/packages/media/src/lib/placeholder/transforms/setMediaNode.ts b/packages/media/src/lib/placeholder/transforms/setMediaNode.ts index d5153681b8..6b55d984a8 100644 --- a/packages/media/src/lib/placeholder/transforms/setMediaNode.ts +++ b/packages/media/src/lib/placeholder/transforms/setMediaNode.ts @@ -7,6 +7,9 @@ import { type props = { type: string; url: string; + fromPlaceholderId?: string; + initialHeight?: number; + initialWidth?: number; isUpload?: boolean; name?: string; width?: number; diff --git a/packages/media/src/react/placeholder/placeholderStore.ts b/packages/media/src/react/placeholder/placeholderStore.ts index 1513ca5b04..9115a34fc9 100644 --- a/packages/media/src/react/placeholder/placeholderStore.ts +++ b/packages/media/src/react/placeholder/placeholderStore.ts @@ -2,6 +2,10 @@ import { createAtomStore } from '@udecode/plate-common/react'; type Progresses = Record; interface PlaceholderStore { + mediaSize: { + height: number; + width: number; + } | null; isUploading: boolean; progresses: Progresses; updatedFiles: File[]; @@ -11,6 +15,7 @@ export const { PlaceholderProvider, placeholderStore, usePlaceholderStore } = createAtomStore( { isUploading: false, + mediaSize: null, progresses: {}, updatedFiles: [], } as PlaceholderStore, diff --git a/packages/media/src/react/placeholder/usePlaceholderElement.ts b/packages/media/src/react/placeholder/usePlaceholderElement.ts index 587f609b2a..c9f3545e04 100644 --- a/packages/media/src/react/placeholder/usePlaceholderElement.ts +++ b/packages/media/src/react/placeholder/usePlaceholderElement.ts @@ -17,6 +17,7 @@ export const usePlaceholderElementState = () => { const progresses = usePlaceholderStore().get.progresses(); const isUploading = usePlaceholderStore().get.isUploading(); const updatedFiles = usePlaceholderStore().get.updatedFiles(); + const setMediaSize = usePlaceholderStore().set.mediaSize(); const { mediaType } = useElement( BasePlaceholderPlugin.key @@ -34,6 +35,7 @@ export const usePlaceholderElementState = () => { progressing, readOnly, selected, + setMediaSize, updatedFiles, }; }; diff --git a/packages/media/src/react/placeholder/usePlaceholderPopover.ts b/packages/media/src/react/placeholder/usePlaceholderPopover.ts index 28da92fcfb..cfdf8f8e0a 100644 --- a/packages/media/src/react/placeholder/usePlaceholderPopover.ts +++ b/packages/media/src/react/placeholder/usePlaceholderPopover.ts @@ -19,7 +19,6 @@ export const usePlaceholderPopoverState = () => { const focused = useFocused(); const selectionCollapsed = useEditorSelector( - // eslint-disable-next-line @typescript-eslint/no-shadow (editor) => !isSelectionExpanded(editor), [] ); @@ -31,11 +30,14 @@ export const usePlaceholderPopoverState = () => { const setIsUploading = usePlaceholderStore().set.isUploading(); const setUpdatedFiles = usePlaceholderStore().set.updatedFiles(); + const mediaSize = usePlaceholderStore().get.mediaSize(); + return { id, editor, element, focused, + mediaSize, mediaType, readOnly, selected, From cea47104da1e82359714c56871dce3e91feebb04 Mon Sep 17 00:00:00 2001 From: Felix Feng Date: Sat, 2 Nov 2024 20:54:38 +0800 Subject: [PATCH 02/25] changeset --- .changeset/sour-bananas-arrive.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/sour-bananas-arrive.md diff --git a/.changeset/sour-bananas-arrive.md b/.changeset/sour-bananas-arrive.md new file mode 100644 index 0000000000..4ea2460ddd --- /dev/null +++ b/.changeset/sour-bananas-arrive.md @@ -0,0 +1,5 @@ +--- +'@udecode/plate-media': minor +--- + +Add `initialHeight` and `initialWidth` in `TImageElement` This will display a loading placeholder while the image is still loading, which helps maintain a consistent height. From 318e608569786a9b17de16473b5de77c0ae3cec9 Mon Sep 17 00:00:00 2001 From: Felix Feng Date: Sat, 2 Nov 2024 20:57:31 +0800 Subject: [PATCH 03/25] docs --- .changeset/sour-bananas-arrive.md | 1 + 1 file changed, 1 insertion(+) diff --git a/.changeset/sour-bananas-arrive.md b/.changeset/sour-bananas-arrive.md index 4ea2460ddd..374a62d04f 100644 --- a/.changeset/sour-bananas-arrive.md +++ b/.changeset/sour-bananas-arrive.md @@ -3,3 +3,4 @@ --- Add `initialHeight` and `initialWidth` in `TImageElement` This will display a loading placeholder while the image is still loading, which helps maintain a consistent height. +Add `fromPlaceholderId` Used to track what was converted from that placeholder plugin. From 47fc2c1eab59ae12c2bc38c81a6b72568a598474 Mon Sep 17 00:00:00 2001 From: Felix Feng Date: Sat, 2 Nov 2024 21:10:03 +0800 Subject: [PATCH 04/25] docs --- .changeset/sour-bananas-arrive.md | 6 +- .../react/placeholder/PlaceholderPlugin.tsx | 149 ++++++++++++++- .../placeholder/transforms/insertMedias.ts | 56 ++++++ .../react/placeholder/utils/validateFiles.ts | 170 ++++++++++++++++++ 4 files changed, 376 insertions(+), 5 deletions(-) create mode 100644 packages/media/src/react/placeholder/transforms/insertMedias.ts create mode 100644 packages/media/src/react/placeholder/utils/validateFiles.ts diff --git a/.changeset/sour-bananas-arrive.md b/.changeset/sour-bananas-arrive.md index 374a62d04f..ba0fa43433 100644 --- a/.changeset/sour-bananas-arrive.md +++ b/.changeset/sour-bananas-arrive.md @@ -2,5 +2,7 @@ '@udecode/plate-media': minor --- -Add `initialHeight` and `initialWidth` in `TImageElement` This will display a loading placeholder while the image is still loading, which helps maintain a consistent height. -Add `fromPlaceholderId` Used to track what was converted from that placeholder plugin. +New `initialHeight` and `initialWidth` in `TImageElement` This will display a loading placeholder while the image is still loading, which helps maintain a consistent height. +Mew `fromPlaceholderId` Used to track what was converted from that placeholder plugin. +New `insertMedias` Used for inserting the placeholder at once. +New `validateFiles` utils for validate the files meet the `mediaConfig`. \ No newline at end of file diff --git a/packages/media/src/react/placeholder/PlaceholderPlugin.tsx b/packages/media/src/react/placeholder/PlaceholderPlugin.tsx index 024c87e7f0..a0e002423b 100644 --- a/packages/media/src/react/placeholder/PlaceholderPlugin.tsx +++ b/packages/media/src/react/placeholder/PlaceholderPlugin.tsx @@ -1,5 +1,148 @@ -import { toPlatePlugin } from '@udecode/plate-common/react'; +import type { PlaceholderConfig } from '@udecode/plate-media'; -import { BasePlaceholderPlugin } from '../../lib/placeholder/BasePlaceholderPlugin'; +import { type ExtendConfig, bindFirst } from '@udecode/plate-common'; +import { findEventRange, toTPlatePlugin } from '@udecode/plate-common/react'; -export const PlaceholderPlugin = toPlatePlugin(BasePlaceholderPlugin); +import { BasePlaceholderPlugin } from '../../lib'; +import { AudioPlugin, FilePlugin, ImagePlugin, VideoPlugin } from '../plugins'; +import { insertMedias } from './transforms/insertMedias'; + +export type MediaType = + | typeof AudioPlugin.key + | typeof FilePlugin.key + | typeof ImagePlugin.key + | typeof VideoPlugin.key; + +export type MediaItemConfig = { + // extensions that are accepted for this media type + accept?: string[]; + // The maximum number of files of this type that can be uploaded. + maxFileCount?: number; + // The maximum file size for a file of this type. FileSize is a string that can be parsed as a number followed by a unit of measurement (B, KB, MB, or GB) + maxFileSize?: string; + // The minimum number of files of this type that must be uploaded. + minFileCount?: number; +}; + +export type PlaceholderApi = { + addUploadingFile: (id: string, file: File) => void; + getUploadingFile: (id: string) => File | undefined; + removeUploadingFile: (id: string) => void; +}; + +export type PlaceholderTransforms = { + insertMedias: (files: FileList) => void; +}; + +export type MediaConfig = Partial>; + +export const PlaceholderPlugin = toTPlatePlugin< + ExtendConfig< + PlaceholderConfig, + { + mediaConfig: MediaConfig; + uploadingFiles: Record; + // Whether multiple files of the same type can be uploaded. + multiple?: boolean; + uploadErrorMessage?: string | null; + uploadMaxFileCount?: number; + }, + { placeholder: PlaceholderApi }, + { placeholder: PlaceholderTransforms } + > +>(BasePlaceholderPlugin, { + options: { + mediaConfig: { + [AudioPlugin.key]: { + accept: ['mp3'], + maxFileCount: 1, + maxFileSize: '8MB', + minFileCount: 1, + }, + [FilePlugin.key]: { + accept: [], + maxFileCount: 1, + maxFileSize: '8MB', + minFileCount: 1, + }, + [ImagePlugin.key]: { + accept: ['.png', '.jpg', '.jpeg'], + maxFileCount: 3, + maxFileSize: '8MB', + minFileCount: 1, + }, + [VideoPlugin.key]: { + accept: ['.mp4'], + maxFileCount: 1, + maxFileSize: '8MB', + minFileCount: 1, + }, + }, + multiple: true, + uploadErrorMessage: null, + uploadMaxFileCount: 3, + uploadingFiles: {}, + }, +}) + .extendTransforms(({ editor }) => ({ + insertMedias: bindFirst(insertMedias, editor), + })) + .extendApi(({ getOption, setOption }) => ({ + addUploadingFile: (id: string, file: File) => { + const uploadingFiles = getOption('uploadingFiles'); + + setOption('uploadingFiles', { + ...uploadingFiles, + [id]: file, + }); + }, + getUploadingFile: (id: string) => { + const uploadingFiles = getOption('uploadingFiles'); + + return uploadingFiles[id]; + }, + removeUploadingFile: (id: string) => { + const uploadingFiles = getOption('uploadingFiles'); + + delete uploadingFiles[id]; + + setOption('uploadingFiles', uploadingFiles); + }, + })) + .extend(() => ({ + handlers: { + onDrop: ({ editor, event, tf }) => { + const { files } = event.dataTransfer; + + if (files.length === 0) return false; + + /** Without this, the dropped file replaces the page */ + event.preventDefault(); + event.stopPropagation(); + /** + * When we drop a file, the selection won't move automatically to the + * drop location. Find the location from the event and upload the files + * at that location. + */ + const at = findEventRange(editor, event); + + if (!at) return false; + + tf.placeholder.insertMedias(files); + + return true; + }, + onPaste: ({ event, tf }) => { + const { files } = event.clipboardData; + + if (files.length === 0) return false; + + event.preventDefault(); + event.stopPropagation(); + + tf.placeholder.insertMedias(files); + + return true; + }, + }, + })); diff --git a/packages/media/src/react/placeholder/transforms/insertMedias.ts b/packages/media/src/react/placeholder/transforms/insertMedias.ts new file mode 100644 index 0000000000..72f4151354 --- /dev/null +++ b/packages/media/src/react/placeholder/transforms/insertMedias.ts @@ -0,0 +1,56 @@ +import type { PlateEditor } from '@udecode/plate-common/react'; + +import { insertNodes, nanoid, withoutNormalizing } from '@udecode/plate-common'; + +import { type TPlaceholderElement, BasePlaceholderPlugin } from '../../../lib'; +import { PlaceholderPlugin } from '../PlaceholderPlugin'; +import { getMediaTypeByFileName, validateFiles } from '../utils/validateFiles'; + +export const insertMedias = (editor: PlateEditor, files: FileList): any => { + const api = editor.getApi(PlaceholderPlugin); + const mediaConfig = editor.getOption(PlaceholderPlugin, 'mediaConfig'); + const multiple = editor.getOption(PlaceholderPlugin, 'multiple'); + + const validationResult = validateFiles(files, mediaConfig); + + if (!validationResult.isValid && validationResult.errorMessage) { + return editor.setOption( + PlaceholderPlugin, + 'uploadErrorMessage', + validationResult.errorMessage + ); + } + if (!multiple && files.length > 1) { + return editor.setOption( + PlaceholderPlugin, + 'uploadErrorMessage', + 'Can not upload multiple files' + ); + } + + const maxFileCount = + editor.getOption(PlaceholderPlugin, 'uploadMaxFileCount') ?? 3; + + if (files.length > maxFileCount) { + return editor.setOption( + PlaceholderPlugin, + 'uploadErrorMessage', + `Can not upload more than ${maxFileCount} files` + ); + } + + Array.from(files).forEach((file) => { + const id = nanoid(); + + withoutNormalizing(editor, () => + insertNodes(editor, { + id, + children: [{ text: '' }], + mediaType: getMediaTypeByFileName(file.name, mediaConfig)!, + type: editor.getType(BasePlaceholderPlugin), + }) + ); + + api.placeholder.addUploadingFile(id, file); + }); +}; diff --git a/packages/media/src/react/placeholder/utils/validateFiles.ts b/packages/media/src/react/placeholder/utils/validateFiles.ts new file mode 100644 index 0000000000..0517b47078 --- /dev/null +++ b/packages/media/src/react/placeholder/utils/validateFiles.ts @@ -0,0 +1,170 @@ +import { + AudioPlugin, + FilePlugin, + ImagePlugin, + VideoPlugin, +} from '@udecode/plate-media/react'; + +import type { + MediaConfig, + MediaItemConfig, + MediaType, +} from '../PlaceholderPlugin'; + +interface ValidationResult { + errorMessage: string | null; + isValid: boolean; +} + +export const validateFiles = ( + fileList: FileList, + config: MediaConfig +): ValidationResult => { + const unknown: File[] = []; + + const map: Record = { + [AudioPlugin.key]: [], + [FilePlugin.key]: [], + [ImagePlugin.key]: [], + [VideoPlugin.key]: [], + }; + + Array.from(fileList).forEach((file) => { + // group files by acceptExtension + const mediaType = getMediaTypeByFileName(file.name, config); + + if (!mediaType) { + unknown.push(file); + } + }); + + if (unknown.length > 0) { + return { + errorMessage: `The files: ${unknown.map((file) => file.name).join(',')} is not support`, + isValid: false, + }; + } + + const keys = Object.keys(map) as (keyof typeof map)[]; + + for (const key of keys) { + const result = validateFileItem(map[key], config[key]!, { + debugName: key, + }); + + if (!result.isValid) { + return result; + } + } + + return { errorMessage: null, isValid: true }; +}; + +const validateFileItem = ( + fileList: File[], + config: MediaItemConfig, + options: { debugName: string } +): ValidationResult => { + if (fileList.length === 0) return { errorMessage: null, isValid: true }; + + const { debugName } = options; + // validate file count + const minFileCount = config.minFileCount ?? 1; + const maxFileCount = config.maxFileCount ?? 3; + + if (fileList.length < minFileCount) { + return { + errorMessage: `Minimum ${debugName} file count is ${minFileCount}`, + isValid: false, + }; + } + if (fileList.length > maxFileCount) { + return { + errorMessage: `Maximum ${debugName} file count is ${maxFileCount}`, + isValid: false, + }; + } + + // validate file size + const maxFileSize = config.maxFileSize ?? '10MB'; + + fileList.forEach((file) => { + if (file.size > parseFileSize(maxFileSize)) { + return { + errors: `Maximum ${debugName} file size is ${maxFileSize}`, + isValid: false, + }; + } + }); + + return { errorMessage: null, isValid: true }; +}; + +export const getMediaTypeByFileName = ( + fileName: string, + config: MediaConfig +): MediaType | null => { + const extension = getFileExtension(fileName); + + for (const [key, value] of Object.entries(config)) { + const accept = value?.accept ?? []; + + // user can use both `.mp3` or `mp3` in options + if (accept.includes(extension) || accept.includes(`.${extension}`)) { + switch (key) { + case AudioPlugin.key: { + return AudioPlugin.key; + } + case FilePlugin.key: { + return FilePlugin.key; + } + case ImagePlugin.key: { + return ImagePlugin.key; + } + case VideoPlugin.key: { + return VideoPlugin.key; + } + } + } + } + + return null; +}; + +/** Convert string like 1B to 1024 number */ +const parseFileSize = (size: string): number => { + const match = /^(\d+(?:\.\d+)?)\s*(b|kb|mb|gb)$/i.exec(size); + + if (!match) { + throw new Error('Invalid file size format'); + } + + const [, value, unit] = match; + const sizes = { B: 0, GB: 3, KB: 1, MB: 2 }; + const k = 1024; + + return Math.floor( + Number.parseFloat(value) * + Math.pow(k, sizes[unit.toUpperCase() as keyof typeof sizes]) + ); +}; + +const getFileExtension = (filename: string) => { + if (!filename || typeof filename !== 'string') { + return ''; + } + + filename = filename.trim(); + + if (filename.endsWith('.')) { + return ''; + } + + const ext = filename.split('.').pop(); + + if (ext === filename || filename.startsWith('.')) { + return ''; + } + + return ext?.toLowerCase() ?? ''; +}; From e93126c043532526711c2dd08af3e18cd8bbc8aa Mon Sep 17 00:00:00 2001 From: Felix Feng Date: Sat, 2 Nov 2024 21:15:30 +0800 Subject: [PATCH 05/25] docs --- .changeset/sour-bananas-arrive.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.changeset/sour-bananas-arrive.md b/.changeset/sour-bananas-arrive.md index ba0fa43433..3690ca611d 100644 --- a/.changeset/sour-bananas-arrive.md +++ b/.changeset/sour-bananas-arrive.md @@ -5,4 +5,6 @@ New `initialHeight` and `initialWidth` in `TImageElement` This will display a loading placeholder while the image is still loading, which helps maintain a consistent height. Mew `fromPlaceholderId` Used to track what was converted from that placeholder plugin. New `insertMedias` Used for inserting the placeholder at once. -New `validateFiles` utils for validate the files meet the `mediaConfig`. \ No newline at end of file +New `validateFiles` utils for validate the files meet the `mediaConfig`. +If validation fails,stop insert placeholder and save the error message in uploadErrorMessage. +NEw `option.multiple` `uploadMaxFileCount` Used to limit the number of placeholders inserted. \ No newline at end of file From 63ec7a65f9cc6ed048c5e4844df1eac7f5dc80ff Mon Sep 17 00:00:00 2001 From: Felix Feng Date: Sat, 2 Nov 2024 21:53:09 +0800 Subject: [PATCH 06/25] fix --- .changeset/sour-bananas-arrive.md | 4 +- packages/media/src/lib/media/types.ts | 2 +- .../placeholder/transforms/setMediaNode.ts | 2 +- .../react/placeholder/PlaceholderPlugin.tsx | 51 ++++++----- .../{insertMedias.ts => insertMedia.ts} | 5 +- .../placeholder/utils/getFileExtension.ts | 19 ++++ .../utils/getMediaTypeByFileName.ts | 34 ++++++++ .../react/placeholder/utils/parseFileSize.ts | 17 ++++ .../react/placeholder/utils/validateFiles.ts | 87 ++----------------- 9 files changed, 115 insertions(+), 106 deletions(-) rename packages/media/src/react/placeholder/transforms/{insertMedias.ts => insertMedia.ts} (88%) create mode 100644 packages/media/src/react/placeholder/utils/getFileExtension.ts create mode 100644 packages/media/src/react/placeholder/utils/getMediaTypeByFileName.ts create mode 100644 packages/media/src/react/placeholder/utils/parseFileSize.ts diff --git a/.changeset/sour-bananas-arrive.md b/.changeset/sour-bananas-arrive.md index 3690ca611d..3d405ccd81 100644 --- a/.changeset/sour-bananas-arrive.md +++ b/.changeset/sour-bananas-arrive.md @@ -3,8 +3,8 @@ --- New `initialHeight` and `initialWidth` in `TImageElement` This will display a loading placeholder while the image is still loading, which helps maintain a consistent height. -Mew `fromPlaceholderId` Used to track what was converted from that placeholder plugin. -New `insertMedias` Used for inserting the placeholder at once. +Mew `placeholderId` Used to track what was converted from that placeholder plugin. +New `insertMedia` Used for inserting the placeholder at once. New `validateFiles` utils for validate the files meet the `mediaConfig`. If validation fails,stop insert placeholder and save the error message in uploadErrorMessage. NEw `option.multiple` `uploadMaxFileCount` Used to limit the number of placeholders inserted. \ No newline at end of file diff --git a/packages/media/src/lib/media/types.ts b/packages/media/src/lib/media/types.ts index 386d72aa1f..6f8dc576b6 100644 --- a/packages/media/src/lib/media/types.ts +++ b/packages/media/src/lib/media/types.ts @@ -4,9 +4,9 @@ export interface TMediaElement extends TElement { url: string; id?: string; align?: 'center' | 'left' | 'right'; - fromPlaceholderId?: string; isUpload?: boolean; name?: string; + placeholderId?: string; } export interface MediaPluginOptions { diff --git a/packages/media/src/lib/placeholder/transforms/setMediaNode.ts b/packages/media/src/lib/placeholder/transforms/setMediaNode.ts index 6b55d984a8..6a8a43a3dc 100644 --- a/packages/media/src/lib/placeholder/transforms/setMediaNode.ts +++ b/packages/media/src/lib/placeholder/transforms/setMediaNode.ts @@ -7,11 +7,11 @@ import { type props = { type: string; url: string; - fromPlaceholderId?: string; initialHeight?: number; initialWidth?: number; isUpload?: boolean; name?: string; + placeholderId?: string; width?: number; }; diff --git a/packages/media/src/react/placeholder/PlaceholderPlugin.tsx b/packages/media/src/react/placeholder/PlaceholderPlugin.tsx index a0e002423b..5c10a4be71 100644 --- a/packages/media/src/react/placeholder/PlaceholderPlugin.tsx +++ b/packages/media/src/react/placeholder/PlaceholderPlugin.tsx @@ -5,15 +5,17 @@ import { findEventRange, toTPlatePlugin } from '@udecode/plate-common/react'; import { BasePlaceholderPlugin } from '../../lib'; import { AudioPlugin, FilePlugin, ImagePlugin, VideoPlugin } from '../plugins'; -import { insertMedias } from './transforms/insertMedias'; +import { insertMedia } from './transforms/insertMedia'; -export type MediaType = - | typeof AudioPlugin.key - | typeof FilePlugin.key - | typeof ImagePlugin.key - | typeof VideoPlugin.key; +export type MediaType = 'audio' | 'file' | 'image' | 'video'; export type MediaItemConfig = { + // The type of media that this config is for. + mediaType: + | typeof AudioPlugin.key + | typeof FilePlugin.key + | typeof ImagePlugin.key + | typeof VideoPlugin.key; // extensions that are accepted for this media type accept?: string[]; // The maximum number of files of this type that can be uploaded. @@ -31,7 +33,7 @@ export type PlaceholderApi = { }; export type PlaceholderTransforms = { - insertMedias: (files: FileList) => void; + insertMedia: (files: FileList) => void; }; export type MediaConfig = Partial>; @@ -53,39 +55,48 @@ export const PlaceholderPlugin = toTPlatePlugin< >(BasePlaceholderPlugin, { options: { mediaConfig: { - [AudioPlugin.key]: { - accept: ['mp3'], + audio: { + accept: ['.mp3'], maxFileCount: 1, maxFileSize: '8MB', + mediaType: AudioPlugin.key, minFileCount: 1, }, - [FilePlugin.key]: { - accept: [], + file: { + accept: ['.pdf', '.txt', '.doc', '.docx'], maxFileCount: 1, maxFileSize: '8MB', + mediaType: FilePlugin.key, minFileCount: 1, }, - [ImagePlugin.key]: { + image: { accept: ['.png', '.jpg', '.jpeg'], - maxFileCount: 3, - maxFileSize: '8MB', + maxFileCount: 4, + maxFileSize: '2MB', + mediaType: ImagePlugin.key, minFileCount: 1, }, - [VideoPlugin.key]: { + video: { accept: ['.mp4'], maxFileCount: 1, - maxFileSize: '8MB', + maxFileSize: '256MB', + mediaType: VideoPlugin.key, minFileCount: 1, }, }, multiple: true, uploadErrorMessage: null, - uploadMaxFileCount: 3, + uploadMaxFileCount: 5, uploadingFiles: {}, }, }) .extendTransforms(({ editor }) => ({ - insertMedias: bindFirst(insertMedias, editor), + insertMedia: bindFirst(insertMedia, editor), + })) + .extendEditorTransforms(({ editor }) => ({ + insert: { + media: bindFirst(insertMedia, editor), + }, })) .extendApi(({ getOption, setOption }) => ({ addUploadingFile: (id: string, file: File) => { @@ -128,7 +139,7 @@ export const PlaceholderPlugin = toTPlatePlugin< if (!at) return false; - tf.placeholder.insertMedias(files); + tf.placeholder.insertMedia(files); return true; }, @@ -140,7 +151,7 @@ export const PlaceholderPlugin = toTPlatePlugin< event.preventDefault(); event.stopPropagation(); - tf.placeholder.insertMedias(files); + tf.placeholder.insertMedia(files); return true; }, diff --git a/packages/media/src/react/placeholder/transforms/insertMedias.ts b/packages/media/src/react/placeholder/transforms/insertMedia.ts similarity index 88% rename from packages/media/src/react/placeholder/transforms/insertMedias.ts rename to packages/media/src/react/placeholder/transforms/insertMedia.ts index 72f4151354..8ff832809f 100644 --- a/packages/media/src/react/placeholder/transforms/insertMedias.ts +++ b/packages/media/src/react/placeholder/transforms/insertMedia.ts @@ -4,9 +4,10 @@ import { insertNodes, nanoid, withoutNormalizing } from '@udecode/plate-common'; import { type TPlaceholderElement, BasePlaceholderPlugin } from '../../../lib'; import { PlaceholderPlugin } from '../PlaceholderPlugin'; -import { getMediaTypeByFileName, validateFiles } from '../utils/validateFiles'; +import { getMediaTypeByFileName } from '../utils/getMediaTypeByFileName'; +import { validateFiles } from '../utils/validateFiles'; -export const insertMedias = (editor: PlateEditor, files: FileList): any => { +export const insertMedia = (editor: PlateEditor, files: FileList): any => { const api = editor.getApi(PlaceholderPlugin); const mediaConfig = editor.getOption(PlaceholderPlugin, 'mediaConfig'); const multiple = editor.getOption(PlaceholderPlugin, 'multiple'); diff --git a/packages/media/src/react/placeholder/utils/getFileExtension.ts b/packages/media/src/react/placeholder/utils/getFileExtension.ts new file mode 100644 index 0000000000..ef59f2ae56 --- /dev/null +++ b/packages/media/src/react/placeholder/utils/getFileExtension.ts @@ -0,0 +1,19 @@ +export const getFileExtension = (filename: string) => { + if (!filename || typeof filename !== 'string') { + return ''; + } + + filename = filename.trim(); + + if (filename.endsWith('.')) { + return ''; + } + + const ext = filename.split('.').pop(); + + if (ext === filename || filename.startsWith('.')) { + return ''; + } + + return ext?.toLowerCase() ?? ''; +}; diff --git a/packages/media/src/react/placeholder/utils/getMediaTypeByFileName.ts b/packages/media/src/react/placeholder/utils/getMediaTypeByFileName.ts new file mode 100644 index 0000000000..94e9f8f59b --- /dev/null +++ b/packages/media/src/react/placeholder/utils/getMediaTypeByFileName.ts @@ -0,0 +1,34 @@ +import type { MediaConfig } from '../PlaceholderPlugin'; + +import { getFileExtension } from './getFileExtension'; + +export const getMediaTypeByFileName = ( + fileName: string, + config: MediaConfig +): string | null => { + const extension = getFileExtension(fileName); + + for (const [key, value] of Object.entries(config)) { + const accept = value?.accept ?? []; + + // user can use both `.mp3` or `mp3` in options + if (accept.includes(extension) || accept.includes(`.${extension}`)) { + switch (key) { + case 'audio': { + return value.mediaType; + } + case 'file': { + return value.mediaType; + } + case 'image': { + return value.mediaType; + } + case 'video': { + return value.mediaType; + } + } + } + } + + return null; +}; diff --git a/packages/media/src/react/placeholder/utils/parseFileSize.ts b/packages/media/src/react/placeholder/utils/parseFileSize.ts new file mode 100644 index 0000000000..97e3ca90b6 --- /dev/null +++ b/packages/media/src/react/placeholder/utils/parseFileSize.ts @@ -0,0 +1,17 @@ +/** Convert string like 1B to 1024 number */ +export const parseFileSize = (size: string): number => { + const match = /^(\d+(?:\.\d+)?)\s*(b|kb|mb|gb)$/i.exec(size); + + if (!match) { + throw new Error('Invalid file size format'); + } + + const [, value, unit] = match; + const sizes = { B: 0, GB: 3, KB: 1, MB: 2 }; + const k = 1024; + + return Math.floor( + Number.parseFloat(value) * + Math.pow(k, sizes[unit.toUpperCase() as keyof typeof sizes]) + ); +}; diff --git a/packages/media/src/react/placeholder/utils/validateFiles.ts b/packages/media/src/react/placeholder/utils/validateFiles.ts index 0517b47078..1a176c27af 100644 --- a/packages/media/src/react/placeholder/utils/validateFiles.ts +++ b/packages/media/src/react/placeholder/utils/validateFiles.ts @@ -1,16 +1,12 @@ -import { - AudioPlugin, - FilePlugin, - ImagePlugin, - VideoPlugin, -} from '@udecode/plate-media/react'; - import type { MediaConfig, MediaItemConfig, MediaType, } from '../PlaceholderPlugin'; +import { getMediaTypeByFileName } from './getMediaTypeByFileName'; +import { parseFileSize } from './parseFileSize'; + interface ValidationResult { errorMessage: string | null; isValid: boolean; @@ -23,10 +19,10 @@ export const validateFiles = ( const unknown: File[] = []; const map: Record = { - [AudioPlugin.key]: [], - [FilePlugin.key]: [], - [ImagePlugin.key]: [], - [VideoPlugin.key]: [], + audio: [], + file: [], + image: [], + video: [], }; Array.from(fileList).forEach((file) => { @@ -99,72 +95,3 @@ const validateFileItem = ( return { errorMessage: null, isValid: true }; }; - -export const getMediaTypeByFileName = ( - fileName: string, - config: MediaConfig -): MediaType | null => { - const extension = getFileExtension(fileName); - - for (const [key, value] of Object.entries(config)) { - const accept = value?.accept ?? []; - - // user can use both `.mp3` or `mp3` in options - if (accept.includes(extension) || accept.includes(`.${extension}`)) { - switch (key) { - case AudioPlugin.key: { - return AudioPlugin.key; - } - case FilePlugin.key: { - return FilePlugin.key; - } - case ImagePlugin.key: { - return ImagePlugin.key; - } - case VideoPlugin.key: { - return VideoPlugin.key; - } - } - } - } - - return null; -}; - -/** Convert string like 1B to 1024 number */ -const parseFileSize = (size: string): number => { - const match = /^(\d+(?:\.\d+)?)\s*(b|kb|mb|gb)$/i.exec(size); - - if (!match) { - throw new Error('Invalid file size format'); - } - - const [, value, unit] = match; - const sizes = { B: 0, GB: 3, KB: 1, MB: 2 }; - const k = 1024; - - return Math.floor( - Number.parseFloat(value) * - Math.pow(k, sizes[unit.toUpperCase() as keyof typeof sizes]) - ); -}; - -const getFileExtension = (filename: string) => { - if (!filename || typeof filename !== 'string') { - return ''; - } - - filename = filename.trim(); - - if (filename.endsWith('.')) { - return ''; - } - - const ext = filename.split('.').pop(); - - if (ext === filename || filename.startsWith('.')) { - return ''; - } - - return ext?.toLowerCase() ?? ''; -}; From 7504fdbc6018f8c564f6aed816fd39555e96c03a Mon Sep 17 00:00:00 2001 From: Felix Feng Date: Sat, 2 Nov 2024 22:46:56 +0800 Subject: [PATCH 07/25] brl --- packages/ai/src/react/copilot/utils/index.ts | 1 + packages/media/src/lib/media/index.ts | 1 - packages/media/src/react/placeholder/index.ts | 2 ++ .../media/src/react/placeholder/transforms/index.ts | 5 +++++ packages/media/src/react/placeholder/utils/index.ts | 8 ++++++++ packages/plate-utils/src/react/index.ts | 2 +- packages/react-utils/src/index.ts | 2 +- packages/selection/src/react/transforms/index.ts | 1 + packages/slate/src/index.ts | 2 +- packages/slate/src/interfaces/history-editor/index.ts | 2 +- packages/slate/src/slate-history/index.ts | 10 +++++++--- 11 files changed, 28 insertions(+), 8 deletions(-) create mode 100644 packages/media/src/react/placeholder/transforms/index.ts create mode 100644 packages/media/src/react/placeholder/utils/index.ts diff --git a/packages/ai/src/react/copilot/utils/index.ts b/packages/ai/src/react/copilot/utils/index.ts index 8dac5c2d04..9f452fa3c3 100644 --- a/packages/ai/src/react/copilot/utils/index.ts +++ b/packages/ai/src/react/copilot/utils/index.ts @@ -3,5 +3,6 @@ */ export * from './callCompletionApi'; +export * from './getNextWord'; export * from './triggerCopilotSuggestion'; export * from './withoutAbort'; diff --git a/packages/media/src/lib/media/index.ts b/packages/media/src/lib/media/index.ts index 88c017703d..7f9a061e57 100644 --- a/packages/media/src/lib/media/index.ts +++ b/packages/media/src/lib/media/index.ts @@ -5,4 +5,3 @@ export * from './insertMedia'; export * from './parseMediaUrl'; export type * from './types'; - diff --git a/packages/media/src/react/placeholder/index.ts b/packages/media/src/react/placeholder/index.ts index 2a9025d94b..8a48475757 100644 --- a/packages/media/src/react/placeholder/index.ts +++ b/packages/media/src/react/placeholder/index.ts @@ -6,3 +6,5 @@ export * from './PlaceholderPlugin'; export * from './placeholderStore'; export * from './usePlaceholderElement'; export * from './usePlaceholderPopover'; +export * from './transforms/index'; +export * from './utils/index'; diff --git a/packages/media/src/react/placeholder/transforms/index.ts b/packages/media/src/react/placeholder/transforms/index.ts new file mode 100644 index 0000000000..790670da5a --- /dev/null +++ b/packages/media/src/react/placeholder/transforms/index.ts @@ -0,0 +1,5 @@ +/** + * @file Automatically generated by barrelsby. + */ + +export * from './insertMedia'; diff --git a/packages/media/src/react/placeholder/utils/index.ts b/packages/media/src/react/placeholder/utils/index.ts new file mode 100644 index 0000000000..c4cb3869b9 --- /dev/null +++ b/packages/media/src/react/placeholder/utils/index.ts @@ -0,0 +1,8 @@ +/** + * @file Automatically generated by barrelsby. + */ + +export * from './getFileExtension'; +export * from './getMediaTypeByFileName'; +export * from './parseFileSize'; +export * from './validateFiles'; diff --git a/packages/plate-utils/src/react/index.ts b/packages/plate-utils/src/react/index.ts index d6d440093d..e470d2d827 100644 --- a/packages/plate-utils/src/react/index.ts +++ b/packages/plate-utils/src/react/index.ts @@ -6,8 +6,8 @@ export * from './PlateElement'; export * from './PlateLeaf'; export * from './createNodeHOC'; export * from './createNodesHOC'; -export * from './selectSiblingNodePoint'; export * from './selectEditor'; +export * from './selectSiblingNodePoint'; export * from './useFormInputProps'; export * from './useMarkToolbarButton'; export * from './usePlaceholder'; diff --git a/packages/react-utils/src/index.ts b/packages/react-utils/src/index.ts index f32b143810..e6174df0a5 100644 --- a/packages/react-utils/src/index.ts +++ b/packages/react-utils/src/index.ts @@ -3,9 +3,9 @@ */ export * from './Box'; +export * from './MemoizedChildren'; export * from './PortalBody'; export * from './Text'; -export * from './MemoizedChildren'; export * from './composeEventHandlers'; export * from './createPrimitiveComponent'; export * from './createPrimitiveElement'; diff --git a/packages/selection/src/react/transforms/index.ts b/packages/selection/src/react/transforms/index.ts index d50706e0fd..6319706f37 100644 --- a/packages/selection/src/react/transforms/index.ts +++ b/packages/selection/src/react/transforms/index.ts @@ -3,6 +3,7 @@ */ export * from './duplicateBlockSelectionNodes'; +export * from './insertBlocksAndSelect'; export * from './removeBlockSelectionNodes'; export * from './selectBlockSelectionNodes'; export * from './setBlockSelectionNodes'; diff --git a/packages/slate/src/index.ts b/packages/slate/src/index.ts index d27f49f961..33ca390098 100644 --- a/packages/slate/src/index.ts +++ b/packages/slate/src/index.ts @@ -5,7 +5,7 @@ export * from './createTEditor'; export * from './interfaces/index'; export * from './queries/index'; +export * from './slate-history/index'; export * from './transforms/index'; export type * from './types/index'; export * from './utils/index'; -export * from './slate-history'; \ No newline at end of file diff --git a/packages/slate/src/interfaces/history-editor/index.ts b/packages/slate/src/interfaces/history-editor/index.ts index 4c2aeafd9e..651e7ba5da 100644 --- a/packages/slate/src/interfaces/history-editor/index.ts +++ b/packages/slate/src/interfaces/history-editor/index.ts @@ -6,6 +6,6 @@ export * from './isHistoryEditor'; export * from './isHistoryMerging'; export * from './isHistorySaving'; export * from './withMerging'; +export * from './withNewBatch'; export * from './withoutMergingHistory'; export * from './withoutSavingHistory'; -export * from './withNewBatch'; diff --git a/packages/slate/src/slate-history/index.ts b/packages/slate/src/slate-history/index.ts index 4dc515690e..487b83720c 100644 --- a/packages/slate/src/slate-history/index.ts +++ b/packages/slate/src/slate-history/index.ts @@ -1,3 +1,7 @@ -export * from './history' -export * from './history-editor' -export * from './with-history' +/** + * @file Automatically generated by barrelsby. + */ + +export * from './history-editor'; +export * from './history'; +export * from './with-history'; From 0028a4ada7f2b09ce297827b29bbbf1bef0ef754 Mon Sep 17 00:00:00 2001 From: Felix Feng Date: Sun, 3 Nov 2024 08:29:59 +0800 Subject: [PATCH 08/25] fix --- packages/media/src/react/placeholder/PlaceholderPlugin.tsx | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/packages/media/src/react/placeholder/PlaceholderPlugin.tsx b/packages/media/src/react/placeholder/PlaceholderPlugin.tsx index 5c10a4be71..cb7560e822 100644 --- a/packages/media/src/react/placeholder/PlaceholderPlugin.tsx +++ b/packages/media/src/react/placeholder/PlaceholderPlugin.tsx @@ -1,9 +1,7 @@ -import type { PlaceholderConfig } from '@udecode/plate-media'; - import { type ExtendConfig, bindFirst } from '@udecode/plate-common'; import { findEventRange, toTPlatePlugin } from '@udecode/plate-common/react'; -import { BasePlaceholderPlugin } from '../../lib'; +import { type PlaceholderConfig, BasePlaceholderPlugin } from '../../lib'; import { AudioPlugin, FilePlugin, ImagePlugin, VideoPlugin } from '../plugins'; import { insertMedia } from './transforms/insertMedia'; From b67649cf6710f703b3f13b22add22fef95848cbc Mon Sep 17 00:00:00 2001 From: Felix Feng Date: Sun, 3 Nov 2024 20:41:18 +0800 Subject: [PATCH 09/25] dnd --- packages/dnd/src/DndPlugin.tsx | 2 ++ packages/dnd/src/hooks/useDndNode.ts | 9 +++++---- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/packages/dnd/src/DndPlugin.tsx b/packages/dnd/src/DndPlugin.tsx index 8b4d98a952..905b78ad8c 100644 --- a/packages/dnd/src/DndPlugin.tsx +++ b/packages/dnd/src/DndPlugin.tsx @@ -10,6 +10,7 @@ export type DndConfig = PluginConfig< 'dnd', { draggingId?: string | null; + enableFile?: boolean; enableScroller?: boolean; isDragging?: boolean; scrollerProps?: Partial; @@ -20,6 +21,7 @@ export const DndPlugin = createTPlatePlugin({ key: 'dnd', options: { draggingId: null, + enableFile: false, isDragging: false, }, handlers: { diff --git a/packages/dnd/src/hooks/useDndNode.ts b/packages/dnd/src/hooks/useDndNode.ts index d652a70637..fbaaa393ea 100644 --- a/packages/dnd/src/hooks/useDndNode.ts +++ b/packages/dnd/src/hooks/useDndNode.ts @@ -1,11 +1,12 @@ -import { getEmptyImage } from 'react-dnd-html5-backend'; +import { NativeTypes, getEmptyImage } from 'react-dnd-html5-backend'; import type { DropTargetMonitor } from 'react-dnd'; -import { type PlateEditor, useEditorRef } from '@udecode/plate-common/react'; +import { type PlateEditor, useEditorPlugin } from '@udecode/plate-common/react'; import type { DragItemNode } from '../types'; +import { DndPlugin } from '../DndPlugin'; import { useDraggableStore } from '../components/useDraggable'; import { type UseDragNodeOptions, useDragNode } from './useDragNode'; import { type UseDropNodeOptions, useDropNode } from './useDropNode'; @@ -47,7 +48,7 @@ export const useDndNode = ({ type, onDropHandler, }: UseDndNodeOptions) => { - const editor = useEditorRef(); + const { editor, getOption } = useEditorPlugin(DndPlugin); const [dropLine, setDropLine] = useDraggableStore().use.dropLine(); @@ -58,7 +59,7 @@ export const useDndNode = ({ }); const [{ isOver }, drop] = useDropNode(editor, { id, - accept: type, + accept: getOption('enableFile') ? [type, NativeTypes.FILE] : [type], dropLine, nodeRef, onChangeDropLine: setDropLine, From db8b0618b46d88690779bca4eb0ad2f272c412fd Mon Sep 17 00:00:00 2001 From: Felix Feng Date: Sun, 3 Nov 2024 20:42:09 +0800 Subject: [PATCH 10/25] fix --- .../react/placeholder/PlaceholderPlugin.tsx | 41 ++++++++++++------- .../src/react/placeholder/placeholderStore.ts | 4 +- .../placeholder/usePlaceholderElement.ts | 4 +- .../placeholder/usePlaceholderPopover.ts | 4 +- .../utils/getMediaTypeByFileName.ts | 31 ++++++++++++++ .../react/placeholder/utils/validateFiles.ts | 13 ++++-- 6 files changed, 73 insertions(+), 24 deletions(-) diff --git a/packages/media/src/react/placeholder/PlaceholderPlugin.tsx b/packages/media/src/react/placeholder/PlaceholderPlugin.tsx index cb7560e822..c1b092ddca 100644 --- a/packages/media/src/react/placeholder/PlaceholderPlugin.tsx +++ b/packages/media/src/react/placeholder/PlaceholderPlugin.tsx @@ -7,13 +7,15 @@ import { insertMedia } from './transforms/insertMedia'; export type MediaType = 'audio' | 'file' | 'image' | 'video'; +export type MediaKeys = + | typeof AudioPlugin.key + | typeof FilePlugin.key + | typeof ImagePlugin.key + | typeof VideoPlugin.key; + export type MediaItemConfig = { // The type of media that this config is for. - mediaType: - | typeof AudioPlugin.key - | typeof FilePlugin.key - | typeof ImagePlugin.key - | typeof VideoPlugin.key; + mediaType: MediaKeys; // extensions that are accepted for this media type accept?: string[]; // The maximum number of files of this type that can be uploaded. @@ -47,8 +49,7 @@ export const PlaceholderPlugin = toTPlatePlugin< uploadErrorMessage?: string | null; uploadMaxFileCount?: number; }, - { placeholder: PlaceholderApi }, - { placeholder: PlaceholderTransforms } + { placeholder: PlaceholderApi } > >(BasePlaceholderPlugin, { options: { @@ -61,7 +62,7 @@ export const PlaceholderPlugin = toTPlatePlugin< minFileCount: 1, }, file: { - accept: ['.pdf', '.txt', '.doc', '.docx'], + accept: ['.pdf', '.txt'], maxFileCount: 1, maxFileSize: '8MB', mediaType: FilePlugin.key, @@ -69,7 +70,7 @@ export const PlaceholderPlugin = toTPlatePlugin< }, image: { accept: ['.png', '.jpg', '.jpeg'], - maxFileCount: 4, + maxFileCount: 1, maxFileSize: '2MB', mediaType: ImagePlugin.key, minFileCount: 1, @@ -88,9 +89,6 @@ export const PlaceholderPlugin = toTPlatePlugin< uploadingFiles: {}, }, }) - .extendTransforms(({ editor }) => ({ - insertMedia: bindFirst(insertMedia, editor), - })) .extendEditorTransforms(({ editor }) => ({ insert: { media: bindFirst(insertMedia, editor), @@ -105,6 +103,21 @@ export const PlaceholderPlugin = toTPlatePlugin< [id]: file, }); }, + getMediaConfig: (mediaType: MediaKeys) => { + const config = getOption('mediaConfig'); + + const keys = Object.keys(config); + + for (const key of keys) { + const item = config[key as MediaType]; + + if (item?.mediaType === mediaType) { + return item; + } + } + + return null; + }, getUploadingFile: (id: string) => { const uploadingFiles = getOption('uploadingFiles'); @@ -137,7 +150,7 @@ export const PlaceholderPlugin = toTPlatePlugin< if (!at) return false; - tf.placeholder.insertMedia(files); + tf.insert.media(files); return true; }, @@ -149,7 +162,7 @@ export const PlaceholderPlugin = toTPlatePlugin< event.preventDefault(); event.stopPropagation(); - tf.placeholder.insertMedia(files); + tf.insert.media(files); return true; }, diff --git a/packages/media/src/react/placeholder/placeholderStore.ts b/packages/media/src/react/placeholder/placeholderStore.ts index 9115a34fc9..e9bb53eaf1 100644 --- a/packages/media/src/react/placeholder/placeholderStore.ts +++ b/packages/media/src/react/placeholder/placeholderStore.ts @@ -2,7 +2,7 @@ import { createAtomStore } from '@udecode/plate-common/react'; type Progresses = Record; interface PlaceholderStore { - mediaSize: { + size: { height: number; width: number; } | null; @@ -15,8 +15,8 @@ export const { PlaceholderProvider, placeholderStore, usePlaceholderStore } = createAtomStore( { isUploading: false, - mediaSize: null, progresses: {}, + size: null, updatedFiles: [], } as PlaceholderStore, { name: 'placeholder' } diff --git a/packages/media/src/react/placeholder/usePlaceholderElement.ts b/packages/media/src/react/placeholder/usePlaceholderElement.ts index c9f3545e04..729d2ca6be 100644 --- a/packages/media/src/react/placeholder/usePlaceholderElement.ts +++ b/packages/media/src/react/placeholder/usePlaceholderElement.ts @@ -17,7 +17,7 @@ export const usePlaceholderElementState = () => { const progresses = usePlaceholderStore().get.progresses(); const isUploading = usePlaceholderStore().get.isUploading(); const updatedFiles = usePlaceholderStore().get.updatedFiles(); - const setMediaSize = usePlaceholderStore().set.mediaSize(); + const setSize = usePlaceholderStore().set.size(); const { mediaType } = useElement( BasePlaceholderPlugin.key @@ -35,7 +35,7 @@ export const usePlaceholderElementState = () => { progressing, readOnly, selected, - setMediaSize, + setSize, updatedFiles, }; }; diff --git a/packages/media/src/react/placeholder/usePlaceholderPopover.ts b/packages/media/src/react/placeholder/usePlaceholderPopover.ts index cfdf8f8e0a..c122c2fc5f 100644 --- a/packages/media/src/react/placeholder/usePlaceholderPopover.ts +++ b/packages/media/src/react/placeholder/usePlaceholderPopover.ts @@ -30,14 +30,13 @@ export const usePlaceholderPopoverState = () => { const setIsUploading = usePlaceholderStore().set.isUploading(); const setUpdatedFiles = usePlaceholderStore().set.updatedFiles(); - const mediaSize = usePlaceholderStore().get.mediaSize(); + const size = usePlaceholderStore().get.size(); return { id, editor, element, focused, - mediaSize, mediaType, readOnly, selected, @@ -45,5 +44,6 @@ export const usePlaceholderPopoverState = () => { setIsUploading, setProgresses, setUpdatedFiles, + size, }; }; diff --git a/packages/media/src/react/placeholder/utils/getMediaTypeByFileName.ts b/packages/media/src/react/placeholder/utils/getMediaTypeByFileName.ts index 94e9f8f59b..91cefa60a1 100644 --- a/packages/media/src/react/placeholder/utils/getMediaTypeByFileName.ts +++ b/packages/media/src/react/placeholder/utils/getMediaTypeByFileName.ts @@ -32,3 +32,34 @@ export const getMediaTypeByFileName = ( return null; }; + +export const getMediaConfigKeyByFileName = ( + fileName: string, + config: MediaConfig +): string | null => { + const extension = getFileExtension(fileName); + + for (const [key, value] of Object.entries(config)) { + const accept = value?.accept ?? []; + + // user can use both `.mp3` or `mp3` in options + if (accept.includes(extension) || accept.includes(`.${extension}`)) { + switch (key) { + case 'audio': { + return key; + } + case 'file': { + return key; + } + case 'image': { + return key; + } + case 'video': { + return key; + } + } + } + } + + return null; +}; diff --git a/packages/media/src/react/placeholder/utils/validateFiles.ts b/packages/media/src/react/placeholder/utils/validateFiles.ts index 1a176c27af..bf1ecb8358 100644 --- a/packages/media/src/react/placeholder/utils/validateFiles.ts +++ b/packages/media/src/react/placeholder/utils/validateFiles.ts @@ -4,7 +4,7 @@ import type { MediaType, } from '../PlaceholderPlugin'; -import { getMediaTypeByFileName } from './getMediaTypeByFileName'; +import { getMediaConfigKeyByFileName } from './getMediaTypeByFileName'; import { parseFileSize } from './parseFileSize'; interface ValidationResult { @@ -27,9 +27,11 @@ export const validateFiles = ( Array.from(fileList).forEach((file) => { // group files by acceptExtension - const mediaType = getMediaTypeByFileName(file.name, config); + const mediaType = getMediaConfigKeyByFileName(file.name, config); - if (!mediaType) { + if (mediaType && mediaType in map) { + map[mediaType as MediaType].push(file); + } else { unknown.push(file); } }); @@ -44,7 +46,9 @@ export const validateFiles = ( const keys = Object.keys(map) as (keyof typeof map)[]; for (const key of keys) { - const result = validateFileItem(map[key], config[key]!, { + const itemFiles = map[key]; + + const result = validateFileItem(itemFiles, config[key]!, { debugName: key, }); @@ -67,6 +71,7 @@ const validateFileItem = ( // validate file count const minFileCount = config.minFileCount ?? 1; const maxFileCount = config.maxFileCount ?? 3; + console.log('🚀 ~ maxFileCount:', maxFileCount); if (fileList.length < minFileCount) { return { From f3cd6015404ad93605d10368ad8ae7466460b56e Mon Sep 17 00:00:00 2001 From: Felix Feng Date: Sun, 3 Nov 2024 20:44:54 +0800 Subject: [PATCH 11/25] docs --- .changeset/rare-zebras-kneel.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/rare-zebras-kneel.md diff --git a/.changeset/rare-zebras-kneel.md b/.changeset/rare-zebras-kneel.md new file mode 100644 index 0000000000..b32db8b005 --- /dev/null +++ b/.changeset/rare-zebras-kneel.md @@ -0,0 +1,5 @@ +--- +'@udecode/plate-dnd': patch +--- + +Add `enableFile` option to check whether to enable the DnD plugin for files dragged in from outside the browser. From 7a5b0092995cd4281e37931a6c31e67f8e407bdd Mon Sep 17 00:00:00 2001 From: Felix Feng Date: Sun, 3 Nov 2024 20:49:38 +0800 Subject: [PATCH 12/25] docs --- .changeset/chilly-peaches-report.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/chilly-peaches-report.md diff --git a/.changeset/chilly-peaches-report.md b/.changeset/chilly-peaches-report.md new file mode 100644 index 0000000000..c7722b8b20 --- /dev/null +++ b/.changeset/chilly-peaches-report.md @@ -0,0 +1,5 @@ +--- +'@udecode/plate-ai': patch +--- + +Missing export From 0cd4eeb3a31ae92e3d732bff156b9fd5ff8a32e0 Mon Sep 17 00:00:00 2001 From: Felix Feng Date: Mon, 4 Nov 2024 09:23:43 +0800 Subject: [PATCH 13/25] drop --- .../demo/plugins/DragOverCursorPlugin.ts | 2 + .../default/example/playground-demo.tsx | 20 +++++++- packages/dnd/src/DndPlugin.tsx | 21 +++++++-- packages/dnd/src/hooks/useDndNode.ts | 8 ++-- packages/dnd/src/hooks/useDropNode.ts | 47 +++++++++++++++++-- packages/dnd/src/transforms/onDropNode.ts | 40 +++++++++++++--- packages/dnd/src/types.ts | 10 +++- .../media/src/lib/image/BaseImagePlugin.ts | 41 +++++++++------- .../image/transforms/insertImageFromFiles.ts | 33 +++++++++++++ .../media/src/lib/image/withImageUpload.ts | 27 ++--------- 10 files changed, 188 insertions(+), 61 deletions(-) create mode 100644 packages/media/src/lib/image/transforms/insertImageFromFiles.ts diff --git a/apps/www/src/lib/plate/demo/plugins/DragOverCursorPlugin.ts b/apps/www/src/lib/plate/demo/plugins/DragOverCursorPlugin.ts index 2c279a2a2d..808a74e897 100644 --- a/apps/www/src/lib/plate/demo/plugins/DragOverCursorPlugin.ts +++ b/apps/www/src/lib/plate/demo/plugins/DragOverCursorPlugin.ts @@ -15,6 +15,8 @@ export const DragOverCursorPlugin = createPlatePlugin({ }, onDragOver: ({ editor, event, plugin }) => { if (editor.getOptions(DndPlugin).isDragging) return; + // Only show cursor for text drag + if (!event.dataTransfer?.types.includes('text/plain')) return; const range = findEventRange(editor, event); diff --git a/apps/www/src/registry/default/example/playground-demo.tsx b/apps/www/src/registry/default/example/playground-demo.tsx index 8bd48ca5e0..2fbd29967c 100644 --- a/apps/www/src/registry/default/example/playground-demo.tsx +++ b/apps/www/src/registry/default/example/playground-demo.tsx @@ -150,6 +150,9 @@ export const usePlaygroundEditor = (id: any = '', scrollSelector?: string) => { }), ...(id === 'list' ? [ListPlugin] : []), ImagePlugin.extend({ + options: { + disableUploadInsert: true, + }, render: { afterEditable: ImagePreview }, }), MediaEmbedPlugin, @@ -294,7 +297,20 @@ export const usePlaygroundEditor = (id: any = '', scrollSelector?: string) => { BlockMenuPlugin.configure({ render: { aboveEditable: BlockContextMenu }, }), - DndPlugin.configure({ options: { enableScroller: true } }), + DndPlugin.configure({ + options: { + enableScroller: true, + onDropFiles: (editor, props) => { + console.log(props.dropPath, 'fj'); + + editor + .getTransforms(ImagePlugin) + .insertImageFromFiles(props.dragItem.files, { + at: props.dropPath, + }); + }, + }, + }), EmojiPlugin, exitBreakPlugin, NodeIdPlugin, @@ -318,7 +334,7 @@ export const usePlaygroundEditor = (id: any = '', scrollSelector?: string) => { TrailingBlockPlugin.configure({ options: { type: ParagraphPlugin.key }, }), - DragOverCursorPlugin, + // DragOverCursorPlugin, // Collaboration CommentsPlugin.configure({ diff --git a/packages/dnd/src/DndPlugin.tsx b/packages/dnd/src/DndPlugin.tsx index 905b78ad8c..ffa5fb4ff1 100644 --- a/packages/dnd/src/DndPlugin.tsx +++ b/packages/dnd/src/DndPlugin.tsx @@ -1,8 +1,15 @@ import React from 'react'; import type { PluginConfig } from '@udecode/plate-common'; +import type { DropTargetMonitor } from 'react-dnd'; +import type { Path } from 'slate'; -import { createTPlatePlugin } from '@udecode/plate-common/react'; +import { + type PlateEditor, + createTPlatePlugin, +} from '@udecode/plate-common/react'; + +import type { DragItemNode, FileDragItemNode } from './types'; import { type ScrollerProps, DndScroller } from './components/Scroller'; @@ -10,10 +17,19 @@ export type DndConfig = PluginConfig< 'dnd', { draggingId?: string | null; - enableFile?: boolean; enableScroller?: boolean; isDragging?: boolean; scrollerProps?: Partial; + onDropFiles?: ( + editor: PlateEditor, + props: { + id: string; + dragItem: FileDragItemNode; + monitor: DropTargetMonitor; + nodeRef: any; + dropPath?: Path; + } + ) => void; } >; @@ -21,7 +37,6 @@ export const DndPlugin = createTPlatePlugin({ key: 'dnd', options: { draggingId: null, - enableFile: false, isDragging: false, }, handlers: { diff --git a/packages/dnd/src/hooks/useDndNode.ts b/packages/dnd/src/hooks/useDndNode.ts index fbaaa393ea..5c7f084704 100644 --- a/packages/dnd/src/hooks/useDndNode.ts +++ b/packages/dnd/src/hooks/useDndNode.ts @@ -2,11 +2,10 @@ import { NativeTypes, getEmptyImage } from 'react-dnd-html5-backend'; import type { DropTargetMonitor } from 'react-dnd'; -import { type PlateEditor, useEditorPlugin } from '@udecode/plate-common/react'; +import { type PlateEditor, useEditorRef } from '@udecode/plate-common/react'; import type { DragItemNode } from '../types'; -import { DndPlugin } from '../DndPlugin'; import { useDraggableStore } from '../components/useDraggable'; import { type UseDragNodeOptions, useDragNode } from './useDragNode'; import { type UseDropNodeOptions, useDropNode } from './useDropNode'; @@ -48,8 +47,7 @@ export const useDndNode = ({ type, onDropHandler, }: UseDndNodeOptions) => { - const { editor, getOption } = useEditorPlugin(DndPlugin); - + const editor = useEditorRef(); const [dropLine, setDropLine] = useDraggableStore().use.dropLine(); const [{ isDragging }, dragRef, preview] = useDragNode(editor, { @@ -59,7 +57,7 @@ export const useDndNode = ({ }); const [{ isOver }, drop] = useDropNode(editor, { id, - accept: getOption('enableFile') ? [type, NativeTypes.FILE] : [type], + accept: [type, NativeTypes.FILE], dropLine, nodeRef, onChangeDropLine: setDropLine, diff --git a/packages/dnd/src/hooks/useDropNode.ts b/packages/dnd/src/hooks/useDropNode.ts index f5eda81157..609a54552b 100644 --- a/packages/dnd/src/hooks/useDropNode.ts +++ b/packages/dnd/src/hooks/useDropNode.ts @@ -6,9 +6,17 @@ import { import type { PlateEditor } from '@udecode/plate-common/react'; -import type { DragItemNode, DropLineDirection } from '../types'; +import { Path } from 'slate'; -import { onDropNode } from '../transforms/onDropNode'; +import type { + DragItemNode, + DropLineDirection, + ElementDragItemNode, + FileDragItemNode, +} from '../types'; + +import { DndPlugin } from '../DndPlugin'; +import { getDropPath, onDropNode } from '../transforms/onDropNode'; import { onHoverNode } from '../transforms/onHoverNode'; export interface UseDropNodeOptions @@ -77,6 +85,34 @@ export const useDropNode = ( isOver: monitor.isOver(), }), drop: (dragItem, monitor) => { + // Don't call onDropNode if this is a file drop + + if (!(dragItem as ElementDragItemNode).id) { + const result = getDropPath(editor, { + id, + dragItem: dragItem as any, + monitor, + nodeRef, + }); + + const onDropFiles = editor.getOptions(DndPlugin).onDropFiles; + + if (!result || !onDropFiles) return; + + //FIXME + const isFirstPath = Path.equals(result.to, [0]); + + const dropPath = isFirstPath ? [0] : Path.previous(result.to); + + return onDropFiles(editor, { + id, + dragItem: dragItem as FileDragItemNode, + dropPath: dropPath, + monitor, + nodeRef, + }); + } + const handled = !!onDropHandler && onDropHandler(editor, { @@ -88,7 +124,12 @@ export const useDropNode = ( if (handled) return; - onDropNode(editor, { id, dragItem, monitor, nodeRef }); + onDropNode(editor, { + id, + dragItem: dragItem as ElementDragItemNode, + monitor, + nodeRef, + }); }, hover(item: DragItemNode, monitor: DropTargetMonitor) { onHoverNode(editor, { diff --git a/packages/dnd/src/transforms/onDropNode.ts b/packages/dnd/src/transforms/onDropNode.ts index f36bf10e12..213bc4e686 100644 --- a/packages/dnd/src/transforms/onDropNode.ts +++ b/packages/dnd/src/transforms/onDropNode.ts @@ -5,12 +5,12 @@ import { focusEditor } from '@udecode/plate-common/react'; import { Path } from 'slate'; import type { UseDropNodeOptions } from '../hooks'; -import type { DragItemNode } from '../types'; +import type { ElementDragItemNode } from '../types'; import { getHoverDirection } from '../utils'; /** Callback called on drag an drop a node with id. */ -export const onDropNode = ( +export const getDropPath = ( editor: TEditor, { id, @@ -18,7 +18,7 @@ export const onDropNode = ( monitor, nodeRef, }: { - dragItem: DragItemNode; + dragItem: ElementDragItemNode; monitor: DropTargetMonitor; } & Pick ) => { @@ -61,9 +61,35 @@ export const onDropNode = ( Path.isBefore(dragPath, _dropPath) && Path.isSibling(dragPath, _dropPath); const to = before ? _dropPath : Path.next(_dropPath); - moveNodes(editor, { - at: dragPath, - to, - }); + return { dragPath, to }; } }; + +export const onDropNode = ( + editor: TEditor, + { + id, + dragItem, + monitor, + nodeRef, + }: { + dragItem: ElementDragItemNode; + monitor: DropTargetMonitor; + } & Pick +) => { + const result = getDropPath(editor, { + id, + dragItem, + monitor, + nodeRef, + }); + + if (!result) return; + + const { dragPath, to } = result; + + moveNodes(editor, { + at: dragPath, + to, + }); +}; diff --git a/packages/dnd/src/types.ts b/packages/dnd/src/types.ts index 21629a6bf8..f628e82f25 100644 --- a/packages/dnd/src/types.ts +++ b/packages/dnd/src/types.ts @@ -1,9 +1,17 @@ -export interface DragItemNode { +export type DragItemNode = ElementDragItemNode | FileDragItemNode; + +export interface ElementDragItemNode { /** Required to identify the node. */ id: string; [key: string]: unknown; } +export interface FileDragItemNode { + dataTransfer: DataTransfer[]; + files: FileList; + items: DataTransferItemList; +} + export type DropLineDirection = '' | 'bottom' | 'top'; export type DropDirection = 'bottom' | 'top' | undefined; diff --git a/packages/media/src/lib/image/BaseImagePlugin.ts b/packages/media/src/lib/image/BaseImagePlugin.ts index 99b8bf98c3..c99c69c249 100644 --- a/packages/media/src/lib/image/BaseImagePlugin.ts +++ b/packages/media/src/lib/image/BaseImagePlugin.ts @@ -1,7 +1,12 @@ -import { type PluginConfig, createTSlatePlugin } from '@udecode/plate-common'; +import { + type PluginConfig, + bindFirst, + createTSlatePlugin, +} from '@udecode/plate-common'; import type { MediaPluginOptions, TMediaElement } from '../media'; +import { insertImageFromFiles } from './transforms/insertImageFromFiles'; import { withImage } from './withImage'; export interface TImageElement extends TMediaElement { @@ -38,20 +43,24 @@ export const BaseImagePlugin = createTSlatePlugin({ isElement: true, isVoid: true, }, -}).extend(({ plugin }) => ({ - parsers: { - html: { - deserializer: { - parse: ({ element }) => ({ - type: plugin.node.type, - url: element.getAttribute('src'), - }), - rules: [ - { - validNodeName: 'IMG', - }, - ], +}) + .extendEditorTransforms(({ editor }) => ({ + insertImageFromFiles: bindFirst(insertImageFromFiles, editor), + })) + .extend(({ plugin }) => ({ + parsers: { + html: { + deserializer: { + parse: ({ element }) => ({ + type: plugin.node.type, + url: element.getAttribute('src'), + }), + rules: [ + { + validNodeName: 'IMG', + }, + ], + }, }, }, - }, -})); + })); diff --git a/packages/media/src/lib/image/transforms/insertImageFromFiles.ts b/packages/media/src/lib/image/transforms/insertImageFromFiles.ts new file mode 100644 index 0000000000..3f2b1dec84 --- /dev/null +++ b/packages/media/src/lib/image/transforms/insertImageFromFiles.ts @@ -0,0 +1,33 @@ +import type { InsertNodesOptions, SlateEditor } from '@udecode/plate-common'; + +import { ImagePlugin } from '../../../react'; +import { insertImage } from './insertImage'; + +export const insertImageFromFiles = ( + editor: SlateEditor, + files: FileList, + options: InsertNodesOptions = {} +) => { + for (const file of files) { + const reader = new FileReader(); + const [mime] = file.type.split('/'); + + if (mime === 'image') { + reader.addEventListener('load', async () => { + if (!reader.result) { + return; + } + + const uploadImage = editor.getOptions(ImagePlugin).uploadImage; + + const uploadedUrl = uploadImage + ? await uploadImage(reader.result) + : reader.result; + + insertImage(editor, uploadedUrl, options); + }); + + reader.readAsDataURL(file); + } + } +}; diff --git a/packages/media/src/lib/image/withImageUpload.ts b/packages/media/src/lib/image/withImageUpload.ts index 15f12b0e79..f8a21db241 100644 --- a/packages/media/src/lib/image/withImageUpload.ts +++ b/packages/media/src/lib/image/withImageUpload.ts @@ -6,7 +6,7 @@ import { import type { ImageConfig } from './BaseImagePlugin'; -import { insertImage } from './transforms/insertImage'; +import { ImagePlugin } from '../../react'; /** * Allows for pasting images from clipboard. Not yet: dragging and dropping @@ -39,30 +39,9 @@ export const withImageUpload: ExtendEditor = ({ return insertData(dataTransfer); } - for (const file of files) { - const reader = new FileReader(); - const [mime] = file.type.split('/'); - - if (mime === 'image') { - reader.addEventListener('load', async () => { - if (!reader.result) { - return; - } - - const uploadImage = getOptions().uploadImage; - - const uploadedUrl = uploadImage - ? await uploadImage(reader.result) - : reader.result; - - insertImage(editor, uploadedUrl); - }); - - reader.readAsDataURL(file); - } - } + editor.getTransforms(ImagePlugin).insertImageFromFiles(files); } else { - insertData(dataTransfer); + return insertData(dataTransfer); } }; From 8f5063baba0db5f2d6cd319334ee5ee7e9106f29 Mon Sep 17 00:00:00 2001 From: Felix Feng Date: Mon, 4 Nov 2024 09:36:04 +0800 Subject: [PATCH 14/25] fix --- .../www/src/registry/default/example/playground-demo.tsx | 5 ++--- packages/dnd/src/hooks/useDropNode.ts | 9 +-------- packages/dnd/src/utils/getHoverDirection.ts | 8 ++++++-- 3 files changed, 9 insertions(+), 13 deletions(-) diff --git a/apps/www/src/registry/default/example/playground-demo.tsx b/apps/www/src/registry/default/example/playground-demo.tsx index 2fbd29967c..cd71d5cc3f 100644 --- a/apps/www/src/registry/default/example/playground-demo.tsx +++ b/apps/www/src/registry/default/example/playground-demo.tsx @@ -301,12 +301,11 @@ export const usePlaygroundEditor = (id: any = '', scrollSelector?: string) => { options: { enableScroller: true, onDropFiles: (editor, props) => { - console.log(props.dropPath, 'fj'); - editor .getTransforms(ImagePlugin) .insertImageFromFiles(props.dragItem.files, { at: props.dropPath, + nextBlock: false, }); }, }, @@ -334,7 +333,7 @@ export const usePlaygroundEditor = (id: any = '', scrollSelector?: string) => { TrailingBlockPlugin.configure({ options: { type: ParagraphPlugin.key }, }), - // DragOverCursorPlugin, + DragOverCursorPlugin, // Collaboration CommentsPlugin.configure({ diff --git a/packages/dnd/src/hooks/useDropNode.ts b/packages/dnd/src/hooks/useDropNode.ts index 609a54552b..bbaeb315fe 100644 --- a/packages/dnd/src/hooks/useDropNode.ts +++ b/packages/dnd/src/hooks/useDropNode.ts @@ -6,8 +6,6 @@ import { import type { PlateEditor } from '@udecode/plate-common/react'; -import { Path } from 'slate'; - import type { DragItemNode, DropLineDirection, @@ -99,15 +97,10 @@ export const useDropNode = ( if (!result || !onDropFiles) return; - //FIXME - const isFirstPath = Path.equals(result.to, [0]); - - const dropPath = isFirstPath ? [0] : Path.previous(result.to); - return onDropFiles(editor, { id, dragItem: dragItem as FileDragItemNode, - dropPath: dropPath, + dropPath: result.to, monitor, nodeRef, }); diff --git a/packages/dnd/src/utils/getHoverDirection.ts b/packages/dnd/src/utils/getHoverDirection.ts index 0d0ea0db75..67ed5d8346 100644 --- a/packages/dnd/src/utils/getHoverDirection.ts +++ b/packages/dnd/src/utils/getHoverDirection.ts @@ -1,6 +1,10 @@ import type { DropTargetMonitor, XYCoord } from 'react-dnd'; -import type { DragItemNode, DropDirection } from '../types'; +import type { + DragItemNode, + DropDirection, + ElementDragItemNode, +} from '../types'; export interface GetHoverDirectionOptions { /** Hovering node id. */ @@ -26,7 +30,7 @@ export const getHoverDirection = ({ }: GetHoverDirectionOptions): DropDirection => { if (!nodeRef.current) return; - const dragId = dragItem.id; + const dragId = (dragItem as ElementDragItemNode).id; // Don't replace items with themselves if (dragId === id) return; From 5bcc4d4c5b1614bef1e34e3a7dae8f3b5f9a533f Mon Sep 17 00:00:00 2001 From: Felix Feng <164472012+felixfeng33@users.noreply.github.com> Date: Mon, 4 Nov 2024 10:19:27 +0800 Subject: [PATCH 15/25] Update packages/dnd/src/DndPlugin.tsx Co-authored-by: Ziad Beyens --- packages/dnd/src/DndPlugin.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/dnd/src/DndPlugin.tsx b/packages/dnd/src/DndPlugin.tsx index ffa5fb4ff1..a2f1bb6e4a 100644 --- a/packages/dnd/src/DndPlugin.tsx +++ b/packages/dnd/src/DndPlugin.tsx @@ -21,8 +21,8 @@ export type DndConfig = PluginConfig< isDragging?: boolean; scrollerProps?: Partial; onDropFiles?: ( - editor: PlateEditor, props: { + editor: PlateEditor; id: string; dragItem: FileDragItemNode; monitor: DropTargetMonitor; From 42ee535678b31e7a0b9b26d0928711303a4f95c7 Mon Sep 17 00:00:00 2001 From: Felix Feng Date: Mon, 4 Nov 2024 14:12:17 +0800 Subject: [PATCH 16/25] wip --- apps/www/public/r/styles/default/ai-demo.json | 2 +- .../public/r/styles/default/align-demo.json | 2 +- .../r/styles/default/basic-elements-demo.json | 2 +- .../r/styles/default/basic-marks-demo.json | 2 +- .../r/styles/default/basic-nodes-demo.json | 2 +- .../r/styles/default/block-menu-demo.json | 2 +- .../r/styles/default/block-selection-demo.json | 2 +- .../public/r/styles/default/column-demo.json | 2 +- .../public/r/styles/default/comment-demo.json | 2 +- .../public/r/styles/default/copilot-demo.json | 2 +- .../www/public/r/styles/default/date-demo.json | 2 +- apps/www/public/r/styles/default/dnd-demo.json | 2 +- .../public/r/styles/default/emoji-demo.json | 2 +- .../r/styles/default/excalidraw-demo.json | 2 +- .../styles/default/floating-toolbar-demo.json | 2 +- .../www/public/r/styles/default/font-demo.json | 2 +- .../r/styles/default/highlight-demo.json | 2 +- apps/www/public/r/styles/default/hr-demo.json | 2 +- .../public/r/styles/default/image-element.json | 2 +- .../public/r/styles/default/indent-demo.json | 2 +- apps/www/public/r/styles/default/kbd-demo.json | 2 +- .../r/styles/default/line-height-demo.json | 2 +- .../www/public/r/styles/default/link-demo.json | 2 +- .../www/public/r/styles/default/list-demo.json | 2 +- .../public/r/styles/default/media-demo.json | 2 +- .../public/r/styles/default/mention-demo.json | 2 +- .../www/public/r/styles/default/mode-demo.json | 2 +- .../r/styles/default/placeholder-demo.json | 2 +- .../r/styles/default/playground-demo.json | 2 +- .../r/styles/default/resizable-demo.json | 2 +- .../r/styles/default/slash-command-demo.json | 2 +- .../public/r/styles/default/table-demo.json | 2 +- apps/www/public/r/styles/default/toc-demo.json | 2 +- .../public/r/styles/default/toggle-demo.json | 2 +- .../public/r/styles/default/toolbar-demo.json | 2 +- .../public/r/styles/default/upload-demo.json | 2 +- .../default/example/playground-demo.tsx | 6 +++--- .../default/plate-ui/image-element.tsx | 12 +++++++++++- packages/dnd/src/DndPlugin.tsx | 18 ++++++++---------- packages/dnd/src/hooks/useDropNode.ts | 5 +++-- .../media/src/lib/image/BaseImagePlugin.ts | 4 +++- .../src/lib/image/withImageEmbed.spec.tsx | 4 ++-- .../src/lib/image/withImageUpload.spec.tsx | 8 ++++---- .../media/src/lib/image/withImageUpload.ts | 2 +- 44 files changed, 71 insertions(+), 60 deletions(-) diff --git a/apps/www/public/r/styles/default/ai-demo.json b/apps/www/public/r/styles/default/ai-demo.json index a8d5cbe3f3..72b02bfb82 100644 --- a/apps/www/public/r/styles/default/ai-demo.json +++ b/apps/www/public/r/styles/default/ai-demo.json @@ -9,7 +9,7 @@ }, "files": [ { - "content": "'use client';\n\nimport React, { useRef } from 'react';\n\nimport type { ValueId } from '@/config/customizer-plugins';\n\nimport { cn } from '@udecode/cn';\nimport { AIChatPlugin, CopilotPlugin } from '@udecode/plate-ai/react';\nimport { AlignPlugin } from '@udecode/plate-alignment/react';\nimport { AutoformatPlugin } from '@udecode/plate-autoformat/react';\nimport {\n BoldPlugin,\n CodePlugin,\n ItalicPlugin,\n StrikethroughPlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n UnderlinePlugin,\n} from '@udecode/plate-basic-marks/react';\nimport { BlockquotePlugin } from '@udecode/plate-block-quote/react';\nimport { SingleLinePlugin } from '@udecode/plate-break/react';\nimport { CaptionPlugin } from '@udecode/plate-caption/react';\nimport { CodeBlockPlugin } from '@udecode/plate-code-block/react';\nimport { CommentsPlugin } from '@udecode/plate-comments/react';\nimport {\n ParagraphPlugin,\n Plate,\n usePlateEditor,\n} from '@udecode/plate-common/react';\nimport { DatePlugin } from '@udecode/plate-date/react';\nimport { DndPlugin } from '@udecode/plate-dnd';\nimport { DocxPlugin } from '@udecode/plate-docx';\nimport { EmojiPlugin } from '@udecode/plate-emoji/react';\nimport { ExcalidrawPlugin } from '@udecode/plate-excalidraw/react';\nimport {\n FontBackgroundColorPlugin,\n FontColorPlugin,\n FontSizePlugin,\n} from '@udecode/plate-font/react';\nimport { HEADING_KEYS } from '@udecode/plate-heading';\nimport { HeadingPlugin, TocPlugin } from '@udecode/plate-heading/react';\nimport { HighlightPlugin } from '@udecode/plate-highlight/react';\nimport { HorizontalRulePlugin } from '@udecode/plate-horizontal-rule/react';\nimport { IndentPlugin } from '@udecode/plate-indent/react';\nimport { IndentListPlugin } from '@udecode/plate-indent-list/react';\nimport { JuicePlugin } from '@udecode/plate-juice';\nimport { KbdPlugin } from '@udecode/plate-kbd/react';\nimport { ColumnPlugin } from '@udecode/plate-layout/react';\nimport { LineHeightPlugin } from '@udecode/plate-line-height/react';\nimport { LinkPlugin } from '@udecode/plate-link/react';\nimport { ListPlugin, TodoListPlugin } from '@udecode/plate-list/react';\nimport { MarkdownPlugin } from '@udecode/plate-markdown';\nimport { ImagePlugin, MediaEmbedPlugin } from '@udecode/plate-media/react';\nimport { MentionPlugin } from '@udecode/plate-mention/react';\nimport { NodeIdPlugin } from '@udecode/plate-node-id';\nimport { NormalizeTypesPlugin } from '@udecode/plate-normalizers';\nimport { PlaywrightPlugin } from '@udecode/plate-playwright';\nimport { DeletePlugin, SelectOnBackspacePlugin } from '@udecode/plate-select';\nimport {\n BlockMenuPlugin,\n BlockSelectionPlugin,\n} from '@udecode/plate-selection/react';\nimport { SlashPlugin } from '@udecode/plate-slash-command/react';\nimport { TablePlugin } from '@udecode/plate-table/react';\nimport { TogglePlugin } from '@udecode/plate-toggle/react';\nimport { TrailingBlockPlugin } from '@udecode/plate-trailing-block';\nimport Prism from 'prismjs';\n\nimport { CheckPlugin } from '@/components/context/check-plugin';\nimport { settingsStore } from '@/components/context/settings-store';\nimport { aiPlugins } from '@/lib/plate/demo/plugins/ai-plugins';\nimport { getAutoformatOptions } from '@/lib/plate/demo/plugins/autoformatOptions';\nimport { copilotPlugins } from '@/lib/plate/demo/plugins/copilot-plugins';\nimport { createPlateUI } from '@/plate/create-plate-ui';\nimport { editableProps } from '@/plate/demo/editableProps';\nimport { isEnabled } from '@/plate/demo/is-enabled';\nimport { DragOverCursorPlugin } from '@/plate/demo/plugins/DragOverCursorPlugin';\nimport { exitBreakPlugin } from '@/plate/demo/plugins/exitBreakPlugin';\nimport { resetBlockTypePlugin } from '@/plate/demo/plugins/resetBlockTypePlugin';\nimport { softBreakPlugin } from '@/plate/demo/plugins/softBreakPlugin';\nimport { tabbablePlugin } from '@/plate/demo/plugins/tabbablePlugin';\nimport { commentsData, usersData } from '@/plate/demo/values/commentsValue';\nimport { usePlaygroundValue } from '@/plate/demo/values/usePlaygroundValue';\nimport { BlockContextMenu } from '@/components/plate-ui/block-context-menu';\nimport { CommentsPopover } from '@/components/plate-ui/comments-popover';\nimport {\n CursorOverlay,\n SelectionOverlayPlugin,\n} from '@/components/plate-ui/cursor-overlay';\nimport { Editor, EditorContainer } from '@/components/plate-ui/editor';\nimport { FixedToolbar } from '@/components/plate-ui/fixed-toolbar';\nimport { FixedToolbarButtons } from '@/components/plate-ui/fixed-toolbar-buttons';\nimport { FloatingToolbar } from '@/components/plate-ui/floating-toolbar';\nimport { FloatingToolbarButtons } from '@/components/plate-ui/floating-toolbar-buttons';\nimport { ImagePreview } from '@/components/plate-ui/image-preview';\nimport {\n FireLiComponent,\n FireMarker,\n} from '@/components/plate-ui/indent-fire-marker';\nimport {\n TodoLi,\n TodoMarker,\n} from '@/components/plate-ui/indent-todo-marker';\nimport { LinkFloatingToolbar } from '@/components/plate-ui/link-floating-toolbar';\n\nimport { usePlaygroundEnabled } from './usePlaygroundEnabled';\n\nexport const usePlaygroundEditor = (id: any = '', scrollSelector?: string) => {\n const enabledPlugins = settingsStore.use.checkedPlugins();\n const overridePlugins = usePlaygroundEnabled(id);\n const autoformatOptions = getAutoformatOptions(id, enabledPlugins);\n\n const value = usePlaygroundValue(id);\n const key = settingsStore.use.version();\n const editorId = id || 'playground-' + key;\n\n return usePlateEditor(\n {\n id: editorId,\n override: {\n components: createPlateUI({\n draggable: isEnabled('dnd', id),\n placeholder: isEnabled('placeholder', id),\n }),\n plugins: overridePlugins,\n },\n plugins: [\n // AI\n ...(id === 'ai' || enabledPlugins[AIChatPlugin.key] ? aiPlugins : []),\n ...(id === 'copilot' || enabledPlugins[CopilotPlugin.key]\n ? copilotPlugins\n : []),\n // Nodes\n HeadingPlugin,\n TocPlugin.configure({\n options: {\n scrollContainerSelector: `#${scrollSelector}`,\n topOffset: 80,\n },\n }),\n BlockquotePlugin,\n CodeBlockPlugin.configure({\n options: {\n prism: Prism,\n },\n }),\n HorizontalRulePlugin,\n LinkPlugin.extend({\n render: { afterEditable: () => },\n }),\n ...(id === 'list' ? [ListPlugin] : []),\n ImagePlugin.extend({\n render: { afterEditable: ImagePreview },\n }),\n MediaEmbedPlugin,\n CaptionPlugin.configure({\n options: {\n plugins: [ImagePlugin, MediaEmbedPlugin],\n },\n }),\n DatePlugin,\n MentionPlugin.configure({\n options: {\n triggerPreviousCharPattern: /^$|^[\\s\"']$/,\n },\n }),\n SlashPlugin,\n TablePlugin.configure({\n options: {\n enableMerging: id === 'tableMerge',\n },\n }),\n ColumnPlugin,\n SelectionOverlayPlugin,\n\n TodoListPlugin,\n TogglePlugin,\n ExcalidrawPlugin,\n // Marks\n BoldPlugin,\n ItalicPlugin,\n UnderlinePlugin,\n StrikethroughPlugin,\n CodePlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n FontColorPlugin,\n FontBackgroundColorPlugin,\n FontSizePlugin,\n HighlightPlugin,\n KbdPlugin,\n\n // Block Style\n AlignPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n MediaEmbedPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n ImagePlugin.key,\n HEADING_KEYS.h6,\n ],\n },\n }),\n IndentPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n }),\n IndentListPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n options: {\n listStyleTypes: {\n fire: {\n liComponent: FireLiComponent,\n markerComponent: FireMarker,\n type: 'fire',\n },\n todo: {\n liComponent: TodoLi,\n markerComponent: TodoMarker,\n type: 'todo',\n },\n },\n },\n }),\n LineHeightPlugin.extend({\n inject: {\n nodeProps: {\n defaultNodeValue: 1.5,\n validNodeValues: [1, 1.2, 1.5, 2, 3],\n },\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n ],\n },\n }),\n\n // Functionality\n AutoformatPlugin.configure({\n options: autoformatOptions,\n }),\n BlockSelectionPlugin.configure({\n options: {\n areaOptions: {\n behaviour: {\n scrolling: {\n speedDivider: 1.5,\n },\n startThreshold: 10,\n },\n boundaries: `#${scrollSelector}`,\n container: `#${scrollSelector}`,\n selectables: [`#${scrollSelector} .slate-selectable`],\n selectionAreaClass: 'slate-selection-area',\n },\n enableContextMenu: true,\n },\n }),\n BlockMenuPlugin.configure({\n render: { aboveEditable: BlockContextMenu },\n }),\n DndPlugin.configure({ options: { enableScroller: true } }),\n EmojiPlugin,\n exitBreakPlugin,\n NodeIdPlugin,\n NormalizeTypesPlugin.configure({\n options: {\n rules: [{ path: [0], strictType: HEADING_KEYS.h1 }],\n },\n }),\n resetBlockTypePlugin,\n SelectOnBackspacePlugin.configure({\n options: {\n query: {\n allow: [ImagePlugin.key, HorizontalRulePlugin.key],\n },\n },\n }),\n DeletePlugin,\n SingleLinePlugin,\n softBreakPlugin,\n tabbablePlugin,\n TrailingBlockPlugin.configure({\n options: { type: ParagraphPlugin.key },\n }),\n DragOverCursorPlugin,\n\n // Collaboration\n CommentsPlugin.configure({\n options: {\n comments: commentsData,\n myUserId: '1',\n users: usersData,\n },\n }),\n\n // Deserialization\n DocxPlugin,\n MarkdownPlugin.configure({ options: { indentList: true } }),\n JuicePlugin,\n\n // Testing\n PlaywrightPlugin.configure({\n enabled: process.env.NODE_ENV !== 'production',\n }),\n ],\n value: value,\n },\n []\n );\n};\n\nexport default function PlaygroundDemo({\n id,\n className,\n scrollSelector,\n}: {\n id?: ValueId;\n className?: string;\n scrollSelector?: string;\n}) {\n const containerRef = useRef(null);\n const enabled = settingsStore.use.checkedComponents();\n\n const editor = usePlaygroundEditor(\n id,\n scrollSelector ?? `blockSelection-${id}`\n );\n\n return (\n \n \n \n \n \n \n \n \n \n\n
\n \n \n\n \n \n \n \n \n \n \n\n \n \n \n \n\n \n \n \n
\n
\n
\n );\n}\n\nconst DemoIdContext = React.createContext(undefined);\n\nexport function DemoId({\n id,\n children,\n}: {\n children: React.ReactNode;\n id?: string;\n}) {\n return {children};\n}\n\nexport function useDemoId() {\n return React.useContext(DemoIdContext);\n}\n", + "content": "'use client';\n\nimport React, { useRef } from 'react';\n\nimport type { ValueId } from '@/config/customizer-plugins';\n\nimport { cn } from '@udecode/cn';\nimport { AIChatPlugin, CopilotPlugin } from '@udecode/plate-ai/react';\nimport { AlignPlugin } from '@udecode/plate-alignment/react';\nimport { AutoformatPlugin } from '@udecode/plate-autoformat/react';\nimport {\n BoldPlugin,\n CodePlugin,\n ItalicPlugin,\n StrikethroughPlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n UnderlinePlugin,\n} from '@udecode/plate-basic-marks/react';\nimport { BlockquotePlugin } from '@udecode/plate-block-quote/react';\nimport { SingleLinePlugin } from '@udecode/plate-break/react';\nimport { CaptionPlugin } from '@udecode/plate-caption/react';\nimport { CodeBlockPlugin } from '@udecode/plate-code-block/react';\nimport { CommentsPlugin } from '@udecode/plate-comments/react';\nimport {\n ParagraphPlugin,\n Plate,\n usePlateEditor,\n} from '@udecode/plate-common/react';\nimport { DatePlugin } from '@udecode/plate-date/react';\nimport { DndPlugin } from '@udecode/plate-dnd';\nimport { DocxPlugin } from '@udecode/plate-docx';\nimport { EmojiPlugin } from '@udecode/plate-emoji/react';\nimport { ExcalidrawPlugin } from '@udecode/plate-excalidraw/react';\nimport {\n FontBackgroundColorPlugin,\n FontColorPlugin,\n FontSizePlugin,\n} from '@udecode/plate-font/react';\nimport { HEADING_KEYS } from '@udecode/plate-heading';\nimport { HeadingPlugin, TocPlugin } from '@udecode/plate-heading/react';\nimport { HighlightPlugin } from '@udecode/plate-highlight/react';\nimport { HorizontalRulePlugin } from '@udecode/plate-horizontal-rule/react';\nimport { IndentPlugin } from '@udecode/plate-indent/react';\nimport { IndentListPlugin } from '@udecode/plate-indent-list/react';\nimport { JuicePlugin } from '@udecode/plate-juice';\nimport { KbdPlugin } from '@udecode/plate-kbd/react';\nimport { ColumnPlugin } from '@udecode/plate-layout/react';\nimport { LineHeightPlugin } from '@udecode/plate-line-height/react';\nimport { LinkPlugin } from '@udecode/plate-link/react';\nimport { ListPlugin, TodoListPlugin } from '@udecode/plate-list/react';\nimport { MarkdownPlugin } from '@udecode/plate-markdown';\nimport { ImagePlugin, MediaEmbedPlugin } from '@udecode/plate-media/react';\nimport { MentionPlugin } from '@udecode/plate-mention/react';\nimport { NodeIdPlugin } from '@udecode/plate-node-id';\nimport { NormalizeTypesPlugin } from '@udecode/plate-normalizers';\nimport { PlaywrightPlugin } from '@udecode/plate-playwright';\nimport { DeletePlugin, SelectOnBackspacePlugin } from '@udecode/plate-select';\nimport {\n BlockMenuPlugin,\n BlockSelectionPlugin,\n} from '@udecode/plate-selection/react';\nimport { SlashPlugin } from '@udecode/plate-slash-command/react';\nimport { TablePlugin } from '@udecode/plate-table/react';\nimport { TogglePlugin } from '@udecode/plate-toggle/react';\nimport { TrailingBlockPlugin } from '@udecode/plate-trailing-block';\nimport Prism from 'prismjs';\n\nimport { CheckPlugin } from '@/components/context/check-plugin';\nimport { settingsStore } from '@/components/context/settings-store';\nimport { aiPlugins } from '@/lib/plate/demo/plugins/ai-plugins';\nimport { getAutoformatOptions } from '@/lib/plate/demo/plugins/autoformatOptions';\nimport { copilotPlugins } from '@/lib/plate/demo/plugins/copilot-plugins';\nimport { createPlateUI } from '@/plate/create-plate-ui';\nimport { editableProps } from '@/plate/demo/editableProps';\nimport { isEnabled } from '@/plate/demo/is-enabled';\nimport { DragOverCursorPlugin } from '@/plate/demo/plugins/DragOverCursorPlugin';\nimport { exitBreakPlugin } from '@/plate/demo/plugins/exitBreakPlugin';\nimport { resetBlockTypePlugin } from '@/plate/demo/plugins/resetBlockTypePlugin';\nimport { softBreakPlugin } from '@/plate/demo/plugins/softBreakPlugin';\nimport { tabbablePlugin } from '@/plate/demo/plugins/tabbablePlugin';\nimport { commentsData, usersData } from '@/plate/demo/values/commentsValue';\nimport { usePlaygroundValue } from '@/plate/demo/values/usePlaygroundValue';\nimport { BlockContextMenu } from '@/components/plate-ui/block-context-menu';\nimport { CommentsPopover } from '@/components/plate-ui/comments-popover';\nimport {\n CursorOverlay,\n SelectionOverlayPlugin,\n} from '@/components/plate-ui/cursor-overlay';\nimport { Editor, EditorContainer } from '@/components/plate-ui/editor';\nimport { FixedToolbar } from '@/components/plate-ui/fixed-toolbar';\nimport { FixedToolbarButtons } from '@/components/plate-ui/fixed-toolbar-buttons';\nimport { FloatingToolbar } from '@/components/plate-ui/floating-toolbar';\nimport { FloatingToolbarButtons } from '@/components/plate-ui/floating-toolbar-buttons';\nimport { ImagePreview } from '@/components/plate-ui/image-preview';\nimport {\n FireLiComponent,\n FireMarker,\n} from '@/components/plate-ui/indent-fire-marker';\nimport {\n TodoLi,\n TodoMarker,\n} from '@/components/plate-ui/indent-todo-marker';\nimport { LinkFloatingToolbar } from '@/components/plate-ui/link-floating-toolbar';\n\nimport { usePlaygroundEnabled } from './usePlaygroundEnabled';\n\nexport const usePlaygroundEditor = (id: any = '', scrollSelector?: string) => {\n const enabledPlugins = settingsStore.use.checkedPlugins();\n const overridePlugins = usePlaygroundEnabled(id);\n const autoformatOptions = getAutoformatOptions(id, enabledPlugins);\n\n const value = usePlaygroundValue(id);\n const key = settingsStore.use.version();\n const editorId = id || 'playground-' + key;\n\n return usePlateEditor(\n {\n id: editorId,\n override: {\n components: createPlateUI({\n draggable: isEnabled('dnd', id),\n placeholder: isEnabled('placeholder', id),\n }),\n plugins: overridePlugins,\n },\n plugins: [\n // AI\n ...(id === 'ai' || enabledPlugins[AIChatPlugin.key] ? aiPlugins : []),\n ...(id === 'copilot' || enabledPlugins[CopilotPlugin.key]\n ? copilotPlugins\n : []),\n // Nodes\n HeadingPlugin,\n TocPlugin.configure({\n options: {\n scrollContainerSelector: `#${scrollSelector}`,\n topOffset: 80,\n },\n }),\n BlockquotePlugin,\n CodeBlockPlugin.configure({\n options: {\n prism: Prism,\n },\n }),\n HorizontalRulePlugin,\n LinkPlugin.extend({\n render: { afterEditable: () => },\n }),\n ...(id === 'list' ? [ListPlugin] : []),\n ImagePlugin.extend({\n options: {\n disableUploadInsert: true,\n },\n render: { afterEditable: ImagePreview },\n }),\n MediaEmbedPlugin,\n CaptionPlugin.configure({\n options: {\n plugins: [ImagePlugin, MediaEmbedPlugin],\n },\n }),\n DatePlugin,\n MentionPlugin.configure({\n options: {\n triggerPreviousCharPattern: /^$|^[\\s\"']$/,\n },\n }),\n SlashPlugin,\n TablePlugin.configure({\n options: {\n enableMerging: id === 'tableMerge',\n },\n }),\n ColumnPlugin,\n SelectionOverlayPlugin,\n\n TodoListPlugin,\n TogglePlugin,\n ExcalidrawPlugin,\n // Marks\n BoldPlugin,\n ItalicPlugin,\n UnderlinePlugin,\n StrikethroughPlugin,\n CodePlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n FontColorPlugin,\n FontBackgroundColorPlugin,\n FontSizePlugin,\n HighlightPlugin,\n KbdPlugin,\n\n // Block Style\n AlignPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n MediaEmbedPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n ImagePlugin.key,\n HEADING_KEYS.h6,\n ],\n },\n }),\n IndentPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n }),\n IndentListPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n options: {\n listStyleTypes: {\n fire: {\n liComponent: FireLiComponent,\n markerComponent: FireMarker,\n type: 'fire',\n },\n todo: {\n liComponent: TodoLi,\n markerComponent: TodoMarker,\n type: 'todo',\n },\n },\n },\n }),\n LineHeightPlugin.extend({\n inject: {\n nodeProps: {\n defaultNodeValue: 1.5,\n validNodeValues: [1, 1.2, 1.5, 2, 3],\n },\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n ],\n },\n }),\n\n // Functionality\n AutoformatPlugin.configure({\n options: autoformatOptions,\n }),\n BlockSelectionPlugin.configure({\n options: {\n areaOptions: {\n behaviour: {\n scrolling: {\n speedDivider: 1.5,\n },\n startThreshold: 10,\n },\n boundaries: `#${scrollSelector}`,\n container: `#${scrollSelector}`,\n selectables: [`#${scrollSelector} .slate-selectable`],\n selectionAreaClass: 'slate-selection-area',\n },\n enableContextMenu: true,\n },\n }),\n BlockMenuPlugin.configure({\n render: { aboveEditable: BlockContextMenu },\n }),\n DndPlugin.configure({\n options: {\n enableScroller: true,\n onDropFiles: ({ dragItem, editor, target }) => {\n editor\n .getTransforms(ImagePlugin)\n .insertImageFromFiles(dragItem.files, {\n at: target,\n nextBlock: false,\n });\n },\n },\n }),\n EmojiPlugin,\n exitBreakPlugin,\n NodeIdPlugin,\n NormalizeTypesPlugin.configure({\n options: {\n rules: [{ path: [0], strictType: HEADING_KEYS.h1 }],\n },\n }),\n resetBlockTypePlugin,\n SelectOnBackspacePlugin.configure({\n options: {\n query: {\n allow: [ImagePlugin.key, HorizontalRulePlugin.key],\n },\n },\n }),\n DeletePlugin,\n SingleLinePlugin,\n softBreakPlugin,\n tabbablePlugin,\n TrailingBlockPlugin.configure({\n options: { type: ParagraphPlugin.key },\n }),\n DragOverCursorPlugin,\n\n // Collaboration\n CommentsPlugin.configure({\n options: {\n comments: commentsData,\n myUserId: '1',\n users: usersData,\n },\n }),\n\n // Deserialization\n DocxPlugin,\n MarkdownPlugin.configure({ options: { indentList: true } }),\n JuicePlugin,\n\n // Testing\n PlaywrightPlugin.configure({\n enabled: process.env.NODE_ENV !== 'production',\n }),\n ],\n value: value,\n },\n []\n );\n};\n\nexport default function PlaygroundDemo({\n id,\n className,\n scrollSelector,\n}: {\n id?: ValueId;\n className?: string;\n scrollSelector?: string;\n}) {\n const containerRef = useRef(null);\n const enabled = settingsStore.use.checkedComponents();\n\n const editor = usePlaygroundEditor(\n id,\n scrollSelector ?? `blockSelection-${id}`\n );\n\n return (\n \n \n \n \n \n \n \n \n \n\n
\n \n \n\n \n \n \n \n \n \n \n\n \n \n \n \n\n \n \n \n
\n
\n
\n );\n}\n\nconst DemoIdContext = React.createContext(undefined);\n\nexport function DemoId({\n id,\n children,\n}: {\n children: React.ReactNode;\n id?: string;\n}) {\n return {children};\n}\n\nexport function useDemoId() {\n return React.useContext(DemoIdContext);\n}\n", "path": "example/playground-demo.tsx", "target": "components/playground-demo.tsx", "type": "registry:example" diff --git a/apps/www/public/r/styles/default/align-demo.json b/apps/www/public/r/styles/default/align-demo.json index cdba8763c8..fbbb2cf467 100644 --- a/apps/www/public/r/styles/default/align-demo.json +++ b/apps/www/public/r/styles/default/align-demo.json @@ -4,7 +4,7 @@ }, "files": [ { - "content": "'use client';\n\nimport React, { useRef } from 'react';\n\nimport type { ValueId } from '@/config/customizer-plugins';\n\nimport { cn } from '@udecode/cn';\nimport { AIChatPlugin, CopilotPlugin } from '@udecode/plate-ai/react';\nimport { AlignPlugin } from '@udecode/plate-alignment/react';\nimport { AutoformatPlugin } from '@udecode/plate-autoformat/react';\nimport {\n BoldPlugin,\n CodePlugin,\n ItalicPlugin,\n StrikethroughPlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n UnderlinePlugin,\n} from '@udecode/plate-basic-marks/react';\nimport { BlockquotePlugin } from '@udecode/plate-block-quote/react';\nimport { SingleLinePlugin } from '@udecode/plate-break/react';\nimport { CaptionPlugin } from '@udecode/plate-caption/react';\nimport { CodeBlockPlugin } from '@udecode/plate-code-block/react';\nimport { CommentsPlugin } from '@udecode/plate-comments/react';\nimport {\n ParagraphPlugin,\n Plate,\n usePlateEditor,\n} from '@udecode/plate-common/react';\nimport { DatePlugin } from '@udecode/plate-date/react';\nimport { DndPlugin } from '@udecode/plate-dnd';\nimport { DocxPlugin } from '@udecode/plate-docx';\nimport { EmojiPlugin } from '@udecode/plate-emoji/react';\nimport { ExcalidrawPlugin } from '@udecode/plate-excalidraw/react';\nimport {\n FontBackgroundColorPlugin,\n FontColorPlugin,\n FontSizePlugin,\n} from '@udecode/plate-font/react';\nimport { HEADING_KEYS } from '@udecode/plate-heading';\nimport { HeadingPlugin, TocPlugin } from '@udecode/plate-heading/react';\nimport { HighlightPlugin } from '@udecode/plate-highlight/react';\nimport { HorizontalRulePlugin } from '@udecode/plate-horizontal-rule/react';\nimport { IndentPlugin } from '@udecode/plate-indent/react';\nimport { IndentListPlugin } from '@udecode/plate-indent-list/react';\nimport { JuicePlugin } from '@udecode/plate-juice';\nimport { KbdPlugin } from '@udecode/plate-kbd/react';\nimport { ColumnPlugin } from '@udecode/plate-layout/react';\nimport { LineHeightPlugin } from '@udecode/plate-line-height/react';\nimport { LinkPlugin } from '@udecode/plate-link/react';\nimport { ListPlugin, TodoListPlugin } from '@udecode/plate-list/react';\nimport { MarkdownPlugin } from '@udecode/plate-markdown';\nimport { ImagePlugin, MediaEmbedPlugin } from '@udecode/plate-media/react';\nimport { MentionPlugin } from '@udecode/plate-mention/react';\nimport { NodeIdPlugin } from '@udecode/plate-node-id';\nimport { NormalizeTypesPlugin } from '@udecode/plate-normalizers';\nimport { PlaywrightPlugin } from '@udecode/plate-playwright';\nimport { DeletePlugin, SelectOnBackspacePlugin } from '@udecode/plate-select';\nimport {\n BlockMenuPlugin,\n BlockSelectionPlugin,\n} from '@udecode/plate-selection/react';\nimport { SlashPlugin } from '@udecode/plate-slash-command/react';\nimport { TablePlugin } from '@udecode/plate-table/react';\nimport { TogglePlugin } from '@udecode/plate-toggle/react';\nimport { TrailingBlockPlugin } from '@udecode/plate-trailing-block';\nimport Prism from 'prismjs';\n\nimport { CheckPlugin } from '@/components/context/check-plugin';\nimport { settingsStore } from '@/components/context/settings-store';\nimport { aiPlugins } from '@/lib/plate/demo/plugins/ai-plugins';\nimport { getAutoformatOptions } from '@/lib/plate/demo/plugins/autoformatOptions';\nimport { copilotPlugins } from '@/lib/plate/demo/plugins/copilot-plugins';\nimport { createPlateUI } from '@/plate/create-plate-ui';\nimport { editableProps } from '@/plate/demo/editableProps';\nimport { isEnabled } from '@/plate/demo/is-enabled';\nimport { DragOverCursorPlugin } from '@/plate/demo/plugins/DragOverCursorPlugin';\nimport { exitBreakPlugin } from '@/plate/demo/plugins/exitBreakPlugin';\nimport { resetBlockTypePlugin } from '@/plate/demo/plugins/resetBlockTypePlugin';\nimport { softBreakPlugin } from '@/plate/demo/plugins/softBreakPlugin';\nimport { tabbablePlugin } from '@/plate/demo/plugins/tabbablePlugin';\nimport { commentsData, usersData } from '@/plate/demo/values/commentsValue';\nimport { usePlaygroundValue } from '@/plate/demo/values/usePlaygroundValue';\nimport { BlockContextMenu } from '@/components/plate-ui/block-context-menu';\nimport { CommentsPopover } from '@/components/plate-ui/comments-popover';\nimport {\n CursorOverlay,\n SelectionOverlayPlugin,\n} from '@/components/plate-ui/cursor-overlay';\nimport { Editor, EditorContainer } from '@/components/plate-ui/editor';\nimport { FixedToolbar } from '@/components/plate-ui/fixed-toolbar';\nimport { FixedToolbarButtons } from '@/components/plate-ui/fixed-toolbar-buttons';\nimport { FloatingToolbar } from '@/components/plate-ui/floating-toolbar';\nimport { FloatingToolbarButtons } from '@/components/plate-ui/floating-toolbar-buttons';\nimport { ImagePreview } from '@/components/plate-ui/image-preview';\nimport {\n FireLiComponent,\n FireMarker,\n} from '@/components/plate-ui/indent-fire-marker';\nimport {\n TodoLi,\n TodoMarker,\n} from '@/components/plate-ui/indent-todo-marker';\nimport { LinkFloatingToolbar } from '@/components/plate-ui/link-floating-toolbar';\n\nimport { usePlaygroundEnabled } from './usePlaygroundEnabled';\n\nexport const usePlaygroundEditor = (id: any = '', scrollSelector?: string) => {\n const enabledPlugins = settingsStore.use.checkedPlugins();\n const overridePlugins = usePlaygroundEnabled(id);\n const autoformatOptions = getAutoformatOptions(id, enabledPlugins);\n\n const value = usePlaygroundValue(id);\n const key = settingsStore.use.version();\n const editorId = id || 'playground-' + key;\n\n return usePlateEditor(\n {\n id: editorId,\n override: {\n components: createPlateUI({\n draggable: isEnabled('dnd', id),\n placeholder: isEnabled('placeholder', id),\n }),\n plugins: overridePlugins,\n },\n plugins: [\n // AI\n ...(id === 'ai' || enabledPlugins[AIChatPlugin.key] ? aiPlugins : []),\n ...(id === 'copilot' || enabledPlugins[CopilotPlugin.key]\n ? copilotPlugins\n : []),\n // Nodes\n HeadingPlugin,\n TocPlugin.configure({\n options: {\n scrollContainerSelector: `#${scrollSelector}`,\n topOffset: 80,\n },\n }),\n BlockquotePlugin,\n CodeBlockPlugin.configure({\n options: {\n prism: Prism,\n },\n }),\n HorizontalRulePlugin,\n LinkPlugin.extend({\n render: { afterEditable: () => },\n }),\n ...(id === 'list' ? [ListPlugin] : []),\n ImagePlugin.extend({\n render: { afterEditable: ImagePreview },\n }),\n MediaEmbedPlugin,\n CaptionPlugin.configure({\n options: {\n plugins: [ImagePlugin, MediaEmbedPlugin],\n },\n }),\n DatePlugin,\n MentionPlugin.configure({\n options: {\n triggerPreviousCharPattern: /^$|^[\\s\"']$/,\n },\n }),\n SlashPlugin,\n TablePlugin.configure({\n options: {\n enableMerging: id === 'tableMerge',\n },\n }),\n ColumnPlugin,\n SelectionOverlayPlugin,\n\n TodoListPlugin,\n TogglePlugin,\n ExcalidrawPlugin,\n // Marks\n BoldPlugin,\n ItalicPlugin,\n UnderlinePlugin,\n StrikethroughPlugin,\n CodePlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n FontColorPlugin,\n FontBackgroundColorPlugin,\n FontSizePlugin,\n HighlightPlugin,\n KbdPlugin,\n\n // Block Style\n AlignPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n MediaEmbedPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n ImagePlugin.key,\n HEADING_KEYS.h6,\n ],\n },\n }),\n IndentPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n }),\n IndentListPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n options: {\n listStyleTypes: {\n fire: {\n liComponent: FireLiComponent,\n markerComponent: FireMarker,\n type: 'fire',\n },\n todo: {\n liComponent: TodoLi,\n markerComponent: TodoMarker,\n type: 'todo',\n },\n },\n },\n }),\n LineHeightPlugin.extend({\n inject: {\n nodeProps: {\n defaultNodeValue: 1.5,\n validNodeValues: [1, 1.2, 1.5, 2, 3],\n },\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n ],\n },\n }),\n\n // Functionality\n AutoformatPlugin.configure({\n options: autoformatOptions,\n }),\n BlockSelectionPlugin.configure({\n options: {\n areaOptions: {\n behaviour: {\n scrolling: {\n speedDivider: 1.5,\n },\n startThreshold: 10,\n },\n boundaries: `#${scrollSelector}`,\n container: `#${scrollSelector}`,\n selectables: [`#${scrollSelector} .slate-selectable`],\n selectionAreaClass: 'slate-selection-area',\n },\n enableContextMenu: true,\n },\n }),\n BlockMenuPlugin.configure({\n render: { aboveEditable: BlockContextMenu },\n }),\n DndPlugin.configure({ options: { enableScroller: true } }),\n EmojiPlugin,\n exitBreakPlugin,\n NodeIdPlugin,\n NormalizeTypesPlugin.configure({\n options: {\n rules: [{ path: [0], strictType: HEADING_KEYS.h1 }],\n },\n }),\n resetBlockTypePlugin,\n SelectOnBackspacePlugin.configure({\n options: {\n query: {\n allow: [ImagePlugin.key, HorizontalRulePlugin.key],\n },\n },\n }),\n DeletePlugin,\n SingleLinePlugin,\n softBreakPlugin,\n tabbablePlugin,\n TrailingBlockPlugin.configure({\n options: { type: ParagraphPlugin.key },\n }),\n DragOverCursorPlugin,\n\n // Collaboration\n CommentsPlugin.configure({\n options: {\n comments: commentsData,\n myUserId: '1',\n users: usersData,\n },\n }),\n\n // Deserialization\n DocxPlugin,\n MarkdownPlugin.configure({ options: { indentList: true } }),\n JuicePlugin,\n\n // Testing\n PlaywrightPlugin.configure({\n enabled: process.env.NODE_ENV !== 'production',\n }),\n ],\n value: value,\n },\n []\n );\n};\n\nexport default function PlaygroundDemo({\n id,\n className,\n scrollSelector,\n}: {\n id?: ValueId;\n className?: string;\n scrollSelector?: string;\n}) {\n const containerRef = useRef(null);\n const enabled = settingsStore.use.checkedComponents();\n\n const editor = usePlaygroundEditor(\n id,\n scrollSelector ?? `blockSelection-${id}`\n );\n\n return (\n \n \n \n \n \n \n \n \n \n\n
\n \n \n\n \n \n \n \n \n \n \n\n \n \n \n \n\n \n \n \n
\n
\n
\n );\n}\n\nconst DemoIdContext = React.createContext(undefined);\n\nexport function DemoId({\n id,\n children,\n}: {\n children: React.ReactNode;\n id?: string;\n}) {\n return {children};\n}\n\nexport function useDemoId() {\n return React.useContext(DemoIdContext);\n}\n", + "content": "'use client';\n\nimport React, { useRef } from 'react';\n\nimport type { ValueId } from '@/config/customizer-plugins';\n\nimport { cn } from '@udecode/cn';\nimport { AIChatPlugin, CopilotPlugin } from '@udecode/plate-ai/react';\nimport { AlignPlugin } from '@udecode/plate-alignment/react';\nimport { AutoformatPlugin } from '@udecode/plate-autoformat/react';\nimport {\n BoldPlugin,\n CodePlugin,\n ItalicPlugin,\n StrikethroughPlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n UnderlinePlugin,\n} from '@udecode/plate-basic-marks/react';\nimport { BlockquotePlugin } from '@udecode/plate-block-quote/react';\nimport { SingleLinePlugin } from '@udecode/plate-break/react';\nimport { CaptionPlugin } from '@udecode/plate-caption/react';\nimport { CodeBlockPlugin } from '@udecode/plate-code-block/react';\nimport { CommentsPlugin } from '@udecode/plate-comments/react';\nimport {\n ParagraphPlugin,\n Plate,\n usePlateEditor,\n} from '@udecode/plate-common/react';\nimport { DatePlugin } from '@udecode/plate-date/react';\nimport { DndPlugin } from '@udecode/plate-dnd';\nimport { DocxPlugin } from '@udecode/plate-docx';\nimport { EmojiPlugin } from '@udecode/plate-emoji/react';\nimport { ExcalidrawPlugin } from '@udecode/plate-excalidraw/react';\nimport {\n FontBackgroundColorPlugin,\n FontColorPlugin,\n FontSizePlugin,\n} from '@udecode/plate-font/react';\nimport { HEADING_KEYS } from '@udecode/plate-heading';\nimport { HeadingPlugin, TocPlugin } from '@udecode/plate-heading/react';\nimport { HighlightPlugin } from '@udecode/plate-highlight/react';\nimport { HorizontalRulePlugin } from '@udecode/plate-horizontal-rule/react';\nimport { IndentPlugin } from '@udecode/plate-indent/react';\nimport { IndentListPlugin } from '@udecode/plate-indent-list/react';\nimport { JuicePlugin } from '@udecode/plate-juice';\nimport { KbdPlugin } from '@udecode/plate-kbd/react';\nimport { ColumnPlugin } from '@udecode/plate-layout/react';\nimport { LineHeightPlugin } from '@udecode/plate-line-height/react';\nimport { LinkPlugin } from '@udecode/plate-link/react';\nimport { ListPlugin, TodoListPlugin } from '@udecode/plate-list/react';\nimport { MarkdownPlugin } from '@udecode/plate-markdown';\nimport { ImagePlugin, MediaEmbedPlugin } from '@udecode/plate-media/react';\nimport { MentionPlugin } from '@udecode/plate-mention/react';\nimport { NodeIdPlugin } from '@udecode/plate-node-id';\nimport { NormalizeTypesPlugin } from '@udecode/plate-normalizers';\nimport { PlaywrightPlugin } from '@udecode/plate-playwright';\nimport { DeletePlugin, SelectOnBackspacePlugin } from '@udecode/plate-select';\nimport {\n BlockMenuPlugin,\n BlockSelectionPlugin,\n} from '@udecode/plate-selection/react';\nimport { SlashPlugin } from '@udecode/plate-slash-command/react';\nimport { TablePlugin } from '@udecode/plate-table/react';\nimport { TogglePlugin } from '@udecode/plate-toggle/react';\nimport { TrailingBlockPlugin } from '@udecode/plate-trailing-block';\nimport Prism from 'prismjs';\n\nimport { CheckPlugin } from '@/components/context/check-plugin';\nimport { settingsStore } from '@/components/context/settings-store';\nimport { aiPlugins } from '@/lib/plate/demo/plugins/ai-plugins';\nimport { getAutoformatOptions } from '@/lib/plate/demo/plugins/autoformatOptions';\nimport { copilotPlugins } from '@/lib/plate/demo/plugins/copilot-plugins';\nimport { createPlateUI } from '@/plate/create-plate-ui';\nimport { editableProps } from '@/plate/demo/editableProps';\nimport { isEnabled } from '@/plate/demo/is-enabled';\nimport { DragOverCursorPlugin } from '@/plate/demo/plugins/DragOverCursorPlugin';\nimport { exitBreakPlugin } from '@/plate/demo/plugins/exitBreakPlugin';\nimport { resetBlockTypePlugin } from '@/plate/demo/plugins/resetBlockTypePlugin';\nimport { softBreakPlugin } from '@/plate/demo/plugins/softBreakPlugin';\nimport { tabbablePlugin } from '@/plate/demo/plugins/tabbablePlugin';\nimport { commentsData, usersData } from '@/plate/demo/values/commentsValue';\nimport { usePlaygroundValue } from '@/plate/demo/values/usePlaygroundValue';\nimport { BlockContextMenu } from '@/components/plate-ui/block-context-menu';\nimport { CommentsPopover } from '@/components/plate-ui/comments-popover';\nimport {\n CursorOverlay,\n SelectionOverlayPlugin,\n} from '@/components/plate-ui/cursor-overlay';\nimport { Editor, EditorContainer } from '@/components/plate-ui/editor';\nimport { FixedToolbar } from '@/components/plate-ui/fixed-toolbar';\nimport { FixedToolbarButtons } from '@/components/plate-ui/fixed-toolbar-buttons';\nimport { FloatingToolbar } from '@/components/plate-ui/floating-toolbar';\nimport { FloatingToolbarButtons } from '@/components/plate-ui/floating-toolbar-buttons';\nimport { ImagePreview } from '@/components/plate-ui/image-preview';\nimport {\n FireLiComponent,\n FireMarker,\n} from '@/components/plate-ui/indent-fire-marker';\nimport {\n TodoLi,\n TodoMarker,\n} from '@/components/plate-ui/indent-todo-marker';\nimport { LinkFloatingToolbar } from '@/components/plate-ui/link-floating-toolbar';\n\nimport { usePlaygroundEnabled } from './usePlaygroundEnabled';\n\nexport const usePlaygroundEditor = (id: any = '', scrollSelector?: string) => {\n const enabledPlugins = settingsStore.use.checkedPlugins();\n const overridePlugins = usePlaygroundEnabled(id);\n const autoformatOptions = getAutoformatOptions(id, enabledPlugins);\n\n const value = usePlaygroundValue(id);\n const key = settingsStore.use.version();\n const editorId = id || 'playground-' + key;\n\n return usePlateEditor(\n {\n id: editorId,\n override: {\n components: createPlateUI({\n draggable: isEnabled('dnd', id),\n placeholder: isEnabled('placeholder', id),\n }),\n plugins: overridePlugins,\n },\n plugins: [\n // AI\n ...(id === 'ai' || enabledPlugins[AIChatPlugin.key] ? aiPlugins : []),\n ...(id === 'copilot' || enabledPlugins[CopilotPlugin.key]\n ? copilotPlugins\n : []),\n // Nodes\n HeadingPlugin,\n TocPlugin.configure({\n options: {\n scrollContainerSelector: `#${scrollSelector}`,\n topOffset: 80,\n },\n }),\n BlockquotePlugin,\n CodeBlockPlugin.configure({\n options: {\n prism: Prism,\n },\n }),\n HorizontalRulePlugin,\n LinkPlugin.extend({\n render: { afterEditable: () => },\n }),\n ...(id === 'list' ? [ListPlugin] : []),\n ImagePlugin.extend({\n options: {\n disableUploadInsert: true,\n },\n render: { afterEditable: ImagePreview },\n }),\n MediaEmbedPlugin,\n CaptionPlugin.configure({\n options: {\n plugins: [ImagePlugin, MediaEmbedPlugin],\n },\n }),\n DatePlugin,\n MentionPlugin.configure({\n options: {\n triggerPreviousCharPattern: /^$|^[\\s\"']$/,\n },\n }),\n SlashPlugin,\n TablePlugin.configure({\n options: {\n enableMerging: id === 'tableMerge',\n },\n }),\n ColumnPlugin,\n SelectionOverlayPlugin,\n\n TodoListPlugin,\n TogglePlugin,\n ExcalidrawPlugin,\n // Marks\n BoldPlugin,\n ItalicPlugin,\n UnderlinePlugin,\n StrikethroughPlugin,\n CodePlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n FontColorPlugin,\n FontBackgroundColorPlugin,\n FontSizePlugin,\n HighlightPlugin,\n KbdPlugin,\n\n // Block Style\n AlignPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n MediaEmbedPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n ImagePlugin.key,\n HEADING_KEYS.h6,\n ],\n },\n }),\n IndentPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n }),\n IndentListPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n options: {\n listStyleTypes: {\n fire: {\n liComponent: FireLiComponent,\n markerComponent: FireMarker,\n type: 'fire',\n },\n todo: {\n liComponent: TodoLi,\n markerComponent: TodoMarker,\n type: 'todo',\n },\n },\n },\n }),\n LineHeightPlugin.extend({\n inject: {\n nodeProps: {\n defaultNodeValue: 1.5,\n validNodeValues: [1, 1.2, 1.5, 2, 3],\n },\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n ],\n },\n }),\n\n // Functionality\n AutoformatPlugin.configure({\n options: autoformatOptions,\n }),\n BlockSelectionPlugin.configure({\n options: {\n areaOptions: {\n behaviour: {\n scrolling: {\n speedDivider: 1.5,\n },\n startThreshold: 10,\n },\n boundaries: `#${scrollSelector}`,\n container: `#${scrollSelector}`,\n selectables: [`#${scrollSelector} .slate-selectable`],\n selectionAreaClass: 'slate-selection-area',\n },\n enableContextMenu: true,\n },\n }),\n BlockMenuPlugin.configure({\n render: { aboveEditable: BlockContextMenu },\n }),\n DndPlugin.configure({\n options: {\n enableScroller: true,\n onDropFiles: ({ dragItem, editor, target }) => {\n editor\n .getTransforms(ImagePlugin)\n .insertImageFromFiles(dragItem.files, {\n at: target,\n nextBlock: false,\n });\n },\n },\n }),\n EmojiPlugin,\n exitBreakPlugin,\n NodeIdPlugin,\n NormalizeTypesPlugin.configure({\n options: {\n rules: [{ path: [0], strictType: HEADING_KEYS.h1 }],\n },\n }),\n resetBlockTypePlugin,\n SelectOnBackspacePlugin.configure({\n options: {\n query: {\n allow: [ImagePlugin.key, HorizontalRulePlugin.key],\n },\n },\n }),\n DeletePlugin,\n SingleLinePlugin,\n softBreakPlugin,\n tabbablePlugin,\n TrailingBlockPlugin.configure({\n options: { type: ParagraphPlugin.key },\n }),\n DragOverCursorPlugin,\n\n // Collaboration\n CommentsPlugin.configure({\n options: {\n comments: commentsData,\n myUserId: '1',\n users: usersData,\n },\n }),\n\n // Deserialization\n DocxPlugin,\n MarkdownPlugin.configure({ options: { indentList: true } }),\n JuicePlugin,\n\n // Testing\n PlaywrightPlugin.configure({\n enabled: process.env.NODE_ENV !== 'production',\n }),\n ],\n value: value,\n },\n []\n );\n};\n\nexport default function PlaygroundDemo({\n id,\n className,\n scrollSelector,\n}: {\n id?: ValueId;\n className?: string;\n scrollSelector?: string;\n}) {\n const containerRef = useRef(null);\n const enabled = settingsStore.use.checkedComponents();\n\n const editor = usePlaygroundEditor(\n id,\n scrollSelector ?? `blockSelection-${id}`\n );\n\n return (\n \n \n \n \n \n \n \n \n \n\n
\n \n \n\n \n \n \n \n \n \n \n\n \n \n \n \n\n \n \n \n
\n
\n
\n );\n}\n\nconst DemoIdContext = React.createContext(undefined);\n\nexport function DemoId({\n id,\n children,\n}: {\n children: React.ReactNode;\n id?: string;\n}) {\n return {children};\n}\n\nexport function useDemoId() {\n return React.useContext(DemoIdContext);\n}\n", "path": "example/playground-demo.tsx", "target": "components/playground-demo.tsx", "type": "registry:example" diff --git a/apps/www/public/r/styles/default/basic-elements-demo.json b/apps/www/public/r/styles/default/basic-elements-demo.json index a6c3ffd3c1..2624ceceac 100644 --- a/apps/www/public/r/styles/default/basic-elements-demo.json +++ b/apps/www/public/r/styles/default/basic-elements-demo.json @@ -4,7 +4,7 @@ }, "files": [ { - "content": "'use client';\n\nimport React, { useRef } from 'react';\n\nimport type { ValueId } from '@/config/customizer-plugins';\n\nimport { cn } from '@udecode/cn';\nimport { AIChatPlugin, CopilotPlugin } from '@udecode/plate-ai/react';\nimport { AlignPlugin } from '@udecode/plate-alignment/react';\nimport { AutoformatPlugin } from '@udecode/plate-autoformat/react';\nimport {\n BoldPlugin,\n CodePlugin,\n ItalicPlugin,\n StrikethroughPlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n UnderlinePlugin,\n} from '@udecode/plate-basic-marks/react';\nimport { BlockquotePlugin } from '@udecode/plate-block-quote/react';\nimport { SingleLinePlugin } from '@udecode/plate-break/react';\nimport { CaptionPlugin } from '@udecode/plate-caption/react';\nimport { CodeBlockPlugin } from '@udecode/plate-code-block/react';\nimport { CommentsPlugin } from '@udecode/plate-comments/react';\nimport {\n ParagraphPlugin,\n Plate,\n usePlateEditor,\n} from '@udecode/plate-common/react';\nimport { DatePlugin } from '@udecode/plate-date/react';\nimport { DndPlugin } from '@udecode/plate-dnd';\nimport { DocxPlugin } from '@udecode/plate-docx';\nimport { EmojiPlugin } from '@udecode/plate-emoji/react';\nimport { ExcalidrawPlugin } from '@udecode/plate-excalidraw/react';\nimport {\n FontBackgroundColorPlugin,\n FontColorPlugin,\n FontSizePlugin,\n} from '@udecode/plate-font/react';\nimport { HEADING_KEYS } from '@udecode/plate-heading';\nimport { HeadingPlugin, TocPlugin } from '@udecode/plate-heading/react';\nimport { HighlightPlugin } from '@udecode/plate-highlight/react';\nimport { HorizontalRulePlugin } from '@udecode/plate-horizontal-rule/react';\nimport { IndentPlugin } from '@udecode/plate-indent/react';\nimport { IndentListPlugin } from '@udecode/plate-indent-list/react';\nimport { JuicePlugin } from '@udecode/plate-juice';\nimport { KbdPlugin } from '@udecode/plate-kbd/react';\nimport { ColumnPlugin } from '@udecode/plate-layout/react';\nimport { LineHeightPlugin } from '@udecode/plate-line-height/react';\nimport { LinkPlugin } from '@udecode/plate-link/react';\nimport { ListPlugin, TodoListPlugin } from '@udecode/plate-list/react';\nimport { MarkdownPlugin } from '@udecode/plate-markdown';\nimport { ImagePlugin, MediaEmbedPlugin } from '@udecode/plate-media/react';\nimport { MentionPlugin } from '@udecode/plate-mention/react';\nimport { NodeIdPlugin } from '@udecode/plate-node-id';\nimport { NormalizeTypesPlugin } from '@udecode/plate-normalizers';\nimport { PlaywrightPlugin } from '@udecode/plate-playwright';\nimport { DeletePlugin, SelectOnBackspacePlugin } from '@udecode/plate-select';\nimport {\n BlockMenuPlugin,\n BlockSelectionPlugin,\n} from '@udecode/plate-selection/react';\nimport { SlashPlugin } from '@udecode/plate-slash-command/react';\nimport { TablePlugin } from '@udecode/plate-table/react';\nimport { TogglePlugin } from '@udecode/plate-toggle/react';\nimport { TrailingBlockPlugin } from '@udecode/plate-trailing-block';\nimport Prism from 'prismjs';\n\nimport { CheckPlugin } from '@/components/context/check-plugin';\nimport { settingsStore } from '@/components/context/settings-store';\nimport { aiPlugins } from '@/lib/plate/demo/plugins/ai-plugins';\nimport { getAutoformatOptions } from '@/lib/plate/demo/plugins/autoformatOptions';\nimport { copilotPlugins } from '@/lib/plate/demo/plugins/copilot-plugins';\nimport { createPlateUI } from '@/plate/create-plate-ui';\nimport { editableProps } from '@/plate/demo/editableProps';\nimport { isEnabled } from '@/plate/demo/is-enabled';\nimport { DragOverCursorPlugin } from '@/plate/demo/plugins/DragOverCursorPlugin';\nimport { exitBreakPlugin } from '@/plate/demo/plugins/exitBreakPlugin';\nimport { resetBlockTypePlugin } from '@/plate/demo/plugins/resetBlockTypePlugin';\nimport { softBreakPlugin } from '@/plate/demo/plugins/softBreakPlugin';\nimport { tabbablePlugin } from '@/plate/demo/plugins/tabbablePlugin';\nimport { commentsData, usersData } from '@/plate/demo/values/commentsValue';\nimport { usePlaygroundValue } from '@/plate/demo/values/usePlaygroundValue';\nimport { BlockContextMenu } from '@/components/plate-ui/block-context-menu';\nimport { CommentsPopover } from '@/components/plate-ui/comments-popover';\nimport {\n CursorOverlay,\n SelectionOverlayPlugin,\n} from '@/components/plate-ui/cursor-overlay';\nimport { Editor, EditorContainer } from '@/components/plate-ui/editor';\nimport { FixedToolbar } from '@/components/plate-ui/fixed-toolbar';\nimport { FixedToolbarButtons } from '@/components/plate-ui/fixed-toolbar-buttons';\nimport { FloatingToolbar } from '@/components/plate-ui/floating-toolbar';\nimport { FloatingToolbarButtons } from '@/components/plate-ui/floating-toolbar-buttons';\nimport { ImagePreview } from '@/components/plate-ui/image-preview';\nimport {\n FireLiComponent,\n FireMarker,\n} from '@/components/plate-ui/indent-fire-marker';\nimport {\n TodoLi,\n TodoMarker,\n} from '@/components/plate-ui/indent-todo-marker';\nimport { LinkFloatingToolbar } from '@/components/plate-ui/link-floating-toolbar';\n\nimport { usePlaygroundEnabled } from './usePlaygroundEnabled';\n\nexport const usePlaygroundEditor = (id: any = '', scrollSelector?: string) => {\n const enabledPlugins = settingsStore.use.checkedPlugins();\n const overridePlugins = usePlaygroundEnabled(id);\n const autoformatOptions = getAutoformatOptions(id, enabledPlugins);\n\n const value = usePlaygroundValue(id);\n const key = settingsStore.use.version();\n const editorId = id || 'playground-' + key;\n\n return usePlateEditor(\n {\n id: editorId,\n override: {\n components: createPlateUI({\n draggable: isEnabled('dnd', id),\n placeholder: isEnabled('placeholder', id),\n }),\n plugins: overridePlugins,\n },\n plugins: [\n // AI\n ...(id === 'ai' || enabledPlugins[AIChatPlugin.key] ? aiPlugins : []),\n ...(id === 'copilot' || enabledPlugins[CopilotPlugin.key]\n ? copilotPlugins\n : []),\n // Nodes\n HeadingPlugin,\n TocPlugin.configure({\n options: {\n scrollContainerSelector: `#${scrollSelector}`,\n topOffset: 80,\n },\n }),\n BlockquotePlugin,\n CodeBlockPlugin.configure({\n options: {\n prism: Prism,\n },\n }),\n HorizontalRulePlugin,\n LinkPlugin.extend({\n render: { afterEditable: () => },\n }),\n ...(id === 'list' ? [ListPlugin] : []),\n ImagePlugin.extend({\n render: { afterEditable: ImagePreview },\n }),\n MediaEmbedPlugin,\n CaptionPlugin.configure({\n options: {\n plugins: [ImagePlugin, MediaEmbedPlugin],\n },\n }),\n DatePlugin,\n MentionPlugin.configure({\n options: {\n triggerPreviousCharPattern: /^$|^[\\s\"']$/,\n },\n }),\n SlashPlugin,\n TablePlugin.configure({\n options: {\n enableMerging: id === 'tableMerge',\n },\n }),\n ColumnPlugin,\n SelectionOverlayPlugin,\n\n TodoListPlugin,\n TogglePlugin,\n ExcalidrawPlugin,\n // Marks\n BoldPlugin,\n ItalicPlugin,\n UnderlinePlugin,\n StrikethroughPlugin,\n CodePlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n FontColorPlugin,\n FontBackgroundColorPlugin,\n FontSizePlugin,\n HighlightPlugin,\n KbdPlugin,\n\n // Block Style\n AlignPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n MediaEmbedPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n ImagePlugin.key,\n HEADING_KEYS.h6,\n ],\n },\n }),\n IndentPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n }),\n IndentListPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n options: {\n listStyleTypes: {\n fire: {\n liComponent: FireLiComponent,\n markerComponent: FireMarker,\n type: 'fire',\n },\n todo: {\n liComponent: TodoLi,\n markerComponent: TodoMarker,\n type: 'todo',\n },\n },\n },\n }),\n LineHeightPlugin.extend({\n inject: {\n nodeProps: {\n defaultNodeValue: 1.5,\n validNodeValues: [1, 1.2, 1.5, 2, 3],\n },\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n ],\n },\n }),\n\n // Functionality\n AutoformatPlugin.configure({\n options: autoformatOptions,\n }),\n BlockSelectionPlugin.configure({\n options: {\n areaOptions: {\n behaviour: {\n scrolling: {\n speedDivider: 1.5,\n },\n startThreshold: 10,\n },\n boundaries: `#${scrollSelector}`,\n container: `#${scrollSelector}`,\n selectables: [`#${scrollSelector} .slate-selectable`],\n selectionAreaClass: 'slate-selection-area',\n },\n enableContextMenu: true,\n },\n }),\n BlockMenuPlugin.configure({\n render: { aboveEditable: BlockContextMenu },\n }),\n DndPlugin.configure({ options: { enableScroller: true } }),\n EmojiPlugin,\n exitBreakPlugin,\n NodeIdPlugin,\n NormalizeTypesPlugin.configure({\n options: {\n rules: [{ path: [0], strictType: HEADING_KEYS.h1 }],\n },\n }),\n resetBlockTypePlugin,\n SelectOnBackspacePlugin.configure({\n options: {\n query: {\n allow: [ImagePlugin.key, HorizontalRulePlugin.key],\n },\n },\n }),\n DeletePlugin,\n SingleLinePlugin,\n softBreakPlugin,\n tabbablePlugin,\n TrailingBlockPlugin.configure({\n options: { type: ParagraphPlugin.key },\n }),\n DragOverCursorPlugin,\n\n // Collaboration\n CommentsPlugin.configure({\n options: {\n comments: commentsData,\n myUserId: '1',\n users: usersData,\n },\n }),\n\n // Deserialization\n DocxPlugin,\n MarkdownPlugin.configure({ options: { indentList: true } }),\n JuicePlugin,\n\n // Testing\n PlaywrightPlugin.configure({\n enabled: process.env.NODE_ENV !== 'production',\n }),\n ],\n value: value,\n },\n []\n );\n};\n\nexport default function PlaygroundDemo({\n id,\n className,\n scrollSelector,\n}: {\n id?: ValueId;\n className?: string;\n scrollSelector?: string;\n}) {\n const containerRef = useRef(null);\n const enabled = settingsStore.use.checkedComponents();\n\n const editor = usePlaygroundEditor(\n id,\n scrollSelector ?? `blockSelection-${id}`\n );\n\n return (\n \n \n \n \n \n \n \n \n \n\n
\n \n \n\n \n \n \n \n \n \n \n\n \n \n \n \n\n \n \n \n
\n
\n
\n );\n}\n\nconst DemoIdContext = React.createContext(undefined);\n\nexport function DemoId({\n id,\n children,\n}: {\n children: React.ReactNode;\n id?: string;\n}) {\n return {children};\n}\n\nexport function useDemoId() {\n return React.useContext(DemoIdContext);\n}\n", + "content": "'use client';\n\nimport React, { useRef } from 'react';\n\nimport type { ValueId } from '@/config/customizer-plugins';\n\nimport { cn } from '@udecode/cn';\nimport { AIChatPlugin, CopilotPlugin } from '@udecode/plate-ai/react';\nimport { AlignPlugin } from '@udecode/plate-alignment/react';\nimport { AutoformatPlugin } from '@udecode/plate-autoformat/react';\nimport {\n BoldPlugin,\n CodePlugin,\n ItalicPlugin,\n StrikethroughPlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n UnderlinePlugin,\n} from '@udecode/plate-basic-marks/react';\nimport { BlockquotePlugin } from '@udecode/plate-block-quote/react';\nimport { SingleLinePlugin } from '@udecode/plate-break/react';\nimport { CaptionPlugin } from '@udecode/plate-caption/react';\nimport { CodeBlockPlugin } from '@udecode/plate-code-block/react';\nimport { CommentsPlugin } from '@udecode/plate-comments/react';\nimport {\n ParagraphPlugin,\n Plate,\n usePlateEditor,\n} from '@udecode/plate-common/react';\nimport { DatePlugin } from '@udecode/plate-date/react';\nimport { DndPlugin } from '@udecode/plate-dnd';\nimport { DocxPlugin } from '@udecode/plate-docx';\nimport { EmojiPlugin } from '@udecode/plate-emoji/react';\nimport { ExcalidrawPlugin } from '@udecode/plate-excalidraw/react';\nimport {\n FontBackgroundColorPlugin,\n FontColorPlugin,\n FontSizePlugin,\n} from '@udecode/plate-font/react';\nimport { HEADING_KEYS } from '@udecode/plate-heading';\nimport { HeadingPlugin, TocPlugin } from '@udecode/plate-heading/react';\nimport { HighlightPlugin } from '@udecode/plate-highlight/react';\nimport { HorizontalRulePlugin } from '@udecode/plate-horizontal-rule/react';\nimport { IndentPlugin } from '@udecode/plate-indent/react';\nimport { IndentListPlugin } from '@udecode/plate-indent-list/react';\nimport { JuicePlugin } from '@udecode/plate-juice';\nimport { KbdPlugin } from '@udecode/plate-kbd/react';\nimport { ColumnPlugin } from '@udecode/plate-layout/react';\nimport { LineHeightPlugin } from '@udecode/plate-line-height/react';\nimport { LinkPlugin } from '@udecode/plate-link/react';\nimport { ListPlugin, TodoListPlugin } from '@udecode/plate-list/react';\nimport { MarkdownPlugin } from '@udecode/plate-markdown';\nimport { ImagePlugin, MediaEmbedPlugin } from '@udecode/plate-media/react';\nimport { MentionPlugin } from '@udecode/plate-mention/react';\nimport { NodeIdPlugin } from '@udecode/plate-node-id';\nimport { NormalizeTypesPlugin } from '@udecode/plate-normalizers';\nimport { PlaywrightPlugin } from '@udecode/plate-playwright';\nimport { DeletePlugin, SelectOnBackspacePlugin } from '@udecode/plate-select';\nimport {\n BlockMenuPlugin,\n BlockSelectionPlugin,\n} from '@udecode/plate-selection/react';\nimport { SlashPlugin } from '@udecode/plate-slash-command/react';\nimport { TablePlugin } from '@udecode/plate-table/react';\nimport { TogglePlugin } from '@udecode/plate-toggle/react';\nimport { TrailingBlockPlugin } from '@udecode/plate-trailing-block';\nimport Prism from 'prismjs';\n\nimport { CheckPlugin } from '@/components/context/check-plugin';\nimport { settingsStore } from '@/components/context/settings-store';\nimport { aiPlugins } from '@/lib/plate/demo/plugins/ai-plugins';\nimport { getAutoformatOptions } from '@/lib/plate/demo/plugins/autoformatOptions';\nimport { copilotPlugins } from '@/lib/plate/demo/plugins/copilot-plugins';\nimport { createPlateUI } from '@/plate/create-plate-ui';\nimport { editableProps } from '@/plate/demo/editableProps';\nimport { isEnabled } from '@/plate/demo/is-enabled';\nimport { DragOverCursorPlugin } from '@/plate/demo/plugins/DragOverCursorPlugin';\nimport { exitBreakPlugin } from '@/plate/demo/plugins/exitBreakPlugin';\nimport { resetBlockTypePlugin } from '@/plate/demo/plugins/resetBlockTypePlugin';\nimport { softBreakPlugin } from '@/plate/demo/plugins/softBreakPlugin';\nimport { tabbablePlugin } from '@/plate/demo/plugins/tabbablePlugin';\nimport { commentsData, usersData } from '@/plate/demo/values/commentsValue';\nimport { usePlaygroundValue } from '@/plate/demo/values/usePlaygroundValue';\nimport { BlockContextMenu } from '@/components/plate-ui/block-context-menu';\nimport { CommentsPopover } from '@/components/plate-ui/comments-popover';\nimport {\n CursorOverlay,\n SelectionOverlayPlugin,\n} from '@/components/plate-ui/cursor-overlay';\nimport { Editor, EditorContainer } from '@/components/plate-ui/editor';\nimport { FixedToolbar } from '@/components/plate-ui/fixed-toolbar';\nimport { FixedToolbarButtons } from '@/components/plate-ui/fixed-toolbar-buttons';\nimport { FloatingToolbar } from '@/components/plate-ui/floating-toolbar';\nimport { FloatingToolbarButtons } from '@/components/plate-ui/floating-toolbar-buttons';\nimport { ImagePreview } from '@/components/plate-ui/image-preview';\nimport {\n FireLiComponent,\n FireMarker,\n} from '@/components/plate-ui/indent-fire-marker';\nimport {\n TodoLi,\n TodoMarker,\n} from '@/components/plate-ui/indent-todo-marker';\nimport { LinkFloatingToolbar } from '@/components/plate-ui/link-floating-toolbar';\n\nimport { usePlaygroundEnabled } from './usePlaygroundEnabled';\n\nexport const usePlaygroundEditor = (id: any = '', scrollSelector?: string) => {\n const enabledPlugins = settingsStore.use.checkedPlugins();\n const overridePlugins = usePlaygroundEnabled(id);\n const autoformatOptions = getAutoformatOptions(id, enabledPlugins);\n\n const value = usePlaygroundValue(id);\n const key = settingsStore.use.version();\n const editorId = id || 'playground-' + key;\n\n return usePlateEditor(\n {\n id: editorId,\n override: {\n components: createPlateUI({\n draggable: isEnabled('dnd', id),\n placeholder: isEnabled('placeholder', id),\n }),\n plugins: overridePlugins,\n },\n plugins: [\n // AI\n ...(id === 'ai' || enabledPlugins[AIChatPlugin.key] ? aiPlugins : []),\n ...(id === 'copilot' || enabledPlugins[CopilotPlugin.key]\n ? copilotPlugins\n : []),\n // Nodes\n HeadingPlugin,\n TocPlugin.configure({\n options: {\n scrollContainerSelector: `#${scrollSelector}`,\n topOffset: 80,\n },\n }),\n BlockquotePlugin,\n CodeBlockPlugin.configure({\n options: {\n prism: Prism,\n },\n }),\n HorizontalRulePlugin,\n LinkPlugin.extend({\n render: { afterEditable: () => },\n }),\n ...(id === 'list' ? [ListPlugin] : []),\n ImagePlugin.extend({\n options: {\n disableUploadInsert: true,\n },\n render: { afterEditable: ImagePreview },\n }),\n MediaEmbedPlugin,\n CaptionPlugin.configure({\n options: {\n plugins: [ImagePlugin, MediaEmbedPlugin],\n },\n }),\n DatePlugin,\n MentionPlugin.configure({\n options: {\n triggerPreviousCharPattern: /^$|^[\\s\"']$/,\n },\n }),\n SlashPlugin,\n TablePlugin.configure({\n options: {\n enableMerging: id === 'tableMerge',\n },\n }),\n ColumnPlugin,\n SelectionOverlayPlugin,\n\n TodoListPlugin,\n TogglePlugin,\n ExcalidrawPlugin,\n // Marks\n BoldPlugin,\n ItalicPlugin,\n UnderlinePlugin,\n StrikethroughPlugin,\n CodePlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n FontColorPlugin,\n FontBackgroundColorPlugin,\n FontSizePlugin,\n HighlightPlugin,\n KbdPlugin,\n\n // Block Style\n AlignPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n MediaEmbedPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n ImagePlugin.key,\n HEADING_KEYS.h6,\n ],\n },\n }),\n IndentPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n }),\n IndentListPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n options: {\n listStyleTypes: {\n fire: {\n liComponent: FireLiComponent,\n markerComponent: FireMarker,\n type: 'fire',\n },\n todo: {\n liComponent: TodoLi,\n markerComponent: TodoMarker,\n type: 'todo',\n },\n },\n },\n }),\n LineHeightPlugin.extend({\n inject: {\n nodeProps: {\n defaultNodeValue: 1.5,\n validNodeValues: [1, 1.2, 1.5, 2, 3],\n },\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n ],\n },\n }),\n\n // Functionality\n AutoformatPlugin.configure({\n options: autoformatOptions,\n }),\n BlockSelectionPlugin.configure({\n options: {\n areaOptions: {\n behaviour: {\n scrolling: {\n speedDivider: 1.5,\n },\n startThreshold: 10,\n },\n boundaries: `#${scrollSelector}`,\n container: `#${scrollSelector}`,\n selectables: [`#${scrollSelector} .slate-selectable`],\n selectionAreaClass: 'slate-selection-area',\n },\n enableContextMenu: true,\n },\n }),\n BlockMenuPlugin.configure({\n render: { aboveEditable: BlockContextMenu },\n }),\n DndPlugin.configure({\n options: {\n enableScroller: true,\n onDropFiles: ({ dragItem, editor, target }) => {\n editor\n .getTransforms(ImagePlugin)\n .insertImageFromFiles(dragItem.files, {\n at: target,\n nextBlock: false,\n });\n },\n },\n }),\n EmojiPlugin,\n exitBreakPlugin,\n NodeIdPlugin,\n NormalizeTypesPlugin.configure({\n options: {\n rules: [{ path: [0], strictType: HEADING_KEYS.h1 }],\n },\n }),\n resetBlockTypePlugin,\n SelectOnBackspacePlugin.configure({\n options: {\n query: {\n allow: [ImagePlugin.key, HorizontalRulePlugin.key],\n },\n },\n }),\n DeletePlugin,\n SingleLinePlugin,\n softBreakPlugin,\n tabbablePlugin,\n TrailingBlockPlugin.configure({\n options: { type: ParagraphPlugin.key },\n }),\n DragOverCursorPlugin,\n\n // Collaboration\n CommentsPlugin.configure({\n options: {\n comments: commentsData,\n myUserId: '1',\n users: usersData,\n },\n }),\n\n // Deserialization\n DocxPlugin,\n MarkdownPlugin.configure({ options: { indentList: true } }),\n JuicePlugin,\n\n // Testing\n PlaywrightPlugin.configure({\n enabled: process.env.NODE_ENV !== 'production',\n }),\n ],\n value: value,\n },\n []\n );\n};\n\nexport default function PlaygroundDemo({\n id,\n className,\n scrollSelector,\n}: {\n id?: ValueId;\n className?: string;\n scrollSelector?: string;\n}) {\n const containerRef = useRef(null);\n const enabled = settingsStore.use.checkedComponents();\n\n const editor = usePlaygroundEditor(\n id,\n scrollSelector ?? `blockSelection-${id}`\n );\n\n return (\n \n \n \n \n \n \n \n \n \n\n
\n \n \n\n \n \n \n \n \n \n \n\n \n \n \n \n\n \n \n \n
\n
\n
\n );\n}\n\nconst DemoIdContext = React.createContext(undefined);\n\nexport function DemoId({\n id,\n children,\n}: {\n children: React.ReactNode;\n id?: string;\n}) {\n return {children};\n}\n\nexport function useDemoId() {\n return React.useContext(DemoIdContext);\n}\n", "path": "example/playground-demo.tsx", "target": "components/playground-demo.tsx", "type": "registry:example" diff --git a/apps/www/public/r/styles/default/basic-marks-demo.json b/apps/www/public/r/styles/default/basic-marks-demo.json index 207926d3f7..a5b58cd2c0 100644 --- a/apps/www/public/r/styles/default/basic-marks-demo.json +++ b/apps/www/public/r/styles/default/basic-marks-demo.json @@ -4,7 +4,7 @@ }, "files": [ { - "content": "'use client';\n\nimport React, { useRef } from 'react';\n\nimport type { ValueId } from '@/config/customizer-plugins';\n\nimport { cn } from '@udecode/cn';\nimport { AIChatPlugin, CopilotPlugin } from '@udecode/plate-ai/react';\nimport { AlignPlugin } from '@udecode/plate-alignment/react';\nimport { AutoformatPlugin } from '@udecode/plate-autoformat/react';\nimport {\n BoldPlugin,\n CodePlugin,\n ItalicPlugin,\n StrikethroughPlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n UnderlinePlugin,\n} from '@udecode/plate-basic-marks/react';\nimport { BlockquotePlugin } from '@udecode/plate-block-quote/react';\nimport { SingleLinePlugin } from '@udecode/plate-break/react';\nimport { CaptionPlugin } from '@udecode/plate-caption/react';\nimport { CodeBlockPlugin } from '@udecode/plate-code-block/react';\nimport { CommentsPlugin } from '@udecode/plate-comments/react';\nimport {\n ParagraphPlugin,\n Plate,\n usePlateEditor,\n} from '@udecode/plate-common/react';\nimport { DatePlugin } from '@udecode/plate-date/react';\nimport { DndPlugin } from '@udecode/plate-dnd';\nimport { DocxPlugin } from '@udecode/plate-docx';\nimport { EmojiPlugin } from '@udecode/plate-emoji/react';\nimport { ExcalidrawPlugin } from '@udecode/plate-excalidraw/react';\nimport {\n FontBackgroundColorPlugin,\n FontColorPlugin,\n FontSizePlugin,\n} from '@udecode/plate-font/react';\nimport { HEADING_KEYS } from '@udecode/plate-heading';\nimport { HeadingPlugin, TocPlugin } from '@udecode/plate-heading/react';\nimport { HighlightPlugin } from '@udecode/plate-highlight/react';\nimport { HorizontalRulePlugin } from '@udecode/plate-horizontal-rule/react';\nimport { IndentPlugin } from '@udecode/plate-indent/react';\nimport { IndentListPlugin } from '@udecode/plate-indent-list/react';\nimport { JuicePlugin } from '@udecode/plate-juice';\nimport { KbdPlugin } from '@udecode/plate-kbd/react';\nimport { ColumnPlugin } from '@udecode/plate-layout/react';\nimport { LineHeightPlugin } from '@udecode/plate-line-height/react';\nimport { LinkPlugin } from '@udecode/plate-link/react';\nimport { ListPlugin, TodoListPlugin } from '@udecode/plate-list/react';\nimport { MarkdownPlugin } from '@udecode/plate-markdown';\nimport { ImagePlugin, MediaEmbedPlugin } from '@udecode/plate-media/react';\nimport { MentionPlugin } from '@udecode/plate-mention/react';\nimport { NodeIdPlugin } from '@udecode/plate-node-id';\nimport { NormalizeTypesPlugin } from '@udecode/plate-normalizers';\nimport { PlaywrightPlugin } from '@udecode/plate-playwright';\nimport { DeletePlugin, SelectOnBackspacePlugin } from '@udecode/plate-select';\nimport {\n BlockMenuPlugin,\n BlockSelectionPlugin,\n} from '@udecode/plate-selection/react';\nimport { SlashPlugin } from '@udecode/plate-slash-command/react';\nimport { TablePlugin } from '@udecode/plate-table/react';\nimport { TogglePlugin } from '@udecode/plate-toggle/react';\nimport { TrailingBlockPlugin } from '@udecode/plate-trailing-block';\nimport Prism from 'prismjs';\n\nimport { CheckPlugin } from '@/components/context/check-plugin';\nimport { settingsStore } from '@/components/context/settings-store';\nimport { aiPlugins } from '@/lib/plate/demo/plugins/ai-plugins';\nimport { getAutoformatOptions } from '@/lib/plate/demo/plugins/autoformatOptions';\nimport { copilotPlugins } from '@/lib/plate/demo/plugins/copilot-plugins';\nimport { createPlateUI } from '@/plate/create-plate-ui';\nimport { editableProps } from '@/plate/demo/editableProps';\nimport { isEnabled } from '@/plate/demo/is-enabled';\nimport { DragOverCursorPlugin } from '@/plate/demo/plugins/DragOverCursorPlugin';\nimport { exitBreakPlugin } from '@/plate/demo/plugins/exitBreakPlugin';\nimport { resetBlockTypePlugin } from '@/plate/demo/plugins/resetBlockTypePlugin';\nimport { softBreakPlugin } from '@/plate/demo/plugins/softBreakPlugin';\nimport { tabbablePlugin } from '@/plate/demo/plugins/tabbablePlugin';\nimport { commentsData, usersData } from '@/plate/demo/values/commentsValue';\nimport { usePlaygroundValue } from '@/plate/demo/values/usePlaygroundValue';\nimport { BlockContextMenu } from '@/components/plate-ui/block-context-menu';\nimport { CommentsPopover } from '@/components/plate-ui/comments-popover';\nimport {\n CursorOverlay,\n SelectionOverlayPlugin,\n} from '@/components/plate-ui/cursor-overlay';\nimport { Editor, EditorContainer } from '@/components/plate-ui/editor';\nimport { FixedToolbar } from '@/components/plate-ui/fixed-toolbar';\nimport { FixedToolbarButtons } from '@/components/plate-ui/fixed-toolbar-buttons';\nimport { FloatingToolbar } from '@/components/plate-ui/floating-toolbar';\nimport { FloatingToolbarButtons } from '@/components/plate-ui/floating-toolbar-buttons';\nimport { ImagePreview } from '@/components/plate-ui/image-preview';\nimport {\n FireLiComponent,\n FireMarker,\n} from '@/components/plate-ui/indent-fire-marker';\nimport {\n TodoLi,\n TodoMarker,\n} from '@/components/plate-ui/indent-todo-marker';\nimport { LinkFloatingToolbar } from '@/components/plate-ui/link-floating-toolbar';\n\nimport { usePlaygroundEnabled } from './usePlaygroundEnabled';\n\nexport const usePlaygroundEditor = (id: any = '', scrollSelector?: string) => {\n const enabledPlugins = settingsStore.use.checkedPlugins();\n const overridePlugins = usePlaygroundEnabled(id);\n const autoformatOptions = getAutoformatOptions(id, enabledPlugins);\n\n const value = usePlaygroundValue(id);\n const key = settingsStore.use.version();\n const editorId = id || 'playground-' + key;\n\n return usePlateEditor(\n {\n id: editorId,\n override: {\n components: createPlateUI({\n draggable: isEnabled('dnd', id),\n placeholder: isEnabled('placeholder', id),\n }),\n plugins: overridePlugins,\n },\n plugins: [\n // AI\n ...(id === 'ai' || enabledPlugins[AIChatPlugin.key] ? aiPlugins : []),\n ...(id === 'copilot' || enabledPlugins[CopilotPlugin.key]\n ? copilotPlugins\n : []),\n // Nodes\n HeadingPlugin,\n TocPlugin.configure({\n options: {\n scrollContainerSelector: `#${scrollSelector}`,\n topOffset: 80,\n },\n }),\n BlockquotePlugin,\n CodeBlockPlugin.configure({\n options: {\n prism: Prism,\n },\n }),\n HorizontalRulePlugin,\n LinkPlugin.extend({\n render: { afterEditable: () => },\n }),\n ...(id === 'list' ? [ListPlugin] : []),\n ImagePlugin.extend({\n render: { afterEditable: ImagePreview },\n }),\n MediaEmbedPlugin,\n CaptionPlugin.configure({\n options: {\n plugins: [ImagePlugin, MediaEmbedPlugin],\n },\n }),\n DatePlugin,\n MentionPlugin.configure({\n options: {\n triggerPreviousCharPattern: /^$|^[\\s\"']$/,\n },\n }),\n SlashPlugin,\n TablePlugin.configure({\n options: {\n enableMerging: id === 'tableMerge',\n },\n }),\n ColumnPlugin,\n SelectionOverlayPlugin,\n\n TodoListPlugin,\n TogglePlugin,\n ExcalidrawPlugin,\n // Marks\n BoldPlugin,\n ItalicPlugin,\n UnderlinePlugin,\n StrikethroughPlugin,\n CodePlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n FontColorPlugin,\n FontBackgroundColorPlugin,\n FontSizePlugin,\n HighlightPlugin,\n KbdPlugin,\n\n // Block Style\n AlignPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n MediaEmbedPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n ImagePlugin.key,\n HEADING_KEYS.h6,\n ],\n },\n }),\n IndentPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n }),\n IndentListPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n options: {\n listStyleTypes: {\n fire: {\n liComponent: FireLiComponent,\n markerComponent: FireMarker,\n type: 'fire',\n },\n todo: {\n liComponent: TodoLi,\n markerComponent: TodoMarker,\n type: 'todo',\n },\n },\n },\n }),\n LineHeightPlugin.extend({\n inject: {\n nodeProps: {\n defaultNodeValue: 1.5,\n validNodeValues: [1, 1.2, 1.5, 2, 3],\n },\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n ],\n },\n }),\n\n // Functionality\n AutoformatPlugin.configure({\n options: autoformatOptions,\n }),\n BlockSelectionPlugin.configure({\n options: {\n areaOptions: {\n behaviour: {\n scrolling: {\n speedDivider: 1.5,\n },\n startThreshold: 10,\n },\n boundaries: `#${scrollSelector}`,\n container: `#${scrollSelector}`,\n selectables: [`#${scrollSelector} .slate-selectable`],\n selectionAreaClass: 'slate-selection-area',\n },\n enableContextMenu: true,\n },\n }),\n BlockMenuPlugin.configure({\n render: { aboveEditable: BlockContextMenu },\n }),\n DndPlugin.configure({ options: { enableScroller: true } }),\n EmojiPlugin,\n exitBreakPlugin,\n NodeIdPlugin,\n NormalizeTypesPlugin.configure({\n options: {\n rules: [{ path: [0], strictType: HEADING_KEYS.h1 }],\n },\n }),\n resetBlockTypePlugin,\n SelectOnBackspacePlugin.configure({\n options: {\n query: {\n allow: [ImagePlugin.key, HorizontalRulePlugin.key],\n },\n },\n }),\n DeletePlugin,\n SingleLinePlugin,\n softBreakPlugin,\n tabbablePlugin,\n TrailingBlockPlugin.configure({\n options: { type: ParagraphPlugin.key },\n }),\n DragOverCursorPlugin,\n\n // Collaboration\n CommentsPlugin.configure({\n options: {\n comments: commentsData,\n myUserId: '1',\n users: usersData,\n },\n }),\n\n // Deserialization\n DocxPlugin,\n MarkdownPlugin.configure({ options: { indentList: true } }),\n JuicePlugin,\n\n // Testing\n PlaywrightPlugin.configure({\n enabled: process.env.NODE_ENV !== 'production',\n }),\n ],\n value: value,\n },\n []\n );\n};\n\nexport default function PlaygroundDemo({\n id,\n className,\n scrollSelector,\n}: {\n id?: ValueId;\n className?: string;\n scrollSelector?: string;\n}) {\n const containerRef = useRef(null);\n const enabled = settingsStore.use.checkedComponents();\n\n const editor = usePlaygroundEditor(\n id,\n scrollSelector ?? `blockSelection-${id}`\n );\n\n return (\n \n \n \n \n \n \n \n \n \n\n
\n \n \n\n \n \n \n \n \n \n \n\n \n \n \n \n\n \n \n \n
\n
\n
\n );\n}\n\nconst DemoIdContext = React.createContext(undefined);\n\nexport function DemoId({\n id,\n children,\n}: {\n children: React.ReactNode;\n id?: string;\n}) {\n return {children};\n}\n\nexport function useDemoId() {\n return React.useContext(DemoIdContext);\n}\n", + "content": "'use client';\n\nimport React, { useRef } from 'react';\n\nimport type { ValueId } from '@/config/customizer-plugins';\n\nimport { cn } from '@udecode/cn';\nimport { AIChatPlugin, CopilotPlugin } from '@udecode/plate-ai/react';\nimport { AlignPlugin } from '@udecode/plate-alignment/react';\nimport { AutoformatPlugin } from '@udecode/plate-autoformat/react';\nimport {\n BoldPlugin,\n CodePlugin,\n ItalicPlugin,\n StrikethroughPlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n UnderlinePlugin,\n} from '@udecode/plate-basic-marks/react';\nimport { BlockquotePlugin } from '@udecode/plate-block-quote/react';\nimport { SingleLinePlugin } from '@udecode/plate-break/react';\nimport { CaptionPlugin } from '@udecode/plate-caption/react';\nimport { CodeBlockPlugin } from '@udecode/plate-code-block/react';\nimport { CommentsPlugin } from '@udecode/plate-comments/react';\nimport {\n ParagraphPlugin,\n Plate,\n usePlateEditor,\n} from '@udecode/plate-common/react';\nimport { DatePlugin } from '@udecode/plate-date/react';\nimport { DndPlugin } from '@udecode/plate-dnd';\nimport { DocxPlugin } from '@udecode/plate-docx';\nimport { EmojiPlugin } from '@udecode/plate-emoji/react';\nimport { ExcalidrawPlugin } from '@udecode/plate-excalidraw/react';\nimport {\n FontBackgroundColorPlugin,\n FontColorPlugin,\n FontSizePlugin,\n} from '@udecode/plate-font/react';\nimport { HEADING_KEYS } from '@udecode/plate-heading';\nimport { HeadingPlugin, TocPlugin } from '@udecode/plate-heading/react';\nimport { HighlightPlugin } from '@udecode/plate-highlight/react';\nimport { HorizontalRulePlugin } from '@udecode/plate-horizontal-rule/react';\nimport { IndentPlugin } from '@udecode/plate-indent/react';\nimport { IndentListPlugin } from '@udecode/plate-indent-list/react';\nimport { JuicePlugin } from '@udecode/plate-juice';\nimport { KbdPlugin } from '@udecode/plate-kbd/react';\nimport { ColumnPlugin } from '@udecode/plate-layout/react';\nimport { LineHeightPlugin } from '@udecode/plate-line-height/react';\nimport { LinkPlugin } from '@udecode/plate-link/react';\nimport { ListPlugin, TodoListPlugin } from '@udecode/plate-list/react';\nimport { MarkdownPlugin } from '@udecode/plate-markdown';\nimport { ImagePlugin, MediaEmbedPlugin } from '@udecode/plate-media/react';\nimport { MentionPlugin } from '@udecode/plate-mention/react';\nimport { NodeIdPlugin } from '@udecode/plate-node-id';\nimport { NormalizeTypesPlugin } from '@udecode/plate-normalizers';\nimport { PlaywrightPlugin } from '@udecode/plate-playwright';\nimport { DeletePlugin, SelectOnBackspacePlugin } from '@udecode/plate-select';\nimport {\n BlockMenuPlugin,\n BlockSelectionPlugin,\n} from '@udecode/plate-selection/react';\nimport { SlashPlugin } from '@udecode/plate-slash-command/react';\nimport { TablePlugin } from '@udecode/plate-table/react';\nimport { TogglePlugin } from '@udecode/plate-toggle/react';\nimport { TrailingBlockPlugin } from '@udecode/plate-trailing-block';\nimport Prism from 'prismjs';\n\nimport { CheckPlugin } from '@/components/context/check-plugin';\nimport { settingsStore } from '@/components/context/settings-store';\nimport { aiPlugins } from '@/lib/plate/demo/plugins/ai-plugins';\nimport { getAutoformatOptions } from '@/lib/plate/demo/plugins/autoformatOptions';\nimport { copilotPlugins } from '@/lib/plate/demo/plugins/copilot-plugins';\nimport { createPlateUI } from '@/plate/create-plate-ui';\nimport { editableProps } from '@/plate/demo/editableProps';\nimport { isEnabled } from '@/plate/demo/is-enabled';\nimport { DragOverCursorPlugin } from '@/plate/demo/plugins/DragOverCursorPlugin';\nimport { exitBreakPlugin } from '@/plate/demo/plugins/exitBreakPlugin';\nimport { resetBlockTypePlugin } from '@/plate/demo/plugins/resetBlockTypePlugin';\nimport { softBreakPlugin } from '@/plate/demo/plugins/softBreakPlugin';\nimport { tabbablePlugin } from '@/plate/demo/plugins/tabbablePlugin';\nimport { commentsData, usersData } from '@/plate/demo/values/commentsValue';\nimport { usePlaygroundValue } from '@/plate/demo/values/usePlaygroundValue';\nimport { BlockContextMenu } from '@/components/plate-ui/block-context-menu';\nimport { CommentsPopover } from '@/components/plate-ui/comments-popover';\nimport {\n CursorOverlay,\n SelectionOverlayPlugin,\n} from '@/components/plate-ui/cursor-overlay';\nimport { Editor, EditorContainer } from '@/components/plate-ui/editor';\nimport { FixedToolbar } from '@/components/plate-ui/fixed-toolbar';\nimport { FixedToolbarButtons } from '@/components/plate-ui/fixed-toolbar-buttons';\nimport { FloatingToolbar } from '@/components/plate-ui/floating-toolbar';\nimport { FloatingToolbarButtons } from '@/components/plate-ui/floating-toolbar-buttons';\nimport { ImagePreview } from '@/components/plate-ui/image-preview';\nimport {\n FireLiComponent,\n FireMarker,\n} from '@/components/plate-ui/indent-fire-marker';\nimport {\n TodoLi,\n TodoMarker,\n} from '@/components/plate-ui/indent-todo-marker';\nimport { LinkFloatingToolbar } from '@/components/plate-ui/link-floating-toolbar';\n\nimport { usePlaygroundEnabled } from './usePlaygroundEnabled';\n\nexport const usePlaygroundEditor = (id: any = '', scrollSelector?: string) => {\n const enabledPlugins = settingsStore.use.checkedPlugins();\n const overridePlugins = usePlaygroundEnabled(id);\n const autoformatOptions = getAutoformatOptions(id, enabledPlugins);\n\n const value = usePlaygroundValue(id);\n const key = settingsStore.use.version();\n const editorId = id || 'playground-' + key;\n\n return usePlateEditor(\n {\n id: editorId,\n override: {\n components: createPlateUI({\n draggable: isEnabled('dnd', id),\n placeholder: isEnabled('placeholder', id),\n }),\n plugins: overridePlugins,\n },\n plugins: [\n // AI\n ...(id === 'ai' || enabledPlugins[AIChatPlugin.key] ? aiPlugins : []),\n ...(id === 'copilot' || enabledPlugins[CopilotPlugin.key]\n ? copilotPlugins\n : []),\n // Nodes\n HeadingPlugin,\n TocPlugin.configure({\n options: {\n scrollContainerSelector: `#${scrollSelector}`,\n topOffset: 80,\n },\n }),\n BlockquotePlugin,\n CodeBlockPlugin.configure({\n options: {\n prism: Prism,\n },\n }),\n HorizontalRulePlugin,\n LinkPlugin.extend({\n render: { afterEditable: () => },\n }),\n ...(id === 'list' ? [ListPlugin] : []),\n ImagePlugin.extend({\n options: {\n disableUploadInsert: true,\n },\n render: { afterEditable: ImagePreview },\n }),\n MediaEmbedPlugin,\n CaptionPlugin.configure({\n options: {\n plugins: [ImagePlugin, MediaEmbedPlugin],\n },\n }),\n DatePlugin,\n MentionPlugin.configure({\n options: {\n triggerPreviousCharPattern: /^$|^[\\s\"']$/,\n },\n }),\n SlashPlugin,\n TablePlugin.configure({\n options: {\n enableMerging: id === 'tableMerge',\n },\n }),\n ColumnPlugin,\n SelectionOverlayPlugin,\n\n TodoListPlugin,\n TogglePlugin,\n ExcalidrawPlugin,\n // Marks\n BoldPlugin,\n ItalicPlugin,\n UnderlinePlugin,\n StrikethroughPlugin,\n CodePlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n FontColorPlugin,\n FontBackgroundColorPlugin,\n FontSizePlugin,\n HighlightPlugin,\n KbdPlugin,\n\n // Block Style\n AlignPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n MediaEmbedPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n ImagePlugin.key,\n HEADING_KEYS.h6,\n ],\n },\n }),\n IndentPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n }),\n IndentListPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n options: {\n listStyleTypes: {\n fire: {\n liComponent: FireLiComponent,\n markerComponent: FireMarker,\n type: 'fire',\n },\n todo: {\n liComponent: TodoLi,\n markerComponent: TodoMarker,\n type: 'todo',\n },\n },\n },\n }),\n LineHeightPlugin.extend({\n inject: {\n nodeProps: {\n defaultNodeValue: 1.5,\n validNodeValues: [1, 1.2, 1.5, 2, 3],\n },\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n ],\n },\n }),\n\n // Functionality\n AutoformatPlugin.configure({\n options: autoformatOptions,\n }),\n BlockSelectionPlugin.configure({\n options: {\n areaOptions: {\n behaviour: {\n scrolling: {\n speedDivider: 1.5,\n },\n startThreshold: 10,\n },\n boundaries: `#${scrollSelector}`,\n container: `#${scrollSelector}`,\n selectables: [`#${scrollSelector} .slate-selectable`],\n selectionAreaClass: 'slate-selection-area',\n },\n enableContextMenu: true,\n },\n }),\n BlockMenuPlugin.configure({\n render: { aboveEditable: BlockContextMenu },\n }),\n DndPlugin.configure({\n options: {\n enableScroller: true,\n onDropFiles: ({ dragItem, editor, target }) => {\n editor\n .getTransforms(ImagePlugin)\n .insertImageFromFiles(dragItem.files, {\n at: target,\n nextBlock: false,\n });\n },\n },\n }),\n EmojiPlugin,\n exitBreakPlugin,\n NodeIdPlugin,\n NormalizeTypesPlugin.configure({\n options: {\n rules: [{ path: [0], strictType: HEADING_KEYS.h1 }],\n },\n }),\n resetBlockTypePlugin,\n SelectOnBackspacePlugin.configure({\n options: {\n query: {\n allow: [ImagePlugin.key, HorizontalRulePlugin.key],\n },\n },\n }),\n DeletePlugin,\n SingleLinePlugin,\n softBreakPlugin,\n tabbablePlugin,\n TrailingBlockPlugin.configure({\n options: { type: ParagraphPlugin.key },\n }),\n DragOverCursorPlugin,\n\n // Collaboration\n CommentsPlugin.configure({\n options: {\n comments: commentsData,\n myUserId: '1',\n users: usersData,\n },\n }),\n\n // Deserialization\n DocxPlugin,\n MarkdownPlugin.configure({ options: { indentList: true } }),\n JuicePlugin,\n\n // Testing\n PlaywrightPlugin.configure({\n enabled: process.env.NODE_ENV !== 'production',\n }),\n ],\n value: value,\n },\n []\n );\n};\n\nexport default function PlaygroundDemo({\n id,\n className,\n scrollSelector,\n}: {\n id?: ValueId;\n className?: string;\n scrollSelector?: string;\n}) {\n const containerRef = useRef(null);\n const enabled = settingsStore.use.checkedComponents();\n\n const editor = usePlaygroundEditor(\n id,\n scrollSelector ?? `blockSelection-${id}`\n );\n\n return (\n \n \n \n \n \n \n \n \n \n\n
\n \n \n\n \n \n \n \n \n \n \n\n \n \n \n \n\n \n \n \n
\n
\n
\n );\n}\n\nconst DemoIdContext = React.createContext(undefined);\n\nexport function DemoId({\n id,\n children,\n}: {\n children: React.ReactNode;\n id?: string;\n}) {\n return {children};\n}\n\nexport function useDemoId() {\n return React.useContext(DemoIdContext);\n}\n", "path": "example/playground-demo.tsx", "target": "components/playground-demo.tsx", "type": "registry:example" diff --git a/apps/www/public/r/styles/default/basic-nodes-demo.json b/apps/www/public/r/styles/default/basic-nodes-demo.json index a0f3490f12..191775580c 100644 --- a/apps/www/public/r/styles/default/basic-nodes-demo.json +++ b/apps/www/public/r/styles/default/basic-nodes-demo.json @@ -8,7 +8,7 @@ }, "files": [ { - "content": "'use client';\n\nimport React, { useRef } from 'react';\n\nimport type { ValueId } from '@/config/customizer-plugins';\n\nimport { cn } from '@udecode/cn';\nimport { AIChatPlugin, CopilotPlugin } from '@udecode/plate-ai/react';\nimport { AlignPlugin } from '@udecode/plate-alignment/react';\nimport { AutoformatPlugin } from '@udecode/plate-autoformat/react';\nimport {\n BoldPlugin,\n CodePlugin,\n ItalicPlugin,\n StrikethroughPlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n UnderlinePlugin,\n} from '@udecode/plate-basic-marks/react';\nimport { BlockquotePlugin } from '@udecode/plate-block-quote/react';\nimport { SingleLinePlugin } from '@udecode/plate-break/react';\nimport { CaptionPlugin } from '@udecode/plate-caption/react';\nimport { CodeBlockPlugin } from '@udecode/plate-code-block/react';\nimport { CommentsPlugin } from '@udecode/plate-comments/react';\nimport {\n ParagraphPlugin,\n Plate,\n usePlateEditor,\n} from '@udecode/plate-common/react';\nimport { DatePlugin } from '@udecode/plate-date/react';\nimport { DndPlugin } from '@udecode/plate-dnd';\nimport { DocxPlugin } from '@udecode/plate-docx';\nimport { EmojiPlugin } from '@udecode/plate-emoji/react';\nimport { ExcalidrawPlugin } from '@udecode/plate-excalidraw/react';\nimport {\n FontBackgroundColorPlugin,\n FontColorPlugin,\n FontSizePlugin,\n} from '@udecode/plate-font/react';\nimport { HEADING_KEYS } from '@udecode/plate-heading';\nimport { HeadingPlugin, TocPlugin } from '@udecode/plate-heading/react';\nimport { HighlightPlugin } from '@udecode/plate-highlight/react';\nimport { HorizontalRulePlugin } from '@udecode/plate-horizontal-rule/react';\nimport { IndentPlugin } from '@udecode/plate-indent/react';\nimport { IndentListPlugin } from '@udecode/plate-indent-list/react';\nimport { JuicePlugin } from '@udecode/plate-juice';\nimport { KbdPlugin } from '@udecode/plate-kbd/react';\nimport { ColumnPlugin } from '@udecode/plate-layout/react';\nimport { LineHeightPlugin } from '@udecode/plate-line-height/react';\nimport { LinkPlugin } from '@udecode/plate-link/react';\nimport { ListPlugin, TodoListPlugin } from '@udecode/plate-list/react';\nimport { MarkdownPlugin } from '@udecode/plate-markdown';\nimport { ImagePlugin, MediaEmbedPlugin } from '@udecode/plate-media/react';\nimport { MentionPlugin } from '@udecode/plate-mention/react';\nimport { NodeIdPlugin } from '@udecode/plate-node-id';\nimport { NormalizeTypesPlugin } from '@udecode/plate-normalizers';\nimport { PlaywrightPlugin } from '@udecode/plate-playwright';\nimport { DeletePlugin, SelectOnBackspacePlugin } from '@udecode/plate-select';\nimport {\n BlockMenuPlugin,\n BlockSelectionPlugin,\n} from '@udecode/plate-selection/react';\nimport { SlashPlugin } from '@udecode/plate-slash-command/react';\nimport { TablePlugin } from '@udecode/plate-table/react';\nimport { TogglePlugin } from '@udecode/plate-toggle/react';\nimport { TrailingBlockPlugin } from '@udecode/plate-trailing-block';\nimport Prism from 'prismjs';\n\nimport { CheckPlugin } from '@/components/context/check-plugin';\nimport { settingsStore } from '@/components/context/settings-store';\nimport { aiPlugins } from '@/lib/plate/demo/plugins/ai-plugins';\nimport { getAutoformatOptions } from '@/lib/plate/demo/plugins/autoformatOptions';\nimport { copilotPlugins } from '@/lib/plate/demo/plugins/copilot-plugins';\nimport { createPlateUI } from '@/plate/create-plate-ui';\nimport { editableProps } from '@/plate/demo/editableProps';\nimport { isEnabled } from '@/plate/demo/is-enabled';\nimport { DragOverCursorPlugin } from '@/plate/demo/plugins/DragOverCursorPlugin';\nimport { exitBreakPlugin } from '@/plate/demo/plugins/exitBreakPlugin';\nimport { resetBlockTypePlugin } from '@/plate/demo/plugins/resetBlockTypePlugin';\nimport { softBreakPlugin } from '@/plate/demo/plugins/softBreakPlugin';\nimport { tabbablePlugin } from '@/plate/demo/plugins/tabbablePlugin';\nimport { commentsData, usersData } from '@/plate/demo/values/commentsValue';\nimport { usePlaygroundValue } from '@/plate/demo/values/usePlaygroundValue';\nimport { BlockContextMenu } from '@/components/plate-ui/block-context-menu';\nimport { CommentsPopover } from '@/components/plate-ui/comments-popover';\nimport {\n CursorOverlay,\n SelectionOverlayPlugin,\n} from '@/components/plate-ui/cursor-overlay';\nimport { Editor, EditorContainer } from '@/components/plate-ui/editor';\nimport { FixedToolbar } from '@/components/plate-ui/fixed-toolbar';\nimport { FixedToolbarButtons } from '@/components/plate-ui/fixed-toolbar-buttons';\nimport { FloatingToolbar } from '@/components/plate-ui/floating-toolbar';\nimport { FloatingToolbarButtons } from '@/components/plate-ui/floating-toolbar-buttons';\nimport { ImagePreview } from '@/components/plate-ui/image-preview';\nimport {\n FireLiComponent,\n FireMarker,\n} from '@/components/plate-ui/indent-fire-marker';\nimport {\n TodoLi,\n TodoMarker,\n} from '@/components/plate-ui/indent-todo-marker';\nimport { LinkFloatingToolbar } from '@/components/plate-ui/link-floating-toolbar';\n\nimport { usePlaygroundEnabled } from './usePlaygroundEnabled';\n\nexport const usePlaygroundEditor = (id: any = '', scrollSelector?: string) => {\n const enabledPlugins = settingsStore.use.checkedPlugins();\n const overridePlugins = usePlaygroundEnabled(id);\n const autoformatOptions = getAutoformatOptions(id, enabledPlugins);\n\n const value = usePlaygroundValue(id);\n const key = settingsStore.use.version();\n const editorId = id || 'playground-' + key;\n\n return usePlateEditor(\n {\n id: editorId,\n override: {\n components: createPlateUI({\n draggable: isEnabled('dnd', id),\n placeholder: isEnabled('placeholder', id),\n }),\n plugins: overridePlugins,\n },\n plugins: [\n // AI\n ...(id === 'ai' || enabledPlugins[AIChatPlugin.key] ? aiPlugins : []),\n ...(id === 'copilot' || enabledPlugins[CopilotPlugin.key]\n ? copilotPlugins\n : []),\n // Nodes\n HeadingPlugin,\n TocPlugin.configure({\n options: {\n scrollContainerSelector: `#${scrollSelector}`,\n topOffset: 80,\n },\n }),\n BlockquotePlugin,\n CodeBlockPlugin.configure({\n options: {\n prism: Prism,\n },\n }),\n HorizontalRulePlugin,\n LinkPlugin.extend({\n render: { afterEditable: () => },\n }),\n ...(id === 'list' ? [ListPlugin] : []),\n ImagePlugin.extend({\n render: { afterEditable: ImagePreview },\n }),\n MediaEmbedPlugin,\n CaptionPlugin.configure({\n options: {\n plugins: [ImagePlugin, MediaEmbedPlugin],\n },\n }),\n DatePlugin,\n MentionPlugin.configure({\n options: {\n triggerPreviousCharPattern: /^$|^[\\s\"']$/,\n },\n }),\n SlashPlugin,\n TablePlugin.configure({\n options: {\n enableMerging: id === 'tableMerge',\n },\n }),\n ColumnPlugin,\n SelectionOverlayPlugin,\n\n TodoListPlugin,\n TogglePlugin,\n ExcalidrawPlugin,\n // Marks\n BoldPlugin,\n ItalicPlugin,\n UnderlinePlugin,\n StrikethroughPlugin,\n CodePlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n FontColorPlugin,\n FontBackgroundColorPlugin,\n FontSizePlugin,\n HighlightPlugin,\n KbdPlugin,\n\n // Block Style\n AlignPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n MediaEmbedPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n ImagePlugin.key,\n HEADING_KEYS.h6,\n ],\n },\n }),\n IndentPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n }),\n IndentListPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n options: {\n listStyleTypes: {\n fire: {\n liComponent: FireLiComponent,\n markerComponent: FireMarker,\n type: 'fire',\n },\n todo: {\n liComponent: TodoLi,\n markerComponent: TodoMarker,\n type: 'todo',\n },\n },\n },\n }),\n LineHeightPlugin.extend({\n inject: {\n nodeProps: {\n defaultNodeValue: 1.5,\n validNodeValues: [1, 1.2, 1.5, 2, 3],\n },\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n ],\n },\n }),\n\n // Functionality\n AutoformatPlugin.configure({\n options: autoformatOptions,\n }),\n BlockSelectionPlugin.configure({\n options: {\n areaOptions: {\n behaviour: {\n scrolling: {\n speedDivider: 1.5,\n },\n startThreshold: 10,\n },\n boundaries: `#${scrollSelector}`,\n container: `#${scrollSelector}`,\n selectables: [`#${scrollSelector} .slate-selectable`],\n selectionAreaClass: 'slate-selection-area',\n },\n enableContextMenu: true,\n },\n }),\n BlockMenuPlugin.configure({\n render: { aboveEditable: BlockContextMenu },\n }),\n DndPlugin.configure({ options: { enableScroller: true } }),\n EmojiPlugin,\n exitBreakPlugin,\n NodeIdPlugin,\n NormalizeTypesPlugin.configure({\n options: {\n rules: [{ path: [0], strictType: HEADING_KEYS.h1 }],\n },\n }),\n resetBlockTypePlugin,\n SelectOnBackspacePlugin.configure({\n options: {\n query: {\n allow: [ImagePlugin.key, HorizontalRulePlugin.key],\n },\n },\n }),\n DeletePlugin,\n SingleLinePlugin,\n softBreakPlugin,\n tabbablePlugin,\n TrailingBlockPlugin.configure({\n options: { type: ParagraphPlugin.key },\n }),\n DragOverCursorPlugin,\n\n // Collaboration\n CommentsPlugin.configure({\n options: {\n comments: commentsData,\n myUserId: '1',\n users: usersData,\n },\n }),\n\n // Deserialization\n DocxPlugin,\n MarkdownPlugin.configure({ options: { indentList: true } }),\n JuicePlugin,\n\n // Testing\n PlaywrightPlugin.configure({\n enabled: process.env.NODE_ENV !== 'production',\n }),\n ],\n value: value,\n },\n []\n );\n};\n\nexport default function PlaygroundDemo({\n id,\n className,\n scrollSelector,\n}: {\n id?: ValueId;\n className?: string;\n scrollSelector?: string;\n}) {\n const containerRef = useRef(null);\n const enabled = settingsStore.use.checkedComponents();\n\n const editor = usePlaygroundEditor(\n id,\n scrollSelector ?? `blockSelection-${id}`\n );\n\n return (\n \n \n \n \n \n \n \n \n \n\n
\n \n \n\n \n \n \n \n \n \n \n\n \n \n \n \n\n \n \n \n
\n
\n
\n );\n}\n\nconst DemoIdContext = React.createContext(undefined);\n\nexport function DemoId({\n id,\n children,\n}: {\n children: React.ReactNode;\n id?: string;\n}) {\n return {children};\n}\n\nexport function useDemoId() {\n return React.useContext(DemoIdContext);\n}\n", + "content": "'use client';\n\nimport React, { useRef } from 'react';\n\nimport type { ValueId } from '@/config/customizer-plugins';\n\nimport { cn } from '@udecode/cn';\nimport { AIChatPlugin, CopilotPlugin } from '@udecode/plate-ai/react';\nimport { AlignPlugin } from '@udecode/plate-alignment/react';\nimport { AutoformatPlugin } from '@udecode/plate-autoformat/react';\nimport {\n BoldPlugin,\n CodePlugin,\n ItalicPlugin,\n StrikethroughPlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n UnderlinePlugin,\n} from '@udecode/plate-basic-marks/react';\nimport { BlockquotePlugin } from '@udecode/plate-block-quote/react';\nimport { SingleLinePlugin } from '@udecode/plate-break/react';\nimport { CaptionPlugin } from '@udecode/plate-caption/react';\nimport { CodeBlockPlugin } from '@udecode/plate-code-block/react';\nimport { CommentsPlugin } from '@udecode/plate-comments/react';\nimport {\n ParagraphPlugin,\n Plate,\n usePlateEditor,\n} from '@udecode/plate-common/react';\nimport { DatePlugin } from '@udecode/plate-date/react';\nimport { DndPlugin } from '@udecode/plate-dnd';\nimport { DocxPlugin } from '@udecode/plate-docx';\nimport { EmojiPlugin } from '@udecode/plate-emoji/react';\nimport { ExcalidrawPlugin } from '@udecode/plate-excalidraw/react';\nimport {\n FontBackgroundColorPlugin,\n FontColorPlugin,\n FontSizePlugin,\n} from '@udecode/plate-font/react';\nimport { HEADING_KEYS } from '@udecode/plate-heading';\nimport { HeadingPlugin, TocPlugin } from '@udecode/plate-heading/react';\nimport { HighlightPlugin } from '@udecode/plate-highlight/react';\nimport { HorizontalRulePlugin } from '@udecode/plate-horizontal-rule/react';\nimport { IndentPlugin } from '@udecode/plate-indent/react';\nimport { IndentListPlugin } from '@udecode/plate-indent-list/react';\nimport { JuicePlugin } from '@udecode/plate-juice';\nimport { KbdPlugin } from '@udecode/plate-kbd/react';\nimport { ColumnPlugin } from '@udecode/plate-layout/react';\nimport { LineHeightPlugin } from '@udecode/plate-line-height/react';\nimport { LinkPlugin } from '@udecode/plate-link/react';\nimport { ListPlugin, TodoListPlugin } from '@udecode/plate-list/react';\nimport { MarkdownPlugin } from '@udecode/plate-markdown';\nimport { ImagePlugin, MediaEmbedPlugin } from '@udecode/plate-media/react';\nimport { MentionPlugin } from '@udecode/plate-mention/react';\nimport { NodeIdPlugin } from '@udecode/plate-node-id';\nimport { NormalizeTypesPlugin } from '@udecode/plate-normalizers';\nimport { PlaywrightPlugin } from '@udecode/plate-playwright';\nimport { DeletePlugin, SelectOnBackspacePlugin } from '@udecode/plate-select';\nimport {\n BlockMenuPlugin,\n BlockSelectionPlugin,\n} from '@udecode/plate-selection/react';\nimport { SlashPlugin } from '@udecode/plate-slash-command/react';\nimport { TablePlugin } from '@udecode/plate-table/react';\nimport { TogglePlugin } from '@udecode/plate-toggle/react';\nimport { TrailingBlockPlugin } from '@udecode/plate-trailing-block';\nimport Prism from 'prismjs';\n\nimport { CheckPlugin } from '@/components/context/check-plugin';\nimport { settingsStore } from '@/components/context/settings-store';\nimport { aiPlugins } from '@/lib/plate/demo/plugins/ai-plugins';\nimport { getAutoformatOptions } from '@/lib/plate/demo/plugins/autoformatOptions';\nimport { copilotPlugins } from '@/lib/plate/demo/plugins/copilot-plugins';\nimport { createPlateUI } from '@/plate/create-plate-ui';\nimport { editableProps } from '@/plate/demo/editableProps';\nimport { isEnabled } from '@/plate/demo/is-enabled';\nimport { DragOverCursorPlugin } from '@/plate/demo/plugins/DragOverCursorPlugin';\nimport { exitBreakPlugin } from '@/plate/demo/plugins/exitBreakPlugin';\nimport { resetBlockTypePlugin } from '@/plate/demo/plugins/resetBlockTypePlugin';\nimport { softBreakPlugin } from '@/plate/demo/plugins/softBreakPlugin';\nimport { tabbablePlugin } from '@/plate/demo/plugins/tabbablePlugin';\nimport { commentsData, usersData } from '@/plate/demo/values/commentsValue';\nimport { usePlaygroundValue } from '@/plate/demo/values/usePlaygroundValue';\nimport { BlockContextMenu } from '@/components/plate-ui/block-context-menu';\nimport { CommentsPopover } from '@/components/plate-ui/comments-popover';\nimport {\n CursorOverlay,\n SelectionOverlayPlugin,\n} from '@/components/plate-ui/cursor-overlay';\nimport { Editor, EditorContainer } from '@/components/plate-ui/editor';\nimport { FixedToolbar } from '@/components/plate-ui/fixed-toolbar';\nimport { FixedToolbarButtons } from '@/components/plate-ui/fixed-toolbar-buttons';\nimport { FloatingToolbar } from '@/components/plate-ui/floating-toolbar';\nimport { FloatingToolbarButtons } from '@/components/plate-ui/floating-toolbar-buttons';\nimport { ImagePreview } from '@/components/plate-ui/image-preview';\nimport {\n FireLiComponent,\n FireMarker,\n} from '@/components/plate-ui/indent-fire-marker';\nimport {\n TodoLi,\n TodoMarker,\n} from '@/components/plate-ui/indent-todo-marker';\nimport { LinkFloatingToolbar } from '@/components/plate-ui/link-floating-toolbar';\n\nimport { usePlaygroundEnabled } from './usePlaygroundEnabled';\n\nexport const usePlaygroundEditor = (id: any = '', scrollSelector?: string) => {\n const enabledPlugins = settingsStore.use.checkedPlugins();\n const overridePlugins = usePlaygroundEnabled(id);\n const autoformatOptions = getAutoformatOptions(id, enabledPlugins);\n\n const value = usePlaygroundValue(id);\n const key = settingsStore.use.version();\n const editorId = id || 'playground-' + key;\n\n return usePlateEditor(\n {\n id: editorId,\n override: {\n components: createPlateUI({\n draggable: isEnabled('dnd', id),\n placeholder: isEnabled('placeholder', id),\n }),\n plugins: overridePlugins,\n },\n plugins: [\n // AI\n ...(id === 'ai' || enabledPlugins[AIChatPlugin.key] ? aiPlugins : []),\n ...(id === 'copilot' || enabledPlugins[CopilotPlugin.key]\n ? copilotPlugins\n : []),\n // Nodes\n HeadingPlugin,\n TocPlugin.configure({\n options: {\n scrollContainerSelector: `#${scrollSelector}`,\n topOffset: 80,\n },\n }),\n BlockquotePlugin,\n CodeBlockPlugin.configure({\n options: {\n prism: Prism,\n },\n }),\n HorizontalRulePlugin,\n LinkPlugin.extend({\n render: { afterEditable: () => },\n }),\n ...(id === 'list' ? [ListPlugin] : []),\n ImagePlugin.extend({\n options: {\n disableUploadInsert: true,\n },\n render: { afterEditable: ImagePreview },\n }),\n MediaEmbedPlugin,\n CaptionPlugin.configure({\n options: {\n plugins: [ImagePlugin, MediaEmbedPlugin],\n },\n }),\n DatePlugin,\n MentionPlugin.configure({\n options: {\n triggerPreviousCharPattern: /^$|^[\\s\"']$/,\n },\n }),\n SlashPlugin,\n TablePlugin.configure({\n options: {\n enableMerging: id === 'tableMerge',\n },\n }),\n ColumnPlugin,\n SelectionOverlayPlugin,\n\n TodoListPlugin,\n TogglePlugin,\n ExcalidrawPlugin,\n // Marks\n BoldPlugin,\n ItalicPlugin,\n UnderlinePlugin,\n StrikethroughPlugin,\n CodePlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n FontColorPlugin,\n FontBackgroundColorPlugin,\n FontSizePlugin,\n HighlightPlugin,\n KbdPlugin,\n\n // Block Style\n AlignPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n MediaEmbedPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n ImagePlugin.key,\n HEADING_KEYS.h6,\n ],\n },\n }),\n IndentPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n }),\n IndentListPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n options: {\n listStyleTypes: {\n fire: {\n liComponent: FireLiComponent,\n markerComponent: FireMarker,\n type: 'fire',\n },\n todo: {\n liComponent: TodoLi,\n markerComponent: TodoMarker,\n type: 'todo',\n },\n },\n },\n }),\n LineHeightPlugin.extend({\n inject: {\n nodeProps: {\n defaultNodeValue: 1.5,\n validNodeValues: [1, 1.2, 1.5, 2, 3],\n },\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n ],\n },\n }),\n\n // Functionality\n AutoformatPlugin.configure({\n options: autoformatOptions,\n }),\n BlockSelectionPlugin.configure({\n options: {\n areaOptions: {\n behaviour: {\n scrolling: {\n speedDivider: 1.5,\n },\n startThreshold: 10,\n },\n boundaries: `#${scrollSelector}`,\n container: `#${scrollSelector}`,\n selectables: [`#${scrollSelector} .slate-selectable`],\n selectionAreaClass: 'slate-selection-area',\n },\n enableContextMenu: true,\n },\n }),\n BlockMenuPlugin.configure({\n render: { aboveEditable: BlockContextMenu },\n }),\n DndPlugin.configure({\n options: {\n enableScroller: true,\n onDropFiles: ({ dragItem, editor, target }) => {\n editor\n .getTransforms(ImagePlugin)\n .insertImageFromFiles(dragItem.files, {\n at: target,\n nextBlock: false,\n });\n },\n },\n }),\n EmojiPlugin,\n exitBreakPlugin,\n NodeIdPlugin,\n NormalizeTypesPlugin.configure({\n options: {\n rules: [{ path: [0], strictType: HEADING_KEYS.h1 }],\n },\n }),\n resetBlockTypePlugin,\n SelectOnBackspacePlugin.configure({\n options: {\n query: {\n allow: [ImagePlugin.key, HorizontalRulePlugin.key],\n },\n },\n }),\n DeletePlugin,\n SingleLinePlugin,\n softBreakPlugin,\n tabbablePlugin,\n TrailingBlockPlugin.configure({\n options: { type: ParagraphPlugin.key },\n }),\n DragOverCursorPlugin,\n\n // Collaboration\n CommentsPlugin.configure({\n options: {\n comments: commentsData,\n myUserId: '1',\n users: usersData,\n },\n }),\n\n // Deserialization\n DocxPlugin,\n MarkdownPlugin.configure({ options: { indentList: true } }),\n JuicePlugin,\n\n // Testing\n PlaywrightPlugin.configure({\n enabled: process.env.NODE_ENV !== 'production',\n }),\n ],\n value: value,\n },\n []\n );\n};\n\nexport default function PlaygroundDemo({\n id,\n className,\n scrollSelector,\n}: {\n id?: ValueId;\n className?: string;\n scrollSelector?: string;\n}) {\n const containerRef = useRef(null);\n const enabled = settingsStore.use.checkedComponents();\n\n const editor = usePlaygroundEditor(\n id,\n scrollSelector ?? `blockSelection-${id}`\n );\n\n return (\n \n \n \n \n \n \n \n \n \n\n
\n \n \n\n \n \n \n \n \n \n \n\n \n \n \n \n\n \n \n \n
\n
\n
\n );\n}\n\nconst DemoIdContext = React.createContext(undefined);\n\nexport function DemoId({\n id,\n children,\n}: {\n children: React.ReactNode;\n id?: string;\n}) {\n return {children};\n}\n\nexport function useDemoId() {\n return React.useContext(DemoIdContext);\n}\n", "path": "example/playground-demo.tsx", "target": "components/playground-demo.tsx", "type": "registry:example" diff --git a/apps/www/public/r/styles/default/block-menu-demo.json b/apps/www/public/r/styles/default/block-menu-demo.json index 067dd84263..7f523b1d3e 100644 --- a/apps/www/public/r/styles/default/block-menu-demo.json +++ b/apps/www/public/r/styles/default/block-menu-demo.json @@ -4,7 +4,7 @@ }, "files": [ { - "content": "'use client';\n\nimport React, { useRef } from 'react';\n\nimport type { ValueId } from '@/config/customizer-plugins';\n\nimport { cn } from '@udecode/cn';\nimport { AIChatPlugin, CopilotPlugin } from '@udecode/plate-ai/react';\nimport { AlignPlugin } from '@udecode/plate-alignment/react';\nimport { AutoformatPlugin } from '@udecode/plate-autoformat/react';\nimport {\n BoldPlugin,\n CodePlugin,\n ItalicPlugin,\n StrikethroughPlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n UnderlinePlugin,\n} from '@udecode/plate-basic-marks/react';\nimport { BlockquotePlugin } from '@udecode/plate-block-quote/react';\nimport { SingleLinePlugin } from '@udecode/plate-break/react';\nimport { CaptionPlugin } from '@udecode/plate-caption/react';\nimport { CodeBlockPlugin } from '@udecode/plate-code-block/react';\nimport { CommentsPlugin } from '@udecode/plate-comments/react';\nimport {\n ParagraphPlugin,\n Plate,\n usePlateEditor,\n} from '@udecode/plate-common/react';\nimport { DatePlugin } from '@udecode/plate-date/react';\nimport { DndPlugin } from '@udecode/plate-dnd';\nimport { DocxPlugin } from '@udecode/plate-docx';\nimport { EmojiPlugin } from '@udecode/plate-emoji/react';\nimport { ExcalidrawPlugin } from '@udecode/plate-excalidraw/react';\nimport {\n FontBackgroundColorPlugin,\n FontColorPlugin,\n FontSizePlugin,\n} from '@udecode/plate-font/react';\nimport { HEADING_KEYS } from '@udecode/plate-heading';\nimport { HeadingPlugin, TocPlugin } from '@udecode/plate-heading/react';\nimport { HighlightPlugin } from '@udecode/plate-highlight/react';\nimport { HorizontalRulePlugin } from '@udecode/plate-horizontal-rule/react';\nimport { IndentPlugin } from '@udecode/plate-indent/react';\nimport { IndentListPlugin } from '@udecode/plate-indent-list/react';\nimport { JuicePlugin } from '@udecode/plate-juice';\nimport { KbdPlugin } from '@udecode/plate-kbd/react';\nimport { ColumnPlugin } from '@udecode/plate-layout/react';\nimport { LineHeightPlugin } from '@udecode/plate-line-height/react';\nimport { LinkPlugin } from '@udecode/plate-link/react';\nimport { ListPlugin, TodoListPlugin } from '@udecode/plate-list/react';\nimport { MarkdownPlugin } from '@udecode/plate-markdown';\nimport { ImagePlugin, MediaEmbedPlugin } from '@udecode/plate-media/react';\nimport { MentionPlugin } from '@udecode/plate-mention/react';\nimport { NodeIdPlugin } from '@udecode/plate-node-id';\nimport { NormalizeTypesPlugin } from '@udecode/plate-normalizers';\nimport { PlaywrightPlugin } from '@udecode/plate-playwright';\nimport { DeletePlugin, SelectOnBackspacePlugin } from '@udecode/plate-select';\nimport {\n BlockMenuPlugin,\n BlockSelectionPlugin,\n} from '@udecode/plate-selection/react';\nimport { SlashPlugin } from '@udecode/plate-slash-command/react';\nimport { TablePlugin } from '@udecode/plate-table/react';\nimport { TogglePlugin } from '@udecode/plate-toggle/react';\nimport { TrailingBlockPlugin } from '@udecode/plate-trailing-block';\nimport Prism from 'prismjs';\n\nimport { CheckPlugin } from '@/components/context/check-plugin';\nimport { settingsStore } from '@/components/context/settings-store';\nimport { aiPlugins } from '@/lib/plate/demo/plugins/ai-plugins';\nimport { getAutoformatOptions } from '@/lib/plate/demo/plugins/autoformatOptions';\nimport { copilotPlugins } from '@/lib/plate/demo/plugins/copilot-plugins';\nimport { createPlateUI } from '@/plate/create-plate-ui';\nimport { editableProps } from '@/plate/demo/editableProps';\nimport { isEnabled } from '@/plate/demo/is-enabled';\nimport { DragOverCursorPlugin } from '@/plate/demo/plugins/DragOverCursorPlugin';\nimport { exitBreakPlugin } from '@/plate/demo/plugins/exitBreakPlugin';\nimport { resetBlockTypePlugin } from '@/plate/demo/plugins/resetBlockTypePlugin';\nimport { softBreakPlugin } from '@/plate/demo/plugins/softBreakPlugin';\nimport { tabbablePlugin } from '@/plate/demo/plugins/tabbablePlugin';\nimport { commentsData, usersData } from '@/plate/demo/values/commentsValue';\nimport { usePlaygroundValue } from '@/plate/demo/values/usePlaygroundValue';\nimport { BlockContextMenu } from '@/components/plate-ui/block-context-menu';\nimport { CommentsPopover } from '@/components/plate-ui/comments-popover';\nimport {\n CursorOverlay,\n SelectionOverlayPlugin,\n} from '@/components/plate-ui/cursor-overlay';\nimport { Editor, EditorContainer } from '@/components/plate-ui/editor';\nimport { FixedToolbar } from '@/components/plate-ui/fixed-toolbar';\nimport { FixedToolbarButtons } from '@/components/plate-ui/fixed-toolbar-buttons';\nimport { FloatingToolbar } from '@/components/plate-ui/floating-toolbar';\nimport { FloatingToolbarButtons } from '@/components/plate-ui/floating-toolbar-buttons';\nimport { ImagePreview } from '@/components/plate-ui/image-preview';\nimport {\n FireLiComponent,\n FireMarker,\n} from '@/components/plate-ui/indent-fire-marker';\nimport {\n TodoLi,\n TodoMarker,\n} from '@/components/plate-ui/indent-todo-marker';\nimport { LinkFloatingToolbar } from '@/components/plate-ui/link-floating-toolbar';\n\nimport { usePlaygroundEnabled } from './usePlaygroundEnabled';\n\nexport const usePlaygroundEditor = (id: any = '', scrollSelector?: string) => {\n const enabledPlugins = settingsStore.use.checkedPlugins();\n const overridePlugins = usePlaygroundEnabled(id);\n const autoformatOptions = getAutoformatOptions(id, enabledPlugins);\n\n const value = usePlaygroundValue(id);\n const key = settingsStore.use.version();\n const editorId = id || 'playground-' + key;\n\n return usePlateEditor(\n {\n id: editorId,\n override: {\n components: createPlateUI({\n draggable: isEnabled('dnd', id),\n placeholder: isEnabled('placeholder', id),\n }),\n plugins: overridePlugins,\n },\n plugins: [\n // AI\n ...(id === 'ai' || enabledPlugins[AIChatPlugin.key] ? aiPlugins : []),\n ...(id === 'copilot' || enabledPlugins[CopilotPlugin.key]\n ? copilotPlugins\n : []),\n // Nodes\n HeadingPlugin,\n TocPlugin.configure({\n options: {\n scrollContainerSelector: `#${scrollSelector}`,\n topOffset: 80,\n },\n }),\n BlockquotePlugin,\n CodeBlockPlugin.configure({\n options: {\n prism: Prism,\n },\n }),\n HorizontalRulePlugin,\n LinkPlugin.extend({\n render: { afterEditable: () => },\n }),\n ...(id === 'list' ? [ListPlugin] : []),\n ImagePlugin.extend({\n render: { afterEditable: ImagePreview },\n }),\n MediaEmbedPlugin,\n CaptionPlugin.configure({\n options: {\n plugins: [ImagePlugin, MediaEmbedPlugin],\n },\n }),\n DatePlugin,\n MentionPlugin.configure({\n options: {\n triggerPreviousCharPattern: /^$|^[\\s\"']$/,\n },\n }),\n SlashPlugin,\n TablePlugin.configure({\n options: {\n enableMerging: id === 'tableMerge',\n },\n }),\n ColumnPlugin,\n SelectionOverlayPlugin,\n\n TodoListPlugin,\n TogglePlugin,\n ExcalidrawPlugin,\n // Marks\n BoldPlugin,\n ItalicPlugin,\n UnderlinePlugin,\n StrikethroughPlugin,\n CodePlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n FontColorPlugin,\n FontBackgroundColorPlugin,\n FontSizePlugin,\n HighlightPlugin,\n KbdPlugin,\n\n // Block Style\n AlignPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n MediaEmbedPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n ImagePlugin.key,\n HEADING_KEYS.h6,\n ],\n },\n }),\n IndentPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n }),\n IndentListPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n options: {\n listStyleTypes: {\n fire: {\n liComponent: FireLiComponent,\n markerComponent: FireMarker,\n type: 'fire',\n },\n todo: {\n liComponent: TodoLi,\n markerComponent: TodoMarker,\n type: 'todo',\n },\n },\n },\n }),\n LineHeightPlugin.extend({\n inject: {\n nodeProps: {\n defaultNodeValue: 1.5,\n validNodeValues: [1, 1.2, 1.5, 2, 3],\n },\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n ],\n },\n }),\n\n // Functionality\n AutoformatPlugin.configure({\n options: autoformatOptions,\n }),\n BlockSelectionPlugin.configure({\n options: {\n areaOptions: {\n behaviour: {\n scrolling: {\n speedDivider: 1.5,\n },\n startThreshold: 10,\n },\n boundaries: `#${scrollSelector}`,\n container: `#${scrollSelector}`,\n selectables: [`#${scrollSelector} .slate-selectable`],\n selectionAreaClass: 'slate-selection-area',\n },\n enableContextMenu: true,\n },\n }),\n BlockMenuPlugin.configure({\n render: { aboveEditable: BlockContextMenu },\n }),\n DndPlugin.configure({ options: { enableScroller: true } }),\n EmojiPlugin,\n exitBreakPlugin,\n NodeIdPlugin,\n NormalizeTypesPlugin.configure({\n options: {\n rules: [{ path: [0], strictType: HEADING_KEYS.h1 }],\n },\n }),\n resetBlockTypePlugin,\n SelectOnBackspacePlugin.configure({\n options: {\n query: {\n allow: [ImagePlugin.key, HorizontalRulePlugin.key],\n },\n },\n }),\n DeletePlugin,\n SingleLinePlugin,\n softBreakPlugin,\n tabbablePlugin,\n TrailingBlockPlugin.configure({\n options: { type: ParagraphPlugin.key },\n }),\n DragOverCursorPlugin,\n\n // Collaboration\n CommentsPlugin.configure({\n options: {\n comments: commentsData,\n myUserId: '1',\n users: usersData,\n },\n }),\n\n // Deserialization\n DocxPlugin,\n MarkdownPlugin.configure({ options: { indentList: true } }),\n JuicePlugin,\n\n // Testing\n PlaywrightPlugin.configure({\n enabled: process.env.NODE_ENV !== 'production',\n }),\n ],\n value: value,\n },\n []\n );\n};\n\nexport default function PlaygroundDemo({\n id,\n className,\n scrollSelector,\n}: {\n id?: ValueId;\n className?: string;\n scrollSelector?: string;\n}) {\n const containerRef = useRef(null);\n const enabled = settingsStore.use.checkedComponents();\n\n const editor = usePlaygroundEditor(\n id,\n scrollSelector ?? `blockSelection-${id}`\n );\n\n return (\n \n \n \n \n \n \n \n \n \n\n
\n \n \n\n \n \n \n \n \n \n \n\n \n \n \n \n\n \n \n \n
\n
\n
\n );\n}\n\nconst DemoIdContext = React.createContext(undefined);\n\nexport function DemoId({\n id,\n children,\n}: {\n children: React.ReactNode;\n id?: string;\n}) {\n return {children};\n}\n\nexport function useDemoId() {\n return React.useContext(DemoIdContext);\n}\n", + "content": "'use client';\n\nimport React, { useRef } from 'react';\n\nimport type { ValueId } from '@/config/customizer-plugins';\n\nimport { cn } from '@udecode/cn';\nimport { AIChatPlugin, CopilotPlugin } from '@udecode/plate-ai/react';\nimport { AlignPlugin } from '@udecode/plate-alignment/react';\nimport { AutoformatPlugin } from '@udecode/plate-autoformat/react';\nimport {\n BoldPlugin,\n CodePlugin,\n ItalicPlugin,\n StrikethroughPlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n UnderlinePlugin,\n} from '@udecode/plate-basic-marks/react';\nimport { BlockquotePlugin } from '@udecode/plate-block-quote/react';\nimport { SingleLinePlugin } from '@udecode/plate-break/react';\nimport { CaptionPlugin } from '@udecode/plate-caption/react';\nimport { CodeBlockPlugin } from '@udecode/plate-code-block/react';\nimport { CommentsPlugin } from '@udecode/plate-comments/react';\nimport {\n ParagraphPlugin,\n Plate,\n usePlateEditor,\n} from '@udecode/plate-common/react';\nimport { DatePlugin } from '@udecode/plate-date/react';\nimport { DndPlugin } from '@udecode/plate-dnd';\nimport { DocxPlugin } from '@udecode/plate-docx';\nimport { EmojiPlugin } from '@udecode/plate-emoji/react';\nimport { ExcalidrawPlugin } from '@udecode/plate-excalidraw/react';\nimport {\n FontBackgroundColorPlugin,\n FontColorPlugin,\n FontSizePlugin,\n} from '@udecode/plate-font/react';\nimport { HEADING_KEYS } from '@udecode/plate-heading';\nimport { HeadingPlugin, TocPlugin } from '@udecode/plate-heading/react';\nimport { HighlightPlugin } from '@udecode/plate-highlight/react';\nimport { HorizontalRulePlugin } from '@udecode/plate-horizontal-rule/react';\nimport { IndentPlugin } from '@udecode/plate-indent/react';\nimport { IndentListPlugin } from '@udecode/plate-indent-list/react';\nimport { JuicePlugin } from '@udecode/plate-juice';\nimport { KbdPlugin } from '@udecode/plate-kbd/react';\nimport { ColumnPlugin } from '@udecode/plate-layout/react';\nimport { LineHeightPlugin } from '@udecode/plate-line-height/react';\nimport { LinkPlugin } from '@udecode/plate-link/react';\nimport { ListPlugin, TodoListPlugin } from '@udecode/plate-list/react';\nimport { MarkdownPlugin } from '@udecode/plate-markdown';\nimport { ImagePlugin, MediaEmbedPlugin } from '@udecode/plate-media/react';\nimport { MentionPlugin } from '@udecode/plate-mention/react';\nimport { NodeIdPlugin } from '@udecode/plate-node-id';\nimport { NormalizeTypesPlugin } from '@udecode/plate-normalizers';\nimport { PlaywrightPlugin } from '@udecode/plate-playwright';\nimport { DeletePlugin, SelectOnBackspacePlugin } from '@udecode/plate-select';\nimport {\n BlockMenuPlugin,\n BlockSelectionPlugin,\n} from '@udecode/plate-selection/react';\nimport { SlashPlugin } from '@udecode/plate-slash-command/react';\nimport { TablePlugin } from '@udecode/plate-table/react';\nimport { TogglePlugin } from '@udecode/plate-toggle/react';\nimport { TrailingBlockPlugin } from '@udecode/plate-trailing-block';\nimport Prism from 'prismjs';\n\nimport { CheckPlugin } from '@/components/context/check-plugin';\nimport { settingsStore } from '@/components/context/settings-store';\nimport { aiPlugins } from '@/lib/plate/demo/plugins/ai-plugins';\nimport { getAutoformatOptions } from '@/lib/plate/demo/plugins/autoformatOptions';\nimport { copilotPlugins } from '@/lib/plate/demo/plugins/copilot-plugins';\nimport { createPlateUI } from '@/plate/create-plate-ui';\nimport { editableProps } from '@/plate/demo/editableProps';\nimport { isEnabled } from '@/plate/demo/is-enabled';\nimport { DragOverCursorPlugin } from '@/plate/demo/plugins/DragOverCursorPlugin';\nimport { exitBreakPlugin } from '@/plate/demo/plugins/exitBreakPlugin';\nimport { resetBlockTypePlugin } from '@/plate/demo/plugins/resetBlockTypePlugin';\nimport { softBreakPlugin } from '@/plate/demo/plugins/softBreakPlugin';\nimport { tabbablePlugin } from '@/plate/demo/plugins/tabbablePlugin';\nimport { commentsData, usersData } from '@/plate/demo/values/commentsValue';\nimport { usePlaygroundValue } from '@/plate/demo/values/usePlaygroundValue';\nimport { BlockContextMenu } from '@/components/plate-ui/block-context-menu';\nimport { CommentsPopover } from '@/components/plate-ui/comments-popover';\nimport {\n CursorOverlay,\n SelectionOverlayPlugin,\n} from '@/components/plate-ui/cursor-overlay';\nimport { Editor, EditorContainer } from '@/components/plate-ui/editor';\nimport { FixedToolbar } from '@/components/plate-ui/fixed-toolbar';\nimport { FixedToolbarButtons } from '@/components/plate-ui/fixed-toolbar-buttons';\nimport { FloatingToolbar } from '@/components/plate-ui/floating-toolbar';\nimport { FloatingToolbarButtons } from '@/components/plate-ui/floating-toolbar-buttons';\nimport { ImagePreview } from '@/components/plate-ui/image-preview';\nimport {\n FireLiComponent,\n FireMarker,\n} from '@/components/plate-ui/indent-fire-marker';\nimport {\n TodoLi,\n TodoMarker,\n} from '@/components/plate-ui/indent-todo-marker';\nimport { LinkFloatingToolbar } from '@/components/plate-ui/link-floating-toolbar';\n\nimport { usePlaygroundEnabled } from './usePlaygroundEnabled';\n\nexport const usePlaygroundEditor = (id: any = '', scrollSelector?: string) => {\n const enabledPlugins = settingsStore.use.checkedPlugins();\n const overridePlugins = usePlaygroundEnabled(id);\n const autoformatOptions = getAutoformatOptions(id, enabledPlugins);\n\n const value = usePlaygroundValue(id);\n const key = settingsStore.use.version();\n const editorId = id || 'playground-' + key;\n\n return usePlateEditor(\n {\n id: editorId,\n override: {\n components: createPlateUI({\n draggable: isEnabled('dnd', id),\n placeholder: isEnabled('placeholder', id),\n }),\n plugins: overridePlugins,\n },\n plugins: [\n // AI\n ...(id === 'ai' || enabledPlugins[AIChatPlugin.key] ? aiPlugins : []),\n ...(id === 'copilot' || enabledPlugins[CopilotPlugin.key]\n ? copilotPlugins\n : []),\n // Nodes\n HeadingPlugin,\n TocPlugin.configure({\n options: {\n scrollContainerSelector: `#${scrollSelector}`,\n topOffset: 80,\n },\n }),\n BlockquotePlugin,\n CodeBlockPlugin.configure({\n options: {\n prism: Prism,\n },\n }),\n HorizontalRulePlugin,\n LinkPlugin.extend({\n render: { afterEditable: () => },\n }),\n ...(id === 'list' ? [ListPlugin] : []),\n ImagePlugin.extend({\n options: {\n disableUploadInsert: true,\n },\n render: { afterEditable: ImagePreview },\n }),\n MediaEmbedPlugin,\n CaptionPlugin.configure({\n options: {\n plugins: [ImagePlugin, MediaEmbedPlugin],\n },\n }),\n DatePlugin,\n MentionPlugin.configure({\n options: {\n triggerPreviousCharPattern: /^$|^[\\s\"']$/,\n },\n }),\n SlashPlugin,\n TablePlugin.configure({\n options: {\n enableMerging: id === 'tableMerge',\n },\n }),\n ColumnPlugin,\n SelectionOverlayPlugin,\n\n TodoListPlugin,\n TogglePlugin,\n ExcalidrawPlugin,\n // Marks\n BoldPlugin,\n ItalicPlugin,\n UnderlinePlugin,\n StrikethroughPlugin,\n CodePlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n FontColorPlugin,\n FontBackgroundColorPlugin,\n FontSizePlugin,\n HighlightPlugin,\n KbdPlugin,\n\n // Block Style\n AlignPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n MediaEmbedPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n ImagePlugin.key,\n HEADING_KEYS.h6,\n ],\n },\n }),\n IndentPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n }),\n IndentListPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n options: {\n listStyleTypes: {\n fire: {\n liComponent: FireLiComponent,\n markerComponent: FireMarker,\n type: 'fire',\n },\n todo: {\n liComponent: TodoLi,\n markerComponent: TodoMarker,\n type: 'todo',\n },\n },\n },\n }),\n LineHeightPlugin.extend({\n inject: {\n nodeProps: {\n defaultNodeValue: 1.5,\n validNodeValues: [1, 1.2, 1.5, 2, 3],\n },\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n ],\n },\n }),\n\n // Functionality\n AutoformatPlugin.configure({\n options: autoformatOptions,\n }),\n BlockSelectionPlugin.configure({\n options: {\n areaOptions: {\n behaviour: {\n scrolling: {\n speedDivider: 1.5,\n },\n startThreshold: 10,\n },\n boundaries: `#${scrollSelector}`,\n container: `#${scrollSelector}`,\n selectables: [`#${scrollSelector} .slate-selectable`],\n selectionAreaClass: 'slate-selection-area',\n },\n enableContextMenu: true,\n },\n }),\n BlockMenuPlugin.configure({\n render: { aboveEditable: BlockContextMenu },\n }),\n DndPlugin.configure({\n options: {\n enableScroller: true,\n onDropFiles: ({ dragItem, editor, target }) => {\n editor\n .getTransforms(ImagePlugin)\n .insertImageFromFiles(dragItem.files, {\n at: target,\n nextBlock: false,\n });\n },\n },\n }),\n EmojiPlugin,\n exitBreakPlugin,\n NodeIdPlugin,\n NormalizeTypesPlugin.configure({\n options: {\n rules: [{ path: [0], strictType: HEADING_KEYS.h1 }],\n },\n }),\n resetBlockTypePlugin,\n SelectOnBackspacePlugin.configure({\n options: {\n query: {\n allow: [ImagePlugin.key, HorizontalRulePlugin.key],\n },\n },\n }),\n DeletePlugin,\n SingleLinePlugin,\n softBreakPlugin,\n tabbablePlugin,\n TrailingBlockPlugin.configure({\n options: { type: ParagraphPlugin.key },\n }),\n DragOverCursorPlugin,\n\n // Collaboration\n CommentsPlugin.configure({\n options: {\n comments: commentsData,\n myUserId: '1',\n users: usersData,\n },\n }),\n\n // Deserialization\n DocxPlugin,\n MarkdownPlugin.configure({ options: { indentList: true } }),\n JuicePlugin,\n\n // Testing\n PlaywrightPlugin.configure({\n enabled: process.env.NODE_ENV !== 'production',\n }),\n ],\n value: value,\n },\n []\n );\n};\n\nexport default function PlaygroundDemo({\n id,\n className,\n scrollSelector,\n}: {\n id?: ValueId;\n className?: string;\n scrollSelector?: string;\n}) {\n const containerRef = useRef(null);\n const enabled = settingsStore.use.checkedComponents();\n\n const editor = usePlaygroundEditor(\n id,\n scrollSelector ?? `blockSelection-${id}`\n );\n\n return (\n \n \n \n \n \n \n \n \n \n\n
\n \n \n\n \n \n \n \n \n \n \n\n \n \n \n \n\n \n \n \n
\n
\n
\n );\n}\n\nconst DemoIdContext = React.createContext(undefined);\n\nexport function DemoId({\n id,\n children,\n}: {\n children: React.ReactNode;\n id?: string;\n}) {\n return {children};\n}\n\nexport function useDemoId() {\n return React.useContext(DemoIdContext);\n}\n", "path": "example/playground-demo.tsx", "target": "components/playground-demo.tsx", "type": "registry:example" diff --git a/apps/www/public/r/styles/default/block-selection-demo.json b/apps/www/public/r/styles/default/block-selection-demo.json index 334a0a12b0..ac573d5563 100644 --- a/apps/www/public/r/styles/default/block-selection-demo.json +++ b/apps/www/public/r/styles/default/block-selection-demo.json @@ -4,7 +4,7 @@ }, "files": [ { - "content": "'use client';\n\nimport React, { useRef } from 'react';\n\nimport type { ValueId } from '@/config/customizer-plugins';\n\nimport { cn } from '@udecode/cn';\nimport { AIChatPlugin, CopilotPlugin } from '@udecode/plate-ai/react';\nimport { AlignPlugin } from '@udecode/plate-alignment/react';\nimport { AutoformatPlugin } from '@udecode/plate-autoformat/react';\nimport {\n BoldPlugin,\n CodePlugin,\n ItalicPlugin,\n StrikethroughPlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n UnderlinePlugin,\n} from '@udecode/plate-basic-marks/react';\nimport { BlockquotePlugin } from '@udecode/plate-block-quote/react';\nimport { SingleLinePlugin } from '@udecode/plate-break/react';\nimport { CaptionPlugin } from '@udecode/plate-caption/react';\nimport { CodeBlockPlugin } from '@udecode/plate-code-block/react';\nimport { CommentsPlugin } from '@udecode/plate-comments/react';\nimport {\n ParagraphPlugin,\n Plate,\n usePlateEditor,\n} from '@udecode/plate-common/react';\nimport { DatePlugin } from '@udecode/plate-date/react';\nimport { DndPlugin } from '@udecode/plate-dnd';\nimport { DocxPlugin } from '@udecode/plate-docx';\nimport { EmojiPlugin } from '@udecode/plate-emoji/react';\nimport { ExcalidrawPlugin } from '@udecode/plate-excalidraw/react';\nimport {\n FontBackgroundColorPlugin,\n FontColorPlugin,\n FontSizePlugin,\n} from '@udecode/plate-font/react';\nimport { HEADING_KEYS } from '@udecode/plate-heading';\nimport { HeadingPlugin, TocPlugin } from '@udecode/plate-heading/react';\nimport { HighlightPlugin } from '@udecode/plate-highlight/react';\nimport { HorizontalRulePlugin } from '@udecode/plate-horizontal-rule/react';\nimport { IndentPlugin } from '@udecode/plate-indent/react';\nimport { IndentListPlugin } from '@udecode/plate-indent-list/react';\nimport { JuicePlugin } from '@udecode/plate-juice';\nimport { KbdPlugin } from '@udecode/plate-kbd/react';\nimport { ColumnPlugin } from '@udecode/plate-layout/react';\nimport { LineHeightPlugin } from '@udecode/plate-line-height/react';\nimport { LinkPlugin } from '@udecode/plate-link/react';\nimport { ListPlugin, TodoListPlugin } from '@udecode/plate-list/react';\nimport { MarkdownPlugin } from '@udecode/plate-markdown';\nimport { ImagePlugin, MediaEmbedPlugin } from '@udecode/plate-media/react';\nimport { MentionPlugin } from '@udecode/plate-mention/react';\nimport { NodeIdPlugin } from '@udecode/plate-node-id';\nimport { NormalizeTypesPlugin } from '@udecode/plate-normalizers';\nimport { PlaywrightPlugin } from '@udecode/plate-playwright';\nimport { DeletePlugin, SelectOnBackspacePlugin } from '@udecode/plate-select';\nimport {\n BlockMenuPlugin,\n BlockSelectionPlugin,\n} from '@udecode/plate-selection/react';\nimport { SlashPlugin } from '@udecode/plate-slash-command/react';\nimport { TablePlugin } from '@udecode/plate-table/react';\nimport { TogglePlugin } from '@udecode/plate-toggle/react';\nimport { TrailingBlockPlugin } from '@udecode/plate-trailing-block';\nimport Prism from 'prismjs';\n\nimport { CheckPlugin } from '@/components/context/check-plugin';\nimport { settingsStore } from '@/components/context/settings-store';\nimport { aiPlugins } from '@/lib/plate/demo/plugins/ai-plugins';\nimport { getAutoformatOptions } from '@/lib/plate/demo/plugins/autoformatOptions';\nimport { copilotPlugins } from '@/lib/plate/demo/plugins/copilot-plugins';\nimport { createPlateUI } from '@/plate/create-plate-ui';\nimport { editableProps } from '@/plate/demo/editableProps';\nimport { isEnabled } from '@/plate/demo/is-enabled';\nimport { DragOverCursorPlugin } from '@/plate/demo/plugins/DragOverCursorPlugin';\nimport { exitBreakPlugin } from '@/plate/demo/plugins/exitBreakPlugin';\nimport { resetBlockTypePlugin } from '@/plate/demo/plugins/resetBlockTypePlugin';\nimport { softBreakPlugin } from '@/plate/demo/plugins/softBreakPlugin';\nimport { tabbablePlugin } from '@/plate/demo/plugins/tabbablePlugin';\nimport { commentsData, usersData } from '@/plate/demo/values/commentsValue';\nimport { usePlaygroundValue } from '@/plate/demo/values/usePlaygroundValue';\nimport { BlockContextMenu } from '@/components/plate-ui/block-context-menu';\nimport { CommentsPopover } from '@/components/plate-ui/comments-popover';\nimport {\n CursorOverlay,\n SelectionOverlayPlugin,\n} from '@/components/plate-ui/cursor-overlay';\nimport { Editor, EditorContainer } from '@/components/plate-ui/editor';\nimport { FixedToolbar } from '@/components/plate-ui/fixed-toolbar';\nimport { FixedToolbarButtons } from '@/components/plate-ui/fixed-toolbar-buttons';\nimport { FloatingToolbar } from '@/components/plate-ui/floating-toolbar';\nimport { FloatingToolbarButtons } from '@/components/plate-ui/floating-toolbar-buttons';\nimport { ImagePreview } from '@/components/plate-ui/image-preview';\nimport {\n FireLiComponent,\n FireMarker,\n} from '@/components/plate-ui/indent-fire-marker';\nimport {\n TodoLi,\n TodoMarker,\n} from '@/components/plate-ui/indent-todo-marker';\nimport { LinkFloatingToolbar } from '@/components/plate-ui/link-floating-toolbar';\n\nimport { usePlaygroundEnabled } from './usePlaygroundEnabled';\n\nexport const usePlaygroundEditor = (id: any = '', scrollSelector?: string) => {\n const enabledPlugins = settingsStore.use.checkedPlugins();\n const overridePlugins = usePlaygroundEnabled(id);\n const autoformatOptions = getAutoformatOptions(id, enabledPlugins);\n\n const value = usePlaygroundValue(id);\n const key = settingsStore.use.version();\n const editorId = id || 'playground-' + key;\n\n return usePlateEditor(\n {\n id: editorId,\n override: {\n components: createPlateUI({\n draggable: isEnabled('dnd', id),\n placeholder: isEnabled('placeholder', id),\n }),\n plugins: overridePlugins,\n },\n plugins: [\n // AI\n ...(id === 'ai' || enabledPlugins[AIChatPlugin.key] ? aiPlugins : []),\n ...(id === 'copilot' || enabledPlugins[CopilotPlugin.key]\n ? copilotPlugins\n : []),\n // Nodes\n HeadingPlugin,\n TocPlugin.configure({\n options: {\n scrollContainerSelector: `#${scrollSelector}`,\n topOffset: 80,\n },\n }),\n BlockquotePlugin,\n CodeBlockPlugin.configure({\n options: {\n prism: Prism,\n },\n }),\n HorizontalRulePlugin,\n LinkPlugin.extend({\n render: { afterEditable: () => },\n }),\n ...(id === 'list' ? [ListPlugin] : []),\n ImagePlugin.extend({\n render: { afterEditable: ImagePreview },\n }),\n MediaEmbedPlugin,\n CaptionPlugin.configure({\n options: {\n plugins: [ImagePlugin, MediaEmbedPlugin],\n },\n }),\n DatePlugin,\n MentionPlugin.configure({\n options: {\n triggerPreviousCharPattern: /^$|^[\\s\"']$/,\n },\n }),\n SlashPlugin,\n TablePlugin.configure({\n options: {\n enableMerging: id === 'tableMerge',\n },\n }),\n ColumnPlugin,\n SelectionOverlayPlugin,\n\n TodoListPlugin,\n TogglePlugin,\n ExcalidrawPlugin,\n // Marks\n BoldPlugin,\n ItalicPlugin,\n UnderlinePlugin,\n StrikethroughPlugin,\n CodePlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n FontColorPlugin,\n FontBackgroundColorPlugin,\n FontSizePlugin,\n HighlightPlugin,\n KbdPlugin,\n\n // Block Style\n AlignPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n MediaEmbedPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n ImagePlugin.key,\n HEADING_KEYS.h6,\n ],\n },\n }),\n IndentPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n }),\n IndentListPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n options: {\n listStyleTypes: {\n fire: {\n liComponent: FireLiComponent,\n markerComponent: FireMarker,\n type: 'fire',\n },\n todo: {\n liComponent: TodoLi,\n markerComponent: TodoMarker,\n type: 'todo',\n },\n },\n },\n }),\n LineHeightPlugin.extend({\n inject: {\n nodeProps: {\n defaultNodeValue: 1.5,\n validNodeValues: [1, 1.2, 1.5, 2, 3],\n },\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n ],\n },\n }),\n\n // Functionality\n AutoformatPlugin.configure({\n options: autoformatOptions,\n }),\n BlockSelectionPlugin.configure({\n options: {\n areaOptions: {\n behaviour: {\n scrolling: {\n speedDivider: 1.5,\n },\n startThreshold: 10,\n },\n boundaries: `#${scrollSelector}`,\n container: `#${scrollSelector}`,\n selectables: [`#${scrollSelector} .slate-selectable`],\n selectionAreaClass: 'slate-selection-area',\n },\n enableContextMenu: true,\n },\n }),\n BlockMenuPlugin.configure({\n render: { aboveEditable: BlockContextMenu },\n }),\n DndPlugin.configure({ options: { enableScroller: true } }),\n EmojiPlugin,\n exitBreakPlugin,\n NodeIdPlugin,\n NormalizeTypesPlugin.configure({\n options: {\n rules: [{ path: [0], strictType: HEADING_KEYS.h1 }],\n },\n }),\n resetBlockTypePlugin,\n SelectOnBackspacePlugin.configure({\n options: {\n query: {\n allow: [ImagePlugin.key, HorizontalRulePlugin.key],\n },\n },\n }),\n DeletePlugin,\n SingleLinePlugin,\n softBreakPlugin,\n tabbablePlugin,\n TrailingBlockPlugin.configure({\n options: { type: ParagraphPlugin.key },\n }),\n DragOverCursorPlugin,\n\n // Collaboration\n CommentsPlugin.configure({\n options: {\n comments: commentsData,\n myUserId: '1',\n users: usersData,\n },\n }),\n\n // Deserialization\n DocxPlugin,\n MarkdownPlugin.configure({ options: { indentList: true } }),\n JuicePlugin,\n\n // Testing\n PlaywrightPlugin.configure({\n enabled: process.env.NODE_ENV !== 'production',\n }),\n ],\n value: value,\n },\n []\n );\n};\n\nexport default function PlaygroundDemo({\n id,\n className,\n scrollSelector,\n}: {\n id?: ValueId;\n className?: string;\n scrollSelector?: string;\n}) {\n const containerRef = useRef(null);\n const enabled = settingsStore.use.checkedComponents();\n\n const editor = usePlaygroundEditor(\n id,\n scrollSelector ?? `blockSelection-${id}`\n );\n\n return (\n \n \n \n \n \n \n \n \n \n\n
\n \n \n\n \n \n \n \n \n \n \n\n \n \n \n \n\n \n \n \n
\n
\n
\n );\n}\n\nconst DemoIdContext = React.createContext(undefined);\n\nexport function DemoId({\n id,\n children,\n}: {\n children: React.ReactNode;\n id?: string;\n}) {\n return {children};\n}\n\nexport function useDemoId() {\n return React.useContext(DemoIdContext);\n}\n", + "content": "'use client';\n\nimport React, { useRef } from 'react';\n\nimport type { ValueId } from '@/config/customizer-plugins';\n\nimport { cn } from '@udecode/cn';\nimport { AIChatPlugin, CopilotPlugin } from '@udecode/plate-ai/react';\nimport { AlignPlugin } from '@udecode/plate-alignment/react';\nimport { AutoformatPlugin } from '@udecode/plate-autoformat/react';\nimport {\n BoldPlugin,\n CodePlugin,\n ItalicPlugin,\n StrikethroughPlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n UnderlinePlugin,\n} from '@udecode/plate-basic-marks/react';\nimport { BlockquotePlugin } from '@udecode/plate-block-quote/react';\nimport { SingleLinePlugin } from '@udecode/plate-break/react';\nimport { CaptionPlugin } from '@udecode/plate-caption/react';\nimport { CodeBlockPlugin } from '@udecode/plate-code-block/react';\nimport { CommentsPlugin } from '@udecode/plate-comments/react';\nimport {\n ParagraphPlugin,\n Plate,\n usePlateEditor,\n} from '@udecode/plate-common/react';\nimport { DatePlugin } from '@udecode/plate-date/react';\nimport { DndPlugin } from '@udecode/plate-dnd';\nimport { DocxPlugin } from '@udecode/plate-docx';\nimport { EmojiPlugin } from '@udecode/plate-emoji/react';\nimport { ExcalidrawPlugin } from '@udecode/plate-excalidraw/react';\nimport {\n FontBackgroundColorPlugin,\n FontColorPlugin,\n FontSizePlugin,\n} from '@udecode/plate-font/react';\nimport { HEADING_KEYS } from '@udecode/plate-heading';\nimport { HeadingPlugin, TocPlugin } from '@udecode/plate-heading/react';\nimport { HighlightPlugin } from '@udecode/plate-highlight/react';\nimport { HorizontalRulePlugin } from '@udecode/plate-horizontal-rule/react';\nimport { IndentPlugin } from '@udecode/plate-indent/react';\nimport { IndentListPlugin } from '@udecode/plate-indent-list/react';\nimport { JuicePlugin } from '@udecode/plate-juice';\nimport { KbdPlugin } from '@udecode/plate-kbd/react';\nimport { ColumnPlugin } from '@udecode/plate-layout/react';\nimport { LineHeightPlugin } from '@udecode/plate-line-height/react';\nimport { LinkPlugin } from '@udecode/plate-link/react';\nimport { ListPlugin, TodoListPlugin } from '@udecode/plate-list/react';\nimport { MarkdownPlugin } from '@udecode/plate-markdown';\nimport { ImagePlugin, MediaEmbedPlugin } from '@udecode/plate-media/react';\nimport { MentionPlugin } from '@udecode/plate-mention/react';\nimport { NodeIdPlugin } from '@udecode/plate-node-id';\nimport { NormalizeTypesPlugin } from '@udecode/plate-normalizers';\nimport { PlaywrightPlugin } from '@udecode/plate-playwright';\nimport { DeletePlugin, SelectOnBackspacePlugin } from '@udecode/plate-select';\nimport {\n BlockMenuPlugin,\n BlockSelectionPlugin,\n} from '@udecode/plate-selection/react';\nimport { SlashPlugin } from '@udecode/plate-slash-command/react';\nimport { TablePlugin } from '@udecode/plate-table/react';\nimport { TogglePlugin } from '@udecode/plate-toggle/react';\nimport { TrailingBlockPlugin } from '@udecode/plate-trailing-block';\nimport Prism from 'prismjs';\n\nimport { CheckPlugin } from '@/components/context/check-plugin';\nimport { settingsStore } from '@/components/context/settings-store';\nimport { aiPlugins } from '@/lib/plate/demo/plugins/ai-plugins';\nimport { getAutoformatOptions } from '@/lib/plate/demo/plugins/autoformatOptions';\nimport { copilotPlugins } from '@/lib/plate/demo/plugins/copilot-plugins';\nimport { createPlateUI } from '@/plate/create-plate-ui';\nimport { editableProps } from '@/plate/demo/editableProps';\nimport { isEnabled } from '@/plate/demo/is-enabled';\nimport { DragOverCursorPlugin } from '@/plate/demo/plugins/DragOverCursorPlugin';\nimport { exitBreakPlugin } from '@/plate/demo/plugins/exitBreakPlugin';\nimport { resetBlockTypePlugin } from '@/plate/demo/plugins/resetBlockTypePlugin';\nimport { softBreakPlugin } from '@/plate/demo/plugins/softBreakPlugin';\nimport { tabbablePlugin } from '@/plate/demo/plugins/tabbablePlugin';\nimport { commentsData, usersData } from '@/plate/demo/values/commentsValue';\nimport { usePlaygroundValue } from '@/plate/demo/values/usePlaygroundValue';\nimport { BlockContextMenu } from '@/components/plate-ui/block-context-menu';\nimport { CommentsPopover } from '@/components/plate-ui/comments-popover';\nimport {\n CursorOverlay,\n SelectionOverlayPlugin,\n} from '@/components/plate-ui/cursor-overlay';\nimport { Editor, EditorContainer } from '@/components/plate-ui/editor';\nimport { FixedToolbar } from '@/components/plate-ui/fixed-toolbar';\nimport { FixedToolbarButtons } from '@/components/plate-ui/fixed-toolbar-buttons';\nimport { FloatingToolbar } from '@/components/plate-ui/floating-toolbar';\nimport { FloatingToolbarButtons } from '@/components/plate-ui/floating-toolbar-buttons';\nimport { ImagePreview } from '@/components/plate-ui/image-preview';\nimport {\n FireLiComponent,\n FireMarker,\n} from '@/components/plate-ui/indent-fire-marker';\nimport {\n TodoLi,\n TodoMarker,\n} from '@/components/plate-ui/indent-todo-marker';\nimport { LinkFloatingToolbar } from '@/components/plate-ui/link-floating-toolbar';\n\nimport { usePlaygroundEnabled } from './usePlaygroundEnabled';\n\nexport const usePlaygroundEditor = (id: any = '', scrollSelector?: string) => {\n const enabledPlugins = settingsStore.use.checkedPlugins();\n const overridePlugins = usePlaygroundEnabled(id);\n const autoformatOptions = getAutoformatOptions(id, enabledPlugins);\n\n const value = usePlaygroundValue(id);\n const key = settingsStore.use.version();\n const editorId = id || 'playground-' + key;\n\n return usePlateEditor(\n {\n id: editorId,\n override: {\n components: createPlateUI({\n draggable: isEnabled('dnd', id),\n placeholder: isEnabled('placeholder', id),\n }),\n plugins: overridePlugins,\n },\n plugins: [\n // AI\n ...(id === 'ai' || enabledPlugins[AIChatPlugin.key] ? aiPlugins : []),\n ...(id === 'copilot' || enabledPlugins[CopilotPlugin.key]\n ? copilotPlugins\n : []),\n // Nodes\n HeadingPlugin,\n TocPlugin.configure({\n options: {\n scrollContainerSelector: `#${scrollSelector}`,\n topOffset: 80,\n },\n }),\n BlockquotePlugin,\n CodeBlockPlugin.configure({\n options: {\n prism: Prism,\n },\n }),\n HorizontalRulePlugin,\n LinkPlugin.extend({\n render: { afterEditable: () => },\n }),\n ...(id === 'list' ? [ListPlugin] : []),\n ImagePlugin.extend({\n options: {\n disableUploadInsert: true,\n },\n render: { afterEditable: ImagePreview },\n }),\n MediaEmbedPlugin,\n CaptionPlugin.configure({\n options: {\n plugins: [ImagePlugin, MediaEmbedPlugin],\n },\n }),\n DatePlugin,\n MentionPlugin.configure({\n options: {\n triggerPreviousCharPattern: /^$|^[\\s\"']$/,\n },\n }),\n SlashPlugin,\n TablePlugin.configure({\n options: {\n enableMerging: id === 'tableMerge',\n },\n }),\n ColumnPlugin,\n SelectionOverlayPlugin,\n\n TodoListPlugin,\n TogglePlugin,\n ExcalidrawPlugin,\n // Marks\n BoldPlugin,\n ItalicPlugin,\n UnderlinePlugin,\n StrikethroughPlugin,\n CodePlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n FontColorPlugin,\n FontBackgroundColorPlugin,\n FontSizePlugin,\n HighlightPlugin,\n KbdPlugin,\n\n // Block Style\n AlignPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n MediaEmbedPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n ImagePlugin.key,\n HEADING_KEYS.h6,\n ],\n },\n }),\n IndentPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n }),\n IndentListPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n options: {\n listStyleTypes: {\n fire: {\n liComponent: FireLiComponent,\n markerComponent: FireMarker,\n type: 'fire',\n },\n todo: {\n liComponent: TodoLi,\n markerComponent: TodoMarker,\n type: 'todo',\n },\n },\n },\n }),\n LineHeightPlugin.extend({\n inject: {\n nodeProps: {\n defaultNodeValue: 1.5,\n validNodeValues: [1, 1.2, 1.5, 2, 3],\n },\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n ],\n },\n }),\n\n // Functionality\n AutoformatPlugin.configure({\n options: autoformatOptions,\n }),\n BlockSelectionPlugin.configure({\n options: {\n areaOptions: {\n behaviour: {\n scrolling: {\n speedDivider: 1.5,\n },\n startThreshold: 10,\n },\n boundaries: `#${scrollSelector}`,\n container: `#${scrollSelector}`,\n selectables: [`#${scrollSelector} .slate-selectable`],\n selectionAreaClass: 'slate-selection-area',\n },\n enableContextMenu: true,\n },\n }),\n BlockMenuPlugin.configure({\n render: { aboveEditable: BlockContextMenu },\n }),\n DndPlugin.configure({\n options: {\n enableScroller: true,\n onDropFiles: ({ dragItem, editor, target }) => {\n editor\n .getTransforms(ImagePlugin)\n .insertImageFromFiles(dragItem.files, {\n at: target,\n nextBlock: false,\n });\n },\n },\n }),\n EmojiPlugin,\n exitBreakPlugin,\n NodeIdPlugin,\n NormalizeTypesPlugin.configure({\n options: {\n rules: [{ path: [0], strictType: HEADING_KEYS.h1 }],\n },\n }),\n resetBlockTypePlugin,\n SelectOnBackspacePlugin.configure({\n options: {\n query: {\n allow: [ImagePlugin.key, HorizontalRulePlugin.key],\n },\n },\n }),\n DeletePlugin,\n SingleLinePlugin,\n softBreakPlugin,\n tabbablePlugin,\n TrailingBlockPlugin.configure({\n options: { type: ParagraphPlugin.key },\n }),\n DragOverCursorPlugin,\n\n // Collaboration\n CommentsPlugin.configure({\n options: {\n comments: commentsData,\n myUserId: '1',\n users: usersData,\n },\n }),\n\n // Deserialization\n DocxPlugin,\n MarkdownPlugin.configure({ options: { indentList: true } }),\n JuicePlugin,\n\n // Testing\n PlaywrightPlugin.configure({\n enabled: process.env.NODE_ENV !== 'production',\n }),\n ],\n value: value,\n },\n []\n );\n};\n\nexport default function PlaygroundDemo({\n id,\n className,\n scrollSelector,\n}: {\n id?: ValueId;\n className?: string;\n scrollSelector?: string;\n}) {\n const containerRef = useRef(null);\n const enabled = settingsStore.use.checkedComponents();\n\n const editor = usePlaygroundEditor(\n id,\n scrollSelector ?? `blockSelection-${id}`\n );\n\n return (\n \n \n \n \n \n \n \n \n \n\n
\n \n \n\n \n \n \n \n \n \n \n\n \n \n \n \n\n \n \n \n
\n
\n
\n );\n}\n\nconst DemoIdContext = React.createContext(undefined);\n\nexport function DemoId({\n id,\n children,\n}: {\n children: React.ReactNode;\n id?: string;\n}) {\n return {children};\n}\n\nexport function useDemoId() {\n return React.useContext(DemoIdContext);\n}\n", "path": "example/playground-demo.tsx", "target": "components/playground-demo.tsx", "type": "registry:example" diff --git a/apps/www/public/r/styles/default/column-demo.json b/apps/www/public/r/styles/default/column-demo.json index b5abebd582..645c7dd781 100644 --- a/apps/www/public/r/styles/default/column-demo.json +++ b/apps/www/public/r/styles/default/column-demo.json @@ -4,7 +4,7 @@ }, "files": [ { - "content": "'use client';\n\nimport React, { useRef } from 'react';\n\nimport type { ValueId } from '@/config/customizer-plugins';\n\nimport { cn } from '@udecode/cn';\nimport { AIChatPlugin, CopilotPlugin } from '@udecode/plate-ai/react';\nimport { AlignPlugin } from '@udecode/plate-alignment/react';\nimport { AutoformatPlugin } from '@udecode/plate-autoformat/react';\nimport {\n BoldPlugin,\n CodePlugin,\n ItalicPlugin,\n StrikethroughPlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n UnderlinePlugin,\n} from '@udecode/plate-basic-marks/react';\nimport { BlockquotePlugin } from '@udecode/plate-block-quote/react';\nimport { SingleLinePlugin } from '@udecode/plate-break/react';\nimport { CaptionPlugin } from '@udecode/plate-caption/react';\nimport { CodeBlockPlugin } from '@udecode/plate-code-block/react';\nimport { CommentsPlugin } from '@udecode/plate-comments/react';\nimport {\n ParagraphPlugin,\n Plate,\n usePlateEditor,\n} from '@udecode/plate-common/react';\nimport { DatePlugin } from '@udecode/plate-date/react';\nimport { DndPlugin } from '@udecode/plate-dnd';\nimport { DocxPlugin } from '@udecode/plate-docx';\nimport { EmojiPlugin } from '@udecode/plate-emoji/react';\nimport { ExcalidrawPlugin } from '@udecode/plate-excalidraw/react';\nimport {\n FontBackgroundColorPlugin,\n FontColorPlugin,\n FontSizePlugin,\n} from '@udecode/plate-font/react';\nimport { HEADING_KEYS } from '@udecode/plate-heading';\nimport { HeadingPlugin, TocPlugin } from '@udecode/plate-heading/react';\nimport { HighlightPlugin } from '@udecode/plate-highlight/react';\nimport { HorizontalRulePlugin } from '@udecode/plate-horizontal-rule/react';\nimport { IndentPlugin } from '@udecode/plate-indent/react';\nimport { IndentListPlugin } from '@udecode/plate-indent-list/react';\nimport { JuicePlugin } from '@udecode/plate-juice';\nimport { KbdPlugin } from '@udecode/plate-kbd/react';\nimport { ColumnPlugin } from '@udecode/plate-layout/react';\nimport { LineHeightPlugin } from '@udecode/plate-line-height/react';\nimport { LinkPlugin } from '@udecode/plate-link/react';\nimport { ListPlugin, TodoListPlugin } from '@udecode/plate-list/react';\nimport { MarkdownPlugin } from '@udecode/plate-markdown';\nimport { ImagePlugin, MediaEmbedPlugin } from '@udecode/plate-media/react';\nimport { MentionPlugin } from '@udecode/plate-mention/react';\nimport { NodeIdPlugin } from '@udecode/plate-node-id';\nimport { NormalizeTypesPlugin } from '@udecode/plate-normalizers';\nimport { PlaywrightPlugin } from '@udecode/plate-playwright';\nimport { DeletePlugin, SelectOnBackspacePlugin } from '@udecode/plate-select';\nimport {\n BlockMenuPlugin,\n BlockSelectionPlugin,\n} from '@udecode/plate-selection/react';\nimport { SlashPlugin } from '@udecode/plate-slash-command/react';\nimport { TablePlugin } from '@udecode/plate-table/react';\nimport { TogglePlugin } from '@udecode/plate-toggle/react';\nimport { TrailingBlockPlugin } from '@udecode/plate-trailing-block';\nimport Prism from 'prismjs';\n\nimport { CheckPlugin } from '@/components/context/check-plugin';\nimport { settingsStore } from '@/components/context/settings-store';\nimport { aiPlugins } from '@/lib/plate/demo/plugins/ai-plugins';\nimport { getAutoformatOptions } from '@/lib/plate/demo/plugins/autoformatOptions';\nimport { copilotPlugins } from '@/lib/plate/demo/plugins/copilot-plugins';\nimport { createPlateUI } from '@/plate/create-plate-ui';\nimport { editableProps } from '@/plate/demo/editableProps';\nimport { isEnabled } from '@/plate/demo/is-enabled';\nimport { DragOverCursorPlugin } from '@/plate/demo/plugins/DragOverCursorPlugin';\nimport { exitBreakPlugin } from '@/plate/demo/plugins/exitBreakPlugin';\nimport { resetBlockTypePlugin } from '@/plate/demo/plugins/resetBlockTypePlugin';\nimport { softBreakPlugin } from '@/plate/demo/plugins/softBreakPlugin';\nimport { tabbablePlugin } from '@/plate/demo/plugins/tabbablePlugin';\nimport { commentsData, usersData } from '@/plate/demo/values/commentsValue';\nimport { usePlaygroundValue } from '@/plate/demo/values/usePlaygroundValue';\nimport { BlockContextMenu } from '@/components/plate-ui/block-context-menu';\nimport { CommentsPopover } from '@/components/plate-ui/comments-popover';\nimport {\n CursorOverlay,\n SelectionOverlayPlugin,\n} from '@/components/plate-ui/cursor-overlay';\nimport { Editor, EditorContainer } from '@/components/plate-ui/editor';\nimport { FixedToolbar } from '@/components/plate-ui/fixed-toolbar';\nimport { FixedToolbarButtons } from '@/components/plate-ui/fixed-toolbar-buttons';\nimport { FloatingToolbar } from '@/components/plate-ui/floating-toolbar';\nimport { FloatingToolbarButtons } from '@/components/plate-ui/floating-toolbar-buttons';\nimport { ImagePreview } from '@/components/plate-ui/image-preview';\nimport {\n FireLiComponent,\n FireMarker,\n} from '@/components/plate-ui/indent-fire-marker';\nimport {\n TodoLi,\n TodoMarker,\n} from '@/components/plate-ui/indent-todo-marker';\nimport { LinkFloatingToolbar } from '@/components/plate-ui/link-floating-toolbar';\n\nimport { usePlaygroundEnabled } from './usePlaygroundEnabled';\n\nexport const usePlaygroundEditor = (id: any = '', scrollSelector?: string) => {\n const enabledPlugins = settingsStore.use.checkedPlugins();\n const overridePlugins = usePlaygroundEnabled(id);\n const autoformatOptions = getAutoformatOptions(id, enabledPlugins);\n\n const value = usePlaygroundValue(id);\n const key = settingsStore.use.version();\n const editorId = id || 'playground-' + key;\n\n return usePlateEditor(\n {\n id: editorId,\n override: {\n components: createPlateUI({\n draggable: isEnabled('dnd', id),\n placeholder: isEnabled('placeholder', id),\n }),\n plugins: overridePlugins,\n },\n plugins: [\n // AI\n ...(id === 'ai' || enabledPlugins[AIChatPlugin.key] ? aiPlugins : []),\n ...(id === 'copilot' || enabledPlugins[CopilotPlugin.key]\n ? copilotPlugins\n : []),\n // Nodes\n HeadingPlugin,\n TocPlugin.configure({\n options: {\n scrollContainerSelector: `#${scrollSelector}`,\n topOffset: 80,\n },\n }),\n BlockquotePlugin,\n CodeBlockPlugin.configure({\n options: {\n prism: Prism,\n },\n }),\n HorizontalRulePlugin,\n LinkPlugin.extend({\n render: { afterEditable: () => },\n }),\n ...(id === 'list' ? [ListPlugin] : []),\n ImagePlugin.extend({\n render: { afterEditable: ImagePreview },\n }),\n MediaEmbedPlugin,\n CaptionPlugin.configure({\n options: {\n plugins: [ImagePlugin, MediaEmbedPlugin],\n },\n }),\n DatePlugin,\n MentionPlugin.configure({\n options: {\n triggerPreviousCharPattern: /^$|^[\\s\"']$/,\n },\n }),\n SlashPlugin,\n TablePlugin.configure({\n options: {\n enableMerging: id === 'tableMerge',\n },\n }),\n ColumnPlugin,\n SelectionOverlayPlugin,\n\n TodoListPlugin,\n TogglePlugin,\n ExcalidrawPlugin,\n // Marks\n BoldPlugin,\n ItalicPlugin,\n UnderlinePlugin,\n StrikethroughPlugin,\n CodePlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n FontColorPlugin,\n FontBackgroundColorPlugin,\n FontSizePlugin,\n HighlightPlugin,\n KbdPlugin,\n\n // Block Style\n AlignPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n MediaEmbedPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n ImagePlugin.key,\n HEADING_KEYS.h6,\n ],\n },\n }),\n IndentPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n }),\n IndentListPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n options: {\n listStyleTypes: {\n fire: {\n liComponent: FireLiComponent,\n markerComponent: FireMarker,\n type: 'fire',\n },\n todo: {\n liComponent: TodoLi,\n markerComponent: TodoMarker,\n type: 'todo',\n },\n },\n },\n }),\n LineHeightPlugin.extend({\n inject: {\n nodeProps: {\n defaultNodeValue: 1.5,\n validNodeValues: [1, 1.2, 1.5, 2, 3],\n },\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n ],\n },\n }),\n\n // Functionality\n AutoformatPlugin.configure({\n options: autoformatOptions,\n }),\n BlockSelectionPlugin.configure({\n options: {\n areaOptions: {\n behaviour: {\n scrolling: {\n speedDivider: 1.5,\n },\n startThreshold: 10,\n },\n boundaries: `#${scrollSelector}`,\n container: `#${scrollSelector}`,\n selectables: [`#${scrollSelector} .slate-selectable`],\n selectionAreaClass: 'slate-selection-area',\n },\n enableContextMenu: true,\n },\n }),\n BlockMenuPlugin.configure({\n render: { aboveEditable: BlockContextMenu },\n }),\n DndPlugin.configure({ options: { enableScroller: true } }),\n EmojiPlugin,\n exitBreakPlugin,\n NodeIdPlugin,\n NormalizeTypesPlugin.configure({\n options: {\n rules: [{ path: [0], strictType: HEADING_KEYS.h1 }],\n },\n }),\n resetBlockTypePlugin,\n SelectOnBackspacePlugin.configure({\n options: {\n query: {\n allow: [ImagePlugin.key, HorizontalRulePlugin.key],\n },\n },\n }),\n DeletePlugin,\n SingleLinePlugin,\n softBreakPlugin,\n tabbablePlugin,\n TrailingBlockPlugin.configure({\n options: { type: ParagraphPlugin.key },\n }),\n DragOverCursorPlugin,\n\n // Collaboration\n CommentsPlugin.configure({\n options: {\n comments: commentsData,\n myUserId: '1',\n users: usersData,\n },\n }),\n\n // Deserialization\n DocxPlugin,\n MarkdownPlugin.configure({ options: { indentList: true } }),\n JuicePlugin,\n\n // Testing\n PlaywrightPlugin.configure({\n enabled: process.env.NODE_ENV !== 'production',\n }),\n ],\n value: value,\n },\n []\n );\n};\n\nexport default function PlaygroundDemo({\n id,\n className,\n scrollSelector,\n}: {\n id?: ValueId;\n className?: string;\n scrollSelector?: string;\n}) {\n const containerRef = useRef(null);\n const enabled = settingsStore.use.checkedComponents();\n\n const editor = usePlaygroundEditor(\n id,\n scrollSelector ?? `blockSelection-${id}`\n );\n\n return (\n \n \n \n \n \n \n \n \n \n\n
\n \n \n\n \n \n \n \n \n \n \n\n \n \n \n \n\n \n \n \n
\n
\n
\n );\n}\n\nconst DemoIdContext = React.createContext(undefined);\n\nexport function DemoId({\n id,\n children,\n}: {\n children: React.ReactNode;\n id?: string;\n}) {\n return {children};\n}\n\nexport function useDemoId() {\n return React.useContext(DemoIdContext);\n}\n", + "content": "'use client';\n\nimport React, { useRef } from 'react';\n\nimport type { ValueId } from '@/config/customizer-plugins';\n\nimport { cn } from '@udecode/cn';\nimport { AIChatPlugin, CopilotPlugin } from '@udecode/plate-ai/react';\nimport { AlignPlugin } from '@udecode/plate-alignment/react';\nimport { AutoformatPlugin } from '@udecode/plate-autoformat/react';\nimport {\n BoldPlugin,\n CodePlugin,\n ItalicPlugin,\n StrikethroughPlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n UnderlinePlugin,\n} from '@udecode/plate-basic-marks/react';\nimport { BlockquotePlugin } from '@udecode/plate-block-quote/react';\nimport { SingleLinePlugin } from '@udecode/plate-break/react';\nimport { CaptionPlugin } from '@udecode/plate-caption/react';\nimport { CodeBlockPlugin } from '@udecode/plate-code-block/react';\nimport { CommentsPlugin } from '@udecode/plate-comments/react';\nimport {\n ParagraphPlugin,\n Plate,\n usePlateEditor,\n} from '@udecode/plate-common/react';\nimport { DatePlugin } from '@udecode/plate-date/react';\nimport { DndPlugin } from '@udecode/plate-dnd';\nimport { DocxPlugin } from '@udecode/plate-docx';\nimport { EmojiPlugin } from '@udecode/plate-emoji/react';\nimport { ExcalidrawPlugin } from '@udecode/plate-excalidraw/react';\nimport {\n FontBackgroundColorPlugin,\n FontColorPlugin,\n FontSizePlugin,\n} from '@udecode/plate-font/react';\nimport { HEADING_KEYS } from '@udecode/plate-heading';\nimport { HeadingPlugin, TocPlugin } from '@udecode/plate-heading/react';\nimport { HighlightPlugin } from '@udecode/plate-highlight/react';\nimport { HorizontalRulePlugin } from '@udecode/plate-horizontal-rule/react';\nimport { IndentPlugin } from '@udecode/plate-indent/react';\nimport { IndentListPlugin } from '@udecode/plate-indent-list/react';\nimport { JuicePlugin } from '@udecode/plate-juice';\nimport { KbdPlugin } from '@udecode/plate-kbd/react';\nimport { ColumnPlugin } from '@udecode/plate-layout/react';\nimport { LineHeightPlugin } from '@udecode/plate-line-height/react';\nimport { LinkPlugin } from '@udecode/plate-link/react';\nimport { ListPlugin, TodoListPlugin } from '@udecode/plate-list/react';\nimport { MarkdownPlugin } from '@udecode/plate-markdown';\nimport { ImagePlugin, MediaEmbedPlugin } from '@udecode/plate-media/react';\nimport { MentionPlugin } from '@udecode/plate-mention/react';\nimport { NodeIdPlugin } from '@udecode/plate-node-id';\nimport { NormalizeTypesPlugin } from '@udecode/plate-normalizers';\nimport { PlaywrightPlugin } from '@udecode/plate-playwright';\nimport { DeletePlugin, SelectOnBackspacePlugin } from '@udecode/plate-select';\nimport {\n BlockMenuPlugin,\n BlockSelectionPlugin,\n} from '@udecode/plate-selection/react';\nimport { SlashPlugin } from '@udecode/plate-slash-command/react';\nimport { TablePlugin } from '@udecode/plate-table/react';\nimport { TogglePlugin } from '@udecode/plate-toggle/react';\nimport { TrailingBlockPlugin } from '@udecode/plate-trailing-block';\nimport Prism from 'prismjs';\n\nimport { CheckPlugin } from '@/components/context/check-plugin';\nimport { settingsStore } from '@/components/context/settings-store';\nimport { aiPlugins } from '@/lib/plate/demo/plugins/ai-plugins';\nimport { getAutoformatOptions } from '@/lib/plate/demo/plugins/autoformatOptions';\nimport { copilotPlugins } from '@/lib/plate/demo/plugins/copilot-plugins';\nimport { createPlateUI } from '@/plate/create-plate-ui';\nimport { editableProps } from '@/plate/demo/editableProps';\nimport { isEnabled } from '@/plate/demo/is-enabled';\nimport { DragOverCursorPlugin } from '@/plate/demo/plugins/DragOverCursorPlugin';\nimport { exitBreakPlugin } from '@/plate/demo/plugins/exitBreakPlugin';\nimport { resetBlockTypePlugin } from '@/plate/demo/plugins/resetBlockTypePlugin';\nimport { softBreakPlugin } from '@/plate/demo/plugins/softBreakPlugin';\nimport { tabbablePlugin } from '@/plate/demo/plugins/tabbablePlugin';\nimport { commentsData, usersData } from '@/plate/demo/values/commentsValue';\nimport { usePlaygroundValue } from '@/plate/demo/values/usePlaygroundValue';\nimport { BlockContextMenu } from '@/components/plate-ui/block-context-menu';\nimport { CommentsPopover } from '@/components/plate-ui/comments-popover';\nimport {\n CursorOverlay,\n SelectionOverlayPlugin,\n} from '@/components/plate-ui/cursor-overlay';\nimport { Editor, EditorContainer } from '@/components/plate-ui/editor';\nimport { FixedToolbar } from '@/components/plate-ui/fixed-toolbar';\nimport { FixedToolbarButtons } from '@/components/plate-ui/fixed-toolbar-buttons';\nimport { FloatingToolbar } from '@/components/plate-ui/floating-toolbar';\nimport { FloatingToolbarButtons } from '@/components/plate-ui/floating-toolbar-buttons';\nimport { ImagePreview } from '@/components/plate-ui/image-preview';\nimport {\n FireLiComponent,\n FireMarker,\n} from '@/components/plate-ui/indent-fire-marker';\nimport {\n TodoLi,\n TodoMarker,\n} from '@/components/plate-ui/indent-todo-marker';\nimport { LinkFloatingToolbar } from '@/components/plate-ui/link-floating-toolbar';\n\nimport { usePlaygroundEnabled } from './usePlaygroundEnabled';\n\nexport const usePlaygroundEditor = (id: any = '', scrollSelector?: string) => {\n const enabledPlugins = settingsStore.use.checkedPlugins();\n const overridePlugins = usePlaygroundEnabled(id);\n const autoformatOptions = getAutoformatOptions(id, enabledPlugins);\n\n const value = usePlaygroundValue(id);\n const key = settingsStore.use.version();\n const editorId = id || 'playground-' + key;\n\n return usePlateEditor(\n {\n id: editorId,\n override: {\n components: createPlateUI({\n draggable: isEnabled('dnd', id),\n placeholder: isEnabled('placeholder', id),\n }),\n plugins: overridePlugins,\n },\n plugins: [\n // AI\n ...(id === 'ai' || enabledPlugins[AIChatPlugin.key] ? aiPlugins : []),\n ...(id === 'copilot' || enabledPlugins[CopilotPlugin.key]\n ? copilotPlugins\n : []),\n // Nodes\n HeadingPlugin,\n TocPlugin.configure({\n options: {\n scrollContainerSelector: `#${scrollSelector}`,\n topOffset: 80,\n },\n }),\n BlockquotePlugin,\n CodeBlockPlugin.configure({\n options: {\n prism: Prism,\n },\n }),\n HorizontalRulePlugin,\n LinkPlugin.extend({\n render: { afterEditable: () => },\n }),\n ...(id === 'list' ? [ListPlugin] : []),\n ImagePlugin.extend({\n options: {\n disableUploadInsert: true,\n },\n render: { afterEditable: ImagePreview },\n }),\n MediaEmbedPlugin,\n CaptionPlugin.configure({\n options: {\n plugins: [ImagePlugin, MediaEmbedPlugin],\n },\n }),\n DatePlugin,\n MentionPlugin.configure({\n options: {\n triggerPreviousCharPattern: /^$|^[\\s\"']$/,\n },\n }),\n SlashPlugin,\n TablePlugin.configure({\n options: {\n enableMerging: id === 'tableMerge',\n },\n }),\n ColumnPlugin,\n SelectionOverlayPlugin,\n\n TodoListPlugin,\n TogglePlugin,\n ExcalidrawPlugin,\n // Marks\n BoldPlugin,\n ItalicPlugin,\n UnderlinePlugin,\n StrikethroughPlugin,\n CodePlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n FontColorPlugin,\n FontBackgroundColorPlugin,\n FontSizePlugin,\n HighlightPlugin,\n KbdPlugin,\n\n // Block Style\n AlignPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n MediaEmbedPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n ImagePlugin.key,\n HEADING_KEYS.h6,\n ],\n },\n }),\n IndentPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n }),\n IndentListPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n options: {\n listStyleTypes: {\n fire: {\n liComponent: FireLiComponent,\n markerComponent: FireMarker,\n type: 'fire',\n },\n todo: {\n liComponent: TodoLi,\n markerComponent: TodoMarker,\n type: 'todo',\n },\n },\n },\n }),\n LineHeightPlugin.extend({\n inject: {\n nodeProps: {\n defaultNodeValue: 1.5,\n validNodeValues: [1, 1.2, 1.5, 2, 3],\n },\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n ],\n },\n }),\n\n // Functionality\n AutoformatPlugin.configure({\n options: autoformatOptions,\n }),\n BlockSelectionPlugin.configure({\n options: {\n areaOptions: {\n behaviour: {\n scrolling: {\n speedDivider: 1.5,\n },\n startThreshold: 10,\n },\n boundaries: `#${scrollSelector}`,\n container: `#${scrollSelector}`,\n selectables: [`#${scrollSelector} .slate-selectable`],\n selectionAreaClass: 'slate-selection-area',\n },\n enableContextMenu: true,\n },\n }),\n BlockMenuPlugin.configure({\n render: { aboveEditable: BlockContextMenu },\n }),\n DndPlugin.configure({\n options: {\n enableScroller: true,\n onDropFiles: ({ dragItem, editor, target }) => {\n editor\n .getTransforms(ImagePlugin)\n .insertImageFromFiles(dragItem.files, {\n at: target,\n nextBlock: false,\n });\n },\n },\n }),\n EmojiPlugin,\n exitBreakPlugin,\n NodeIdPlugin,\n NormalizeTypesPlugin.configure({\n options: {\n rules: [{ path: [0], strictType: HEADING_KEYS.h1 }],\n },\n }),\n resetBlockTypePlugin,\n SelectOnBackspacePlugin.configure({\n options: {\n query: {\n allow: [ImagePlugin.key, HorizontalRulePlugin.key],\n },\n },\n }),\n DeletePlugin,\n SingleLinePlugin,\n softBreakPlugin,\n tabbablePlugin,\n TrailingBlockPlugin.configure({\n options: { type: ParagraphPlugin.key },\n }),\n DragOverCursorPlugin,\n\n // Collaboration\n CommentsPlugin.configure({\n options: {\n comments: commentsData,\n myUserId: '1',\n users: usersData,\n },\n }),\n\n // Deserialization\n DocxPlugin,\n MarkdownPlugin.configure({ options: { indentList: true } }),\n JuicePlugin,\n\n // Testing\n PlaywrightPlugin.configure({\n enabled: process.env.NODE_ENV !== 'production',\n }),\n ],\n value: value,\n },\n []\n );\n};\n\nexport default function PlaygroundDemo({\n id,\n className,\n scrollSelector,\n}: {\n id?: ValueId;\n className?: string;\n scrollSelector?: string;\n}) {\n const containerRef = useRef(null);\n const enabled = settingsStore.use.checkedComponents();\n\n const editor = usePlaygroundEditor(\n id,\n scrollSelector ?? `blockSelection-${id}`\n );\n\n return (\n \n \n \n \n \n \n \n \n \n\n
\n \n \n\n \n \n \n \n \n \n \n\n \n \n \n \n\n \n \n \n
\n
\n
\n );\n}\n\nconst DemoIdContext = React.createContext(undefined);\n\nexport function DemoId({\n id,\n children,\n}: {\n children: React.ReactNode;\n id?: string;\n}) {\n return {children};\n}\n\nexport function useDemoId() {\n return React.useContext(DemoIdContext);\n}\n", "path": "example/playground-demo.tsx", "target": "components/playground-demo.tsx", "type": "registry:example" diff --git a/apps/www/public/r/styles/default/comment-demo.json b/apps/www/public/r/styles/default/comment-demo.json index a968ae50d2..d31b981889 100644 --- a/apps/www/public/r/styles/default/comment-demo.json +++ b/apps/www/public/r/styles/default/comment-demo.json @@ -4,7 +4,7 @@ }, "files": [ { - "content": "'use client';\n\nimport React, { useRef } from 'react';\n\nimport type { ValueId } from '@/config/customizer-plugins';\n\nimport { cn } from '@udecode/cn';\nimport { AIChatPlugin, CopilotPlugin } from '@udecode/plate-ai/react';\nimport { AlignPlugin } from '@udecode/plate-alignment/react';\nimport { AutoformatPlugin } from '@udecode/plate-autoformat/react';\nimport {\n BoldPlugin,\n CodePlugin,\n ItalicPlugin,\n StrikethroughPlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n UnderlinePlugin,\n} from '@udecode/plate-basic-marks/react';\nimport { BlockquotePlugin } from '@udecode/plate-block-quote/react';\nimport { SingleLinePlugin } from '@udecode/plate-break/react';\nimport { CaptionPlugin } from '@udecode/plate-caption/react';\nimport { CodeBlockPlugin } from '@udecode/plate-code-block/react';\nimport { CommentsPlugin } from '@udecode/plate-comments/react';\nimport {\n ParagraphPlugin,\n Plate,\n usePlateEditor,\n} from '@udecode/plate-common/react';\nimport { DatePlugin } from '@udecode/plate-date/react';\nimport { DndPlugin } from '@udecode/plate-dnd';\nimport { DocxPlugin } from '@udecode/plate-docx';\nimport { EmojiPlugin } from '@udecode/plate-emoji/react';\nimport { ExcalidrawPlugin } from '@udecode/plate-excalidraw/react';\nimport {\n FontBackgroundColorPlugin,\n FontColorPlugin,\n FontSizePlugin,\n} from '@udecode/plate-font/react';\nimport { HEADING_KEYS } from '@udecode/plate-heading';\nimport { HeadingPlugin, TocPlugin } from '@udecode/plate-heading/react';\nimport { HighlightPlugin } from '@udecode/plate-highlight/react';\nimport { HorizontalRulePlugin } from '@udecode/plate-horizontal-rule/react';\nimport { IndentPlugin } from '@udecode/plate-indent/react';\nimport { IndentListPlugin } from '@udecode/plate-indent-list/react';\nimport { JuicePlugin } from '@udecode/plate-juice';\nimport { KbdPlugin } from '@udecode/plate-kbd/react';\nimport { ColumnPlugin } from '@udecode/plate-layout/react';\nimport { LineHeightPlugin } from '@udecode/plate-line-height/react';\nimport { LinkPlugin } from '@udecode/plate-link/react';\nimport { ListPlugin, TodoListPlugin } from '@udecode/plate-list/react';\nimport { MarkdownPlugin } from '@udecode/plate-markdown';\nimport { ImagePlugin, MediaEmbedPlugin } from '@udecode/plate-media/react';\nimport { MentionPlugin } from '@udecode/plate-mention/react';\nimport { NodeIdPlugin } from '@udecode/plate-node-id';\nimport { NormalizeTypesPlugin } from '@udecode/plate-normalizers';\nimport { PlaywrightPlugin } from '@udecode/plate-playwright';\nimport { DeletePlugin, SelectOnBackspacePlugin } from '@udecode/plate-select';\nimport {\n BlockMenuPlugin,\n BlockSelectionPlugin,\n} from '@udecode/plate-selection/react';\nimport { SlashPlugin } from '@udecode/plate-slash-command/react';\nimport { TablePlugin } from '@udecode/plate-table/react';\nimport { TogglePlugin } from '@udecode/plate-toggle/react';\nimport { TrailingBlockPlugin } from '@udecode/plate-trailing-block';\nimport Prism from 'prismjs';\n\nimport { CheckPlugin } from '@/components/context/check-plugin';\nimport { settingsStore } from '@/components/context/settings-store';\nimport { aiPlugins } from '@/lib/plate/demo/plugins/ai-plugins';\nimport { getAutoformatOptions } from '@/lib/plate/demo/plugins/autoformatOptions';\nimport { copilotPlugins } from '@/lib/plate/demo/plugins/copilot-plugins';\nimport { createPlateUI } from '@/plate/create-plate-ui';\nimport { editableProps } from '@/plate/demo/editableProps';\nimport { isEnabled } from '@/plate/demo/is-enabled';\nimport { DragOverCursorPlugin } from '@/plate/demo/plugins/DragOverCursorPlugin';\nimport { exitBreakPlugin } from '@/plate/demo/plugins/exitBreakPlugin';\nimport { resetBlockTypePlugin } from '@/plate/demo/plugins/resetBlockTypePlugin';\nimport { softBreakPlugin } from '@/plate/demo/plugins/softBreakPlugin';\nimport { tabbablePlugin } from '@/plate/demo/plugins/tabbablePlugin';\nimport { commentsData, usersData } from '@/plate/demo/values/commentsValue';\nimport { usePlaygroundValue } from '@/plate/demo/values/usePlaygroundValue';\nimport { BlockContextMenu } from '@/components/plate-ui/block-context-menu';\nimport { CommentsPopover } from '@/components/plate-ui/comments-popover';\nimport {\n CursorOverlay,\n SelectionOverlayPlugin,\n} from '@/components/plate-ui/cursor-overlay';\nimport { Editor, EditorContainer } from '@/components/plate-ui/editor';\nimport { FixedToolbar } from '@/components/plate-ui/fixed-toolbar';\nimport { FixedToolbarButtons } from '@/components/plate-ui/fixed-toolbar-buttons';\nimport { FloatingToolbar } from '@/components/plate-ui/floating-toolbar';\nimport { FloatingToolbarButtons } from '@/components/plate-ui/floating-toolbar-buttons';\nimport { ImagePreview } from '@/components/plate-ui/image-preview';\nimport {\n FireLiComponent,\n FireMarker,\n} from '@/components/plate-ui/indent-fire-marker';\nimport {\n TodoLi,\n TodoMarker,\n} from '@/components/plate-ui/indent-todo-marker';\nimport { LinkFloatingToolbar } from '@/components/plate-ui/link-floating-toolbar';\n\nimport { usePlaygroundEnabled } from './usePlaygroundEnabled';\n\nexport const usePlaygroundEditor = (id: any = '', scrollSelector?: string) => {\n const enabledPlugins = settingsStore.use.checkedPlugins();\n const overridePlugins = usePlaygroundEnabled(id);\n const autoformatOptions = getAutoformatOptions(id, enabledPlugins);\n\n const value = usePlaygroundValue(id);\n const key = settingsStore.use.version();\n const editorId = id || 'playground-' + key;\n\n return usePlateEditor(\n {\n id: editorId,\n override: {\n components: createPlateUI({\n draggable: isEnabled('dnd', id),\n placeholder: isEnabled('placeholder', id),\n }),\n plugins: overridePlugins,\n },\n plugins: [\n // AI\n ...(id === 'ai' || enabledPlugins[AIChatPlugin.key] ? aiPlugins : []),\n ...(id === 'copilot' || enabledPlugins[CopilotPlugin.key]\n ? copilotPlugins\n : []),\n // Nodes\n HeadingPlugin,\n TocPlugin.configure({\n options: {\n scrollContainerSelector: `#${scrollSelector}`,\n topOffset: 80,\n },\n }),\n BlockquotePlugin,\n CodeBlockPlugin.configure({\n options: {\n prism: Prism,\n },\n }),\n HorizontalRulePlugin,\n LinkPlugin.extend({\n render: { afterEditable: () => },\n }),\n ...(id === 'list' ? [ListPlugin] : []),\n ImagePlugin.extend({\n render: { afterEditable: ImagePreview },\n }),\n MediaEmbedPlugin,\n CaptionPlugin.configure({\n options: {\n plugins: [ImagePlugin, MediaEmbedPlugin],\n },\n }),\n DatePlugin,\n MentionPlugin.configure({\n options: {\n triggerPreviousCharPattern: /^$|^[\\s\"']$/,\n },\n }),\n SlashPlugin,\n TablePlugin.configure({\n options: {\n enableMerging: id === 'tableMerge',\n },\n }),\n ColumnPlugin,\n SelectionOverlayPlugin,\n\n TodoListPlugin,\n TogglePlugin,\n ExcalidrawPlugin,\n // Marks\n BoldPlugin,\n ItalicPlugin,\n UnderlinePlugin,\n StrikethroughPlugin,\n CodePlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n FontColorPlugin,\n FontBackgroundColorPlugin,\n FontSizePlugin,\n HighlightPlugin,\n KbdPlugin,\n\n // Block Style\n AlignPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n MediaEmbedPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n ImagePlugin.key,\n HEADING_KEYS.h6,\n ],\n },\n }),\n IndentPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n }),\n IndentListPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n options: {\n listStyleTypes: {\n fire: {\n liComponent: FireLiComponent,\n markerComponent: FireMarker,\n type: 'fire',\n },\n todo: {\n liComponent: TodoLi,\n markerComponent: TodoMarker,\n type: 'todo',\n },\n },\n },\n }),\n LineHeightPlugin.extend({\n inject: {\n nodeProps: {\n defaultNodeValue: 1.5,\n validNodeValues: [1, 1.2, 1.5, 2, 3],\n },\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n ],\n },\n }),\n\n // Functionality\n AutoformatPlugin.configure({\n options: autoformatOptions,\n }),\n BlockSelectionPlugin.configure({\n options: {\n areaOptions: {\n behaviour: {\n scrolling: {\n speedDivider: 1.5,\n },\n startThreshold: 10,\n },\n boundaries: `#${scrollSelector}`,\n container: `#${scrollSelector}`,\n selectables: [`#${scrollSelector} .slate-selectable`],\n selectionAreaClass: 'slate-selection-area',\n },\n enableContextMenu: true,\n },\n }),\n BlockMenuPlugin.configure({\n render: { aboveEditable: BlockContextMenu },\n }),\n DndPlugin.configure({ options: { enableScroller: true } }),\n EmojiPlugin,\n exitBreakPlugin,\n NodeIdPlugin,\n NormalizeTypesPlugin.configure({\n options: {\n rules: [{ path: [0], strictType: HEADING_KEYS.h1 }],\n },\n }),\n resetBlockTypePlugin,\n SelectOnBackspacePlugin.configure({\n options: {\n query: {\n allow: [ImagePlugin.key, HorizontalRulePlugin.key],\n },\n },\n }),\n DeletePlugin,\n SingleLinePlugin,\n softBreakPlugin,\n tabbablePlugin,\n TrailingBlockPlugin.configure({\n options: { type: ParagraphPlugin.key },\n }),\n DragOverCursorPlugin,\n\n // Collaboration\n CommentsPlugin.configure({\n options: {\n comments: commentsData,\n myUserId: '1',\n users: usersData,\n },\n }),\n\n // Deserialization\n DocxPlugin,\n MarkdownPlugin.configure({ options: { indentList: true } }),\n JuicePlugin,\n\n // Testing\n PlaywrightPlugin.configure({\n enabled: process.env.NODE_ENV !== 'production',\n }),\n ],\n value: value,\n },\n []\n );\n};\n\nexport default function PlaygroundDemo({\n id,\n className,\n scrollSelector,\n}: {\n id?: ValueId;\n className?: string;\n scrollSelector?: string;\n}) {\n const containerRef = useRef(null);\n const enabled = settingsStore.use.checkedComponents();\n\n const editor = usePlaygroundEditor(\n id,\n scrollSelector ?? `blockSelection-${id}`\n );\n\n return (\n \n \n \n \n \n \n \n \n \n\n
\n \n \n\n \n \n \n \n \n \n \n\n \n \n \n \n\n \n \n \n
\n
\n
\n );\n}\n\nconst DemoIdContext = React.createContext(undefined);\n\nexport function DemoId({\n id,\n children,\n}: {\n children: React.ReactNode;\n id?: string;\n}) {\n return {children};\n}\n\nexport function useDemoId() {\n return React.useContext(DemoIdContext);\n}\n", + "content": "'use client';\n\nimport React, { useRef } from 'react';\n\nimport type { ValueId } from '@/config/customizer-plugins';\n\nimport { cn } from '@udecode/cn';\nimport { AIChatPlugin, CopilotPlugin } from '@udecode/plate-ai/react';\nimport { AlignPlugin } from '@udecode/plate-alignment/react';\nimport { AutoformatPlugin } from '@udecode/plate-autoformat/react';\nimport {\n BoldPlugin,\n CodePlugin,\n ItalicPlugin,\n StrikethroughPlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n UnderlinePlugin,\n} from '@udecode/plate-basic-marks/react';\nimport { BlockquotePlugin } from '@udecode/plate-block-quote/react';\nimport { SingleLinePlugin } from '@udecode/plate-break/react';\nimport { CaptionPlugin } from '@udecode/plate-caption/react';\nimport { CodeBlockPlugin } from '@udecode/plate-code-block/react';\nimport { CommentsPlugin } from '@udecode/plate-comments/react';\nimport {\n ParagraphPlugin,\n Plate,\n usePlateEditor,\n} from '@udecode/plate-common/react';\nimport { DatePlugin } from '@udecode/plate-date/react';\nimport { DndPlugin } from '@udecode/plate-dnd';\nimport { DocxPlugin } from '@udecode/plate-docx';\nimport { EmojiPlugin } from '@udecode/plate-emoji/react';\nimport { ExcalidrawPlugin } from '@udecode/plate-excalidraw/react';\nimport {\n FontBackgroundColorPlugin,\n FontColorPlugin,\n FontSizePlugin,\n} from '@udecode/plate-font/react';\nimport { HEADING_KEYS } from '@udecode/plate-heading';\nimport { HeadingPlugin, TocPlugin } from '@udecode/plate-heading/react';\nimport { HighlightPlugin } from '@udecode/plate-highlight/react';\nimport { HorizontalRulePlugin } from '@udecode/plate-horizontal-rule/react';\nimport { IndentPlugin } from '@udecode/plate-indent/react';\nimport { IndentListPlugin } from '@udecode/plate-indent-list/react';\nimport { JuicePlugin } from '@udecode/plate-juice';\nimport { KbdPlugin } from '@udecode/plate-kbd/react';\nimport { ColumnPlugin } from '@udecode/plate-layout/react';\nimport { LineHeightPlugin } from '@udecode/plate-line-height/react';\nimport { LinkPlugin } from '@udecode/plate-link/react';\nimport { ListPlugin, TodoListPlugin } from '@udecode/plate-list/react';\nimport { MarkdownPlugin } from '@udecode/plate-markdown';\nimport { ImagePlugin, MediaEmbedPlugin } from '@udecode/plate-media/react';\nimport { MentionPlugin } from '@udecode/plate-mention/react';\nimport { NodeIdPlugin } from '@udecode/plate-node-id';\nimport { NormalizeTypesPlugin } from '@udecode/plate-normalizers';\nimport { PlaywrightPlugin } from '@udecode/plate-playwright';\nimport { DeletePlugin, SelectOnBackspacePlugin } from '@udecode/plate-select';\nimport {\n BlockMenuPlugin,\n BlockSelectionPlugin,\n} from '@udecode/plate-selection/react';\nimport { SlashPlugin } from '@udecode/plate-slash-command/react';\nimport { TablePlugin } from '@udecode/plate-table/react';\nimport { TogglePlugin } from '@udecode/plate-toggle/react';\nimport { TrailingBlockPlugin } from '@udecode/plate-trailing-block';\nimport Prism from 'prismjs';\n\nimport { CheckPlugin } from '@/components/context/check-plugin';\nimport { settingsStore } from '@/components/context/settings-store';\nimport { aiPlugins } from '@/lib/plate/demo/plugins/ai-plugins';\nimport { getAutoformatOptions } from '@/lib/plate/demo/plugins/autoformatOptions';\nimport { copilotPlugins } from '@/lib/plate/demo/plugins/copilot-plugins';\nimport { createPlateUI } from '@/plate/create-plate-ui';\nimport { editableProps } from '@/plate/demo/editableProps';\nimport { isEnabled } from '@/plate/demo/is-enabled';\nimport { DragOverCursorPlugin } from '@/plate/demo/plugins/DragOverCursorPlugin';\nimport { exitBreakPlugin } from '@/plate/demo/plugins/exitBreakPlugin';\nimport { resetBlockTypePlugin } from '@/plate/demo/plugins/resetBlockTypePlugin';\nimport { softBreakPlugin } from '@/plate/demo/plugins/softBreakPlugin';\nimport { tabbablePlugin } from '@/plate/demo/plugins/tabbablePlugin';\nimport { commentsData, usersData } from '@/plate/demo/values/commentsValue';\nimport { usePlaygroundValue } from '@/plate/demo/values/usePlaygroundValue';\nimport { BlockContextMenu } from '@/components/plate-ui/block-context-menu';\nimport { CommentsPopover } from '@/components/plate-ui/comments-popover';\nimport {\n CursorOverlay,\n SelectionOverlayPlugin,\n} from '@/components/plate-ui/cursor-overlay';\nimport { Editor, EditorContainer } from '@/components/plate-ui/editor';\nimport { FixedToolbar } from '@/components/plate-ui/fixed-toolbar';\nimport { FixedToolbarButtons } from '@/components/plate-ui/fixed-toolbar-buttons';\nimport { FloatingToolbar } from '@/components/plate-ui/floating-toolbar';\nimport { FloatingToolbarButtons } from '@/components/plate-ui/floating-toolbar-buttons';\nimport { ImagePreview } from '@/components/plate-ui/image-preview';\nimport {\n FireLiComponent,\n FireMarker,\n} from '@/components/plate-ui/indent-fire-marker';\nimport {\n TodoLi,\n TodoMarker,\n} from '@/components/plate-ui/indent-todo-marker';\nimport { LinkFloatingToolbar } from '@/components/plate-ui/link-floating-toolbar';\n\nimport { usePlaygroundEnabled } from './usePlaygroundEnabled';\n\nexport const usePlaygroundEditor = (id: any = '', scrollSelector?: string) => {\n const enabledPlugins = settingsStore.use.checkedPlugins();\n const overridePlugins = usePlaygroundEnabled(id);\n const autoformatOptions = getAutoformatOptions(id, enabledPlugins);\n\n const value = usePlaygroundValue(id);\n const key = settingsStore.use.version();\n const editorId = id || 'playground-' + key;\n\n return usePlateEditor(\n {\n id: editorId,\n override: {\n components: createPlateUI({\n draggable: isEnabled('dnd', id),\n placeholder: isEnabled('placeholder', id),\n }),\n plugins: overridePlugins,\n },\n plugins: [\n // AI\n ...(id === 'ai' || enabledPlugins[AIChatPlugin.key] ? aiPlugins : []),\n ...(id === 'copilot' || enabledPlugins[CopilotPlugin.key]\n ? copilotPlugins\n : []),\n // Nodes\n HeadingPlugin,\n TocPlugin.configure({\n options: {\n scrollContainerSelector: `#${scrollSelector}`,\n topOffset: 80,\n },\n }),\n BlockquotePlugin,\n CodeBlockPlugin.configure({\n options: {\n prism: Prism,\n },\n }),\n HorizontalRulePlugin,\n LinkPlugin.extend({\n render: { afterEditable: () => },\n }),\n ...(id === 'list' ? [ListPlugin] : []),\n ImagePlugin.extend({\n options: {\n disableUploadInsert: true,\n },\n render: { afterEditable: ImagePreview },\n }),\n MediaEmbedPlugin,\n CaptionPlugin.configure({\n options: {\n plugins: [ImagePlugin, MediaEmbedPlugin],\n },\n }),\n DatePlugin,\n MentionPlugin.configure({\n options: {\n triggerPreviousCharPattern: /^$|^[\\s\"']$/,\n },\n }),\n SlashPlugin,\n TablePlugin.configure({\n options: {\n enableMerging: id === 'tableMerge',\n },\n }),\n ColumnPlugin,\n SelectionOverlayPlugin,\n\n TodoListPlugin,\n TogglePlugin,\n ExcalidrawPlugin,\n // Marks\n BoldPlugin,\n ItalicPlugin,\n UnderlinePlugin,\n StrikethroughPlugin,\n CodePlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n FontColorPlugin,\n FontBackgroundColorPlugin,\n FontSizePlugin,\n HighlightPlugin,\n KbdPlugin,\n\n // Block Style\n AlignPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n MediaEmbedPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n ImagePlugin.key,\n HEADING_KEYS.h6,\n ],\n },\n }),\n IndentPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n }),\n IndentListPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n options: {\n listStyleTypes: {\n fire: {\n liComponent: FireLiComponent,\n markerComponent: FireMarker,\n type: 'fire',\n },\n todo: {\n liComponent: TodoLi,\n markerComponent: TodoMarker,\n type: 'todo',\n },\n },\n },\n }),\n LineHeightPlugin.extend({\n inject: {\n nodeProps: {\n defaultNodeValue: 1.5,\n validNodeValues: [1, 1.2, 1.5, 2, 3],\n },\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n ],\n },\n }),\n\n // Functionality\n AutoformatPlugin.configure({\n options: autoformatOptions,\n }),\n BlockSelectionPlugin.configure({\n options: {\n areaOptions: {\n behaviour: {\n scrolling: {\n speedDivider: 1.5,\n },\n startThreshold: 10,\n },\n boundaries: `#${scrollSelector}`,\n container: `#${scrollSelector}`,\n selectables: [`#${scrollSelector} .slate-selectable`],\n selectionAreaClass: 'slate-selection-area',\n },\n enableContextMenu: true,\n },\n }),\n BlockMenuPlugin.configure({\n render: { aboveEditable: BlockContextMenu },\n }),\n DndPlugin.configure({\n options: {\n enableScroller: true,\n onDropFiles: ({ dragItem, editor, target }) => {\n editor\n .getTransforms(ImagePlugin)\n .insertImageFromFiles(dragItem.files, {\n at: target,\n nextBlock: false,\n });\n },\n },\n }),\n EmojiPlugin,\n exitBreakPlugin,\n NodeIdPlugin,\n NormalizeTypesPlugin.configure({\n options: {\n rules: [{ path: [0], strictType: HEADING_KEYS.h1 }],\n },\n }),\n resetBlockTypePlugin,\n SelectOnBackspacePlugin.configure({\n options: {\n query: {\n allow: [ImagePlugin.key, HorizontalRulePlugin.key],\n },\n },\n }),\n DeletePlugin,\n SingleLinePlugin,\n softBreakPlugin,\n tabbablePlugin,\n TrailingBlockPlugin.configure({\n options: { type: ParagraphPlugin.key },\n }),\n DragOverCursorPlugin,\n\n // Collaboration\n CommentsPlugin.configure({\n options: {\n comments: commentsData,\n myUserId: '1',\n users: usersData,\n },\n }),\n\n // Deserialization\n DocxPlugin,\n MarkdownPlugin.configure({ options: { indentList: true } }),\n JuicePlugin,\n\n // Testing\n PlaywrightPlugin.configure({\n enabled: process.env.NODE_ENV !== 'production',\n }),\n ],\n value: value,\n },\n []\n );\n};\n\nexport default function PlaygroundDemo({\n id,\n className,\n scrollSelector,\n}: {\n id?: ValueId;\n className?: string;\n scrollSelector?: string;\n}) {\n const containerRef = useRef(null);\n const enabled = settingsStore.use.checkedComponents();\n\n const editor = usePlaygroundEditor(\n id,\n scrollSelector ?? `blockSelection-${id}`\n );\n\n return (\n \n \n \n \n \n \n \n \n \n\n
\n \n \n\n \n \n \n \n \n \n \n\n \n \n \n \n\n \n \n \n
\n
\n
\n );\n}\n\nconst DemoIdContext = React.createContext(undefined);\n\nexport function DemoId({\n id,\n children,\n}: {\n children: React.ReactNode;\n id?: string;\n}) {\n return {children};\n}\n\nexport function useDemoId() {\n return React.useContext(DemoIdContext);\n}\n", "path": "example/playground-demo.tsx", "target": "components/playground-demo.tsx", "type": "registry:example" diff --git a/apps/www/public/r/styles/default/copilot-demo.json b/apps/www/public/r/styles/default/copilot-demo.json index 0b8aff0524..41ccfa8853 100644 --- a/apps/www/public/r/styles/default/copilot-demo.json +++ b/apps/www/public/r/styles/default/copilot-demo.json @@ -4,7 +4,7 @@ }, "files": [ { - "content": "'use client';\n\nimport React, { useRef } from 'react';\n\nimport type { ValueId } from '@/config/customizer-plugins';\n\nimport { cn } from '@udecode/cn';\nimport { AIChatPlugin, CopilotPlugin } from '@udecode/plate-ai/react';\nimport { AlignPlugin } from '@udecode/plate-alignment/react';\nimport { AutoformatPlugin } from '@udecode/plate-autoformat/react';\nimport {\n BoldPlugin,\n CodePlugin,\n ItalicPlugin,\n StrikethroughPlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n UnderlinePlugin,\n} from '@udecode/plate-basic-marks/react';\nimport { BlockquotePlugin } from '@udecode/plate-block-quote/react';\nimport { SingleLinePlugin } from '@udecode/plate-break/react';\nimport { CaptionPlugin } from '@udecode/plate-caption/react';\nimport { CodeBlockPlugin } from '@udecode/plate-code-block/react';\nimport { CommentsPlugin } from '@udecode/plate-comments/react';\nimport {\n ParagraphPlugin,\n Plate,\n usePlateEditor,\n} from '@udecode/plate-common/react';\nimport { DatePlugin } from '@udecode/plate-date/react';\nimport { DndPlugin } from '@udecode/plate-dnd';\nimport { DocxPlugin } from '@udecode/plate-docx';\nimport { EmojiPlugin } from '@udecode/plate-emoji/react';\nimport { ExcalidrawPlugin } from '@udecode/plate-excalidraw/react';\nimport {\n FontBackgroundColorPlugin,\n FontColorPlugin,\n FontSizePlugin,\n} from '@udecode/plate-font/react';\nimport { HEADING_KEYS } from '@udecode/plate-heading';\nimport { HeadingPlugin, TocPlugin } from '@udecode/plate-heading/react';\nimport { HighlightPlugin } from '@udecode/plate-highlight/react';\nimport { HorizontalRulePlugin } from '@udecode/plate-horizontal-rule/react';\nimport { IndentPlugin } from '@udecode/plate-indent/react';\nimport { IndentListPlugin } from '@udecode/plate-indent-list/react';\nimport { JuicePlugin } from '@udecode/plate-juice';\nimport { KbdPlugin } from '@udecode/plate-kbd/react';\nimport { ColumnPlugin } from '@udecode/plate-layout/react';\nimport { LineHeightPlugin } from '@udecode/plate-line-height/react';\nimport { LinkPlugin } from '@udecode/plate-link/react';\nimport { ListPlugin, TodoListPlugin } from '@udecode/plate-list/react';\nimport { MarkdownPlugin } from '@udecode/plate-markdown';\nimport { ImagePlugin, MediaEmbedPlugin } from '@udecode/plate-media/react';\nimport { MentionPlugin } from '@udecode/plate-mention/react';\nimport { NodeIdPlugin } from '@udecode/plate-node-id';\nimport { NormalizeTypesPlugin } from '@udecode/plate-normalizers';\nimport { PlaywrightPlugin } from '@udecode/plate-playwright';\nimport { DeletePlugin, SelectOnBackspacePlugin } from '@udecode/plate-select';\nimport {\n BlockMenuPlugin,\n BlockSelectionPlugin,\n} from '@udecode/plate-selection/react';\nimport { SlashPlugin } from '@udecode/plate-slash-command/react';\nimport { TablePlugin } from '@udecode/plate-table/react';\nimport { TogglePlugin } from '@udecode/plate-toggle/react';\nimport { TrailingBlockPlugin } from '@udecode/plate-trailing-block';\nimport Prism from 'prismjs';\n\nimport { CheckPlugin } from '@/components/context/check-plugin';\nimport { settingsStore } from '@/components/context/settings-store';\nimport { aiPlugins } from '@/lib/plate/demo/plugins/ai-plugins';\nimport { getAutoformatOptions } from '@/lib/plate/demo/plugins/autoformatOptions';\nimport { copilotPlugins } from '@/lib/plate/demo/plugins/copilot-plugins';\nimport { createPlateUI } from '@/plate/create-plate-ui';\nimport { editableProps } from '@/plate/demo/editableProps';\nimport { isEnabled } from '@/plate/demo/is-enabled';\nimport { DragOverCursorPlugin } from '@/plate/demo/plugins/DragOverCursorPlugin';\nimport { exitBreakPlugin } from '@/plate/demo/plugins/exitBreakPlugin';\nimport { resetBlockTypePlugin } from '@/plate/demo/plugins/resetBlockTypePlugin';\nimport { softBreakPlugin } from '@/plate/demo/plugins/softBreakPlugin';\nimport { tabbablePlugin } from '@/plate/demo/plugins/tabbablePlugin';\nimport { commentsData, usersData } from '@/plate/demo/values/commentsValue';\nimport { usePlaygroundValue } from '@/plate/demo/values/usePlaygroundValue';\nimport { BlockContextMenu } from '@/components/plate-ui/block-context-menu';\nimport { CommentsPopover } from '@/components/plate-ui/comments-popover';\nimport {\n CursorOverlay,\n SelectionOverlayPlugin,\n} from '@/components/plate-ui/cursor-overlay';\nimport { Editor, EditorContainer } from '@/components/plate-ui/editor';\nimport { FixedToolbar } from '@/components/plate-ui/fixed-toolbar';\nimport { FixedToolbarButtons } from '@/components/plate-ui/fixed-toolbar-buttons';\nimport { FloatingToolbar } from '@/components/plate-ui/floating-toolbar';\nimport { FloatingToolbarButtons } from '@/components/plate-ui/floating-toolbar-buttons';\nimport { ImagePreview } from '@/components/plate-ui/image-preview';\nimport {\n FireLiComponent,\n FireMarker,\n} from '@/components/plate-ui/indent-fire-marker';\nimport {\n TodoLi,\n TodoMarker,\n} from '@/components/plate-ui/indent-todo-marker';\nimport { LinkFloatingToolbar } from '@/components/plate-ui/link-floating-toolbar';\n\nimport { usePlaygroundEnabled } from './usePlaygroundEnabled';\n\nexport const usePlaygroundEditor = (id: any = '', scrollSelector?: string) => {\n const enabledPlugins = settingsStore.use.checkedPlugins();\n const overridePlugins = usePlaygroundEnabled(id);\n const autoformatOptions = getAutoformatOptions(id, enabledPlugins);\n\n const value = usePlaygroundValue(id);\n const key = settingsStore.use.version();\n const editorId = id || 'playground-' + key;\n\n return usePlateEditor(\n {\n id: editorId,\n override: {\n components: createPlateUI({\n draggable: isEnabled('dnd', id),\n placeholder: isEnabled('placeholder', id),\n }),\n plugins: overridePlugins,\n },\n plugins: [\n // AI\n ...(id === 'ai' || enabledPlugins[AIChatPlugin.key] ? aiPlugins : []),\n ...(id === 'copilot' || enabledPlugins[CopilotPlugin.key]\n ? copilotPlugins\n : []),\n // Nodes\n HeadingPlugin,\n TocPlugin.configure({\n options: {\n scrollContainerSelector: `#${scrollSelector}`,\n topOffset: 80,\n },\n }),\n BlockquotePlugin,\n CodeBlockPlugin.configure({\n options: {\n prism: Prism,\n },\n }),\n HorizontalRulePlugin,\n LinkPlugin.extend({\n render: { afterEditable: () => },\n }),\n ...(id === 'list' ? [ListPlugin] : []),\n ImagePlugin.extend({\n render: { afterEditable: ImagePreview },\n }),\n MediaEmbedPlugin,\n CaptionPlugin.configure({\n options: {\n plugins: [ImagePlugin, MediaEmbedPlugin],\n },\n }),\n DatePlugin,\n MentionPlugin.configure({\n options: {\n triggerPreviousCharPattern: /^$|^[\\s\"']$/,\n },\n }),\n SlashPlugin,\n TablePlugin.configure({\n options: {\n enableMerging: id === 'tableMerge',\n },\n }),\n ColumnPlugin,\n SelectionOverlayPlugin,\n\n TodoListPlugin,\n TogglePlugin,\n ExcalidrawPlugin,\n // Marks\n BoldPlugin,\n ItalicPlugin,\n UnderlinePlugin,\n StrikethroughPlugin,\n CodePlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n FontColorPlugin,\n FontBackgroundColorPlugin,\n FontSizePlugin,\n HighlightPlugin,\n KbdPlugin,\n\n // Block Style\n AlignPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n MediaEmbedPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n ImagePlugin.key,\n HEADING_KEYS.h6,\n ],\n },\n }),\n IndentPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n }),\n IndentListPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n options: {\n listStyleTypes: {\n fire: {\n liComponent: FireLiComponent,\n markerComponent: FireMarker,\n type: 'fire',\n },\n todo: {\n liComponent: TodoLi,\n markerComponent: TodoMarker,\n type: 'todo',\n },\n },\n },\n }),\n LineHeightPlugin.extend({\n inject: {\n nodeProps: {\n defaultNodeValue: 1.5,\n validNodeValues: [1, 1.2, 1.5, 2, 3],\n },\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n ],\n },\n }),\n\n // Functionality\n AutoformatPlugin.configure({\n options: autoformatOptions,\n }),\n BlockSelectionPlugin.configure({\n options: {\n areaOptions: {\n behaviour: {\n scrolling: {\n speedDivider: 1.5,\n },\n startThreshold: 10,\n },\n boundaries: `#${scrollSelector}`,\n container: `#${scrollSelector}`,\n selectables: [`#${scrollSelector} .slate-selectable`],\n selectionAreaClass: 'slate-selection-area',\n },\n enableContextMenu: true,\n },\n }),\n BlockMenuPlugin.configure({\n render: { aboveEditable: BlockContextMenu },\n }),\n DndPlugin.configure({ options: { enableScroller: true } }),\n EmojiPlugin,\n exitBreakPlugin,\n NodeIdPlugin,\n NormalizeTypesPlugin.configure({\n options: {\n rules: [{ path: [0], strictType: HEADING_KEYS.h1 }],\n },\n }),\n resetBlockTypePlugin,\n SelectOnBackspacePlugin.configure({\n options: {\n query: {\n allow: [ImagePlugin.key, HorizontalRulePlugin.key],\n },\n },\n }),\n DeletePlugin,\n SingleLinePlugin,\n softBreakPlugin,\n tabbablePlugin,\n TrailingBlockPlugin.configure({\n options: { type: ParagraphPlugin.key },\n }),\n DragOverCursorPlugin,\n\n // Collaboration\n CommentsPlugin.configure({\n options: {\n comments: commentsData,\n myUserId: '1',\n users: usersData,\n },\n }),\n\n // Deserialization\n DocxPlugin,\n MarkdownPlugin.configure({ options: { indentList: true } }),\n JuicePlugin,\n\n // Testing\n PlaywrightPlugin.configure({\n enabled: process.env.NODE_ENV !== 'production',\n }),\n ],\n value: value,\n },\n []\n );\n};\n\nexport default function PlaygroundDemo({\n id,\n className,\n scrollSelector,\n}: {\n id?: ValueId;\n className?: string;\n scrollSelector?: string;\n}) {\n const containerRef = useRef(null);\n const enabled = settingsStore.use.checkedComponents();\n\n const editor = usePlaygroundEditor(\n id,\n scrollSelector ?? `blockSelection-${id}`\n );\n\n return (\n \n \n \n \n \n \n \n \n \n\n
\n \n \n\n \n \n \n \n \n \n \n\n \n \n \n \n\n \n \n \n
\n
\n
\n );\n}\n\nconst DemoIdContext = React.createContext(undefined);\n\nexport function DemoId({\n id,\n children,\n}: {\n children: React.ReactNode;\n id?: string;\n}) {\n return {children};\n}\n\nexport function useDemoId() {\n return React.useContext(DemoIdContext);\n}\n", + "content": "'use client';\n\nimport React, { useRef } from 'react';\n\nimport type { ValueId } from '@/config/customizer-plugins';\n\nimport { cn } from '@udecode/cn';\nimport { AIChatPlugin, CopilotPlugin } from '@udecode/plate-ai/react';\nimport { AlignPlugin } from '@udecode/plate-alignment/react';\nimport { AutoformatPlugin } from '@udecode/plate-autoformat/react';\nimport {\n BoldPlugin,\n CodePlugin,\n ItalicPlugin,\n StrikethroughPlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n UnderlinePlugin,\n} from '@udecode/plate-basic-marks/react';\nimport { BlockquotePlugin } from '@udecode/plate-block-quote/react';\nimport { SingleLinePlugin } from '@udecode/plate-break/react';\nimport { CaptionPlugin } from '@udecode/plate-caption/react';\nimport { CodeBlockPlugin } from '@udecode/plate-code-block/react';\nimport { CommentsPlugin } from '@udecode/plate-comments/react';\nimport {\n ParagraphPlugin,\n Plate,\n usePlateEditor,\n} from '@udecode/plate-common/react';\nimport { DatePlugin } from '@udecode/plate-date/react';\nimport { DndPlugin } from '@udecode/plate-dnd';\nimport { DocxPlugin } from '@udecode/plate-docx';\nimport { EmojiPlugin } from '@udecode/plate-emoji/react';\nimport { ExcalidrawPlugin } from '@udecode/plate-excalidraw/react';\nimport {\n FontBackgroundColorPlugin,\n FontColorPlugin,\n FontSizePlugin,\n} from '@udecode/plate-font/react';\nimport { HEADING_KEYS } from '@udecode/plate-heading';\nimport { HeadingPlugin, TocPlugin } from '@udecode/plate-heading/react';\nimport { HighlightPlugin } from '@udecode/plate-highlight/react';\nimport { HorizontalRulePlugin } from '@udecode/plate-horizontal-rule/react';\nimport { IndentPlugin } from '@udecode/plate-indent/react';\nimport { IndentListPlugin } from '@udecode/plate-indent-list/react';\nimport { JuicePlugin } from '@udecode/plate-juice';\nimport { KbdPlugin } from '@udecode/plate-kbd/react';\nimport { ColumnPlugin } from '@udecode/plate-layout/react';\nimport { LineHeightPlugin } from '@udecode/plate-line-height/react';\nimport { LinkPlugin } from '@udecode/plate-link/react';\nimport { ListPlugin, TodoListPlugin } from '@udecode/plate-list/react';\nimport { MarkdownPlugin } from '@udecode/plate-markdown';\nimport { ImagePlugin, MediaEmbedPlugin } from '@udecode/plate-media/react';\nimport { MentionPlugin } from '@udecode/plate-mention/react';\nimport { NodeIdPlugin } from '@udecode/plate-node-id';\nimport { NormalizeTypesPlugin } from '@udecode/plate-normalizers';\nimport { PlaywrightPlugin } from '@udecode/plate-playwright';\nimport { DeletePlugin, SelectOnBackspacePlugin } from '@udecode/plate-select';\nimport {\n BlockMenuPlugin,\n BlockSelectionPlugin,\n} from '@udecode/plate-selection/react';\nimport { SlashPlugin } from '@udecode/plate-slash-command/react';\nimport { TablePlugin } from '@udecode/plate-table/react';\nimport { TogglePlugin } from '@udecode/plate-toggle/react';\nimport { TrailingBlockPlugin } from '@udecode/plate-trailing-block';\nimport Prism from 'prismjs';\n\nimport { CheckPlugin } from '@/components/context/check-plugin';\nimport { settingsStore } from '@/components/context/settings-store';\nimport { aiPlugins } from '@/lib/plate/demo/plugins/ai-plugins';\nimport { getAutoformatOptions } from '@/lib/plate/demo/plugins/autoformatOptions';\nimport { copilotPlugins } from '@/lib/plate/demo/plugins/copilot-plugins';\nimport { createPlateUI } from '@/plate/create-plate-ui';\nimport { editableProps } from '@/plate/demo/editableProps';\nimport { isEnabled } from '@/plate/demo/is-enabled';\nimport { DragOverCursorPlugin } from '@/plate/demo/plugins/DragOverCursorPlugin';\nimport { exitBreakPlugin } from '@/plate/demo/plugins/exitBreakPlugin';\nimport { resetBlockTypePlugin } from '@/plate/demo/plugins/resetBlockTypePlugin';\nimport { softBreakPlugin } from '@/plate/demo/plugins/softBreakPlugin';\nimport { tabbablePlugin } from '@/plate/demo/plugins/tabbablePlugin';\nimport { commentsData, usersData } from '@/plate/demo/values/commentsValue';\nimport { usePlaygroundValue } from '@/plate/demo/values/usePlaygroundValue';\nimport { BlockContextMenu } from '@/components/plate-ui/block-context-menu';\nimport { CommentsPopover } from '@/components/plate-ui/comments-popover';\nimport {\n CursorOverlay,\n SelectionOverlayPlugin,\n} from '@/components/plate-ui/cursor-overlay';\nimport { Editor, EditorContainer } from '@/components/plate-ui/editor';\nimport { FixedToolbar } from '@/components/plate-ui/fixed-toolbar';\nimport { FixedToolbarButtons } from '@/components/plate-ui/fixed-toolbar-buttons';\nimport { FloatingToolbar } from '@/components/plate-ui/floating-toolbar';\nimport { FloatingToolbarButtons } from '@/components/plate-ui/floating-toolbar-buttons';\nimport { ImagePreview } from '@/components/plate-ui/image-preview';\nimport {\n FireLiComponent,\n FireMarker,\n} from '@/components/plate-ui/indent-fire-marker';\nimport {\n TodoLi,\n TodoMarker,\n} from '@/components/plate-ui/indent-todo-marker';\nimport { LinkFloatingToolbar } from '@/components/plate-ui/link-floating-toolbar';\n\nimport { usePlaygroundEnabled } from './usePlaygroundEnabled';\n\nexport const usePlaygroundEditor = (id: any = '', scrollSelector?: string) => {\n const enabledPlugins = settingsStore.use.checkedPlugins();\n const overridePlugins = usePlaygroundEnabled(id);\n const autoformatOptions = getAutoformatOptions(id, enabledPlugins);\n\n const value = usePlaygroundValue(id);\n const key = settingsStore.use.version();\n const editorId = id || 'playground-' + key;\n\n return usePlateEditor(\n {\n id: editorId,\n override: {\n components: createPlateUI({\n draggable: isEnabled('dnd', id),\n placeholder: isEnabled('placeholder', id),\n }),\n plugins: overridePlugins,\n },\n plugins: [\n // AI\n ...(id === 'ai' || enabledPlugins[AIChatPlugin.key] ? aiPlugins : []),\n ...(id === 'copilot' || enabledPlugins[CopilotPlugin.key]\n ? copilotPlugins\n : []),\n // Nodes\n HeadingPlugin,\n TocPlugin.configure({\n options: {\n scrollContainerSelector: `#${scrollSelector}`,\n topOffset: 80,\n },\n }),\n BlockquotePlugin,\n CodeBlockPlugin.configure({\n options: {\n prism: Prism,\n },\n }),\n HorizontalRulePlugin,\n LinkPlugin.extend({\n render: { afterEditable: () => },\n }),\n ...(id === 'list' ? [ListPlugin] : []),\n ImagePlugin.extend({\n options: {\n disableUploadInsert: true,\n },\n render: { afterEditable: ImagePreview },\n }),\n MediaEmbedPlugin,\n CaptionPlugin.configure({\n options: {\n plugins: [ImagePlugin, MediaEmbedPlugin],\n },\n }),\n DatePlugin,\n MentionPlugin.configure({\n options: {\n triggerPreviousCharPattern: /^$|^[\\s\"']$/,\n },\n }),\n SlashPlugin,\n TablePlugin.configure({\n options: {\n enableMerging: id === 'tableMerge',\n },\n }),\n ColumnPlugin,\n SelectionOverlayPlugin,\n\n TodoListPlugin,\n TogglePlugin,\n ExcalidrawPlugin,\n // Marks\n BoldPlugin,\n ItalicPlugin,\n UnderlinePlugin,\n StrikethroughPlugin,\n CodePlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n FontColorPlugin,\n FontBackgroundColorPlugin,\n FontSizePlugin,\n HighlightPlugin,\n KbdPlugin,\n\n // Block Style\n AlignPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n MediaEmbedPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n ImagePlugin.key,\n HEADING_KEYS.h6,\n ],\n },\n }),\n IndentPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n }),\n IndentListPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n options: {\n listStyleTypes: {\n fire: {\n liComponent: FireLiComponent,\n markerComponent: FireMarker,\n type: 'fire',\n },\n todo: {\n liComponent: TodoLi,\n markerComponent: TodoMarker,\n type: 'todo',\n },\n },\n },\n }),\n LineHeightPlugin.extend({\n inject: {\n nodeProps: {\n defaultNodeValue: 1.5,\n validNodeValues: [1, 1.2, 1.5, 2, 3],\n },\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n ],\n },\n }),\n\n // Functionality\n AutoformatPlugin.configure({\n options: autoformatOptions,\n }),\n BlockSelectionPlugin.configure({\n options: {\n areaOptions: {\n behaviour: {\n scrolling: {\n speedDivider: 1.5,\n },\n startThreshold: 10,\n },\n boundaries: `#${scrollSelector}`,\n container: `#${scrollSelector}`,\n selectables: [`#${scrollSelector} .slate-selectable`],\n selectionAreaClass: 'slate-selection-area',\n },\n enableContextMenu: true,\n },\n }),\n BlockMenuPlugin.configure({\n render: { aboveEditable: BlockContextMenu },\n }),\n DndPlugin.configure({\n options: {\n enableScroller: true,\n onDropFiles: ({ dragItem, editor, target }) => {\n editor\n .getTransforms(ImagePlugin)\n .insertImageFromFiles(dragItem.files, {\n at: target,\n nextBlock: false,\n });\n },\n },\n }),\n EmojiPlugin,\n exitBreakPlugin,\n NodeIdPlugin,\n NormalizeTypesPlugin.configure({\n options: {\n rules: [{ path: [0], strictType: HEADING_KEYS.h1 }],\n },\n }),\n resetBlockTypePlugin,\n SelectOnBackspacePlugin.configure({\n options: {\n query: {\n allow: [ImagePlugin.key, HorizontalRulePlugin.key],\n },\n },\n }),\n DeletePlugin,\n SingleLinePlugin,\n softBreakPlugin,\n tabbablePlugin,\n TrailingBlockPlugin.configure({\n options: { type: ParagraphPlugin.key },\n }),\n DragOverCursorPlugin,\n\n // Collaboration\n CommentsPlugin.configure({\n options: {\n comments: commentsData,\n myUserId: '1',\n users: usersData,\n },\n }),\n\n // Deserialization\n DocxPlugin,\n MarkdownPlugin.configure({ options: { indentList: true } }),\n JuicePlugin,\n\n // Testing\n PlaywrightPlugin.configure({\n enabled: process.env.NODE_ENV !== 'production',\n }),\n ],\n value: value,\n },\n []\n );\n};\n\nexport default function PlaygroundDemo({\n id,\n className,\n scrollSelector,\n}: {\n id?: ValueId;\n className?: string;\n scrollSelector?: string;\n}) {\n const containerRef = useRef(null);\n const enabled = settingsStore.use.checkedComponents();\n\n const editor = usePlaygroundEditor(\n id,\n scrollSelector ?? `blockSelection-${id}`\n );\n\n return (\n \n \n \n \n \n \n \n \n \n\n
\n \n \n\n \n \n \n \n \n \n \n\n \n \n \n \n\n \n \n \n
\n
\n
\n );\n}\n\nconst DemoIdContext = React.createContext(undefined);\n\nexport function DemoId({\n id,\n children,\n}: {\n children: React.ReactNode;\n id?: string;\n}) {\n return {children};\n}\n\nexport function useDemoId() {\n return React.useContext(DemoIdContext);\n}\n", "path": "example/playground-demo.tsx", "target": "components/playground-demo.tsx", "type": "registry:example" diff --git a/apps/www/public/r/styles/default/date-demo.json b/apps/www/public/r/styles/default/date-demo.json index 6a0a294da7..0d3d98040b 100644 --- a/apps/www/public/r/styles/default/date-demo.json +++ b/apps/www/public/r/styles/default/date-demo.json @@ -5,7 +5,7 @@ }, "files": [ { - "content": "'use client';\n\nimport React, { useRef } from 'react';\n\nimport type { ValueId } from '@/config/customizer-plugins';\n\nimport { cn } from '@udecode/cn';\nimport { AIChatPlugin, CopilotPlugin } from '@udecode/plate-ai/react';\nimport { AlignPlugin } from '@udecode/plate-alignment/react';\nimport { AutoformatPlugin } from '@udecode/plate-autoformat/react';\nimport {\n BoldPlugin,\n CodePlugin,\n ItalicPlugin,\n StrikethroughPlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n UnderlinePlugin,\n} from '@udecode/plate-basic-marks/react';\nimport { BlockquotePlugin } from '@udecode/plate-block-quote/react';\nimport { SingleLinePlugin } from '@udecode/plate-break/react';\nimport { CaptionPlugin } from '@udecode/plate-caption/react';\nimport { CodeBlockPlugin } from '@udecode/plate-code-block/react';\nimport { CommentsPlugin } from '@udecode/plate-comments/react';\nimport {\n ParagraphPlugin,\n Plate,\n usePlateEditor,\n} from '@udecode/plate-common/react';\nimport { DatePlugin } from '@udecode/plate-date/react';\nimport { DndPlugin } from '@udecode/plate-dnd';\nimport { DocxPlugin } from '@udecode/plate-docx';\nimport { EmojiPlugin } from '@udecode/plate-emoji/react';\nimport { ExcalidrawPlugin } from '@udecode/plate-excalidraw/react';\nimport {\n FontBackgroundColorPlugin,\n FontColorPlugin,\n FontSizePlugin,\n} from '@udecode/plate-font/react';\nimport { HEADING_KEYS } from '@udecode/plate-heading';\nimport { HeadingPlugin, TocPlugin } from '@udecode/plate-heading/react';\nimport { HighlightPlugin } from '@udecode/plate-highlight/react';\nimport { HorizontalRulePlugin } from '@udecode/plate-horizontal-rule/react';\nimport { IndentPlugin } from '@udecode/plate-indent/react';\nimport { IndentListPlugin } from '@udecode/plate-indent-list/react';\nimport { JuicePlugin } from '@udecode/plate-juice';\nimport { KbdPlugin } from '@udecode/plate-kbd/react';\nimport { ColumnPlugin } from '@udecode/plate-layout/react';\nimport { LineHeightPlugin } from '@udecode/plate-line-height/react';\nimport { LinkPlugin } from '@udecode/plate-link/react';\nimport { ListPlugin, TodoListPlugin } from '@udecode/plate-list/react';\nimport { MarkdownPlugin } from '@udecode/plate-markdown';\nimport { ImagePlugin, MediaEmbedPlugin } from '@udecode/plate-media/react';\nimport { MentionPlugin } from '@udecode/plate-mention/react';\nimport { NodeIdPlugin } from '@udecode/plate-node-id';\nimport { NormalizeTypesPlugin } from '@udecode/plate-normalizers';\nimport { PlaywrightPlugin } from '@udecode/plate-playwright';\nimport { DeletePlugin, SelectOnBackspacePlugin } from '@udecode/plate-select';\nimport {\n BlockMenuPlugin,\n BlockSelectionPlugin,\n} from '@udecode/plate-selection/react';\nimport { SlashPlugin } from '@udecode/plate-slash-command/react';\nimport { TablePlugin } from '@udecode/plate-table/react';\nimport { TogglePlugin } from '@udecode/plate-toggle/react';\nimport { TrailingBlockPlugin } from '@udecode/plate-trailing-block';\nimport Prism from 'prismjs';\n\nimport { CheckPlugin } from '@/components/context/check-plugin';\nimport { settingsStore } from '@/components/context/settings-store';\nimport { aiPlugins } from '@/lib/plate/demo/plugins/ai-plugins';\nimport { getAutoformatOptions } from '@/lib/plate/demo/plugins/autoformatOptions';\nimport { copilotPlugins } from '@/lib/plate/demo/plugins/copilot-plugins';\nimport { createPlateUI } from '@/plate/create-plate-ui';\nimport { editableProps } from '@/plate/demo/editableProps';\nimport { isEnabled } from '@/plate/demo/is-enabled';\nimport { DragOverCursorPlugin } from '@/plate/demo/plugins/DragOverCursorPlugin';\nimport { exitBreakPlugin } from '@/plate/demo/plugins/exitBreakPlugin';\nimport { resetBlockTypePlugin } from '@/plate/demo/plugins/resetBlockTypePlugin';\nimport { softBreakPlugin } from '@/plate/demo/plugins/softBreakPlugin';\nimport { tabbablePlugin } from '@/plate/demo/plugins/tabbablePlugin';\nimport { commentsData, usersData } from '@/plate/demo/values/commentsValue';\nimport { usePlaygroundValue } from '@/plate/demo/values/usePlaygroundValue';\nimport { BlockContextMenu } from '@/components/plate-ui/block-context-menu';\nimport { CommentsPopover } from '@/components/plate-ui/comments-popover';\nimport {\n CursorOverlay,\n SelectionOverlayPlugin,\n} from '@/components/plate-ui/cursor-overlay';\nimport { Editor, EditorContainer } from '@/components/plate-ui/editor';\nimport { FixedToolbar } from '@/components/plate-ui/fixed-toolbar';\nimport { FixedToolbarButtons } from '@/components/plate-ui/fixed-toolbar-buttons';\nimport { FloatingToolbar } from '@/components/plate-ui/floating-toolbar';\nimport { FloatingToolbarButtons } from '@/components/plate-ui/floating-toolbar-buttons';\nimport { ImagePreview } from '@/components/plate-ui/image-preview';\nimport {\n FireLiComponent,\n FireMarker,\n} from '@/components/plate-ui/indent-fire-marker';\nimport {\n TodoLi,\n TodoMarker,\n} from '@/components/plate-ui/indent-todo-marker';\nimport { LinkFloatingToolbar } from '@/components/plate-ui/link-floating-toolbar';\n\nimport { usePlaygroundEnabled } from './usePlaygroundEnabled';\n\nexport const usePlaygroundEditor = (id: any = '', scrollSelector?: string) => {\n const enabledPlugins = settingsStore.use.checkedPlugins();\n const overridePlugins = usePlaygroundEnabled(id);\n const autoformatOptions = getAutoformatOptions(id, enabledPlugins);\n\n const value = usePlaygroundValue(id);\n const key = settingsStore.use.version();\n const editorId = id || 'playground-' + key;\n\n return usePlateEditor(\n {\n id: editorId,\n override: {\n components: createPlateUI({\n draggable: isEnabled('dnd', id),\n placeholder: isEnabled('placeholder', id),\n }),\n plugins: overridePlugins,\n },\n plugins: [\n // AI\n ...(id === 'ai' || enabledPlugins[AIChatPlugin.key] ? aiPlugins : []),\n ...(id === 'copilot' || enabledPlugins[CopilotPlugin.key]\n ? copilotPlugins\n : []),\n // Nodes\n HeadingPlugin,\n TocPlugin.configure({\n options: {\n scrollContainerSelector: `#${scrollSelector}`,\n topOffset: 80,\n },\n }),\n BlockquotePlugin,\n CodeBlockPlugin.configure({\n options: {\n prism: Prism,\n },\n }),\n HorizontalRulePlugin,\n LinkPlugin.extend({\n render: { afterEditable: () => },\n }),\n ...(id === 'list' ? [ListPlugin] : []),\n ImagePlugin.extend({\n render: { afterEditable: ImagePreview },\n }),\n MediaEmbedPlugin,\n CaptionPlugin.configure({\n options: {\n plugins: [ImagePlugin, MediaEmbedPlugin],\n },\n }),\n DatePlugin,\n MentionPlugin.configure({\n options: {\n triggerPreviousCharPattern: /^$|^[\\s\"']$/,\n },\n }),\n SlashPlugin,\n TablePlugin.configure({\n options: {\n enableMerging: id === 'tableMerge',\n },\n }),\n ColumnPlugin,\n SelectionOverlayPlugin,\n\n TodoListPlugin,\n TogglePlugin,\n ExcalidrawPlugin,\n // Marks\n BoldPlugin,\n ItalicPlugin,\n UnderlinePlugin,\n StrikethroughPlugin,\n CodePlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n FontColorPlugin,\n FontBackgroundColorPlugin,\n FontSizePlugin,\n HighlightPlugin,\n KbdPlugin,\n\n // Block Style\n AlignPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n MediaEmbedPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n ImagePlugin.key,\n HEADING_KEYS.h6,\n ],\n },\n }),\n IndentPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n }),\n IndentListPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n options: {\n listStyleTypes: {\n fire: {\n liComponent: FireLiComponent,\n markerComponent: FireMarker,\n type: 'fire',\n },\n todo: {\n liComponent: TodoLi,\n markerComponent: TodoMarker,\n type: 'todo',\n },\n },\n },\n }),\n LineHeightPlugin.extend({\n inject: {\n nodeProps: {\n defaultNodeValue: 1.5,\n validNodeValues: [1, 1.2, 1.5, 2, 3],\n },\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n ],\n },\n }),\n\n // Functionality\n AutoformatPlugin.configure({\n options: autoformatOptions,\n }),\n BlockSelectionPlugin.configure({\n options: {\n areaOptions: {\n behaviour: {\n scrolling: {\n speedDivider: 1.5,\n },\n startThreshold: 10,\n },\n boundaries: `#${scrollSelector}`,\n container: `#${scrollSelector}`,\n selectables: [`#${scrollSelector} .slate-selectable`],\n selectionAreaClass: 'slate-selection-area',\n },\n enableContextMenu: true,\n },\n }),\n BlockMenuPlugin.configure({\n render: { aboveEditable: BlockContextMenu },\n }),\n DndPlugin.configure({ options: { enableScroller: true } }),\n EmojiPlugin,\n exitBreakPlugin,\n NodeIdPlugin,\n NormalizeTypesPlugin.configure({\n options: {\n rules: [{ path: [0], strictType: HEADING_KEYS.h1 }],\n },\n }),\n resetBlockTypePlugin,\n SelectOnBackspacePlugin.configure({\n options: {\n query: {\n allow: [ImagePlugin.key, HorizontalRulePlugin.key],\n },\n },\n }),\n DeletePlugin,\n SingleLinePlugin,\n softBreakPlugin,\n tabbablePlugin,\n TrailingBlockPlugin.configure({\n options: { type: ParagraphPlugin.key },\n }),\n DragOverCursorPlugin,\n\n // Collaboration\n CommentsPlugin.configure({\n options: {\n comments: commentsData,\n myUserId: '1',\n users: usersData,\n },\n }),\n\n // Deserialization\n DocxPlugin,\n MarkdownPlugin.configure({ options: { indentList: true } }),\n JuicePlugin,\n\n // Testing\n PlaywrightPlugin.configure({\n enabled: process.env.NODE_ENV !== 'production',\n }),\n ],\n value: value,\n },\n []\n );\n};\n\nexport default function PlaygroundDemo({\n id,\n className,\n scrollSelector,\n}: {\n id?: ValueId;\n className?: string;\n scrollSelector?: string;\n}) {\n const containerRef = useRef(null);\n const enabled = settingsStore.use.checkedComponents();\n\n const editor = usePlaygroundEditor(\n id,\n scrollSelector ?? `blockSelection-${id}`\n );\n\n return (\n \n \n \n \n \n \n \n \n \n\n
\n \n \n\n \n \n \n \n \n \n \n\n \n \n \n \n\n \n \n \n
\n
\n
\n );\n}\n\nconst DemoIdContext = React.createContext(undefined);\n\nexport function DemoId({\n id,\n children,\n}: {\n children: React.ReactNode;\n id?: string;\n}) {\n return {children};\n}\n\nexport function useDemoId() {\n return React.useContext(DemoIdContext);\n}\n", + "content": "'use client';\n\nimport React, { useRef } from 'react';\n\nimport type { ValueId } from '@/config/customizer-plugins';\n\nimport { cn } from '@udecode/cn';\nimport { AIChatPlugin, CopilotPlugin } from '@udecode/plate-ai/react';\nimport { AlignPlugin } from '@udecode/plate-alignment/react';\nimport { AutoformatPlugin } from '@udecode/plate-autoformat/react';\nimport {\n BoldPlugin,\n CodePlugin,\n ItalicPlugin,\n StrikethroughPlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n UnderlinePlugin,\n} from '@udecode/plate-basic-marks/react';\nimport { BlockquotePlugin } from '@udecode/plate-block-quote/react';\nimport { SingleLinePlugin } from '@udecode/plate-break/react';\nimport { CaptionPlugin } from '@udecode/plate-caption/react';\nimport { CodeBlockPlugin } from '@udecode/plate-code-block/react';\nimport { CommentsPlugin } from '@udecode/plate-comments/react';\nimport {\n ParagraphPlugin,\n Plate,\n usePlateEditor,\n} from '@udecode/plate-common/react';\nimport { DatePlugin } from '@udecode/plate-date/react';\nimport { DndPlugin } from '@udecode/plate-dnd';\nimport { DocxPlugin } from '@udecode/plate-docx';\nimport { EmojiPlugin } from '@udecode/plate-emoji/react';\nimport { ExcalidrawPlugin } from '@udecode/plate-excalidraw/react';\nimport {\n FontBackgroundColorPlugin,\n FontColorPlugin,\n FontSizePlugin,\n} from '@udecode/plate-font/react';\nimport { HEADING_KEYS } from '@udecode/plate-heading';\nimport { HeadingPlugin, TocPlugin } from '@udecode/plate-heading/react';\nimport { HighlightPlugin } from '@udecode/plate-highlight/react';\nimport { HorizontalRulePlugin } from '@udecode/plate-horizontal-rule/react';\nimport { IndentPlugin } from '@udecode/plate-indent/react';\nimport { IndentListPlugin } from '@udecode/plate-indent-list/react';\nimport { JuicePlugin } from '@udecode/plate-juice';\nimport { KbdPlugin } from '@udecode/plate-kbd/react';\nimport { ColumnPlugin } from '@udecode/plate-layout/react';\nimport { LineHeightPlugin } from '@udecode/plate-line-height/react';\nimport { LinkPlugin } from '@udecode/plate-link/react';\nimport { ListPlugin, TodoListPlugin } from '@udecode/plate-list/react';\nimport { MarkdownPlugin } from '@udecode/plate-markdown';\nimport { ImagePlugin, MediaEmbedPlugin } from '@udecode/plate-media/react';\nimport { MentionPlugin } from '@udecode/plate-mention/react';\nimport { NodeIdPlugin } from '@udecode/plate-node-id';\nimport { NormalizeTypesPlugin } from '@udecode/plate-normalizers';\nimport { PlaywrightPlugin } from '@udecode/plate-playwright';\nimport { DeletePlugin, SelectOnBackspacePlugin } from '@udecode/plate-select';\nimport {\n BlockMenuPlugin,\n BlockSelectionPlugin,\n} from '@udecode/plate-selection/react';\nimport { SlashPlugin } from '@udecode/plate-slash-command/react';\nimport { TablePlugin } from '@udecode/plate-table/react';\nimport { TogglePlugin } from '@udecode/plate-toggle/react';\nimport { TrailingBlockPlugin } from '@udecode/plate-trailing-block';\nimport Prism from 'prismjs';\n\nimport { CheckPlugin } from '@/components/context/check-plugin';\nimport { settingsStore } from '@/components/context/settings-store';\nimport { aiPlugins } from '@/lib/plate/demo/plugins/ai-plugins';\nimport { getAutoformatOptions } from '@/lib/plate/demo/plugins/autoformatOptions';\nimport { copilotPlugins } from '@/lib/plate/demo/plugins/copilot-plugins';\nimport { createPlateUI } from '@/plate/create-plate-ui';\nimport { editableProps } from '@/plate/demo/editableProps';\nimport { isEnabled } from '@/plate/demo/is-enabled';\nimport { DragOverCursorPlugin } from '@/plate/demo/plugins/DragOverCursorPlugin';\nimport { exitBreakPlugin } from '@/plate/demo/plugins/exitBreakPlugin';\nimport { resetBlockTypePlugin } from '@/plate/demo/plugins/resetBlockTypePlugin';\nimport { softBreakPlugin } from '@/plate/demo/plugins/softBreakPlugin';\nimport { tabbablePlugin } from '@/plate/demo/plugins/tabbablePlugin';\nimport { commentsData, usersData } from '@/plate/demo/values/commentsValue';\nimport { usePlaygroundValue } from '@/plate/demo/values/usePlaygroundValue';\nimport { BlockContextMenu } from '@/components/plate-ui/block-context-menu';\nimport { CommentsPopover } from '@/components/plate-ui/comments-popover';\nimport {\n CursorOverlay,\n SelectionOverlayPlugin,\n} from '@/components/plate-ui/cursor-overlay';\nimport { Editor, EditorContainer } from '@/components/plate-ui/editor';\nimport { FixedToolbar } from '@/components/plate-ui/fixed-toolbar';\nimport { FixedToolbarButtons } from '@/components/plate-ui/fixed-toolbar-buttons';\nimport { FloatingToolbar } from '@/components/plate-ui/floating-toolbar';\nimport { FloatingToolbarButtons } from '@/components/plate-ui/floating-toolbar-buttons';\nimport { ImagePreview } from '@/components/plate-ui/image-preview';\nimport {\n FireLiComponent,\n FireMarker,\n} from '@/components/plate-ui/indent-fire-marker';\nimport {\n TodoLi,\n TodoMarker,\n} from '@/components/plate-ui/indent-todo-marker';\nimport { LinkFloatingToolbar } from '@/components/plate-ui/link-floating-toolbar';\n\nimport { usePlaygroundEnabled } from './usePlaygroundEnabled';\n\nexport const usePlaygroundEditor = (id: any = '', scrollSelector?: string) => {\n const enabledPlugins = settingsStore.use.checkedPlugins();\n const overridePlugins = usePlaygroundEnabled(id);\n const autoformatOptions = getAutoformatOptions(id, enabledPlugins);\n\n const value = usePlaygroundValue(id);\n const key = settingsStore.use.version();\n const editorId = id || 'playground-' + key;\n\n return usePlateEditor(\n {\n id: editorId,\n override: {\n components: createPlateUI({\n draggable: isEnabled('dnd', id),\n placeholder: isEnabled('placeholder', id),\n }),\n plugins: overridePlugins,\n },\n plugins: [\n // AI\n ...(id === 'ai' || enabledPlugins[AIChatPlugin.key] ? aiPlugins : []),\n ...(id === 'copilot' || enabledPlugins[CopilotPlugin.key]\n ? copilotPlugins\n : []),\n // Nodes\n HeadingPlugin,\n TocPlugin.configure({\n options: {\n scrollContainerSelector: `#${scrollSelector}`,\n topOffset: 80,\n },\n }),\n BlockquotePlugin,\n CodeBlockPlugin.configure({\n options: {\n prism: Prism,\n },\n }),\n HorizontalRulePlugin,\n LinkPlugin.extend({\n render: { afterEditable: () => },\n }),\n ...(id === 'list' ? [ListPlugin] : []),\n ImagePlugin.extend({\n options: {\n disableUploadInsert: true,\n },\n render: { afterEditable: ImagePreview },\n }),\n MediaEmbedPlugin,\n CaptionPlugin.configure({\n options: {\n plugins: [ImagePlugin, MediaEmbedPlugin],\n },\n }),\n DatePlugin,\n MentionPlugin.configure({\n options: {\n triggerPreviousCharPattern: /^$|^[\\s\"']$/,\n },\n }),\n SlashPlugin,\n TablePlugin.configure({\n options: {\n enableMerging: id === 'tableMerge',\n },\n }),\n ColumnPlugin,\n SelectionOverlayPlugin,\n\n TodoListPlugin,\n TogglePlugin,\n ExcalidrawPlugin,\n // Marks\n BoldPlugin,\n ItalicPlugin,\n UnderlinePlugin,\n StrikethroughPlugin,\n CodePlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n FontColorPlugin,\n FontBackgroundColorPlugin,\n FontSizePlugin,\n HighlightPlugin,\n KbdPlugin,\n\n // Block Style\n AlignPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n MediaEmbedPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n ImagePlugin.key,\n HEADING_KEYS.h6,\n ],\n },\n }),\n IndentPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n }),\n IndentListPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n options: {\n listStyleTypes: {\n fire: {\n liComponent: FireLiComponent,\n markerComponent: FireMarker,\n type: 'fire',\n },\n todo: {\n liComponent: TodoLi,\n markerComponent: TodoMarker,\n type: 'todo',\n },\n },\n },\n }),\n LineHeightPlugin.extend({\n inject: {\n nodeProps: {\n defaultNodeValue: 1.5,\n validNodeValues: [1, 1.2, 1.5, 2, 3],\n },\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n ],\n },\n }),\n\n // Functionality\n AutoformatPlugin.configure({\n options: autoformatOptions,\n }),\n BlockSelectionPlugin.configure({\n options: {\n areaOptions: {\n behaviour: {\n scrolling: {\n speedDivider: 1.5,\n },\n startThreshold: 10,\n },\n boundaries: `#${scrollSelector}`,\n container: `#${scrollSelector}`,\n selectables: [`#${scrollSelector} .slate-selectable`],\n selectionAreaClass: 'slate-selection-area',\n },\n enableContextMenu: true,\n },\n }),\n BlockMenuPlugin.configure({\n render: { aboveEditable: BlockContextMenu },\n }),\n DndPlugin.configure({\n options: {\n enableScroller: true,\n onDropFiles: ({ dragItem, editor, target }) => {\n editor\n .getTransforms(ImagePlugin)\n .insertImageFromFiles(dragItem.files, {\n at: target,\n nextBlock: false,\n });\n },\n },\n }),\n EmojiPlugin,\n exitBreakPlugin,\n NodeIdPlugin,\n NormalizeTypesPlugin.configure({\n options: {\n rules: [{ path: [0], strictType: HEADING_KEYS.h1 }],\n },\n }),\n resetBlockTypePlugin,\n SelectOnBackspacePlugin.configure({\n options: {\n query: {\n allow: [ImagePlugin.key, HorizontalRulePlugin.key],\n },\n },\n }),\n DeletePlugin,\n SingleLinePlugin,\n softBreakPlugin,\n tabbablePlugin,\n TrailingBlockPlugin.configure({\n options: { type: ParagraphPlugin.key },\n }),\n DragOverCursorPlugin,\n\n // Collaboration\n CommentsPlugin.configure({\n options: {\n comments: commentsData,\n myUserId: '1',\n users: usersData,\n },\n }),\n\n // Deserialization\n DocxPlugin,\n MarkdownPlugin.configure({ options: { indentList: true } }),\n JuicePlugin,\n\n // Testing\n PlaywrightPlugin.configure({\n enabled: process.env.NODE_ENV !== 'production',\n }),\n ],\n value: value,\n },\n []\n );\n};\n\nexport default function PlaygroundDemo({\n id,\n className,\n scrollSelector,\n}: {\n id?: ValueId;\n className?: string;\n scrollSelector?: string;\n}) {\n const containerRef = useRef(null);\n const enabled = settingsStore.use.checkedComponents();\n\n const editor = usePlaygroundEditor(\n id,\n scrollSelector ?? `blockSelection-${id}`\n );\n\n return (\n \n \n \n \n \n \n \n \n \n\n
\n \n \n\n \n \n \n \n \n \n \n\n \n \n \n \n\n \n \n \n
\n
\n
\n );\n}\n\nconst DemoIdContext = React.createContext(undefined);\n\nexport function DemoId({\n id,\n children,\n}: {\n children: React.ReactNode;\n id?: string;\n}) {\n return {children};\n}\n\nexport function useDemoId() {\n return React.useContext(DemoIdContext);\n}\n", "path": "example/playground-demo.tsx", "target": "components/playground-demo.tsx", "type": "registry:example" diff --git a/apps/www/public/r/styles/default/dnd-demo.json b/apps/www/public/r/styles/default/dnd-demo.json index 8d0dc9f8cc..a94cca653f 100644 --- a/apps/www/public/r/styles/default/dnd-demo.json +++ b/apps/www/public/r/styles/default/dnd-demo.json @@ -5,7 +5,7 @@ }, "files": [ { - "content": "'use client';\n\nimport React, { useRef } from 'react';\n\nimport type { ValueId } from '@/config/customizer-plugins';\n\nimport { cn } from '@udecode/cn';\nimport { AIChatPlugin, CopilotPlugin } from '@udecode/plate-ai/react';\nimport { AlignPlugin } from '@udecode/plate-alignment/react';\nimport { AutoformatPlugin } from '@udecode/plate-autoformat/react';\nimport {\n BoldPlugin,\n CodePlugin,\n ItalicPlugin,\n StrikethroughPlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n UnderlinePlugin,\n} from '@udecode/plate-basic-marks/react';\nimport { BlockquotePlugin } from '@udecode/plate-block-quote/react';\nimport { SingleLinePlugin } from '@udecode/plate-break/react';\nimport { CaptionPlugin } from '@udecode/plate-caption/react';\nimport { CodeBlockPlugin } from '@udecode/plate-code-block/react';\nimport { CommentsPlugin } from '@udecode/plate-comments/react';\nimport {\n ParagraphPlugin,\n Plate,\n usePlateEditor,\n} from '@udecode/plate-common/react';\nimport { DatePlugin } from '@udecode/plate-date/react';\nimport { DndPlugin } from '@udecode/plate-dnd';\nimport { DocxPlugin } from '@udecode/plate-docx';\nimport { EmojiPlugin } from '@udecode/plate-emoji/react';\nimport { ExcalidrawPlugin } from '@udecode/plate-excalidraw/react';\nimport {\n FontBackgroundColorPlugin,\n FontColorPlugin,\n FontSizePlugin,\n} from '@udecode/plate-font/react';\nimport { HEADING_KEYS } from '@udecode/plate-heading';\nimport { HeadingPlugin, TocPlugin } from '@udecode/plate-heading/react';\nimport { HighlightPlugin } from '@udecode/plate-highlight/react';\nimport { HorizontalRulePlugin } from '@udecode/plate-horizontal-rule/react';\nimport { IndentPlugin } from '@udecode/plate-indent/react';\nimport { IndentListPlugin } from '@udecode/plate-indent-list/react';\nimport { JuicePlugin } from '@udecode/plate-juice';\nimport { KbdPlugin } from '@udecode/plate-kbd/react';\nimport { ColumnPlugin } from '@udecode/plate-layout/react';\nimport { LineHeightPlugin } from '@udecode/plate-line-height/react';\nimport { LinkPlugin } from '@udecode/plate-link/react';\nimport { ListPlugin, TodoListPlugin } from '@udecode/plate-list/react';\nimport { MarkdownPlugin } from '@udecode/plate-markdown';\nimport { ImagePlugin, MediaEmbedPlugin } from '@udecode/plate-media/react';\nimport { MentionPlugin } from '@udecode/plate-mention/react';\nimport { NodeIdPlugin } from '@udecode/plate-node-id';\nimport { NormalizeTypesPlugin } from '@udecode/plate-normalizers';\nimport { PlaywrightPlugin } from '@udecode/plate-playwright';\nimport { DeletePlugin, SelectOnBackspacePlugin } from '@udecode/plate-select';\nimport {\n BlockMenuPlugin,\n BlockSelectionPlugin,\n} from '@udecode/plate-selection/react';\nimport { SlashPlugin } from '@udecode/plate-slash-command/react';\nimport { TablePlugin } from '@udecode/plate-table/react';\nimport { TogglePlugin } from '@udecode/plate-toggle/react';\nimport { TrailingBlockPlugin } from '@udecode/plate-trailing-block';\nimport Prism from 'prismjs';\n\nimport { CheckPlugin } from '@/components/context/check-plugin';\nimport { settingsStore } from '@/components/context/settings-store';\nimport { aiPlugins } from '@/lib/plate/demo/plugins/ai-plugins';\nimport { getAutoformatOptions } from '@/lib/plate/demo/plugins/autoformatOptions';\nimport { copilotPlugins } from '@/lib/plate/demo/plugins/copilot-plugins';\nimport { createPlateUI } from '@/plate/create-plate-ui';\nimport { editableProps } from '@/plate/demo/editableProps';\nimport { isEnabled } from '@/plate/demo/is-enabled';\nimport { DragOverCursorPlugin } from '@/plate/demo/plugins/DragOverCursorPlugin';\nimport { exitBreakPlugin } from '@/plate/demo/plugins/exitBreakPlugin';\nimport { resetBlockTypePlugin } from '@/plate/demo/plugins/resetBlockTypePlugin';\nimport { softBreakPlugin } from '@/plate/demo/plugins/softBreakPlugin';\nimport { tabbablePlugin } from '@/plate/demo/plugins/tabbablePlugin';\nimport { commentsData, usersData } from '@/plate/demo/values/commentsValue';\nimport { usePlaygroundValue } from '@/plate/demo/values/usePlaygroundValue';\nimport { BlockContextMenu } from '@/components/plate-ui/block-context-menu';\nimport { CommentsPopover } from '@/components/plate-ui/comments-popover';\nimport {\n CursorOverlay,\n SelectionOverlayPlugin,\n} from '@/components/plate-ui/cursor-overlay';\nimport { Editor, EditorContainer } from '@/components/plate-ui/editor';\nimport { FixedToolbar } from '@/components/plate-ui/fixed-toolbar';\nimport { FixedToolbarButtons } from '@/components/plate-ui/fixed-toolbar-buttons';\nimport { FloatingToolbar } from '@/components/plate-ui/floating-toolbar';\nimport { FloatingToolbarButtons } from '@/components/plate-ui/floating-toolbar-buttons';\nimport { ImagePreview } from '@/components/plate-ui/image-preview';\nimport {\n FireLiComponent,\n FireMarker,\n} from '@/components/plate-ui/indent-fire-marker';\nimport {\n TodoLi,\n TodoMarker,\n} from '@/components/plate-ui/indent-todo-marker';\nimport { LinkFloatingToolbar } from '@/components/plate-ui/link-floating-toolbar';\n\nimport { usePlaygroundEnabled } from './usePlaygroundEnabled';\n\nexport const usePlaygroundEditor = (id: any = '', scrollSelector?: string) => {\n const enabledPlugins = settingsStore.use.checkedPlugins();\n const overridePlugins = usePlaygroundEnabled(id);\n const autoformatOptions = getAutoformatOptions(id, enabledPlugins);\n\n const value = usePlaygroundValue(id);\n const key = settingsStore.use.version();\n const editorId = id || 'playground-' + key;\n\n return usePlateEditor(\n {\n id: editorId,\n override: {\n components: createPlateUI({\n draggable: isEnabled('dnd', id),\n placeholder: isEnabled('placeholder', id),\n }),\n plugins: overridePlugins,\n },\n plugins: [\n // AI\n ...(id === 'ai' || enabledPlugins[AIChatPlugin.key] ? aiPlugins : []),\n ...(id === 'copilot' || enabledPlugins[CopilotPlugin.key]\n ? copilotPlugins\n : []),\n // Nodes\n HeadingPlugin,\n TocPlugin.configure({\n options: {\n scrollContainerSelector: `#${scrollSelector}`,\n topOffset: 80,\n },\n }),\n BlockquotePlugin,\n CodeBlockPlugin.configure({\n options: {\n prism: Prism,\n },\n }),\n HorizontalRulePlugin,\n LinkPlugin.extend({\n render: { afterEditable: () => },\n }),\n ...(id === 'list' ? [ListPlugin] : []),\n ImagePlugin.extend({\n render: { afterEditable: ImagePreview },\n }),\n MediaEmbedPlugin,\n CaptionPlugin.configure({\n options: {\n plugins: [ImagePlugin, MediaEmbedPlugin],\n },\n }),\n DatePlugin,\n MentionPlugin.configure({\n options: {\n triggerPreviousCharPattern: /^$|^[\\s\"']$/,\n },\n }),\n SlashPlugin,\n TablePlugin.configure({\n options: {\n enableMerging: id === 'tableMerge',\n },\n }),\n ColumnPlugin,\n SelectionOverlayPlugin,\n\n TodoListPlugin,\n TogglePlugin,\n ExcalidrawPlugin,\n // Marks\n BoldPlugin,\n ItalicPlugin,\n UnderlinePlugin,\n StrikethroughPlugin,\n CodePlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n FontColorPlugin,\n FontBackgroundColorPlugin,\n FontSizePlugin,\n HighlightPlugin,\n KbdPlugin,\n\n // Block Style\n AlignPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n MediaEmbedPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n ImagePlugin.key,\n HEADING_KEYS.h6,\n ],\n },\n }),\n IndentPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n }),\n IndentListPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n options: {\n listStyleTypes: {\n fire: {\n liComponent: FireLiComponent,\n markerComponent: FireMarker,\n type: 'fire',\n },\n todo: {\n liComponent: TodoLi,\n markerComponent: TodoMarker,\n type: 'todo',\n },\n },\n },\n }),\n LineHeightPlugin.extend({\n inject: {\n nodeProps: {\n defaultNodeValue: 1.5,\n validNodeValues: [1, 1.2, 1.5, 2, 3],\n },\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n ],\n },\n }),\n\n // Functionality\n AutoformatPlugin.configure({\n options: autoformatOptions,\n }),\n BlockSelectionPlugin.configure({\n options: {\n areaOptions: {\n behaviour: {\n scrolling: {\n speedDivider: 1.5,\n },\n startThreshold: 10,\n },\n boundaries: `#${scrollSelector}`,\n container: `#${scrollSelector}`,\n selectables: [`#${scrollSelector} .slate-selectable`],\n selectionAreaClass: 'slate-selection-area',\n },\n enableContextMenu: true,\n },\n }),\n BlockMenuPlugin.configure({\n render: { aboveEditable: BlockContextMenu },\n }),\n DndPlugin.configure({ options: { enableScroller: true } }),\n EmojiPlugin,\n exitBreakPlugin,\n NodeIdPlugin,\n NormalizeTypesPlugin.configure({\n options: {\n rules: [{ path: [0], strictType: HEADING_KEYS.h1 }],\n },\n }),\n resetBlockTypePlugin,\n SelectOnBackspacePlugin.configure({\n options: {\n query: {\n allow: [ImagePlugin.key, HorizontalRulePlugin.key],\n },\n },\n }),\n DeletePlugin,\n SingleLinePlugin,\n softBreakPlugin,\n tabbablePlugin,\n TrailingBlockPlugin.configure({\n options: { type: ParagraphPlugin.key },\n }),\n DragOverCursorPlugin,\n\n // Collaboration\n CommentsPlugin.configure({\n options: {\n comments: commentsData,\n myUserId: '1',\n users: usersData,\n },\n }),\n\n // Deserialization\n DocxPlugin,\n MarkdownPlugin.configure({ options: { indentList: true } }),\n JuicePlugin,\n\n // Testing\n PlaywrightPlugin.configure({\n enabled: process.env.NODE_ENV !== 'production',\n }),\n ],\n value: value,\n },\n []\n );\n};\n\nexport default function PlaygroundDemo({\n id,\n className,\n scrollSelector,\n}: {\n id?: ValueId;\n className?: string;\n scrollSelector?: string;\n}) {\n const containerRef = useRef(null);\n const enabled = settingsStore.use.checkedComponents();\n\n const editor = usePlaygroundEditor(\n id,\n scrollSelector ?? `blockSelection-${id}`\n );\n\n return (\n \n \n \n \n \n \n \n \n \n\n
\n \n \n\n \n \n \n \n \n \n \n\n \n \n \n \n\n \n \n \n
\n
\n
\n );\n}\n\nconst DemoIdContext = React.createContext(undefined);\n\nexport function DemoId({\n id,\n children,\n}: {\n children: React.ReactNode;\n id?: string;\n}) {\n return {children};\n}\n\nexport function useDemoId() {\n return React.useContext(DemoIdContext);\n}\n", + "content": "'use client';\n\nimport React, { useRef } from 'react';\n\nimport type { ValueId } from '@/config/customizer-plugins';\n\nimport { cn } from '@udecode/cn';\nimport { AIChatPlugin, CopilotPlugin } from '@udecode/plate-ai/react';\nimport { AlignPlugin } from '@udecode/plate-alignment/react';\nimport { AutoformatPlugin } from '@udecode/plate-autoformat/react';\nimport {\n BoldPlugin,\n CodePlugin,\n ItalicPlugin,\n StrikethroughPlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n UnderlinePlugin,\n} from '@udecode/plate-basic-marks/react';\nimport { BlockquotePlugin } from '@udecode/plate-block-quote/react';\nimport { SingleLinePlugin } from '@udecode/plate-break/react';\nimport { CaptionPlugin } from '@udecode/plate-caption/react';\nimport { CodeBlockPlugin } from '@udecode/plate-code-block/react';\nimport { CommentsPlugin } from '@udecode/plate-comments/react';\nimport {\n ParagraphPlugin,\n Plate,\n usePlateEditor,\n} from '@udecode/plate-common/react';\nimport { DatePlugin } from '@udecode/plate-date/react';\nimport { DndPlugin } from '@udecode/plate-dnd';\nimport { DocxPlugin } from '@udecode/plate-docx';\nimport { EmojiPlugin } from '@udecode/plate-emoji/react';\nimport { ExcalidrawPlugin } from '@udecode/plate-excalidraw/react';\nimport {\n FontBackgroundColorPlugin,\n FontColorPlugin,\n FontSizePlugin,\n} from '@udecode/plate-font/react';\nimport { HEADING_KEYS } from '@udecode/plate-heading';\nimport { HeadingPlugin, TocPlugin } from '@udecode/plate-heading/react';\nimport { HighlightPlugin } from '@udecode/plate-highlight/react';\nimport { HorizontalRulePlugin } from '@udecode/plate-horizontal-rule/react';\nimport { IndentPlugin } from '@udecode/plate-indent/react';\nimport { IndentListPlugin } from '@udecode/plate-indent-list/react';\nimport { JuicePlugin } from '@udecode/plate-juice';\nimport { KbdPlugin } from '@udecode/plate-kbd/react';\nimport { ColumnPlugin } from '@udecode/plate-layout/react';\nimport { LineHeightPlugin } from '@udecode/plate-line-height/react';\nimport { LinkPlugin } from '@udecode/plate-link/react';\nimport { ListPlugin, TodoListPlugin } from '@udecode/plate-list/react';\nimport { MarkdownPlugin } from '@udecode/plate-markdown';\nimport { ImagePlugin, MediaEmbedPlugin } from '@udecode/plate-media/react';\nimport { MentionPlugin } from '@udecode/plate-mention/react';\nimport { NodeIdPlugin } from '@udecode/plate-node-id';\nimport { NormalizeTypesPlugin } from '@udecode/plate-normalizers';\nimport { PlaywrightPlugin } from '@udecode/plate-playwright';\nimport { DeletePlugin, SelectOnBackspacePlugin } from '@udecode/plate-select';\nimport {\n BlockMenuPlugin,\n BlockSelectionPlugin,\n} from '@udecode/plate-selection/react';\nimport { SlashPlugin } from '@udecode/plate-slash-command/react';\nimport { TablePlugin } from '@udecode/plate-table/react';\nimport { TogglePlugin } from '@udecode/plate-toggle/react';\nimport { TrailingBlockPlugin } from '@udecode/plate-trailing-block';\nimport Prism from 'prismjs';\n\nimport { CheckPlugin } from '@/components/context/check-plugin';\nimport { settingsStore } from '@/components/context/settings-store';\nimport { aiPlugins } from '@/lib/plate/demo/plugins/ai-plugins';\nimport { getAutoformatOptions } from '@/lib/plate/demo/plugins/autoformatOptions';\nimport { copilotPlugins } from '@/lib/plate/demo/plugins/copilot-plugins';\nimport { createPlateUI } from '@/plate/create-plate-ui';\nimport { editableProps } from '@/plate/demo/editableProps';\nimport { isEnabled } from '@/plate/demo/is-enabled';\nimport { DragOverCursorPlugin } from '@/plate/demo/plugins/DragOverCursorPlugin';\nimport { exitBreakPlugin } from '@/plate/demo/plugins/exitBreakPlugin';\nimport { resetBlockTypePlugin } from '@/plate/demo/plugins/resetBlockTypePlugin';\nimport { softBreakPlugin } from '@/plate/demo/plugins/softBreakPlugin';\nimport { tabbablePlugin } from '@/plate/demo/plugins/tabbablePlugin';\nimport { commentsData, usersData } from '@/plate/demo/values/commentsValue';\nimport { usePlaygroundValue } from '@/plate/demo/values/usePlaygroundValue';\nimport { BlockContextMenu } from '@/components/plate-ui/block-context-menu';\nimport { CommentsPopover } from '@/components/plate-ui/comments-popover';\nimport {\n CursorOverlay,\n SelectionOverlayPlugin,\n} from '@/components/plate-ui/cursor-overlay';\nimport { Editor, EditorContainer } from '@/components/plate-ui/editor';\nimport { FixedToolbar } from '@/components/plate-ui/fixed-toolbar';\nimport { FixedToolbarButtons } from '@/components/plate-ui/fixed-toolbar-buttons';\nimport { FloatingToolbar } from '@/components/plate-ui/floating-toolbar';\nimport { FloatingToolbarButtons } from '@/components/plate-ui/floating-toolbar-buttons';\nimport { ImagePreview } from '@/components/plate-ui/image-preview';\nimport {\n FireLiComponent,\n FireMarker,\n} from '@/components/plate-ui/indent-fire-marker';\nimport {\n TodoLi,\n TodoMarker,\n} from '@/components/plate-ui/indent-todo-marker';\nimport { LinkFloatingToolbar } from '@/components/plate-ui/link-floating-toolbar';\n\nimport { usePlaygroundEnabled } from './usePlaygroundEnabled';\n\nexport const usePlaygroundEditor = (id: any = '', scrollSelector?: string) => {\n const enabledPlugins = settingsStore.use.checkedPlugins();\n const overridePlugins = usePlaygroundEnabled(id);\n const autoformatOptions = getAutoformatOptions(id, enabledPlugins);\n\n const value = usePlaygroundValue(id);\n const key = settingsStore.use.version();\n const editorId = id || 'playground-' + key;\n\n return usePlateEditor(\n {\n id: editorId,\n override: {\n components: createPlateUI({\n draggable: isEnabled('dnd', id),\n placeholder: isEnabled('placeholder', id),\n }),\n plugins: overridePlugins,\n },\n plugins: [\n // AI\n ...(id === 'ai' || enabledPlugins[AIChatPlugin.key] ? aiPlugins : []),\n ...(id === 'copilot' || enabledPlugins[CopilotPlugin.key]\n ? copilotPlugins\n : []),\n // Nodes\n HeadingPlugin,\n TocPlugin.configure({\n options: {\n scrollContainerSelector: `#${scrollSelector}`,\n topOffset: 80,\n },\n }),\n BlockquotePlugin,\n CodeBlockPlugin.configure({\n options: {\n prism: Prism,\n },\n }),\n HorizontalRulePlugin,\n LinkPlugin.extend({\n render: { afterEditable: () => },\n }),\n ...(id === 'list' ? [ListPlugin] : []),\n ImagePlugin.extend({\n options: {\n disableUploadInsert: true,\n },\n render: { afterEditable: ImagePreview },\n }),\n MediaEmbedPlugin,\n CaptionPlugin.configure({\n options: {\n plugins: [ImagePlugin, MediaEmbedPlugin],\n },\n }),\n DatePlugin,\n MentionPlugin.configure({\n options: {\n triggerPreviousCharPattern: /^$|^[\\s\"']$/,\n },\n }),\n SlashPlugin,\n TablePlugin.configure({\n options: {\n enableMerging: id === 'tableMerge',\n },\n }),\n ColumnPlugin,\n SelectionOverlayPlugin,\n\n TodoListPlugin,\n TogglePlugin,\n ExcalidrawPlugin,\n // Marks\n BoldPlugin,\n ItalicPlugin,\n UnderlinePlugin,\n StrikethroughPlugin,\n CodePlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n FontColorPlugin,\n FontBackgroundColorPlugin,\n FontSizePlugin,\n HighlightPlugin,\n KbdPlugin,\n\n // Block Style\n AlignPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n MediaEmbedPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n ImagePlugin.key,\n HEADING_KEYS.h6,\n ],\n },\n }),\n IndentPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n }),\n IndentListPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n options: {\n listStyleTypes: {\n fire: {\n liComponent: FireLiComponent,\n markerComponent: FireMarker,\n type: 'fire',\n },\n todo: {\n liComponent: TodoLi,\n markerComponent: TodoMarker,\n type: 'todo',\n },\n },\n },\n }),\n LineHeightPlugin.extend({\n inject: {\n nodeProps: {\n defaultNodeValue: 1.5,\n validNodeValues: [1, 1.2, 1.5, 2, 3],\n },\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n ],\n },\n }),\n\n // Functionality\n AutoformatPlugin.configure({\n options: autoformatOptions,\n }),\n BlockSelectionPlugin.configure({\n options: {\n areaOptions: {\n behaviour: {\n scrolling: {\n speedDivider: 1.5,\n },\n startThreshold: 10,\n },\n boundaries: `#${scrollSelector}`,\n container: `#${scrollSelector}`,\n selectables: [`#${scrollSelector} .slate-selectable`],\n selectionAreaClass: 'slate-selection-area',\n },\n enableContextMenu: true,\n },\n }),\n BlockMenuPlugin.configure({\n render: { aboveEditable: BlockContextMenu },\n }),\n DndPlugin.configure({\n options: {\n enableScroller: true,\n onDropFiles: ({ dragItem, editor, target }) => {\n editor\n .getTransforms(ImagePlugin)\n .insertImageFromFiles(dragItem.files, {\n at: target,\n nextBlock: false,\n });\n },\n },\n }),\n EmojiPlugin,\n exitBreakPlugin,\n NodeIdPlugin,\n NormalizeTypesPlugin.configure({\n options: {\n rules: [{ path: [0], strictType: HEADING_KEYS.h1 }],\n },\n }),\n resetBlockTypePlugin,\n SelectOnBackspacePlugin.configure({\n options: {\n query: {\n allow: [ImagePlugin.key, HorizontalRulePlugin.key],\n },\n },\n }),\n DeletePlugin,\n SingleLinePlugin,\n softBreakPlugin,\n tabbablePlugin,\n TrailingBlockPlugin.configure({\n options: { type: ParagraphPlugin.key },\n }),\n DragOverCursorPlugin,\n\n // Collaboration\n CommentsPlugin.configure({\n options: {\n comments: commentsData,\n myUserId: '1',\n users: usersData,\n },\n }),\n\n // Deserialization\n DocxPlugin,\n MarkdownPlugin.configure({ options: { indentList: true } }),\n JuicePlugin,\n\n // Testing\n PlaywrightPlugin.configure({\n enabled: process.env.NODE_ENV !== 'production',\n }),\n ],\n value: value,\n },\n []\n );\n};\n\nexport default function PlaygroundDemo({\n id,\n className,\n scrollSelector,\n}: {\n id?: ValueId;\n className?: string;\n scrollSelector?: string;\n}) {\n const containerRef = useRef(null);\n const enabled = settingsStore.use.checkedComponents();\n\n const editor = usePlaygroundEditor(\n id,\n scrollSelector ?? `blockSelection-${id}`\n );\n\n return (\n \n \n \n \n \n \n \n \n \n\n
\n \n \n\n \n \n \n \n \n \n \n\n \n \n \n \n\n \n \n \n
\n
\n
\n );\n}\n\nconst DemoIdContext = React.createContext(undefined);\n\nexport function DemoId({\n id,\n children,\n}: {\n children: React.ReactNode;\n id?: string;\n}) {\n return {children};\n}\n\nexport function useDemoId() {\n return React.useContext(DemoIdContext);\n}\n", "path": "example/playground-demo.tsx", "target": "components/playground-demo.tsx", "type": "registry:example" diff --git a/apps/www/public/r/styles/default/emoji-demo.json b/apps/www/public/r/styles/default/emoji-demo.json index 87699abcef..ab4cc9118a 100644 --- a/apps/www/public/r/styles/default/emoji-demo.json +++ b/apps/www/public/r/styles/default/emoji-demo.json @@ -4,7 +4,7 @@ }, "files": [ { - "content": "'use client';\n\nimport React, { useRef } from 'react';\n\nimport type { ValueId } from '@/config/customizer-plugins';\n\nimport { cn } from '@udecode/cn';\nimport { AIChatPlugin, CopilotPlugin } from '@udecode/plate-ai/react';\nimport { AlignPlugin } from '@udecode/plate-alignment/react';\nimport { AutoformatPlugin } from '@udecode/plate-autoformat/react';\nimport {\n BoldPlugin,\n CodePlugin,\n ItalicPlugin,\n StrikethroughPlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n UnderlinePlugin,\n} from '@udecode/plate-basic-marks/react';\nimport { BlockquotePlugin } from '@udecode/plate-block-quote/react';\nimport { SingleLinePlugin } from '@udecode/plate-break/react';\nimport { CaptionPlugin } from '@udecode/plate-caption/react';\nimport { CodeBlockPlugin } from '@udecode/plate-code-block/react';\nimport { CommentsPlugin } from '@udecode/plate-comments/react';\nimport {\n ParagraphPlugin,\n Plate,\n usePlateEditor,\n} from '@udecode/plate-common/react';\nimport { DatePlugin } from '@udecode/plate-date/react';\nimport { DndPlugin } from '@udecode/plate-dnd';\nimport { DocxPlugin } from '@udecode/plate-docx';\nimport { EmojiPlugin } from '@udecode/plate-emoji/react';\nimport { ExcalidrawPlugin } from '@udecode/plate-excalidraw/react';\nimport {\n FontBackgroundColorPlugin,\n FontColorPlugin,\n FontSizePlugin,\n} from '@udecode/plate-font/react';\nimport { HEADING_KEYS } from '@udecode/plate-heading';\nimport { HeadingPlugin, TocPlugin } from '@udecode/plate-heading/react';\nimport { HighlightPlugin } from '@udecode/plate-highlight/react';\nimport { HorizontalRulePlugin } from '@udecode/plate-horizontal-rule/react';\nimport { IndentPlugin } from '@udecode/plate-indent/react';\nimport { IndentListPlugin } from '@udecode/plate-indent-list/react';\nimport { JuicePlugin } from '@udecode/plate-juice';\nimport { KbdPlugin } from '@udecode/plate-kbd/react';\nimport { ColumnPlugin } from '@udecode/plate-layout/react';\nimport { LineHeightPlugin } from '@udecode/plate-line-height/react';\nimport { LinkPlugin } from '@udecode/plate-link/react';\nimport { ListPlugin, TodoListPlugin } from '@udecode/plate-list/react';\nimport { MarkdownPlugin } from '@udecode/plate-markdown';\nimport { ImagePlugin, MediaEmbedPlugin } from '@udecode/plate-media/react';\nimport { MentionPlugin } from '@udecode/plate-mention/react';\nimport { NodeIdPlugin } from '@udecode/plate-node-id';\nimport { NormalizeTypesPlugin } from '@udecode/plate-normalizers';\nimport { PlaywrightPlugin } from '@udecode/plate-playwright';\nimport { DeletePlugin, SelectOnBackspacePlugin } from '@udecode/plate-select';\nimport {\n BlockMenuPlugin,\n BlockSelectionPlugin,\n} from '@udecode/plate-selection/react';\nimport { SlashPlugin } from '@udecode/plate-slash-command/react';\nimport { TablePlugin } from '@udecode/plate-table/react';\nimport { TogglePlugin } from '@udecode/plate-toggle/react';\nimport { TrailingBlockPlugin } from '@udecode/plate-trailing-block';\nimport Prism from 'prismjs';\n\nimport { CheckPlugin } from '@/components/context/check-plugin';\nimport { settingsStore } from '@/components/context/settings-store';\nimport { aiPlugins } from '@/lib/plate/demo/plugins/ai-plugins';\nimport { getAutoformatOptions } from '@/lib/plate/demo/plugins/autoformatOptions';\nimport { copilotPlugins } from '@/lib/plate/demo/plugins/copilot-plugins';\nimport { createPlateUI } from '@/plate/create-plate-ui';\nimport { editableProps } from '@/plate/demo/editableProps';\nimport { isEnabled } from '@/plate/demo/is-enabled';\nimport { DragOverCursorPlugin } from '@/plate/demo/plugins/DragOverCursorPlugin';\nimport { exitBreakPlugin } from '@/plate/demo/plugins/exitBreakPlugin';\nimport { resetBlockTypePlugin } from '@/plate/demo/plugins/resetBlockTypePlugin';\nimport { softBreakPlugin } from '@/plate/demo/plugins/softBreakPlugin';\nimport { tabbablePlugin } from '@/plate/demo/plugins/tabbablePlugin';\nimport { commentsData, usersData } from '@/plate/demo/values/commentsValue';\nimport { usePlaygroundValue } from '@/plate/demo/values/usePlaygroundValue';\nimport { BlockContextMenu } from '@/components/plate-ui/block-context-menu';\nimport { CommentsPopover } from '@/components/plate-ui/comments-popover';\nimport {\n CursorOverlay,\n SelectionOverlayPlugin,\n} from '@/components/plate-ui/cursor-overlay';\nimport { Editor, EditorContainer } from '@/components/plate-ui/editor';\nimport { FixedToolbar } from '@/components/plate-ui/fixed-toolbar';\nimport { FixedToolbarButtons } from '@/components/plate-ui/fixed-toolbar-buttons';\nimport { FloatingToolbar } from '@/components/plate-ui/floating-toolbar';\nimport { FloatingToolbarButtons } from '@/components/plate-ui/floating-toolbar-buttons';\nimport { ImagePreview } from '@/components/plate-ui/image-preview';\nimport {\n FireLiComponent,\n FireMarker,\n} from '@/components/plate-ui/indent-fire-marker';\nimport {\n TodoLi,\n TodoMarker,\n} from '@/components/plate-ui/indent-todo-marker';\nimport { LinkFloatingToolbar } from '@/components/plate-ui/link-floating-toolbar';\n\nimport { usePlaygroundEnabled } from './usePlaygroundEnabled';\n\nexport const usePlaygroundEditor = (id: any = '', scrollSelector?: string) => {\n const enabledPlugins = settingsStore.use.checkedPlugins();\n const overridePlugins = usePlaygroundEnabled(id);\n const autoformatOptions = getAutoformatOptions(id, enabledPlugins);\n\n const value = usePlaygroundValue(id);\n const key = settingsStore.use.version();\n const editorId = id || 'playground-' + key;\n\n return usePlateEditor(\n {\n id: editorId,\n override: {\n components: createPlateUI({\n draggable: isEnabled('dnd', id),\n placeholder: isEnabled('placeholder', id),\n }),\n plugins: overridePlugins,\n },\n plugins: [\n // AI\n ...(id === 'ai' || enabledPlugins[AIChatPlugin.key] ? aiPlugins : []),\n ...(id === 'copilot' || enabledPlugins[CopilotPlugin.key]\n ? copilotPlugins\n : []),\n // Nodes\n HeadingPlugin,\n TocPlugin.configure({\n options: {\n scrollContainerSelector: `#${scrollSelector}`,\n topOffset: 80,\n },\n }),\n BlockquotePlugin,\n CodeBlockPlugin.configure({\n options: {\n prism: Prism,\n },\n }),\n HorizontalRulePlugin,\n LinkPlugin.extend({\n render: { afterEditable: () => },\n }),\n ...(id === 'list' ? [ListPlugin] : []),\n ImagePlugin.extend({\n render: { afterEditable: ImagePreview },\n }),\n MediaEmbedPlugin,\n CaptionPlugin.configure({\n options: {\n plugins: [ImagePlugin, MediaEmbedPlugin],\n },\n }),\n DatePlugin,\n MentionPlugin.configure({\n options: {\n triggerPreviousCharPattern: /^$|^[\\s\"']$/,\n },\n }),\n SlashPlugin,\n TablePlugin.configure({\n options: {\n enableMerging: id === 'tableMerge',\n },\n }),\n ColumnPlugin,\n SelectionOverlayPlugin,\n\n TodoListPlugin,\n TogglePlugin,\n ExcalidrawPlugin,\n // Marks\n BoldPlugin,\n ItalicPlugin,\n UnderlinePlugin,\n StrikethroughPlugin,\n CodePlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n FontColorPlugin,\n FontBackgroundColorPlugin,\n FontSizePlugin,\n HighlightPlugin,\n KbdPlugin,\n\n // Block Style\n AlignPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n MediaEmbedPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n ImagePlugin.key,\n HEADING_KEYS.h6,\n ],\n },\n }),\n IndentPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n }),\n IndentListPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n options: {\n listStyleTypes: {\n fire: {\n liComponent: FireLiComponent,\n markerComponent: FireMarker,\n type: 'fire',\n },\n todo: {\n liComponent: TodoLi,\n markerComponent: TodoMarker,\n type: 'todo',\n },\n },\n },\n }),\n LineHeightPlugin.extend({\n inject: {\n nodeProps: {\n defaultNodeValue: 1.5,\n validNodeValues: [1, 1.2, 1.5, 2, 3],\n },\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n ],\n },\n }),\n\n // Functionality\n AutoformatPlugin.configure({\n options: autoformatOptions,\n }),\n BlockSelectionPlugin.configure({\n options: {\n areaOptions: {\n behaviour: {\n scrolling: {\n speedDivider: 1.5,\n },\n startThreshold: 10,\n },\n boundaries: `#${scrollSelector}`,\n container: `#${scrollSelector}`,\n selectables: [`#${scrollSelector} .slate-selectable`],\n selectionAreaClass: 'slate-selection-area',\n },\n enableContextMenu: true,\n },\n }),\n BlockMenuPlugin.configure({\n render: { aboveEditable: BlockContextMenu },\n }),\n DndPlugin.configure({ options: { enableScroller: true } }),\n EmojiPlugin,\n exitBreakPlugin,\n NodeIdPlugin,\n NormalizeTypesPlugin.configure({\n options: {\n rules: [{ path: [0], strictType: HEADING_KEYS.h1 }],\n },\n }),\n resetBlockTypePlugin,\n SelectOnBackspacePlugin.configure({\n options: {\n query: {\n allow: [ImagePlugin.key, HorizontalRulePlugin.key],\n },\n },\n }),\n DeletePlugin,\n SingleLinePlugin,\n softBreakPlugin,\n tabbablePlugin,\n TrailingBlockPlugin.configure({\n options: { type: ParagraphPlugin.key },\n }),\n DragOverCursorPlugin,\n\n // Collaboration\n CommentsPlugin.configure({\n options: {\n comments: commentsData,\n myUserId: '1',\n users: usersData,\n },\n }),\n\n // Deserialization\n DocxPlugin,\n MarkdownPlugin.configure({ options: { indentList: true } }),\n JuicePlugin,\n\n // Testing\n PlaywrightPlugin.configure({\n enabled: process.env.NODE_ENV !== 'production',\n }),\n ],\n value: value,\n },\n []\n );\n};\n\nexport default function PlaygroundDemo({\n id,\n className,\n scrollSelector,\n}: {\n id?: ValueId;\n className?: string;\n scrollSelector?: string;\n}) {\n const containerRef = useRef(null);\n const enabled = settingsStore.use.checkedComponents();\n\n const editor = usePlaygroundEditor(\n id,\n scrollSelector ?? `blockSelection-${id}`\n );\n\n return (\n \n \n \n \n \n \n \n \n \n\n
\n \n \n\n \n \n \n \n \n \n \n\n \n \n \n \n\n \n \n \n
\n
\n
\n );\n}\n\nconst DemoIdContext = React.createContext(undefined);\n\nexport function DemoId({\n id,\n children,\n}: {\n children: React.ReactNode;\n id?: string;\n}) {\n return {children};\n}\n\nexport function useDemoId() {\n return React.useContext(DemoIdContext);\n}\n", + "content": "'use client';\n\nimport React, { useRef } from 'react';\n\nimport type { ValueId } from '@/config/customizer-plugins';\n\nimport { cn } from '@udecode/cn';\nimport { AIChatPlugin, CopilotPlugin } from '@udecode/plate-ai/react';\nimport { AlignPlugin } from '@udecode/plate-alignment/react';\nimport { AutoformatPlugin } from '@udecode/plate-autoformat/react';\nimport {\n BoldPlugin,\n CodePlugin,\n ItalicPlugin,\n StrikethroughPlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n UnderlinePlugin,\n} from '@udecode/plate-basic-marks/react';\nimport { BlockquotePlugin } from '@udecode/plate-block-quote/react';\nimport { SingleLinePlugin } from '@udecode/plate-break/react';\nimport { CaptionPlugin } from '@udecode/plate-caption/react';\nimport { CodeBlockPlugin } from '@udecode/plate-code-block/react';\nimport { CommentsPlugin } from '@udecode/plate-comments/react';\nimport {\n ParagraphPlugin,\n Plate,\n usePlateEditor,\n} from '@udecode/plate-common/react';\nimport { DatePlugin } from '@udecode/plate-date/react';\nimport { DndPlugin } from '@udecode/plate-dnd';\nimport { DocxPlugin } from '@udecode/plate-docx';\nimport { EmojiPlugin } from '@udecode/plate-emoji/react';\nimport { ExcalidrawPlugin } from '@udecode/plate-excalidraw/react';\nimport {\n FontBackgroundColorPlugin,\n FontColorPlugin,\n FontSizePlugin,\n} from '@udecode/plate-font/react';\nimport { HEADING_KEYS } from '@udecode/plate-heading';\nimport { HeadingPlugin, TocPlugin } from '@udecode/plate-heading/react';\nimport { HighlightPlugin } from '@udecode/plate-highlight/react';\nimport { HorizontalRulePlugin } from '@udecode/plate-horizontal-rule/react';\nimport { IndentPlugin } from '@udecode/plate-indent/react';\nimport { IndentListPlugin } from '@udecode/plate-indent-list/react';\nimport { JuicePlugin } from '@udecode/plate-juice';\nimport { KbdPlugin } from '@udecode/plate-kbd/react';\nimport { ColumnPlugin } from '@udecode/plate-layout/react';\nimport { LineHeightPlugin } from '@udecode/plate-line-height/react';\nimport { LinkPlugin } from '@udecode/plate-link/react';\nimport { ListPlugin, TodoListPlugin } from '@udecode/plate-list/react';\nimport { MarkdownPlugin } from '@udecode/plate-markdown';\nimport { ImagePlugin, MediaEmbedPlugin } from '@udecode/plate-media/react';\nimport { MentionPlugin } from '@udecode/plate-mention/react';\nimport { NodeIdPlugin } from '@udecode/plate-node-id';\nimport { NormalizeTypesPlugin } from '@udecode/plate-normalizers';\nimport { PlaywrightPlugin } from '@udecode/plate-playwright';\nimport { DeletePlugin, SelectOnBackspacePlugin } from '@udecode/plate-select';\nimport {\n BlockMenuPlugin,\n BlockSelectionPlugin,\n} from '@udecode/plate-selection/react';\nimport { SlashPlugin } from '@udecode/plate-slash-command/react';\nimport { TablePlugin } from '@udecode/plate-table/react';\nimport { TogglePlugin } from '@udecode/plate-toggle/react';\nimport { TrailingBlockPlugin } from '@udecode/plate-trailing-block';\nimport Prism from 'prismjs';\n\nimport { CheckPlugin } from '@/components/context/check-plugin';\nimport { settingsStore } from '@/components/context/settings-store';\nimport { aiPlugins } from '@/lib/plate/demo/plugins/ai-plugins';\nimport { getAutoformatOptions } from '@/lib/plate/demo/plugins/autoformatOptions';\nimport { copilotPlugins } from '@/lib/plate/demo/plugins/copilot-plugins';\nimport { createPlateUI } from '@/plate/create-plate-ui';\nimport { editableProps } from '@/plate/demo/editableProps';\nimport { isEnabled } from '@/plate/demo/is-enabled';\nimport { DragOverCursorPlugin } from '@/plate/demo/plugins/DragOverCursorPlugin';\nimport { exitBreakPlugin } from '@/plate/demo/plugins/exitBreakPlugin';\nimport { resetBlockTypePlugin } from '@/plate/demo/plugins/resetBlockTypePlugin';\nimport { softBreakPlugin } from '@/plate/demo/plugins/softBreakPlugin';\nimport { tabbablePlugin } from '@/plate/demo/plugins/tabbablePlugin';\nimport { commentsData, usersData } from '@/plate/demo/values/commentsValue';\nimport { usePlaygroundValue } from '@/plate/demo/values/usePlaygroundValue';\nimport { BlockContextMenu } from '@/components/plate-ui/block-context-menu';\nimport { CommentsPopover } from '@/components/plate-ui/comments-popover';\nimport {\n CursorOverlay,\n SelectionOverlayPlugin,\n} from '@/components/plate-ui/cursor-overlay';\nimport { Editor, EditorContainer } from '@/components/plate-ui/editor';\nimport { FixedToolbar } from '@/components/plate-ui/fixed-toolbar';\nimport { FixedToolbarButtons } from '@/components/plate-ui/fixed-toolbar-buttons';\nimport { FloatingToolbar } from '@/components/plate-ui/floating-toolbar';\nimport { FloatingToolbarButtons } from '@/components/plate-ui/floating-toolbar-buttons';\nimport { ImagePreview } from '@/components/plate-ui/image-preview';\nimport {\n FireLiComponent,\n FireMarker,\n} from '@/components/plate-ui/indent-fire-marker';\nimport {\n TodoLi,\n TodoMarker,\n} from '@/components/plate-ui/indent-todo-marker';\nimport { LinkFloatingToolbar } from '@/components/plate-ui/link-floating-toolbar';\n\nimport { usePlaygroundEnabled } from './usePlaygroundEnabled';\n\nexport const usePlaygroundEditor = (id: any = '', scrollSelector?: string) => {\n const enabledPlugins = settingsStore.use.checkedPlugins();\n const overridePlugins = usePlaygroundEnabled(id);\n const autoformatOptions = getAutoformatOptions(id, enabledPlugins);\n\n const value = usePlaygroundValue(id);\n const key = settingsStore.use.version();\n const editorId = id || 'playground-' + key;\n\n return usePlateEditor(\n {\n id: editorId,\n override: {\n components: createPlateUI({\n draggable: isEnabled('dnd', id),\n placeholder: isEnabled('placeholder', id),\n }),\n plugins: overridePlugins,\n },\n plugins: [\n // AI\n ...(id === 'ai' || enabledPlugins[AIChatPlugin.key] ? aiPlugins : []),\n ...(id === 'copilot' || enabledPlugins[CopilotPlugin.key]\n ? copilotPlugins\n : []),\n // Nodes\n HeadingPlugin,\n TocPlugin.configure({\n options: {\n scrollContainerSelector: `#${scrollSelector}`,\n topOffset: 80,\n },\n }),\n BlockquotePlugin,\n CodeBlockPlugin.configure({\n options: {\n prism: Prism,\n },\n }),\n HorizontalRulePlugin,\n LinkPlugin.extend({\n render: { afterEditable: () => },\n }),\n ...(id === 'list' ? [ListPlugin] : []),\n ImagePlugin.extend({\n options: {\n disableUploadInsert: true,\n },\n render: { afterEditable: ImagePreview },\n }),\n MediaEmbedPlugin,\n CaptionPlugin.configure({\n options: {\n plugins: [ImagePlugin, MediaEmbedPlugin],\n },\n }),\n DatePlugin,\n MentionPlugin.configure({\n options: {\n triggerPreviousCharPattern: /^$|^[\\s\"']$/,\n },\n }),\n SlashPlugin,\n TablePlugin.configure({\n options: {\n enableMerging: id === 'tableMerge',\n },\n }),\n ColumnPlugin,\n SelectionOverlayPlugin,\n\n TodoListPlugin,\n TogglePlugin,\n ExcalidrawPlugin,\n // Marks\n BoldPlugin,\n ItalicPlugin,\n UnderlinePlugin,\n StrikethroughPlugin,\n CodePlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n FontColorPlugin,\n FontBackgroundColorPlugin,\n FontSizePlugin,\n HighlightPlugin,\n KbdPlugin,\n\n // Block Style\n AlignPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n MediaEmbedPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n ImagePlugin.key,\n HEADING_KEYS.h6,\n ],\n },\n }),\n IndentPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n }),\n IndentListPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n options: {\n listStyleTypes: {\n fire: {\n liComponent: FireLiComponent,\n markerComponent: FireMarker,\n type: 'fire',\n },\n todo: {\n liComponent: TodoLi,\n markerComponent: TodoMarker,\n type: 'todo',\n },\n },\n },\n }),\n LineHeightPlugin.extend({\n inject: {\n nodeProps: {\n defaultNodeValue: 1.5,\n validNodeValues: [1, 1.2, 1.5, 2, 3],\n },\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n ],\n },\n }),\n\n // Functionality\n AutoformatPlugin.configure({\n options: autoformatOptions,\n }),\n BlockSelectionPlugin.configure({\n options: {\n areaOptions: {\n behaviour: {\n scrolling: {\n speedDivider: 1.5,\n },\n startThreshold: 10,\n },\n boundaries: `#${scrollSelector}`,\n container: `#${scrollSelector}`,\n selectables: [`#${scrollSelector} .slate-selectable`],\n selectionAreaClass: 'slate-selection-area',\n },\n enableContextMenu: true,\n },\n }),\n BlockMenuPlugin.configure({\n render: { aboveEditable: BlockContextMenu },\n }),\n DndPlugin.configure({\n options: {\n enableScroller: true,\n onDropFiles: ({ dragItem, editor, target }) => {\n editor\n .getTransforms(ImagePlugin)\n .insertImageFromFiles(dragItem.files, {\n at: target,\n nextBlock: false,\n });\n },\n },\n }),\n EmojiPlugin,\n exitBreakPlugin,\n NodeIdPlugin,\n NormalizeTypesPlugin.configure({\n options: {\n rules: [{ path: [0], strictType: HEADING_KEYS.h1 }],\n },\n }),\n resetBlockTypePlugin,\n SelectOnBackspacePlugin.configure({\n options: {\n query: {\n allow: [ImagePlugin.key, HorizontalRulePlugin.key],\n },\n },\n }),\n DeletePlugin,\n SingleLinePlugin,\n softBreakPlugin,\n tabbablePlugin,\n TrailingBlockPlugin.configure({\n options: { type: ParagraphPlugin.key },\n }),\n DragOverCursorPlugin,\n\n // Collaboration\n CommentsPlugin.configure({\n options: {\n comments: commentsData,\n myUserId: '1',\n users: usersData,\n },\n }),\n\n // Deserialization\n DocxPlugin,\n MarkdownPlugin.configure({ options: { indentList: true } }),\n JuicePlugin,\n\n // Testing\n PlaywrightPlugin.configure({\n enabled: process.env.NODE_ENV !== 'production',\n }),\n ],\n value: value,\n },\n []\n );\n};\n\nexport default function PlaygroundDemo({\n id,\n className,\n scrollSelector,\n}: {\n id?: ValueId;\n className?: string;\n scrollSelector?: string;\n}) {\n const containerRef = useRef(null);\n const enabled = settingsStore.use.checkedComponents();\n\n const editor = usePlaygroundEditor(\n id,\n scrollSelector ?? `blockSelection-${id}`\n );\n\n return (\n \n \n \n \n \n \n \n \n \n\n
\n \n \n\n \n \n \n \n \n \n \n\n \n \n \n \n\n \n \n \n
\n
\n
\n );\n}\n\nconst DemoIdContext = React.createContext(undefined);\n\nexport function DemoId({\n id,\n children,\n}: {\n children: React.ReactNode;\n id?: string;\n}) {\n return {children};\n}\n\nexport function useDemoId() {\n return React.useContext(DemoIdContext);\n}\n", "path": "example/playground-demo.tsx", "target": "components/playground-demo.tsx", "type": "registry:example" diff --git a/apps/www/public/r/styles/default/excalidraw-demo.json b/apps/www/public/r/styles/default/excalidraw-demo.json index c95cc2312f..fdc01f0220 100644 --- a/apps/www/public/r/styles/default/excalidraw-demo.json +++ b/apps/www/public/r/styles/default/excalidraw-demo.json @@ -5,7 +5,7 @@ }, "files": [ { - "content": "'use client';\n\nimport React, { useRef } from 'react';\n\nimport type { ValueId } from '@/config/customizer-plugins';\n\nimport { cn } from '@udecode/cn';\nimport { AIChatPlugin, CopilotPlugin } from '@udecode/plate-ai/react';\nimport { AlignPlugin } from '@udecode/plate-alignment/react';\nimport { AutoformatPlugin } from '@udecode/plate-autoformat/react';\nimport {\n BoldPlugin,\n CodePlugin,\n ItalicPlugin,\n StrikethroughPlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n UnderlinePlugin,\n} from '@udecode/plate-basic-marks/react';\nimport { BlockquotePlugin } from '@udecode/plate-block-quote/react';\nimport { SingleLinePlugin } from '@udecode/plate-break/react';\nimport { CaptionPlugin } from '@udecode/plate-caption/react';\nimport { CodeBlockPlugin } from '@udecode/plate-code-block/react';\nimport { CommentsPlugin } from '@udecode/plate-comments/react';\nimport {\n ParagraphPlugin,\n Plate,\n usePlateEditor,\n} from '@udecode/plate-common/react';\nimport { DatePlugin } from '@udecode/plate-date/react';\nimport { DndPlugin } from '@udecode/plate-dnd';\nimport { DocxPlugin } from '@udecode/plate-docx';\nimport { EmojiPlugin } from '@udecode/plate-emoji/react';\nimport { ExcalidrawPlugin } from '@udecode/plate-excalidraw/react';\nimport {\n FontBackgroundColorPlugin,\n FontColorPlugin,\n FontSizePlugin,\n} from '@udecode/plate-font/react';\nimport { HEADING_KEYS } from '@udecode/plate-heading';\nimport { HeadingPlugin, TocPlugin } from '@udecode/plate-heading/react';\nimport { HighlightPlugin } from '@udecode/plate-highlight/react';\nimport { HorizontalRulePlugin } from '@udecode/plate-horizontal-rule/react';\nimport { IndentPlugin } from '@udecode/plate-indent/react';\nimport { IndentListPlugin } from '@udecode/plate-indent-list/react';\nimport { JuicePlugin } from '@udecode/plate-juice';\nimport { KbdPlugin } from '@udecode/plate-kbd/react';\nimport { ColumnPlugin } from '@udecode/plate-layout/react';\nimport { LineHeightPlugin } from '@udecode/plate-line-height/react';\nimport { LinkPlugin } from '@udecode/plate-link/react';\nimport { ListPlugin, TodoListPlugin } from '@udecode/plate-list/react';\nimport { MarkdownPlugin } from '@udecode/plate-markdown';\nimport { ImagePlugin, MediaEmbedPlugin } from '@udecode/plate-media/react';\nimport { MentionPlugin } from '@udecode/plate-mention/react';\nimport { NodeIdPlugin } from '@udecode/plate-node-id';\nimport { NormalizeTypesPlugin } from '@udecode/plate-normalizers';\nimport { PlaywrightPlugin } from '@udecode/plate-playwright';\nimport { DeletePlugin, SelectOnBackspacePlugin } from '@udecode/plate-select';\nimport {\n BlockMenuPlugin,\n BlockSelectionPlugin,\n} from '@udecode/plate-selection/react';\nimport { SlashPlugin } from '@udecode/plate-slash-command/react';\nimport { TablePlugin } from '@udecode/plate-table/react';\nimport { TogglePlugin } from '@udecode/plate-toggle/react';\nimport { TrailingBlockPlugin } from '@udecode/plate-trailing-block';\nimport Prism from 'prismjs';\n\nimport { CheckPlugin } from '@/components/context/check-plugin';\nimport { settingsStore } from '@/components/context/settings-store';\nimport { aiPlugins } from '@/lib/plate/demo/plugins/ai-plugins';\nimport { getAutoformatOptions } from '@/lib/plate/demo/plugins/autoformatOptions';\nimport { copilotPlugins } from '@/lib/plate/demo/plugins/copilot-plugins';\nimport { createPlateUI } from '@/plate/create-plate-ui';\nimport { editableProps } from '@/plate/demo/editableProps';\nimport { isEnabled } from '@/plate/demo/is-enabled';\nimport { DragOverCursorPlugin } from '@/plate/demo/plugins/DragOverCursorPlugin';\nimport { exitBreakPlugin } from '@/plate/demo/plugins/exitBreakPlugin';\nimport { resetBlockTypePlugin } from '@/plate/demo/plugins/resetBlockTypePlugin';\nimport { softBreakPlugin } from '@/plate/demo/plugins/softBreakPlugin';\nimport { tabbablePlugin } from '@/plate/demo/plugins/tabbablePlugin';\nimport { commentsData, usersData } from '@/plate/demo/values/commentsValue';\nimport { usePlaygroundValue } from '@/plate/demo/values/usePlaygroundValue';\nimport { BlockContextMenu } from '@/components/plate-ui/block-context-menu';\nimport { CommentsPopover } from '@/components/plate-ui/comments-popover';\nimport {\n CursorOverlay,\n SelectionOverlayPlugin,\n} from '@/components/plate-ui/cursor-overlay';\nimport { Editor, EditorContainer } from '@/components/plate-ui/editor';\nimport { FixedToolbar } from '@/components/plate-ui/fixed-toolbar';\nimport { FixedToolbarButtons } from '@/components/plate-ui/fixed-toolbar-buttons';\nimport { FloatingToolbar } from '@/components/plate-ui/floating-toolbar';\nimport { FloatingToolbarButtons } from '@/components/plate-ui/floating-toolbar-buttons';\nimport { ImagePreview } from '@/components/plate-ui/image-preview';\nimport {\n FireLiComponent,\n FireMarker,\n} from '@/components/plate-ui/indent-fire-marker';\nimport {\n TodoLi,\n TodoMarker,\n} from '@/components/plate-ui/indent-todo-marker';\nimport { LinkFloatingToolbar } from '@/components/plate-ui/link-floating-toolbar';\n\nimport { usePlaygroundEnabled } from './usePlaygroundEnabled';\n\nexport const usePlaygroundEditor = (id: any = '', scrollSelector?: string) => {\n const enabledPlugins = settingsStore.use.checkedPlugins();\n const overridePlugins = usePlaygroundEnabled(id);\n const autoformatOptions = getAutoformatOptions(id, enabledPlugins);\n\n const value = usePlaygroundValue(id);\n const key = settingsStore.use.version();\n const editorId = id || 'playground-' + key;\n\n return usePlateEditor(\n {\n id: editorId,\n override: {\n components: createPlateUI({\n draggable: isEnabled('dnd', id),\n placeholder: isEnabled('placeholder', id),\n }),\n plugins: overridePlugins,\n },\n plugins: [\n // AI\n ...(id === 'ai' || enabledPlugins[AIChatPlugin.key] ? aiPlugins : []),\n ...(id === 'copilot' || enabledPlugins[CopilotPlugin.key]\n ? copilotPlugins\n : []),\n // Nodes\n HeadingPlugin,\n TocPlugin.configure({\n options: {\n scrollContainerSelector: `#${scrollSelector}`,\n topOffset: 80,\n },\n }),\n BlockquotePlugin,\n CodeBlockPlugin.configure({\n options: {\n prism: Prism,\n },\n }),\n HorizontalRulePlugin,\n LinkPlugin.extend({\n render: { afterEditable: () => },\n }),\n ...(id === 'list' ? [ListPlugin] : []),\n ImagePlugin.extend({\n render: { afterEditable: ImagePreview },\n }),\n MediaEmbedPlugin,\n CaptionPlugin.configure({\n options: {\n plugins: [ImagePlugin, MediaEmbedPlugin],\n },\n }),\n DatePlugin,\n MentionPlugin.configure({\n options: {\n triggerPreviousCharPattern: /^$|^[\\s\"']$/,\n },\n }),\n SlashPlugin,\n TablePlugin.configure({\n options: {\n enableMerging: id === 'tableMerge',\n },\n }),\n ColumnPlugin,\n SelectionOverlayPlugin,\n\n TodoListPlugin,\n TogglePlugin,\n ExcalidrawPlugin,\n // Marks\n BoldPlugin,\n ItalicPlugin,\n UnderlinePlugin,\n StrikethroughPlugin,\n CodePlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n FontColorPlugin,\n FontBackgroundColorPlugin,\n FontSizePlugin,\n HighlightPlugin,\n KbdPlugin,\n\n // Block Style\n AlignPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n MediaEmbedPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n ImagePlugin.key,\n HEADING_KEYS.h6,\n ],\n },\n }),\n IndentPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n }),\n IndentListPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n options: {\n listStyleTypes: {\n fire: {\n liComponent: FireLiComponent,\n markerComponent: FireMarker,\n type: 'fire',\n },\n todo: {\n liComponent: TodoLi,\n markerComponent: TodoMarker,\n type: 'todo',\n },\n },\n },\n }),\n LineHeightPlugin.extend({\n inject: {\n nodeProps: {\n defaultNodeValue: 1.5,\n validNodeValues: [1, 1.2, 1.5, 2, 3],\n },\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n ],\n },\n }),\n\n // Functionality\n AutoformatPlugin.configure({\n options: autoformatOptions,\n }),\n BlockSelectionPlugin.configure({\n options: {\n areaOptions: {\n behaviour: {\n scrolling: {\n speedDivider: 1.5,\n },\n startThreshold: 10,\n },\n boundaries: `#${scrollSelector}`,\n container: `#${scrollSelector}`,\n selectables: [`#${scrollSelector} .slate-selectable`],\n selectionAreaClass: 'slate-selection-area',\n },\n enableContextMenu: true,\n },\n }),\n BlockMenuPlugin.configure({\n render: { aboveEditable: BlockContextMenu },\n }),\n DndPlugin.configure({ options: { enableScroller: true } }),\n EmojiPlugin,\n exitBreakPlugin,\n NodeIdPlugin,\n NormalizeTypesPlugin.configure({\n options: {\n rules: [{ path: [0], strictType: HEADING_KEYS.h1 }],\n },\n }),\n resetBlockTypePlugin,\n SelectOnBackspacePlugin.configure({\n options: {\n query: {\n allow: [ImagePlugin.key, HorizontalRulePlugin.key],\n },\n },\n }),\n DeletePlugin,\n SingleLinePlugin,\n softBreakPlugin,\n tabbablePlugin,\n TrailingBlockPlugin.configure({\n options: { type: ParagraphPlugin.key },\n }),\n DragOverCursorPlugin,\n\n // Collaboration\n CommentsPlugin.configure({\n options: {\n comments: commentsData,\n myUserId: '1',\n users: usersData,\n },\n }),\n\n // Deserialization\n DocxPlugin,\n MarkdownPlugin.configure({ options: { indentList: true } }),\n JuicePlugin,\n\n // Testing\n PlaywrightPlugin.configure({\n enabled: process.env.NODE_ENV !== 'production',\n }),\n ],\n value: value,\n },\n []\n );\n};\n\nexport default function PlaygroundDemo({\n id,\n className,\n scrollSelector,\n}: {\n id?: ValueId;\n className?: string;\n scrollSelector?: string;\n}) {\n const containerRef = useRef(null);\n const enabled = settingsStore.use.checkedComponents();\n\n const editor = usePlaygroundEditor(\n id,\n scrollSelector ?? `blockSelection-${id}`\n );\n\n return (\n \n \n \n \n \n \n \n \n \n\n
\n \n \n\n \n \n \n \n \n \n \n\n \n \n \n \n\n \n \n \n
\n
\n
\n );\n}\n\nconst DemoIdContext = React.createContext(undefined);\n\nexport function DemoId({\n id,\n children,\n}: {\n children: React.ReactNode;\n id?: string;\n}) {\n return {children};\n}\n\nexport function useDemoId() {\n return React.useContext(DemoIdContext);\n}\n", + "content": "'use client';\n\nimport React, { useRef } from 'react';\n\nimport type { ValueId } from '@/config/customizer-plugins';\n\nimport { cn } from '@udecode/cn';\nimport { AIChatPlugin, CopilotPlugin } from '@udecode/plate-ai/react';\nimport { AlignPlugin } from '@udecode/plate-alignment/react';\nimport { AutoformatPlugin } from '@udecode/plate-autoformat/react';\nimport {\n BoldPlugin,\n CodePlugin,\n ItalicPlugin,\n StrikethroughPlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n UnderlinePlugin,\n} from '@udecode/plate-basic-marks/react';\nimport { BlockquotePlugin } from '@udecode/plate-block-quote/react';\nimport { SingleLinePlugin } from '@udecode/plate-break/react';\nimport { CaptionPlugin } from '@udecode/plate-caption/react';\nimport { CodeBlockPlugin } from '@udecode/plate-code-block/react';\nimport { CommentsPlugin } from '@udecode/plate-comments/react';\nimport {\n ParagraphPlugin,\n Plate,\n usePlateEditor,\n} from '@udecode/plate-common/react';\nimport { DatePlugin } from '@udecode/plate-date/react';\nimport { DndPlugin } from '@udecode/plate-dnd';\nimport { DocxPlugin } from '@udecode/plate-docx';\nimport { EmojiPlugin } from '@udecode/plate-emoji/react';\nimport { ExcalidrawPlugin } from '@udecode/plate-excalidraw/react';\nimport {\n FontBackgroundColorPlugin,\n FontColorPlugin,\n FontSizePlugin,\n} from '@udecode/plate-font/react';\nimport { HEADING_KEYS } from '@udecode/plate-heading';\nimport { HeadingPlugin, TocPlugin } from '@udecode/plate-heading/react';\nimport { HighlightPlugin } from '@udecode/plate-highlight/react';\nimport { HorizontalRulePlugin } from '@udecode/plate-horizontal-rule/react';\nimport { IndentPlugin } from '@udecode/plate-indent/react';\nimport { IndentListPlugin } from '@udecode/plate-indent-list/react';\nimport { JuicePlugin } from '@udecode/plate-juice';\nimport { KbdPlugin } from '@udecode/plate-kbd/react';\nimport { ColumnPlugin } from '@udecode/plate-layout/react';\nimport { LineHeightPlugin } from '@udecode/plate-line-height/react';\nimport { LinkPlugin } from '@udecode/plate-link/react';\nimport { ListPlugin, TodoListPlugin } from '@udecode/plate-list/react';\nimport { MarkdownPlugin } from '@udecode/plate-markdown';\nimport { ImagePlugin, MediaEmbedPlugin } from '@udecode/plate-media/react';\nimport { MentionPlugin } from '@udecode/plate-mention/react';\nimport { NodeIdPlugin } from '@udecode/plate-node-id';\nimport { NormalizeTypesPlugin } from '@udecode/plate-normalizers';\nimport { PlaywrightPlugin } from '@udecode/plate-playwright';\nimport { DeletePlugin, SelectOnBackspacePlugin } from '@udecode/plate-select';\nimport {\n BlockMenuPlugin,\n BlockSelectionPlugin,\n} from '@udecode/plate-selection/react';\nimport { SlashPlugin } from '@udecode/plate-slash-command/react';\nimport { TablePlugin } from '@udecode/plate-table/react';\nimport { TogglePlugin } from '@udecode/plate-toggle/react';\nimport { TrailingBlockPlugin } from '@udecode/plate-trailing-block';\nimport Prism from 'prismjs';\n\nimport { CheckPlugin } from '@/components/context/check-plugin';\nimport { settingsStore } from '@/components/context/settings-store';\nimport { aiPlugins } from '@/lib/plate/demo/plugins/ai-plugins';\nimport { getAutoformatOptions } from '@/lib/plate/demo/plugins/autoformatOptions';\nimport { copilotPlugins } from '@/lib/plate/demo/plugins/copilot-plugins';\nimport { createPlateUI } from '@/plate/create-plate-ui';\nimport { editableProps } from '@/plate/demo/editableProps';\nimport { isEnabled } from '@/plate/demo/is-enabled';\nimport { DragOverCursorPlugin } from '@/plate/demo/plugins/DragOverCursorPlugin';\nimport { exitBreakPlugin } from '@/plate/demo/plugins/exitBreakPlugin';\nimport { resetBlockTypePlugin } from '@/plate/demo/plugins/resetBlockTypePlugin';\nimport { softBreakPlugin } from '@/plate/demo/plugins/softBreakPlugin';\nimport { tabbablePlugin } from '@/plate/demo/plugins/tabbablePlugin';\nimport { commentsData, usersData } from '@/plate/demo/values/commentsValue';\nimport { usePlaygroundValue } from '@/plate/demo/values/usePlaygroundValue';\nimport { BlockContextMenu } from '@/components/plate-ui/block-context-menu';\nimport { CommentsPopover } from '@/components/plate-ui/comments-popover';\nimport {\n CursorOverlay,\n SelectionOverlayPlugin,\n} from '@/components/plate-ui/cursor-overlay';\nimport { Editor, EditorContainer } from '@/components/plate-ui/editor';\nimport { FixedToolbar } from '@/components/plate-ui/fixed-toolbar';\nimport { FixedToolbarButtons } from '@/components/plate-ui/fixed-toolbar-buttons';\nimport { FloatingToolbar } from '@/components/plate-ui/floating-toolbar';\nimport { FloatingToolbarButtons } from '@/components/plate-ui/floating-toolbar-buttons';\nimport { ImagePreview } from '@/components/plate-ui/image-preview';\nimport {\n FireLiComponent,\n FireMarker,\n} from '@/components/plate-ui/indent-fire-marker';\nimport {\n TodoLi,\n TodoMarker,\n} from '@/components/plate-ui/indent-todo-marker';\nimport { LinkFloatingToolbar } from '@/components/plate-ui/link-floating-toolbar';\n\nimport { usePlaygroundEnabled } from './usePlaygroundEnabled';\n\nexport const usePlaygroundEditor = (id: any = '', scrollSelector?: string) => {\n const enabledPlugins = settingsStore.use.checkedPlugins();\n const overridePlugins = usePlaygroundEnabled(id);\n const autoformatOptions = getAutoformatOptions(id, enabledPlugins);\n\n const value = usePlaygroundValue(id);\n const key = settingsStore.use.version();\n const editorId = id || 'playground-' + key;\n\n return usePlateEditor(\n {\n id: editorId,\n override: {\n components: createPlateUI({\n draggable: isEnabled('dnd', id),\n placeholder: isEnabled('placeholder', id),\n }),\n plugins: overridePlugins,\n },\n plugins: [\n // AI\n ...(id === 'ai' || enabledPlugins[AIChatPlugin.key] ? aiPlugins : []),\n ...(id === 'copilot' || enabledPlugins[CopilotPlugin.key]\n ? copilotPlugins\n : []),\n // Nodes\n HeadingPlugin,\n TocPlugin.configure({\n options: {\n scrollContainerSelector: `#${scrollSelector}`,\n topOffset: 80,\n },\n }),\n BlockquotePlugin,\n CodeBlockPlugin.configure({\n options: {\n prism: Prism,\n },\n }),\n HorizontalRulePlugin,\n LinkPlugin.extend({\n render: { afterEditable: () => },\n }),\n ...(id === 'list' ? [ListPlugin] : []),\n ImagePlugin.extend({\n options: {\n disableUploadInsert: true,\n },\n render: { afterEditable: ImagePreview },\n }),\n MediaEmbedPlugin,\n CaptionPlugin.configure({\n options: {\n plugins: [ImagePlugin, MediaEmbedPlugin],\n },\n }),\n DatePlugin,\n MentionPlugin.configure({\n options: {\n triggerPreviousCharPattern: /^$|^[\\s\"']$/,\n },\n }),\n SlashPlugin,\n TablePlugin.configure({\n options: {\n enableMerging: id === 'tableMerge',\n },\n }),\n ColumnPlugin,\n SelectionOverlayPlugin,\n\n TodoListPlugin,\n TogglePlugin,\n ExcalidrawPlugin,\n // Marks\n BoldPlugin,\n ItalicPlugin,\n UnderlinePlugin,\n StrikethroughPlugin,\n CodePlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n FontColorPlugin,\n FontBackgroundColorPlugin,\n FontSizePlugin,\n HighlightPlugin,\n KbdPlugin,\n\n // Block Style\n AlignPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n MediaEmbedPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n ImagePlugin.key,\n HEADING_KEYS.h6,\n ],\n },\n }),\n IndentPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n }),\n IndentListPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n options: {\n listStyleTypes: {\n fire: {\n liComponent: FireLiComponent,\n markerComponent: FireMarker,\n type: 'fire',\n },\n todo: {\n liComponent: TodoLi,\n markerComponent: TodoMarker,\n type: 'todo',\n },\n },\n },\n }),\n LineHeightPlugin.extend({\n inject: {\n nodeProps: {\n defaultNodeValue: 1.5,\n validNodeValues: [1, 1.2, 1.5, 2, 3],\n },\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n ],\n },\n }),\n\n // Functionality\n AutoformatPlugin.configure({\n options: autoformatOptions,\n }),\n BlockSelectionPlugin.configure({\n options: {\n areaOptions: {\n behaviour: {\n scrolling: {\n speedDivider: 1.5,\n },\n startThreshold: 10,\n },\n boundaries: `#${scrollSelector}`,\n container: `#${scrollSelector}`,\n selectables: [`#${scrollSelector} .slate-selectable`],\n selectionAreaClass: 'slate-selection-area',\n },\n enableContextMenu: true,\n },\n }),\n BlockMenuPlugin.configure({\n render: { aboveEditable: BlockContextMenu },\n }),\n DndPlugin.configure({\n options: {\n enableScroller: true,\n onDropFiles: ({ dragItem, editor, target }) => {\n editor\n .getTransforms(ImagePlugin)\n .insertImageFromFiles(dragItem.files, {\n at: target,\n nextBlock: false,\n });\n },\n },\n }),\n EmojiPlugin,\n exitBreakPlugin,\n NodeIdPlugin,\n NormalizeTypesPlugin.configure({\n options: {\n rules: [{ path: [0], strictType: HEADING_KEYS.h1 }],\n },\n }),\n resetBlockTypePlugin,\n SelectOnBackspacePlugin.configure({\n options: {\n query: {\n allow: [ImagePlugin.key, HorizontalRulePlugin.key],\n },\n },\n }),\n DeletePlugin,\n SingleLinePlugin,\n softBreakPlugin,\n tabbablePlugin,\n TrailingBlockPlugin.configure({\n options: { type: ParagraphPlugin.key },\n }),\n DragOverCursorPlugin,\n\n // Collaboration\n CommentsPlugin.configure({\n options: {\n comments: commentsData,\n myUserId: '1',\n users: usersData,\n },\n }),\n\n // Deserialization\n DocxPlugin,\n MarkdownPlugin.configure({ options: { indentList: true } }),\n JuicePlugin,\n\n // Testing\n PlaywrightPlugin.configure({\n enabled: process.env.NODE_ENV !== 'production',\n }),\n ],\n value: value,\n },\n []\n );\n};\n\nexport default function PlaygroundDemo({\n id,\n className,\n scrollSelector,\n}: {\n id?: ValueId;\n className?: string;\n scrollSelector?: string;\n}) {\n const containerRef = useRef(null);\n const enabled = settingsStore.use.checkedComponents();\n\n const editor = usePlaygroundEditor(\n id,\n scrollSelector ?? `blockSelection-${id}`\n );\n\n return (\n \n \n \n \n \n \n \n \n \n\n
\n \n \n\n \n \n \n \n \n \n \n\n \n \n \n \n\n \n \n \n
\n
\n
\n );\n}\n\nconst DemoIdContext = React.createContext(undefined);\n\nexport function DemoId({\n id,\n children,\n}: {\n children: React.ReactNode;\n id?: string;\n}) {\n return {children};\n}\n\nexport function useDemoId() {\n return React.useContext(DemoIdContext);\n}\n", "path": "example/playground-demo.tsx", "target": "components/playground-demo.tsx", "type": "registry:example" diff --git a/apps/www/public/r/styles/default/floating-toolbar-demo.json b/apps/www/public/r/styles/default/floating-toolbar-demo.json index 803522ec21..d8ad642643 100644 --- a/apps/www/public/r/styles/default/floating-toolbar-demo.json +++ b/apps/www/public/r/styles/default/floating-toolbar-demo.json @@ -4,7 +4,7 @@ }, "files": [ { - "content": "'use client';\n\nimport React, { useRef } from 'react';\n\nimport type { ValueId } from '@/config/customizer-plugins';\n\nimport { cn } from '@udecode/cn';\nimport { AIChatPlugin, CopilotPlugin } from '@udecode/plate-ai/react';\nimport { AlignPlugin } from '@udecode/plate-alignment/react';\nimport { AutoformatPlugin } from '@udecode/plate-autoformat/react';\nimport {\n BoldPlugin,\n CodePlugin,\n ItalicPlugin,\n StrikethroughPlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n UnderlinePlugin,\n} from '@udecode/plate-basic-marks/react';\nimport { BlockquotePlugin } from '@udecode/plate-block-quote/react';\nimport { SingleLinePlugin } from '@udecode/plate-break/react';\nimport { CaptionPlugin } from '@udecode/plate-caption/react';\nimport { CodeBlockPlugin } from '@udecode/plate-code-block/react';\nimport { CommentsPlugin } from '@udecode/plate-comments/react';\nimport {\n ParagraphPlugin,\n Plate,\n usePlateEditor,\n} from '@udecode/plate-common/react';\nimport { DatePlugin } from '@udecode/plate-date/react';\nimport { DndPlugin } from '@udecode/plate-dnd';\nimport { DocxPlugin } from '@udecode/plate-docx';\nimport { EmojiPlugin } from '@udecode/plate-emoji/react';\nimport { ExcalidrawPlugin } from '@udecode/plate-excalidraw/react';\nimport {\n FontBackgroundColorPlugin,\n FontColorPlugin,\n FontSizePlugin,\n} from '@udecode/plate-font/react';\nimport { HEADING_KEYS } from '@udecode/plate-heading';\nimport { HeadingPlugin, TocPlugin } from '@udecode/plate-heading/react';\nimport { HighlightPlugin } from '@udecode/plate-highlight/react';\nimport { HorizontalRulePlugin } from '@udecode/plate-horizontal-rule/react';\nimport { IndentPlugin } from '@udecode/plate-indent/react';\nimport { IndentListPlugin } from '@udecode/plate-indent-list/react';\nimport { JuicePlugin } from '@udecode/plate-juice';\nimport { KbdPlugin } from '@udecode/plate-kbd/react';\nimport { ColumnPlugin } from '@udecode/plate-layout/react';\nimport { LineHeightPlugin } from '@udecode/plate-line-height/react';\nimport { LinkPlugin } from '@udecode/plate-link/react';\nimport { ListPlugin, TodoListPlugin } from '@udecode/plate-list/react';\nimport { MarkdownPlugin } from '@udecode/plate-markdown';\nimport { ImagePlugin, MediaEmbedPlugin } from '@udecode/plate-media/react';\nimport { MentionPlugin } from '@udecode/plate-mention/react';\nimport { NodeIdPlugin } from '@udecode/plate-node-id';\nimport { NormalizeTypesPlugin } from '@udecode/plate-normalizers';\nimport { PlaywrightPlugin } from '@udecode/plate-playwright';\nimport { DeletePlugin, SelectOnBackspacePlugin } from '@udecode/plate-select';\nimport {\n BlockMenuPlugin,\n BlockSelectionPlugin,\n} from '@udecode/plate-selection/react';\nimport { SlashPlugin } from '@udecode/plate-slash-command/react';\nimport { TablePlugin } from '@udecode/plate-table/react';\nimport { TogglePlugin } from '@udecode/plate-toggle/react';\nimport { TrailingBlockPlugin } from '@udecode/plate-trailing-block';\nimport Prism from 'prismjs';\n\nimport { CheckPlugin } from '@/components/context/check-plugin';\nimport { settingsStore } from '@/components/context/settings-store';\nimport { aiPlugins } from '@/lib/plate/demo/plugins/ai-plugins';\nimport { getAutoformatOptions } from '@/lib/plate/demo/plugins/autoformatOptions';\nimport { copilotPlugins } from '@/lib/plate/demo/plugins/copilot-plugins';\nimport { createPlateUI } from '@/plate/create-plate-ui';\nimport { editableProps } from '@/plate/demo/editableProps';\nimport { isEnabled } from '@/plate/demo/is-enabled';\nimport { DragOverCursorPlugin } from '@/plate/demo/plugins/DragOverCursorPlugin';\nimport { exitBreakPlugin } from '@/plate/demo/plugins/exitBreakPlugin';\nimport { resetBlockTypePlugin } from '@/plate/demo/plugins/resetBlockTypePlugin';\nimport { softBreakPlugin } from '@/plate/demo/plugins/softBreakPlugin';\nimport { tabbablePlugin } from '@/plate/demo/plugins/tabbablePlugin';\nimport { commentsData, usersData } from '@/plate/demo/values/commentsValue';\nimport { usePlaygroundValue } from '@/plate/demo/values/usePlaygroundValue';\nimport { BlockContextMenu } from '@/components/plate-ui/block-context-menu';\nimport { CommentsPopover } from '@/components/plate-ui/comments-popover';\nimport {\n CursorOverlay,\n SelectionOverlayPlugin,\n} from '@/components/plate-ui/cursor-overlay';\nimport { Editor, EditorContainer } from '@/components/plate-ui/editor';\nimport { FixedToolbar } from '@/components/plate-ui/fixed-toolbar';\nimport { FixedToolbarButtons } from '@/components/plate-ui/fixed-toolbar-buttons';\nimport { FloatingToolbar } from '@/components/plate-ui/floating-toolbar';\nimport { FloatingToolbarButtons } from '@/components/plate-ui/floating-toolbar-buttons';\nimport { ImagePreview } from '@/components/plate-ui/image-preview';\nimport {\n FireLiComponent,\n FireMarker,\n} from '@/components/plate-ui/indent-fire-marker';\nimport {\n TodoLi,\n TodoMarker,\n} from '@/components/plate-ui/indent-todo-marker';\nimport { LinkFloatingToolbar } from '@/components/plate-ui/link-floating-toolbar';\n\nimport { usePlaygroundEnabled } from './usePlaygroundEnabled';\n\nexport const usePlaygroundEditor = (id: any = '', scrollSelector?: string) => {\n const enabledPlugins = settingsStore.use.checkedPlugins();\n const overridePlugins = usePlaygroundEnabled(id);\n const autoformatOptions = getAutoformatOptions(id, enabledPlugins);\n\n const value = usePlaygroundValue(id);\n const key = settingsStore.use.version();\n const editorId = id || 'playground-' + key;\n\n return usePlateEditor(\n {\n id: editorId,\n override: {\n components: createPlateUI({\n draggable: isEnabled('dnd', id),\n placeholder: isEnabled('placeholder', id),\n }),\n plugins: overridePlugins,\n },\n plugins: [\n // AI\n ...(id === 'ai' || enabledPlugins[AIChatPlugin.key] ? aiPlugins : []),\n ...(id === 'copilot' || enabledPlugins[CopilotPlugin.key]\n ? copilotPlugins\n : []),\n // Nodes\n HeadingPlugin,\n TocPlugin.configure({\n options: {\n scrollContainerSelector: `#${scrollSelector}`,\n topOffset: 80,\n },\n }),\n BlockquotePlugin,\n CodeBlockPlugin.configure({\n options: {\n prism: Prism,\n },\n }),\n HorizontalRulePlugin,\n LinkPlugin.extend({\n render: { afterEditable: () => },\n }),\n ...(id === 'list' ? [ListPlugin] : []),\n ImagePlugin.extend({\n render: { afterEditable: ImagePreview },\n }),\n MediaEmbedPlugin,\n CaptionPlugin.configure({\n options: {\n plugins: [ImagePlugin, MediaEmbedPlugin],\n },\n }),\n DatePlugin,\n MentionPlugin.configure({\n options: {\n triggerPreviousCharPattern: /^$|^[\\s\"']$/,\n },\n }),\n SlashPlugin,\n TablePlugin.configure({\n options: {\n enableMerging: id === 'tableMerge',\n },\n }),\n ColumnPlugin,\n SelectionOverlayPlugin,\n\n TodoListPlugin,\n TogglePlugin,\n ExcalidrawPlugin,\n // Marks\n BoldPlugin,\n ItalicPlugin,\n UnderlinePlugin,\n StrikethroughPlugin,\n CodePlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n FontColorPlugin,\n FontBackgroundColorPlugin,\n FontSizePlugin,\n HighlightPlugin,\n KbdPlugin,\n\n // Block Style\n AlignPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n MediaEmbedPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n ImagePlugin.key,\n HEADING_KEYS.h6,\n ],\n },\n }),\n IndentPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n }),\n IndentListPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n options: {\n listStyleTypes: {\n fire: {\n liComponent: FireLiComponent,\n markerComponent: FireMarker,\n type: 'fire',\n },\n todo: {\n liComponent: TodoLi,\n markerComponent: TodoMarker,\n type: 'todo',\n },\n },\n },\n }),\n LineHeightPlugin.extend({\n inject: {\n nodeProps: {\n defaultNodeValue: 1.5,\n validNodeValues: [1, 1.2, 1.5, 2, 3],\n },\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n ],\n },\n }),\n\n // Functionality\n AutoformatPlugin.configure({\n options: autoformatOptions,\n }),\n BlockSelectionPlugin.configure({\n options: {\n areaOptions: {\n behaviour: {\n scrolling: {\n speedDivider: 1.5,\n },\n startThreshold: 10,\n },\n boundaries: `#${scrollSelector}`,\n container: `#${scrollSelector}`,\n selectables: [`#${scrollSelector} .slate-selectable`],\n selectionAreaClass: 'slate-selection-area',\n },\n enableContextMenu: true,\n },\n }),\n BlockMenuPlugin.configure({\n render: { aboveEditable: BlockContextMenu },\n }),\n DndPlugin.configure({ options: { enableScroller: true } }),\n EmojiPlugin,\n exitBreakPlugin,\n NodeIdPlugin,\n NormalizeTypesPlugin.configure({\n options: {\n rules: [{ path: [0], strictType: HEADING_KEYS.h1 }],\n },\n }),\n resetBlockTypePlugin,\n SelectOnBackspacePlugin.configure({\n options: {\n query: {\n allow: [ImagePlugin.key, HorizontalRulePlugin.key],\n },\n },\n }),\n DeletePlugin,\n SingleLinePlugin,\n softBreakPlugin,\n tabbablePlugin,\n TrailingBlockPlugin.configure({\n options: { type: ParagraphPlugin.key },\n }),\n DragOverCursorPlugin,\n\n // Collaboration\n CommentsPlugin.configure({\n options: {\n comments: commentsData,\n myUserId: '1',\n users: usersData,\n },\n }),\n\n // Deserialization\n DocxPlugin,\n MarkdownPlugin.configure({ options: { indentList: true } }),\n JuicePlugin,\n\n // Testing\n PlaywrightPlugin.configure({\n enabled: process.env.NODE_ENV !== 'production',\n }),\n ],\n value: value,\n },\n []\n );\n};\n\nexport default function PlaygroundDemo({\n id,\n className,\n scrollSelector,\n}: {\n id?: ValueId;\n className?: string;\n scrollSelector?: string;\n}) {\n const containerRef = useRef(null);\n const enabled = settingsStore.use.checkedComponents();\n\n const editor = usePlaygroundEditor(\n id,\n scrollSelector ?? `blockSelection-${id}`\n );\n\n return (\n \n \n \n \n \n \n \n \n \n\n
\n \n \n\n \n \n \n \n \n \n \n\n \n \n \n \n\n \n \n \n
\n
\n
\n );\n}\n\nconst DemoIdContext = React.createContext(undefined);\n\nexport function DemoId({\n id,\n children,\n}: {\n children: React.ReactNode;\n id?: string;\n}) {\n return {children};\n}\n\nexport function useDemoId() {\n return React.useContext(DemoIdContext);\n}\n", + "content": "'use client';\n\nimport React, { useRef } from 'react';\n\nimport type { ValueId } from '@/config/customizer-plugins';\n\nimport { cn } from '@udecode/cn';\nimport { AIChatPlugin, CopilotPlugin } from '@udecode/plate-ai/react';\nimport { AlignPlugin } from '@udecode/plate-alignment/react';\nimport { AutoformatPlugin } from '@udecode/plate-autoformat/react';\nimport {\n BoldPlugin,\n CodePlugin,\n ItalicPlugin,\n StrikethroughPlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n UnderlinePlugin,\n} from '@udecode/plate-basic-marks/react';\nimport { BlockquotePlugin } from '@udecode/plate-block-quote/react';\nimport { SingleLinePlugin } from '@udecode/plate-break/react';\nimport { CaptionPlugin } from '@udecode/plate-caption/react';\nimport { CodeBlockPlugin } from '@udecode/plate-code-block/react';\nimport { CommentsPlugin } from '@udecode/plate-comments/react';\nimport {\n ParagraphPlugin,\n Plate,\n usePlateEditor,\n} from '@udecode/plate-common/react';\nimport { DatePlugin } from '@udecode/plate-date/react';\nimport { DndPlugin } from '@udecode/plate-dnd';\nimport { DocxPlugin } from '@udecode/plate-docx';\nimport { EmojiPlugin } from '@udecode/plate-emoji/react';\nimport { ExcalidrawPlugin } from '@udecode/plate-excalidraw/react';\nimport {\n FontBackgroundColorPlugin,\n FontColorPlugin,\n FontSizePlugin,\n} from '@udecode/plate-font/react';\nimport { HEADING_KEYS } from '@udecode/plate-heading';\nimport { HeadingPlugin, TocPlugin } from '@udecode/plate-heading/react';\nimport { HighlightPlugin } from '@udecode/plate-highlight/react';\nimport { HorizontalRulePlugin } from '@udecode/plate-horizontal-rule/react';\nimport { IndentPlugin } from '@udecode/plate-indent/react';\nimport { IndentListPlugin } from '@udecode/plate-indent-list/react';\nimport { JuicePlugin } from '@udecode/plate-juice';\nimport { KbdPlugin } from '@udecode/plate-kbd/react';\nimport { ColumnPlugin } from '@udecode/plate-layout/react';\nimport { LineHeightPlugin } from '@udecode/plate-line-height/react';\nimport { LinkPlugin } from '@udecode/plate-link/react';\nimport { ListPlugin, TodoListPlugin } from '@udecode/plate-list/react';\nimport { MarkdownPlugin } from '@udecode/plate-markdown';\nimport { ImagePlugin, MediaEmbedPlugin } from '@udecode/plate-media/react';\nimport { MentionPlugin } from '@udecode/plate-mention/react';\nimport { NodeIdPlugin } from '@udecode/plate-node-id';\nimport { NormalizeTypesPlugin } from '@udecode/plate-normalizers';\nimport { PlaywrightPlugin } from '@udecode/plate-playwright';\nimport { DeletePlugin, SelectOnBackspacePlugin } from '@udecode/plate-select';\nimport {\n BlockMenuPlugin,\n BlockSelectionPlugin,\n} from '@udecode/plate-selection/react';\nimport { SlashPlugin } from '@udecode/plate-slash-command/react';\nimport { TablePlugin } from '@udecode/plate-table/react';\nimport { TogglePlugin } from '@udecode/plate-toggle/react';\nimport { TrailingBlockPlugin } from '@udecode/plate-trailing-block';\nimport Prism from 'prismjs';\n\nimport { CheckPlugin } from '@/components/context/check-plugin';\nimport { settingsStore } from '@/components/context/settings-store';\nimport { aiPlugins } from '@/lib/plate/demo/plugins/ai-plugins';\nimport { getAutoformatOptions } from '@/lib/plate/demo/plugins/autoformatOptions';\nimport { copilotPlugins } from '@/lib/plate/demo/plugins/copilot-plugins';\nimport { createPlateUI } from '@/plate/create-plate-ui';\nimport { editableProps } from '@/plate/demo/editableProps';\nimport { isEnabled } from '@/plate/demo/is-enabled';\nimport { DragOverCursorPlugin } from '@/plate/demo/plugins/DragOverCursorPlugin';\nimport { exitBreakPlugin } from '@/plate/demo/plugins/exitBreakPlugin';\nimport { resetBlockTypePlugin } from '@/plate/demo/plugins/resetBlockTypePlugin';\nimport { softBreakPlugin } from '@/plate/demo/plugins/softBreakPlugin';\nimport { tabbablePlugin } from '@/plate/demo/plugins/tabbablePlugin';\nimport { commentsData, usersData } from '@/plate/demo/values/commentsValue';\nimport { usePlaygroundValue } from '@/plate/demo/values/usePlaygroundValue';\nimport { BlockContextMenu } from '@/components/plate-ui/block-context-menu';\nimport { CommentsPopover } from '@/components/plate-ui/comments-popover';\nimport {\n CursorOverlay,\n SelectionOverlayPlugin,\n} from '@/components/plate-ui/cursor-overlay';\nimport { Editor, EditorContainer } from '@/components/plate-ui/editor';\nimport { FixedToolbar } from '@/components/plate-ui/fixed-toolbar';\nimport { FixedToolbarButtons } from '@/components/plate-ui/fixed-toolbar-buttons';\nimport { FloatingToolbar } from '@/components/plate-ui/floating-toolbar';\nimport { FloatingToolbarButtons } from '@/components/plate-ui/floating-toolbar-buttons';\nimport { ImagePreview } from '@/components/plate-ui/image-preview';\nimport {\n FireLiComponent,\n FireMarker,\n} from '@/components/plate-ui/indent-fire-marker';\nimport {\n TodoLi,\n TodoMarker,\n} from '@/components/plate-ui/indent-todo-marker';\nimport { LinkFloatingToolbar } from '@/components/plate-ui/link-floating-toolbar';\n\nimport { usePlaygroundEnabled } from './usePlaygroundEnabled';\n\nexport const usePlaygroundEditor = (id: any = '', scrollSelector?: string) => {\n const enabledPlugins = settingsStore.use.checkedPlugins();\n const overridePlugins = usePlaygroundEnabled(id);\n const autoformatOptions = getAutoformatOptions(id, enabledPlugins);\n\n const value = usePlaygroundValue(id);\n const key = settingsStore.use.version();\n const editorId = id || 'playground-' + key;\n\n return usePlateEditor(\n {\n id: editorId,\n override: {\n components: createPlateUI({\n draggable: isEnabled('dnd', id),\n placeholder: isEnabled('placeholder', id),\n }),\n plugins: overridePlugins,\n },\n plugins: [\n // AI\n ...(id === 'ai' || enabledPlugins[AIChatPlugin.key] ? aiPlugins : []),\n ...(id === 'copilot' || enabledPlugins[CopilotPlugin.key]\n ? copilotPlugins\n : []),\n // Nodes\n HeadingPlugin,\n TocPlugin.configure({\n options: {\n scrollContainerSelector: `#${scrollSelector}`,\n topOffset: 80,\n },\n }),\n BlockquotePlugin,\n CodeBlockPlugin.configure({\n options: {\n prism: Prism,\n },\n }),\n HorizontalRulePlugin,\n LinkPlugin.extend({\n render: { afterEditable: () => },\n }),\n ...(id === 'list' ? [ListPlugin] : []),\n ImagePlugin.extend({\n options: {\n disableUploadInsert: true,\n },\n render: { afterEditable: ImagePreview },\n }),\n MediaEmbedPlugin,\n CaptionPlugin.configure({\n options: {\n plugins: [ImagePlugin, MediaEmbedPlugin],\n },\n }),\n DatePlugin,\n MentionPlugin.configure({\n options: {\n triggerPreviousCharPattern: /^$|^[\\s\"']$/,\n },\n }),\n SlashPlugin,\n TablePlugin.configure({\n options: {\n enableMerging: id === 'tableMerge',\n },\n }),\n ColumnPlugin,\n SelectionOverlayPlugin,\n\n TodoListPlugin,\n TogglePlugin,\n ExcalidrawPlugin,\n // Marks\n BoldPlugin,\n ItalicPlugin,\n UnderlinePlugin,\n StrikethroughPlugin,\n CodePlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n FontColorPlugin,\n FontBackgroundColorPlugin,\n FontSizePlugin,\n HighlightPlugin,\n KbdPlugin,\n\n // Block Style\n AlignPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n MediaEmbedPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n ImagePlugin.key,\n HEADING_KEYS.h6,\n ],\n },\n }),\n IndentPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n }),\n IndentListPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n options: {\n listStyleTypes: {\n fire: {\n liComponent: FireLiComponent,\n markerComponent: FireMarker,\n type: 'fire',\n },\n todo: {\n liComponent: TodoLi,\n markerComponent: TodoMarker,\n type: 'todo',\n },\n },\n },\n }),\n LineHeightPlugin.extend({\n inject: {\n nodeProps: {\n defaultNodeValue: 1.5,\n validNodeValues: [1, 1.2, 1.5, 2, 3],\n },\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n ],\n },\n }),\n\n // Functionality\n AutoformatPlugin.configure({\n options: autoformatOptions,\n }),\n BlockSelectionPlugin.configure({\n options: {\n areaOptions: {\n behaviour: {\n scrolling: {\n speedDivider: 1.5,\n },\n startThreshold: 10,\n },\n boundaries: `#${scrollSelector}`,\n container: `#${scrollSelector}`,\n selectables: [`#${scrollSelector} .slate-selectable`],\n selectionAreaClass: 'slate-selection-area',\n },\n enableContextMenu: true,\n },\n }),\n BlockMenuPlugin.configure({\n render: { aboveEditable: BlockContextMenu },\n }),\n DndPlugin.configure({\n options: {\n enableScroller: true,\n onDropFiles: ({ dragItem, editor, target }) => {\n editor\n .getTransforms(ImagePlugin)\n .insertImageFromFiles(dragItem.files, {\n at: target,\n nextBlock: false,\n });\n },\n },\n }),\n EmojiPlugin,\n exitBreakPlugin,\n NodeIdPlugin,\n NormalizeTypesPlugin.configure({\n options: {\n rules: [{ path: [0], strictType: HEADING_KEYS.h1 }],\n },\n }),\n resetBlockTypePlugin,\n SelectOnBackspacePlugin.configure({\n options: {\n query: {\n allow: [ImagePlugin.key, HorizontalRulePlugin.key],\n },\n },\n }),\n DeletePlugin,\n SingleLinePlugin,\n softBreakPlugin,\n tabbablePlugin,\n TrailingBlockPlugin.configure({\n options: { type: ParagraphPlugin.key },\n }),\n DragOverCursorPlugin,\n\n // Collaboration\n CommentsPlugin.configure({\n options: {\n comments: commentsData,\n myUserId: '1',\n users: usersData,\n },\n }),\n\n // Deserialization\n DocxPlugin,\n MarkdownPlugin.configure({ options: { indentList: true } }),\n JuicePlugin,\n\n // Testing\n PlaywrightPlugin.configure({\n enabled: process.env.NODE_ENV !== 'production',\n }),\n ],\n value: value,\n },\n []\n );\n};\n\nexport default function PlaygroundDemo({\n id,\n className,\n scrollSelector,\n}: {\n id?: ValueId;\n className?: string;\n scrollSelector?: string;\n}) {\n const containerRef = useRef(null);\n const enabled = settingsStore.use.checkedComponents();\n\n const editor = usePlaygroundEditor(\n id,\n scrollSelector ?? `blockSelection-${id}`\n );\n\n return (\n \n \n \n \n \n \n \n \n \n\n
\n \n \n\n \n \n \n \n \n \n \n\n \n \n \n \n\n \n \n \n
\n
\n
\n );\n}\n\nconst DemoIdContext = React.createContext(undefined);\n\nexport function DemoId({\n id,\n children,\n}: {\n children: React.ReactNode;\n id?: string;\n}) {\n return {children};\n}\n\nexport function useDemoId() {\n return React.useContext(DemoIdContext);\n}\n", "path": "example/playground-demo.tsx", "target": "components/playground-demo.tsx", "type": "registry:example" diff --git a/apps/www/public/r/styles/default/font-demo.json b/apps/www/public/r/styles/default/font-demo.json index 28700db28d..9a403575df 100644 --- a/apps/www/public/r/styles/default/font-demo.json +++ b/apps/www/public/r/styles/default/font-demo.json @@ -4,7 +4,7 @@ }, "files": [ { - "content": "'use client';\n\nimport React, { useRef } from 'react';\n\nimport type { ValueId } from '@/config/customizer-plugins';\n\nimport { cn } from '@udecode/cn';\nimport { AIChatPlugin, CopilotPlugin } from '@udecode/plate-ai/react';\nimport { AlignPlugin } from '@udecode/plate-alignment/react';\nimport { AutoformatPlugin } from '@udecode/plate-autoformat/react';\nimport {\n BoldPlugin,\n CodePlugin,\n ItalicPlugin,\n StrikethroughPlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n UnderlinePlugin,\n} from '@udecode/plate-basic-marks/react';\nimport { BlockquotePlugin } from '@udecode/plate-block-quote/react';\nimport { SingleLinePlugin } from '@udecode/plate-break/react';\nimport { CaptionPlugin } from '@udecode/plate-caption/react';\nimport { CodeBlockPlugin } from '@udecode/plate-code-block/react';\nimport { CommentsPlugin } from '@udecode/plate-comments/react';\nimport {\n ParagraphPlugin,\n Plate,\n usePlateEditor,\n} from '@udecode/plate-common/react';\nimport { DatePlugin } from '@udecode/plate-date/react';\nimport { DndPlugin } from '@udecode/plate-dnd';\nimport { DocxPlugin } from '@udecode/plate-docx';\nimport { EmojiPlugin } from '@udecode/plate-emoji/react';\nimport { ExcalidrawPlugin } from '@udecode/plate-excalidraw/react';\nimport {\n FontBackgroundColorPlugin,\n FontColorPlugin,\n FontSizePlugin,\n} from '@udecode/plate-font/react';\nimport { HEADING_KEYS } from '@udecode/plate-heading';\nimport { HeadingPlugin, TocPlugin } from '@udecode/plate-heading/react';\nimport { HighlightPlugin } from '@udecode/plate-highlight/react';\nimport { HorizontalRulePlugin } from '@udecode/plate-horizontal-rule/react';\nimport { IndentPlugin } from '@udecode/plate-indent/react';\nimport { IndentListPlugin } from '@udecode/plate-indent-list/react';\nimport { JuicePlugin } from '@udecode/plate-juice';\nimport { KbdPlugin } from '@udecode/plate-kbd/react';\nimport { ColumnPlugin } from '@udecode/plate-layout/react';\nimport { LineHeightPlugin } from '@udecode/plate-line-height/react';\nimport { LinkPlugin } from '@udecode/plate-link/react';\nimport { ListPlugin, TodoListPlugin } from '@udecode/plate-list/react';\nimport { MarkdownPlugin } from '@udecode/plate-markdown';\nimport { ImagePlugin, MediaEmbedPlugin } from '@udecode/plate-media/react';\nimport { MentionPlugin } from '@udecode/plate-mention/react';\nimport { NodeIdPlugin } from '@udecode/plate-node-id';\nimport { NormalizeTypesPlugin } from '@udecode/plate-normalizers';\nimport { PlaywrightPlugin } from '@udecode/plate-playwright';\nimport { DeletePlugin, SelectOnBackspacePlugin } from '@udecode/plate-select';\nimport {\n BlockMenuPlugin,\n BlockSelectionPlugin,\n} from '@udecode/plate-selection/react';\nimport { SlashPlugin } from '@udecode/plate-slash-command/react';\nimport { TablePlugin } from '@udecode/plate-table/react';\nimport { TogglePlugin } from '@udecode/plate-toggle/react';\nimport { TrailingBlockPlugin } from '@udecode/plate-trailing-block';\nimport Prism from 'prismjs';\n\nimport { CheckPlugin } from '@/components/context/check-plugin';\nimport { settingsStore } from '@/components/context/settings-store';\nimport { aiPlugins } from '@/lib/plate/demo/plugins/ai-plugins';\nimport { getAutoformatOptions } from '@/lib/plate/demo/plugins/autoformatOptions';\nimport { copilotPlugins } from '@/lib/plate/demo/plugins/copilot-plugins';\nimport { createPlateUI } from '@/plate/create-plate-ui';\nimport { editableProps } from '@/plate/demo/editableProps';\nimport { isEnabled } from '@/plate/demo/is-enabled';\nimport { DragOverCursorPlugin } from '@/plate/demo/plugins/DragOverCursorPlugin';\nimport { exitBreakPlugin } from '@/plate/demo/plugins/exitBreakPlugin';\nimport { resetBlockTypePlugin } from '@/plate/demo/plugins/resetBlockTypePlugin';\nimport { softBreakPlugin } from '@/plate/demo/plugins/softBreakPlugin';\nimport { tabbablePlugin } from '@/plate/demo/plugins/tabbablePlugin';\nimport { commentsData, usersData } from '@/plate/demo/values/commentsValue';\nimport { usePlaygroundValue } from '@/plate/demo/values/usePlaygroundValue';\nimport { BlockContextMenu } from '@/components/plate-ui/block-context-menu';\nimport { CommentsPopover } from '@/components/plate-ui/comments-popover';\nimport {\n CursorOverlay,\n SelectionOverlayPlugin,\n} from '@/components/plate-ui/cursor-overlay';\nimport { Editor, EditorContainer } from '@/components/plate-ui/editor';\nimport { FixedToolbar } from '@/components/plate-ui/fixed-toolbar';\nimport { FixedToolbarButtons } from '@/components/plate-ui/fixed-toolbar-buttons';\nimport { FloatingToolbar } from '@/components/plate-ui/floating-toolbar';\nimport { FloatingToolbarButtons } from '@/components/plate-ui/floating-toolbar-buttons';\nimport { ImagePreview } from '@/components/plate-ui/image-preview';\nimport {\n FireLiComponent,\n FireMarker,\n} from '@/components/plate-ui/indent-fire-marker';\nimport {\n TodoLi,\n TodoMarker,\n} from '@/components/plate-ui/indent-todo-marker';\nimport { LinkFloatingToolbar } from '@/components/plate-ui/link-floating-toolbar';\n\nimport { usePlaygroundEnabled } from './usePlaygroundEnabled';\n\nexport const usePlaygroundEditor = (id: any = '', scrollSelector?: string) => {\n const enabledPlugins = settingsStore.use.checkedPlugins();\n const overridePlugins = usePlaygroundEnabled(id);\n const autoformatOptions = getAutoformatOptions(id, enabledPlugins);\n\n const value = usePlaygroundValue(id);\n const key = settingsStore.use.version();\n const editorId = id || 'playground-' + key;\n\n return usePlateEditor(\n {\n id: editorId,\n override: {\n components: createPlateUI({\n draggable: isEnabled('dnd', id),\n placeholder: isEnabled('placeholder', id),\n }),\n plugins: overridePlugins,\n },\n plugins: [\n // AI\n ...(id === 'ai' || enabledPlugins[AIChatPlugin.key] ? aiPlugins : []),\n ...(id === 'copilot' || enabledPlugins[CopilotPlugin.key]\n ? copilotPlugins\n : []),\n // Nodes\n HeadingPlugin,\n TocPlugin.configure({\n options: {\n scrollContainerSelector: `#${scrollSelector}`,\n topOffset: 80,\n },\n }),\n BlockquotePlugin,\n CodeBlockPlugin.configure({\n options: {\n prism: Prism,\n },\n }),\n HorizontalRulePlugin,\n LinkPlugin.extend({\n render: { afterEditable: () => },\n }),\n ...(id === 'list' ? [ListPlugin] : []),\n ImagePlugin.extend({\n render: { afterEditable: ImagePreview },\n }),\n MediaEmbedPlugin,\n CaptionPlugin.configure({\n options: {\n plugins: [ImagePlugin, MediaEmbedPlugin],\n },\n }),\n DatePlugin,\n MentionPlugin.configure({\n options: {\n triggerPreviousCharPattern: /^$|^[\\s\"']$/,\n },\n }),\n SlashPlugin,\n TablePlugin.configure({\n options: {\n enableMerging: id === 'tableMerge',\n },\n }),\n ColumnPlugin,\n SelectionOverlayPlugin,\n\n TodoListPlugin,\n TogglePlugin,\n ExcalidrawPlugin,\n // Marks\n BoldPlugin,\n ItalicPlugin,\n UnderlinePlugin,\n StrikethroughPlugin,\n CodePlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n FontColorPlugin,\n FontBackgroundColorPlugin,\n FontSizePlugin,\n HighlightPlugin,\n KbdPlugin,\n\n // Block Style\n AlignPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n MediaEmbedPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n ImagePlugin.key,\n HEADING_KEYS.h6,\n ],\n },\n }),\n IndentPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n }),\n IndentListPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n options: {\n listStyleTypes: {\n fire: {\n liComponent: FireLiComponent,\n markerComponent: FireMarker,\n type: 'fire',\n },\n todo: {\n liComponent: TodoLi,\n markerComponent: TodoMarker,\n type: 'todo',\n },\n },\n },\n }),\n LineHeightPlugin.extend({\n inject: {\n nodeProps: {\n defaultNodeValue: 1.5,\n validNodeValues: [1, 1.2, 1.5, 2, 3],\n },\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n ],\n },\n }),\n\n // Functionality\n AutoformatPlugin.configure({\n options: autoformatOptions,\n }),\n BlockSelectionPlugin.configure({\n options: {\n areaOptions: {\n behaviour: {\n scrolling: {\n speedDivider: 1.5,\n },\n startThreshold: 10,\n },\n boundaries: `#${scrollSelector}`,\n container: `#${scrollSelector}`,\n selectables: [`#${scrollSelector} .slate-selectable`],\n selectionAreaClass: 'slate-selection-area',\n },\n enableContextMenu: true,\n },\n }),\n BlockMenuPlugin.configure({\n render: { aboveEditable: BlockContextMenu },\n }),\n DndPlugin.configure({ options: { enableScroller: true } }),\n EmojiPlugin,\n exitBreakPlugin,\n NodeIdPlugin,\n NormalizeTypesPlugin.configure({\n options: {\n rules: [{ path: [0], strictType: HEADING_KEYS.h1 }],\n },\n }),\n resetBlockTypePlugin,\n SelectOnBackspacePlugin.configure({\n options: {\n query: {\n allow: [ImagePlugin.key, HorizontalRulePlugin.key],\n },\n },\n }),\n DeletePlugin,\n SingleLinePlugin,\n softBreakPlugin,\n tabbablePlugin,\n TrailingBlockPlugin.configure({\n options: { type: ParagraphPlugin.key },\n }),\n DragOverCursorPlugin,\n\n // Collaboration\n CommentsPlugin.configure({\n options: {\n comments: commentsData,\n myUserId: '1',\n users: usersData,\n },\n }),\n\n // Deserialization\n DocxPlugin,\n MarkdownPlugin.configure({ options: { indentList: true } }),\n JuicePlugin,\n\n // Testing\n PlaywrightPlugin.configure({\n enabled: process.env.NODE_ENV !== 'production',\n }),\n ],\n value: value,\n },\n []\n );\n};\n\nexport default function PlaygroundDemo({\n id,\n className,\n scrollSelector,\n}: {\n id?: ValueId;\n className?: string;\n scrollSelector?: string;\n}) {\n const containerRef = useRef(null);\n const enabled = settingsStore.use.checkedComponents();\n\n const editor = usePlaygroundEditor(\n id,\n scrollSelector ?? `blockSelection-${id}`\n );\n\n return (\n \n \n \n \n \n \n \n \n \n\n
\n \n \n\n \n \n \n \n \n \n \n\n \n \n \n \n\n \n \n \n
\n
\n
\n );\n}\n\nconst DemoIdContext = React.createContext(undefined);\n\nexport function DemoId({\n id,\n children,\n}: {\n children: React.ReactNode;\n id?: string;\n}) {\n return {children};\n}\n\nexport function useDemoId() {\n return React.useContext(DemoIdContext);\n}\n", + "content": "'use client';\n\nimport React, { useRef } from 'react';\n\nimport type { ValueId } from '@/config/customizer-plugins';\n\nimport { cn } from '@udecode/cn';\nimport { AIChatPlugin, CopilotPlugin } from '@udecode/plate-ai/react';\nimport { AlignPlugin } from '@udecode/plate-alignment/react';\nimport { AutoformatPlugin } from '@udecode/plate-autoformat/react';\nimport {\n BoldPlugin,\n CodePlugin,\n ItalicPlugin,\n StrikethroughPlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n UnderlinePlugin,\n} from '@udecode/plate-basic-marks/react';\nimport { BlockquotePlugin } from '@udecode/plate-block-quote/react';\nimport { SingleLinePlugin } from '@udecode/plate-break/react';\nimport { CaptionPlugin } from '@udecode/plate-caption/react';\nimport { CodeBlockPlugin } from '@udecode/plate-code-block/react';\nimport { CommentsPlugin } from '@udecode/plate-comments/react';\nimport {\n ParagraphPlugin,\n Plate,\n usePlateEditor,\n} from '@udecode/plate-common/react';\nimport { DatePlugin } from '@udecode/plate-date/react';\nimport { DndPlugin } from '@udecode/plate-dnd';\nimport { DocxPlugin } from '@udecode/plate-docx';\nimport { EmojiPlugin } from '@udecode/plate-emoji/react';\nimport { ExcalidrawPlugin } from '@udecode/plate-excalidraw/react';\nimport {\n FontBackgroundColorPlugin,\n FontColorPlugin,\n FontSizePlugin,\n} from '@udecode/plate-font/react';\nimport { HEADING_KEYS } from '@udecode/plate-heading';\nimport { HeadingPlugin, TocPlugin } from '@udecode/plate-heading/react';\nimport { HighlightPlugin } from '@udecode/plate-highlight/react';\nimport { HorizontalRulePlugin } from '@udecode/plate-horizontal-rule/react';\nimport { IndentPlugin } from '@udecode/plate-indent/react';\nimport { IndentListPlugin } from '@udecode/plate-indent-list/react';\nimport { JuicePlugin } from '@udecode/plate-juice';\nimport { KbdPlugin } from '@udecode/plate-kbd/react';\nimport { ColumnPlugin } from '@udecode/plate-layout/react';\nimport { LineHeightPlugin } from '@udecode/plate-line-height/react';\nimport { LinkPlugin } from '@udecode/plate-link/react';\nimport { ListPlugin, TodoListPlugin } from '@udecode/plate-list/react';\nimport { MarkdownPlugin } from '@udecode/plate-markdown';\nimport { ImagePlugin, MediaEmbedPlugin } from '@udecode/plate-media/react';\nimport { MentionPlugin } from '@udecode/plate-mention/react';\nimport { NodeIdPlugin } from '@udecode/plate-node-id';\nimport { NormalizeTypesPlugin } from '@udecode/plate-normalizers';\nimport { PlaywrightPlugin } from '@udecode/plate-playwright';\nimport { DeletePlugin, SelectOnBackspacePlugin } from '@udecode/plate-select';\nimport {\n BlockMenuPlugin,\n BlockSelectionPlugin,\n} from '@udecode/plate-selection/react';\nimport { SlashPlugin } from '@udecode/plate-slash-command/react';\nimport { TablePlugin } from '@udecode/plate-table/react';\nimport { TogglePlugin } from '@udecode/plate-toggle/react';\nimport { TrailingBlockPlugin } from '@udecode/plate-trailing-block';\nimport Prism from 'prismjs';\n\nimport { CheckPlugin } from '@/components/context/check-plugin';\nimport { settingsStore } from '@/components/context/settings-store';\nimport { aiPlugins } from '@/lib/plate/demo/plugins/ai-plugins';\nimport { getAutoformatOptions } from '@/lib/plate/demo/plugins/autoformatOptions';\nimport { copilotPlugins } from '@/lib/plate/demo/plugins/copilot-plugins';\nimport { createPlateUI } from '@/plate/create-plate-ui';\nimport { editableProps } from '@/plate/demo/editableProps';\nimport { isEnabled } from '@/plate/demo/is-enabled';\nimport { DragOverCursorPlugin } from '@/plate/demo/plugins/DragOverCursorPlugin';\nimport { exitBreakPlugin } from '@/plate/demo/plugins/exitBreakPlugin';\nimport { resetBlockTypePlugin } from '@/plate/demo/plugins/resetBlockTypePlugin';\nimport { softBreakPlugin } from '@/plate/demo/plugins/softBreakPlugin';\nimport { tabbablePlugin } from '@/plate/demo/plugins/tabbablePlugin';\nimport { commentsData, usersData } from '@/plate/demo/values/commentsValue';\nimport { usePlaygroundValue } from '@/plate/demo/values/usePlaygroundValue';\nimport { BlockContextMenu } from '@/components/plate-ui/block-context-menu';\nimport { CommentsPopover } from '@/components/plate-ui/comments-popover';\nimport {\n CursorOverlay,\n SelectionOverlayPlugin,\n} from '@/components/plate-ui/cursor-overlay';\nimport { Editor, EditorContainer } from '@/components/plate-ui/editor';\nimport { FixedToolbar } from '@/components/plate-ui/fixed-toolbar';\nimport { FixedToolbarButtons } from '@/components/plate-ui/fixed-toolbar-buttons';\nimport { FloatingToolbar } from '@/components/plate-ui/floating-toolbar';\nimport { FloatingToolbarButtons } from '@/components/plate-ui/floating-toolbar-buttons';\nimport { ImagePreview } from '@/components/plate-ui/image-preview';\nimport {\n FireLiComponent,\n FireMarker,\n} from '@/components/plate-ui/indent-fire-marker';\nimport {\n TodoLi,\n TodoMarker,\n} from '@/components/plate-ui/indent-todo-marker';\nimport { LinkFloatingToolbar } from '@/components/plate-ui/link-floating-toolbar';\n\nimport { usePlaygroundEnabled } from './usePlaygroundEnabled';\n\nexport const usePlaygroundEditor = (id: any = '', scrollSelector?: string) => {\n const enabledPlugins = settingsStore.use.checkedPlugins();\n const overridePlugins = usePlaygroundEnabled(id);\n const autoformatOptions = getAutoformatOptions(id, enabledPlugins);\n\n const value = usePlaygroundValue(id);\n const key = settingsStore.use.version();\n const editorId = id || 'playground-' + key;\n\n return usePlateEditor(\n {\n id: editorId,\n override: {\n components: createPlateUI({\n draggable: isEnabled('dnd', id),\n placeholder: isEnabled('placeholder', id),\n }),\n plugins: overridePlugins,\n },\n plugins: [\n // AI\n ...(id === 'ai' || enabledPlugins[AIChatPlugin.key] ? aiPlugins : []),\n ...(id === 'copilot' || enabledPlugins[CopilotPlugin.key]\n ? copilotPlugins\n : []),\n // Nodes\n HeadingPlugin,\n TocPlugin.configure({\n options: {\n scrollContainerSelector: `#${scrollSelector}`,\n topOffset: 80,\n },\n }),\n BlockquotePlugin,\n CodeBlockPlugin.configure({\n options: {\n prism: Prism,\n },\n }),\n HorizontalRulePlugin,\n LinkPlugin.extend({\n render: { afterEditable: () => },\n }),\n ...(id === 'list' ? [ListPlugin] : []),\n ImagePlugin.extend({\n options: {\n disableUploadInsert: true,\n },\n render: { afterEditable: ImagePreview },\n }),\n MediaEmbedPlugin,\n CaptionPlugin.configure({\n options: {\n plugins: [ImagePlugin, MediaEmbedPlugin],\n },\n }),\n DatePlugin,\n MentionPlugin.configure({\n options: {\n triggerPreviousCharPattern: /^$|^[\\s\"']$/,\n },\n }),\n SlashPlugin,\n TablePlugin.configure({\n options: {\n enableMerging: id === 'tableMerge',\n },\n }),\n ColumnPlugin,\n SelectionOverlayPlugin,\n\n TodoListPlugin,\n TogglePlugin,\n ExcalidrawPlugin,\n // Marks\n BoldPlugin,\n ItalicPlugin,\n UnderlinePlugin,\n StrikethroughPlugin,\n CodePlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n FontColorPlugin,\n FontBackgroundColorPlugin,\n FontSizePlugin,\n HighlightPlugin,\n KbdPlugin,\n\n // Block Style\n AlignPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n MediaEmbedPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n ImagePlugin.key,\n HEADING_KEYS.h6,\n ],\n },\n }),\n IndentPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n }),\n IndentListPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n options: {\n listStyleTypes: {\n fire: {\n liComponent: FireLiComponent,\n markerComponent: FireMarker,\n type: 'fire',\n },\n todo: {\n liComponent: TodoLi,\n markerComponent: TodoMarker,\n type: 'todo',\n },\n },\n },\n }),\n LineHeightPlugin.extend({\n inject: {\n nodeProps: {\n defaultNodeValue: 1.5,\n validNodeValues: [1, 1.2, 1.5, 2, 3],\n },\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n ],\n },\n }),\n\n // Functionality\n AutoformatPlugin.configure({\n options: autoformatOptions,\n }),\n BlockSelectionPlugin.configure({\n options: {\n areaOptions: {\n behaviour: {\n scrolling: {\n speedDivider: 1.5,\n },\n startThreshold: 10,\n },\n boundaries: `#${scrollSelector}`,\n container: `#${scrollSelector}`,\n selectables: [`#${scrollSelector} .slate-selectable`],\n selectionAreaClass: 'slate-selection-area',\n },\n enableContextMenu: true,\n },\n }),\n BlockMenuPlugin.configure({\n render: { aboveEditable: BlockContextMenu },\n }),\n DndPlugin.configure({\n options: {\n enableScroller: true,\n onDropFiles: ({ dragItem, editor, target }) => {\n editor\n .getTransforms(ImagePlugin)\n .insertImageFromFiles(dragItem.files, {\n at: target,\n nextBlock: false,\n });\n },\n },\n }),\n EmojiPlugin,\n exitBreakPlugin,\n NodeIdPlugin,\n NormalizeTypesPlugin.configure({\n options: {\n rules: [{ path: [0], strictType: HEADING_KEYS.h1 }],\n },\n }),\n resetBlockTypePlugin,\n SelectOnBackspacePlugin.configure({\n options: {\n query: {\n allow: [ImagePlugin.key, HorizontalRulePlugin.key],\n },\n },\n }),\n DeletePlugin,\n SingleLinePlugin,\n softBreakPlugin,\n tabbablePlugin,\n TrailingBlockPlugin.configure({\n options: { type: ParagraphPlugin.key },\n }),\n DragOverCursorPlugin,\n\n // Collaboration\n CommentsPlugin.configure({\n options: {\n comments: commentsData,\n myUserId: '1',\n users: usersData,\n },\n }),\n\n // Deserialization\n DocxPlugin,\n MarkdownPlugin.configure({ options: { indentList: true } }),\n JuicePlugin,\n\n // Testing\n PlaywrightPlugin.configure({\n enabled: process.env.NODE_ENV !== 'production',\n }),\n ],\n value: value,\n },\n []\n );\n};\n\nexport default function PlaygroundDemo({\n id,\n className,\n scrollSelector,\n}: {\n id?: ValueId;\n className?: string;\n scrollSelector?: string;\n}) {\n const containerRef = useRef(null);\n const enabled = settingsStore.use.checkedComponents();\n\n const editor = usePlaygroundEditor(\n id,\n scrollSelector ?? `blockSelection-${id}`\n );\n\n return (\n \n \n \n \n \n \n \n \n \n\n
\n \n \n\n \n \n \n \n \n \n \n\n \n \n \n \n\n \n \n \n
\n
\n
\n );\n}\n\nconst DemoIdContext = React.createContext(undefined);\n\nexport function DemoId({\n id,\n children,\n}: {\n children: React.ReactNode;\n id?: string;\n}) {\n return {children};\n}\n\nexport function useDemoId() {\n return React.useContext(DemoIdContext);\n}\n", "path": "example/playground-demo.tsx", "target": "components/playground-demo.tsx", "type": "registry:example" diff --git a/apps/www/public/r/styles/default/highlight-demo.json b/apps/www/public/r/styles/default/highlight-demo.json index 4f1152382a..2a32c44967 100644 --- a/apps/www/public/r/styles/default/highlight-demo.json +++ b/apps/www/public/r/styles/default/highlight-demo.json @@ -4,7 +4,7 @@ }, "files": [ { - "content": "'use client';\n\nimport React, { useRef } from 'react';\n\nimport type { ValueId } from '@/config/customizer-plugins';\n\nimport { cn } from '@udecode/cn';\nimport { AIChatPlugin, CopilotPlugin } from '@udecode/plate-ai/react';\nimport { AlignPlugin } from '@udecode/plate-alignment/react';\nimport { AutoformatPlugin } from '@udecode/plate-autoformat/react';\nimport {\n BoldPlugin,\n CodePlugin,\n ItalicPlugin,\n StrikethroughPlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n UnderlinePlugin,\n} from '@udecode/plate-basic-marks/react';\nimport { BlockquotePlugin } from '@udecode/plate-block-quote/react';\nimport { SingleLinePlugin } from '@udecode/plate-break/react';\nimport { CaptionPlugin } from '@udecode/plate-caption/react';\nimport { CodeBlockPlugin } from '@udecode/plate-code-block/react';\nimport { CommentsPlugin } from '@udecode/plate-comments/react';\nimport {\n ParagraphPlugin,\n Plate,\n usePlateEditor,\n} from '@udecode/plate-common/react';\nimport { DatePlugin } from '@udecode/plate-date/react';\nimport { DndPlugin } from '@udecode/plate-dnd';\nimport { DocxPlugin } from '@udecode/plate-docx';\nimport { EmojiPlugin } from '@udecode/plate-emoji/react';\nimport { ExcalidrawPlugin } from '@udecode/plate-excalidraw/react';\nimport {\n FontBackgroundColorPlugin,\n FontColorPlugin,\n FontSizePlugin,\n} from '@udecode/plate-font/react';\nimport { HEADING_KEYS } from '@udecode/plate-heading';\nimport { HeadingPlugin, TocPlugin } from '@udecode/plate-heading/react';\nimport { HighlightPlugin } from '@udecode/plate-highlight/react';\nimport { HorizontalRulePlugin } from '@udecode/plate-horizontal-rule/react';\nimport { IndentPlugin } from '@udecode/plate-indent/react';\nimport { IndentListPlugin } from '@udecode/plate-indent-list/react';\nimport { JuicePlugin } from '@udecode/plate-juice';\nimport { KbdPlugin } from '@udecode/plate-kbd/react';\nimport { ColumnPlugin } from '@udecode/plate-layout/react';\nimport { LineHeightPlugin } from '@udecode/plate-line-height/react';\nimport { LinkPlugin } from '@udecode/plate-link/react';\nimport { ListPlugin, TodoListPlugin } from '@udecode/plate-list/react';\nimport { MarkdownPlugin } from '@udecode/plate-markdown';\nimport { ImagePlugin, MediaEmbedPlugin } from '@udecode/plate-media/react';\nimport { MentionPlugin } from '@udecode/plate-mention/react';\nimport { NodeIdPlugin } from '@udecode/plate-node-id';\nimport { NormalizeTypesPlugin } from '@udecode/plate-normalizers';\nimport { PlaywrightPlugin } from '@udecode/plate-playwright';\nimport { DeletePlugin, SelectOnBackspacePlugin } from '@udecode/plate-select';\nimport {\n BlockMenuPlugin,\n BlockSelectionPlugin,\n} from '@udecode/plate-selection/react';\nimport { SlashPlugin } from '@udecode/plate-slash-command/react';\nimport { TablePlugin } from '@udecode/plate-table/react';\nimport { TogglePlugin } from '@udecode/plate-toggle/react';\nimport { TrailingBlockPlugin } from '@udecode/plate-trailing-block';\nimport Prism from 'prismjs';\n\nimport { CheckPlugin } from '@/components/context/check-plugin';\nimport { settingsStore } from '@/components/context/settings-store';\nimport { aiPlugins } from '@/lib/plate/demo/plugins/ai-plugins';\nimport { getAutoformatOptions } from '@/lib/plate/demo/plugins/autoformatOptions';\nimport { copilotPlugins } from '@/lib/plate/demo/plugins/copilot-plugins';\nimport { createPlateUI } from '@/plate/create-plate-ui';\nimport { editableProps } from '@/plate/demo/editableProps';\nimport { isEnabled } from '@/plate/demo/is-enabled';\nimport { DragOverCursorPlugin } from '@/plate/demo/plugins/DragOverCursorPlugin';\nimport { exitBreakPlugin } from '@/plate/demo/plugins/exitBreakPlugin';\nimport { resetBlockTypePlugin } from '@/plate/demo/plugins/resetBlockTypePlugin';\nimport { softBreakPlugin } from '@/plate/demo/plugins/softBreakPlugin';\nimport { tabbablePlugin } from '@/plate/demo/plugins/tabbablePlugin';\nimport { commentsData, usersData } from '@/plate/demo/values/commentsValue';\nimport { usePlaygroundValue } from '@/plate/demo/values/usePlaygroundValue';\nimport { BlockContextMenu } from '@/components/plate-ui/block-context-menu';\nimport { CommentsPopover } from '@/components/plate-ui/comments-popover';\nimport {\n CursorOverlay,\n SelectionOverlayPlugin,\n} from '@/components/plate-ui/cursor-overlay';\nimport { Editor, EditorContainer } from '@/components/plate-ui/editor';\nimport { FixedToolbar } from '@/components/plate-ui/fixed-toolbar';\nimport { FixedToolbarButtons } from '@/components/plate-ui/fixed-toolbar-buttons';\nimport { FloatingToolbar } from '@/components/plate-ui/floating-toolbar';\nimport { FloatingToolbarButtons } from '@/components/plate-ui/floating-toolbar-buttons';\nimport { ImagePreview } from '@/components/plate-ui/image-preview';\nimport {\n FireLiComponent,\n FireMarker,\n} from '@/components/plate-ui/indent-fire-marker';\nimport {\n TodoLi,\n TodoMarker,\n} from '@/components/plate-ui/indent-todo-marker';\nimport { LinkFloatingToolbar } from '@/components/plate-ui/link-floating-toolbar';\n\nimport { usePlaygroundEnabled } from './usePlaygroundEnabled';\n\nexport const usePlaygroundEditor = (id: any = '', scrollSelector?: string) => {\n const enabledPlugins = settingsStore.use.checkedPlugins();\n const overridePlugins = usePlaygroundEnabled(id);\n const autoformatOptions = getAutoformatOptions(id, enabledPlugins);\n\n const value = usePlaygroundValue(id);\n const key = settingsStore.use.version();\n const editorId = id || 'playground-' + key;\n\n return usePlateEditor(\n {\n id: editorId,\n override: {\n components: createPlateUI({\n draggable: isEnabled('dnd', id),\n placeholder: isEnabled('placeholder', id),\n }),\n plugins: overridePlugins,\n },\n plugins: [\n // AI\n ...(id === 'ai' || enabledPlugins[AIChatPlugin.key] ? aiPlugins : []),\n ...(id === 'copilot' || enabledPlugins[CopilotPlugin.key]\n ? copilotPlugins\n : []),\n // Nodes\n HeadingPlugin,\n TocPlugin.configure({\n options: {\n scrollContainerSelector: `#${scrollSelector}`,\n topOffset: 80,\n },\n }),\n BlockquotePlugin,\n CodeBlockPlugin.configure({\n options: {\n prism: Prism,\n },\n }),\n HorizontalRulePlugin,\n LinkPlugin.extend({\n render: { afterEditable: () => },\n }),\n ...(id === 'list' ? [ListPlugin] : []),\n ImagePlugin.extend({\n render: { afterEditable: ImagePreview },\n }),\n MediaEmbedPlugin,\n CaptionPlugin.configure({\n options: {\n plugins: [ImagePlugin, MediaEmbedPlugin],\n },\n }),\n DatePlugin,\n MentionPlugin.configure({\n options: {\n triggerPreviousCharPattern: /^$|^[\\s\"']$/,\n },\n }),\n SlashPlugin,\n TablePlugin.configure({\n options: {\n enableMerging: id === 'tableMerge',\n },\n }),\n ColumnPlugin,\n SelectionOverlayPlugin,\n\n TodoListPlugin,\n TogglePlugin,\n ExcalidrawPlugin,\n // Marks\n BoldPlugin,\n ItalicPlugin,\n UnderlinePlugin,\n StrikethroughPlugin,\n CodePlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n FontColorPlugin,\n FontBackgroundColorPlugin,\n FontSizePlugin,\n HighlightPlugin,\n KbdPlugin,\n\n // Block Style\n AlignPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n MediaEmbedPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n ImagePlugin.key,\n HEADING_KEYS.h6,\n ],\n },\n }),\n IndentPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n }),\n IndentListPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n options: {\n listStyleTypes: {\n fire: {\n liComponent: FireLiComponent,\n markerComponent: FireMarker,\n type: 'fire',\n },\n todo: {\n liComponent: TodoLi,\n markerComponent: TodoMarker,\n type: 'todo',\n },\n },\n },\n }),\n LineHeightPlugin.extend({\n inject: {\n nodeProps: {\n defaultNodeValue: 1.5,\n validNodeValues: [1, 1.2, 1.5, 2, 3],\n },\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n ],\n },\n }),\n\n // Functionality\n AutoformatPlugin.configure({\n options: autoformatOptions,\n }),\n BlockSelectionPlugin.configure({\n options: {\n areaOptions: {\n behaviour: {\n scrolling: {\n speedDivider: 1.5,\n },\n startThreshold: 10,\n },\n boundaries: `#${scrollSelector}`,\n container: `#${scrollSelector}`,\n selectables: [`#${scrollSelector} .slate-selectable`],\n selectionAreaClass: 'slate-selection-area',\n },\n enableContextMenu: true,\n },\n }),\n BlockMenuPlugin.configure({\n render: { aboveEditable: BlockContextMenu },\n }),\n DndPlugin.configure({ options: { enableScroller: true } }),\n EmojiPlugin,\n exitBreakPlugin,\n NodeIdPlugin,\n NormalizeTypesPlugin.configure({\n options: {\n rules: [{ path: [0], strictType: HEADING_KEYS.h1 }],\n },\n }),\n resetBlockTypePlugin,\n SelectOnBackspacePlugin.configure({\n options: {\n query: {\n allow: [ImagePlugin.key, HorizontalRulePlugin.key],\n },\n },\n }),\n DeletePlugin,\n SingleLinePlugin,\n softBreakPlugin,\n tabbablePlugin,\n TrailingBlockPlugin.configure({\n options: { type: ParagraphPlugin.key },\n }),\n DragOverCursorPlugin,\n\n // Collaboration\n CommentsPlugin.configure({\n options: {\n comments: commentsData,\n myUserId: '1',\n users: usersData,\n },\n }),\n\n // Deserialization\n DocxPlugin,\n MarkdownPlugin.configure({ options: { indentList: true } }),\n JuicePlugin,\n\n // Testing\n PlaywrightPlugin.configure({\n enabled: process.env.NODE_ENV !== 'production',\n }),\n ],\n value: value,\n },\n []\n );\n};\n\nexport default function PlaygroundDemo({\n id,\n className,\n scrollSelector,\n}: {\n id?: ValueId;\n className?: string;\n scrollSelector?: string;\n}) {\n const containerRef = useRef(null);\n const enabled = settingsStore.use.checkedComponents();\n\n const editor = usePlaygroundEditor(\n id,\n scrollSelector ?? `blockSelection-${id}`\n );\n\n return (\n \n \n \n \n \n \n \n \n \n\n
\n \n \n\n \n \n \n \n \n \n \n\n \n \n \n \n\n \n \n \n
\n
\n
\n );\n}\n\nconst DemoIdContext = React.createContext(undefined);\n\nexport function DemoId({\n id,\n children,\n}: {\n children: React.ReactNode;\n id?: string;\n}) {\n return {children};\n}\n\nexport function useDemoId() {\n return React.useContext(DemoIdContext);\n}\n", + "content": "'use client';\n\nimport React, { useRef } from 'react';\n\nimport type { ValueId } from '@/config/customizer-plugins';\n\nimport { cn } from '@udecode/cn';\nimport { AIChatPlugin, CopilotPlugin } from '@udecode/plate-ai/react';\nimport { AlignPlugin } from '@udecode/plate-alignment/react';\nimport { AutoformatPlugin } from '@udecode/plate-autoformat/react';\nimport {\n BoldPlugin,\n CodePlugin,\n ItalicPlugin,\n StrikethroughPlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n UnderlinePlugin,\n} from '@udecode/plate-basic-marks/react';\nimport { BlockquotePlugin } from '@udecode/plate-block-quote/react';\nimport { SingleLinePlugin } from '@udecode/plate-break/react';\nimport { CaptionPlugin } from '@udecode/plate-caption/react';\nimport { CodeBlockPlugin } from '@udecode/plate-code-block/react';\nimport { CommentsPlugin } from '@udecode/plate-comments/react';\nimport {\n ParagraphPlugin,\n Plate,\n usePlateEditor,\n} from '@udecode/plate-common/react';\nimport { DatePlugin } from '@udecode/plate-date/react';\nimport { DndPlugin } from '@udecode/plate-dnd';\nimport { DocxPlugin } from '@udecode/plate-docx';\nimport { EmojiPlugin } from '@udecode/plate-emoji/react';\nimport { ExcalidrawPlugin } from '@udecode/plate-excalidraw/react';\nimport {\n FontBackgroundColorPlugin,\n FontColorPlugin,\n FontSizePlugin,\n} from '@udecode/plate-font/react';\nimport { HEADING_KEYS } from '@udecode/plate-heading';\nimport { HeadingPlugin, TocPlugin } from '@udecode/plate-heading/react';\nimport { HighlightPlugin } from '@udecode/plate-highlight/react';\nimport { HorizontalRulePlugin } from '@udecode/plate-horizontal-rule/react';\nimport { IndentPlugin } from '@udecode/plate-indent/react';\nimport { IndentListPlugin } from '@udecode/plate-indent-list/react';\nimport { JuicePlugin } from '@udecode/plate-juice';\nimport { KbdPlugin } from '@udecode/plate-kbd/react';\nimport { ColumnPlugin } from '@udecode/plate-layout/react';\nimport { LineHeightPlugin } from '@udecode/plate-line-height/react';\nimport { LinkPlugin } from '@udecode/plate-link/react';\nimport { ListPlugin, TodoListPlugin } from '@udecode/plate-list/react';\nimport { MarkdownPlugin } from '@udecode/plate-markdown';\nimport { ImagePlugin, MediaEmbedPlugin } from '@udecode/plate-media/react';\nimport { MentionPlugin } from '@udecode/plate-mention/react';\nimport { NodeIdPlugin } from '@udecode/plate-node-id';\nimport { NormalizeTypesPlugin } from '@udecode/plate-normalizers';\nimport { PlaywrightPlugin } from '@udecode/plate-playwright';\nimport { DeletePlugin, SelectOnBackspacePlugin } from '@udecode/plate-select';\nimport {\n BlockMenuPlugin,\n BlockSelectionPlugin,\n} from '@udecode/plate-selection/react';\nimport { SlashPlugin } from '@udecode/plate-slash-command/react';\nimport { TablePlugin } from '@udecode/plate-table/react';\nimport { TogglePlugin } from '@udecode/plate-toggle/react';\nimport { TrailingBlockPlugin } from '@udecode/plate-trailing-block';\nimport Prism from 'prismjs';\n\nimport { CheckPlugin } from '@/components/context/check-plugin';\nimport { settingsStore } from '@/components/context/settings-store';\nimport { aiPlugins } from '@/lib/plate/demo/plugins/ai-plugins';\nimport { getAutoformatOptions } from '@/lib/plate/demo/plugins/autoformatOptions';\nimport { copilotPlugins } from '@/lib/plate/demo/plugins/copilot-plugins';\nimport { createPlateUI } from '@/plate/create-plate-ui';\nimport { editableProps } from '@/plate/demo/editableProps';\nimport { isEnabled } from '@/plate/demo/is-enabled';\nimport { DragOverCursorPlugin } from '@/plate/demo/plugins/DragOverCursorPlugin';\nimport { exitBreakPlugin } from '@/plate/demo/plugins/exitBreakPlugin';\nimport { resetBlockTypePlugin } from '@/plate/demo/plugins/resetBlockTypePlugin';\nimport { softBreakPlugin } from '@/plate/demo/plugins/softBreakPlugin';\nimport { tabbablePlugin } from '@/plate/demo/plugins/tabbablePlugin';\nimport { commentsData, usersData } from '@/plate/demo/values/commentsValue';\nimport { usePlaygroundValue } from '@/plate/demo/values/usePlaygroundValue';\nimport { BlockContextMenu } from '@/components/plate-ui/block-context-menu';\nimport { CommentsPopover } from '@/components/plate-ui/comments-popover';\nimport {\n CursorOverlay,\n SelectionOverlayPlugin,\n} from '@/components/plate-ui/cursor-overlay';\nimport { Editor, EditorContainer } from '@/components/plate-ui/editor';\nimport { FixedToolbar } from '@/components/plate-ui/fixed-toolbar';\nimport { FixedToolbarButtons } from '@/components/plate-ui/fixed-toolbar-buttons';\nimport { FloatingToolbar } from '@/components/plate-ui/floating-toolbar';\nimport { FloatingToolbarButtons } from '@/components/plate-ui/floating-toolbar-buttons';\nimport { ImagePreview } from '@/components/plate-ui/image-preview';\nimport {\n FireLiComponent,\n FireMarker,\n} from '@/components/plate-ui/indent-fire-marker';\nimport {\n TodoLi,\n TodoMarker,\n} from '@/components/plate-ui/indent-todo-marker';\nimport { LinkFloatingToolbar } from '@/components/plate-ui/link-floating-toolbar';\n\nimport { usePlaygroundEnabled } from './usePlaygroundEnabled';\n\nexport const usePlaygroundEditor = (id: any = '', scrollSelector?: string) => {\n const enabledPlugins = settingsStore.use.checkedPlugins();\n const overridePlugins = usePlaygroundEnabled(id);\n const autoformatOptions = getAutoformatOptions(id, enabledPlugins);\n\n const value = usePlaygroundValue(id);\n const key = settingsStore.use.version();\n const editorId = id || 'playground-' + key;\n\n return usePlateEditor(\n {\n id: editorId,\n override: {\n components: createPlateUI({\n draggable: isEnabled('dnd', id),\n placeholder: isEnabled('placeholder', id),\n }),\n plugins: overridePlugins,\n },\n plugins: [\n // AI\n ...(id === 'ai' || enabledPlugins[AIChatPlugin.key] ? aiPlugins : []),\n ...(id === 'copilot' || enabledPlugins[CopilotPlugin.key]\n ? copilotPlugins\n : []),\n // Nodes\n HeadingPlugin,\n TocPlugin.configure({\n options: {\n scrollContainerSelector: `#${scrollSelector}`,\n topOffset: 80,\n },\n }),\n BlockquotePlugin,\n CodeBlockPlugin.configure({\n options: {\n prism: Prism,\n },\n }),\n HorizontalRulePlugin,\n LinkPlugin.extend({\n render: { afterEditable: () => },\n }),\n ...(id === 'list' ? [ListPlugin] : []),\n ImagePlugin.extend({\n options: {\n disableUploadInsert: true,\n },\n render: { afterEditable: ImagePreview },\n }),\n MediaEmbedPlugin,\n CaptionPlugin.configure({\n options: {\n plugins: [ImagePlugin, MediaEmbedPlugin],\n },\n }),\n DatePlugin,\n MentionPlugin.configure({\n options: {\n triggerPreviousCharPattern: /^$|^[\\s\"']$/,\n },\n }),\n SlashPlugin,\n TablePlugin.configure({\n options: {\n enableMerging: id === 'tableMerge',\n },\n }),\n ColumnPlugin,\n SelectionOverlayPlugin,\n\n TodoListPlugin,\n TogglePlugin,\n ExcalidrawPlugin,\n // Marks\n BoldPlugin,\n ItalicPlugin,\n UnderlinePlugin,\n StrikethroughPlugin,\n CodePlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n FontColorPlugin,\n FontBackgroundColorPlugin,\n FontSizePlugin,\n HighlightPlugin,\n KbdPlugin,\n\n // Block Style\n AlignPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n MediaEmbedPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n ImagePlugin.key,\n HEADING_KEYS.h6,\n ],\n },\n }),\n IndentPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n }),\n IndentListPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n options: {\n listStyleTypes: {\n fire: {\n liComponent: FireLiComponent,\n markerComponent: FireMarker,\n type: 'fire',\n },\n todo: {\n liComponent: TodoLi,\n markerComponent: TodoMarker,\n type: 'todo',\n },\n },\n },\n }),\n LineHeightPlugin.extend({\n inject: {\n nodeProps: {\n defaultNodeValue: 1.5,\n validNodeValues: [1, 1.2, 1.5, 2, 3],\n },\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n ],\n },\n }),\n\n // Functionality\n AutoformatPlugin.configure({\n options: autoformatOptions,\n }),\n BlockSelectionPlugin.configure({\n options: {\n areaOptions: {\n behaviour: {\n scrolling: {\n speedDivider: 1.5,\n },\n startThreshold: 10,\n },\n boundaries: `#${scrollSelector}`,\n container: `#${scrollSelector}`,\n selectables: [`#${scrollSelector} .slate-selectable`],\n selectionAreaClass: 'slate-selection-area',\n },\n enableContextMenu: true,\n },\n }),\n BlockMenuPlugin.configure({\n render: { aboveEditable: BlockContextMenu },\n }),\n DndPlugin.configure({\n options: {\n enableScroller: true,\n onDropFiles: ({ dragItem, editor, target }) => {\n editor\n .getTransforms(ImagePlugin)\n .insertImageFromFiles(dragItem.files, {\n at: target,\n nextBlock: false,\n });\n },\n },\n }),\n EmojiPlugin,\n exitBreakPlugin,\n NodeIdPlugin,\n NormalizeTypesPlugin.configure({\n options: {\n rules: [{ path: [0], strictType: HEADING_KEYS.h1 }],\n },\n }),\n resetBlockTypePlugin,\n SelectOnBackspacePlugin.configure({\n options: {\n query: {\n allow: [ImagePlugin.key, HorizontalRulePlugin.key],\n },\n },\n }),\n DeletePlugin,\n SingleLinePlugin,\n softBreakPlugin,\n tabbablePlugin,\n TrailingBlockPlugin.configure({\n options: { type: ParagraphPlugin.key },\n }),\n DragOverCursorPlugin,\n\n // Collaboration\n CommentsPlugin.configure({\n options: {\n comments: commentsData,\n myUserId: '1',\n users: usersData,\n },\n }),\n\n // Deserialization\n DocxPlugin,\n MarkdownPlugin.configure({ options: { indentList: true } }),\n JuicePlugin,\n\n // Testing\n PlaywrightPlugin.configure({\n enabled: process.env.NODE_ENV !== 'production',\n }),\n ],\n value: value,\n },\n []\n );\n};\n\nexport default function PlaygroundDemo({\n id,\n className,\n scrollSelector,\n}: {\n id?: ValueId;\n className?: string;\n scrollSelector?: string;\n}) {\n const containerRef = useRef(null);\n const enabled = settingsStore.use.checkedComponents();\n\n const editor = usePlaygroundEditor(\n id,\n scrollSelector ?? `blockSelection-${id}`\n );\n\n return (\n \n \n \n \n \n \n \n \n \n\n
\n \n \n\n \n \n \n \n \n \n \n\n \n \n \n \n\n \n \n \n
\n
\n
\n );\n}\n\nconst DemoIdContext = React.createContext(undefined);\n\nexport function DemoId({\n id,\n children,\n}: {\n children: React.ReactNode;\n id?: string;\n}) {\n return {children};\n}\n\nexport function useDemoId() {\n return React.useContext(DemoIdContext);\n}\n", "path": "example/playground-demo.tsx", "target": "components/playground-demo.tsx", "type": "registry:example" diff --git a/apps/www/public/r/styles/default/hr-demo.json b/apps/www/public/r/styles/default/hr-demo.json index 3e59b3d150..e3cbb00b88 100644 --- a/apps/www/public/r/styles/default/hr-demo.json +++ b/apps/www/public/r/styles/default/hr-demo.json @@ -5,7 +5,7 @@ }, "files": [ { - "content": "'use client';\n\nimport React, { useRef } from 'react';\n\nimport type { ValueId } from '@/config/customizer-plugins';\n\nimport { cn } from '@udecode/cn';\nimport { AIChatPlugin, CopilotPlugin } from '@udecode/plate-ai/react';\nimport { AlignPlugin } from '@udecode/plate-alignment/react';\nimport { AutoformatPlugin } from '@udecode/plate-autoformat/react';\nimport {\n BoldPlugin,\n CodePlugin,\n ItalicPlugin,\n StrikethroughPlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n UnderlinePlugin,\n} from '@udecode/plate-basic-marks/react';\nimport { BlockquotePlugin } from '@udecode/plate-block-quote/react';\nimport { SingleLinePlugin } from '@udecode/plate-break/react';\nimport { CaptionPlugin } from '@udecode/plate-caption/react';\nimport { CodeBlockPlugin } from '@udecode/plate-code-block/react';\nimport { CommentsPlugin } from '@udecode/plate-comments/react';\nimport {\n ParagraphPlugin,\n Plate,\n usePlateEditor,\n} from '@udecode/plate-common/react';\nimport { DatePlugin } from '@udecode/plate-date/react';\nimport { DndPlugin } from '@udecode/plate-dnd';\nimport { DocxPlugin } from '@udecode/plate-docx';\nimport { EmojiPlugin } from '@udecode/plate-emoji/react';\nimport { ExcalidrawPlugin } from '@udecode/plate-excalidraw/react';\nimport {\n FontBackgroundColorPlugin,\n FontColorPlugin,\n FontSizePlugin,\n} from '@udecode/plate-font/react';\nimport { HEADING_KEYS } from '@udecode/plate-heading';\nimport { HeadingPlugin, TocPlugin } from '@udecode/plate-heading/react';\nimport { HighlightPlugin } from '@udecode/plate-highlight/react';\nimport { HorizontalRulePlugin } from '@udecode/plate-horizontal-rule/react';\nimport { IndentPlugin } from '@udecode/plate-indent/react';\nimport { IndentListPlugin } from '@udecode/plate-indent-list/react';\nimport { JuicePlugin } from '@udecode/plate-juice';\nimport { KbdPlugin } from '@udecode/plate-kbd/react';\nimport { ColumnPlugin } from '@udecode/plate-layout/react';\nimport { LineHeightPlugin } from '@udecode/plate-line-height/react';\nimport { LinkPlugin } from '@udecode/plate-link/react';\nimport { ListPlugin, TodoListPlugin } from '@udecode/plate-list/react';\nimport { MarkdownPlugin } from '@udecode/plate-markdown';\nimport { ImagePlugin, MediaEmbedPlugin } from '@udecode/plate-media/react';\nimport { MentionPlugin } from '@udecode/plate-mention/react';\nimport { NodeIdPlugin } from '@udecode/plate-node-id';\nimport { NormalizeTypesPlugin } from '@udecode/plate-normalizers';\nimport { PlaywrightPlugin } from '@udecode/plate-playwright';\nimport { DeletePlugin, SelectOnBackspacePlugin } from '@udecode/plate-select';\nimport {\n BlockMenuPlugin,\n BlockSelectionPlugin,\n} from '@udecode/plate-selection/react';\nimport { SlashPlugin } from '@udecode/plate-slash-command/react';\nimport { TablePlugin } from '@udecode/plate-table/react';\nimport { TogglePlugin } from '@udecode/plate-toggle/react';\nimport { TrailingBlockPlugin } from '@udecode/plate-trailing-block';\nimport Prism from 'prismjs';\n\nimport { CheckPlugin } from '@/components/context/check-plugin';\nimport { settingsStore } from '@/components/context/settings-store';\nimport { aiPlugins } from '@/lib/plate/demo/plugins/ai-plugins';\nimport { getAutoformatOptions } from '@/lib/plate/demo/plugins/autoformatOptions';\nimport { copilotPlugins } from '@/lib/plate/demo/plugins/copilot-plugins';\nimport { createPlateUI } from '@/plate/create-plate-ui';\nimport { editableProps } from '@/plate/demo/editableProps';\nimport { isEnabled } from '@/plate/demo/is-enabled';\nimport { DragOverCursorPlugin } from '@/plate/demo/plugins/DragOverCursorPlugin';\nimport { exitBreakPlugin } from '@/plate/demo/plugins/exitBreakPlugin';\nimport { resetBlockTypePlugin } from '@/plate/demo/plugins/resetBlockTypePlugin';\nimport { softBreakPlugin } from '@/plate/demo/plugins/softBreakPlugin';\nimport { tabbablePlugin } from '@/plate/demo/plugins/tabbablePlugin';\nimport { commentsData, usersData } from '@/plate/demo/values/commentsValue';\nimport { usePlaygroundValue } from '@/plate/demo/values/usePlaygroundValue';\nimport { BlockContextMenu } from '@/components/plate-ui/block-context-menu';\nimport { CommentsPopover } from '@/components/plate-ui/comments-popover';\nimport {\n CursorOverlay,\n SelectionOverlayPlugin,\n} from '@/components/plate-ui/cursor-overlay';\nimport { Editor, EditorContainer } from '@/components/plate-ui/editor';\nimport { FixedToolbar } from '@/components/plate-ui/fixed-toolbar';\nimport { FixedToolbarButtons } from '@/components/plate-ui/fixed-toolbar-buttons';\nimport { FloatingToolbar } from '@/components/plate-ui/floating-toolbar';\nimport { FloatingToolbarButtons } from '@/components/plate-ui/floating-toolbar-buttons';\nimport { ImagePreview } from '@/components/plate-ui/image-preview';\nimport {\n FireLiComponent,\n FireMarker,\n} from '@/components/plate-ui/indent-fire-marker';\nimport {\n TodoLi,\n TodoMarker,\n} from '@/components/plate-ui/indent-todo-marker';\nimport { LinkFloatingToolbar } from '@/components/plate-ui/link-floating-toolbar';\n\nimport { usePlaygroundEnabled } from './usePlaygroundEnabled';\n\nexport const usePlaygroundEditor = (id: any = '', scrollSelector?: string) => {\n const enabledPlugins = settingsStore.use.checkedPlugins();\n const overridePlugins = usePlaygroundEnabled(id);\n const autoformatOptions = getAutoformatOptions(id, enabledPlugins);\n\n const value = usePlaygroundValue(id);\n const key = settingsStore.use.version();\n const editorId = id || 'playground-' + key;\n\n return usePlateEditor(\n {\n id: editorId,\n override: {\n components: createPlateUI({\n draggable: isEnabled('dnd', id),\n placeholder: isEnabled('placeholder', id),\n }),\n plugins: overridePlugins,\n },\n plugins: [\n // AI\n ...(id === 'ai' || enabledPlugins[AIChatPlugin.key] ? aiPlugins : []),\n ...(id === 'copilot' || enabledPlugins[CopilotPlugin.key]\n ? copilotPlugins\n : []),\n // Nodes\n HeadingPlugin,\n TocPlugin.configure({\n options: {\n scrollContainerSelector: `#${scrollSelector}`,\n topOffset: 80,\n },\n }),\n BlockquotePlugin,\n CodeBlockPlugin.configure({\n options: {\n prism: Prism,\n },\n }),\n HorizontalRulePlugin,\n LinkPlugin.extend({\n render: { afterEditable: () => },\n }),\n ...(id === 'list' ? [ListPlugin] : []),\n ImagePlugin.extend({\n render: { afterEditable: ImagePreview },\n }),\n MediaEmbedPlugin,\n CaptionPlugin.configure({\n options: {\n plugins: [ImagePlugin, MediaEmbedPlugin],\n },\n }),\n DatePlugin,\n MentionPlugin.configure({\n options: {\n triggerPreviousCharPattern: /^$|^[\\s\"']$/,\n },\n }),\n SlashPlugin,\n TablePlugin.configure({\n options: {\n enableMerging: id === 'tableMerge',\n },\n }),\n ColumnPlugin,\n SelectionOverlayPlugin,\n\n TodoListPlugin,\n TogglePlugin,\n ExcalidrawPlugin,\n // Marks\n BoldPlugin,\n ItalicPlugin,\n UnderlinePlugin,\n StrikethroughPlugin,\n CodePlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n FontColorPlugin,\n FontBackgroundColorPlugin,\n FontSizePlugin,\n HighlightPlugin,\n KbdPlugin,\n\n // Block Style\n AlignPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n MediaEmbedPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n ImagePlugin.key,\n HEADING_KEYS.h6,\n ],\n },\n }),\n IndentPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n }),\n IndentListPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n options: {\n listStyleTypes: {\n fire: {\n liComponent: FireLiComponent,\n markerComponent: FireMarker,\n type: 'fire',\n },\n todo: {\n liComponent: TodoLi,\n markerComponent: TodoMarker,\n type: 'todo',\n },\n },\n },\n }),\n LineHeightPlugin.extend({\n inject: {\n nodeProps: {\n defaultNodeValue: 1.5,\n validNodeValues: [1, 1.2, 1.5, 2, 3],\n },\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n ],\n },\n }),\n\n // Functionality\n AutoformatPlugin.configure({\n options: autoformatOptions,\n }),\n BlockSelectionPlugin.configure({\n options: {\n areaOptions: {\n behaviour: {\n scrolling: {\n speedDivider: 1.5,\n },\n startThreshold: 10,\n },\n boundaries: `#${scrollSelector}`,\n container: `#${scrollSelector}`,\n selectables: [`#${scrollSelector} .slate-selectable`],\n selectionAreaClass: 'slate-selection-area',\n },\n enableContextMenu: true,\n },\n }),\n BlockMenuPlugin.configure({\n render: { aboveEditable: BlockContextMenu },\n }),\n DndPlugin.configure({ options: { enableScroller: true } }),\n EmojiPlugin,\n exitBreakPlugin,\n NodeIdPlugin,\n NormalizeTypesPlugin.configure({\n options: {\n rules: [{ path: [0], strictType: HEADING_KEYS.h1 }],\n },\n }),\n resetBlockTypePlugin,\n SelectOnBackspacePlugin.configure({\n options: {\n query: {\n allow: [ImagePlugin.key, HorizontalRulePlugin.key],\n },\n },\n }),\n DeletePlugin,\n SingleLinePlugin,\n softBreakPlugin,\n tabbablePlugin,\n TrailingBlockPlugin.configure({\n options: { type: ParagraphPlugin.key },\n }),\n DragOverCursorPlugin,\n\n // Collaboration\n CommentsPlugin.configure({\n options: {\n comments: commentsData,\n myUserId: '1',\n users: usersData,\n },\n }),\n\n // Deserialization\n DocxPlugin,\n MarkdownPlugin.configure({ options: { indentList: true } }),\n JuicePlugin,\n\n // Testing\n PlaywrightPlugin.configure({\n enabled: process.env.NODE_ENV !== 'production',\n }),\n ],\n value: value,\n },\n []\n );\n};\n\nexport default function PlaygroundDemo({\n id,\n className,\n scrollSelector,\n}: {\n id?: ValueId;\n className?: string;\n scrollSelector?: string;\n}) {\n const containerRef = useRef(null);\n const enabled = settingsStore.use.checkedComponents();\n\n const editor = usePlaygroundEditor(\n id,\n scrollSelector ?? `blockSelection-${id}`\n );\n\n return (\n \n \n \n \n \n \n \n \n \n\n
\n \n \n\n \n \n \n \n \n \n \n\n \n \n \n \n\n \n \n \n
\n
\n
\n );\n}\n\nconst DemoIdContext = React.createContext(undefined);\n\nexport function DemoId({\n id,\n children,\n}: {\n children: React.ReactNode;\n id?: string;\n}) {\n return {children};\n}\n\nexport function useDemoId() {\n return React.useContext(DemoIdContext);\n}\n", + "content": "'use client';\n\nimport React, { useRef } from 'react';\n\nimport type { ValueId } from '@/config/customizer-plugins';\n\nimport { cn } from '@udecode/cn';\nimport { AIChatPlugin, CopilotPlugin } from '@udecode/plate-ai/react';\nimport { AlignPlugin } from '@udecode/plate-alignment/react';\nimport { AutoformatPlugin } from '@udecode/plate-autoformat/react';\nimport {\n BoldPlugin,\n CodePlugin,\n ItalicPlugin,\n StrikethroughPlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n UnderlinePlugin,\n} from '@udecode/plate-basic-marks/react';\nimport { BlockquotePlugin } from '@udecode/plate-block-quote/react';\nimport { SingleLinePlugin } from '@udecode/plate-break/react';\nimport { CaptionPlugin } from '@udecode/plate-caption/react';\nimport { CodeBlockPlugin } from '@udecode/plate-code-block/react';\nimport { CommentsPlugin } from '@udecode/plate-comments/react';\nimport {\n ParagraphPlugin,\n Plate,\n usePlateEditor,\n} from '@udecode/plate-common/react';\nimport { DatePlugin } from '@udecode/plate-date/react';\nimport { DndPlugin } from '@udecode/plate-dnd';\nimport { DocxPlugin } from '@udecode/plate-docx';\nimport { EmojiPlugin } from '@udecode/plate-emoji/react';\nimport { ExcalidrawPlugin } from '@udecode/plate-excalidraw/react';\nimport {\n FontBackgroundColorPlugin,\n FontColorPlugin,\n FontSizePlugin,\n} from '@udecode/plate-font/react';\nimport { HEADING_KEYS } from '@udecode/plate-heading';\nimport { HeadingPlugin, TocPlugin } from '@udecode/plate-heading/react';\nimport { HighlightPlugin } from '@udecode/plate-highlight/react';\nimport { HorizontalRulePlugin } from '@udecode/plate-horizontal-rule/react';\nimport { IndentPlugin } from '@udecode/plate-indent/react';\nimport { IndentListPlugin } from '@udecode/plate-indent-list/react';\nimport { JuicePlugin } from '@udecode/plate-juice';\nimport { KbdPlugin } from '@udecode/plate-kbd/react';\nimport { ColumnPlugin } from '@udecode/plate-layout/react';\nimport { LineHeightPlugin } from '@udecode/plate-line-height/react';\nimport { LinkPlugin } from '@udecode/plate-link/react';\nimport { ListPlugin, TodoListPlugin } from '@udecode/plate-list/react';\nimport { MarkdownPlugin } from '@udecode/plate-markdown';\nimport { ImagePlugin, MediaEmbedPlugin } from '@udecode/plate-media/react';\nimport { MentionPlugin } from '@udecode/plate-mention/react';\nimport { NodeIdPlugin } from '@udecode/plate-node-id';\nimport { NormalizeTypesPlugin } from '@udecode/plate-normalizers';\nimport { PlaywrightPlugin } from '@udecode/plate-playwright';\nimport { DeletePlugin, SelectOnBackspacePlugin } from '@udecode/plate-select';\nimport {\n BlockMenuPlugin,\n BlockSelectionPlugin,\n} from '@udecode/plate-selection/react';\nimport { SlashPlugin } from '@udecode/plate-slash-command/react';\nimport { TablePlugin } from '@udecode/plate-table/react';\nimport { TogglePlugin } from '@udecode/plate-toggle/react';\nimport { TrailingBlockPlugin } from '@udecode/plate-trailing-block';\nimport Prism from 'prismjs';\n\nimport { CheckPlugin } from '@/components/context/check-plugin';\nimport { settingsStore } from '@/components/context/settings-store';\nimport { aiPlugins } from '@/lib/plate/demo/plugins/ai-plugins';\nimport { getAutoformatOptions } from '@/lib/plate/demo/plugins/autoformatOptions';\nimport { copilotPlugins } from '@/lib/plate/demo/plugins/copilot-plugins';\nimport { createPlateUI } from '@/plate/create-plate-ui';\nimport { editableProps } from '@/plate/demo/editableProps';\nimport { isEnabled } from '@/plate/demo/is-enabled';\nimport { DragOverCursorPlugin } from '@/plate/demo/plugins/DragOverCursorPlugin';\nimport { exitBreakPlugin } from '@/plate/demo/plugins/exitBreakPlugin';\nimport { resetBlockTypePlugin } from '@/plate/demo/plugins/resetBlockTypePlugin';\nimport { softBreakPlugin } from '@/plate/demo/plugins/softBreakPlugin';\nimport { tabbablePlugin } from '@/plate/demo/plugins/tabbablePlugin';\nimport { commentsData, usersData } from '@/plate/demo/values/commentsValue';\nimport { usePlaygroundValue } from '@/plate/demo/values/usePlaygroundValue';\nimport { BlockContextMenu } from '@/components/plate-ui/block-context-menu';\nimport { CommentsPopover } from '@/components/plate-ui/comments-popover';\nimport {\n CursorOverlay,\n SelectionOverlayPlugin,\n} from '@/components/plate-ui/cursor-overlay';\nimport { Editor, EditorContainer } from '@/components/plate-ui/editor';\nimport { FixedToolbar } from '@/components/plate-ui/fixed-toolbar';\nimport { FixedToolbarButtons } from '@/components/plate-ui/fixed-toolbar-buttons';\nimport { FloatingToolbar } from '@/components/plate-ui/floating-toolbar';\nimport { FloatingToolbarButtons } from '@/components/plate-ui/floating-toolbar-buttons';\nimport { ImagePreview } from '@/components/plate-ui/image-preview';\nimport {\n FireLiComponent,\n FireMarker,\n} from '@/components/plate-ui/indent-fire-marker';\nimport {\n TodoLi,\n TodoMarker,\n} from '@/components/plate-ui/indent-todo-marker';\nimport { LinkFloatingToolbar } from '@/components/plate-ui/link-floating-toolbar';\n\nimport { usePlaygroundEnabled } from './usePlaygroundEnabled';\n\nexport const usePlaygroundEditor = (id: any = '', scrollSelector?: string) => {\n const enabledPlugins = settingsStore.use.checkedPlugins();\n const overridePlugins = usePlaygroundEnabled(id);\n const autoformatOptions = getAutoformatOptions(id, enabledPlugins);\n\n const value = usePlaygroundValue(id);\n const key = settingsStore.use.version();\n const editorId = id || 'playground-' + key;\n\n return usePlateEditor(\n {\n id: editorId,\n override: {\n components: createPlateUI({\n draggable: isEnabled('dnd', id),\n placeholder: isEnabled('placeholder', id),\n }),\n plugins: overridePlugins,\n },\n plugins: [\n // AI\n ...(id === 'ai' || enabledPlugins[AIChatPlugin.key] ? aiPlugins : []),\n ...(id === 'copilot' || enabledPlugins[CopilotPlugin.key]\n ? copilotPlugins\n : []),\n // Nodes\n HeadingPlugin,\n TocPlugin.configure({\n options: {\n scrollContainerSelector: `#${scrollSelector}`,\n topOffset: 80,\n },\n }),\n BlockquotePlugin,\n CodeBlockPlugin.configure({\n options: {\n prism: Prism,\n },\n }),\n HorizontalRulePlugin,\n LinkPlugin.extend({\n render: { afterEditable: () => },\n }),\n ...(id === 'list' ? [ListPlugin] : []),\n ImagePlugin.extend({\n options: {\n disableUploadInsert: true,\n },\n render: { afterEditable: ImagePreview },\n }),\n MediaEmbedPlugin,\n CaptionPlugin.configure({\n options: {\n plugins: [ImagePlugin, MediaEmbedPlugin],\n },\n }),\n DatePlugin,\n MentionPlugin.configure({\n options: {\n triggerPreviousCharPattern: /^$|^[\\s\"']$/,\n },\n }),\n SlashPlugin,\n TablePlugin.configure({\n options: {\n enableMerging: id === 'tableMerge',\n },\n }),\n ColumnPlugin,\n SelectionOverlayPlugin,\n\n TodoListPlugin,\n TogglePlugin,\n ExcalidrawPlugin,\n // Marks\n BoldPlugin,\n ItalicPlugin,\n UnderlinePlugin,\n StrikethroughPlugin,\n CodePlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n FontColorPlugin,\n FontBackgroundColorPlugin,\n FontSizePlugin,\n HighlightPlugin,\n KbdPlugin,\n\n // Block Style\n AlignPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n MediaEmbedPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n ImagePlugin.key,\n HEADING_KEYS.h6,\n ],\n },\n }),\n IndentPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n }),\n IndentListPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n options: {\n listStyleTypes: {\n fire: {\n liComponent: FireLiComponent,\n markerComponent: FireMarker,\n type: 'fire',\n },\n todo: {\n liComponent: TodoLi,\n markerComponent: TodoMarker,\n type: 'todo',\n },\n },\n },\n }),\n LineHeightPlugin.extend({\n inject: {\n nodeProps: {\n defaultNodeValue: 1.5,\n validNodeValues: [1, 1.2, 1.5, 2, 3],\n },\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n ],\n },\n }),\n\n // Functionality\n AutoformatPlugin.configure({\n options: autoformatOptions,\n }),\n BlockSelectionPlugin.configure({\n options: {\n areaOptions: {\n behaviour: {\n scrolling: {\n speedDivider: 1.5,\n },\n startThreshold: 10,\n },\n boundaries: `#${scrollSelector}`,\n container: `#${scrollSelector}`,\n selectables: [`#${scrollSelector} .slate-selectable`],\n selectionAreaClass: 'slate-selection-area',\n },\n enableContextMenu: true,\n },\n }),\n BlockMenuPlugin.configure({\n render: { aboveEditable: BlockContextMenu },\n }),\n DndPlugin.configure({\n options: {\n enableScroller: true,\n onDropFiles: ({ dragItem, editor, target }) => {\n editor\n .getTransforms(ImagePlugin)\n .insertImageFromFiles(dragItem.files, {\n at: target,\n nextBlock: false,\n });\n },\n },\n }),\n EmojiPlugin,\n exitBreakPlugin,\n NodeIdPlugin,\n NormalizeTypesPlugin.configure({\n options: {\n rules: [{ path: [0], strictType: HEADING_KEYS.h1 }],\n },\n }),\n resetBlockTypePlugin,\n SelectOnBackspacePlugin.configure({\n options: {\n query: {\n allow: [ImagePlugin.key, HorizontalRulePlugin.key],\n },\n },\n }),\n DeletePlugin,\n SingleLinePlugin,\n softBreakPlugin,\n tabbablePlugin,\n TrailingBlockPlugin.configure({\n options: { type: ParagraphPlugin.key },\n }),\n DragOverCursorPlugin,\n\n // Collaboration\n CommentsPlugin.configure({\n options: {\n comments: commentsData,\n myUserId: '1',\n users: usersData,\n },\n }),\n\n // Deserialization\n DocxPlugin,\n MarkdownPlugin.configure({ options: { indentList: true } }),\n JuicePlugin,\n\n // Testing\n PlaywrightPlugin.configure({\n enabled: process.env.NODE_ENV !== 'production',\n }),\n ],\n value: value,\n },\n []\n );\n};\n\nexport default function PlaygroundDemo({\n id,\n className,\n scrollSelector,\n}: {\n id?: ValueId;\n className?: string;\n scrollSelector?: string;\n}) {\n const containerRef = useRef(null);\n const enabled = settingsStore.use.checkedComponents();\n\n const editor = usePlaygroundEditor(\n id,\n scrollSelector ?? `blockSelection-${id}`\n );\n\n return (\n \n \n \n \n \n \n \n \n \n\n
\n \n \n\n \n \n \n \n \n \n \n\n \n \n \n \n\n \n \n \n
\n
\n
\n );\n}\n\nconst DemoIdContext = React.createContext(undefined);\n\nexport function DemoId({\n id,\n children,\n}: {\n children: React.ReactNode;\n id?: string;\n}) {\n return {children};\n}\n\nexport function useDemoId() {\n return React.useContext(DemoIdContext);\n}\n", "path": "example/playground-demo.tsx", "target": "components/playground-demo.tsx", "type": "registry:example" diff --git a/apps/www/public/r/styles/default/image-element.json b/apps/www/public/r/styles/default/image-element.json index 7944632052..5f56dfc54f 100644 --- a/apps/www/public/r/styles/default/image-element.json +++ b/apps/www/public/r/styles/default/image-element.json @@ -20,7 +20,7 @@ }, "files": [ { - "content": "'use client';\n\nimport React from 'react';\n\nimport { cn, withRef } from '@udecode/cn';\nimport { withHOC } from '@udecode/plate-common/react';\nimport { Image, ImagePlugin, useMediaState } from '@udecode/plate-media/react';\nimport { ResizableProvider, useResizableStore } from '@udecode/plate-resizable';\n\nimport { Caption, CaptionTextarea } from './caption';\nimport { MediaPopover } from './media-popover';\nimport { PlateElement } from './plate-element';\nimport {\n Resizable,\n ResizeHandle,\n mediaResizeHandleVariants,\n} from './resizable';\n\nexport const ImageElement = withHOC(\n ResizableProvider,\n withRef(\n ({ children, className, nodeProps, ...props }, ref) => {\n const { align = 'center', focused, readOnly, selected } = useMediaState();\n\n const width = useResizableStore().get.width();\n\n return (\n \n \n
\n \n \n \n \n \n\n \n \n \n
\n\n {children}\n \n
\n );\n }\n )\n);\n", + "content": "'use client';\n\nimport React from 'react';\n\nimport { cn, withRef } from '@udecode/cn';\nimport { withHOC } from '@udecode/plate-common/react';\nimport { useDraggable, useDraggableState } from '@udecode/plate-dnd';\nimport { Image, ImagePlugin, useMediaState } from '@udecode/plate-media/react';\nimport { ResizableProvider, useResizableStore } from '@udecode/plate-resizable';\n\nimport { Caption, CaptionTextarea } from './caption';\nimport { MediaPopover } from './media-popover';\nimport { PlateElement } from './plate-element';\nimport {\n Resizable,\n ResizeHandle,\n mediaResizeHandleVariants,\n} from './resizable';\n\nexport const ImageElement = withHOC(\n ResizableProvider,\n withRef(\n ({ children, className, nodeProps, ...props }, ref) => {\n const { align = 'center', focused, readOnly, selected } = useMediaState();\n\n const width = useResizableStore().get.width();\n\n const state = useDraggableState({ element: props.element });\n const { isDragging } = state;\n const { handleRef } = useDraggable(state);\n\n return (\n \n \n
\n \n \n \n \n \n\n \n {\n e.preventDefault();\n }}\n placeholder=\"Write a caption...\"\n />\n \n
\n\n {children}\n \n
\n );\n }\n )\n);\n", "path": "plate-ui/image-element.tsx", "target": "components/plate-ui/image-element.tsx", "type": "registry:ui" diff --git a/apps/www/public/r/styles/default/indent-demo.json b/apps/www/public/r/styles/default/indent-demo.json index 1abe6b9969..456b956bcf 100644 --- a/apps/www/public/r/styles/default/indent-demo.json +++ b/apps/www/public/r/styles/default/indent-demo.json @@ -4,7 +4,7 @@ }, "files": [ { - "content": "'use client';\n\nimport React, { useRef } from 'react';\n\nimport type { ValueId } from '@/config/customizer-plugins';\n\nimport { cn } from '@udecode/cn';\nimport { AIChatPlugin, CopilotPlugin } from '@udecode/plate-ai/react';\nimport { AlignPlugin } from '@udecode/plate-alignment/react';\nimport { AutoformatPlugin } from '@udecode/plate-autoformat/react';\nimport {\n BoldPlugin,\n CodePlugin,\n ItalicPlugin,\n StrikethroughPlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n UnderlinePlugin,\n} from '@udecode/plate-basic-marks/react';\nimport { BlockquotePlugin } from '@udecode/plate-block-quote/react';\nimport { SingleLinePlugin } from '@udecode/plate-break/react';\nimport { CaptionPlugin } from '@udecode/plate-caption/react';\nimport { CodeBlockPlugin } from '@udecode/plate-code-block/react';\nimport { CommentsPlugin } from '@udecode/plate-comments/react';\nimport {\n ParagraphPlugin,\n Plate,\n usePlateEditor,\n} from '@udecode/plate-common/react';\nimport { DatePlugin } from '@udecode/plate-date/react';\nimport { DndPlugin } from '@udecode/plate-dnd';\nimport { DocxPlugin } from '@udecode/plate-docx';\nimport { EmojiPlugin } from '@udecode/plate-emoji/react';\nimport { ExcalidrawPlugin } from '@udecode/plate-excalidraw/react';\nimport {\n FontBackgroundColorPlugin,\n FontColorPlugin,\n FontSizePlugin,\n} from '@udecode/plate-font/react';\nimport { HEADING_KEYS } from '@udecode/plate-heading';\nimport { HeadingPlugin, TocPlugin } from '@udecode/plate-heading/react';\nimport { HighlightPlugin } from '@udecode/plate-highlight/react';\nimport { HorizontalRulePlugin } from '@udecode/plate-horizontal-rule/react';\nimport { IndentPlugin } from '@udecode/plate-indent/react';\nimport { IndentListPlugin } from '@udecode/plate-indent-list/react';\nimport { JuicePlugin } from '@udecode/plate-juice';\nimport { KbdPlugin } from '@udecode/plate-kbd/react';\nimport { ColumnPlugin } from '@udecode/plate-layout/react';\nimport { LineHeightPlugin } from '@udecode/plate-line-height/react';\nimport { LinkPlugin } from '@udecode/plate-link/react';\nimport { ListPlugin, TodoListPlugin } from '@udecode/plate-list/react';\nimport { MarkdownPlugin } from '@udecode/plate-markdown';\nimport { ImagePlugin, MediaEmbedPlugin } from '@udecode/plate-media/react';\nimport { MentionPlugin } from '@udecode/plate-mention/react';\nimport { NodeIdPlugin } from '@udecode/plate-node-id';\nimport { NormalizeTypesPlugin } from '@udecode/plate-normalizers';\nimport { PlaywrightPlugin } from '@udecode/plate-playwright';\nimport { DeletePlugin, SelectOnBackspacePlugin } from '@udecode/plate-select';\nimport {\n BlockMenuPlugin,\n BlockSelectionPlugin,\n} from '@udecode/plate-selection/react';\nimport { SlashPlugin } from '@udecode/plate-slash-command/react';\nimport { TablePlugin } from '@udecode/plate-table/react';\nimport { TogglePlugin } from '@udecode/plate-toggle/react';\nimport { TrailingBlockPlugin } from '@udecode/plate-trailing-block';\nimport Prism from 'prismjs';\n\nimport { CheckPlugin } from '@/components/context/check-plugin';\nimport { settingsStore } from '@/components/context/settings-store';\nimport { aiPlugins } from '@/lib/plate/demo/plugins/ai-plugins';\nimport { getAutoformatOptions } from '@/lib/plate/demo/plugins/autoformatOptions';\nimport { copilotPlugins } from '@/lib/plate/demo/plugins/copilot-plugins';\nimport { createPlateUI } from '@/plate/create-plate-ui';\nimport { editableProps } from '@/plate/demo/editableProps';\nimport { isEnabled } from '@/plate/demo/is-enabled';\nimport { DragOverCursorPlugin } from '@/plate/demo/plugins/DragOverCursorPlugin';\nimport { exitBreakPlugin } from '@/plate/demo/plugins/exitBreakPlugin';\nimport { resetBlockTypePlugin } from '@/plate/demo/plugins/resetBlockTypePlugin';\nimport { softBreakPlugin } from '@/plate/demo/plugins/softBreakPlugin';\nimport { tabbablePlugin } from '@/plate/demo/plugins/tabbablePlugin';\nimport { commentsData, usersData } from '@/plate/demo/values/commentsValue';\nimport { usePlaygroundValue } from '@/plate/demo/values/usePlaygroundValue';\nimport { BlockContextMenu } from '@/components/plate-ui/block-context-menu';\nimport { CommentsPopover } from '@/components/plate-ui/comments-popover';\nimport {\n CursorOverlay,\n SelectionOverlayPlugin,\n} from '@/components/plate-ui/cursor-overlay';\nimport { Editor, EditorContainer } from '@/components/plate-ui/editor';\nimport { FixedToolbar } from '@/components/plate-ui/fixed-toolbar';\nimport { FixedToolbarButtons } from '@/components/plate-ui/fixed-toolbar-buttons';\nimport { FloatingToolbar } from '@/components/plate-ui/floating-toolbar';\nimport { FloatingToolbarButtons } from '@/components/plate-ui/floating-toolbar-buttons';\nimport { ImagePreview } from '@/components/plate-ui/image-preview';\nimport {\n FireLiComponent,\n FireMarker,\n} from '@/components/plate-ui/indent-fire-marker';\nimport {\n TodoLi,\n TodoMarker,\n} from '@/components/plate-ui/indent-todo-marker';\nimport { LinkFloatingToolbar } from '@/components/plate-ui/link-floating-toolbar';\n\nimport { usePlaygroundEnabled } from './usePlaygroundEnabled';\n\nexport const usePlaygroundEditor = (id: any = '', scrollSelector?: string) => {\n const enabledPlugins = settingsStore.use.checkedPlugins();\n const overridePlugins = usePlaygroundEnabled(id);\n const autoformatOptions = getAutoformatOptions(id, enabledPlugins);\n\n const value = usePlaygroundValue(id);\n const key = settingsStore.use.version();\n const editorId = id || 'playground-' + key;\n\n return usePlateEditor(\n {\n id: editorId,\n override: {\n components: createPlateUI({\n draggable: isEnabled('dnd', id),\n placeholder: isEnabled('placeholder', id),\n }),\n plugins: overridePlugins,\n },\n plugins: [\n // AI\n ...(id === 'ai' || enabledPlugins[AIChatPlugin.key] ? aiPlugins : []),\n ...(id === 'copilot' || enabledPlugins[CopilotPlugin.key]\n ? copilotPlugins\n : []),\n // Nodes\n HeadingPlugin,\n TocPlugin.configure({\n options: {\n scrollContainerSelector: `#${scrollSelector}`,\n topOffset: 80,\n },\n }),\n BlockquotePlugin,\n CodeBlockPlugin.configure({\n options: {\n prism: Prism,\n },\n }),\n HorizontalRulePlugin,\n LinkPlugin.extend({\n render: { afterEditable: () => },\n }),\n ...(id === 'list' ? [ListPlugin] : []),\n ImagePlugin.extend({\n render: { afterEditable: ImagePreview },\n }),\n MediaEmbedPlugin,\n CaptionPlugin.configure({\n options: {\n plugins: [ImagePlugin, MediaEmbedPlugin],\n },\n }),\n DatePlugin,\n MentionPlugin.configure({\n options: {\n triggerPreviousCharPattern: /^$|^[\\s\"']$/,\n },\n }),\n SlashPlugin,\n TablePlugin.configure({\n options: {\n enableMerging: id === 'tableMerge',\n },\n }),\n ColumnPlugin,\n SelectionOverlayPlugin,\n\n TodoListPlugin,\n TogglePlugin,\n ExcalidrawPlugin,\n // Marks\n BoldPlugin,\n ItalicPlugin,\n UnderlinePlugin,\n StrikethroughPlugin,\n CodePlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n FontColorPlugin,\n FontBackgroundColorPlugin,\n FontSizePlugin,\n HighlightPlugin,\n KbdPlugin,\n\n // Block Style\n AlignPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n MediaEmbedPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n ImagePlugin.key,\n HEADING_KEYS.h6,\n ],\n },\n }),\n IndentPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n }),\n IndentListPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n options: {\n listStyleTypes: {\n fire: {\n liComponent: FireLiComponent,\n markerComponent: FireMarker,\n type: 'fire',\n },\n todo: {\n liComponent: TodoLi,\n markerComponent: TodoMarker,\n type: 'todo',\n },\n },\n },\n }),\n LineHeightPlugin.extend({\n inject: {\n nodeProps: {\n defaultNodeValue: 1.5,\n validNodeValues: [1, 1.2, 1.5, 2, 3],\n },\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n ],\n },\n }),\n\n // Functionality\n AutoformatPlugin.configure({\n options: autoformatOptions,\n }),\n BlockSelectionPlugin.configure({\n options: {\n areaOptions: {\n behaviour: {\n scrolling: {\n speedDivider: 1.5,\n },\n startThreshold: 10,\n },\n boundaries: `#${scrollSelector}`,\n container: `#${scrollSelector}`,\n selectables: [`#${scrollSelector} .slate-selectable`],\n selectionAreaClass: 'slate-selection-area',\n },\n enableContextMenu: true,\n },\n }),\n BlockMenuPlugin.configure({\n render: { aboveEditable: BlockContextMenu },\n }),\n DndPlugin.configure({ options: { enableScroller: true } }),\n EmojiPlugin,\n exitBreakPlugin,\n NodeIdPlugin,\n NormalizeTypesPlugin.configure({\n options: {\n rules: [{ path: [0], strictType: HEADING_KEYS.h1 }],\n },\n }),\n resetBlockTypePlugin,\n SelectOnBackspacePlugin.configure({\n options: {\n query: {\n allow: [ImagePlugin.key, HorizontalRulePlugin.key],\n },\n },\n }),\n DeletePlugin,\n SingleLinePlugin,\n softBreakPlugin,\n tabbablePlugin,\n TrailingBlockPlugin.configure({\n options: { type: ParagraphPlugin.key },\n }),\n DragOverCursorPlugin,\n\n // Collaboration\n CommentsPlugin.configure({\n options: {\n comments: commentsData,\n myUserId: '1',\n users: usersData,\n },\n }),\n\n // Deserialization\n DocxPlugin,\n MarkdownPlugin.configure({ options: { indentList: true } }),\n JuicePlugin,\n\n // Testing\n PlaywrightPlugin.configure({\n enabled: process.env.NODE_ENV !== 'production',\n }),\n ],\n value: value,\n },\n []\n );\n};\n\nexport default function PlaygroundDemo({\n id,\n className,\n scrollSelector,\n}: {\n id?: ValueId;\n className?: string;\n scrollSelector?: string;\n}) {\n const containerRef = useRef(null);\n const enabled = settingsStore.use.checkedComponents();\n\n const editor = usePlaygroundEditor(\n id,\n scrollSelector ?? `blockSelection-${id}`\n );\n\n return (\n \n \n \n \n \n \n \n \n \n\n
\n \n \n\n \n \n \n \n \n \n \n\n \n \n \n \n\n \n \n \n
\n
\n
\n );\n}\n\nconst DemoIdContext = React.createContext(undefined);\n\nexport function DemoId({\n id,\n children,\n}: {\n children: React.ReactNode;\n id?: string;\n}) {\n return {children};\n}\n\nexport function useDemoId() {\n return React.useContext(DemoIdContext);\n}\n", + "content": "'use client';\n\nimport React, { useRef } from 'react';\n\nimport type { ValueId } from '@/config/customizer-plugins';\n\nimport { cn } from '@udecode/cn';\nimport { AIChatPlugin, CopilotPlugin } from '@udecode/plate-ai/react';\nimport { AlignPlugin } from '@udecode/plate-alignment/react';\nimport { AutoformatPlugin } from '@udecode/plate-autoformat/react';\nimport {\n BoldPlugin,\n CodePlugin,\n ItalicPlugin,\n StrikethroughPlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n UnderlinePlugin,\n} from '@udecode/plate-basic-marks/react';\nimport { BlockquotePlugin } from '@udecode/plate-block-quote/react';\nimport { SingleLinePlugin } from '@udecode/plate-break/react';\nimport { CaptionPlugin } from '@udecode/plate-caption/react';\nimport { CodeBlockPlugin } from '@udecode/plate-code-block/react';\nimport { CommentsPlugin } from '@udecode/plate-comments/react';\nimport {\n ParagraphPlugin,\n Plate,\n usePlateEditor,\n} from '@udecode/plate-common/react';\nimport { DatePlugin } from '@udecode/plate-date/react';\nimport { DndPlugin } from '@udecode/plate-dnd';\nimport { DocxPlugin } from '@udecode/plate-docx';\nimport { EmojiPlugin } from '@udecode/plate-emoji/react';\nimport { ExcalidrawPlugin } from '@udecode/plate-excalidraw/react';\nimport {\n FontBackgroundColorPlugin,\n FontColorPlugin,\n FontSizePlugin,\n} from '@udecode/plate-font/react';\nimport { HEADING_KEYS } from '@udecode/plate-heading';\nimport { HeadingPlugin, TocPlugin } from '@udecode/plate-heading/react';\nimport { HighlightPlugin } from '@udecode/plate-highlight/react';\nimport { HorizontalRulePlugin } from '@udecode/plate-horizontal-rule/react';\nimport { IndentPlugin } from '@udecode/plate-indent/react';\nimport { IndentListPlugin } from '@udecode/plate-indent-list/react';\nimport { JuicePlugin } from '@udecode/plate-juice';\nimport { KbdPlugin } from '@udecode/plate-kbd/react';\nimport { ColumnPlugin } from '@udecode/plate-layout/react';\nimport { LineHeightPlugin } from '@udecode/plate-line-height/react';\nimport { LinkPlugin } from '@udecode/plate-link/react';\nimport { ListPlugin, TodoListPlugin } from '@udecode/plate-list/react';\nimport { MarkdownPlugin } from '@udecode/plate-markdown';\nimport { ImagePlugin, MediaEmbedPlugin } from '@udecode/plate-media/react';\nimport { MentionPlugin } from '@udecode/plate-mention/react';\nimport { NodeIdPlugin } from '@udecode/plate-node-id';\nimport { NormalizeTypesPlugin } from '@udecode/plate-normalizers';\nimport { PlaywrightPlugin } from '@udecode/plate-playwright';\nimport { DeletePlugin, SelectOnBackspacePlugin } from '@udecode/plate-select';\nimport {\n BlockMenuPlugin,\n BlockSelectionPlugin,\n} from '@udecode/plate-selection/react';\nimport { SlashPlugin } from '@udecode/plate-slash-command/react';\nimport { TablePlugin } from '@udecode/plate-table/react';\nimport { TogglePlugin } from '@udecode/plate-toggle/react';\nimport { TrailingBlockPlugin } from '@udecode/plate-trailing-block';\nimport Prism from 'prismjs';\n\nimport { CheckPlugin } from '@/components/context/check-plugin';\nimport { settingsStore } from '@/components/context/settings-store';\nimport { aiPlugins } from '@/lib/plate/demo/plugins/ai-plugins';\nimport { getAutoformatOptions } from '@/lib/plate/demo/plugins/autoformatOptions';\nimport { copilotPlugins } from '@/lib/plate/demo/plugins/copilot-plugins';\nimport { createPlateUI } from '@/plate/create-plate-ui';\nimport { editableProps } from '@/plate/demo/editableProps';\nimport { isEnabled } from '@/plate/demo/is-enabled';\nimport { DragOverCursorPlugin } from '@/plate/demo/plugins/DragOverCursorPlugin';\nimport { exitBreakPlugin } from '@/plate/demo/plugins/exitBreakPlugin';\nimport { resetBlockTypePlugin } from '@/plate/demo/plugins/resetBlockTypePlugin';\nimport { softBreakPlugin } from '@/plate/demo/plugins/softBreakPlugin';\nimport { tabbablePlugin } from '@/plate/demo/plugins/tabbablePlugin';\nimport { commentsData, usersData } from '@/plate/demo/values/commentsValue';\nimport { usePlaygroundValue } from '@/plate/demo/values/usePlaygroundValue';\nimport { BlockContextMenu } from '@/components/plate-ui/block-context-menu';\nimport { CommentsPopover } from '@/components/plate-ui/comments-popover';\nimport {\n CursorOverlay,\n SelectionOverlayPlugin,\n} from '@/components/plate-ui/cursor-overlay';\nimport { Editor, EditorContainer } from '@/components/plate-ui/editor';\nimport { FixedToolbar } from '@/components/plate-ui/fixed-toolbar';\nimport { FixedToolbarButtons } from '@/components/plate-ui/fixed-toolbar-buttons';\nimport { FloatingToolbar } from '@/components/plate-ui/floating-toolbar';\nimport { FloatingToolbarButtons } from '@/components/plate-ui/floating-toolbar-buttons';\nimport { ImagePreview } from '@/components/plate-ui/image-preview';\nimport {\n FireLiComponent,\n FireMarker,\n} from '@/components/plate-ui/indent-fire-marker';\nimport {\n TodoLi,\n TodoMarker,\n} from '@/components/plate-ui/indent-todo-marker';\nimport { LinkFloatingToolbar } from '@/components/plate-ui/link-floating-toolbar';\n\nimport { usePlaygroundEnabled } from './usePlaygroundEnabled';\n\nexport const usePlaygroundEditor = (id: any = '', scrollSelector?: string) => {\n const enabledPlugins = settingsStore.use.checkedPlugins();\n const overridePlugins = usePlaygroundEnabled(id);\n const autoformatOptions = getAutoformatOptions(id, enabledPlugins);\n\n const value = usePlaygroundValue(id);\n const key = settingsStore.use.version();\n const editorId = id || 'playground-' + key;\n\n return usePlateEditor(\n {\n id: editorId,\n override: {\n components: createPlateUI({\n draggable: isEnabled('dnd', id),\n placeholder: isEnabled('placeholder', id),\n }),\n plugins: overridePlugins,\n },\n plugins: [\n // AI\n ...(id === 'ai' || enabledPlugins[AIChatPlugin.key] ? aiPlugins : []),\n ...(id === 'copilot' || enabledPlugins[CopilotPlugin.key]\n ? copilotPlugins\n : []),\n // Nodes\n HeadingPlugin,\n TocPlugin.configure({\n options: {\n scrollContainerSelector: `#${scrollSelector}`,\n topOffset: 80,\n },\n }),\n BlockquotePlugin,\n CodeBlockPlugin.configure({\n options: {\n prism: Prism,\n },\n }),\n HorizontalRulePlugin,\n LinkPlugin.extend({\n render: { afterEditable: () => },\n }),\n ...(id === 'list' ? [ListPlugin] : []),\n ImagePlugin.extend({\n options: {\n disableUploadInsert: true,\n },\n render: { afterEditable: ImagePreview },\n }),\n MediaEmbedPlugin,\n CaptionPlugin.configure({\n options: {\n plugins: [ImagePlugin, MediaEmbedPlugin],\n },\n }),\n DatePlugin,\n MentionPlugin.configure({\n options: {\n triggerPreviousCharPattern: /^$|^[\\s\"']$/,\n },\n }),\n SlashPlugin,\n TablePlugin.configure({\n options: {\n enableMerging: id === 'tableMerge',\n },\n }),\n ColumnPlugin,\n SelectionOverlayPlugin,\n\n TodoListPlugin,\n TogglePlugin,\n ExcalidrawPlugin,\n // Marks\n BoldPlugin,\n ItalicPlugin,\n UnderlinePlugin,\n StrikethroughPlugin,\n CodePlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n FontColorPlugin,\n FontBackgroundColorPlugin,\n FontSizePlugin,\n HighlightPlugin,\n KbdPlugin,\n\n // Block Style\n AlignPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n MediaEmbedPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n ImagePlugin.key,\n HEADING_KEYS.h6,\n ],\n },\n }),\n IndentPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n }),\n IndentListPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n options: {\n listStyleTypes: {\n fire: {\n liComponent: FireLiComponent,\n markerComponent: FireMarker,\n type: 'fire',\n },\n todo: {\n liComponent: TodoLi,\n markerComponent: TodoMarker,\n type: 'todo',\n },\n },\n },\n }),\n LineHeightPlugin.extend({\n inject: {\n nodeProps: {\n defaultNodeValue: 1.5,\n validNodeValues: [1, 1.2, 1.5, 2, 3],\n },\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n ],\n },\n }),\n\n // Functionality\n AutoformatPlugin.configure({\n options: autoformatOptions,\n }),\n BlockSelectionPlugin.configure({\n options: {\n areaOptions: {\n behaviour: {\n scrolling: {\n speedDivider: 1.5,\n },\n startThreshold: 10,\n },\n boundaries: `#${scrollSelector}`,\n container: `#${scrollSelector}`,\n selectables: [`#${scrollSelector} .slate-selectable`],\n selectionAreaClass: 'slate-selection-area',\n },\n enableContextMenu: true,\n },\n }),\n BlockMenuPlugin.configure({\n render: { aboveEditable: BlockContextMenu },\n }),\n DndPlugin.configure({\n options: {\n enableScroller: true,\n onDropFiles: ({ dragItem, editor, target }) => {\n editor\n .getTransforms(ImagePlugin)\n .insertImageFromFiles(dragItem.files, {\n at: target,\n nextBlock: false,\n });\n },\n },\n }),\n EmojiPlugin,\n exitBreakPlugin,\n NodeIdPlugin,\n NormalizeTypesPlugin.configure({\n options: {\n rules: [{ path: [0], strictType: HEADING_KEYS.h1 }],\n },\n }),\n resetBlockTypePlugin,\n SelectOnBackspacePlugin.configure({\n options: {\n query: {\n allow: [ImagePlugin.key, HorizontalRulePlugin.key],\n },\n },\n }),\n DeletePlugin,\n SingleLinePlugin,\n softBreakPlugin,\n tabbablePlugin,\n TrailingBlockPlugin.configure({\n options: { type: ParagraphPlugin.key },\n }),\n DragOverCursorPlugin,\n\n // Collaboration\n CommentsPlugin.configure({\n options: {\n comments: commentsData,\n myUserId: '1',\n users: usersData,\n },\n }),\n\n // Deserialization\n DocxPlugin,\n MarkdownPlugin.configure({ options: { indentList: true } }),\n JuicePlugin,\n\n // Testing\n PlaywrightPlugin.configure({\n enabled: process.env.NODE_ENV !== 'production',\n }),\n ],\n value: value,\n },\n []\n );\n};\n\nexport default function PlaygroundDemo({\n id,\n className,\n scrollSelector,\n}: {\n id?: ValueId;\n className?: string;\n scrollSelector?: string;\n}) {\n const containerRef = useRef(null);\n const enabled = settingsStore.use.checkedComponents();\n\n const editor = usePlaygroundEditor(\n id,\n scrollSelector ?? `blockSelection-${id}`\n );\n\n return (\n \n \n \n \n \n \n \n \n \n\n
\n \n \n\n \n \n \n \n \n \n \n\n \n \n \n \n\n \n \n \n
\n
\n
\n );\n}\n\nconst DemoIdContext = React.createContext(undefined);\n\nexport function DemoId({\n id,\n children,\n}: {\n children: React.ReactNode;\n id?: string;\n}) {\n return {children};\n}\n\nexport function useDemoId() {\n return React.useContext(DemoIdContext);\n}\n", "path": "example/playground-demo.tsx", "target": "components/playground-demo.tsx", "type": "registry:example" diff --git a/apps/www/public/r/styles/default/kbd-demo.json b/apps/www/public/r/styles/default/kbd-demo.json index 32d062e655..42fe130014 100644 --- a/apps/www/public/r/styles/default/kbd-demo.json +++ b/apps/www/public/r/styles/default/kbd-demo.json @@ -4,7 +4,7 @@ }, "files": [ { - "content": "'use client';\n\nimport React, { useRef } from 'react';\n\nimport type { ValueId } from '@/config/customizer-plugins';\n\nimport { cn } from '@udecode/cn';\nimport { AIChatPlugin, CopilotPlugin } from '@udecode/plate-ai/react';\nimport { AlignPlugin } from '@udecode/plate-alignment/react';\nimport { AutoformatPlugin } from '@udecode/plate-autoformat/react';\nimport {\n BoldPlugin,\n CodePlugin,\n ItalicPlugin,\n StrikethroughPlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n UnderlinePlugin,\n} from '@udecode/plate-basic-marks/react';\nimport { BlockquotePlugin } from '@udecode/plate-block-quote/react';\nimport { SingleLinePlugin } from '@udecode/plate-break/react';\nimport { CaptionPlugin } from '@udecode/plate-caption/react';\nimport { CodeBlockPlugin } from '@udecode/plate-code-block/react';\nimport { CommentsPlugin } from '@udecode/plate-comments/react';\nimport {\n ParagraphPlugin,\n Plate,\n usePlateEditor,\n} from '@udecode/plate-common/react';\nimport { DatePlugin } from '@udecode/plate-date/react';\nimport { DndPlugin } from '@udecode/plate-dnd';\nimport { DocxPlugin } from '@udecode/plate-docx';\nimport { EmojiPlugin } from '@udecode/plate-emoji/react';\nimport { ExcalidrawPlugin } from '@udecode/plate-excalidraw/react';\nimport {\n FontBackgroundColorPlugin,\n FontColorPlugin,\n FontSizePlugin,\n} from '@udecode/plate-font/react';\nimport { HEADING_KEYS } from '@udecode/plate-heading';\nimport { HeadingPlugin, TocPlugin } from '@udecode/plate-heading/react';\nimport { HighlightPlugin } from '@udecode/plate-highlight/react';\nimport { HorizontalRulePlugin } from '@udecode/plate-horizontal-rule/react';\nimport { IndentPlugin } from '@udecode/plate-indent/react';\nimport { IndentListPlugin } from '@udecode/plate-indent-list/react';\nimport { JuicePlugin } from '@udecode/plate-juice';\nimport { KbdPlugin } from '@udecode/plate-kbd/react';\nimport { ColumnPlugin } from '@udecode/plate-layout/react';\nimport { LineHeightPlugin } from '@udecode/plate-line-height/react';\nimport { LinkPlugin } from '@udecode/plate-link/react';\nimport { ListPlugin, TodoListPlugin } from '@udecode/plate-list/react';\nimport { MarkdownPlugin } from '@udecode/plate-markdown';\nimport { ImagePlugin, MediaEmbedPlugin } from '@udecode/plate-media/react';\nimport { MentionPlugin } from '@udecode/plate-mention/react';\nimport { NodeIdPlugin } from '@udecode/plate-node-id';\nimport { NormalizeTypesPlugin } from '@udecode/plate-normalizers';\nimport { PlaywrightPlugin } from '@udecode/plate-playwright';\nimport { DeletePlugin, SelectOnBackspacePlugin } from '@udecode/plate-select';\nimport {\n BlockMenuPlugin,\n BlockSelectionPlugin,\n} from '@udecode/plate-selection/react';\nimport { SlashPlugin } from '@udecode/plate-slash-command/react';\nimport { TablePlugin } from '@udecode/plate-table/react';\nimport { TogglePlugin } from '@udecode/plate-toggle/react';\nimport { TrailingBlockPlugin } from '@udecode/plate-trailing-block';\nimport Prism from 'prismjs';\n\nimport { CheckPlugin } from '@/components/context/check-plugin';\nimport { settingsStore } from '@/components/context/settings-store';\nimport { aiPlugins } from '@/lib/plate/demo/plugins/ai-plugins';\nimport { getAutoformatOptions } from '@/lib/plate/demo/plugins/autoformatOptions';\nimport { copilotPlugins } from '@/lib/plate/demo/plugins/copilot-plugins';\nimport { createPlateUI } from '@/plate/create-plate-ui';\nimport { editableProps } from '@/plate/demo/editableProps';\nimport { isEnabled } from '@/plate/demo/is-enabled';\nimport { DragOverCursorPlugin } from '@/plate/demo/plugins/DragOverCursorPlugin';\nimport { exitBreakPlugin } from '@/plate/demo/plugins/exitBreakPlugin';\nimport { resetBlockTypePlugin } from '@/plate/demo/plugins/resetBlockTypePlugin';\nimport { softBreakPlugin } from '@/plate/demo/plugins/softBreakPlugin';\nimport { tabbablePlugin } from '@/plate/demo/plugins/tabbablePlugin';\nimport { commentsData, usersData } from '@/plate/demo/values/commentsValue';\nimport { usePlaygroundValue } from '@/plate/demo/values/usePlaygroundValue';\nimport { BlockContextMenu } from '@/components/plate-ui/block-context-menu';\nimport { CommentsPopover } from '@/components/plate-ui/comments-popover';\nimport {\n CursorOverlay,\n SelectionOverlayPlugin,\n} from '@/components/plate-ui/cursor-overlay';\nimport { Editor, EditorContainer } from '@/components/plate-ui/editor';\nimport { FixedToolbar } from '@/components/plate-ui/fixed-toolbar';\nimport { FixedToolbarButtons } from '@/components/plate-ui/fixed-toolbar-buttons';\nimport { FloatingToolbar } from '@/components/plate-ui/floating-toolbar';\nimport { FloatingToolbarButtons } from '@/components/plate-ui/floating-toolbar-buttons';\nimport { ImagePreview } from '@/components/plate-ui/image-preview';\nimport {\n FireLiComponent,\n FireMarker,\n} from '@/components/plate-ui/indent-fire-marker';\nimport {\n TodoLi,\n TodoMarker,\n} from '@/components/plate-ui/indent-todo-marker';\nimport { LinkFloatingToolbar } from '@/components/plate-ui/link-floating-toolbar';\n\nimport { usePlaygroundEnabled } from './usePlaygroundEnabled';\n\nexport const usePlaygroundEditor = (id: any = '', scrollSelector?: string) => {\n const enabledPlugins = settingsStore.use.checkedPlugins();\n const overridePlugins = usePlaygroundEnabled(id);\n const autoformatOptions = getAutoformatOptions(id, enabledPlugins);\n\n const value = usePlaygroundValue(id);\n const key = settingsStore.use.version();\n const editorId = id || 'playground-' + key;\n\n return usePlateEditor(\n {\n id: editorId,\n override: {\n components: createPlateUI({\n draggable: isEnabled('dnd', id),\n placeholder: isEnabled('placeholder', id),\n }),\n plugins: overridePlugins,\n },\n plugins: [\n // AI\n ...(id === 'ai' || enabledPlugins[AIChatPlugin.key] ? aiPlugins : []),\n ...(id === 'copilot' || enabledPlugins[CopilotPlugin.key]\n ? copilotPlugins\n : []),\n // Nodes\n HeadingPlugin,\n TocPlugin.configure({\n options: {\n scrollContainerSelector: `#${scrollSelector}`,\n topOffset: 80,\n },\n }),\n BlockquotePlugin,\n CodeBlockPlugin.configure({\n options: {\n prism: Prism,\n },\n }),\n HorizontalRulePlugin,\n LinkPlugin.extend({\n render: { afterEditable: () => },\n }),\n ...(id === 'list' ? [ListPlugin] : []),\n ImagePlugin.extend({\n render: { afterEditable: ImagePreview },\n }),\n MediaEmbedPlugin,\n CaptionPlugin.configure({\n options: {\n plugins: [ImagePlugin, MediaEmbedPlugin],\n },\n }),\n DatePlugin,\n MentionPlugin.configure({\n options: {\n triggerPreviousCharPattern: /^$|^[\\s\"']$/,\n },\n }),\n SlashPlugin,\n TablePlugin.configure({\n options: {\n enableMerging: id === 'tableMerge',\n },\n }),\n ColumnPlugin,\n SelectionOverlayPlugin,\n\n TodoListPlugin,\n TogglePlugin,\n ExcalidrawPlugin,\n // Marks\n BoldPlugin,\n ItalicPlugin,\n UnderlinePlugin,\n StrikethroughPlugin,\n CodePlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n FontColorPlugin,\n FontBackgroundColorPlugin,\n FontSizePlugin,\n HighlightPlugin,\n KbdPlugin,\n\n // Block Style\n AlignPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n MediaEmbedPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n ImagePlugin.key,\n HEADING_KEYS.h6,\n ],\n },\n }),\n IndentPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n }),\n IndentListPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n options: {\n listStyleTypes: {\n fire: {\n liComponent: FireLiComponent,\n markerComponent: FireMarker,\n type: 'fire',\n },\n todo: {\n liComponent: TodoLi,\n markerComponent: TodoMarker,\n type: 'todo',\n },\n },\n },\n }),\n LineHeightPlugin.extend({\n inject: {\n nodeProps: {\n defaultNodeValue: 1.5,\n validNodeValues: [1, 1.2, 1.5, 2, 3],\n },\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n ],\n },\n }),\n\n // Functionality\n AutoformatPlugin.configure({\n options: autoformatOptions,\n }),\n BlockSelectionPlugin.configure({\n options: {\n areaOptions: {\n behaviour: {\n scrolling: {\n speedDivider: 1.5,\n },\n startThreshold: 10,\n },\n boundaries: `#${scrollSelector}`,\n container: `#${scrollSelector}`,\n selectables: [`#${scrollSelector} .slate-selectable`],\n selectionAreaClass: 'slate-selection-area',\n },\n enableContextMenu: true,\n },\n }),\n BlockMenuPlugin.configure({\n render: { aboveEditable: BlockContextMenu },\n }),\n DndPlugin.configure({ options: { enableScroller: true } }),\n EmojiPlugin,\n exitBreakPlugin,\n NodeIdPlugin,\n NormalizeTypesPlugin.configure({\n options: {\n rules: [{ path: [0], strictType: HEADING_KEYS.h1 }],\n },\n }),\n resetBlockTypePlugin,\n SelectOnBackspacePlugin.configure({\n options: {\n query: {\n allow: [ImagePlugin.key, HorizontalRulePlugin.key],\n },\n },\n }),\n DeletePlugin,\n SingleLinePlugin,\n softBreakPlugin,\n tabbablePlugin,\n TrailingBlockPlugin.configure({\n options: { type: ParagraphPlugin.key },\n }),\n DragOverCursorPlugin,\n\n // Collaboration\n CommentsPlugin.configure({\n options: {\n comments: commentsData,\n myUserId: '1',\n users: usersData,\n },\n }),\n\n // Deserialization\n DocxPlugin,\n MarkdownPlugin.configure({ options: { indentList: true } }),\n JuicePlugin,\n\n // Testing\n PlaywrightPlugin.configure({\n enabled: process.env.NODE_ENV !== 'production',\n }),\n ],\n value: value,\n },\n []\n );\n};\n\nexport default function PlaygroundDemo({\n id,\n className,\n scrollSelector,\n}: {\n id?: ValueId;\n className?: string;\n scrollSelector?: string;\n}) {\n const containerRef = useRef(null);\n const enabled = settingsStore.use.checkedComponents();\n\n const editor = usePlaygroundEditor(\n id,\n scrollSelector ?? `blockSelection-${id}`\n );\n\n return (\n \n \n \n \n \n \n \n \n \n\n
\n \n \n\n \n \n \n \n \n \n \n\n \n \n \n \n\n \n \n \n
\n
\n
\n );\n}\n\nconst DemoIdContext = React.createContext(undefined);\n\nexport function DemoId({\n id,\n children,\n}: {\n children: React.ReactNode;\n id?: string;\n}) {\n return {children};\n}\n\nexport function useDemoId() {\n return React.useContext(DemoIdContext);\n}\n", + "content": "'use client';\n\nimport React, { useRef } from 'react';\n\nimport type { ValueId } from '@/config/customizer-plugins';\n\nimport { cn } from '@udecode/cn';\nimport { AIChatPlugin, CopilotPlugin } from '@udecode/plate-ai/react';\nimport { AlignPlugin } from '@udecode/plate-alignment/react';\nimport { AutoformatPlugin } from '@udecode/plate-autoformat/react';\nimport {\n BoldPlugin,\n CodePlugin,\n ItalicPlugin,\n StrikethroughPlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n UnderlinePlugin,\n} from '@udecode/plate-basic-marks/react';\nimport { BlockquotePlugin } from '@udecode/plate-block-quote/react';\nimport { SingleLinePlugin } from '@udecode/plate-break/react';\nimport { CaptionPlugin } from '@udecode/plate-caption/react';\nimport { CodeBlockPlugin } from '@udecode/plate-code-block/react';\nimport { CommentsPlugin } from '@udecode/plate-comments/react';\nimport {\n ParagraphPlugin,\n Plate,\n usePlateEditor,\n} from '@udecode/plate-common/react';\nimport { DatePlugin } from '@udecode/plate-date/react';\nimport { DndPlugin } from '@udecode/plate-dnd';\nimport { DocxPlugin } from '@udecode/plate-docx';\nimport { EmojiPlugin } from '@udecode/plate-emoji/react';\nimport { ExcalidrawPlugin } from '@udecode/plate-excalidraw/react';\nimport {\n FontBackgroundColorPlugin,\n FontColorPlugin,\n FontSizePlugin,\n} from '@udecode/plate-font/react';\nimport { HEADING_KEYS } from '@udecode/plate-heading';\nimport { HeadingPlugin, TocPlugin } from '@udecode/plate-heading/react';\nimport { HighlightPlugin } from '@udecode/plate-highlight/react';\nimport { HorizontalRulePlugin } from '@udecode/plate-horizontal-rule/react';\nimport { IndentPlugin } from '@udecode/plate-indent/react';\nimport { IndentListPlugin } from '@udecode/plate-indent-list/react';\nimport { JuicePlugin } from '@udecode/plate-juice';\nimport { KbdPlugin } from '@udecode/plate-kbd/react';\nimport { ColumnPlugin } from '@udecode/plate-layout/react';\nimport { LineHeightPlugin } from '@udecode/plate-line-height/react';\nimport { LinkPlugin } from '@udecode/plate-link/react';\nimport { ListPlugin, TodoListPlugin } from '@udecode/plate-list/react';\nimport { MarkdownPlugin } from '@udecode/plate-markdown';\nimport { ImagePlugin, MediaEmbedPlugin } from '@udecode/plate-media/react';\nimport { MentionPlugin } from '@udecode/plate-mention/react';\nimport { NodeIdPlugin } from '@udecode/plate-node-id';\nimport { NormalizeTypesPlugin } from '@udecode/plate-normalizers';\nimport { PlaywrightPlugin } from '@udecode/plate-playwright';\nimport { DeletePlugin, SelectOnBackspacePlugin } from '@udecode/plate-select';\nimport {\n BlockMenuPlugin,\n BlockSelectionPlugin,\n} from '@udecode/plate-selection/react';\nimport { SlashPlugin } from '@udecode/plate-slash-command/react';\nimport { TablePlugin } from '@udecode/plate-table/react';\nimport { TogglePlugin } from '@udecode/plate-toggle/react';\nimport { TrailingBlockPlugin } from '@udecode/plate-trailing-block';\nimport Prism from 'prismjs';\n\nimport { CheckPlugin } from '@/components/context/check-plugin';\nimport { settingsStore } from '@/components/context/settings-store';\nimport { aiPlugins } from '@/lib/plate/demo/plugins/ai-plugins';\nimport { getAutoformatOptions } from '@/lib/plate/demo/plugins/autoformatOptions';\nimport { copilotPlugins } from '@/lib/plate/demo/plugins/copilot-plugins';\nimport { createPlateUI } from '@/plate/create-plate-ui';\nimport { editableProps } from '@/plate/demo/editableProps';\nimport { isEnabled } from '@/plate/demo/is-enabled';\nimport { DragOverCursorPlugin } from '@/plate/demo/plugins/DragOverCursorPlugin';\nimport { exitBreakPlugin } from '@/plate/demo/plugins/exitBreakPlugin';\nimport { resetBlockTypePlugin } from '@/plate/demo/plugins/resetBlockTypePlugin';\nimport { softBreakPlugin } from '@/plate/demo/plugins/softBreakPlugin';\nimport { tabbablePlugin } from '@/plate/demo/plugins/tabbablePlugin';\nimport { commentsData, usersData } from '@/plate/demo/values/commentsValue';\nimport { usePlaygroundValue } from '@/plate/demo/values/usePlaygroundValue';\nimport { BlockContextMenu } from '@/components/plate-ui/block-context-menu';\nimport { CommentsPopover } from '@/components/plate-ui/comments-popover';\nimport {\n CursorOverlay,\n SelectionOverlayPlugin,\n} from '@/components/plate-ui/cursor-overlay';\nimport { Editor, EditorContainer } from '@/components/plate-ui/editor';\nimport { FixedToolbar } from '@/components/plate-ui/fixed-toolbar';\nimport { FixedToolbarButtons } from '@/components/plate-ui/fixed-toolbar-buttons';\nimport { FloatingToolbar } from '@/components/plate-ui/floating-toolbar';\nimport { FloatingToolbarButtons } from '@/components/plate-ui/floating-toolbar-buttons';\nimport { ImagePreview } from '@/components/plate-ui/image-preview';\nimport {\n FireLiComponent,\n FireMarker,\n} from '@/components/plate-ui/indent-fire-marker';\nimport {\n TodoLi,\n TodoMarker,\n} from '@/components/plate-ui/indent-todo-marker';\nimport { LinkFloatingToolbar } from '@/components/plate-ui/link-floating-toolbar';\n\nimport { usePlaygroundEnabled } from './usePlaygroundEnabled';\n\nexport const usePlaygroundEditor = (id: any = '', scrollSelector?: string) => {\n const enabledPlugins = settingsStore.use.checkedPlugins();\n const overridePlugins = usePlaygroundEnabled(id);\n const autoformatOptions = getAutoformatOptions(id, enabledPlugins);\n\n const value = usePlaygroundValue(id);\n const key = settingsStore.use.version();\n const editorId = id || 'playground-' + key;\n\n return usePlateEditor(\n {\n id: editorId,\n override: {\n components: createPlateUI({\n draggable: isEnabled('dnd', id),\n placeholder: isEnabled('placeholder', id),\n }),\n plugins: overridePlugins,\n },\n plugins: [\n // AI\n ...(id === 'ai' || enabledPlugins[AIChatPlugin.key] ? aiPlugins : []),\n ...(id === 'copilot' || enabledPlugins[CopilotPlugin.key]\n ? copilotPlugins\n : []),\n // Nodes\n HeadingPlugin,\n TocPlugin.configure({\n options: {\n scrollContainerSelector: `#${scrollSelector}`,\n topOffset: 80,\n },\n }),\n BlockquotePlugin,\n CodeBlockPlugin.configure({\n options: {\n prism: Prism,\n },\n }),\n HorizontalRulePlugin,\n LinkPlugin.extend({\n render: { afterEditable: () => },\n }),\n ...(id === 'list' ? [ListPlugin] : []),\n ImagePlugin.extend({\n options: {\n disableUploadInsert: true,\n },\n render: { afterEditable: ImagePreview },\n }),\n MediaEmbedPlugin,\n CaptionPlugin.configure({\n options: {\n plugins: [ImagePlugin, MediaEmbedPlugin],\n },\n }),\n DatePlugin,\n MentionPlugin.configure({\n options: {\n triggerPreviousCharPattern: /^$|^[\\s\"']$/,\n },\n }),\n SlashPlugin,\n TablePlugin.configure({\n options: {\n enableMerging: id === 'tableMerge',\n },\n }),\n ColumnPlugin,\n SelectionOverlayPlugin,\n\n TodoListPlugin,\n TogglePlugin,\n ExcalidrawPlugin,\n // Marks\n BoldPlugin,\n ItalicPlugin,\n UnderlinePlugin,\n StrikethroughPlugin,\n CodePlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n FontColorPlugin,\n FontBackgroundColorPlugin,\n FontSizePlugin,\n HighlightPlugin,\n KbdPlugin,\n\n // Block Style\n AlignPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n MediaEmbedPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n ImagePlugin.key,\n HEADING_KEYS.h6,\n ],\n },\n }),\n IndentPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n }),\n IndentListPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n options: {\n listStyleTypes: {\n fire: {\n liComponent: FireLiComponent,\n markerComponent: FireMarker,\n type: 'fire',\n },\n todo: {\n liComponent: TodoLi,\n markerComponent: TodoMarker,\n type: 'todo',\n },\n },\n },\n }),\n LineHeightPlugin.extend({\n inject: {\n nodeProps: {\n defaultNodeValue: 1.5,\n validNodeValues: [1, 1.2, 1.5, 2, 3],\n },\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n ],\n },\n }),\n\n // Functionality\n AutoformatPlugin.configure({\n options: autoformatOptions,\n }),\n BlockSelectionPlugin.configure({\n options: {\n areaOptions: {\n behaviour: {\n scrolling: {\n speedDivider: 1.5,\n },\n startThreshold: 10,\n },\n boundaries: `#${scrollSelector}`,\n container: `#${scrollSelector}`,\n selectables: [`#${scrollSelector} .slate-selectable`],\n selectionAreaClass: 'slate-selection-area',\n },\n enableContextMenu: true,\n },\n }),\n BlockMenuPlugin.configure({\n render: { aboveEditable: BlockContextMenu },\n }),\n DndPlugin.configure({\n options: {\n enableScroller: true,\n onDropFiles: ({ dragItem, editor, target }) => {\n editor\n .getTransforms(ImagePlugin)\n .insertImageFromFiles(dragItem.files, {\n at: target,\n nextBlock: false,\n });\n },\n },\n }),\n EmojiPlugin,\n exitBreakPlugin,\n NodeIdPlugin,\n NormalizeTypesPlugin.configure({\n options: {\n rules: [{ path: [0], strictType: HEADING_KEYS.h1 }],\n },\n }),\n resetBlockTypePlugin,\n SelectOnBackspacePlugin.configure({\n options: {\n query: {\n allow: [ImagePlugin.key, HorizontalRulePlugin.key],\n },\n },\n }),\n DeletePlugin,\n SingleLinePlugin,\n softBreakPlugin,\n tabbablePlugin,\n TrailingBlockPlugin.configure({\n options: { type: ParagraphPlugin.key },\n }),\n DragOverCursorPlugin,\n\n // Collaboration\n CommentsPlugin.configure({\n options: {\n comments: commentsData,\n myUserId: '1',\n users: usersData,\n },\n }),\n\n // Deserialization\n DocxPlugin,\n MarkdownPlugin.configure({ options: { indentList: true } }),\n JuicePlugin,\n\n // Testing\n PlaywrightPlugin.configure({\n enabled: process.env.NODE_ENV !== 'production',\n }),\n ],\n value: value,\n },\n []\n );\n};\n\nexport default function PlaygroundDemo({\n id,\n className,\n scrollSelector,\n}: {\n id?: ValueId;\n className?: string;\n scrollSelector?: string;\n}) {\n const containerRef = useRef(null);\n const enabled = settingsStore.use.checkedComponents();\n\n const editor = usePlaygroundEditor(\n id,\n scrollSelector ?? `blockSelection-${id}`\n );\n\n return (\n \n \n \n \n \n \n \n \n \n\n
\n \n \n\n \n \n \n \n \n \n \n\n \n \n \n \n\n \n \n \n
\n
\n
\n );\n}\n\nconst DemoIdContext = React.createContext(undefined);\n\nexport function DemoId({\n id,\n children,\n}: {\n children: React.ReactNode;\n id?: string;\n}) {\n return {children};\n}\n\nexport function useDemoId() {\n return React.useContext(DemoIdContext);\n}\n", "path": "example/playground-demo.tsx", "target": "components/playground-demo.tsx", "type": "registry:example" diff --git a/apps/www/public/r/styles/default/line-height-demo.json b/apps/www/public/r/styles/default/line-height-demo.json index a5090ab9ec..01f209d824 100644 --- a/apps/www/public/r/styles/default/line-height-demo.json +++ b/apps/www/public/r/styles/default/line-height-demo.json @@ -4,7 +4,7 @@ }, "files": [ { - "content": "'use client';\n\nimport React, { useRef } from 'react';\n\nimport type { ValueId } from '@/config/customizer-plugins';\n\nimport { cn } from '@udecode/cn';\nimport { AIChatPlugin, CopilotPlugin } from '@udecode/plate-ai/react';\nimport { AlignPlugin } from '@udecode/plate-alignment/react';\nimport { AutoformatPlugin } from '@udecode/plate-autoformat/react';\nimport {\n BoldPlugin,\n CodePlugin,\n ItalicPlugin,\n StrikethroughPlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n UnderlinePlugin,\n} from '@udecode/plate-basic-marks/react';\nimport { BlockquotePlugin } from '@udecode/plate-block-quote/react';\nimport { SingleLinePlugin } from '@udecode/plate-break/react';\nimport { CaptionPlugin } from '@udecode/plate-caption/react';\nimport { CodeBlockPlugin } from '@udecode/plate-code-block/react';\nimport { CommentsPlugin } from '@udecode/plate-comments/react';\nimport {\n ParagraphPlugin,\n Plate,\n usePlateEditor,\n} from '@udecode/plate-common/react';\nimport { DatePlugin } from '@udecode/plate-date/react';\nimport { DndPlugin } from '@udecode/plate-dnd';\nimport { DocxPlugin } from '@udecode/plate-docx';\nimport { EmojiPlugin } from '@udecode/plate-emoji/react';\nimport { ExcalidrawPlugin } from '@udecode/plate-excalidraw/react';\nimport {\n FontBackgroundColorPlugin,\n FontColorPlugin,\n FontSizePlugin,\n} from '@udecode/plate-font/react';\nimport { HEADING_KEYS } from '@udecode/plate-heading';\nimport { HeadingPlugin, TocPlugin } from '@udecode/plate-heading/react';\nimport { HighlightPlugin } from '@udecode/plate-highlight/react';\nimport { HorizontalRulePlugin } from '@udecode/plate-horizontal-rule/react';\nimport { IndentPlugin } from '@udecode/plate-indent/react';\nimport { IndentListPlugin } from '@udecode/plate-indent-list/react';\nimport { JuicePlugin } from '@udecode/plate-juice';\nimport { KbdPlugin } from '@udecode/plate-kbd/react';\nimport { ColumnPlugin } from '@udecode/plate-layout/react';\nimport { LineHeightPlugin } from '@udecode/plate-line-height/react';\nimport { LinkPlugin } from '@udecode/plate-link/react';\nimport { ListPlugin, TodoListPlugin } from '@udecode/plate-list/react';\nimport { MarkdownPlugin } from '@udecode/plate-markdown';\nimport { ImagePlugin, MediaEmbedPlugin } from '@udecode/plate-media/react';\nimport { MentionPlugin } from '@udecode/plate-mention/react';\nimport { NodeIdPlugin } from '@udecode/plate-node-id';\nimport { NormalizeTypesPlugin } from '@udecode/plate-normalizers';\nimport { PlaywrightPlugin } from '@udecode/plate-playwright';\nimport { DeletePlugin, SelectOnBackspacePlugin } from '@udecode/plate-select';\nimport {\n BlockMenuPlugin,\n BlockSelectionPlugin,\n} from '@udecode/plate-selection/react';\nimport { SlashPlugin } from '@udecode/plate-slash-command/react';\nimport { TablePlugin } from '@udecode/plate-table/react';\nimport { TogglePlugin } from '@udecode/plate-toggle/react';\nimport { TrailingBlockPlugin } from '@udecode/plate-trailing-block';\nimport Prism from 'prismjs';\n\nimport { CheckPlugin } from '@/components/context/check-plugin';\nimport { settingsStore } from '@/components/context/settings-store';\nimport { aiPlugins } from '@/lib/plate/demo/plugins/ai-plugins';\nimport { getAutoformatOptions } from '@/lib/plate/demo/plugins/autoformatOptions';\nimport { copilotPlugins } from '@/lib/plate/demo/plugins/copilot-plugins';\nimport { createPlateUI } from '@/plate/create-plate-ui';\nimport { editableProps } from '@/plate/demo/editableProps';\nimport { isEnabled } from '@/plate/demo/is-enabled';\nimport { DragOverCursorPlugin } from '@/plate/demo/plugins/DragOverCursorPlugin';\nimport { exitBreakPlugin } from '@/plate/demo/plugins/exitBreakPlugin';\nimport { resetBlockTypePlugin } from '@/plate/demo/plugins/resetBlockTypePlugin';\nimport { softBreakPlugin } from '@/plate/demo/plugins/softBreakPlugin';\nimport { tabbablePlugin } from '@/plate/demo/plugins/tabbablePlugin';\nimport { commentsData, usersData } from '@/plate/demo/values/commentsValue';\nimport { usePlaygroundValue } from '@/plate/demo/values/usePlaygroundValue';\nimport { BlockContextMenu } from '@/components/plate-ui/block-context-menu';\nimport { CommentsPopover } from '@/components/plate-ui/comments-popover';\nimport {\n CursorOverlay,\n SelectionOverlayPlugin,\n} from '@/components/plate-ui/cursor-overlay';\nimport { Editor, EditorContainer } from '@/components/plate-ui/editor';\nimport { FixedToolbar } from '@/components/plate-ui/fixed-toolbar';\nimport { FixedToolbarButtons } from '@/components/plate-ui/fixed-toolbar-buttons';\nimport { FloatingToolbar } from '@/components/plate-ui/floating-toolbar';\nimport { FloatingToolbarButtons } from '@/components/plate-ui/floating-toolbar-buttons';\nimport { ImagePreview } from '@/components/plate-ui/image-preview';\nimport {\n FireLiComponent,\n FireMarker,\n} from '@/components/plate-ui/indent-fire-marker';\nimport {\n TodoLi,\n TodoMarker,\n} from '@/components/plate-ui/indent-todo-marker';\nimport { LinkFloatingToolbar } from '@/components/plate-ui/link-floating-toolbar';\n\nimport { usePlaygroundEnabled } from './usePlaygroundEnabled';\n\nexport const usePlaygroundEditor = (id: any = '', scrollSelector?: string) => {\n const enabledPlugins = settingsStore.use.checkedPlugins();\n const overridePlugins = usePlaygroundEnabled(id);\n const autoformatOptions = getAutoformatOptions(id, enabledPlugins);\n\n const value = usePlaygroundValue(id);\n const key = settingsStore.use.version();\n const editorId = id || 'playground-' + key;\n\n return usePlateEditor(\n {\n id: editorId,\n override: {\n components: createPlateUI({\n draggable: isEnabled('dnd', id),\n placeholder: isEnabled('placeholder', id),\n }),\n plugins: overridePlugins,\n },\n plugins: [\n // AI\n ...(id === 'ai' || enabledPlugins[AIChatPlugin.key] ? aiPlugins : []),\n ...(id === 'copilot' || enabledPlugins[CopilotPlugin.key]\n ? copilotPlugins\n : []),\n // Nodes\n HeadingPlugin,\n TocPlugin.configure({\n options: {\n scrollContainerSelector: `#${scrollSelector}`,\n topOffset: 80,\n },\n }),\n BlockquotePlugin,\n CodeBlockPlugin.configure({\n options: {\n prism: Prism,\n },\n }),\n HorizontalRulePlugin,\n LinkPlugin.extend({\n render: { afterEditable: () => },\n }),\n ...(id === 'list' ? [ListPlugin] : []),\n ImagePlugin.extend({\n render: { afterEditable: ImagePreview },\n }),\n MediaEmbedPlugin,\n CaptionPlugin.configure({\n options: {\n plugins: [ImagePlugin, MediaEmbedPlugin],\n },\n }),\n DatePlugin,\n MentionPlugin.configure({\n options: {\n triggerPreviousCharPattern: /^$|^[\\s\"']$/,\n },\n }),\n SlashPlugin,\n TablePlugin.configure({\n options: {\n enableMerging: id === 'tableMerge',\n },\n }),\n ColumnPlugin,\n SelectionOverlayPlugin,\n\n TodoListPlugin,\n TogglePlugin,\n ExcalidrawPlugin,\n // Marks\n BoldPlugin,\n ItalicPlugin,\n UnderlinePlugin,\n StrikethroughPlugin,\n CodePlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n FontColorPlugin,\n FontBackgroundColorPlugin,\n FontSizePlugin,\n HighlightPlugin,\n KbdPlugin,\n\n // Block Style\n AlignPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n MediaEmbedPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n ImagePlugin.key,\n HEADING_KEYS.h6,\n ],\n },\n }),\n IndentPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n }),\n IndentListPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n options: {\n listStyleTypes: {\n fire: {\n liComponent: FireLiComponent,\n markerComponent: FireMarker,\n type: 'fire',\n },\n todo: {\n liComponent: TodoLi,\n markerComponent: TodoMarker,\n type: 'todo',\n },\n },\n },\n }),\n LineHeightPlugin.extend({\n inject: {\n nodeProps: {\n defaultNodeValue: 1.5,\n validNodeValues: [1, 1.2, 1.5, 2, 3],\n },\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n ],\n },\n }),\n\n // Functionality\n AutoformatPlugin.configure({\n options: autoformatOptions,\n }),\n BlockSelectionPlugin.configure({\n options: {\n areaOptions: {\n behaviour: {\n scrolling: {\n speedDivider: 1.5,\n },\n startThreshold: 10,\n },\n boundaries: `#${scrollSelector}`,\n container: `#${scrollSelector}`,\n selectables: [`#${scrollSelector} .slate-selectable`],\n selectionAreaClass: 'slate-selection-area',\n },\n enableContextMenu: true,\n },\n }),\n BlockMenuPlugin.configure({\n render: { aboveEditable: BlockContextMenu },\n }),\n DndPlugin.configure({ options: { enableScroller: true } }),\n EmojiPlugin,\n exitBreakPlugin,\n NodeIdPlugin,\n NormalizeTypesPlugin.configure({\n options: {\n rules: [{ path: [0], strictType: HEADING_KEYS.h1 }],\n },\n }),\n resetBlockTypePlugin,\n SelectOnBackspacePlugin.configure({\n options: {\n query: {\n allow: [ImagePlugin.key, HorizontalRulePlugin.key],\n },\n },\n }),\n DeletePlugin,\n SingleLinePlugin,\n softBreakPlugin,\n tabbablePlugin,\n TrailingBlockPlugin.configure({\n options: { type: ParagraphPlugin.key },\n }),\n DragOverCursorPlugin,\n\n // Collaboration\n CommentsPlugin.configure({\n options: {\n comments: commentsData,\n myUserId: '1',\n users: usersData,\n },\n }),\n\n // Deserialization\n DocxPlugin,\n MarkdownPlugin.configure({ options: { indentList: true } }),\n JuicePlugin,\n\n // Testing\n PlaywrightPlugin.configure({\n enabled: process.env.NODE_ENV !== 'production',\n }),\n ],\n value: value,\n },\n []\n );\n};\n\nexport default function PlaygroundDemo({\n id,\n className,\n scrollSelector,\n}: {\n id?: ValueId;\n className?: string;\n scrollSelector?: string;\n}) {\n const containerRef = useRef(null);\n const enabled = settingsStore.use.checkedComponents();\n\n const editor = usePlaygroundEditor(\n id,\n scrollSelector ?? `blockSelection-${id}`\n );\n\n return (\n \n \n \n \n \n \n \n \n \n\n
\n \n \n\n \n \n \n \n \n \n \n\n \n \n \n \n\n \n \n \n
\n
\n
\n );\n}\n\nconst DemoIdContext = React.createContext(undefined);\n\nexport function DemoId({\n id,\n children,\n}: {\n children: React.ReactNode;\n id?: string;\n}) {\n return {children};\n}\n\nexport function useDemoId() {\n return React.useContext(DemoIdContext);\n}\n", + "content": "'use client';\n\nimport React, { useRef } from 'react';\n\nimport type { ValueId } from '@/config/customizer-plugins';\n\nimport { cn } from '@udecode/cn';\nimport { AIChatPlugin, CopilotPlugin } from '@udecode/plate-ai/react';\nimport { AlignPlugin } from '@udecode/plate-alignment/react';\nimport { AutoformatPlugin } from '@udecode/plate-autoformat/react';\nimport {\n BoldPlugin,\n CodePlugin,\n ItalicPlugin,\n StrikethroughPlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n UnderlinePlugin,\n} from '@udecode/plate-basic-marks/react';\nimport { BlockquotePlugin } from '@udecode/plate-block-quote/react';\nimport { SingleLinePlugin } from '@udecode/plate-break/react';\nimport { CaptionPlugin } from '@udecode/plate-caption/react';\nimport { CodeBlockPlugin } from '@udecode/plate-code-block/react';\nimport { CommentsPlugin } from '@udecode/plate-comments/react';\nimport {\n ParagraphPlugin,\n Plate,\n usePlateEditor,\n} from '@udecode/plate-common/react';\nimport { DatePlugin } from '@udecode/plate-date/react';\nimport { DndPlugin } from '@udecode/plate-dnd';\nimport { DocxPlugin } from '@udecode/plate-docx';\nimport { EmojiPlugin } from '@udecode/plate-emoji/react';\nimport { ExcalidrawPlugin } from '@udecode/plate-excalidraw/react';\nimport {\n FontBackgroundColorPlugin,\n FontColorPlugin,\n FontSizePlugin,\n} from '@udecode/plate-font/react';\nimport { HEADING_KEYS } from '@udecode/plate-heading';\nimport { HeadingPlugin, TocPlugin } from '@udecode/plate-heading/react';\nimport { HighlightPlugin } from '@udecode/plate-highlight/react';\nimport { HorizontalRulePlugin } from '@udecode/plate-horizontal-rule/react';\nimport { IndentPlugin } from '@udecode/plate-indent/react';\nimport { IndentListPlugin } from '@udecode/plate-indent-list/react';\nimport { JuicePlugin } from '@udecode/plate-juice';\nimport { KbdPlugin } from '@udecode/plate-kbd/react';\nimport { ColumnPlugin } from '@udecode/plate-layout/react';\nimport { LineHeightPlugin } from '@udecode/plate-line-height/react';\nimport { LinkPlugin } from '@udecode/plate-link/react';\nimport { ListPlugin, TodoListPlugin } from '@udecode/plate-list/react';\nimport { MarkdownPlugin } from '@udecode/plate-markdown';\nimport { ImagePlugin, MediaEmbedPlugin } from '@udecode/plate-media/react';\nimport { MentionPlugin } from '@udecode/plate-mention/react';\nimport { NodeIdPlugin } from '@udecode/plate-node-id';\nimport { NormalizeTypesPlugin } from '@udecode/plate-normalizers';\nimport { PlaywrightPlugin } from '@udecode/plate-playwright';\nimport { DeletePlugin, SelectOnBackspacePlugin } from '@udecode/plate-select';\nimport {\n BlockMenuPlugin,\n BlockSelectionPlugin,\n} from '@udecode/plate-selection/react';\nimport { SlashPlugin } from '@udecode/plate-slash-command/react';\nimport { TablePlugin } from '@udecode/plate-table/react';\nimport { TogglePlugin } from '@udecode/plate-toggle/react';\nimport { TrailingBlockPlugin } from '@udecode/plate-trailing-block';\nimport Prism from 'prismjs';\n\nimport { CheckPlugin } from '@/components/context/check-plugin';\nimport { settingsStore } from '@/components/context/settings-store';\nimport { aiPlugins } from '@/lib/plate/demo/plugins/ai-plugins';\nimport { getAutoformatOptions } from '@/lib/plate/demo/plugins/autoformatOptions';\nimport { copilotPlugins } from '@/lib/plate/demo/plugins/copilot-plugins';\nimport { createPlateUI } from '@/plate/create-plate-ui';\nimport { editableProps } from '@/plate/demo/editableProps';\nimport { isEnabled } from '@/plate/demo/is-enabled';\nimport { DragOverCursorPlugin } from '@/plate/demo/plugins/DragOverCursorPlugin';\nimport { exitBreakPlugin } from '@/plate/demo/plugins/exitBreakPlugin';\nimport { resetBlockTypePlugin } from '@/plate/demo/plugins/resetBlockTypePlugin';\nimport { softBreakPlugin } from '@/plate/demo/plugins/softBreakPlugin';\nimport { tabbablePlugin } from '@/plate/demo/plugins/tabbablePlugin';\nimport { commentsData, usersData } from '@/plate/demo/values/commentsValue';\nimport { usePlaygroundValue } from '@/plate/demo/values/usePlaygroundValue';\nimport { BlockContextMenu } from '@/components/plate-ui/block-context-menu';\nimport { CommentsPopover } from '@/components/plate-ui/comments-popover';\nimport {\n CursorOverlay,\n SelectionOverlayPlugin,\n} from '@/components/plate-ui/cursor-overlay';\nimport { Editor, EditorContainer } from '@/components/plate-ui/editor';\nimport { FixedToolbar } from '@/components/plate-ui/fixed-toolbar';\nimport { FixedToolbarButtons } from '@/components/plate-ui/fixed-toolbar-buttons';\nimport { FloatingToolbar } from '@/components/plate-ui/floating-toolbar';\nimport { FloatingToolbarButtons } from '@/components/plate-ui/floating-toolbar-buttons';\nimport { ImagePreview } from '@/components/plate-ui/image-preview';\nimport {\n FireLiComponent,\n FireMarker,\n} from '@/components/plate-ui/indent-fire-marker';\nimport {\n TodoLi,\n TodoMarker,\n} from '@/components/plate-ui/indent-todo-marker';\nimport { LinkFloatingToolbar } from '@/components/plate-ui/link-floating-toolbar';\n\nimport { usePlaygroundEnabled } from './usePlaygroundEnabled';\n\nexport const usePlaygroundEditor = (id: any = '', scrollSelector?: string) => {\n const enabledPlugins = settingsStore.use.checkedPlugins();\n const overridePlugins = usePlaygroundEnabled(id);\n const autoformatOptions = getAutoformatOptions(id, enabledPlugins);\n\n const value = usePlaygroundValue(id);\n const key = settingsStore.use.version();\n const editorId = id || 'playground-' + key;\n\n return usePlateEditor(\n {\n id: editorId,\n override: {\n components: createPlateUI({\n draggable: isEnabled('dnd', id),\n placeholder: isEnabled('placeholder', id),\n }),\n plugins: overridePlugins,\n },\n plugins: [\n // AI\n ...(id === 'ai' || enabledPlugins[AIChatPlugin.key] ? aiPlugins : []),\n ...(id === 'copilot' || enabledPlugins[CopilotPlugin.key]\n ? copilotPlugins\n : []),\n // Nodes\n HeadingPlugin,\n TocPlugin.configure({\n options: {\n scrollContainerSelector: `#${scrollSelector}`,\n topOffset: 80,\n },\n }),\n BlockquotePlugin,\n CodeBlockPlugin.configure({\n options: {\n prism: Prism,\n },\n }),\n HorizontalRulePlugin,\n LinkPlugin.extend({\n render: { afterEditable: () => },\n }),\n ...(id === 'list' ? [ListPlugin] : []),\n ImagePlugin.extend({\n options: {\n disableUploadInsert: true,\n },\n render: { afterEditable: ImagePreview },\n }),\n MediaEmbedPlugin,\n CaptionPlugin.configure({\n options: {\n plugins: [ImagePlugin, MediaEmbedPlugin],\n },\n }),\n DatePlugin,\n MentionPlugin.configure({\n options: {\n triggerPreviousCharPattern: /^$|^[\\s\"']$/,\n },\n }),\n SlashPlugin,\n TablePlugin.configure({\n options: {\n enableMerging: id === 'tableMerge',\n },\n }),\n ColumnPlugin,\n SelectionOverlayPlugin,\n\n TodoListPlugin,\n TogglePlugin,\n ExcalidrawPlugin,\n // Marks\n BoldPlugin,\n ItalicPlugin,\n UnderlinePlugin,\n StrikethroughPlugin,\n CodePlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n FontColorPlugin,\n FontBackgroundColorPlugin,\n FontSizePlugin,\n HighlightPlugin,\n KbdPlugin,\n\n // Block Style\n AlignPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n MediaEmbedPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n ImagePlugin.key,\n HEADING_KEYS.h6,\n ],\n },\n }),\n IndentPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n }),\n IndentListPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n options: {\n listStyleTypes: {\n fire: {\n liComponent: FireLiComponent,\n markerComponent: FireMarker,\n type: 'fire',\n },\n todo: {\n liComponent: TodoLi,\n markerComponent: TodoMarker,\n type: 'todo',\n },\n },\n },\n }),\n LineHeightPlugin.extend({\n inject: {\n nodeProps: {\n defaultNodeValue: 1.5,\n validNodeValues: [1, 1.2, 1.5, 2, 3],\n },\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n ],\n },\n }),\n\n // Functionality\n AutoformatPlugin.configure({\n options: autoformatOptions,\n }),\n BlockSelectionPlugin.configure({\n options: {\n areaOptions: {\n behaviour: {\n scrolling: {\n speedDivider: 1.5,\n },\n startThreshold: 10,\n },\n boundaries: `#${scrollSelector}`,\n container: `#${scrollSelector}`,\n selectables: [`#${scrollSelector} .slate-selectable`],\n selectionAreaClass: 'slate-selection-area',\n },\n enableContextMenu: true,\n },\n }),\n BlockMenuPlugin.configure({\n render: { aboveEditable: BlockContextMenu },\n }),\n DndPlugin.configure({\n options: {\n enableScroller: true,\n onDropFiles: ({ dragItem, editor, target }) => {\n editor\n .getTransforms(ImagePlugin)\n .insertImageFromFiles(dragItem.files, {\n at: target,\n nextBlock: false,\n });\n },\n },\n }),\n EmojiPlugin,\n exitBreakPlugin,\n NodeIdPlugin,\n NormalizeTypesPlugin.configure({\n options: {\n rules: [{ path: [0], strictType: HEADING_KEYS.h1 }],\n },\n }),\n resetBlockTypePlugin,\n SelectOnBackspacePlugin.configure({\n options: {\n query: {\n allow: [ImagePlugin.key, HorizontalRulePlugin.key],\n },\n },\n }),\n DeletePlugin,\n SingleLinePlugin,\n softBreakPlugin,\n tabbablePlugin,\n TrailingBlockPlugin.configure({\n options: { type: ParagraphPlugin.key },\n }),\n DragOverCursorPlugin,\n\n // Collaboration\n CommentsPlugin.configure({\n options: {\n comments: commentsData,\n myUserId: '1',\n users: usersData,\n },\n }),\n\n // Deserialization\n DocxPlugin,\n MarkdownPlugin.configure({ options: { indentList: true } }),\n JuicePlugin,\n\n // Testing\n PlaywrightPlugin.configure({\n enabled: process.env.NODE_ENV !== 'production',\n }),\n ],\n value: value,\n },\n []\n );\n};\n\nexport default function PlaygroundDemo({\n id,\n className,\n scrollSelector,\n}: {\n id?: ValueId;\n className?: string;\n scrollSelector?: string;\n}) {\n const containerRef = useRef(null);\n const enabled = settingsStore.use.checkedComponents();\n\n const editor = usePlaygroundEditor(\n id,\n scrollSelector ?? `blockSelection-${id}`\n );\n\n return (\n \n \n \n \n \n \n \n \n \n\n
\n \n \n\n \n \n \n \n \n \n \n\n \n \n \n \n\n \n \n \n
\n
\n
\n );\n}\n\nconst DemoIdContext = React.createContext(undefined);\n\nexport function DemoId({\n id,\n children,\n}: {\n children: React.ReactNode;\n id?: string;\n}) {\n return {children};\n}\n\nexport function useDemoId() {\n return React.useContext(DemoIdContext);\n}\n", "path": "example/playground-demo.tsx", "target": "components/playground-demo.tsx", "type": "registry:example" diff --git a/apps/www/public/r/styles/default/link-demo.json b/apps/www/public/r/styles/default/link-demo.json index a0a7df6d85..b3f619f9e8 100644 --- a/apps/www/public/r/styles/default/link-demo.json +++ b/apps/www/public/r/styles/default/link-demo.json @@ -4,7 +4,7 @@ }, "files": [ { - "content": "'use client';\n\nimport React, { useRef } from 'react';\n\nimport type { ValueId } from '@/config/customizer-plugins';\n\nimport { cn } from '@udecode/cn';\nimport { AIChatPlugin, CopilotPlugin } from '@udecode/plate-ai/react';\nimport { AlignPlugin } from '@udecode/plate-alignment/react';\nimport { AutoformatPlugin } from '@udecode/plate-autoformat/react';\nimport {\n BoldPlugin,\n CodePlugin,\n ItalicPlugin,\n StrikethroughPlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n UnderlinePlugin,\n} from '@udecode/plate-basic-marks/react';\nimport { BlockquotePlugin } from '@udecode/plate-block-quote/react';\nimport { SingleLinePlugin } from '@udecode/plate-break/react';\nimport { CaptionPlugin } from '@udecode/plate-caption/react';\nimport { CodeBlockPlugin } from '@udecode/plate-code-block/react';\nimport { CommentsPlugin } from '@udecode/plate-comments/react';\nimport {\n ParagraphPlugin,\n Plate,\n usePlateEditor,\n} from '@udecode/plate-common/react';\nimport { DatePlugin } from '@udecode/plate-date/react';\nimport { DndPlugin } from '@udecode/plate-dnd';\nimport { DocxPlugin } from '@udecode/plate-docx';\nimport { EmojiPlugin } from '@udecode/plate-emoji/react';\nimport { ExcalidrawPlugin } from '@udecode/plate-excalidraw/react';\nimport {\n FontBackgroundColorPlugin,\n FontColorPlugin,\n FontSizePlugin,\n} from '@udecode/plate-font/react';\nimport { HEADING_KEYS } from '@udecode/plate-heading';\nimport { HeadingPlugin, TocPlugin } from '@udecode/plate-heading/react';\nimport { HighlightPlugin } from '@udecode/plate-highlight/react';\nimport { HorizontalRulePlugin } from '@udecode/plate-horizontal-rule/react';\nimport { IndentPlugin } from '@udecode/plate-indent/react';\nimport { IndentListPlugin } from '@udecode/plate-indent-list/react';\nimport { JuicePlugin } from '@udecode/plate-juice';\nimport { KbdPlugin } from '@udecode/plate-kbd/react';\nimport { ColumnPlugin } from '@udecode/plate-layout/react';\nimport { LineHeightPlugin } from '@udecode/plate-line-height/react';\nimport { LinkPlugin } from '@udecode/plate-link/react';\nimport { ListPlugin, TodoListPlugin } from '@udecode/plate-list/react';\nimport { MarkdownPlugin } from '@udecode/plate-markdown';\nimport { ImagePlugin, MediaEmbedPlugin } from '@udecode/plate-media/react';\nimport { MentionPlugin } from '@udecode/plate-mention/react';\nimport { NodeIdPlugin } from '@udecode/plate-node-id';\nimport { NormalizeTypesPlugin } from '@udecode/plate-normalizers';\nimport { PlaywrightPlugin } from '@udecode/plate-playwright';\nimport { DeletePlugin, SelectOnBackspacePlugin } from '@udecode/plate-select';\nimport {\n BlockMenuPlugin,\n BlockSelectionPlugin,\n} from '@udecode/plate-selection/react';\nimport { SlashPlugin } from '@udecode/plate-slash-command/react';\nimport { TablePlugin } from '@udecode/plate-table/react';\nimport { TogglePlugin } from '@udecode/plate-toggle/react';\nimport { TrailingBlockPlugin } from '@udecode/plate-trailing-block';\nimport Prism from 'prismjs';\n\nimport { CheckPlugin } from '@/components/context/check-plugin';\nimport { settingsStore } from '@/components/context/settings-store';\nimport { aiPlugins } from '@/lib/plate/demo/plugins/ai-plugins';\nimport { getAutoformatOptions } from '@/lib/plate/demo/plugins/autoformatOptions';\nimport { copilotPlugins } from '@/lib/plate/demo/plugins/copilot-plugins';\nimport { createPlateUI } from '@/plate/create-plate-ui';\nimport { editableProps } from '@/plate/demo/editableProps';\nimport { isEnabled } from '@/plate/demo/is-enabled';\nimport { DragOverCursorPlugin } from '@/plate/demo/plugins/DragOverCursorPlugin';\nimport { exitBreakPlugin } from '@/plate/demo/plugins/exitBreakPlugin';\nimport { resetBlockTypePlugin } from '@/plate/demo/plugins/resetBlockTypePlugin';\nimport { softBreakPlugin } from '@/plate/demo/plugins/softBreakPlugin';\nimport { tabbablePlugin } from '@/plate/demo/plugins/tabbablePlugin';\nimport { commentsData, usersData } from '@/plate/demo/values/commentsValue';\nimport { usePlaygroundValue } from '@/plate/demo/values/usePlaygroundValue';\nimport { BlockContextMenu } from '@/components/plate-ui/block-context-menu';\nimport { CommentsPopover } from '@/components/plate-ui/comments-popover';\nimport {\n CursorOverlay,\n SelectionOverlayPlugin,\n} from '@/components/plate-ui/cursor-overlay';\nimport { Editor, EditorContainer } from '@/components/plate-ui/editor';\nimport { FixedToolbar } from '@/components/plate-ui/fixed-toolbar';\nimport { FixedToolbarButtons } from '@/components/plate-ui/fixed-toolbar-buttons';\nimport { FloatingToolbar } from '@/components/plate-ui/floating-toolbar';\nimport { FloatingToolbarButtons } from '@/components/plate-ui/floating-toolbar-buttons';\nimport { ImagePreview } from '@/components/plate-ui/image-preview';\nimport {\n FireLiComponent,\n FireMarker,\n} from '@/components/plate-ui/indent-fire-marker';\nimport {\n TodoLi,\n TodoMarker,\n} from '@/components/plate-ui/indent-todo-marker';\nimport { LinkFloatingToolbar } from '@/components/plate-ui/link-floating-toolbar';\n\nimport { usePlaygroundEnabled } from './usePlaygroundEnabled';\n\nexport const usePlaygroundEditor = (id: any = '', scrollSelector?: string) => {\n const enabledPlugins = settingsStore.use.checkedPlugins();\n const overridePlugins = usePlaygroundEnabled(id);\n const autoformatOptions = getAutoformatOptions(id, enabledPlugins);\n\n const value = usePlaygroundValue(id);\n const key = settingsStore.use.version();\n const editorId = id || 'playground-' + key;\n\n return usePlateEditor(\n {\n id: editorId,\n override: {\n components: createPlateUI({\n draggable: isEnabled('dnd', id),\n placeholder: isEnabled('placeholder', id),\n }),\n plugins: overridePlugins,\n },\n plugins: [\n // AI\n ...(id === 'ai' || enabledPlugins[AIChatPlugin.key] ? aiPlugins : []),\n ...(id === 'copilot' || enabledPlugins[CopilotPlugin.key]\n ? copilotPlugins\n : []),\n // Nodes\n HeadingPlugin,\n TocPlugin.configure({\n options: {\n scrollContainerSelector: `#${scrollSelector}`,\n topOffset: 80,\n },\n }),\n BlockquotePlugin,\n CodeBlockPlugin.configure({\n options: {\n prism: Prism,\n },\n }),\n HorizontalRulePlugin,\n LinkPlugin.extend({\n render: { afterEditable: () => },\n }),\n ...(id === 'list' ? [ListPlugin] : []),\n ImagePlugin.extend({\n render: { afterEditable: ImagePreview },\n }),\n MediaEmbedPlugin,\n CaptionPlugin.configure({\n options: {\n plugins: [ImagePlugin, MediaEmbedPlugin],\n },\n }),\n DatePlugin,\n MentionPlugin.configure({\n options: {\n triggerPreviousCharPattern: /^$|^[\\s\"']$/,\n },\n }),\n SlashPlugin,\n TablePlugin.configure({\n options: {\n enableMerging: id === 'tableMerge',\n },\n }),\n ColumnPlugin,\n SelectionOverlayPlugin,\n\n TodoListPlugin,\n TogglePlugin,\n ExcalidrawPlugin,\n // Marks\n BoldPlugin,\n ItalicPlugin,\n UnderlinePlugin,\n StrikethroughPlugin,\n CodePlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n FontColorPlugin,\n FontBackgroundColorPlugin,\n FontSizePlugin,\n HighlightPlugin,\n KbdPlugin,\n\n // Block Style\n AlignPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n MediaEmbedPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n ImagePlugin.key,\n HEADING_KEYS.h6,\n ],\n },\n }),\n IndentPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n }),\n IndentListPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n options: {\n listStyleTypes: {\n fire: {\n liComponent: FireLiComponent,\n markerComponent: FireMarker,\n type: 'fire',\n },\n todo: {\n liComponent: TodoLi,\n markerComponent: TodoMarker,\n type: 'todo',\n },\n },\n },\n }),\n LineHeightPlugin.extend({\n inject: {\n nodeProps: {\n defaultNodeValue: 1.5,\n validNodeValues: [1, 1.2, 1.5, 2, 3],\n },\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n ],\n },\n }),\n\n // Functionality\n AutoformatPlugin.configure({\n options: autoformatOptions,\n }),\n BlockSelectionPlugin.configure({\n options: {\n areaOptions: {\n behaviour: {\n scrolling: {\n speedDivider: 1.5,\n },\n startThreshold: 10,\n },\n boundaries: `#${scrollSelector}`,\n container: `#${scrollSelector}`,\n selectables: [`#${scrollSelector} .slate-selectable`],\n selectionAreaClass: 'slate-selection-area',\n },\n enableContextMenu: true,\n },\n }),\n BlockMenuPlugin.configure({\n render: { aboveEditable: BlockContextMenu },\n }),\n DndPlugin.configure({ options: { enableScroller: true } }),\n EmojiPlugin,\n exitBreakPlugin,\n NodeIdPlugin,\n NormalizeTypesPlugin.configure({\n options: {\n rules: [{ path: [0], strictType: HEADING_KEYS.h1 }],\n },\n }),\n resetBlockTypePlugin,\n SelectOnBackspacePlugin.configure({\n options: {\n query: {\n allow: [ImagePlugin.key, HorizontalRulePlugin.key],\n },\n },\n }),\n DeletePlugin,\n SingleLinePlugin,\n softBreakPlugin,\n tabbablePlugin,\n TrailingBlockPlugin.configure({\n options: { type: ParagraphPlugin.key },\n }),\n DragOverCursorPlugin,\n\n // Collaboration\n CommentsPlugin.configure({\n options: {\n comments: commentsData,\n myUserId: '1',\n users: usersData,\n },\n }),\n\n // Deserialization\n DocxPlugin,\n MarkdownPlugin.configure({ options: { indentList: true } }),\n JuicePlugin,\n\n // Testing\n PlaywrightPlugin.configure({\n enabled: process.env.NODE_ENV !== 'production',\n }),\n ],\n value: value,\n },\n []\n );\n};\n\nexport default function PlaygroundDemo({\n id,\n className,\n scrollSelector,\n}: {\n id?: ValueId;\n className?: string;\n scrollSelector?: string;\n}) {\n const containerRef = useRef(null);\n const enabled = settingsStore.use.checkedComponents();\n\n const editor = usePlaygroundEditor(\n id,\n scrollSelector ?? `blockSelection-${id}`\n );\n\n return (\n \n \n \n \n \n \n \n \n \n\n
\n \n \n\n \n \n \n \n \n \n \n\n \n \n \n \n\n \n \n \n
\n
\n
\n );\n}\n\nconst DemoIdContext = React.createContext(undefined);\n\nexport function DemoId({\n id,\n children,\n}: {\n children: React.ReactNode;\n id?: string;\n}) {\n return {children};\n}\n\nexport function useDemoId() {\n return React.useContext(DemoIdContext);\n}\n", + "content": "'use client';\n\nimport React, { useRef } from 'react';\n\nimport type { ValueId } from '@/config/customizer-plugins';\n\nimport { cn } from '@udecode/cn';\nimport { AIChatPlugin, CopilotPlugin } from '@udecode/plate-ai/react';\nimport { AlignPlugin } from '@udecode/plate-alignment/react';\nimport { AutoformatPlugin } from '@udecode/plate-autoformat/react';\nimport {\n BoldPlugin,\n CodePlugin,\n ItalicPlugin,\n StrikethroughPlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n UnderlinePlugin,\n} from '@udecode/plate-basic-marks/react';\nimport { BlockquotePlugin } from '@udecode/plate-block-quote/react';\nimport { SingleLinePlugin } from '@udecode/plate-break/react';\nimport { CaptionPlugin } from '@udecode/plate-caption/react';\nimport { CodeBlockPlugin } from '@udecode/plate-code-block/react';\nimport { CommentsPlugin } from '@udecode/plate-comments/react';\nimport {\n ParagraphPlugin,\n Plate,\n usePlateEditor,\n} from '@udecode/plate-common/react';\nimport { DatePlugin } from '@udecode/plate-date/react';\nimport { DndPlugin } from '@udecode/plate-dnd';\nimport { DocxPlugin } from '@udecode/plate-docx';\nimport { EmojiPlugin } from '@udecode/plate-emoji/react';\nimport { ExcalidrawPlugin } from '@udecode/plate-excalidraw/react';\nimport {\n FontBackgroundColorPlugin,\n FontColorPlugin,\n FontSizePlugin,\n} from '@udecode/plate-font/react';\nimport { HEADING_KEYS } from '@udecode/plate-heading';\nimport { HeadingPlugin, TocPlugin } from '@udecode/plate-heading/react';\nimport { HighlightPlugin } from '@udecode/plate-highlight/react';\nimport { HorizontalRulePlugin } from '@udecode/plate-horizontal-rule/react';\nimport { IndentPlugin } from '@udecode/plate-indent/react';\nimport { IndentListPlugin } from '@udecode/plate-indent-list/react';\nimport { JuicePlugin } from '@udecode/plate-juice';\nimport { KbdPlugin } from '@udecode/plate-kbd/react';\nimport { ColumnPlugin } from '@udecode/plate-layout/react';\nimport { LineHeightPlugin } from '@udecode/plate-line-height/react';\nimport { LinkPlugin } from '@udecode/plate-link/react';\nimport { ListPlugin, TodoListPlugin } from '@udecode/plate-list/react';\nimport { MarkdownPlugin } from '@udecode/plate-markdown';\nimport { ImagePlugin, MediaEmbedPlugin } from '@udecode/plate-media/react';\nimport { MentionPlugin } from '@udecode/plate-mention/react';\nimport { NodeIdPlugin } from '@udecode/plate-node-id';\nimport { NormalizeTypesPlugin } from '@udecode/plate-normalizers';\nimport { PlaywrightPlugin } from '@udecode/plate-playwright';\nimport { DeletePlugin, SelectOnBackspacePlugin } from '@udecode/plate-select';\nimport {\n BlockMenuPlugin,\n BlockSelectionPlugin,\n} from '@udecode/plate-selection/react';\nimport { SlashPlugin } from '@udecode/plate-slash-command/react';\nimport { TablePlugin } from '@udecode/plate-table/react';\nimport { TogglePlugin } from '@udecode/plate-toggle/react';\nimport { TrailingBlockPlugin } from '@udecode/plate-trailing-block';\nimport Prism from 'prismjs';\n\nimport { CheckPlugin } from '@/components/context/check-plugin';\nimport { settingsStore } from '@/components/context/settings-store';\nimport { aiPlugins } from '@/lib/plate/demo/plugins/ai-plugins';\nimport { getAutoformatOptions } from '@/lib/plate/demo/plugins/autoformatOptions';\nimport { copilotPlugins } from '@/lib/plate/demo/plugins/copilot-plugins';\nimport { createPlateUI } from '@/plate/create-plate-ui';\nimport { editableProps } from '@/plate/demo/editableProps';\nimport { isEnabled } from '@/plate/demo/is-enabled';\nimport { DragOverCursorPlugin } from '@/plate/demo/plugins/DragOverCursorPlugin';\nimport { exitBreakPlugin } from '@/plate/demo/plugins/exitBreakPlugin';\nimport { resetBlockTypePlugin } from '@/plate/demo/plugins/resetBlockTypePlugin';\nimport { softBreakPlugin } from '@/plate/demo/plugins/softBreakPlugin';\nimport { tabbablePlugin } from '@/plate/demo/plugins/tabbablePlugin';\nimport { commentsData, usersData } from '@/plate/demo/values/commentsValue';\nimport { usePlaygroundValue } from '@/plate/demo/values/usePlaygroundValue';\nimport { BlockContextMenu } from '@/components/plate-ui/block-context-menu';\nimport { CommentsPopover } from '@/components/plate-ui/comments-popover';\nimport {\n CursorOverlay,\n SelectionOverlayPlugin,\n} from '@/components/plate-ui/cursor-overlay';\nimport { Editor, EditorContainer } from '@/components/plate-ui/editor';\nimport { FixedToolbar } from '@/components/plate-ui/fixed-toolbar';\nimport { FixedToolbarButtons } from '@/components/plate-ui/fixed-toolbar-buttons';\nimport { FloatingToolbar } from '@/components/plate-ui/floating-toolbar';\nimport { FloatingToolbarButtons } from '@/components/plate-ui/floating-toolbar-buttons';\nimport { ImagePreview } from '@/components/plate-ui/image-preview';\nimport {\n FireLiComponent,\n FireMarker,\n} from '@/components/plate-ui/indent-fire-marker';\nimport {\n TodoLi,\n TodoMarker,\n} from '@/components/plate-ui/indent-todo-marker';\nimport { LinkFloatingToolbar } from '@/components/plate-ui/link-floating-toolbar';\n\nimport { usePlaygroundEnabled } from './usePlaygroundEnabled';\n\nexport const usePlaygroundEditor = (id: any = '', scrollSelector?: string) => {\n const enabledPlugins = settingsStore.use.checkedPlugins();\n const overridePlugins = usePlaygroundEnabled(id);\n const autoformatOptions = getAutoformatOptions(id, enabledPlugins);\n\n const value = usePlaygroundValue(id);\n const key = settingsStore.use.version();\n const editorId = id || 'playground-' + key;\n\n return usePlateEditor(\n {\n id: editorId,\n override: {\n components: createPlateUI({\n draggable: isEnabled('dnd', id),\n placeholder: isEnabled('placeholder', id),\n }),\n plugins: overridePlugins,\n },\n plugins: [\n // AI\n ...(id === 'ai' || enabledPlugins[AIChatPlugin.key] ? aiPlugins : []),\n ...(id === 'copilot' || enabledPlugins[CopilotPlugin.key]\n ? copilotPlugins\n : []),\n // Nodes\n HeadingPlugin,\n TocPlugin.configure({\n options: {\n scrollContainerSelector: `#${scrollSelector}`,\n topOffset: 80,\n },\n }),\n BlockquotePlugin,\n CodeBlockPlugin.configure({\n options: {\n prism: Prism,\n },\n }),\n HorizontalRulePlugin,\n LinkPlugin.extend({\n render: { afterEditable: () => },\n }),\n ...(id === 'list' ? [ListPlugin] : []),\n ImagePlugin.extend({\n options: {\n disableUploadInsert: true,\n },\n render: { afterEditable: ImagePreview },\n }),\n MediaEmbedPlugin,\n CaptionPlugin.configure({\n options: {\n plugins: [ImagePlugin, MediaEmbedPlugin],\n },\n }),\n DatePlugin,\n MentionPlugin.configure({\n options: {\n triggerPreviousCharPattern: /^$|^[\\s\"']$/,\n },\n }),\n SlashPlugin,\n TablePlugin.configure({\n options: {\n enableMerging: id === 'tableMerge',\n },\n }),\n ColumnPlugin,\n SelectionOverlayPlugin,\n\n TodoListPlugin,\n TogglePlugin,\n ExcalidrawPlugin,\n // Marks\n BoldPlugin,\n ItalicPlugin,\n UnderlinePlugin,\n StrikethroughPlugin,\n CodePlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n FontColorPlugin,\n FontBackgroundColorPlugin,\n FontSizePlugin,\n HighlightPlugin,\n KbdPlugin,\n\n // Block Style\n AlignPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n MediaEmbedPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n ImagePlugin.key,\n HEADING_KEYS.h6,\n ],\n },\n }),\n IndentPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n }),\n IndentListPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n options: {\n listStyleTypes: {\n fire: {\n liComponent: FireLiComponent,\n markerComponent: FireMarker,\n type: 'fire',\n },\n todo: {\n liComponent: TodoLi,\n markerComponent: TodoMarker,\n type: 'todo',\n },\n },\n },\n }),\n LineHeightPlugin.extend({\n inject: {\n nodeProps: {\n defaultNodeValue: 1.5,\n validNodeValues: [1, 1.2, 1.5, 2, 3],\n },\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n ],\n },\n }),\n\n // Functionality\n AutoformatPlugin.configure({\n options: autoformatOptions,\n }),\n BlockSelectionPlugin.configure({\n options: {\n areaOptions: {\n behaviour: {\n scrolling: {\n speedDivider: 1.5,\n },\n startThreshold: 10,\n },\n boundaries: `#${scrollSelector}`,\n container: `#${scrollSelector}`,\n selectables: [`#${scrollSelector} .slate-selectable`],\n selectionAreaClass: 'slate-selection-area',\n },\n enableContextMenu: true,\n },\n }),\n BlockMenuPlugin.configure({\n render: { aboveEditable: BlockContextMenu },\n }),\n DndPlugin.configure({\n options: {\n enableScroller: true,\n onDropFiles: ({ dragItem, editor, target }) => {\n editor\n .getTransforms(ImagePlugin)\n .insertImageFromFiles(dragItem.files, {\n at: target,\n nextBlock: false,\n });\n },\n },\n }),\n EmojiPlugin,\n exitBreakPlugin,\n NodeIdPlugin,\n NormalizeTypesPlugin.configure({\n options: {\n rules: [{ path: [0], strictType: HEADING_KEYS.h1 }],\n },\n }),\n resetBlockTypePlugin,\n SelectOnBackspacePlugin.configure({\n options: {\n query: {\n allow: [ImagePlugin.key, HorizontalRulePlugin.key],\n },\n },\n }),\n DeletePlugin,\n SingleLinePlugin,\n softBreakPlugin,\n tabbablePlugin,\n TrailingBlockPlugin.configure({\n options: { type: ParagraphPlugin.key },\n }),\n DragOverCursorPlugin,\n\n // Collaboration\n CommentsPlugin.configure({\n options: {\n comments: commentsData,\n myUserId: '1',\n users: usersData,\n },\n }),\n\n // Deserialization\n DocxPlugin,\n MarkdownPlugin.configure({ options: { indentList: true } }),\n JuicePlugin,\n\n // Testing\n PlaywrightPlugin.configure({\n enabled: process.env.NODE_ENV !== 'production',\n }),\n ],\n value: value,\n },\n []\n );\n};\n\nexport default function PlaygroundDemo({\n id,\n className,\n scrollSelector,\n}: {\n id?: ValueId;\n className?: string;\n scrollSelector?: string;\n}) {\n const containerRef = useRef(null);\n const enabled = settingsStore.use.checkedComponents();\n\n const editor = usePlaygroundEditor(\n id,\n scrollSelector ?? `blockSelection-${id}`\n );\n\n return (\n \n \n \n \n \n \n \n \n \n\n
\n \n \n\n \n \n \n \n \n \n \n\n \n \n \n \n\n \n \n \n
\n
\n
\n );\n}\n\nconst DemoIdContext = React.createContext(undefined);\n\nexport function DemoId({\n id,\n children,\n}: {\n children: React.ReactNode;\n id?: string;\n}) {\n return {children};\n}\n\nexport function useDemoId() {\n return React.useContext(DemoIdContext);\n}\n", "path": "example/playground-demo.tsx", "target": "components/playground-demo.tsx", "type": "registry:example" diff --git a/apps/www/public/r/styles/default/list-demo.json b/apps/www/public/r/styles/default/list-demo.json index 0184f1fc15..d27499fc66 100644 --- a/apps/www/public/r/styles/default/list-demo.json +++ b/apps/www/public/r/styles/default/list-demo.json @@ -4,7 +4,7 @@ }, "files": [ { - "content": "'use client';\n\nimport React, { useRef } from 'react';\n\nimport type { ValueId } from '@/config/customizer-plugins';\n\nimport { cn } from '@udecode/cn';\nimport { AIChatPlugin, CopilotPlugin } from '@udecode/plate-ai/react';\nimport { AlignPlugin } from '@udecode/plate-alignment/react';\nimport { AutoformatPlugin } from '@udecode/plate-autoformat/react';\nimport {\n BoldPlugin,\n CodePlugin,\n ItalicPlugin,\n StrikethroughPlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n UnderlinePlugin,\n} from '@udecode/plate-basic-marks/react';\nimport { BlockquotePlugin } from '@udecode/plate-block-quote/react';\nimport { SingleLinePlugin } from '@udecode/plate-break/react';\nimport { CaptionPlugin } from '@udecode/plate-caption/react';\nimport { CodeBlockPlugin } from '@udecode/plate-code-block/react';\nimport { CommentsPlugin } from '@udecode/plate-comments/react';\nimport {\n ParagraphPlugin,\n Plate,\n usePlateEditor,\n} from '@udecode/plate-common/react';\nimport { DatePlugin } from '@udecode/plate-date/react';\nimport { DndPlugin } from '@udecode/plate-dnd';\nimport { DocxPlugin } from '@udecode/plate-docx';\nimport { EmojiPlugin } from '@udecode/plate-emoji/react';\nimport { ExcalidrawPlugin } from '@udecode/plate-excalidraw/react';\nimport {\n FontBackgroundColorPlugin,\n FontColorPlugin,\n FontSizePlugin,\n} from '@udecode/plate-font/react';\nimport { HEADING_KEYS } from '@udecode/plate-heading';\nimport { HeadingPlugin, TocPlugin } from '@udecode/plate-heading/react';\nimport { HighlightPlugin } from '@udecode/plate-highlight/react';\nimport { HorizontalRulePlugin } from '@udecode/plate-horizontal-rule/react';\nimport { IndentPlugin } from '@udecode/plate-indent/react';\nimport { IndentListPlugin } from '@udecode/plate-indent-list/react';\nimport { JuicePlugin } from '@udecode/plate-juice';\nimport { KbdPlugin } from '@udecode/plate-kbd/react';\nimport { ColumnPlugin } from '@udecode/plate-layout/react';\nimport { LineHeightPlugin } from '@udecode/plate-line-height/react';\nimport { LinkPlugin } from '@udecode/plate-link/react';\nimport { ListPlugin, TodoListPlugin } from '@udecode/plate-list/react';\nimport { MarkdownPlugin } from '@udecode/plate-markdown';\nimport { ImagePlugin, MediaEmbedPlugin } from '@udecode/plate-media/react';\nimport { MentionPlugin } from '@udecode/plate-mention/react';\nimport { NodeIdPlugin } from '@udecode/plate-node-id';\nimport { NormalizeTypesPlugin } from '@udecode/plate-normalizers';\nimport { PlaywrightPlugin } from '@udecode/plate-playwright';\nimport { DeletePlugin, SelectOnBackspacePlugin } from '@udecode/plate-select';\nimport {\n BlockMenuPlugin,\n BlockSelectionPlugin,\n} from '@udecode/plate-selection/react';\nimport { SlashPlugin } from '@udecode/plate-slash-command/react';\nimport { TablePlugin } from '@udecode/plate-table/react';\nimport { TogglePlugin } from '@udecode/plate-toggle/react';\nimport { TrailingBlockPlugin } from '@udecode/plate-trailing-block';\nimport Prism from 'prismjs';\n\nimport { CheckPlugin } from '@/components/context/check-plugin';\nimport { settingsStore } from '@/components/context/settings-store';\nimport { aiPlugins } from '@/lib/plate/demo/plugins/ai-plugins';\nimport { getAutoformatOptions } from '@/lib/plate/demo/plugins/autoformatOptions';\nimport { copilotPlugins } from '@/lib/plate/demo/plugins/copilot-plugins';\nimport { createPlateUI } from '@/plate/create-plate-ui';\nimport { editableProps } from '@/plate/demo/editableProps';\nimport { isEnabled } from '@/plate/demo/is-enabled';\nimport { DragOverCursorPlugin } from '@/plate/demo/plugins/DragOverCursorPlugin';\nimport { exitBreakPlugin } from '@/plate/demo/plugins/exitBreakPlugin';\nimport { resetBlockTypePlugin } from '@/plate/demo/plugins/resetBlockTypePlugin';\nimport { softBreakPlugin } from '@/plate/demo/plugins/softBreakPlugin';\nimport { tabbablePlugin } from '@/plate/demo/plugins/tabbablePlugin';\nimport { commentsData, usersData } from '@/plate/demo/values/commentsValue';\nimport { usePlaygroundValue } from '@/plate/demo/values/usePlaygroundValue';\nimport { BlockContextMenu } from '@/components/plate-ui/block-context-menu';\nimport { CommentsPopover } from '@/components/plate-ui/comments-popover';\nimport {\n CursorOverlay,\n SelectionOverlayPlugin,\n} from '@/components/plate-ui/cursor-overlay';\nimport { Editor, EditorContainer } from '@/components/plate-ui/editor';\nimport { FixedToolbar } from '@/components/plate-ui/fixed-toolbar';\nimport { FixedToolbarButtons } from '@/components/plate-ui/fixed-toolbar-buttons';\nimport { FloatingToolbar } from '@/components/plate-ui/floating-toolbar';\nimport { FloatingToolbarButtons } from '@/components/plate-ui/floating-toolbar-buttons';\nimport { ImagePreview } from '@/components/plate-ui/image-preview';\nimport {\n FireLiComponent,\n FireMarker,\n} from '@/components/plate-ui/indent-fire-marker';\nimport {\n TodoLi,\n TodoMarker,\n} from '@/components/plate-ui/indent-todo-marker';\nimport { LinkFloatingToolbar } from '@/components/plate-ui/link-floating-toolbar';\n\nimport { usePlaygroundEnabled } from './usePlaygroundEnabled';\n\nexport const usePlaygroundEditor = (id: any = '', scrollSelector?: string) => {\n const enabledPlugins = settingsStore.use.checkedPlugins();\n const overridePlugins = usePlaygroundEnabled(id);\n const autoformatOptions = getAutoformatOptions(id, enabledPlugins);\n\n const value = usePlaygroundValue(id);\n const key = settingsStore.use.version();\n const editorId = id || 'playground-' + key;\n\n return usePlateEditor(\n {\n id: editorId,\n override: {\n components: createPlateUI({\n draggable: isEnabled('dnd', id),\n placeholder: isEnabled('placeholder', id),\n }),\n plugins: overridePlugins,\n },\n plugins: [\n // AI\n ...(id === 'ai' || enabledPlugins[AIChatPlugin.key] ? aiPlugins : []),\n ...(id === 'copilot' || enabledPlugins[CopilotPlugin.key]\n ? copilotPlugins\n : []),\n // Nodes\n HeadingPlugin,\n TocPlugin.configure({\n options: {\n scrollContainerSelector: `#${scrollSelector}`,\n topOffset: 80,\n },\n }),\n BlockquotePlugin,\n CodeBlockPlugin.configure({\n options: {\n prism: Prism,\n },\n }),\n HorizontalRulePlugin,\n LinkPlugin.extend({\n render: { afterEditable: () => },\n }),\n ...(id === 'list' ? [ListPlugin] : []),\n ImagePlugin.extend({\n render: { afterEditable: ImagePreview },\n }),\n MediaEmbedPlugin,\n CaptionPlugin.configure({\n options: {\n plugins: [ImagePlugin, MediaEmbedPlugin],\n },\n }),\n DatePlugin,\n MentionPlugin.configure({\n options: {\n triggerPreviousCharPattern: /^$|^[\\s\"']$/,\n },\n }),\n SlashPlugin,\n TablePlugin.configure({\n options: {\n enableMerging: id === 'tableMerge',\n },\n }),\n ColumnPlugin,\n SelectionOverlayPlugin,\n\n TodoListPlugin,\n TogglePlugin,\n ExcalidrawPlugin,\n // Marks\n BoldPlugin,\n ItalicPlugin,\n UnderlinePlugin,\n StrikethroughPlugin,\n CodePlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n FontColorPlugin,\n FontBackgroundColorPlugin,\n FontSizePlugin,\n HighlightPlugin,\n KbdPlugin,\n\n // Block Style\n AlignPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n MediaEmbedPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n ImagePlugin.key,\n HEADING_KEYS.h6,\n ],\n },\n }),\n IndentPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n }),\n IndentListPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n options: {\n listStyleTypes: {\n fire: {\n liComponent: FireLiComponent,\n markerComponent: FireMarker,\n type: 'fire',\n },\n todo: {\n liComponent: TodoLi,\n markerComponent: TodoMarker,\n type: 'todo',\n },\n },\n },\n }),\n LineHeightPlugin.extend({\n inject: {\n nodeProps: {\n defaultNodeValue: 1.5,\n validNodeValues: [1, 1.2, 1.5, 2, 3],\n },\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n ],\n },\n }),\n\n // Functionality\n AutoformatPlugin.configure({\n options: autoformatOptions,\n }),\n BlockSelectionPlugin.configure({\n options: {\n areaOptions: {\n behaviour: {\n scrolling: {\n speedDivider: 1.5,\n },\n startThreshold: 10,\n },\n boundaries: `#${scrollSelector}`,\n container: `#${scrollSelector}`,\n selectables: [`#${scrollSelector} .slate-selectable`],\n selectionAreaClass: 'slate-selection-area',\n },\n enableContextMenu: true,\n },\n }),\n BlockMenuPlugin.configure({\n render: { aboveEditable: BlockContextMenu },\n }),\n DndPlugin.configure({ options: { enableScroller: true } }),\n EmojiPlugin,\n exitBreakPlugin,\n NodeIdPlugin,\n NormalizeTypesPlugin.configure({\n options: {\n rules: [{ path: [0], strictType: HEADING_KEYS.h1 }],\n },\n }),\n resetBlockTypePlugin,\n SelectOnBackspacePlugin.configure({\n options: {\n query: {\n allow: [ImagePlugin.key, HorizontalRulePlugin.key],\n },\n },\n }),\n DeletePlugin,\n SingleLinePlugin,\n softBreakPlugin,\n tabbablePlugin,\n TrailingBlockPlugin.configure({\n options: { type: ParagraphPlugin.key },\n }),\n DragOverCursorPlugin,\n\n // Collaboration\n CommentsPlugin.configure({\n options: {\n comments: commentsData,\n myUserId: '1',\n users: usersData,\n },\n }),\n\n // Deserialization\n DocxPlugin,\n MarkdownPlugin.configure({ options: { indentList: true } }),\n JuicePlugin,\n\n // Testing\n PlaywrightPlugin.configure({\n enabled: process.env.NODE_ENV !== 'production',\n }),\n ],\n value: value,\n },\n []\n );\n};\n\nexport default function PlaygroundDemo({\n id,\n className,\n scrollSelector,\n}: {\n id?: ValueId;\n className?: string;\n scrollSelector?: string;\n}) {\n const containerRef = useRef(null);\n const enabled = settingsStore.use.checkedComponents();\n\n const editor = usePlaygroundEditor(\n id,\n scrollSelector ?? `blockSelection-${id}`\n );\n\n return (\n \n \n \n \n \n \n \n \n \n\n
\n \n \n\n \n \n \n \n \n \n \n\n \n \n \n \n\n \n \n \n
\n
\n
\n );\n}\n\nconst DemoIdContext = React.createContext(undefined);\n\nexport function DemoId({\n id,\n children,\n}: {\n children: React.ReactNode;\n id?: string;\n}) {\n return {children};\n}\n\nexport function useDemoId() {\n return React.useContext(DemoIdContext);\n}\n", + "content": "'use client';\n\nimport React, { useRef } from 'react';\n\nimport type { ValueId } from '@/config/customizer-plugins';\n\nimport { cn } from '@udecode/cn';\nimport { AIChatPlugin, CopilotPlugin } from '@udecode/plate-ai/react';\nimport { AlignPlugin } from '@udecode/plate-alignment/react';\nimport { AutoformatPlugin } from '@udecode/plate-autoformat/react';\nimport {\n BoldPlugin,\n CodePlugin,\n ItalicPlugin,\n StrikethroughPlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n UnderlinePlugin,\n} from '@udecode/plate-basic-marks/react';\nimport { BlockquotePlugin } from '@udecode/plate-block-quote/react';\nimport { SingleLinePlugin } from '@udecode/plate-break/react';\nimport { CaptionPlugin } from '@udecode/plate-caption/react';\nimport { CodeBlockPlugin } from '@udecode/plate-code-block/react';\nimport { CommentsPlugin } from '@udecode/plate-comments/react';\nimport {\n ParagraphPlugin,\n Plate,\n usePlateEditor,\n} from '@udecode/plate-common/react';\nimport { DatePlugin } from '@udecode/plate-date/react';\nimport { DndPlugin } from '@udecode/plate-dnd';\nimport { DocxPlugin } from '@udecode/plate-docx';\nimport { EmojiPlugin } from '@udecode/plate-emoji/react';\nimport { ExcalidrawPlugin } from '@udecode/plate-excalidraw/react';\nimport {\n FontBackgroundColorPlugin,\n FontColorPlugin,\n FontSizePlugin,\n} from '@udecode/plate-font/react';\nimport { HEADING_KEYS } from '@udecode/plate-heading';\nimport { HeadingPlugin, TocPlugin } from '@udecode/plate-heading/react';\nimport { HighlightPlugin } from '@udecode/plate-highlight/react';\nimport { HorizontalRulePlugin } from '@udecode/plate-horizontal-rule/react';\nimport { IndentPlugin } from '@udecode/plate-indent/react';\nimport { IndentListPlugin } from '@udecode/plate-indent-list/react';\nimport { JuicePlugin } from '@udecode/plate-juice';\nimport { KbdPlugin } from '@udecode/plate-kbd/react';\nimport { ColumnPlugin } from '@udecode/plate-layout/react';\nimport { LineHeightPlugin } from '@udecode/plate-line-height/react';\nimport { LinkPlugin } from '@udecode/plate-link/react';\nimport { ListPlugin, TodoListPlugin } from '@udecode/plate-list/react';\nimport { MarkdownPlugin } from '@udecode/plate-markdown';\nimport { ImagePlugin, MediaEmbedPlugin } from '@udecode/plate-media/react';\nimport { MentionPlugin } from '@udecode/plate-mention/react';\nimport { NodeIdPlugin } from '@udecode/plate-node-id';\nimport { NormalizeTypesPlugin } from '@udecode/plate-normalizers';\nimport { PlaywrightPlugin } from '@udecode/plate-playwright';\nimport { DeletePlugin, SelectOnBackspacePlugin } from '@udecode/plate-select';\nimport {\n BlockMenuPlugin,\n BlockSelectionPlugin,\n} from '@udecode/plate-selection/react';\nimport { SlashPlugin } from '@udecode/plate-slash-command/react';\nimport { TablePlugin } from '@udecode/plate-table/react';\nimport { TogglePlugin } from '@udecode/plate-toggle/react';\nimport { TrailingBlockPlugin } from '@udecode/plate-trailing-block';\nimport Prism from 'prismjs';\n\nimport { CheckPlugin } from '@/components/context/check-plugin';\nimport { settingsStore } from '@/components/context/settings-store';\nimport { aiPlugins } from '@/lib/plate/demo/plugins/ai-plugins';\nimport { getAutoformatOptions } from '@/lib/plate/demo/plugins/autoformatOptions';\nimport { copilotPlugins } from '@/lib/plate/demo/plugins/copilot-plugins';\nimport { createPlateUI } from '@/plate/create-plate-ui';\nimport { editableProps } from '@/plate/demo/editableProps';\nimport { isEnabled } from '@/plate/demo/is-enabled';\nimport { DragOverCursorPlugin } from '@/plate/demo/plugins/DragOverCursorPlugin';\nimport { exitBreakPlugin } from '@/plate/demo/plugins/exitBreakPlugin';\nimport { resetBlockTypePlugin } from '@/plate/demo/plugins/resetBlockTypePlugin';\nimport { softBreakPlugin } from '@/plate/demo/plugins/softBreakPlugin';\nimport { tabbablePlugin } from '@/plate/demo/plugins/tabbablePlugin';\nimport { commentsData, usersData } from '@/plate/demo/values/commentsValue';\nimport { usePlaygroundValue } from '@/plate/demo/values/usePlaygroundValue';\nimport { BlockContextMenu } from '@/components/plate-ui/block-context-menu';\nimport { CommentsPopover } from '@/components/plate-ui/comments-popover';\nimport {\n CursorOverlay,\n SelectionOverlayPlugin,\n} from '@/components/plate-ui/cursor-overlay';\nimport { Editor, EditorContainer } from '@/components/plate-ui/editor';\nimport { FixedToolbar } from '@/components/plate-ui/fixed-toolbar';\nimport { FixedToolbarButtons } from '@/components/plate-ui/fixed-toolbar-buttons';\nimport { FloatingToolbar } from '@/components/plate-ui/floating-toolbar';\nimport { FloatingToolbarButtons } from '@/components/plate-ui/floating-toolbar-buttons';\nimport { ImagePreview } from '@/components/plate-ui/image-preview';\nimport {\n FireLiComponent,\n FireMarker,\n} from '@/components/plate-ui/indent-fire-marker';\nimport {\n TodoLi,\n TodoMarker,\n} from '@/components/plate-ui/indent-todo-marker';\nimport { LinkFloatingToolbar } from '@/components/plate-ui/link-floating-toolbar';\n\nimport { usePlaygroundEnabled } from './usePlaygroundEnabled';\n\nexport const usePlaygroundEditor = (id: any = '', scrollSelector?: string) => {\n const enabledPlugins = settingsStore.use.checkedPlugins();\n const overridePlugins = usePlaygroundEnabled(id);\n const autoformatOptions = getAutoformatOptions(id, enabledPlugins);\n\n const value = usePlaygroundValue(id);\n const key = settingsStore.use.version();\n const editorId = id || 'playground-' + key;\n\n return usePlateEditor(\n {\n id: editorId,\n override: {\n components: createPlateUI({\n draggable: isEnabled('dnd', id),\n placeholder: isEnabled('placeholder', id),\n }),\n plugins: overridePlugins,\n },\n plugins: [\n // AI\n ...(id === 'ai' || enabledPlugins[AIChatPlugin.key] ? aiPlugins : []),\n ...(id === 'copilot' || enabledPlugins[CopilotPlugin.key]\n ? copilotPlugins\n : []),\n // Nodes\n HeadingPlugin,\n TocPlugin.configure({\n options: {\n scrollContainerSelector: `#${scrollSelector}`,\n topOffset: 80,\n },\n }),\n BlockquotePlugin,\n CodeBlockPlugin.configure({\n options: {\n prism: Prism,\n },\n }),\n HorizontalRulePlugin,\n LinkPlugin.extend({\n render: { afterEditable: () => },\n }),\n ...(id === 'list' ? [ListPlugin] : []),\n ImagePlugin.extend({\n options: {\n disableUploadInsert: true,\n },\n render: { afterEditable: ImagePreview },\n }),\n MediaEmbedPlugin,\n CaptionPlugin.configure({\n options: {\n plugins: [ImagePlugin, MediaEmbedPlugin],\n },\n }),\n DatePlugin,\n MentionPlugin.configure({\n options: {\n triggerPreviousCharPattern: /^$|^[\\s\"']$/,\n },\n }),\n SlashPlugin,\n TablePlugin.configure({\n options: {\n enableMerging: id === 'tableMerge',\n },\n }),\n ColumnPlugin,\n SelectionOverlayPlugin,\n\n TodoListPlugin,\n TogglePlugin,\n ExcalidrawPlugin,\n // Marks\n BoldPlugin,\n ItalicPlugin,\n UnderlinePlugin,\n StrikethroughPlugin,\n CodePlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n FontColorPlugin,\n FontBackgroundColorPlugin,\n FontSizePlugin,\n HighlightPlugin,\n KbdPlugin,\n\n // Block Style\n AlignPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n MediaEmbedPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n ImagePlugin.key,\n HEADING_KEYS.h6,\n ],\n },\n }),\n IndentPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n }),\n IndentListPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n options: {\n listStyleTypes: {\n fire: {\n liComponent: FireLiComponent,\n markerComponent: FireMarker,\n type: 'fire',\n },\n todo: {\n liComponent: TodoLi,\n markerComponent: TodoMarker,\n type: 'todo',\n },\n },\n },\n }),\n LineHeightPlugin.extend({\n inject: {\n nodeProps: {\n defaultNodeValue: 1.5,\n validNodeValues: [1, 1.2, 1.5, 2, 3],\n },\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n ],\n },\n }),\n\n // Functionality\n AutoformatPlugin.configure({\n options: autoformatOptions,\n }),\n BlockSelectionPlugin.configure({\n options: {\n areaOptions: {\n behaviour: {\n scrolling: {\n speedDivider: 1.5,\n },\n startThreshold: 10,\n },\n boundaries: `#${scrollSelector}`,\n container: `#${scrollSelector}`,\n selectables: [`#${scrollSelector} .slate-selectable`],\n selectionAreaClass: 'slate-selection-area',\n },\n enableContextMenu: true,\n },\n }),\n BlockMenuPlugin.configure({\n render: { aboveEditable: BlockContextMenu },\n }),\n DndPlugin.configure({\n options: {\n enableScroller: true,\n onDropFiles: ({ dragItem, editor, target }) => {\n editor\n .getTransforms(ImagePlugin)\n .insertImageFromFiles(dragItem.files, {\n at: target,\n nextBlock: false,\n });\n },\n },\n }),\n EmojiPlugin,\n exitBreakPlugin,\n NodeIdPlugin,\n NormalizeTypesPlugin.configure({\n options: {\n rules: [{ path: [0], strictType: HEADING_KEYS.h1 }],\n },\n }),\n resetBlockTypePlugin,\n SelectOnBackspacePlugin.configure({\n options: {\n query: {\n allow: [ImagePlugin.key, HorizontalRulePlugin.key],\n },\n },\n }),\n DeletePlugin,\n SingleLinePlugin,\n softBreakPlugin,\n tabbablePlugin,\n TrailingBlockPlugin.configure({\n options: { type: ParagraphPlugin.key },\n }),\n DragOverCursorPlugin,\n\n // Collaboration\n CommentsPlugin.configure({\n options: {\n comments: commentsData,\n myUserId: '1',\n users: usersData,\n },\n }),\n\n // Deserialization\n DocxPlugin,\n MarkdownPlugin.configure({ options: { indentList: true } }),\n JuicePlugin,\n\n // Testing\n PlaywrightPlugin.configure({\n enabled: process.env.NODE_ENV !== 'production',\n }),\n ],\n value: value,\n },\n []\n );\n};\n\nexport default function PlaygroundDemo({\n id,\n className,\n scrollSelector,\n}: {\n id?: ValueId;\n className?: string;\n scrollSelector?: string;\n}) {\n const containerRef = useRef(null);\n const enabled = settingsStore.use.checkedComponents();\n\n const editor = usePlaygroundEditor(\n id,\n scrollSelector ?? `blockSelection-${id}`\n );\n\n return (\n \n \n \n \n \n \n \n \n \n\n
\n \n \n\n \n \n \n \n \n \n \n\n \n \n \n \n\n \n \n \n
\n
\n
\n );\n}\n\nconst DemoIdContext = React.createContext(undefined);\n\nexport function DemoId({\n id,\n children,\n}: {\n children: React.ReactNode;\n id?: string;\n}) {\n return {children};\n}\n\nexport function useDemoId() {\n return React.useContext(DemoIdContext);\n}\n", "path": "example/playground-demo.tsx", "target": "components/playground-demo.tsx", "type": "registry:example" diff --git a/apps/www/public/r/styles/default/media-demo.json b/apps/www/public/r/styles/default/media-demo.json index 11a91dbbe7..0c13504d57 100644 --- a/apps/www/public/r/styles/default/media-demo.json +++ b/apps/www/public/r/styles/default/media-demo.json @@ -4,7 +4,7 @@ }, "files": [ { - "content": "'use client';\n\nimport React, { useRef } from 'react';\n\nimport type { ValueId } from '@/config/customizer-plugins';\n\nimport { cn } from '@udecode/cn';\nimport { AIChatPlugin, CopilotPlugin } from '@udecode/plate-ai/react';\nimport { AlignPlugin } from '@udecode/plate-alignment/react';\nimport { AutoformatPlugin } from '@udecode/plate-autoformat/react';\nimport {\n BoldPlugin,\n CodePlugin,\n ItalicPlugin,\n StrikethroughPlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n UnderlinePlugin,\n} from '@udecode/plate-basic-marks/react';\nimport { BlockquotePlugin } from '@udecode/plate-block-quote/react';\nimport { SingleLinePlugin } from '@udecode/plate-break/react';\nimport { CaptionPlugin } from '@udecode/plate-caption/react';\nimport { CodeBlockPlugin } from '@udecode/plate-code-block/react';\nimport { CommentsPlugin } from '@udecode/plate-comments/react';\nimport {\n ParagraphPlugin,\n Plate,\n usePlateEditor,\n} from '@udecode/plate-common/react';\nimport { DatePlugin } from '@udecode/plate-date/react';\nimport { DndPlugin } from '@udecode/plate-dnd';\nimport { DocxPlugin } from '@udecode/plate-docx';\nimport { EmojiPlugin } from '@udecode/plate-emoji/react';\nimport { ExcalidrawPlugin } from '@udecode/plate-excalidraw/react';\nimport {\n FontBackgroundColorPlugin,\n FontColorPlugin,\n FontSizePlugin,\n} from '@udecode/plate-font/react';\nimport { HEADING_KEYS } from '@udecode/plate-heading';\nimport { HeadingPlugin, TocPlugin } from '@udecode/plate-heading/react';\nimport { HighlightPlugin } from '@udecode/plate-highlight/react';\nimport { HorizontalRulePlugin } from '@udecode/plate-horizontal-rule/react';\nimport { IndentPlugin } from '@udecode/plate-indent/react';\nimport { IndentListPlugin } from '@udecode/plate-indent-list/react';\nimport { JuicePlugin } from '@udecode/plate-juice';\nimport { KbdPlugin } from '@udecode/plate-kbd/react';\nimport { ColumnPlugin } from '@udecode/plate-layout/react';\nimport { LineHeightPlugin } from '@udecode/plate-line-height/react';\nimport { LinkPlugin } from '@udecode/plate-link/react';\nimport { ListPlugin, TodoListPlugin } from '@udecode/plate-list/react';\nimport { MarkdownPlugin } from '@udecode/plate-markdown';\nimport { ImagePlugin, MediaEmbedPlugin } from '@udecode/plate-media/react';\nimport { MentionPlugin } from '@udecode/plate-mention/react';\nimport { NodeIdPlugin } from '@udecode/plate-node-id';\nimport { NormalizeTypesPlugin } from '@udecode/plate-normalizers';\nimport { PlaywrightPlugin } from '@udecode/plate-playwright';\nimport { DeletePlugin, SelectOnBackspacePlugin } from '@udecode/plate-select';\nimport {\n BlockMenuPlugin,\n BlockSelectionPlugin,\n} from '@udecode/plate-selection/react';\nimport { SlashPlugin } from '@udecode/plate-slash-command/react';\nimport { TablePlugin } from '@udecode/plate-table/react';\nimport { TogglePlugin } from '@udecode/plate-toggle/react';\nimport { TrailingBlockPlugin } from '@udecode/plate-trailing-block';\nimport Prism from 'prismjs';\n\nimport { CheckPlugin } from '@/components/context/check-plugin';\nimport { settingsStore } from '@/components/context/settings-store';\nimport { aiPlugins } from '@/lib/plate/demo/plugins/ai-plugins';\nimport { getAutoformatOptions } from '@/lib/plate/demo/plugins/autoformatOptions';\nimport { copilotPlugins } from '@/lib/plate/demo/plugins/copilot-plugins';\nimport { createPlateUI } from '@/plate/create-plate-ui';\nimport { editableProps } from '@/plate/demo/editableProps';\nimport { isEnabled } from '@/plate/demo/is-enabled';\nimport { DragOverCursorPlugin } from '@/plate/demo/plugins/DragOverCursorPlugin';\nimport { exitBreakPlugin } from '@/plate/demo/plugins/exitBreakPlugin';\nimport { resetBlockTypePlugin } from '@/plate/demo/plugins/resetBlockTypePlugin';\nimport { softBreakPlugin } from '@/plate/demo/plugins/softBreakPlugin';\nimport { tabbablePlugin } from '@/plate/demo/plugins/tabbablePlugin';\nimport { commentsData, usersData } from '@/plate/demo/values/commentsValue';\nimport { usePlaygroundValue } from '@/plate/demo/values/usePlaygroundValue';\nimport { BlockContextMenu } from '@/components/plate-ui/block-context-menu';\nimport { CommentsPopover } from '@/components/plate-ui/comments-popover';\nimport {\n CursorOverlay,\n SelectionOverlayPlugin,\n} from '@/components/plate-ui/cursor-overlay';\nimport { Editor, EditorContainer } from '@/components/plate-ui/editor';\nimport { FixedToolbar } from '@/components/plate-ui/fixed-toolbar';\nimport { FixedToolbarButtons } from '@/components/plate-ui/fixed-toolbar-buttons';\nimport { FloatingToolbar } from '@/components/plate-ui/floating-toolbar';\nimport { FloatingToolbarButtons } from '@/components/plate-ui/floating-toolbar-buttons';\nimport { ImagePreview } from '@/components/plate-ui/image-preview';\nimport {\n FireLiComponent,\n FireMarker,\n} from '@/components/plate-ui/indent-fire-marker';\nimport {\n TodoLi,\n TodoMarker,\n} from '@/components/plate-ui/indent-todo-marker';\nimport { LinkFloatingToolbar } from '@/components/plate-ui/link-floating-toolbar';\n\nimport { usePlaygroundEnabled } from './usePlaygroundEnabled';\n\nexport const usePlaygroundEditor = (id: any = '', scrollSelector?: string) => {\n const enabledPlugins = settingsStore.use.checkedPlugins();\n const overridePlugins = usePlaygroundEnabled(id);\n const autoformatOptions = getAutoformatOptions(id, enabledPlugins);\n\n const value = usePlaygroundValue(id);\n const key = settingsStore.use.version();\n const editorId = id || 'playground-' + key;\n\n return usePlateEditor(\n {\n id: editorId,\n override: {\n components: createPlateUI({\n draggable: isEnabled('dnd', id),\n placeholder: isEnabled('placeholder', id),\n }),\n plugins: overridePlugins,\n },\n plugins: [\n // AI\n ...(id === 'ai' || enabledPlugins[AIChatPlugin.key] ? aiPlugins : []),\n ...(id === 'copilot' || enabledPlugins[CopilotPlugin.key]\n ? copilotPlugins\n : []),\n // Nodes\n HeadingPlugin,\n TocPlugin.configure({\n options: {\n scrollContainerSelector: `#${scrollSelector}`,\n topOffset: 80,\n },\n }),\n BlockquotePlugin,\n CodeBlockPlugin.configure({\n options: {\n prism: Prism,\n },\n }),\n HorizontalRulePlugin,\n LinkPlugin.extend({\n render: { afterEditable: () => },\n }),\n ...(id === 'list' ? [ListPlugin] : []),\n ImagePlugin.extend({\n render: { afterEditable: ImagePreview },\n }),\n MediaEmbedPlugin,\n CaptionPlugin.configure({\n options: {\n plugins: [ImagePlugin, MediaEmbedPlugin],\n },\n }),\n DatePlugin,\n MentionPlugin.configure({\n options: {\n triggerPreviousCharPattern: /^$|^[\\s\"']$/,\n },\n }),\n SlashPlugin,\n TablePlugin.configure({\n options: {\n enableMerging: id === 'tableMerge',\n },\n }),\n ColumnPlugin,\n SelectionOverlayPlugin,\n\n TodoListPlugin,\n TogglePlugin,\n ExcalidrawPlugin,\n // Marks\n BoldPlugin,\n ItalicPlugin,\n UnderlinePlugin,\n StrikethroughPlugin,\n CodePlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n FontColorPlugin,\n FontBackgroundColorPlugin,\n FontSizePlugin,\n HighlightPlugin,\n KbdPlugin,\n\n // Block Style\n AlignPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n MediaEmbedPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n ImagePlugin.key,\n HEADING_KEYS.h6,\n ],\n },\n }),\n IndentPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n }),\n IndentListPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n options: {\n listStyleTypes: {\n fire: {\n liComponent: FireLiComponent,\n markerComponent: FireMarker,\n type: 'fire',\n },\n todo: {\n liComponent: TodoLi,\n markerComponent: TodoMarker,\n type: 'todo',\n },\n },\n },\n }),\n LineHeightPlugin.extend({\n inject: {\n nodeProps: {\n defaultNodeValue: 1.5,\n validNodeValues: [1, 1.2, 1.5, 2, 3],\n },\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n ],\n },\n }),\n\n // Functionality\n AutoformatPlugin.configure({\n options: autoformatOptions,\n }),\n BlockSelectionPlugin.configure({\n options: {\n areaOptions: {\n behaviour: {\n scrolling: {\n speedDivider: 1.5,\n },\n startThreshold: 10,\n },\n boundaries: `#${scrollSelector}`,\n container: `#${scrollSelector}`,\n selectables: [`#${scrollSelector} .slate-selectable`],\n selectionAreaClass: 'slate-selection-area',\n },\n enableContextMenu: true,\n },\n }),\n BlockMenuPlugin.configure({\n render: { aboveEditable: BlockContextMenu },\n }),\n DndPlugin.configure({ options: { enableScroller: true } }),\n EmojiPlugin,\n exitBreakPlugin,\n NodeIdPlugin,\n NormalizeTypesPlugin.configure({\n options: {\n rules: [{ path: [0], strictType: HEADING_KEYS.h1 }],\n },\n }),\n resetBlockTypePlugin,\n SelectOnBackspacePlugin.configure({\n options: {\n query: {\n allow: [ImagePlugin.key, HorizontalRulePlugin.key],\n },\n },\n }),\n DeletePlugin,\n SingleLinePlugin,\n softBreakPlugin,\n tabbablePlugin,\n TrailingBlockPlugin.configure({\n options: { type: ParagraphPlugin.key },\n }),\n DragOverCursorPlugin,\n\n // Collaboration\n CommentsPlugin.configure({\n options: {\n comments: commentsData,\n myUserId: '1',\n users: usersData,\n },\n }),\n\n // Deserialization\n DocxPlugin,\n MarkdownPlugin.configure({ options: { indentList: true } }),\n JuicePlugin,\n\n // Testing\n PlaywrightPlugin.configure({\n enabled: process.env.NODE_ENV !== 'production',\n }),\n ],\n value: value,\n },\n []\n );\n};\n\nexport default function PlaygroundDemo({\n id,\n className,\n scrollSelector,\n}: {\n id?: ValueId;\n className?: string;\n scrollSelector?: string;\n}) {\n const containerRef = useRef(null);\n const enabled = settingsStore.use.checkedComponents();\n\n const editor = usePlaygroundEditor(\n id,\n scrollSelector ?? `blockSelection-${id}`\n );\n\n return (\n \n \n \n \n \n \n \n \n \n\n
\n \n \n\n \n \n \n \n \n \n \n\n \n \n \n \n\n \n \n \n
\n
\n
\n );\n}\n\nconst DemoIdContext = React.createContext(undefined);\n\nexport function DemoId({\n id,\n children,\n}: {\n children: React.ReactNode;\n id?: string;\n}) {\n return {children};\n}\n\nexport function useDemoId() {\n return React.useContext(DemoIdContext);\n}\n", + "content": "'use client';\n\nimport React, { useRef } from 'react';\n\nimport type { ValueId } from '@/config/customizer-plugins';\n\nimport { cn } from '@udecode/cn';\nimport { AIChatPlugin, CopilotPlugin } from '@udecode/plate-ai/react';\nimport { AlignPlugin } from '@udecode/plate-alignment/react';\nimport { AutoformatPlugin } from '@udecode/plate-autoformat/react';\nimport {\n BoldPlugin,\n CodePlugin,\n ItalicPlugin,\n StrikethroughPlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n UnderlinePlugin,\n} from '@udecode/plate-basic-marks/react';\nimport { BlockquotePlugin } from '@udecode/plate-block-quote/react';\nimport { SingleLinePlugin } from '@udecode/plate-break/react';\nimport { CaptionPlugin } from '@udecode/plate-caption/react';\nimport { CodeBlockPlugin } from '@udecode/plate-code-block/react';\nimport { CommentsPlugin } from '@udecode/plate-comments/react';\nimport {\n ParagraphPlugin,\n Plate,\n usePlateEditor,\n} from '@udecode/plate-common/react';\nimport { DatePlugin } from '@udecode/plate-date/react';\nimport { DndPlugin } from '@udecode/plate-dnd';\nimport { DocxPlugin } from '@udecode/plate-docx';\nimport { EmojiPlugin } from '@udecode/plate-emoji/react';\nimport { ExcalidrawPlugin } from '@udecode/plate-excalidraw/react';\nimport {\n FontBackgroundColorPlugin,\n FontColorPlugin,\n FontSizePlugin,\n} from '@udecode/plate-font/react';\nimport { HEADING_KEYS } from '@udecode/plate-heading';\nimport { HeadingPlugin, TocPlugin } from '@udecode/plate-heading/react';\nimport { HighlightPlugin } from '@udecode/plate-highlight/react';\nimport { HorizontalRulePlugin } from '@udecode/plate-horizontal-rule/react';\nimport { IndentPlugin } from '@udecode/plate-indent/react';\nimport { IndentListPlugin } from '@udecode/plate-indent-list/react';\nimport { JuicePlugin } from '@udecode/plate-juice';\nimport { KbdPlugin } from '@udecode/plate-kbd/react';\nimport { ColumnPlugin } from '@udecode/plate-layout/react';\nimport { LineHeightPlugin } from '@udecode/plate-line-height/react';\nimport { LinkPlugin } from '@udecode/plate-link/react';\nimport { ListPlugin, TodoListPlugin } from '@udecode/plate-list/react';\nimport { MarkdownPlugin } from '@udecode/plate-markdown';\nimport { ImagePlugin, MediaEmbedPlugin } from '@udecode/plate-media/react';\nimport { MentionPlugin } from '@udecode/plate-mention/react';\nimport { NodeIdPlugin } from '@udecode/plate-node-id';\nimport { NormalizeTypesPlugin } from '@udecode/plate-normalizers';\nimport { PlaywrightPlugin } from '@udecode/plate-playwright';\nimport { DeletePlugin, SelectOnBackspacePlugin } from '@udecode/plate-select';\nimport {\n BlockMenuPlugin,\n BlockSelectionPlugin,\n} from '@udecode/plate-selection/react';\nimport { SlashPlugin } from '@udecode/plate-slash-command/react';\nimport { TablePlugin } from '@udecode/plate-table/react';\nimport { TogglePlugin } from '@udecode/plate-toggle/react';\nimport { TrailingBlockPlugin } from '@udecode/plate-trailing-block';\nimport Prism from 'prismjs';\n\nimport { CheckPlugin } from '@/components/context/check-plugin';\nimport { settingsStore } from '@/components/context/settings-store';\nimport { aiPlugins } from '@/lib/plate/demo/plugins/ai-plugins';\nimport { getAutoformatOptions } from '@/lib/plate/demo/plugins/autoformatOptions';\nimport { copilotPlugins } from '@/lib/plate/demo/plugins/copilot-plugins';\nimport { createPlateUI } from '@/plate/create-plate-ui';\nimport { editableProps } from '@/plate/demo/editableProps';\nimport { isEnabled } from '@/plate/demo/is-enabled';\nimport { DragOverCursorPlugin } from '@/plate/demo/plugins/DragOverCursorPlugin';\nimport { exitBreakPlugin } from '@/plate/demo/plugins/exitBreakPlugin';\nimport { resetBlockTypePlugin } from '@/plate/demo/plugins/resetBlockTypePlugin';\nimport { softBreakPlugin } from '@/plate/demo/plugins/softBreakPlugin';\nimport { tabbablePlugin } from '@/plate/demo/plugins/tabbablePlugin';\nimport { commentsData, usersData } from '@/plate/demo/values/commentsValue';\nimport { usePlaygroundValue } from '@/plate/demo/values/usePlaygroundValue';\nimport { BlockContextMenu } from '@/components/plate-ui/block-context-menu';\nimport { CommentsPopover } from '@/components/plate-ui/comments-popover';\nimport {\n CursorOverlay,\n SelectionOverlayPlugin,\n} from '@/components/plate-ui/cursor-overlay';\nimport { Editor, EditorContainer } from '@/components/plate-ui/editor';\nimport { FixedToolbar } from '@/components/plate-ui/fixed-toolbar';\nimport { FixedToolbarButtons } from '@/components/plate-ui/fixed-toolbar-buttons';\nimport { FloatingToolbar } from '@/components/plate-ui/floating-toolbar';\nimport { FloatingToolbarButtons } from '@/components/plate-ui/floating-toolbar-buttons';\nimport { ImagePreview } from '@/components/plate-ui/image-preview';\nimport {\n FireLiComponent,\n FireMarker,\n} from '@/components/plate-ui/indent-fire-marker';\nimport {\n TodoLi,\n TodoMarker,\n} from '@/components/plate-ui/indent-todo-marker';\nimport { LinkFloatingToolbar } from '@/components/plate-ui/link-floating-toolbar';\n\nimport { usePlaygroundEnabled } from './usePlaygroundEnabled';\n\nexport const usePlaygroundEditor = (id: any = '', scrollSelector?: string) => {\n const enabledPlugins = settingsStore.use.checkedPlugins();\n const overridePlugins = usePlaygroundEnabled(id);\n const autoformatOptions = getAutoformatOptions(id, enabledPlugins);\n\n const value = usePlaygroundValue(id);\n const key = settingsStore.use.version();\n const editorId = id || 'playground-' + key;\n\n return usePlateEditor(\n {\n id: editorId,\n override: {\n components: createPlateUI({\n draggable: isEnabled('dnd', id),\n placeholder: isEnabled('placeholder', id),\n }),\n plugins: overridePlugins,\n },\n plugins: [\n // AI\n ...(id === 'ai' || enabledPlugins[AIChatPlugin.key] ? aiPlugins : []),\n ...(id === 'copilot' || enabledPlugins[CopilotPlugin.key]\n ? copilotPlugins\n : []),\n // Nodes\n HeadingPlugin,\n TocPlugin.configure({\n options: {\n scrollContainerSelector: `#${scrollSelector}`,\n topOffset: 80,\n },\n }),\n BlockquotePlugin,\n CodeBlockPlugin.configure({\n options: {\n prism: Prism,\n },\n }),\n HorizontalRulePlugin,\n LinkPlugin.extend({\n render: { afterEditable: () => },\n }),\n ...(id === 'list' ? [ListPlugin] : []),\n ImagePlugin.extend({\n options: {\n disableUploadInsert: true,\n },\n render: { afterEditable: ImagePreview },\n }),\n MediaEmbedPlugin,\n CaptionPlugin.configure({\n options: {\n plugins: [ImagePlugin, MediaEmbedPlugin],\n },\n }),\n DatePlugin,\n MentionPlugin.configure({\n options: {\n triggerPreviousCharPattern: /^$|^[\\s\"']$/,\n },\n }),\n SlashPlugin,\n TablePlugin.configure({\n options: {\n enableMerging: id === 'tableMerge',\n },\n }),\n ColumnPlugin,\n SelectionOverlayPlugin,\n\n TodoListPlugin,\n TogglePlugin,\n ExcalidrawPlugin,\n // Marks\n BoldPlugin,\n ItalicPlugin,\n UnderlinePlugin,\n StrikethroughPlugin,\n CodePlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n FontColorPlugin,\n FontBackgroundColorPlugin,\n FontSizePlugin,\n HighlightPlugin,\n KbdPlugin,\n\n // Block Style\n AlignPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n MediaEmbedPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n ImagePlugin.key,\n HEADING_KEYS.h6,\n ],\n },\n }),\n IndentPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n }),\n IndentListPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n options: {\n listStyleTypes: {\n fire: {\n liComponent: FireLiComponent,\n markerComponent: FireMarker,\n type: 'fire',\n },\n todo: {\n liComponent: TodoLi,\n markerComponent: TodoMarker,\n type: 'todo',\n },\n },\n },\n }),\n LineHeightPlugin.extend({\n inject: {\n nodeProps: {\n defaultNodeValue: 1.5,\n validNodeValues: [1, 1.2, 1.5, 2, 3],\n },\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n ],\n },\n }),\n\n // Functionality\n AutoformatPlugin.configure({\n options: autoformatOptions,\n }),\n BlockSelectionPlugin.configure({\n options: {\n areaOptions: {\n behaviour: {\n scrolling: {\n speedDivider: 1.5,\n },\n startThreshold: 10,\n },\n boundaries: `#${scrollSelector}`,\n container: `#${scrollSelector}`,\n selectables: [`#${scrollSelector} .slate-selectable`],\n selectionAreaClass: 'slate-selection-area',\n },\n enableContextMenu: true,\n },\n }),\n BlockMenuPlugin.configure({\n render: { aboveEditable: BlockContextMenu },\n }),\n DndPlugin.configure({\n options: {\n enableScroller: true,\n onDropFiles: ({ dragItem, editor, target }) => {\n editor\n .getTransforms(ImagePlugin)\n .insertImageFromFiles(dragItem.files, {\n at: target,\n nextBlock: false,\n });\n },\n },\n }),\n EmojiPlugin,\n exitBreakPlugin,\n NodeIdPlugin,\n NormalizeTypesPlugin.configure({\n options: {\n rules: [{ path: [0], strictType: HEADING_KEYS.h1 }],\n },\n }),\n resetBlockTypePlugin,\n SelectOnBackspacePlugin.configure({\n options: {\n query: {\n allow: [ImagePlugin.key, HorizontalRulePlugin.key],\n },\n },\n }),\n DeletePlugin,\n SingleLinePlugin,\n softBreakPlugin,\n tabbablePlugin,\n TrailingBlockPlugin.configure({\n options: { type: ParagraphPlugin.key },\n }),\n DragOverCursorPlugin,\n\n // Collaboration\n CommentsPlugin.configure({\n options: {\n comments: commentsData,\n myUserId: '1',\n users: usersData,\n },\n }),\n\n // Deserialization\n DocxPlugin,\n MarkdownPlugin.configure({ options: { indentList: true } }),\n JuicePlugin,\n\n // Testing\n PlaywrightPlugin.configure({\n enabled: process.env.NODE_ENV !== 'production',\n }),\n ],\n value: value,\n },\n []\n );\n};\n\nexport default function PlaygroundDemo({\n id,\n className,\n scrollSelector,\n}: {\n id?: ValueId;\n className?: string;\n scrollSelector?: string;\n}) {\n const containerRef = useRef(null);\n const enabled = settingsStore.use.checkedComponents();\n\n const editor = usePlaygroundEditor(\n id,\n scrollSelector ?? `blockSelection-${id}`\n );\n\n return (\n \n \n \n \n \n \n \n \n \n\n
\n \n \n\n \n \n \n \n \n \n \n\n \n \n \n \n\n \n \n \n
\n
\n
\n );\n}\n\nconst DemoIdContext = React.createContext(undefined);\n\nexport function DemoId({\n id,\n children,\n}: {\n children: React.ReactNode;\n id?: string;\n}) {\n return {children};\n}\n\nexport function useDemoId() {\n return React.useContext(DemoIdContext);\n}\n", "path": "example/playground-demo.tsx", "target": "components/playground-demo.tsx", "type": "registry:example" diff --git a/apps/www/public/r/styles/default/mention-demo.json b/apps/www/public/r/styles/default/mention-demo.json index 24c4edfa1c..4ec689b387 100644 --- a/apps/www/public/r/styles/default/mention-demo.json +++ b/apps/www/public/r/styles/default/mention-demo.json @@ -4,7 +4,7 @@ }, "files": [ { - "content": "'use client';\n\nimport React, { useRef } from 'react';\n\nimport type { ValueId } from '@/config/customizer-plugins';\n\nimport { cn } from '@udecode/cn';\nimport { AIChatPlugin, CopilotPlugin } from '@udecode/plate-ai/react';\nimport { AlignPlugin } from '@udecode/plate-alignment/react';\nimport { AutoformatPlugin } from '@udecode/plate-autoformat/react';\nimport {\n BoldPlugin,\n CodePlugin,\n ItalicPlugin,\n StrikethroughPlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n UnderlinePlugin,\n} from '@udecode/plate-basic-marks/react';\nimport { BlockquotePlugin } from '@udecode/plate-block-quote/react';\nimport { SingleLinePlugin } from '@udecode/plate-break/react';\nimport { CaptionPlugin } from '@udecode/plate-caption/react';\nimport { CodeBlockPlugin } from '@udecode/plate-code-block/react';\nimport { CommentsPlugin } from '@udecode/plate-comments/react';\nimport {\n ParagraphPlugin,\n Plate,\n usePlateEditor,\n} from '@udecode/plate-common/react';\nimport { DatePlugin } from '@udecode/plate-date/react';\nimport { DndPlugin } from '@udecode/plate-dnd';\nimport { DocxPlugin } from '@udecode/plate-docx';\nimport { EmojiPlugin } from '@udecode/plate-emoji/react';\nimport { ExcalidrawPlugin } from '@udecode/plate-excalidraw/react';\nimport {\n FontBackgroundColorPlugin,\n FontColorPlugin,\n FontSizePlugin,\n} from '@udecode/plate-font/react';\nimport { HEADING_KEYS } from '@udecode/plate-heading';\nimport { HeadingPlugin, TocPlugin } from '@udecode/plate-heading/react';\nimport { HighlightPlugin } from '@udecode/plate-highlight/react';\nimport { HorizontalRulePlugin } from '@udecode/plate-horizontal-rule/react';\nimport { IndentPlugin } from '@udecode/plate-indent/react';\nimport { IndentListPlugin } from '@udecode/plate-indent-list/react';\nimport { JuicePlugin } from '@udecode/plate-juice';\nimport { KbdPlugin } from '@udecode/plate-kbd/react';\nimport { ColumnPlugin } from '@udecode/plate-layout/react';\nimport { LineHeightPlugin } from '@udecode/plate-line-height/react';\nimport { LinkPlugin } from '@udecode/plate-link/react';\nimport { ListPlugin, TodoListPlugin } from '@udecode/plate-list/react';\nimport { MarkdownPlugin } from '@udecode/plate-markdown';\nimport { ImagePlugin, MediaEmbedPlugin } from '@udecode/plate-media/react';\nimport { MentionPlugin } from '@udecode/plate-mention/react';\nimport { NodeIdPlugin } from '@udecode/plate-node-id';\nimport { NormalizeTypesPlugin } from '@udecode/plate-normalizers';\nimport { PlaywrightPlugin } from '@udecode/plate-playwright';\nimport { DeletePlugin, SelectOnBackspacePlugin } from '@udecode/plate-select';\nimport {\n BlockMenuPlugin,\n BlockSelectionPlugin,\n} from '@udecode/plate-selection/react';\nimport { SlashPlugin } from '@udecode/plate-slash-command/react';\nimport { TablePlugin } from '@udecode/plate-table/react';\nimport { TogglePlugin } from '@udecode/plate-toggle/react';\nimport { TrailingBlockPlugin } from '@udecode/plate-trailing-block';\nimport Prism from 'prismjs';\n\nimport { CheckPlugin } from '@/components/context/check-plugin';\nimport { settingsStore } from '@/components/context/settings-store';\nimport { aiPlugins } from '@/lib/plate/demo/plugins/ai-plugins';\nimport { getAutoformatOptions } from '@/lib/plate/demo/plugins/autoformatOptions';\nimport { copilotPlugins } from '@/lib/plate/demo/plugins/copilot-plugins';\nimport { createPlateUI } from '@/plate/create-plate-ui';\nimport { editableProps } from '@/plate/demo/editableProps';\nimport { isEnabled } from '@/plate/demo/is-enabled';\nimport { DragOverCursorPlugin } from '@/plate/demo/plugins/DragOverCursorPlugin';\nimport { exitBreakPlugin } from '@/plate/demo/plugins/exitBreakPlugin';\nimport { resetBlockTypePlugin } from '@/plate/demo/plugins/resetBlockTypePlugin';\nimport { softBreakPlugin } from '@/plate/demo/plugins/softBreakPlugin';\nimport { tabbablePlugin } from '@/plate/demo/plugins/tabbablePlugin';\nimport { commentsData, usersData } from '@/plate/demo/values/commentsValue';\nimport { usePlaygroundValue } from '@/plate/demo/values/usePlaygroundValue';\nimport { BlockContextMenu } from '@/components/plate-ui/block-context-menu';\nimport { CommentsPopover } from '@/components/plate-ui/comments-popover';\nimport {\n CursorOverlay,\n SelectionOverlayPlugin,\n} from '@/components/plate-ui/cursor-overlay';\nimport { Editor, EditorContainer } from '@/components/plate-ui/editor';\nimport { FixedToolbar } from '@/components/plate-ui/fixed-toolbar';\nimport { FixedToolbarButtons } from '@/components/plate-ui/fixed-toolbar-buttons';\nimport { FloatingToolbar } from '@/components/plate-ui/floating-toolbar';\nimport { FloatingToolbarButtons } from '@/components/plate-ui/floating-toolbar-buttons';\nimport { ImagePreview } from '@/components/plate-ui/image-preview';\nimport {\n FireLiComponent,\n FireMarker,\n} from '@/components/plate-ui/indent-fire-marker';\nimport {\n TodoLi,\n TodoMarker,\n} from '@/components/plate-ui/indent-todo-marker';\nimport { LinkFloatingToolbar } from '@/components/plate-ui/link-floating-toolbar';\n\nimport { usePlaygroundEnabled } from './usePlaygroundEnabled';\n\nexport const usePlaygroundEditor = (id: any = '', scrollSelector?: string) => {\n const enabledPlugins = settingsStore.use.checkedPlugins();\n const overridePlugins = usePlaygroundEnabled(id);\n const autoformatOptions = getAutoformatOptions(id, enabledPlugins);\n\n const value = usePlaygroundValue(id);\n const key = settingsStore.use.version();\n const editorId = id || 'playground-' + key;\n\n return usePlateEditor(\n {\n id: editorId,\n override: {\n components: createPlateUI({\n draggable: isEnabled('dnd', id),\n placeholder: isEnabled('placeholder', id),\n }),\n plugins: overridePlugins,\n },\n plugins: [\n // AI\n ...(id === 'ai' || enabledPlugins[AIChatPlugin.key] ? aiPlugins : []),\n ...(id === 'copilot' || enabledPlugins[CopilotPlugin.key]\n ? copilotPlugins\n : []),\n // Nodes\n HeadingPlugin,\n TocPlugin.configure({\n options: {\n scrollContainerSelector: `#${scrollSelector}`,\n topOffset: 80,\n },\n }),\n BlockquotePlugin,\n CodeBlockPlugin.configure({\n options: {\n prism: Prism,\n },\n }),\n HorizontalRulePlugin,\n LinkPlugin.extend({\n render: { afterEditable: () => },\n }),\n ...(id === 'list' ? [ListPlugin] : []),\n ImagePlugin.extend({\n render: { afterEditable: ImagePreview },\n }),\n MediaEmbedPlugin,\n CaptionPlugin.configure({\n options: {\n plugins: [ImagePlugin, MediaEmbedPlugin],\n },\n }),\n DatePlugin,\n MentionPlugin.configure({\n options: {\n triggerPreviousCharPattern: /^$|^[\\s\"']$/,\n },\n }),\n SlashPlugin,\n TablePlugin.configure({\n options: {\n enableMerging: id === 'tableMerge',\n },\n }),\n ColumnPlugin,\n SelectionOverlayPlugin,\n\n TodoListPlugin,\n TogglePlugin,\n ExcalidrawPlugin,\n // Marks\n BoldPlugin,\n ItalicPlugin,\n UnderlinePlugin,\n StrikethroughPlugin,\n CodePlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n FontColorPlugin,\n FontBackgroundColorPlugin,\n FontSizePlugin,\n HighlightPlugin,\n KbdPlugin,\n\n // Block Style\n AlignPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n MediaEmbedPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n ImagePlugin.key,\n HEADING_KEYS.h6,\n ],\n },\n }),\n IndentPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n }),\n IndentListPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n options: {\n listStyleTypes: {\n fire: {\n liComponent: FireLiComponent,\n markerComponent: FireMarker,\n type: 'fire',\n },\n todo: {\n liComponent: TodoLi,\n markerComponent: TodoMarker,\n type: 'todo',\n },\n },\n },\n }),\n LineHeightPlugin.extend({\n inject: {\n nodeProps: {\n defaultNodeValue: 1.5,\n validNodeValues: [1, 1.2, 1.5, 2, 3],\n },\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n ],\n },\n }),\n\n // Functionality\n AutoformatPlugin.configure({\n options: autoformatOptions,\n }),\n BlockSelectionPlugin.configure({\n options: {\n areaOptions: {\n behaviour: {\n scrolling: {\n speedDivider: 1.5,\n },\n startThreshold: 10,\n },\n boundaries: `#${scrollSelector}`,\n container: `#${scrollSelector}`,\n selectables: [`#${scrollSelector} .slate-selectable`],\n selectionAreaClass: 'slate-selection-area',\n },\n enableContextMenu: true,\n },\n }),\n BlockMenuPlugin.configure({\n render: { aboveEditable: BlockContextMenu },\n }),\n DndPlugin.configure({ options: { enableScroller: true } }),\n EmojiPlugin,\n exitBreakPlugin,\n NodeIdPlugin,\n NormalizeTypesPlugin.configure({\n options: {\n rules: [{ path: [0], strictType: HEADING_KEYS.h1 }],\n },\n }),\n resetBlockTypePlugin,\n SelectOnBackspacePlugin.configure({\n options: {\n query: {\n allow: [ImagePlugin.key, HorizontalRulePlugin.key],\n },\n },\n }),\n DeletePlugin,\n SingleLinePlugin,\n softBreakPlugin,\n tabbablePlugin,\n TrailingBlockPlugin.configure({\n options: { type: ParagraphPlugin.key },\n }),\n DragOverCursorPlugin,\n\n // Collaboration\n CommentsPlugin.configure({\n options: {\n comments: commentsData,\n myUserId: '1',\n users: usersData,\n },\n }),\n\n // Deserialization\n DocxPlugin,\n MarkdownPlugin.configure({ options: { indentList: true } }),\n JuicePlugin,\n\n // Testing\n PlaywrightPlugin.configure({\n enabled: process.env.NODE_ENV !== 'production',\n }),\n ],\n value: value,\n },\n []\n );\n};\n\nexport default function PlaygroundDemo({\n id,\n className,\n scrollSelector,\n}: {\n id?: ValueId;\n className?: string;\n scrollSelector?: string;\n}) {\n const containerRef = useRef(null);\n const enabled = settingsStore.use.checkedComponents();\n\n const editor = usePlaygroundEditor(\n id,\n scrollSelector ?? `blockSelection-${id}`\n );\n\n return (\n \n \n \n \n \n \n \n \n \n\n
\n \n \n\n \n \n \n \n \n \n \n\n \n \n \n \n\n \n \n \n
\n
\n
\n );\n}\n\nconst DemoIdContext = React.createContext(undefined);\n\nexport function DemoId({\n id,\n children,\n}: {\n children: React.ReactNode;\n id?: string;\n}) {\n return {children};\n}\n\nexport function useDemoId() {\n return React.useContext(DemoIdContext);\n}\n", + "content": "'use client';\n\nimport React, { useRef } from 'react';\n\nimport type { ValueId } from '@/config/customizer-plugins';\n\nimport { cn } from '@udecode/cn';\nimport { AIChatPlugin, CopilotPlugin } from '@udecode/plate-ai/react';\nimport { AlignPlugin } from '@udecode/plate-alignment/react';\nimport { AutoformatPlugin } from '@udecode/plate-autoformat/react';\nimport {\n BoldPlugin,\n CodePlugin,\n ItalicPlugin,\n StrikethroughPlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n UnderlinePlugin,\n} from '@udecode/plate-basic-marks/react';\nimport { BlockquotePlugin } from '@udecode/plate-block-quote/react';\nimport { SingleLinePlugin } from '@udecode/plate-break/react';\nimport { CaptionPlugin } from '@udecode/plate-caption/react';\nimport { CodeBlockPlugin } from '@udecode/plate-code-block/react';\nimport { CommentsPlugin } from '@udecode/plate-comments/react';\nimport {\n ParagraphPlugin,\n Plate,\n usePlateEditor,\n} from '@udecode/plate-common/react';\nimport { DatePlugin } from '@udecode/plate-date/react';\nimport { DndPlugin } from '@udecode/plate-dnd';\nimport { DocxPlugin } from '@udecode/plate-docx';\nimport { EmojiPlugin } from '@udecode/plate-emoji/react';\nimport { ExcalidrawPlugin } from '@udecode/plate-excalidraw/react';\nimport {\n FontBackgroundColorPlugin,\n FontColorPlugin,\n FontSizePlugin,\n} from '@udecode/plate-font/react';\nimport { HEADING_KEYS } from '@udecode/plate-heading';\nimport { HeadingPlugin, TocPlugin } from '@udecode/plate-heading/react';\nimport { HighlightPlugin } from '@udecode/plate-highlight/react';\nimport { HorizontalRulePlugin } from '@udecode/plate-horizontal-rule/react';\nimport { IndentPlugin } from '@udecode/plate-indent/react';\nimport { IndentListPlugin } from '@udecode/plate-indent-list/react';\nimport { JuicePlugin } from '@udecode/plate-juice';\nimport { KbdPlugin } from '@udecode/plate-kbd/react';\nimport { ColumnPlugin } from '@udecode/plate-layout/react';\nimport { LineHeightPlugin } from '@udecode/plate-line-height/react';\nimport { LinkPlugin } from '@udecode/plate-link/react';\nimport { ListPlugin, TodoListPlugin } from '@udecode/plate-list/react';\nimport { MarkdownPlugin } from '@udecode/plate-markdown';\nimport { ImagePlugin, MediaEmbedPlugin } from '@udecode/plate-media/react';\nimport { MentionPlugin } from '@udecode/plate-mention/react';\nimport { NodeIdPlugin } from '@udecode/plate-node-id';\nimport { NormalizeTypesPlugin } from '@udecode/plate-normalizers';\nimport { PlaywrightPlugin } from '@udecode/plate-playwright';\nimport { DeletePlugin, SelectOnBackspacePlugin } from '@udecode/plate-select';\nimport {\n BlockMenuPlugin,\n BlockSelectionPlugin,\n} from '@udecode/plate-selection/react';\nimport { SlashPlugin } from '@udecode/plate-slash-command/react';\nimport { TablePlugin } from '@udecode/plate-table/react';\nimport { TogglePlugin } from '@udecode/plate-toggle/react';\nimport { TrailingBlockPlugin } from '@udecode/plate-trailing-block';\nimport Prism from 'prismjs';\n\nimport { CheckPlugin } from '@/components/context/check-plugin';\nimport { settingsStore } from '@/components/context/settings-store';\nimport { aiPlugins } from '@/lib/plate/demo/plugins/ai-plugins';\nimport { getAutoformatOptions } from '@/lib/plate/demo/plugins/autoformatOptions';\nimport { copilotPlugins } from '@/lib/plate/demo/plugins/copilot-plugins';\nimport { createPlateUI } from '@/plate/create-plate-ui';\nimport { editableProps } from '@/plate/demo/editableProps';\nimport { isEnabled } from '@/plate/demo/is-enabled';\nimport { DragOverCursorPlugin } from '@/plate/demo/plugins/DragOverCursorPlugin';\nimport { exitBreakPlugin } from '@/plate/demo/plugins/exitBreakPlugin';\nimport { resetBlockTypePlugin } from '@/plate/demo/plugins/resetBlockTypePlugin';\nimport { softBreakPlugin } from '@/plate/demo/plugins/softBreakPlugin';\nimport { tabbablePlugin } from '@/plate/demo/plugins/tabbablePlugin';\nimport { commentsData, usersData } from '@/plate/demo/values/commentsValue';\nimport { usePlaygroundValue } from '@/plate/demo/values/usePlaygroundValue';\nimport { BlockContextMenu } from '@/components/plate-ui/block-context-menu';\nimport { CommentsPopover } from '@/components/plate-ui/comments-popover';\nimport {\n CursorOverlay,\n SelectionOverlayPlugin,\n} from '@/components/plate-ui/cursor-overlay';\nimport { Editor, EditorContainer } from '@/components/plate-ui/editor';\nimport { FixedToolbar } from '@/components/plate-ui/fixed-toolbar';\nimport { FixedToolbarButtons } from '@/components/plate-ui/fixed-toolbar-buttons';\nimport { FloatingToolbar } from '@/components/plate-ui/floating-toolbar';\nimport { FloatingToolbarButtons } from '@/components/plate-ui/floating-toolbar-buttons';\nimport { ImagePreview } from '@/components/plate-ui/image-preview';\nimport {\n FireLiComponent,\n FireMarker,\n} from '@/components/plate-ui/indent-fire-marker';\nimport {\n TodoLi,\n TodoMarker,\n} from '@/components/plate-ui/indent-todo-marker';\nimport { LinkFloatingToolbar } from '@/components/plate-ui/link-floating-toolbar';\n\nimport { usePlaygroundEnabled } from './usePlaygroundEnabled';\n\nexport const usePlaygroundEditor = (id: any = '', scrollSelector?: string) => {\n const enabledPlugins = settingsStore.use.checkedPlugins();\n const overridePlugins = usePlaygroundEnabled(id);\n const autoformatOptions = getAutoformatOptions(id, enabledPlugins);\n\n const value = usePlaygroundValue(id);\n const key = settingsStore.use.version();\n const editorId = id || 'playground-' + key;\n\n return usePlateEditor(\n {\n id: editorId,\n override: {\n components: createPlateUI({\n draggable: isEnabled('dnd', id),\n placeholder: isEnabled('placeholder', id),\n }),\n plugins: overridePlugins,\n },\n plugins: [\n // AI\n ...(id === 'ai' || enabledPlugins[AIChatPlugin.key] ? aiPlugins : []),\n ...(id === 'copilot' || enabledPlugins[CopilotPlugin.key]\n ? copilotPlugins\n : []),\n // Nodes\n HeadingPlugin,\n TocPlugin.configure({\n options: {\n scrollContainerSelector: `#${scrollSelector}`,\n topOffset: 80,\n },\n }),\n BlockquotePlugin,\n CodeBlockPlugin.configure({\n options: {\n prism: Prism,\n },\n }),\n HorizontalRulePlugin,\n LinkPlugin.extend({\n render: { afterEditable: () => },\n }),\n ...(id === 'list' ? [ListPlugin] : []),\n ImagePlugin.extend({\n options: {\n disableUploadInsert: true,\n },\n render: { afterEditable: ImagePreview },\n }),\n MediaEmbedPlugin,\n CaptionPlugin.configure({\n options: {\n plugins: [ImagePlugin, MediaEmbedPlugin],\n },\n }),\n DatePlugin,\n MentionPlugin.configure({\n options: {\n triggerPreviousCharPattern: /^$|^[\\s\"']$/,\n },\n }),\n SlashPlugin,\n TablePlugin.configure({\n options: {\n enableMerging: id === 'tableMerge',\n },\n }),\n ColumnPlugin,\n SelectionOverlayPlugin,\n\n TodoListPlugin,\n TogglePlugin,\n ExcalidrawPlugin,\n // Marks\n BoldPlugin,\n ItalicPlugin,\n UnderlinePlugin,\n StrikethroughPlugin,\n CodePlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n FontColorPlugin,\n FontBackgroundColorPlugin,\n FontSizePlugin,\n HighlightPlugin,\n KbdPlugin,\n\n // Block Style\n AlignPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n MediaEmbedPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n ImagePlugin.key,\n HEADING_KEYS.h6,\n ],\n },\n }),\n IndentPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n }),\n IndentListPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n options: {\n listStyleTypes: {\n fire: {\n liComponent: FireLiComponent,\n markerComponent: FireMarker,\n type: 'fire',\n },\n todo: {\n liComponent: TodoLi,\n markerComponent: TodoMarker,\n type: 'todo',\n },\n },\n },\n }),\n LineHeightPlugin.extend({\n inject: {\n nodeProps: {\n defaultNodeValue: 1.5,\n validNodeValues: [1, 1.2, 1.5, 2, 3],\n },\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n ],\n },\n }),\n\n // Functionality\n AutoformatPlugin.configure({\n options: autoformatOptions,\n }),\n BlockSelectionPlugin.configure({\n options: {\n areaOptions: {\n behaviour: {\n scrolling: {\n speedDivider: 1.5,\n },\n startThreshold: 10,\n },\n boundaries: `#${scrollSelector}`,\n container: `#${scrollSelector}`,\n selectables: [`#${scrollSelector} .slate-selectable`],\n selectionAreaClass: 'slate-selection-area',\n },\n enableContextMenu: true,\n },\n }),\n BlockMenuPlugin.configure({\n render: { aboveEditable: BlockContextMenu },\n }),\n DndPlugin.configure({\n options: {\n enableScroller: true,\n onDropFiles: ({ dragItem, editor, target }) => {\n editor\n .getTransforms(ImagePlugin)\n .insertImageFromFiles(dragItem.files, {\n at: target,\n nextBlock: false,\n });\n },\n },\n }),\n EmojiPlugin,\n exitBreakPlugin,\n NodeIdPlugin,\n NormalizeTypesPlugin.configure({\n options: {\n rules: [{ path: [0], strictType: HEADING_KEYS.h1 }],\n },\n }),\n resetBlockTypePlugin,\n SelectOnBackspacePlugin.configure({\n options: {\n query: {\n allow: [ImagePlugin.key, HorizontalRulePlugin.key],\n },\n },\n }),\n DeletePlugin,\n SingleLinePlugin,\n softBreakPlugin,\n tabbablePlugin,\n TrailingBlockPlugin.configure({\n options: { type: ParagraphPlugin.key },\n }),\n DragOverCursorPlugin,\n\n // Collaboration\n CommentsPlugin.configure({\n options: {\n comments: commentsData,\n myUserId: '1',\n users: usersData,\n },\n }),\n\n // Deserialization\n DocxPlugin,\n MarkdownPlugin.configure({ options: { indentList: true } }),\n JuicePlugin,\n\n // Testing\n PlaywrightPlugin.configure({\n enabled: process.env.NODE_ENV !== 'production',\n }),\n ],\n value: value,\n },\n []\n );\n};\n\nexport default function PlaygroundDemo({\n id,\n className,\n scrollSelector,\n}: {\n id?: ValueId;\n className?: string;\n scrollSelector?: string;\n}) {\n const containerRef = useRef(null);\n const enabled = settingsStore.use.checkedComponents();\n\n const editor = usePlaygroundEditor(\n id,\n scrollSelector ?? `blockSelection-${id}`\n );\n\n return (\n \n \n \n \n \n \n \n \n \n\n
\n \n \n\n \n \n \n \n \n \n \n\n \n \n \n \n\n \n \n \n
\n
\n
\n );\n}\n\nconst DemoIdContext = React.createContext(undefined);\n\nexport function DemoId({\n id,\n children,\n}: {\n children: React.ReactNode;\n id?: string;\n}) {\n return {children};\n}\n\nexport function useDemoId() {\n return React.useContext(DemoIdContext);\n}\n", "path": "example/playground-demo.tsx", "target": "components/playground-demo.tsx", "type": "registry:example" diff --git a/apps/www/public/r/styles/default/mode-demo.json b/apps/www/public/r/styles/default/mode-demo.json index 198b38b777..e71ca9f9f0 100644 --- a/apps/www/public/r/styles/default/mode-demo.json +++ b/apps/www/public/r/styles/default/mode-demo.json @@ -4,7 +4,7 @@ }, "files": [ { - "content": "'use client';\n\nimport React, { useRef } from 'react';\n\nimport type { ValueId } from '@/config/customizer-plugins';\n\nimport { cn } from '@udecode/cn';\nimport { AIChatPlugin, CopilotPlugin } from '@udecode/plate-ai/react';\nimport { AlignPlugin } from '@udecode/plate-alignment/react';\nimport { AutoformatPlugin } from '@udecode/plate-autoformat/react';\nimport {\n BoldPlugin,\n CodePlugin,\n ItalicPlugin,\n StrikethroughPlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n UnderlinePlugin,\n} from '@udecode/plate-basic-marks/react';\nimport { BlockquotePlugin } from '@udecode/plate-block-quote/react';\nimport { SingleLinePlugin } from '@udecode/plate-break/react';\nimport { CaptionPlugin } from '@udecode/plate-caption/react';\nimport { CodeBlockPlugin } from '@udecode/plate-code-block/react';\nimport { CommentsPlugin } from '@udecode/plate-comments/react';\nimport {\n ParagraphPlugin,\n Plate,\n usePlateEditor,\n} from '@udecode/plate-common/react';\nimport { DatePlugin } from '@udecode/plate-date/react';\nimport { DndPlugin } from '@udecode/plate-dnd';\nimport { DocxPlugin } from '@udecode/plate-docx';\nimport { EmojiPlugin } from '@udecode/plate-emoji/react';\nimport { ExcalidrawPlugin } from '@udecode/plate-excalidraw/react';\nimport {\n FontBackgroundColorPlugin,\n FontColorPlugin,\n FontSizePlugin,\n} from '@udecode/plate-font/react';\nimport { HEADING_KEYS } from '@udecode/plate-heading';\nimport { HeadingPlugin, TocPlugin } from '@udecode/plate-heading/react';\nimport { HighlightPlugin } from '@udecode/plate-highlight/react';\nimport { HorizontalRulePlugin } from '@udecode/plate-horizontal-rule/react';\nimport { IndentPlugin } from '@udecode/plate-indent/react';\nimport { IndentListPlugin } from '@udecode/plate-indent-list/react';\nimport { JuicePlugin } from '@udecode/plate-juice';\nimport { KbdPlugin } from '@udecode/plate-kbd/react';\nimport { ColumnPlugin } from '@udecode/plate-layout/react';\nimport { LineHeightPlugin } from '@udecode/plate-line-height/react';\nimport { LinkPlugin } from '@udecode/plate-link/react';\nimport { ListPlugin, TodoListPlugin } from '@udecode/plate-list/react';\nimport { MarkdownPlugin } from '@udecode/plate-markdown';\nimport { ImagePlugin, MediaEmbedPlugin } from '@udecode/plate-media/react';\nimport { MentionPlugin } from '@udecode/plate-mention/react';\nimport { NodeIdPlugin } from '@udecode/plate-node-id';\nimport { NormalizeTypesPlugin } from '@udecode/plate-normalizers';\nimport { PlaywrightPlugin } from '@udecode/plate-playwright';\nimport { DeletePlugin, SelectOnBackspacePlugin } from '@udecode/plate-select';\nimport {\n BlockMenuPlugin,\n BlockSelectionPlugin,\n} from '@udecode/plate-selection/react';\nimport { SlashPlugin } from '@udecode/plate-slash-command/react';\nimport { TablePlugin } from '@udecode/plate-table/react';\nimport { TogglePlugin } from '@udecode/plate-toggle/react';\nimport { TrailingBlockPlugin } from '@udecode/plate-trailing-block';\nimport Prism from 'prismjs';\n\nimport { CheckPlugin } from '@/components/context/check-plugin';\nimport { settingsStore } from '@/components/context/settings-store';\nimport { aiPlugins } from '@/lib/plate/demo/plugins/ai-plugins';\nimport { getAutoformatOptions } from '@/lib/plate/demo/plugins/autoformatOptions';\nimport { copilotPlugins } from '@/lib/plate/demo/plugins/copilot-plugins';\nimport { createPlateUI } from '@/plate/create-plate-ui';\nimport { editableProps } from '@/plate/demo/editableProps';\nimport { isEnabled } from '@/plate/demo/is-enabled';\nimport { DragOverCursorPlugin } from '@/plate/demo/plugins/DragOverCursorPlugin';\nimport { exitBreakPlugin } from '@/plate/demo/plugins/exitBreakPlugin';\nimport { resetBlockTypePlugin } from '@/plate/demo/plugins/resetBlockTypePlugin';\nimport { softBreakPlugin } from '@/plate/demo/plugins/softBreakPlugin';\nimport { tabbablePlugin } from '@/plate/demo/plugins/tabbablePlugin';\nimport { commentsData, usersData } from '@/plate/demo/values/commentsValue';\nimport { usePlaygroundValue } from '@/plate/demo/values/usePlaygroundValue';\nimport { BlockContextMenu } from '@/components/plate-ui/block-context-menu';\nimport { CommentsPopover } from '@/components/plate-ui/comments-popover';\nimport {\n CursorOverlay,\n SelectionOverlayPlugin,\n} from '@/components/plate-ui/cursor-overlay';\nimport { Editor, EditorContainer } from '@/components/plate-ui/editor';\nimport { FixedToolbar } from '@/components/plate-ui/fixed-toolbar';\nimport { FixedToolbarButtons } from '@/components/plate-ui/fixed-toolbar-buttons';\nimport { FloatingToolbar } from '@/components/plate-ui/floating-toolbar';\nimport { FloatingToolbarButtons } from '@/components/plate-ui/floating-toolbar-buttons';\nimport { ImagePreview } from '@/components/plate-ui/image-preview';\nimport {\n FireLiComponent,\n FireMarker,\n} from '@/components/plate-ui/indent-fire-marker';\nimport {\n TodoLi,\n TodoMarker,\n} from '@/components/plate-ui/indent-todo-marker';\nimport { LinkFloatingToolbar } from '@/components/plate-ui/link-floating-toolbar';\n\nimport { usePlaygroundEnabled } from './usePlaygroundEnabled';\n\nexport const usePlaygroundEditor = (id: any = '', scrollSelector?: string) => {\n const enabledPlugins = settingsStore.use.checkedPlugins();\n const overridePlugins = usePlaygroundEnabled(id);\n const autoformatOptions = getAutoformatOptions(id, enabledPlugins);\n\n const value = usePlaygroundValue(id);\n const key = settingsStore.use.version();\n const editorId = id || 'playground-' + key;\n\n return usePlateEditor(\n {\n id: editorId,\n override: {\n components: createPlateUI({\n draggable: isEnabled('dnd', id),\n placeholder: isEnabled('placeholder', id),\n }),\n plugins: overridePlugins,\n },\n plugins: [\n // AI\n ...(id === 'ai' || enabledPlugins[AIChatPlugin.key] ? aiPlugins : []),\n ...(id === 'copilot' || enabledPlugins[CopilotPlugin.key]\n ? copilotPlugins\n : []),\n // Nodes\n HeadingPlugin,\n TocPlugin.configure({\n options: {\n scrollContainerSelector: `#${scrollSelector}`,\n topOffset: 80,\n },\n }),\n BlockquotePlugin,\n CodeBlockPlugin.configure({\n options: {\n prism: Prism,\n },\n }),\n HorizontalRulePlugin,\n LinkPlugin.extend({\n render: { afterEditable: () => },\n }),\n ...(id === 'list' ? [ListPlugin] : []),\n ImagePlugin.extend({\n render: { afterEditable: ImagePreview },\n }),\n MediaEmbedPlugin,\n CaptionPlugin.configure({\n options: {\n plugins: [ImagePlugin, MediaEmbedPlugin],\n },\n }),\n DatePlugin,\n MentionPlugin.configure({\n options: {\n triggerPreviousCharPattern: /^$|^[\\s\"']$/,\n },\n }),\n SlashPlugin,\n TablePlugin.configure({\n options: {\n enableMerging: id === 'tableMerge',\n },\n }),\n ColumnPlugin,\n SelectionOverlayPlugin,\n\n TodoListPlugin,\n TogglePlugin,\n ExcalidrawPlugin,\n // Marks\n BoldPlugin,\n ItalicPlugin,\n UnderlinePlugin,\n StrikethroughPlugin,\n CodePlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n FontColorPlugin,\n FontBackgroundColorPlugin,\n FontSizePlugin,\n HighlightPlugin,\n KbdPlugin,\n\n // Block Style\n AlignPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n MediaEmbedPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n ImagePlugin.key,\n HEADING_KEYS.h6,\n ],\n },\n }),\n IndentPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n }),\n IndentListPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n options: {\n listStyleTypes: {\n fire: {\n liComponent: FireLiComponent,\n markerComponent: FireMarker,\n type: 'fire',\n },\n todo: {\n liComponent: TodoLi,\n markerComponent: TodoMarker,\n type: 'todo',\n },\n },\n },\n }),\n LineHeightPlugin.extend({\n inject: {\n nodeProps: {\n defaultNodeValue: 1.5,\n validNodeValues: [1, 1.2, 1.5, 2, 3],\n },\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n ],\n },\n }),\n\n // Functionality\n AutoformatPlugin.configure({\n options: autoformatOptions,\n }),\n BlockSelectionPlugin.configure({\n options: {\n areaOptions: {\n behaviour: {\n scrolling: {\n speedDivider: 1.5,\n },\n startThreshold: 10,\n },\n boundaries: `#${scrollSelector}`,\n container: `#${scrollSelector}`,\n selectables: [`#${scrollSelector} .slate-selectable`],\n selectionAreaClass: 'slate-selection-area',\n },\n enableContextMenu: true,\n },\n }),\n BlockMenuPlugin.configure({\n render: { aboveEditable: BlockContextMenu },\n }),\n DndPlugin.configure({ options: { enableScroller: true } }),\n EmojiPlugin,\n exitBreakPlugin,\n NodeIdPlugin,\n NormalizeTypesPlugin.configure({\n options: {\n rules: [{ path: [0], strictType: HEADING_KEYS.h1 }],\n },\n }),\n resetBlockTypePlugin,\n SelectOnBackspacePlugin.configure({\n options: {\n query: {\n allow: [ImagePlugin.key, HorizontalRulePlugin.key],\n },\n },\n }),\n DeletePlugin,\n SingleLinePlugin,\n softBreakPlugin,\n tabbablePlugin,\n TrailingBlockPlugin.configure({\n options: { type: ParagraphPlugin.key },\n }),\n DragOverCursorPlugin,\n\n // Collaboration\n CommentsPlugin.configure({\n options: {\n comments: commentsData,\n myUserId: '1',\n users: usersData,\n },\n }),\n\n // Deserialization\n DocxPlugin,\n MarkdownPlugin.configure({ options: { indentList: true } }),\n JuicePlugin,\n\n // Testing\n PlaywrightPlugin.configure({\n enabled: process.env.NODE_ENV !== 'production',\n }),\n ],\n value: value,\n },\n []\n );\n};\n\nexport default function PlaygroundDemo({\n id,\n className,\n scrollSelector,\n}: {\n id?: ValueId;\n className?: string;\n scrollSelector?: string;\n}) {\n const containerRef = useRef(null);\n const enabled = settingsStore.use.checkedComponents();\n\n const editor = usePlaygroundEditor(\n id,\n scrollSelector ?? `blockSelection-${id}`\n );\n\n return (\n \n \n \n \n \n \n \n \n \n\n
\n \n \n\n \n \n \n \n \n \n \n\n \n \n \n \n\n \n \n \n
\n
\n
\n );\n}\n\nconst DemoIdContext = React.createContext(undefined);\n\nexport function DemoId({\n id,\n children,\n}: {\n children: React.ReactNode;\n id?: string;\n}) {\n return {children};\n}\n\nexport function useDemoId() {\n return React.useContext(DemoIdContext);\n}\n", + "content": "'use client';\n\nimport React, { useRef } from 'react';\n\nimport type { ValueId } from '@/config/customizer-plugins';\n\nimport { cn } from '@udecode/cn';\nimport { AIChatPlugin, CopilotPlugin } from '@udecode/plate-ai/react';\nimport { AlignPlugin } from '@udecode/plate-alignment/react';\nimport { AutoformatPlugin } from '@udecode/plate-autoformat/react';\nimport {\n BoldPlugin,\n CodePlugin,\n ItalicPlugin,\n StrikethroughPlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n UnderlinePlugin,\n} from '@udecode/plate-basic-marks/react';\nimport { BlockquotePlugin } from '@udecode/plate-block-quote/react';\nimport { SingleLinePlugin } from '@udecode/plate-break/react';\nimport { CaptionPlugin } from '@udecode/plate-caption/react';\nimport { CodeBlockPlugin } from '@udecode/plate-code-block/react';\nimport { CommentsPlugin } from '@udecode/plate-comments/react';\nimport {\n ParagraphPlugin,\n Plate,\n usePlateEditor,\n} from '@udecode/plate-common/react';\nimport { DatePlugin } from '@udecode/plate-date/react';\nimport { DndPlugin } from '@udecode/plate-dnd';\nimport { DocxPlugin } from '@udecode/plate-docx';\nimport { EmojiPlugin } from '@udecode/plate-emoji/react';\nimport { ExcalidrawPlugin } from '@udecode/plate-excalidraw/react';\nimport {\n FontBackgroundColorPlugin,\n FontColorPlugin,\n FontSizePlugin,\n} from '@udecode/plate-font/react';\nimport { HEADING_KEYS } from '@udecode/plate-heading';\nimport { HeadingPlugin, TocPlugin } from '@udecode/plate-heading/react';\nimport { HighlightPlugin } from '@udecode/plate-highlight/react';\nimport { HorizontalRulePlugin } from '@udecode/plate-horizontal-rule/react';\nimport { IndentPlugin } from '@udecode/plate-indent/react';\nimport { IndentListPlugin } from '@udecode/plate-indent-list/react';\nimport { JuicePlugin } from '@udecode/plate-juice';\nimport { KbdPlugin } from '@udecode/plate-kbd/react';\nimport { ColumnPlugin } from '@udecode/plate-layout/react';\nimport { LineHeightPlugin } from '@udecode/plate-line-height/react';\nimport { LinkPlugin } from '@udecode/plate-link/react';\nimport { ListPlugin, TodoListPlugin } from '@udecode/plate-list/react';\nimport { MarkdownPlugin } from '@udecode/plate-markdown';\nimport { ImagePlugin, MediaEmbedPlugin } from '@udecode/plate-media/react';\nimport { MentionPlugin } from '@udecode/plate-mention/react';\nimport { NodeIdPlugin } from '@udecode/plate-node-id';\nimport { NormalizeTypesPlugin } from '@udecode/plate-normalizers';\nimport { PlaywrightPlugin } from '@udecode/plate-playwright';\nimport { DeletePlugin, SelectOnBackspacePlugin } from '@udecode/plate-select';\nimport {\n BlockMenuPlugin,\n BlockSelectionPlugin,\n} from '@udecode/plate-selection/react';\nimport { SlashPlugin } from '@udecode/plate-slash-command/react';\nimport { TablePlugin } from '@udecode/plate-table/react';\nimport { TogglePlugin } from '@udecode/plate-toggle/react';\nimport { TrailingBlockPlugin } from '@udecode/plate-trailing-block';\nimport Prism from 'prismjs';\n\nimport { CheckPlugin } from '@/components/context/check-plugin';\nimport { settingsStore } from '@/components/context/settings-store';\nimport { aiPlugins } from '@/lib/plate/demo/plugins/ai-plugins';\nimport { getAutoformatOptions } from '@/lib/plate/demo/plugins/autoformatOptions';\nimport { copilotPlugins } from '@/lib/plate/demo/plugins/copilot-plugins';\nimport { createPlateUI } from '@/plate/create-plate-ui';\nimport { editableProps } from '@/plate/demo/editableProps';\nimport { isEnabled } from '@/plate/demo/is-enabled';\nimport { DragOverCursorPlugin } from '@/plate/demo/plugins/DragOverCursorPlugin';\nimport { exitBreakPlugin } from '@/plate/demo/plugins/exitBreakPlugin';\nimport { resetBlockTypePlugin } from '@/plate/demo/plugins/resetBlockTypePlugin';\nimport { softBreakPlugin } from '@/plate/demo/plugins/softBreakPlugin';\nimport { tabbablePlugin } from '@/plate/demo/plugins/tabbablePlugin';\nimport { commentsData, usersData } from '@/plate/demo/values/commentsValue';\nimport { usePlaygroundValue } from '@/plate/demo/values/usePlaygroundValue';\nimport { BlockContextMenu } from '@/components/plate-ui/block-context-menu';\nimport { CommentsPopover } from '@/components/plate-ui/comments-popover';\nimport {\n CursorOverlay,\n SelectionOverlayPlugin,\n} from '@/components/plate-ui/cursor-overlay';\nimport { Editor, EditorContainer } from '@/components/plate-ui/editor';\nimport { FixedToolbar } from '@/components/plate-ui/fixed-toolbar';\nimport { FixedToolbarButtons } from '@/components/plate-ui/fixed-toolbar-buttons';\nimport { FloatingToolbar } from '@/components/plate-ui/floating-toolbar';\nimport { FloatingToolbarButtons } from '@/components/plate-ui/floating-toolbar-buttons';\nimport { ImagePreview } from '@/components/plate-ui/image-preview';\nimport {\n FireLiComponent,\n FireMarker,\n} from '@/components/plate-ui/indent-fire-marker';\nimport {\n TodoLi,\n TodoMarker,\n} from '@/components/plate-ui/indent-todo-marker';\nimport { LinkFloatingToolbar } from '@/components/plate-ui/link-floating-toolbar';\n\nimport { usePlaygroundEnabled } from './usePlaygroundEnabled';\n\nexport const usePlaygroundEditor = (id: any = '', scrollSelector?: string) => {\n const enabledPlugins = settingsStore.use.checkedPlugins();\n const overridePlugins = usePlaygroundEnabled(id);\n const autoformatOptions = getAutoformatOptions(id, enabledPlugins);\n\n const value = usePlaygroundValue(id);\n const key = settingsStore.use.version();\n const editorId = id || 'playground-' + key;\n\n return usePlateEditor(\n {\n id: editorId,\n override: {\n components: createPlateUI({\n draggable: isEnabled('dnd', id),\n placeholder: isEnabled('placeholder', id),\n }),\n plugins: overridePlugins,\n },\n plugins: [\n // AI\n ...(id === 'ai' || enabledPlugins[AIChatPlugin.key] ? aiPlugins : []),\n ...(id === 'copilot' || enabledPlugins[CopilotPlugin.key]\n ? copilotPlugins\n : []),\n // Nodes\n HeadingPlugin,\n TocPlugin.configure({\n options: {\n scrollContainerSelector: `#${scrollSelector}`,\n topOffset: 80,\n },\n }),\n BlockquotePlugin,\n CodeBlockPlugin.configure({\n options: {\n prism: Prism,\n },\n }),\n HorizontalRulePlugin,\n LinkPlugin.extend({\n render: { afterEditable: () => },\n }),\n ...(id === 'list' ? [ListPlugin] : []),\n ImagePlugin.extend({\n options: {\n disableUploadInsert: true,\n },\n render: { afterEditable: ImagePreview },\n }),\n MediaEmbedPlugin,\n CaptionPlugin.configure({\n options: {\n plugins: [ImagePlugin, MediaEmbedPlugin],\n },\n }),\n DatePlugin,\n MentionPlugin.configure({\n options: {\n triggerPreviousCharPattern: /^$|^[\\s\"']$/,\n },\n }),\n SlashPlugin,\n TablePlugin.configure({\n options: {\n enableMerging: id === 'tableMerge',\n },\n }),\n ColumnPlugin,\n SelectionOverlayPlugin,\n\n TodoListPlugin,\n TogglePlugin,\n ExcalidrawPlugin,\n // Marks\n BoldPlugin,\n ItalicPlugin,\n UnderlinePlugin,\n StrikethroughPlugin,\n CodePlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n FontColorPlugin,\n FontBackgroundColorPlugin,\n FontSizePlugin,\n HighlightPlugin,\n KbdPlugin,\n\n // Block Style\n AlignPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n MediaEmbedPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n ImagePlugin.key,\n HEADING_KEYS.h6,\n ],\n },\n }),\n IndentPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n }),\n IndentListPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n options: {\n listStyleTypes: {\n fire: {\n liComponent: FireLiComponent,\n markerComponent: FireMarker,\n type: 'fire',\n },\n todo: {\n liComponent: TodoLi,\n markerComponent: TodoMarker,\n type: 'todo',\n },\n },\n },\n }),\n LineHeightPlugin.extend({\n inject: {\n nodeProps: {\n defaultNodeValue: 1.5,\n validNodeValues: [1, 1.2, 1.5, 2, 3],\n },\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n ],\n },\n }),\n\n // Functionality\n AutoformatPlugin.configure({\n options: autoformatOptions,\n }),\n BlockSelectionPlugin.configure({\n options: {\n areaOptions: {\n behaviour: {\n scrolling: {\n speedDivider: 1.5,\n },\n startThreshold: 10,\n },\n boundaries: `#${scrollSelector}`,\n container: `#${scrollSelector}`,\n selectables: [`#${scrollSelector} .slate-selectable`],\n selectionAreaClass: 'slate-selection-area',\n },\n enableContextMenu: true,\n },\n }),\n BlockMenuPlugin.configure({\n render: { aboveEditable: BlockContextMenu },\n }),\n DndPlugin.configure({\n options: {\n enableScroller: true,\n onDropFiles: ({ dragItem, editor, target }) => {\n editor\n .getTransforms(ImagePlugin)\n .insertImageFromFiles(dragItem.files, {\n at: target,\n nextBlock: false,\n });\n },\n },\n }),\n EmojiPlugin,\n exitBreakPlugin,\n NodeIdPlugin,\n NormalizeTypesPlugin.configure({\n options: {\n rules: [{ path: [0], strictType: HEADING_KEYS.h1 }],\n },\n }),\n resetBlockTypePlugin,\n SelectOnBackspacePlugin.configure({\n options: {\n query: {\n allow: [ImagePlugin.key, HorizontalRulePlugin.key],\n },\n },\n }),\n DeletePlugin,\n SingleLinePlugin,\n softBreakPlugin,\n tabbablePlugin,\n TrailingBlockPlugin.configure({\n options: { type: ParagraphPlugin.key },\n }),\n DragOverCursorPlugin,\n\n // Collaboration\n CommentsPlugin.configure({\n options: {\n comments: commentsData,\n myUserId: '1',\n users: usersData,\n },\n }),\n\n // Deserialization\n DocxPlugin,\n MarkdownPlugin.configure({ options: { indentList: true } }),\n JuicePlugin,\n\n // Testing\n PlaywrightPlugin.configure({\n enabled: process.env.NODE_ENV !== 'production',\n }),\n ],\n value: value,\n },\n []\n );\n};\n\nexport default function PlaygroundDemo({\n id,\n className,\n scrollSelector,\n}: {\n id?: ValueId;\n className?: string;\n scrollSelector?: string;\n}) {\n const containerRef = useRef(null);\n const enabled = settingsStore.use.checkedComponents();\n\n const editor = usePlaygroundEditor(\n id,\n scrollSelector ?? `blockSelection-${id}`\n );\n\n return (\n \n \n \n \n \n \n \n \n \n\n
\n \n \n\n \n \n \n \n \n \n \n\n \n \n \n \n\n \n \n \n
\n
\n
\n );\n}\n\nconst DemoIdContext = React.createContext(undefined);\n\nexport function DemoId({\n id,\n children,\n}: {\n children: React.ReactNode;\n id?: string;\n}) {\n return {children};\n}\n\nexport function useDemoId() {\n return React.useContext(DemoIdContext);\n}\n", "path": "example/playground-demo.tsx", "target": "components/playground-demo.tsx", "type": "registry:example" diff --git a/apps/www/public/r/styles/default/placeholder-demo.json b/apps/www/public/r/styles/default/placeholder-demo.json index 69adb67a15..2fe089de42 100644 --- a/apps/www/public/r/styles/default/placeholder-demo.json +++ b/apps/www/public/r/styles/default/placeholder-demo.json @@ -4,7 +4,7 @@ }, "files": [ { - "content": "'use client';\n\nimport React, { useRef } from 'react';\n\nimport type { ValueId } from '@/config/customizer-plugins';\n\nimport { cn } from '@udecode/cn';\nimport { AIChatPlugin, CopilotPlugin } from '@udecode/plate-ai/react';\nimport { AlignPlugin } from '@udecode/plate-alignment/react';\nimport { AutoformatPlugin } from '@udecode/plate-autoformat/react';\nimport {\n BoldPlugin,\n CodePlugin,\n ItalicPlugin,\n StrikethroughPlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n UnderlinePlugin,\n} from '@udecode/plate-basic-marks/react';\nimport { BlockquotePlugin } from '@udecode/plate-block-quote/react';\nimport { SingleLinePlugin } from '@udecode/plate-break/react';\nimport { CaptionPlugin } from '@udecode/plate-caption/react';\nimport { CodeBlockPlugin } from '@udecode/plate-code-block/react';\nimport { CommentsPlugin } from '@udecode/plate-comments/react';\nimport {\n ParagraphPlugin,\n Plate,\n usePlateEditor,\n} from '@udecode/plate-common/react';\nimport { DatePlugin } from '@udecode/plate-date/react';\nimport { DndPlugin } from '@udecode/plate-dnd';\nimport { DocxPlugin } from '@udecode/plate-docx';\nimport { EmojiPlugin } from '@udecode/plate-emoji/react';\nimport { ExcalidrawPlugin } from '@udecode/plate-excalidraw/react';\nimport {\n FontBackgroundColorPlugin,\n FontColorPlugin,\n FontSizePlugin,\n} from '@udecode/plate-font/react';\nimport { HEADING_KEYS } from '@udecode/plate-heading';\nimport { HeadingPlugin, TocPlugin } from '@udecode/plate-heading/react';\nimport { HighlightPlugin } from '@udecode/plate-highlight/react';\nimport { HorizontalRulePlugin } from '@udecode/plate-horizontal-rule/react';\nimport { IndentPlugin } from '@udecode/plate-indent/react';\nimport { IndentListPlugin } from '@udecode/plate-indent-list/react';\nimport { JuicePlugin } from '@udecode/plate-juice';\nimport { KbdPlugin } from '@udecode/plate-kbd/react';\nimport { ColumnPlugin } from '@udecode/plate-layout/react';\nimport { LineHeightPlugin } from '@udecode/plate-line-height/react';\nimport { LinkPlugin } from '@udecode/plate-link/react';\nimport { ListPlugin, TodoListPlugin } from '@udecode/plate-list/react';\nimport { MarkdownPlugin } from '@udecode/plate-markdown';\nimport { ImagePlugin, MediaEmbedPlugin } from '@udecode/plate-media/react';\nimport { MentionPlugin } from '@udecode/plate-mention/react';\nimport { NodeIdPlugin } from '@udecode/plate-node-id';\nimport { NormalizeTypesPlugin } from '@udecode/plate-normalizers';\nimport { PlaywrightPlugin } from '@udecode/plate-playwright';\nimport { DeletePlugin, SelectOnBackspacePlugin } from '@udecode/plate-select';\nimport {\n BlockMenuPlugin,\n BlockSelectionPlugin,\n} from '@udecode/plate-selection/react';\nimport { SlashPlugin } from '@udecode/plate-slash-command/react';\nimport { TablePlugin } from '@udecode/plate-table/react';\nimport { TogglePlugin } from '@udecode/plate-toggle/react';\nimport { TrailingBlockPlugin } from '@udecode/plate-trailing-block';\nimport Prism from 'prismjs';\n\nimport { CheckPlugin } from '@/components/context/check-plugin';\nimport { settingsStore } from '@/components/context/settings-store';\nimport { aiPlugins } from '@/lib/plate/demo/plugins/ai-plugins';\nimport { getAutoformatOptions } from '@/lib/plate/demo/plugins/autoformatOptions';\nimport { copilotPlugins } from '@/lib/plate/demo/plugins/copilot-plugins';\nimport { createPlateUI } from '@/plate/create-plate-ui';\nimport { editableProps } from '@/plate/demo/editableProps';\nimport { isEnabled } from '@/plate/demo/is-enabled';\nimport { DragOverCursorPlugin } from '@/plate/demo/plugins/DragOverCursorPlugin';\nimport { exitBreakPlugin } from '@/plate/demo/plugins/exitBreakPlugin';\nimport { resetBlockTypePlugin } from '@/plate/demo/plugins/resetBlockTypePlugin';\nimport { softBreakPlugin } from '@/plate/demo/plugins/softBreakPlugin';\nimport { tabbablePlugin } from '@/plate/demo/plugins/tabbablePlugin';\nimport { commentsData, usersData } from '@/plate/demo/values/commentsValue';\nimport { usePlaygroundValue } from '@/plate/demo/values/usePlaygroundValue';\nimport { BlockContextMenu } from '@/components/plate-ui/block-context-menu';\nimport { CommentsPopover } from '@/components/plate-ui/comments-popover';\nimport {\n CursorOverlay,\n SelectionOverlayPlugin,\n} from '@/components/plate-ui/cursor-overlay';\nimport { Editor, EditorContainer } from '@/components/plate-ui/editor';\nimport { FixedToolbar } from '@/components/plate-ui/fixed-toolbar';\nimport { FixedToolbarButtons } from '@/components/plate-ui/fixed-toolbar-buttons';\nimport { FloatingToolbar } from '@/components/plate-ui/floating-toolbar';\nimport { FloatingToolbarButtons } from '@/components/plate-ui/floating-toolbar-buttons';\nimport { ImagePreview } from '@/components/plate-ui/image-preview';\nimport {\n FireLiComponent,\n FireMarker,\n} from '@/components/plate-ui/indent-fire-marker';\nimport {\n TodoLi,\n TodoMarker,\n} from '@/components/plate-ui/indent-todo-marker';\nimport { LinkFloatingToolbar } from '@/components/plate-ui/link-floating-toolbar';\n\nimport { usePlaygroundEnabled } from './usePlaygroundEnabled';\n\nexport const usePlaygroundEditor = (id: any = '', scrollSelector?: string) => {\n const enabledPlugins = settingsStore.use.checkedPlugins();\n const overridePlugins = usePlaygroundEnabled(id);\n const autoformatOptions = getAutoformatOptions(id, enabledPlugins);\n\n const value = usePlaygroundValue(id);\n const key = settingsStore.use.version();\n const editorId = id || 'playground-' + key;\n\n return usePlateEditor(\n {\n id: editorId,\n override: {\n components: createPlateUI({\n draggable: isEnabled('dnd', id),\n placeholder: isEnabled('placeholder', id),\n }),\n plugins: overridePlugins,\n },\n plugins: [\n // AI\n ...(id === 'ai' || enabledPlugins[AIChatPlugin.key] ? aiPlugins : []),\n ...(id === 'copilot' || enabledPlugins[CopilotPlugin.key]\n ? copilotPlugins\n : []),\n // Nodes\n HeadingPlugin,\n TocPlugin.configure({\n options: {\n scrollContainerSelector: `#${scrollSelector}`,\n topOffset: 80,\n },\n }),\n BlockquotePlugin,\n CodeBlockPlugin.configure({\n options: {\n prism: Prism,\n },\n }),\n HorizontalRulePlugin,\n LinkPlugin.extend({\n render: { afterEditable: () => },\n }),\n ...(id === 'list' ? [ListPlugin] : []),\n ImagePlugin.extend({\n render: { afterEditable: ImagePreview },\n }),\n MediaEmbedPlugin,\n CaptionPlugin.configure({\n options: {\n plugins: [ImagePlugin, MediaEmbedPlugin],\n },\n }),\n DatePlugin,\n MentionPlugin.configure({\n options: {\n triggerPreviousCharPattern: /^$|^[\\s\"']$/,\n },\n }),\n SlashPlugin,\n TablePlugin.configure({\n options: {\n enableMerging: id === 'tableMerge',\n },\n }),\n ColumnPlugin,\n SelectionOverlayPlugin,\n\n TodoListPlugin,\n TogglePlugin,\n ExcalidrawPlugin,\n // Marks\n BoldPlugin,\n ItalicPlugin,\n UnderlinePlugin,\n StrikethroughPlugin,\n CodePlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n FontColorPlugin,\n FontBackgroundColorPlugin,\n FontSizePlugin,\n HighlightPlugin,\n KbdPlugin,\n\n // Block Style\n AlignPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n MediaEmbedPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n ImagePlugin.key,\n HEADING_KEYS.h6,\n ],\n },\n }),\n IndentPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n }),\n IndentListPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n options: {\n listStyleTypes: {\n fire: {\n liComponent: FireLiComponent,\n markerComponent: FireMarker,\n type: 'fire',\n },\n todo: {\n liComponent: TodoLi,\n markerComponent: TodoMarker,\n type: 'todo',\n },\n },\n },\n }),\n LineHeightPlugin.extend({\n inject: {\n nodeProps: {\n defaultNodeValue: 1.5,\n validNodeValues: [1, 1.2, 1.5, 2, 3],\n },\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n ],\n },\n }),\n\n // Functionality\n AutoformatPlugin.configure({\n options: autoformatOptions,\n }),\n BlockSelectionPlugin.configure({\n options: {\n areaOptions: {\n behaviour: {\n scrolling: {\n speedDivider: 1.5,\n },\n startThreshold: 10,\n },\n boundaries: `#${scrollSelector}`,\n container: `#${scrollSelector}`,\n selectables: [`#${scrollSelector} .slate-selectable`],\n selectionAreaClass: 'slate-selection-area',\n },\n enableContextMenu: true,\n },\n }),\n BlockMenuPlugin.configure({\n render: { aboveEditable: BlockContextMenu },\n }),\n DndPlugin.configure({ options: { enableScroller: true } }),\n EmojiPlugin,\n exitBreakPlugin,\n NodeIdPlugin,\n NormalizeTypesPlugin.configure({\n options: {\n rules: [{ path: [0], strictType: HEADING_KEYS.h1 }],\n },\n }),\n resetBlockTypePlugin,\n SelectOnBackspacePlugin.configure({\n options: {\n query: {\n allow: [ImagePlugin.key, HorizontalRulePlugin.key],\n },\n },\n }),\n DeletePlugin,\n SingleLinePlugin,\n softBreakPlugin,\n tabbablePlugin,\n TrailingBlockPlugin.configure({\n options: { type: ParagraphPlugin.key },\n }),\n DragOverCursorPlugin,\n\n // Collaboration\n CommentsPlugin.configure({\n options: {\n comments: commentsData,\n myUserId: '1',\n users: usersData,\n },\n }),\n\n // Deserialization\n DocxPlugin,\n MarkdownPlugin.configure({ options: { indentList: true } }),\n JuicePlugin,\n\n // Testing\n PlaywrightPlugin.configure({\n enabled: process.env.NODE_ENV !== 'production',\n }),\n ],\n value: value,\n },\n []\n );\n};\n\nexport default function PlaygroundDemo({\n id,\n className,\n scrollSelector,\n}: {\n id?: ValueId;\n className?: string;\n scrollSelector?: string;\n}) {\n const containerRef = useRef(null);\n const enabled = settingsStore.use.checkedComponents();\n\n const editor = usePlaygroundEditor(\n id,\n scrollSelector ?? `blockSelection-${id}`\n );\n\n return (\n \n \n \n \n \n \n \n \n \n\n
\n \n \n\n \n \n \n \n \n \n \n\n \n \n \n \n\n \n \n \n
\n
\n
\n );\n}\n\nconst DemoIdContext = React.createContext(undefined);\n\nexport function DemoId({\n id,\n children,\n}: {\n children: React.ReactNode;\n id?: string;\n}) {\n return {children};\n}\n\nexport function useDemoId() {\n return React.useContext(DemoIdContext);\n}\n", + "content": "'use client';\n\nimport React, { useRef } from 'react';\n\nimport type { ValueId } from '@/config/customizer-plugins';\n\nimport { cn } from '@udecode/cn';\nimport { AIChatPlugin, CopilotPlugin } from '@udecode/plate-ai/react';\nimport { AlignPlugin } from '@udecode/plate-alignment/react';\nimport { AutoformatPlugin } from '@udecode/plate-autoformat/react';\nimport {\n BoldPlugin,\n CodePlugin,\n ItalicPlugin,\n StrikethroughPlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n UnderlinePlugin,\n} from '@udecode/plate-basic-marks/react';\nimport { BlockquotePlugin } from '@udecode/plate-block-quote/react';\nimport { SingleLinePlugin } from '@udecode/plate-break/react';\nimport { CaptionPlugin } from '@udecode/plate-caption/react';\nimport { CodeBlockPlugin } from '@udecode/plate-code-block/react';\nimport { CommentsPlugin } from '@udecode/plate-comments/react';\nimport {\n ParagraphPlugin,\n Plate,\n usePlateEditor,\n} from '@udecode/plate-common/react';\nimport { DatePlugin } from '@udecode/plate-date/react';\nimport { DndPlugin } from '@udecode/plate-dnd';\nimport { DocxPlugin } from '@udecode/plate-docx';\nimport { EmojiPlugin } from '@udecode/plate-emoji/react';\nimport { ExcalidrawPlugin } from '@udecode/plate-excalidraw/react';\nimport {\n FontBackgroundColorPlugin,\n FontColorPlugin,\n FontSizePlugin,\n} from '@udecode/plate-font/react';\nimport { HEADING_KEYS } from '@udecode/plate-heading';\nimport { HeadingPlugin, TocPlugin } from '@udecode/plate-heading/react';\nimport { HighlightPlugin } from '@udecode/plate-highlight/react';\nimport { HorizontalRulePlugin } from '@udecode/plate-horizontal-rule/react';\nimport { IndentPlugin } from '@udecode/plate-indent/react';\nimport { IndentListPlugin } from '@udecode/plate-indent-list/react';\nimport { JuicePlugin } from '@udecode/plate-juice';\nimport { KbdPlugin } from '@udecode/plate-kbd/react';\nimport { ColumnPlugin } from '@udecode/plate-layout/react';\nimport { LineHeightPlugin } from '@udecode/plate-line-height/react';\nimport { LinkPlugin } from '@udecode/plate-link/react';\nimport { ListPlugin, TodoListPlugin } from '@udecode/plate-list/react';\nimport { MarkdownPlugin } from '@udecode/plate-markdown';\nimport { ImagePlugin, MediaEmbedPlugin } from '@udecode/plate-media/react';\nimport { MentionPlugin } from '@udecode/plate-mention/react';\nimport { NodeIdPlugin } from '@udecode/plate-node-id';\nimport { NormalizeTypesPlugin } from '@udecode/plate-normalizers';\nimport { PlaywrightPlugin } from '@udecode/plate-playwright';\nimport { DeletePlugin, SelectOnBackspacePlugin } from '@udecode/plate-select';\nimport {\n BlockMenuPlugin,\n BlockSelectionPlugin,\n} from '@udecode/plate-selection/react';\nimport { SlashPlugin } from '@udecode/plate-slash-command/react';\nimport { TablePlugin } from '@udecode/plate-table/react';\nimport { TogglePlugin } from '@udecode/plate-toggle/react';\nimport { TrailingBlockPlugin } from '@udecode/plate-trailing-block';\nimport Prism from 'prismjs';\n\nimport { CheckPlugin } from '@/components/context/check-plugin';\nimport { settingsStore } from '@/components/context/settings-store';\nimport { aiPlugins } from '@/lib/plate/demo/plugins/ai-plugins';\nimport { getAutoformatOptions } from '@/lib/plate/demo/plugins/autoformatOptions';\nimport { copilotPlugins } from '@/lib/plate/demo/plugins/copilot-plugins';\nimport { createPlateUI } from '@/plate/create-plate-ui';\nimport { editableProps } from '@/plate/demo/editableProps';\nimport { isEnabled } from '@/plate/demo/is-enabled';\nimport { DragOverCursorPlugin } from '@/plate/demo/plugins/DragOverCursorPlugin';\nimport { exitBreakPlugin } from '@/plate/demo/plugins/exitBreakPlugin';\nimport { resetBlockTypePlugin } from '@/plate/demo/plugins/resetBlockTypePlugin';\nimport { softBreakPlugin } from '@/plate/demo/plugins/softBreakPlugin';\nimport { tabbablePlugin } from '@/plate/demo/plugins/tabbablePlugin';\nimport { commentsData, usersData } from '@/plate/demo/values/commentsValue';\nimport { usePlaygroundValue } from '@/plate/demo/values/usePlaygroundValue';\nimport { BlockContextMenu } from '@/components/plate-ui/block-context-menu';\nimport { CommentsPopover } from '@/components/plate-ui/comments-popover';\nimport {\n CursorOverlay,\n SelectionOverlayPlugin,\n} from '@/components/plate-ui/cursor-overlay';\nimport { Editor, EditorContainer } from '@/components/plate-ui/editor';\nimport { FixedToolbar } from '@/components/plate-ui/fixed-toolbar';\nimport { FixedToolbarButtons } from '@/components/plate-ui/fixed-toolbar-buttons';\nimport { FloatingToolbar } from '@/components/plate-ui/floating-toolbar';\nimport { FloatingToolbarButtons } from '@/components/plate-ui/floating-toolbar-buttons';\nimport { ImagePreview } from '@/components/plate-ui/image-preview';\nimport {\n FireLiComponent,\n FireMarker,\n} from '@/components/plate-ui/indent-fire-marker';\nimport {\n TodoLi,\n TodoMarker,\n} from '@/components/plate-ui/indent-todo-marker';\nimport { LinkFloatingToolbar } from '@/components/plate-ui/link-floating-toolbar';\n\nimport { usePlaygroundEnabled } from './usePlaygroundEnabled';\n\nexport const usePlaygroundEditor = (id: any = '', scrollSelector?: string) => {\n const enabledPlugins = settingsStore.use.checkedPlugins();\n const overridePlugins = usePlaygroundEnabled(id);\n const autoformatOptions = getAutoformatOptions(id, enabledPlugins);\n\n const value = usePlaygroundValue(id);\n const key = settingsStore.use.version();\n const editorId = id || 'playground-' + key;\n\n return usePlateEditor(\n {\n id: editorId,\n override: {\n components: createPlateUI({\n draggable: isEnabled('dnd', id),\n placeholder: isEnabled('placeholder', id),\n }),\n plugins: overridePlugins,\n },\n plugins: [\n // AI\n ...(id === 'ai' || enabledPlugins[AIChatPlugin.key] ? aiPlugins : []),\n ...(id === 'copilot' || enabledPlugins[CopilotPlugin.key]\n ? copilotPlugins\n : []),\n // Nodes\n HeadingPlugin,\n TocPlugin.configure({\n options: {\n scrollContainerSelector: `#${scrollSelector}`,\n topOffset: 80,\n },\n }),\n BlockquotePlugin,\n CodeBlockPlugin.configure({\n options: {\n prism: Prism,\n },\n }),\n HorizontalRulePlugin,\n LinkPlugin.extend({\n render: { afterEditable: () => },\n }),\n ...(id === 'list' ? [ListPlugin] : []),\n ImagePlugin.extend({\n options: {\n disableUploadInsert: true,\n },\n render: { afterEditable: ImagePreview },\n }),\n MediaEmbedPlugin,\n CaptionPlugin.configure({\n options: {\n plugins: [ImagePlugin, MediaEmbedPlugin],\n },\n }),\n DatePlugin,\n MentionPlugin.configure({\n options: {\n triggerPreviousCharPattern: /^$|^[\\s\"']$/,\n },\n }),\n SlashPlugin,\n TablePlugin.configure({\n options: {\n enableMerging: id === 'tableMerge',\n },\n }),\n ColumnPlugin,\n SelectionOverlayPlugin,\n\n TodoListPlugin,\n TogglePlugin,\n ExcalidrawPlugin,\n // Marks\n BoldPlugin,\n ItalicPlugin,\n UnderlinePlugin,\n StrikethroughPlugin,\n CodePlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n FontColorPlugin,\n FontBackgroundColorPlugin,\n FontSizePlugin,\n HighlightPlugin,\n KbdPlugin,\n\n // Block Style\n AlignPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n MediaEmbedPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n ImagePlugin.key,\n HEADING_KEYS.h6,\n ],\n },\n }),\n IndentPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n }),\n IndentListPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n options: {\n listStyleTypes: {\n fire: {\n liComponent: FireLiComponent,\n markerComponent: FireMarker,\n type: 'fire',\n },\n todo: {\n liComponent: TodoLi,\n markerComponent: TodoMarker,\n type: 'todo',\n },\n },\n },\n }),\n LineHeightPlugin.extend({\n inject: {\n nodeProps: {\n defaultNodeValue: 1.5,\n validNodeValues: [1, 1.2, 1.5, 2, 3],\n },\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n ],\n },\n }),\n\n // Functionality\n AutoformatPlugin.configure({\n options: autoformatOptions,\n }),\n BlockSelectionPlugin.configure({\n options: {\n areaOptions: {\n behaviour: {\n scrolling: {\n speedDivider: 1.5,\n },\n startThreshold: 10,\n },\n boundaries: `#${scrollSelector}`,\n container: `#${scrollSelector}`,\n selectables: [`#${scrollSelector} .slate-selectable`],\n selectionAreaClass: 'slate-selection-area',\n },\n enableContextMenu: true,\n },\n }),\n BlockMenuPlugin.configure({\n render: { aboveEditable: BlockContextMenu },\n }),\n DndPlugin.configure({\n options: {\n enableScroller: true,\n onDropFiles: ({ dragItem, editor, target }) => {\n editor\n .getTransforms(ImagePlugin)\n .insertImageFromFiles(dragItem.files, {\n at: target,\n nextBlock: false,\n });\n },\n },\n }),\n EmojiPlugin,\n exitBreakPlugin,\n NodeIdPlugin,\n NormalizeTypesPlugin.configure({\n options: {\n rules: [{ path: [0], strictType: HEADING_KEYS.h1 }],\n },\n }),\n resetBlockTypePlugin,\n SelectOnBackspacePlugin.configure({\n options: {\n query: {\n allow: [ImagePlugin.key, HorizontalRulePlugin.key],\n },\n },\n }),\n DeletePlugin,\n SingleLinePlugin,\n softBreakPlugin,\n tabbablePlugin,\n TrailingBlockPlugin.configure({\n options: { type: ParagraphPlugin.key },\n }),\n DragOverCursorPlugin,\n\n // Collaboration\n CommentsPlugin.configure({\n options: {\n comments: commentsData,\n myUserId: '1',\n users: usersData,\n },\n }),\n\n // Deserialization\n DocxPlugin,\n MarkdownPlugin.configure({ options: { indentList: true } }),\n JuicePlugin,\n\n // Testing\n PlaywrightPlugin.configure({\n enabled: process.env.NODE_ENV !== 'production',\n }),\n ],\n value: value,\n },\n []\n );\n};\n\nexport default function PlaygroundDemo({\n id,\n className,\n scrollSelector,\n}: {\n id?: ValueId;\n className?: string;\n scrollSelector?: string;\n}) {\n const containerRef = useRef(null);\n const enabled = settingsStore.use.checkedComponents();\n\n const editor = usePlaygroundEditor(\n id,\n scrollSelector ?? `blockSelection-${id}`\n );\n\n return (\n \n \n \n \n \n \n \n \n \n\n
\n \n \n\n \n \n \n \n \n \n \n\n \n \n \n \n\n \n \n \n
\n
\n
\n );\n}\n\nconst DemoIdContext = React.createContext(undefined);\n\nexport function DemoId({\n id,\n children,\n}: {\n children: React.ReactNode;\n id?: string;\n}) {\n return {children};\n}\n\nexport function useDemoId() {\n return React.useContext(DemoIdContext);\n}\n", "path": "example/playground-demo.tsx", "target": "components/playground-demo.tsx", "type": "registry:example" diff --git a/apps/www/public/r/styles/default/playground-demo.json b/apps/www/public/r/styles/default/playground-demo.json index de016eaf22..8027bbb752 100644 --- a/apps/www/public/r/styles/default/playground-demo.json +++ b/apps/www/public/r/styles/default/playground-demo.json @@ -1,7 +1,7 @@ { "files": [ { - "content": "'use client';\n\nimport React, { useRef } from 'react';\n\nimport type { ValueId } from '@/config/customizer-plugins';\n\nimport { cn } from '@udecode/cn';\nimport { AIChatPlugin, CopilotPlugin } from '@udecode/plate-ai/react';\nimport { AlignPlugin } from '@udecode/plate-alignment/react';\nimport { AutoformatPlugin } from '@udecode/plate-autoformat/react';\nimport {\n BoldPlugin,\n CodePlugin,\n ItalicPlugin,\n StrikethroughPlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n UnderlinePlugin,\n} from '@udecode/plate-basic-marks/react';\nimport { BlockquotePlugin } from '@udecode/plate-block-quote/react';\nimport { SingleLinePlugin } from '@udecode/plate-break/react';\nimport { CaptionPlugin } from '@udecode/plate-caption/react';\nimport { CodeBlockPlugin } from '@udecode/plate-code-block/react';\nimport { CommentsPlugin } from '@udecode/plate-comments/react';\nimport {\n ParagraphPlugin,\n Plate,\n usePlateEditor,\n} from '@udecode/plate-common/react';\nimport { DatePlugin } from '@udecode/plate-date/react';\nimport { DndPlugin } from '@udecode/plate-dnd';\nimport { DocxPlugin } from '@udecode/plate-docx';\nimport { EmojiPlugin } from '@udecode/plate-emoji/react';\nimport { ExcalidrawPlugin } from '@udecode/plate-excalidraw/react';\nimport {\n FontBackgroundColorPlugin,\n FontColorPlugin,\n FontSizePlugin,\n} from '@udecode/plate-font/react';\nimport { HEADING_KEYS } from '@udecode/plate-heading';\nimport { HeadingPlugin, TocPlugin } from '@udecode/plate-heading/react';\nimport { HighlightPlugin } from '@udecode/plate-highlight/react';\nimport { HorizontalRulePlugin } from '@udecode/plate-horizontal-rule/react';\nimport { IndentPlugin } from '@udecode/plate-indent/react';\nimport { IndentListPlugin } from '@udecode/plate-indent-list/react';\nimport { JuicePlugin } from '@udecode/plate-juice';\nimport { KbdPlugin } from '@udecode/plate-kbd/react';\nimport { ColumnPlugin } from '@udecode/plate-layout/react';\nimport { LineHeightPlugin } from '@udecode/plate-line-height/react';\nimport { LinkPlugin } from '@udecode/plate-link/react';\nimport { ListPlugin, TodoListPlugin } from '@udecode/plate-list/react';\nimport { MarkdownPlugin } from '@udecode/plate-markdown';\nimport { ImagePlugin, MediaEmbedPlugin } from '@udecode/plate-media/react';\nimport { MentionPlugin } from '@udecode/plate-mention/react';\nimport { NodeIdPlugin } from '@udecode/plate-node-id';\nimport { NormalizeTypesPlugin } from '@udecode/plate-normalizers';\nimport { PlaywrightPlugin } from '@udecode/plate-playwright';\nimport { DeletePlugin, SelectOnBackspacePlugin } from '@udecode/plate-select';\nimport {\n BlockMenuPlugin,\n BlockSelectionPlugin,\n} from '@udecode/plate-selection/react';\nimport { SlashPlugin } from '@udecode/plate-slash-command/react';\nimport { TablePlugin } from '@udecode/plate-table/react';\nimport { TogglePlugin } from '@udecode/plate-toggle/react';\nimport { TrailingBlockPlugin } from '@udecode/plate-trailing-block';\nimport Prism from 'prismjs';\n\nimport { CheckPlugin } from '@/components/context/check-plugin';\nimport { settingsStore } from '@/components/context/settings-store';\nimport { aiPlugins } from '@/lib/plate/demo/plugins/ai-plugins';\nimport { getAutoformatOptions } from '@/lib/plate/demo/plugins/autoformatOptions';\nimport { copilotPlugins } from '@/lib/plate/demo/plugins/copilot-plugins';\nimport { createPlateUI } from '@/plate/create-plate-ui';\nimport { editableProps } from '@/plate/demo/editableProps';\nimport { isEnabled } from '@/plate/demo/is-enabled';\nimport { DragOverCursorPlugin } from '@/plate/demo/plugins/DragOverCursorPlugin';\nimport { exitBreakPlugin } from '@/plate/demo/plugins/exitBreakPlugin';\nimport { resetBlockTypePlugin } from '@/plate/demo/plugins/resetBlockTypePlugin';\nimport { softBreakPlugin } from '@/plate/demo/plugins/softBreakPlugin';\nimport { tabbablePlugin } from '@/plate/demo/plugins/tabbablePlugin';\nimport { commentsData, usersData } from '@/plate/demo/values/commentsValue';\nimport { usePlaygroundValue } from '@/plate/demo/values/usePlaygroundValue';\nimport { BlockContextMenu } from '@/components/plate-ui/block-context-menu';\nimport { CommentsPopover } from '@/components/plate-ui/comments-popover';\nimport {\n CursorOverlay,\n SelectionOverlayPlugin,\n} from '@/components/plate-ui/cursor-overlay';\nimport { Editor, EditorContainer } from '@/components/plate-ui/editor';\nimport { FixedToolbar } from '@/components/plate-ui/fixed-toolbar';\nimport { FixedToolbarButtons } from '@/components/plate-ui/fixed-toolbar-buttons';\nimport { FloatingToolbar } from '@/components/plate-ui/floating-toolbar';\nimport { FloatingToolbarButtons } from '@/components/plate-ui/floating-toolbar-buttons';\nimport { ImagePreview } from '@/components/plate-ui/image-preview';\nimport {\n FireLiComponent,\n FireMarker,\n} from '@/components/plate-ui/indent-fire-marker';\nimport {\n TodoLi,\n TodoMarker,\n} from '@/components/plate-ui/indent-todo-marker';\nimport { LinkFloatingToolbar } from '@/components/plate-ui/link-floating-toolbar';\n\nimport { usePlaygroundEnabled } from './usePlaygroundEnabled';\n\nexport const usePlaygroundEditor = (id: any = '', scrollSelector?: string) => {\n const enabledPlugins = settingsStore.use.checkedPlugins();\n const overridePlugins = usePlaygroundEnabled(id);\n const autoformatOptions = getAutoformatOptions(id, enabledPlugins);\n\n const value = usePlaygroundValue(id);\n const key = settingsStore.use.version();\n const editorId = id || 'playground-' + key;\n\n return usePlateEditor(\n {\n id: editorId,\n override: {\n components: createPlateUI({\n draggable: isEnabled('dnd', id),\n placeholder: isEnabled('placeholder', id),\n }),\n plugins: overridePlugins,\n },\n plugins: [\n // AI\n ...(id === 'ai' || enabledPlugins[AIChatPlugin.key] ? aiPlugins : []),\n ...(id === 'copilot' || enabledPlugins[CopilotPlugin.key]\n ? copilotPlugins\n : []),\n // Nodes\n HeadingPlugin,\n TocPlugin.configure({\n options: {\n scrollContainerSelector: `#${scrollSelector}`,\n topOffset: 80,\n },\n }),\n BlockquotePlugin,\n CodeBlockPlugin.configure({\n options: {\n prism: Prism,\n },\n }),\n HorizontalRulePlugin,\n LinkPlugin.extend({\n render: { afterEditable: () => },\n }),\n ...(id === 'list' ? [ListPlugin] : []),\n ImagePlugin.extend({\n render: { afterEditable: ImagePreview },\n }),\n MediaEmbedPlugin,\n CaptionPlugin.configure({\n options: {\n plugins: [ImagePlugin, MediaEmbedPlugin],\n },\n }),\n DatePlugin,\n MentionPlugin.configure({\n options: {\n triggerPreviousCharPattern: /^$|^[\\s\"']$/,\n },\n }),\n SlashPlugin,\n TablePlugin.configure({\n options: {\n enableMerging: id === 'tableMerge',\n },\n }),\n ColumnPlugin,\n SelectionOverlayPlugin,\n\n TodoListPlugin,\n TogglePlugin,\n ExcalidrawPlugin,\n // Marks\n BoldPlugin,\n ItalicPlugin,\n UnderlinePlugin,\n StrikethroughPlugin,\n CodePlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n FontColorPlugin,\n FontBackgroundColorPlugin,\n FontSizePlugin,\n HighlightPlugin,\n KbdPlugin,\n\n // Block Style\n AlignPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n MediaEmbedPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n ImagePlugin.key,\n HEADING_KEYS.h6,\n ],\n },\n }),\n IndentPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n }),\n IndentListPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n options: {\n listStyleTypes: {\n fire: {\n liComponent: FireLiComponent,\n markerComponent: FireMarker,\n type: 'fire',\n },\n todo: {\n liComponent: TodoLi,\n markerComponent: TodoMarker,\n type: 'todo',\n },\n },\n },\n }),\n LineHeightPlugin.extend({\n inject: {\n nodeProps: {\n defaultNodeValue: 1.5,\n validNodeValues: [1, 1.2, 1.5, 2, 3],\n },\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n ],\n },\n }),\n\n // Functionality\n AutoformatPlugin.configure({\n options: autoformatOptions,\n }),\n BlockSelectionPlugin.configure({\n options: {\n areaOptions: {\n behaviour: {\n scrolling: {\n speedDivider: 1.5,\n },\n startThreshold: 10,\n },\n boundaries: `#${scrollSelector}`,\n container: `#${scrollSelector}`,\n selectables: [`#${scrollSelector} .slate-selectable`],\n selectionAreaClass: 'slate-selection-area',\n },\n enableContextMenu: true,\n },\n }),\n BlockMenuPlugin.configure({\n render: { aboveEditable: BlockContextMenu },\n }),\n DndPlugin.configure({ options: { enableScroller: true } }),\n EmojiPlugin,\n exitBreakPlugin,\n NodeIdPlugin,\n NormalizeTypesPlugin.configure({\n options: {\n rules: [{ path: [0], strictType: HEADING_KEYS.h1 }],\n },\n }),\n resetBlockTypePlugin,\n SelectOnBackspacePlugin.configure({\n options: {\n query: {\n allow: [ImagePlugin.key, HorizontalRulePlugin.key],\n },\n },\n }),\n DeletePlugin,\n SingleLinePlugin,\n softBreakPlugin,\n tabbablePlugin,\n TrailingBlockPlugin.configure({\n options: { type: ParagraphPlugin.key },\n }),\n DragOverCursorPlugin,\n\n // Collaboration\n CommentsPlugin.configure({\n options: {\n comments: commentsData,\n myUserId: '1',\n users: usersData,\n },\n }),\n\n // Deserialization\n DocxPlugin,\n MarkdownPlugin.configure({ options: { indentList: true } }),\n JuicePlugin,\n\n // Testing\n PlaywrightPlugin.configure({\n enabled: process.env.NODE_ENV !== 'production',\n }),\n ],\n value: value,\n },\n []\n );\n};\n\nexport default function PlaygroundDemo({\n id,\n className,\n scrollSelector,\n}: {\n id?: ValueId;\n className?: string;\n scrollSelector?: string;\n}) {\n const containerRef = useRef(null);\n const enabled = settingsStore.use.checkedComponents();\n\n const editor = usePlaygroundEditor(\n id,\n scrollSelector ?? `blockSelection-${id}`\n );\n\n return (\n \n \n \n \n \n \n \n \n \n\n
\n \n \n\n \n \n \n \n \n \n \n\n \n \n \n \n\n \n \n \n
\n
\n
\n );\n}\n\nconst DemoIdContext = React.createContext(undefined);\n\nexport function DemoId({\n id,\n children,\n}: {\n children: React.ReactNode;\n id?: string;\n}) {\n return {children};\n}\n\nexport function useDemoId() {\n return React.useContext(DemoIdContext);\n}\n", + "content": "'use client';\n\nimport React, { useRef } from 'react';\n\nimport type { ValueId } from '@/config/customizer-plugins';\n\nimport { cn } from '@udecode/cn';\nimport { AIChatPlugin, CopilotPlugin } from '@udecode/plate-ai/react';\nimport { AlignPlugin } from '@udecode/plate-alignment/react';\nimport { AutoformatPlugin } from '@udecode/plate-autoformat/react';\nimport {\n BoldPlugin,\n CodePlugin,\n ItalicPlugin,\n StrikethroughPlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n UnderlinePlugin,\n} from '@udecode/plate-basic-marks/react';\nimport { BlockquotePlugin } from '@udecode/plate-block-quote/react';\nimport { SingleLinePlugin } from '@udecode/plate-break/react';\nimport { CaptionPlugin } from '@udecode/plate-caption/react';\nimport { CodeBlockPlugin } from '@udecode/plate-code-block/react';\nimport { CommentsPlugin } from '@udecode/plate-comments/react';\nimport {\n ParagraphPlugin,\n Plate,\n usePlateEditor,\n} from '@udecode/plate-common/react';\nimport { DatePlugin } from '@udecode/plate-date/react';\nimport { DndPlugin } from '@udecode/plate-dnd';\nimport { DocxPlugin } from '@udecode/plate-docx';\nimport { EmojiPlugin } from '@udecode/plate-emoji/react';\nimport { ExcalidrawPlugin } from '@udecode/plate-excalidraw/react';\nimport {\n FontBackgroundColorPlugin,\n FontColorPlugin,\n FontSizePlugin,\n} from '@udecode/plate-font/react';\nimport { HEADING_KEYS } from '@udecode/plate-heading';\nimport { HeadingPlugin, TocPlugin } from '@udecode/plate-heading/react';\nimport { HighlightPlugin } from '@udecode/plate-highlight/react';\nimport { HorizontalRulePlugin } from '@udecode/plate-horizontal-rule/react';\nimport { IndentPlugin } from '@udecode/plate-indent/react';\nimport { IndentListPlugin } from '@udecode/plate-indent-list/react';\nimport { JuicePlugin } from '@udecode/plate-juice';\nimport { KbdPlugin } from '@udecode/plate-kbd/react';\nimport { ColumnPlugin } from '@udecode/plate-layout/react';\nimport { LineHeightPlugin } from '@udecode/plate-line-height/react';\nimport { LinkPlugin } from '@udecode/plate-link/react';\nimport { ListPlugin, TodoListPlugin } from '@udecode/plate-list/react';\nimport { MarkdownPlugin } from '@udecode/plate-markdown';\nimport { ImagePlugin, MediaEmbedPlugin } from '@udecode/plate-media/react';\nimport { MentionPlugin } from '@udecode/plate-mention/react';\nimport { NodeIdPlugin } from '@udecode/plate-node-id';\nimport { NormalizeTypesPlugin } from '@udecode/plate-normalizers';\nimport { PlaywrightPlugin } from '@udecode/plate-playwright';\nimport { DeletePlugin, SelectOnBackspacePlugin } from '@udecode/plate-select';\nimport {\n BlockMenuPlugin,\n BlockSelectionPlugin,\n} from '@udecode/plate-selection/react';\nimport { SlashPlugin } from '@udecode/plate-slash-command/react';\nimport { TablePlugin } from '@udecode/plate-table/react';\nimport { TogglePlugin } from '@udecode/plate-toggle/react';\nimport { TrailingBlockPlugin } from '@udecode/plate-trailing-block';\nimport Prism from 'prismjs';\n\nimport { CheckPlugin } from '@/components/context/check-plugin';\nimport { settingsStore } from '@/components/context/settings-store';\nimport { aiPlugins } from '@/lib/plate/demo/plugins/ai-plugins';\nimport { getAutoformatOptions } from '@/lib/plate/demo/plugins/autoformatOptions';\nimport { copilotPlugins } from '@/lib/plate/demo/plugins/copilot-plugins';\nimport { createPlateUI } from '@/plate/create-plate-ui';\nimport { editableProps } from '@/plate/demo/editableProps';\nimport { isEnabled } from '@/plate/demo/is-enabled';\nimport { DragOverCursorPlugin } from '@/plate/demo/plugins/DragOverCursorPlugin';\nimport { exitBreakPlugin } from '@/plate/demo/plugins/exitBreakPlugin';\nimport { resetBlockTypePlugin } from '@/plate/demo/plugins/resetBlockTypePlugin';\nimport { softBreakPlugin } from '@/plate/demo/plugins/softBreakPlugin';\nimport { tabbablePlugin } from '@/plate/demo/plugins/tabbablePlugin';\nimport { commentsData, usersData } from '@/plate/demo/values/commentsValue';\nimport { usePlaygroundValue } from '@/plate/demo/values/usePlaygroundValue';\nimport { BlockContextMenu } from '@/components/plate-ui/block-context-menu';\nimport { CommentsPopover } from '@/components/plate-ui/comments-popover';\nimport {\n CursorOverlay,\n SelectionOverlayPlugin,\n} from '@/components/plate-ui/cursor-overlay';\nimport { Editor, EditorContainer } from '@/components/plate-ui/editor';\nimport { FixedToolbar } from '@/components/plate-ui/fixed-toolbar';\nimport { FixedToolbarButtons } from '@/components/plate-ui/fixed-toolbar-buttons';\nimport { FloatingToolbar } from '@/components/plate-ui/floating-toolbar';\nimport { FloatingToolbarButtons } from '@/components/plate-ui/floating-toolbar-buttons';\nimport { ImagePreview } from '@/components/plate-ui/image-preview';\nimport {\n FireLiComponent,\n FireMarker,\n} from '@/components/plate-ui/indent-fire-marker';\nimport {\n TodoLi,\n TodoMarker,\n} from '@/components/plate-ui/indent-todo-marker';\nimport { LinkFloatingToolbar } from '@/components/plate-ui/link-floating-toolbar';\n\nimport { usePlaygroundEnabled } from './usePlaygroundEnabled';\n\nexport const usePlaygroundEditor = (id: any = '', scrollSelector?: string) => {\n const enabledPlugins = settingsStore.use.checkedPlugins();\n const overridePlugins = usePlaygroundEnabled(id);\n const autoformatOptions = getAutoformatOptions(id, enabledPlugins);\n\n const value = usePlaygroundValue(id);\n const key = settingsStore.use.version();\n const editorId = id || 'playground-' + key;\n\n return usePlateEditor(\n {\n id: editorId,\n override: {\n components: createPlateUI({\n draggable: isEnabled('dnd', id),\n placeholder: isEnabled('placeholder', id),\n }),\n plugins: overridePlugins,\n },\n plugins: [\n // AI\n ...(id === 'ai' || enabledPlugins[AIChatPlugin.key] ? aiPlugins : []),\n ...(id === 'copilot' || enabledPlugins[CopilotPlugin.key]\n ? copilotPlugins\n : []),\n // Nodes\n HeadingPlugin,\n TocPlugin.configure({\n options: {\n scrollContainerSelector: `#${scrollSelector}`,\n topOffset: 80,\n },\n }),\n BlockquotePlugin,\n CodeBlockPlugin.configure({\n options: {\n prism: Prism,\n },\n }),\n HorizontalRulePlugin,\n LinkPlugin.extend({\n render: { afterEditable: () => },\n }),\n ...(id === 'list' ? [ListPlugin] : []),\n ImagePlugin.extend({\n options: {\n disableUploadInsert: true,\n },\n render: { afterEditable: ImagePreview },\n }),\n MediaEmbedPlugin,\n CaptionPlugin.configure({\n options: {\n plugins: [ImagePlugin, MediaEmbedPlugin],\n },\n }),\n DatePlugin,\n MentionPlugin.configure({\n options: {\n triggerPreviousCharPattern: /^$|^[\\s\"']$/,\n },\n }),\n SlashPlugin,\n TablePlugin.configure({\n options: {\n enableMerging: id === 'tableMerge',\n },\n }),\n ColumnPlugin,\n SelectionOverlayPlugin,\n\n TodoListPlugin,\n TogglePlugin,\n ExcalidrawPlugin,\n // Marks\n BoldPlugin,\n ItalicPlugin,\n UnderlinePlugin,\n StrikethroughPlugin,\n CodePlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n FontColorPlugin,\n FontBackgroundColorPlugin,\n FontSizePlugin,\n HighlightPlugin,\n KbdPlugin,\n\n // Block Style\n AlignPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n MediaEmbedPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n ImagePlugin.key,\n HEADING_KEYS.h6,\n ],\n },\n }),\n IndentPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n }),\n IndentListPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n options: {\n listStyleTypes: {\n fire: {\n liComponent: FireLiComponent,\n markerComponent: FireMarker,\n type: 'fire',\n },\n todo: {\n liComponent: TodoLi,\n markerComponent: TodoMarker,\n type: 'todo',\n },\n },\n },\n }),\n LineHeightPlugin.extend({\n inject: {\n nodeProps: {\n defaultNodeValue: 1.5,\n validNodeValues: [1, 1.2, 1.5, 2, 3],\n },\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n ],\n },\n }),\n\n // Functionality\n AutoformatPlugin.configure({\n options: autoformatOptions,\n }),\n BlockSelectionPlugin.configure({\n options: {\n areaOptions: {\n behaviour: {\n scrolling: {\n speedDivider: 1.5,\n },\n startThreshold: 10,\n },\n boundaries: `#${scrollSelector}`,\n container: `#${scrollSelector}`,\n selectables: [`#${scrollSelector} .slate-selectable`],\n selectionAreaClass: 'slate-selection-area',\n },\n enableContextMenu: true,\n },\n }),\n BlockMenuPlugin.configure({\n render: { aboveEditable: BlockContextMenu },\n }),\n DndPlugin.configure({\n options: {\n enableScroller: true,\n onDropFiles: ({ dragItem, editor, target }) => {\n editor\n .getTransforms(ImagePlugin)\n .insertImageFromFiles(dragItem.files, {\n at: target,\n nextBlock: false,\n });\n },\n },\n }),\n EmojiPlugin,\n exitBreakPlugin,\n NodeIdPlugin,\n NormalizeTypesPlugin.configure({\n options: {\n rules: [{ path: [0], strictType: HEADING_KEYS.h1 }],\n },\n }),\n resetBlockTypePlugin,\n SelectOnBackspacePlugin.configure({\n options: {\n query: {\n allow: [ImagePlugin.key, HorizontalRulePlugin.key],\n },\n },\n }),\n DeletePlugin,\n SingleLinePlugin,\n softBreakPlugin,\n tabbablePlugin,\n TrailingBlockPlugin.configure({\n options: { type: ParagraphPlugin.key },\n }),\n DragOverCursorPlugin,\n\n // Collaboration\n CommentsPlugin.configure({\n options: {\n comments: commentsData,\n myUserId: '1',\n users: usersData,\n },\n }),\n\n // Deserialization\n DocxPlugin,\n MarkdownPlugin.configure({ options: { indentList: true } }),\n JuicePlugin,\n\n // Testing\n PlaywrightPlugin.configure({\n enabled: process.env.NODE_ENV !== 'production',\n }),\n ],\n value: value,\n },\n []\n );\n};\n\nexport default function PlaygroundDemo({\n id,\n className,\n scrollSelector,\n}: {\n id?: ValueId;\n className?: string;\n scrollSelector?: string;\n}) {\n const containerRef = useRef(null);\n const enabled = settingsStore.use.checkedComponents();\n\n const editor = usePlaygroundEditor(\n id,\n scrollSelector ?? `blockSelection-${id}`\n );\n\n return (\n \n \n \n \n \n \n \n \n \n\n
\n \n \n\n \n \n \n \n \n \n \n\n \n \n \n \n\n \n \n \n
\n
\n
\n );\n}\n\nconst DemoIdContext = React.createContext(undefined);\n\nexport function DemoId({\n id,\n children,\n}: {\n children: React.ReactNode;\n id?: string;\n}) {\n return {children};\n}\n\nexport function useDemoId() {\n return React.useContext(DemoIdContext);\n}\n", "path": "example/playground-demo.tsx", "target": "components/playground-demo.tsx", "type": "registry:example" diff --git a/apps/www/public/r/styles/default/resizable-demo.json b/apps/www/public/r/styles/default/resizable-demo.json index c43b06c13b..02c877e5ee 100644 --- a/apps/www/public/r/styles/default/resizable-demo.json +++ b/apps/www/public/r/styles/default/resizable-demo.json @@ -4,7 +4,7 @@ }, "files": [ { - "content": "'use client';\n\nimport React, { useRef } from 'react';\n\nimport type { ValueId } from '@/config/customizer-plugins';\n\nimport { cn } from '@udecode/cn';\nimport { AIChatPlugin, CopilotPlugin } from '@udecode/plate-ai/react';\nimport { AlignPlugin } from '@udecode/plate-alignment/react';\nimport { AutoformatPlugin } from '@udecode/plate-autoformat/react';\nimport {\n BoldPlugin,\n CodePlugin,\n ItalicPlugin,\n StrikethroughPlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n UnderlinePlugin,\n} from '@udecode/plate-basic-marks/react';\nimport { BlockquotePlugin } from '@udecode/plate-block-quote/react';\nimport { SingleLinePlugin } from '@udecode/plate-break/react';\nimport { CaptionPlugin } from '@udecode/plate-caption/react';\nimport { CodeBlockPlugin } from '@udecode/plate-code-block/react';\nimport { CommentsPlugin } from '@udecode/plate-comments/react';\nimport {\n ParagraphPlugin,\n Plate,\n usePlateEditor,\n} from '@udecode/plate-common/react';\nimport { DatePlugin } from '@udecode/plate-date/react';\nimport { DndPlugin } from '@udecode/plate-dnd';\nimport { DocxPlugin } from '@udecode/plate-docx';\nimport { EmojiPlugin } from '@udecode/plate-emoji/react';\nimport { ExcalidrawPlugin } from '@udecode/plate-excalidraw/react';\nimport {\n FontBackgroundColorPlugin,\n FontColorPlugin,\n FontSizePlugin,\n} from '@udecode/plate-font/react';\nimport { HEADING_KEYS } from '@udecode/plate-heading';\nimport { HeadingPlugin, TocPlugin } from '@udecode/plate-heading/react';\nimport { HighlightPlugin } from '@udecode/plate-highlight/react';\nimport { HorizontalRulePlugin } from '@udecode/plate-horizontal-rule/react';\nimport { IndentPlugin } from '@udecode/plate-indent/react';\nimport { IndentListPlugin } from '@udecode/plate-indent-list/react';\nimport { JuicePlugin } from '@udecode/plate-juice';\nimport { KbdPlugin } from '@udecode/plate-kbd/react';\nimport { ColumnPlugin } from '@udecode/plate-layout/react';\nimport { LineHeightPlugin } from '@udecode/plate-line-height/react';\nimport { LinkPlugin } from '@udecode/plate-link/react';\nimport { ListPlugin, TodoListPlugin } from '@udecode/plate-list/react';\nimport { MarkdownPlugin } from '@udecode/plate-markdown';\nimport { ImagePlugin, MediaEmbedPlugin } from '@udecode/plate-media/react';\nimport { MentionPlugin } from '@udecode/plate-mention/react';\nimport { NodeIdPlugin } from '@udecode/plate-node-id';\nimport { NormalizeTypesPlugin } from '@udecode/plate-normalizers';\nimport { PlaywrightPlugin } from '@udecode/plate-playwright';\nimport { DeletePlugin, SelectOnBackspacePlugin } from '@udecode/plate-select';\nimport {\n BlockMenuPlugin,\n BlockSelectionPlugin,\n} from '@udecode/plate-selection/react';\nimport { SlashPlugin } from '@udecode/plate-slash-command/react';\nimport { TablePlugin } from '@udecode/plate-table/react';\nimport { TogglePlugin } from '@udecode/plate-toggle/react';\nimport { TrailingBlockPlugin } from '@udecode/plate-trailing-block';\nimport Prism from 'prismjs';\n\nimport { CheckPlugin } from '@/components/context/check-plugin';\nimport { settingsStore } from '@/components/context/settings-store';\nimport { aiPlugins } from '@/lib/plate/demo/plugins/ai-plugins';\nimport { getAutoformatOptions } from '@/lib/plate/demo/plugins/autoformatOptions';\nimport { copilotPlugins } from '@/lib/plate/demo/plugins/copilot-plugins';\nimport { createPlateUI } from '@/plate/create-plate-ui';\nimport { editableProps } from '@/plate/demo/editableProps';\nimport { isEnabled } from '@/plate/demo/is-enabled';\nimport { DragOverCursorPlugin } from '@/plate/demo/plugins/DragOverCursorPlugin';\nimport { exitBreakPlugin } from '@/plate/demo/plugins/exitBreakPlugin';\nimport { resetBlockTypePlugin } from '@/plate/demo/plugins/resetBlockTypePlugin';\nimport { softBreakPlugin } from '@/plate/demo/plugins/softBreakPlugin';\nimport { tabbablePlugin } from '@/plate/demo/plugins/tabbablePlugin';\nimport { commentsData, usersData } from '@/plate/demo/values/commentsValue';\nimport { usePlaygroundValue } from '@/plate/demo/values/usePlaygroundValue';\nimport { BlockContextMenu } from '@/components/plate-ui/block-context-menu';\nimport { CommentsPopover } from '@/components/plate-ui/comments-popover';\nimport {\n CursorOverlay,\n SelectionOverlayPlugin,\n} from '@/components/plate-ui/cursor-overlay';\nimport { Editor, EditorContainer } from '@/components/plate-ui/editor';\nimport { FixedToolbar } from '@/components/plate-ui/fixed-toolbar';\nimport { FixedToolbarButtons } from '@/components/plate-ui/fixed-toolbar-buttons';\nimport { FloatingToolbar } from '@/components/plate-ui/floating-toolbar';\nimport { FloatingToolbarButtons } from '@/components/plate-ui/floating-toolbar-buttons';\nimport { ImagePreview } from '@/components/plate-ui/image-preview';\nimport {\n FireLiComponent,\n FireMarker,\n} from '@/components/plate-ui/indent-fire-marker';\nimport {\n TodoLi,\n TodoMarker,\n} from '@/components/plate-ui/indent-todo-marker';\nimport { LinkFloatingToolbar } from '@/components/plate-ui/link-floating-toolbar';\n\nimport { usePlaygroundEnabled } from './usePlaygroundEnabled';\n\nexport const usePlaygroundEditor = (id: any = '', scrollSelector?: string) => {\n const enabledPlugins = settingsStore.use.checkedPlugins();\n const overridePlugins = usePlaygroundEnabled(id);\n const autoformatOptions = getAutoformatOptions(id, enabledPlugins);\n\n const value = usePlaygroundValue(id);\n const key = settingsStore.use.version();\n const editorId = id || 'playground-' + key;\n\n return usePlateEditor(\n {\n id: editorId,\n override: {\n components: createPlateUI({\n draggable: isEnabled('dnd', id),\n placeholder: isEnabled('placeholder', id),\n }),\n plugins: overridePlugins,\n },\n plugins: [\n // AI\n ...(id === 'ai' || enabledPlugins[AIChatPlugin.key] ? aiPlugins : []),\n ...(id === 'copilot' || enabledPlugins[CopilotPlugin.key]\n ? copilotPlugins\n : []),\n // Nodes\n HeadingPlugin,\n TocPlugin.configure({\n options: {\n scrollContainerSelector: `#${scrollSelector}`,\n topOffset: 80,\n },\n }),\n BlockquotePlugin,\n CodeBlockPlugin.configure({\n options: {\n prism: Prism,\n },\n }),\n HorizontalRulePlugin,\n LinkPlugin.extend({\n render: { afterEditable: () => },\n }),\n ...(id === 'list' ? [ListPlugin] : []),\n ImagePlugin.extend({\n render: { afterEditable: ImagePreview },\n }),\n MediaEmbedPlugin,\n CaptionPlugin.configure({\n options: {\n plugins: [ImagePlugin, MediaEmbedPlugin],\n },\n }),\n DatePlugin,\n MentionPlugin.configure({\n options: {\n triggerPreviousCharPattern: /^$|^[\\s\"']$/,\n },\n }),\n SlashPlugin,\n TablePlugin.configure({\n options: {\n enableMerging: id === 'tableMerge',\n },\n }),\n ColumnPlugin,\n SelectionOverlayPlugin,\n\n TodoListPlugin,\n TogglePlugin,\n ExcalidrawPlugin,\n // Marks\n BoldPlugin,\n ItalicPlugin,\n UnderlinePlugin,\n StrikethroughPlugin,\n CodePlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n FontColorPlugin,\n FontBackgroundColorPlugin,\n FontSizePlugin,\n HighlightPlugin,\n KbdPlugin,\n\n // Block Style\n AlignPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n MediaEmbedPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n ImagePlugin.key,\n HEADING_KEYS.h6,\n ],\n },\n }),\n IndentPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n }),\n IndentListPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n options: {\n listStyleTypes: {\n fire: {\n liComponent: FireLiComponent,\n markerComponent: FireMarker,\n type: 'fire',\n },\n todo: {\n liComponent: TodoLi,\n markerComponent: TodoMarker,\n type: 'todo',\n },\n },\n },\n }),\n LineHeightPlugin.extend({\n inject: {\n nodeProps: {\n defaultNodeValue: 1.5,\n validNodeValues: [1, 1.2, 1.5, 2, 3],\n },\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n ],\n },\n }),\n\n // Functionality\n AutoformatPlugin.configure({\n options: autoformatOptions,\n }),\n BlockSelectionPlugin.configure({\n options: {\n areaOptions: {\n behaviour: {\n scrolling: {\n speedDivider: 1.5,\n },\n startThreshold: 10,\n },\n boundaries: `#${scrollSelector}`,\n container: `#${scrollSelector}`,\n selectables: [`#${scrollSelector} .slate-selectable`],\n selectionAreaClass: 'slate-selection-area',\n },\n enableContextMenu: true,\n },\n }),\n BlockMenuPlugin.configure({\n render: { aboveEditable: BlockContextMenu },\n }),\n DndPlugin.configure({ options: { enableScroller: true } }),\n EmojiPlugin,\n exitBreakPlugin,\n NodeIdPlugin,\n NormalizeTypesPlugin.configure({\n options: {\n rules: [{ path: [0], strictType: HEADING_KEYS.h1 }],\n },\n }),\n resetBlockTypePlugin,\n SelectOnBackspacePlugin.configure({\n options: {\n query: {\n allow: [ImagePlugin.key, HorizontalRulePlugin.key],\n },\n },\n }),\n DeletePlugin,\n SingleLinePlugin,\n softBreakPlugin,\n tabbablePlugin,\n TrailingBlockPlugin.configure({\n options: { type: ParagraphPlugin.key },\n }),\n DragOverCursorPlugin,\n\n // Collaboration\n CommentsPlugin.configure({\n options: {\n comments: commentsData,\n myUserId: '1',\n users: usersData,\n },\n }),\n\n // Deserialization\n DocxPlugin,\n MarkdownPlugin.configure({ options: { indentList: true } }),\n JuicePlugin,\n\n // Testing\n PlaywrightPlugin.configure({\n enabled: process.env.NODE_ENV !== 'production',\n }),\n ],\n value: value,\n },\n []\n );\n};\n\nexport default function PlaygroundDemo({\n id,\n className,\n scrollSelector,\n}: {\n id?: ValueId;\n className?: string;\n scrollSelector?: string;\n}) {\n const containerRef = useRef(null);\n const enabled = settingsStore.use.checkedComponents();\n\n const editor = usePlaygroundEditor(\n id,\n scrollSelector ?? `blockSelection-${id}`\n );\n\n return (\n \n \n \n \n \n \n \n \n \n\n
\n \n \n\n \n \n \n \n \n \n \n\n \n \n \n \n\n \n \n \n
\n
\n
\n );\n}\n\nconst DemoIdContext = React.createContext(undefined);\n\nexport function DemoId({\n id,\n children,\n}: {\n children: React.ReactNode;\n id?: string;\n}) {\n return {children};\n}\n\nexport function useDemoId() {\n return React.useContext(DemoIdContext);\n}\n", + "content": "'use client';\n\nimport React, { useRef } from 'react';\n\nimport type { ValueId } from '@/config/customizer-plugins';\n\nimport { cn } from '@udecode/cn';\nimport { AIChatPlugin, CopilotPlugin } from '@udecode/plate-ai/react';\nimport { AlignPlugin } from '@udecode/plate-alignment/react';\nimport { AutoformatPlugin } from '@udecode/plate-autoformat/react';\nimport {\n BoldPlugin,\n CodePlugin,\n ItalicPlugin,\n StrikethroughPlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n UnderlinePlugin,\n} from '@udecode/plate-basic-marks/react';\nimport { BlockquotePlugin } from '@udecode/plate-block-quote/react';\nimport { SingleLinePlugin } from '@udecode/plate-break/react';\nimport { CaptionPlugin } from '@udecode/plate-caption/react';\nimport { CodeBlockPlugin } from '@udecode/plate-code-block/react';\nimport { CommentsPlugin } from '@udecode/plate-comments/react';\nimport {\n ParagraphPlugin,\n Plate,\n usePlateEditor,\n} from '@udecode/plate-common/react';\nimport { DatePlugin } from '@udecode/plate-date/react';\nimport { DndPlugin } from '@udecode/plate-dnd';\nimport { DocxPlugin } from '@udecode/plate-docx';\nimport { EmojiPlugin } from '@udecode/plate-emoji/react';\nimport { ExcalidrawPlugin } from '@udecode/plate-excalidraw/react';\nimport {\n FontBackgroundColorPlugin,\n FontColorPlugin,\n FontSizePlugin,\n} from '@udecode/plate-font/react';\nimport { HEADING_KEYS } from '@udecode/plate-heading';\nimport { HeadingPlugin, TocPlugin } from '@udecode/plate-heading/react';\nimport { HighlightPlugin } from '@udecode/plate-highlight/react';\nimport { HorizontalRulePlugin } from '@udecode/plate-horizontal-rule/react';\nimport { IndentPlugin } from '@udecode/plate-indent/react';\nimport { IndentListPlugin } from '@udecode/plate-indent-list/react';\nimport { JuicePlugin } from '@udecode/plate-juice';\nimport { KbdPlugin } from '@udecode/plate-kbd/react';\nimport { ColumnPlugin } from '@udecode/plate-layout/react';\nimport { LineHeightPlugin } from '@udecode/plate-line-height/react';\nimport { LinkPlugin } from '@udecode/plate-link/react';\nimport { ListPlugin, TodoListPlugin } from '@udecode/plate-list/react';\nimport { MarkdownPlugin } from '@udecode/plate-markdown';\nimport { ImagePlugin, MediaEmbedPlugin } from '@udecode/plate-media/react';\nimport { MentionPlugin } from '@udecode/plate-mention/react';\nimport { NodeIdPlugin } from '@udecode/plate-node-id';\nimport { NormalizeTypesPlugin } from '@udecode/plate-normalizers';\nimport { PlaywrightPlugin } from '@udecode/plate-playwright';\nimport { DeletePlugin, SelectOnBackspacePlugin } from '@udecode/plate-select';\nimport {\n BlockMenuPlugin,\n BlockSelectionPlugin,\n} from '@udecode/plate-selection/react';\nimport { SlashPlugin } from '@udecode/plate-slash-command/react';\nimport { TablePlugin } from '@udecode/plate-table/react';\nimport { TogglePlugin } from '@udecode/plate-toggle/react';\nimport { TrailingBlockPlugin } from '@udecode/plate-trailing-block';\nimport Prism from 'prismjs';\n\nimport { CheckPlugin } from '@/components/context/check-plugin';\nimport { settingsStore } from '@/components/context/settings-store';\nimport { aiPlugins } from '@/lib/plate/demo/plugins/ai-plugins';\nimport { getAutoformatOptions } from '@/lib/plate/demo/plugins/autoformatOptions';\nimport { copilotPlugins } from '@/lib/plate/demo/plugins/copilot-plugins';\nimport { createPlateUI } from '@/plate/create-plate-ui';\nimport { editableProps } from '@/plate/demo/editableProps';\nimport { isEnabled } from '@/plate/demo/is-enabled';\nimport { DragOverCursorPlugin } from '@/plate/demo/plugins/DragOverCursorPlugin';\nimport { exitBreakPlugin } from '@/plate/demo/plugins/exitBreakPlugin';\nimport { resetBlockTypePlugin } from '@/plate/demo/plugins/resetBlockTypePlugin';\nimport { softBreakPlugin } from '@/plate/demo/plugins/softBreakPlugin';\nimport { tabbablePlugin } from '@/plate/demo/plugins/tabbablePlugin';\nimport { commentsData, usersData } from '@/plate/demo/values/commentsValue';\nimport { usePlaygroundValue } from '@/plate/demo/values/usePlaygroundValue';\nimport { BlockContextMenu } from '@/components/plate-ui/block-context-menu';\nimport { CommentsPopover } from '@/components/plate-ui/comments-popover';\nimport {\n CursorOverlay,\n SelectionOverlayPlugin,\n} from '@/components/plate-ui/cursor-overlay';\nimport { Editor, EditorContainer } from '@/components/plate-ui/editor';\nimport { FixedToolbar } from '@/components/plate-ui/fixed-toolbar';\nimport { FixedToolbarButtons } from '@/components/plate-ui/fixed-toolbar-buttons';\nimport { FloatingToolbar } from '@/components/plate-ui/floating-toolbar';\nimport { FloatingToolbarButtons } from '@/components/plate-ui/floating-toolbar-buttons';\nimport { ImagePreview } from '@/components/plate-ui/image-preview';\nimport {\n FireLiComponent,\n FireMarker,\n} from '@/components/plate-ui/indent-fire-marker';\nimport {\n TodoLi,\n TodoMarker,\n} from '@/components/plate-ui/indent-todo-marker';\nimport { LinkFloatingToolbar } from '@/components/plate-ui/link-floating-toolbar';\n\nimport { usePlaygroundEnabled } from './usePlaygroundEnabled';\n\nexport const usePlaygroundEditor = (id: any = '', scrollSelector?: string) => {\n const enabledPlugins = settingsStore.use.checkedPlugins();\n const overridePlugins = usePlaygroundEnabled(id);\n const autoformatOptions = getAutoformatOptions(id, enabledPlugins);\n\n const value = usePlaygroundValue(id);\n const key = settingsStore.use.version();\n const editorId = id || 'playground-' + key;\n\n return usePlateEditor(\n {\n id: editorId,\n override: {\n components: createPlateUI({\n draggable: isEnabled('dnd', id),\n placeholder: isEnabled('placeholder', id),\n }),\n plugins: overridePlugins,\n },\n plugins: [\n // AI\n ...(id === 'ai' || enabledPlugins[AIChatPlugin.key] ? aiPlugins : []),\n ...(id === 'copilot' || enabledPlugins[CopilotPlugin.key]\n ? copilotPlugins\n : []),\n // Nodes\n HeadingPlugin,\n TocPlugin.configure({\n options: {\n scrollContainerSelector: `#${scrollSelector}`,\n topOffset: 80,\n },\n }),\n BlockquotePlugin,\n CodeBlockPlugin.configure({\n options: {\n prism: Prism,\n },\n }),\n HorizontalRulePlugin,\n LinkPlugin.extend({\n render: { afterEditable: () => },\n }),\n ...(id === 'list' ? [ListPlugin] : []),\n ImagePlugin.extend({\n options: {\n disableUploadInsert: true,\n },\n render: { afterEditable: ImagePreview },\n }),\n MediaEmbedPlugin,\n CaptionPlugin.configure({\n options: {\n plugins: [ImagePlugin, MediaEmbedPlugin],\n },\n }),\n DatePlugin,\n MentionPlugin.configure({\n options: {\n triggerPreviousCharPattern: /^$|^[\\s\"']$/,\n },\n }),\n SlashPlugin,\n TablePlugin.configure({\n options: {\n enableMerging: id === 'tableMerge',\n },\n }),\n ColumnPlugin,\n SelectionOverlayPlugin,\n\n TodoListPlugin,\n TogglePlugin,\n ExcalidrawPlugin,\n // Marks\n BoldPlugin,\n ItalicPlugin,\n UnderlinePlugin,\n StrikethroughPlugin,\n CodePlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n FontColorPlugin,\n FontBackgroundColorPlugin,\n FontSizePlugin,\n HighlightPlugin,\n KbdPlugin,\n\n // Block Style\n AlignPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n MediaEmbedPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n ImagePlugin.key,\n HEADING_KEYS.h6,\n ],\n },\n }),\n IndentPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n }),\n IndentListPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n options: {\n listStyleTypes: {\n fire: {\n liComponent: FireLiComponent,\n markerComponent: FireMarker,\n type: 'fire',\n },\n todo: {\n liComponent: TodoLi,\n markerComponent: TodoMarker,\n type: 'todo',\n },\n },\n },\n }),\n LineHeightPlugin.extend({\n inject: {\n nodeProps: {\n defaultNodeValue: 1.5,\n validNodeValues: [1, 1.2, 1.5, 2, 3],\n },\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n ],\n },\n }),\n\n // Functionality\n AutoformatPlugin.configure({\n options: autoformatOptions,\n }),\n BlockSelectionPlugin.configure({\n options: {\n areaOptions: {\n behaviour: {\n scrolling: {\n speedDivider: 1.5,\n },\n startThreshold: 10,\n },\n boundaries: `#${scrollSelector}`,\n container: `#${scrollSelector}`,\n selectables: [`#${scrollSelector} .slate-selectable`],\n selectionAreaClass: 'slate-selection-area',\n },\n enableContextMenu: true,\n },\n }),\n BlockMenuPlugin.configure({\n render: { aboveEditable: BlockContextMenu },\n }),\n DndPlugin.configure({\n options: {\n enableScroller: true,\n onDropFiles: ({ dragItem, editor, target }) => {\n editor\n .getTransforms(ImagePlugin)\n .insertImageFromFiles(dragItem.files, {\n at: target,\n nextBlock: false,\n });\n },\n },\n }),\n EmojiPlugin,\n exitBreakPlugin,\n NodeIdPlugin,\n NormalizeTypesPlugin.configure({\n options: {\n rules: [{ path: [0], strictType: HEADING_KEYS.h1 }],\n },\n }),\n resetBlockTypePlugin,\n SelectOnBackspacePlugin.configure({\n options: {\n query: {\n allow: [ImagePlugin.key, HorizontalRulePlugin.key],\n },\n },\n }),\n DeletePlugin,\n SingleLinePlugin,\n softBreakPlugin,\n tabbablePlugin,\n TrailingBlockPlugin.configure({\n options: { type: ParagraphPlugin.key },\n }),\n DragOverCursorPlugin,\n\n // Collaboration\n CommentsPlugin.configure({\n options: {\n comments: commentsData,\n myUserId: '1',\n users: usersData,\n },\n }),\n\n // Deserialization\n DocxPlugin,\n MarkdownPlugin.configure({ options: { indentList: true } }),\n JuicePlugin,\n\n // Testing\n PlaywrightPlugin.configure({\n enabled: process.env.NODE_ENV !== 'production',\n }),\n ],\n value: value,\n },\n []\n );\n};\n\nexport default function PlaygroundDemo({\n id,\n className,\n scrollSelector,\n}: {\n id?: ValueId;\n className?: string;\n scrollSelector?: string;\n}) {\n const containerRef = useRef(null);\n const enabled = settingsStore.use.checkedComponents();\n\n const editor = usePlaygroundEditor(\n id,\n scrollSelector ?? `blockSelection-${id}`\n );\n\n return (\n \n \n \n \n \n \n \n \n \n\n
\n \n \n\n \n \n \n \n \n \n \n\n \n \n \n \n\n \n \n \n
\n
\n
\n );\n}\n\nconst DemoIdContext = React.createContext(undefined);\n\nexport function DemoId({\n id,\n children,\n}: {\n children: React.ReactNode;\n id?: string;\n}) {\n return {children};\n}\n\nexport function useDemoId() {\n return React.useContext(DemoIdContext);\n}\n", "path": "example/playground-demo.tsx", "target": "components/playground-demo.tsx", "type": "registry:example" diff --git a/apps/www/public/r/styles/default/slash-command-demo.json b/apps/www/public/r/styles/default/slash-command-demo.json index 19f61e7051..09306aa04c 100644 --- a/apps/www/public/r/styles/default/slash-command-demo.json +++ b/apps/www/public/r/styles/default/slash-command-demo.json @@ -4,7 +4,7 @@ }, "files": [ { - "content": "'use client';\n\nimport React, { useRef } from 'react';\n\nimport type { ValueId } from '@/config/customizer-plugins';\n\nimport { cn } from '@udecode/cn';\nimport { AIChatPlugin, CopilotPlugin } from '@udecode/plate-ai/react';\nimport { AlignPlugin } from '@udecode/plate-alignment/react';\nimport { AutoformatPlugin } from '@udecode/plate-autoformat/react';\nimport {\n BoldPlugin,\n CodePlugin,\n ItalicPlugin,\n StrikethroughPlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n UnderlinePlugin,\n} from '@udecode/plate-basic-marks/react';\nimport { BlockquotePlugin } from '@udecode/plate-block-quote/react';\nimport { SingleLinePlugin } from '@udecode/plate-break/react';\nimport { CaptionPlugin } from '@udecode/plate-caption/react';\nimport { CodeBlockPlugin } from '@udecode/plate-code-block/react';\nimport { CommentsPlugin } from '@udecode/plate-comments/react';\nimport {\n ParagraphPlugin,\n Plate,\n usePlateEditor,\n} from '@udecode/plate-common/react';\nimport { DatePlugin } from '@udecode/plate-date/react';\nimport { DndPlugin } from '@udecode/plate-dnd';\nimport { DocxPlugin } from '@udecode/plate-docx';\nimport { EmojiPlugin } from '@udecode/plate-emoji/react';\nimport { ExcalidrawPlugin } from '@udecode/plate-excalidraw/react';\nimport {\n FontBackgroundColorPlugin,\n FontColorPlugin,\n FontSizePlugin,\n} from '@udecode/plate-font/react';\nimport { HEADING_KEYS } from '@udecode/plate-heading';\nimport { HeadingPlugin, TocPlugin } from '@udecode/plate-heading/react';\nimport { HighlightPlugin } from '@udecode/plate-highlight/react';\nimport { HorizontalRulePlugin } from '@udecode/plate-horizontal-rule/react';\nimport { IndentPlugin } from '@udecode/plate-indent/react';\nimport { IndentListPlugin } from '@udecode/plate-indent-list/react';\nimport { JuicePlugin } from '@udecode/plate-juice';\nimport { KbdPlugin } from '@udecode/plate-kbd/react';\nimport { ColumnPlugin } from '@udecode/plate-layout/react';\nimport { LineHeightPlugin } from '@udecode/plate-line-height/react';\nimport { LinkPlugin } from '@udecode/plate-link/react';\nimport { ListPlugin, TodoListPlugin } from '@udecode/plate-list/react';\nimport { MarkdownPlugin } from '@udecode/plate-markdown';\nimport { ImagePlugin, MediaEmbedPlugin } from '@udecode/plate-media/react';\nimport { MentionPlugin } from '@udecode/plate-mention/react';\nimport { NodeIdPlugin } from '@udecode/plate-node-id';\nimport { NormalizeTypesPlugin } from '@udecode/plate-normalizers';\nimport { PlaywrightPlugin } from '@udecode/plate-playwright';\nimport { DeletePlugin, SelectOnBackspacePlugin } from '@udecode/plate-select';\nimport {\n BlockMenuPlugin,\n BlockSelectionPlugin,\n} from '@udecode/plate-selection/react';\nimport { SlashPlugin } from '@udecode/plate-slash-command/react';\nimport { TablePlugin } from '@udecode/plate-table/react';\nimport { TogglePlugin } from '@udecode/plate-toggle/react';\nimport { TrailingBlockPlugin } from '@udecode/plate-trailing-block';\nimport Prism from 'prismjs';\n\nimport { CheckPlugin } from '@/components/context/check-plugin';\nimport { settingsStore } from '@/components/context/settings-store';\nimport { aiPlugins } from '@/lib/plate/demo/plugins/ai-plugins';\nimport { getAutoformatOptions } from '@/lib/plate/demo/plugins/autoformatOptions';\nimport { copilotPlugins } from '@/lib/plate/demo/plugins/copilot-plugins';\nimport { createPlateUI } from '@/plate/create-plate-ui';\nimport { editableProps } from '@/plate/demo/editableProps';\nimport { isEnabled } from '@/plate/demo/is-enabled';\nimport { DragOverCursorPlugin } from '@/plate/demo/plugins/DragOverCursorPlugin';\nimport { exitBreakPlugin } from '@/plate/demo/plugins/exitBreakPlugin';\nimport { resetBlockTypePlugin } from '@/plate/demo/plugins/resetBlockTypePlugin';\nimport { softBreakPlugin } from '@/plate/demo/plugins/softBreakPlugin';\nimport { tabbablePlugin } from '@/plate/demo/plugins/tabbablePlugin';\nimport { commentsData, usersData } from '@/plate/demo/values/commentsValue';\nimport { usePlaygroundValue } from '@/plate/demo/values/usePlaygroundValue';\nimport { BlockContextMenu } from '@/components/plate-ui/block-context-menu';\nimport { CommentsPopover } from '@/components/plate-ui/comments-popover';\nimport {\n CursorOverlay,\n SelectionOverlayPlugin,\n} from '@/components/plate-ui/cursor-overlay';\nimport { Editor, EditorContainer } from '@/components/plate-ui/editor';\nimport { FixedToolbar } from '@/components/plate-ui/fixed-toolbar';\nimport { FixedToolbarButtons } from '@/components/plate-ui/fixed-toolbar-buttons';\nimport { FloatingToolbar } from '@/components/plate-ui/floating-toolbar';\nimport { FloatingToolbarButtons } from '@/components/plate-ui/floating-toolbar-buttons';\nimport { ImagePreview } from '@/components/plate-ui/image-preview';\nimport {\n FireLiComponent,\n FireMarker,\n} from '@/components/plate-ui/indent-fire-marker';\nimport {\n TodoLi,\n TodoMarker,\n} from '@/components/plate-ui/indent-todo-marker';\nimport { LinkFloatingToolbar } from '@/components/plate-ui/link-floating-toolbar';\n\nimport { usePlaygroundEnabled } from './usePlaygroundEnabled';\n\nexport const usePlaygroundEditor = (id: any = '', scrollSelector?: string) => {\n const enabledPlugins = settingsStore.use.checkedPlugins();\n const overridePlugins = usePlaygroundEnabled(id);\n const autoformatOptions = getAutoformatOptions(id, enabledPlugins);\n\n const value = usePlaygroundValue(id);\n const key = settingsStore.use.version();\n const editorId = id || 'playground-' + key;\n\n return usePlateEditor(\n {\n id: editorId,\n override: {\n components: createPlateUI({\n draggable: isEnabled('dnd', id),\n placeholder: isEnabled('placeholder', id),\n }),\n plugins: overridePlugins,\n },\n plugins: [\n // AI\n ...(id === 'ai' || enabledPlugins[AIChatPlugin.key] ? aiPlugins : []),\n ...(id === 'copilot' || enabledPlugins[CopilotPlugin.key]\n ? copilotPlugins\n : []),\n // Nodes\n HeadingPlugin,\n TocPlugin.configure({\n options: {\n scrollContainerSelector: `#${scrollSelector}`,\n topOffset: 80,\n },\n }),\n BlockquotePlugin,\n CodeBlockPlugin.configure({\n options: {\n prism: Prism,\n },\n }),\n HorizontalRulePlugin,\n LinkPlugin.extend({\n render: { afterEditable: () => },\n }),\n ...(id === 'list' ? [ListPlugin] : []),\n ImagePlugin.extend({\n render: { afterEditable: ImagePreview },\n }),\n MediaEmbedPlugin,\n CaptionPlugin.configure({\n options: {\n plugins: [ImagePlugin, MediaEmbedPlugin],\n },\n }),\n DatePlugin,\n MentionPlugin.configure({\n options: {\n triggerPreviousCharPattern: /^$|^[\\s\"']$/,\n },\n }),\n SlashPlugin,\n TablePlugin.configure({\n options: {\n enableMerging: id === 'tableMerge',\n },\n }),\n ColumnPlugin,\n SelectionOverlayPlugin,\n\n TodoListPlugin,\n TogglePlugin,\n ExcalidrawPlugin,\n // Marks\n BoldPlugin,\n ItalicPlugin,\n UnderlinePlugin,\n StrikethroughPlugin,\n CodePlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n FontColorPlugin,\n FontBackgroundColorPlugin,\n FontSizePlugin,\n HighlightPlugin,\n KbdPlugin,\n\n // Block Style\n AlignPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n MediaEmbedPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n ImagePlugin.key,\n HEADING_KEYS.h6,\n ],\n },\n }),\n IndentPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n }),\n IndentListPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n options: {\n listStyleTypes: {\n fire: {\n liComponent: FireLiComponent,\n markerComponent: FireMarker,\n type: 'fire',\n },\n todo: {\n liComponent: TodoLi,\n markerComponent: TodoMarker,\n type: 'todo',\n },\n },\n },\n }),\n LineHeightPlugin.extend({\n inject: {\n nodeProps: {\n defaultNodeValue: 1.5,\n validNodeValues: [1, 1.2, 1.5, 2, 3],\n },\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n ],\n },\n }),\n\n // Functionality\n AutoformatPlugin.configure({\n options: autoformatOptions,\n }),\n BlockSelectionPlugin.configure({\n options: {\n areaOptions: {\n behaviour: {\n scrolling: {\n speedDivider: 1.5,\n },\n startThreshold: 10,\n },\n boundaries: `#${scrollSelector}`,\n container: `#${scrollSelector}`,\n selectables: [`#${scrollSelector} .slate-selectable`],\n selectionAreaClass: 'slate-selection-area',\n },\n enableContextMenu: true,\n },\n }),\n BlockMenuPlugin.configure({\n render: { aboveEditable: BlockContextMenu },\n }),\n DndPlugin.configure({ options: { enableScroller: true } }),\n EmojiPlugin,\n exitBreakPlugin,\n NodeIdPlugin,\n NormalizeTypesPlugin.configure({\n options: {\n rules: [{ path: [0], strictType: HEADING_KEYS.h1 }],\n },\n }),\n resetBlockTypePlugin,\n SelectOnBackspacePlugin.configure({\n options: {\n query: {\n allow: [ImagePlugin.key, HorizontalRulePlugin.key],\n },\n },\n }),\n DeletePlugin,\n SingleLinePlugin,\n softBreakPlugin,\n tabbablePlugin,\n TrailingBlockPlugin.configure({\n options: { type: ParagraphPlugin.key },\n }),\n DragOverCursorPlugin,\n\n // Collaboration\n CommentsPlugin.configure({\n options: {\n comments: commentsData,\n myUserId: '1',\n users: usersData,\n },\n }),\n\n // Deserialization\n DocxPlugin,\n MarkdownPlugin.configure({ options: { indentList: true } }),\n JuicePlugin,\n\n // Testing\n PlaywrightPlugin.configure({\n enabled: process.env.NODE_ENV !== 'production',\n }),\n ],\n value: value,\n },\n []\n );\n};\n\nexport default function PlaygroundDemo({\n id,\n className,\n scrollSelector,\n}: {\n id?: ValueId;\n className?: string;\n scrollSelector?: string;\n}) {\n const containerRef = useRef(null);\n const enabled = settingsStore.use.checkedComponents();\n\n const editor = usePlaygroundEditor(\n id,\n scrollSelector ?? `blockSelection-${id}`\n );\n\n return (\n \n \n \n \n \n \n \n \n \n\n
\n \n \n\n \n \n \n \n \n \n \n\n \n \n \n \n\n \n \n \n
\n
\n
\n );\n}\n\nconst DemoIdContext = React.createContext(undefined);\n\nexport function DemoId({\n id,\n children,\n}: {\n children: React.ReactNode;\n id?: string;\n}) {\n return {children};\n}\n\nexport function useDemoId() {\n return React.useContext(DemoIdContext);\n}\n", + "content": "'use client';\n\nimport React, { useRef } from 'react';\n\nimport type { ValueId } from '@/config/customizer-plugins';\n\nimport { cn } from '@udecode/cn';\nimport { AIChatPlugin, CopilotPlugin } from '@udecode/plate-ai/react';\nimport { AlignPlugin } from '@udecode/plate-alignment/react';\nimport { AutoformatPlugin } from '@udecode/plate-autoformat/react';\nimport {\n BoldPlugin,\n CodePlugin,\n ItalicPlugin,\n StrikethroughPlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n UnderlinePlugin,\n} from '@udecode/plate-basic-marks/react';\nimport { BlockquotePlugin } from '@udecode/plate-block-quote/react';\nimport { SingleLinePlugin } from '@udecode/plate-break/react';\nimport { CaptionPlugin } from '@udecode/plate-caption/react';\nimport { CodeBlockPlugin } from '@udecode/plate-code-block/react';\nimport { CommentsPlugin } from '@udecode/plate-comments/react';\nimport {\n ParagraphPlugin,\n Plate,\n usePlateEditor,\n} from '@udecode/plate-common/react';\nimport { DatePlugin } from '@udecode/plate-date/react';\nimport { DndPlugin } from '@udecode/plate-dnd';\nimport { DocxPlugin } from '@udecode/plate-docx';\nimport { EmojiPlugin } from '@udecode/plate-emoji/react';\nimport { ExcalidrawPlugin } from '@udecode/plate-excalidraw/react';\nimport {\n FontBackgroundColorPlugin,\n FontColorPlugin,\n FontSizePlugin,\n} from '@udecode/plate-font/react';\nimport { HEADING_KEYS } from '@udecode/plate-heading';\nimport { HeadingPlugin, TocPlugin } from '@udecode/plate-heading/react';\nimport { HighlightPlugin } from '@udecode/plate-highlight/react';\nimport { HorizontalRulePlugin } from '@udecode/plate-horizontal-rule/react';\nimport { IndentPlugin } from '@udecode/plate-indent/react';\nimport { IndentListPlugin } from '@udecode/plate-indent-list/react';\nimport { JuicePlugin } from '@udecode/plate-juice';\nimport { KbdPlugin } from '@udecode/plate-kbd/react';\nimport { ColumnPlugin } from '@udecode/plate-layout/react';\nimport { LineHeightPlugin } from '@udecode/plate-line-height/react';\nimport { LinkPlugin } from '@udecode/plate-link/react';\nimport { ListPlugin, TodoListPlugin } from '@udecode/plate-list/react';\nimport { MarkdownPlugin } from '@udecode/plate-markdown';\nimport { ImagePlugin, MediaEmbedPlugin } from '@udecode/plate-media/react';\nimport { MentionPlugin } from '@udecode/plate-mention/react';\nimport { NodeIdPlugin } from '@udecode/plate-node-id';\nimport { NormalizeTypesPlugin } from '@udecode/plate-normalizers';\nimport { PlaywrightPlugin } from '@udecode/plate-playwright';\nimport { DeletePlugin, SelectOnBackspacePlugin } from '@udecode/plate-select';\nimport {\n BlockMenuPlugin,\n BlockSelectionPlugin,\n} from '@udecode/plate-selection/react';\nimport { SlashPlugin } from '@udecode/plate-slash-command/react';\nimport { TablePlugin } from '@udecode/plate-table/react';\nimport { TogglePlugin } from '@udecode/plate-toggle/react';\nimport { TrailingBlockPlugin } from '@udecode/plate-trailing-block';\nimport Prism from 'prismjs';\n\nimport { CheckPlugin } from '@/components/context/check-plugin';\nimport { settingsStore } from '@/components/context/settings-store';\nimport { aiPlugins } from '@/lib/plate/demo/plugins/ai-plugins';\nimport { getAutoformatOptions } from '@/lib/plate/demo/plugins/autoformatOptions';\nimport { copilotPlugins } from '@/lib/plate/demo/plugins/copilot-plugins';\nimport { createPlateUI } from '@/plate/create-plate-ui';\nimport { editableProps } from '@/plate/demo/editableProps';\nimport { isEnabled } from '@/plate/demo/is-enabled';\nimport { DragOverCursorPlugin } from '@/plate/demo/plugins/DragOverCursorPlugin';\nimport { exitBreakPlugin } from '@/plate/demo/plugins/exitBreakPlugin';\nimport { resetBlockTypePlugin } from '@/plate/demo/plugins/resetBlockTypePlugin';\nimport { softBreakPlugin } from '@/plate/demo/plugins/softBreakPlugin';\nimport { tabbablePlugin } from '@/plate/demo/plugins/tabbablePlugin';\nimport { commentsData, usersData } from '@/plate/demo/values/commentsValue';\nimport { usePlaygroundValue } from '@/plate/demo/values/usePlaygroundValue';\nimport { BlockContextMenu } from '@/components/plate-ui/block-context-menu';\nimport { CommentsPopover } from '@/components/plate-ui/comments-popover';\nimport {\n CursorOverlay,\n SelectionOverlayPlugin,\n} from '@/components/plate-ui/cursor-overlay';\nimport { Editor, EditorContainer } from '@/components/plate-ui/editor';\nimport { FixedToolbar } from '@/components/plate-ui/fixed-toolbar';\nimport { FixedToolbarButtons } from '@/components/plate-ui/fixed-toolbar-buttons';\nimport { FloatingToolbar } from '@/components/plate-ui/floating-toolbar';\nimport { FloatingToolbarButtons } from '@/components/plate-ui/floating-toolbar-buttons';\nimport { ImagePreview } from '@/components/plate-ui/image-preview';\nimport {\n FireLiComponent,\n FireMarker,\n} from '@/components/plate-ui/indent-fire-marker';\nimport {\n TodoLi,\n TodoMarker,\n} from '@/components/plate-ui/indent-todo-marker';\nimport { LinkFloatingToolbar } from '@/components/plate-ui/link-floating-toolbar';\n\nimport { usePlaygroundEnabled } from './usePlaygroundEnabled';\n\nexport const usePlaygroundEditor = (id: any = '', scrollSelector?: string) => {\n const enabledPlugins = settingsStore.use.checkedPlugins();\n const overridePlugins = usePlaygroundEnabled(id);\n const autoformatOptions = getAutoformatOptions(id, enabledPlugins);\n\n const value = usePlaygroundValue(id);\n const key = settingsStore.use.version();\n const editorId = id || 'playground-' + key;\n\n return usePlateEditor(\n {\n id: editorId,\n override: {\n components: createPlateUI({\n draggable: isEnabled('dnd', id),\n placeholder: isEnabled('placeholder', id),\n }),\n plugins: overridePlugins,\n },\n plugins: [\n // AI\n ...(id === 'ai' || enabledPlugins[AIChatPlugin.key] ? aiPlugins : []),\n ...(id === 'copilot' || enabledPlugins[CopilotPlugin.key]\n ? copilotPlugins\n : []),\n // Nodes\n HeadingPlugin,\n TocPlugin.configure({\n options: {\n scrollContainerSelector: `#${scrollSelector}`,\n topOffset: 80,\n },\n }),\n BlockquotePlugin,\n CodeBlockPlugin.configure({\n options: {\n prism: Prism,\n },\n }),\n HorizontalRulePlugin,\n LinkPlugin.extend({\n render: { afterEditable: () => },\n }),\n ...(id === 'list' ? [ListPlugin] : []),\n ImagePlugin.extend({\n options: {\n disableUploadInsert: true,\n },\n render: { afterEditable: ImagePreview },\n }),\n MediaEmbedPlugin,\n CaptionPlugin.configure({\n options: {\n plugins: [ImagePlugin, MediaEmbedPlugin],\n },\n }),\n DatePlugin,\n MentionPlugin.configure({\n options: {\n triggerPreviousCharPattern: /^$|^[\\s\"']$/,\n },\n }),\n SlashPlugin,\n TablePlugin.configure({\n options: {\n enableMerging: id === 'tableMerge',\n },\n }),\n ColumnPlugin,\n SelectionOverlayPlugin,\n\n TodoListPlugin,\n TogglePlugin,\n ExcalidrawPlugin,\n // Marks\n BoldPlugin,\n ItalicPlugin,\n UnderlinePlugin,\n StrikethroughPlugin,\n CodePlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n FontColorPlugin,\n FontBackgroundColorPlugin,\n FontSizePlugin,\n HighlightPlugin,\n KbdPlugin,\n\n // Block Style\n AlignPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n MediaEmbedPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n ImagePlugin.key,\n HEADING_KEYS.h6,\n ],\n },\n }),\n IndentPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n }),\n IndentListPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n options: {\n listStyleTypes: {\n fire: {\n liComponent: FireLiComponent,\n markerComponent: FireMarker,\n type: 'fire',\n },\n todo: {\n liComponent: TodoLi,\n markerComponent: TodoMarker,\n type: 'todo',\n },\n },\n },\n }),\n LineHeightPlugin.extend({\n inject: {\n nodeProps: {\n defaultNodeValue: 1.5,\n validNodeValues: [1, 1.2, 1.5, 2, 3],\n },\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n ],\n },\n }),\n\n // Functionality\n AutoformatPlugin.configure({\n options: autoformatOptions,\n }),\n BlockSelectionPlugin.configure({\n options: {\n areaOptions: {\n behaviour: {\n scrolling: {\n speedDivider: 1.5,\n },\n startThreshold: 10,\n },\n boundaries: `#${scrollSelector}`,\n container: `#${scrollSelector}`,\n selectables: [`#${scrollSelector} .slate-selectable`],\n selectionAreaClass: 'slate-selection-area',\n },\n enableContextMenu: true,\n },\n }),\n BlockMenuPlugin.configure({\n render: { aboveEditable: BlockContextMenu },\n }),\n DndPlugin.configure({\n options: {\n enableScroller: true,\n onDropFiles: ({ dragItem, editor, target }) => {\n editor\n .getTransforms(ImagePlugin)\n .insertImageFromFiles(dragItem.files, {\n at: target,\n nextBlock: false,\n });\n },\n },\n }),\n EmojiPlugin,\n exitBreakPlugin,\n NodeIdPlugin,\n NormalizeTypesPlugin.configure({\n options: {\n rules: [{ path: [0], strictType: HEADING_KEYS.h1 }],\n },\n }),\n resetBlockTypePlugin,\n SelectOnBackspacePlugin.configure({\n options: {\n query: {\n allow: [ImagePlugin.key, HorizontalRulePlugin.key],\n },\n },\n }),\n DeletePlugin,\n SingleLinePlugin,\n softBreakPlugin,\n tabbablePlugin,\n TrailingBlockPlugin.configure({\n options: { type: ParagraphPlugin.key },\n }),\n DragOverCursorPlugin,\n\n // Collaboration\n CommentsPlugin.configure({\n options: {\n comments: commentsData,\n myUserId: '1',\n users: usersData,\n },\n }),\n\n // Deserialization\n DocxPlugin,\n MarkdownPlugin.configure({ options: { indentList: true } }),\n JuicePlugin,\n\n // Testing\n PlaywrightPlugin.configure({\n enabled: process.env.NODE_ENV !== 'production',\n }),\n ],\n value: value,\n },\n []\n );\n};\n\nexport default function PlaygroundDemo({\n id,\n className,\n scrollSelector,\n}: {\n id?: ValueId;\n className?: string;\n scrollSelector?: string;\n}) {\n const containerRef = useRef(null);\n const enabled = settingsStore.use.checkedComponents();\n\n const editor = usePlaygroundEditor(\n id,\n scrollSelector ?? `blockSelection-${id}`\n );\n\n return (\n \n \n \n \n \n \n \n \n \n\n
\n \n \n\n \n \n \n \n \n \n \n\n \n \n \n \n\n \n \n \n
\n
\n
\n );\n}\n\nconst DemoIdContext = React.createContext(undefined);\n\nexport function DemoId({\n id,\n children,\n}: {\n children: React.ReactNode;\n id?: string;\n}) {\n return {children};\n}\n\nexport function useDemoId() {\n return React.useContext(DemoIdContext);\n}\n", "path": "example/playground-demo.tsx", "target": "components/playground-demo.tsx", "type": "registry:example" diff --git a/apps/www/public/r/styles/default/table-demo.json b/apps/www/public/r/styles/default/table-demo.json index 4a704643d0..d761e26bf4 100644 --- a/apps/www/public/r/styles/default/table-demo.json +++ b/apps/www/public/r/styles/default/table-demo.json @@ -4,7 +4,7 @@ }, "files": [ { - "content": "'use client';\n\nimport React, { useRef } from 'react';\n\nimport type { ValueId } from '@/config/customizer-plugins';\n\nimport { cn } from '@udecode/cn';\nimport { AIChatPlugin, CopilotPlugin } from '@udecode/plate-ai/react';\nimport { AlignPlugin } from '@udecode/plate-alignment/react';\nimport { AutoformatPlugin } from '@udecode/plate-autoformat/react';\nimport {\n BoldPlugin,\n CodePlugin,\n ItalicPlugin,\n StrikethroughPlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n UnderlinePlugin,\n} from '@udecode/plate-basic-marks/react';\nimport { BlockquotePlugin } from '@udecode/plate-block-quote/react';\nimport { SingleLinePlugin } from '@udecode/plate-break/react';\nimport { CaptionPlugin } from '@udecode/plate-caption/react';\nimport { CodeBlockPlugin } from '@udecode/plate-code-block/react';\nimport { CommentsPlugin } from '@udecode/plate-comments/react';\nimport {\n ParagraphPlugin,\n Plate,\n usePlateEditor,\n} from '@udecode/plate-common/react';\nimport { DatePlugin } from '@udecode/plate-date/react';\nimport { DndPlugin } from '@udecode/plate-dnd';\nimport { DocxPlugin } from '@udecode/plate-docx';\nimport { EmojiPlugin } from '@udecode/plate-emoji/react';\nimport { ExcalidrawPlugin } from '@udecode/plate-excalidraw/react';\nimport {\n FontBackgroundColorPlugin,\n FontColorPlugin,\n FontSizePlugin,\n} from '@udecode/plate-font/react';\nimport { HEADING_KEYS } from '@udecode/plate-heading';\nimport { HeadingPlugin, TocPlugin } from '@udecode/plate-heading/react';\nimport { HighlightPlugin } from '@udecode/plate-highlight/react';\nimport { HorizontalRulePlugin } from '@udecode/plate-horizontal-rule/react';\nimport { IndentPlugin } from '@udecode/plate-indent/react';\nimport { IndentListPlugin } from '@udecode/plate-indent-list/react';\nimport { JuicePlugin } from '@udecode/plate-juice';\nimport { KbdPlugin } from '@udecode/plate-kbd/react';\nimport { ColumnPlugin } from '@udecode/plate-layout/react';\nimport { LineHeightPlugin } from '@udecode/plate-line-height/react';\nimport { LinkPlugin } from '@udecode/plate-link/react';\nimport { ListPlugin, TodoListPlugin } from '@udecode/plate-list/react';\nimport { MarkdownPlugin } from '@udecode/plate-markdown';\nimport { ImagePlugin, MediaEmbedPlugin } from '@udecode/plate-media/react';\nimport { MentionPlugin } from '@udecode/plate-mention/react';\nimport { NodeIdPlugin } from '@udecode/plate-node-id';\nimport { NormalizeTypesPlugin } from '@udecode/plate-normalizers';\nimport { PlaywrightPlugin } from '@udecode/plate-playwright';\nimport { DeletePlugin, SelectOnBackspacePlugin } from '@udecode/plate-select';\nimport {\n BlockMenuPlugin,\n BlockSelectionPlugin,\n} from '@udecode/plate-selection/react';\nimport { SlashPlugin } from '@udecode/plate-slash-command/react';\nimport { TablePlugin } from '@udecode/plate-table/react';\nimport { TogglePlugin } from '@udecode/plate-toggle/react';\nimport { TrailingBlockPlugin } from '@udecode/plate-trailing-block';\nimport Prism from 'prismjs';\n\nimport { CheckPlugin } from '@/components/context/check-plugin';\nimport { settingsStore } from '@/components/context/settings-store';\nimport { aiPlugins } from '@/lib/plate/demo/plugins/ai-plugins';\nimport { getAutoformatOptions } from '@/lib/plate/demo/plugins/autoformatOptions';\nimport { copilotPlugins } from '@/lib/plate/demo/plugins/copilot-plugins';\nimport { createPlateUI } from '@/plate/create-plate-ui';\nimport { editableProps } from '@/plate/demo/editableProps';\nimport { isEnabled } from '@/plate/demo/is-enabled';\nimport { DragOverCursorPlugin } from '@/plate/demo/plugins/DragOverCursorPlugin';\nimport { exitBreakPlugin } from '@/plate/demo/plugins/exitBreakPlugin';\nimport { resetBlockTypePlugin } from '@/plate/demo/plugins/resetBlockTypePlugin';\nimport { softBreakPlugin } from '@/plate/demo/plugins/softBreakPlugin';\nimport { tabbablePlugin } from '@/plate/demo/plugins/tabbablePlugin';\nimport { commentsData, usersData } from '@/plate/demo/values/commentsValue';\nimport { usePlaygroundValue } from '@/plate/demo/values/usePlaygroundValue';\nimport { BlockContextMenu } from '@/components/plate-ui/block-context-menu';\nimport { CommentsPopover } from '@/components/plate-ui/comments-popover';\nimport {\n CursorOverlay,\n SelectionOverlayPlugin,\n} from '@/components/plate-ui/cursor-overlay';\nimport { Editor, EditorContainer } from '@/components/plate-ui/editor';\nimport { FixedToolbar } from '@/components/plate-ui/fixed-toolbar';\nimport { FixedToolbarButtons } from '@/components/plate-ui/fixed-toolbar-buttons';\nimport { FloatingToolbar } from '@/components/plate-ui/floating-toolbar';\nimport { FloatingToolbarButtons } from '@/components/plate-ui/floating-toolbar-buttons';\nimport { ImagePreview } from '@/components/plate-ui/image-preview';\nimport {\n FireLiComponent,\n FireMarker,\n} from '@/components/plate-ui/indent-fire-marker';\nimport {\n TodoLi,\n TodoMarker,\n} from '@/components/plate-ui/indent-todo-marker';\nimport { LinkFloatingToolbar } from '@/components/plate-ui/link-floating-toolbar';\n\nimport { usePlaygroundEnabled } from './usePlaygroundEnabled';\n\nexport const usePlaygroundEditor = (id: any = '', scrollSelector?: string) => {\n const enabledPlugins = settingsStore.use.checkedPlugins();\n const overridePlugins = usePlaygroundEnabled(id);\n const autoformatOptions = getAutoformatOptions(id, enabledPlugins);\n\n const value = usePlaygroundValue(id);\n const key = settingsStore.use.version();\n const editorId = id || 'playground-' + key;\n\n return usePlateEditor(\n {\n id: editorId,\n override: {\n components: createPlateUI({\n draggable: isEnabled('dnd', id),\n placeholder: isEnabled('placeholder', id),\n }),\n plugins: overridePlugins,\n },\n plugins: [\n // AI\n ...(id === 'ai' || enabledPlugins[AIChatPlugin.key] ? aiPlugins : []),\n ...(id === 'copilot' || enabledPlugins[CopilotPlugin.key]\n ? copilotPlugins\n : []),\n // Nodes\n HeadingPlugin,\n TocPlugin.configure({\n options: {\n scrollContainerSelector: `#${scrollSelector}`,\n topOffset: 80,\n },\n }),\n BlockquotePlugin,\n CodeBlockPlugin.configure({\n options: {\n prism: Prism,\n },\n }),\n HorizontalRulePlugin,\n LinkPlugin.extend({\n render: { afterEditable: () => },\n }),\n ...(id === 'list' ? [ListPlugin] : []),\n ImagePlugin.extend({\n render: { afterEditable: ImagePreview },\n }),\n MediaEmbedPlugin,\n CaptionPlugin.configure({\n options: {\n plugins: [ImagePlugin, MediaEmbedPlugin],\n },\n }),\n DatePlugin,\n MentionPlugin.configure({\n options: {\n triggerPreviousCharPattern: /^$|^[\\s\"']$/,\n },\n }),\n SlashPlugin,\n TablePlugin.configure({\n options: {\n enableMerging: id === 'tableMerge',\n },\n }),\n ColumnPlugin,\n SelectionOverlayPlugin,\n\n TodoListPlugin,\n TogglePlugin,\n ExcalidrawPlugin,\n // Marks\n BoldPlugin,\n ItalicPlugin,\n UnderlinePlugin,\n StrikethroughPlugin,\n CodePlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n FontColorPlugin,\n FontBackgroundColorPlugin,\n FontSizePlugin,\n HighlightPlugin,\n KbdPlugin,\n\n // Block Style\n AlignPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n MediaEmbedPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n ImagePlugin.key,\n HEADING_KEYS.h6,\n ],\n },\n }),\n IndentPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n }),\n IndentListPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n options: {\n listStyleTypes: {\n fire: {\n liComponent: FireLiComponent,\n markerComponent: FireMarker,\n type: 'fire',\n },\n todo: {\n liComponent: TodoLi,\n markerComponent: TodoMarker,\n type: 'todo',\n },\n },\n },\n }),\n LineHeightPlugin.extend({\n inject: {\n nodeProps: {\n defaultNodeValue: 1.5,\n validNodeValues: [1, 1.2, 1.5, 2, 3],\n },\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n ],\n },\n }),\n\n // Functionality\n AutoformatPlugin.configure({\n options: autoformatOptions,\n }),\n BlockSelectionPlugin.configure({\n options: {\n areaOptions: {\n behaviour: {\n scrolling: {\n speedDivider: 1.5,\n },\n startThreshold: 10,\n },\n boundaries: `#${scrollSelector}`,\n container: `#${scrollSelector}`,\n selectables: [`#${scrollSelector} .slate-selectable`],\n selectionAreaClass: 'slate-selection-area',\n },\n enableContextMenu: true,\n },\n }),\n BlockMenuPlugin.configure({\n render: { aboveEditable: BlockContextMenu },\n }),\n DndPlugin.configure({ options: { enableScroller: true } }),\n EmojiPlugin,\n exitBreakPlugin,\n NodeIdPlugin,\n NormalizeTypesPlugin.configure({\n options: {\n rules: [{ path: [0], strictType: HEADING_KEYS.h1 }],\n },\n }),\n resetBlockTypePlugin,\n SelectOnBackspacePlugin.configure({\n options: {\n query: {\n allow: [ImagePlugin.key, HorizontalRulePlugin.key],\n },\n },\n }),\n DeletePlugin,\n SingleLinePlugin,\n softBreakPlugin,\n tabbablePlugin,\n TrailingBlockPlugin.configure({\n options: { type: ParagraphPlugin.key },\n }),\n DragOverCursorPlugin,\n\n // Collaboration\n CommentsPlugin.configure({\n options: {\n comments: commentsData,\n myUserId: '1',\n users: usersData,\n },\n }),\n\n // Deserialization\n DocxPlugin,\n MarkdownPlugin.configure({ options: { indentList: true } }),\n JuicePlugin,\n\n // Testing\n PlaywrightPlugin.configure({\n enabled: process.env.NODE_ENV !== 'production',\n }),\n ],\n value: value,\n },\n []\n );\n};\n\nexport default function PlaygroundDemo({\n id,\n className,\n scrollSelector,\n}: {\n id?: ValueId;\n className?: string;\n scrollSelector?: string;\n}) {\n const containerRef = useRef(null);\n const enabled = settingsStore.use.checkedComponents();\n\n const editor = usePlaygroundEditor(\n id,\n scrollSelector ?? `blockSelection-${id}`\n );\n\n return (\n \n \n \n \n \n \n \n \n \n\n
\n \n \n\n \n \n \n \n \n \n \n\n \n \n \n \n\n \n \n \n
\n
\n
\n );\n}\n\nconst DemoIdContext = React.createContext(undefined);\n\nexport function DemoId({\n id,\n children,\n}: {\n children: React.ReactNode;\n id?: string;\n}) {\n return {children};\n}\n\nexport function useDemoId() {\n return React.useContext(DemoIdContext);\n}\n", + "content": "'use client';\n\nimport React, { useRef } from 'react';\n\nimport type { ValueId } from '@/config/customizer-plugins';\n\nimport { cn } from '@udecode/cn';\nimport { AIChatPlugin, CopilotPlugin } from '@udecode/plate-ai/react';\nimport { AlignPlugin } from '@udecode/plate-alignment/react';\nimport { AutoformatPlugin } from '@udecode/plate-autoformat/react';\nimport {\n BoldPlugin,\n CodePlugin,\n ItalicPlugin,\n StrikethroughPlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n UnderlinePlugin,\n} from '@udecode/plate-basic-marks/react';\nimport { BlockquotePlugin } from '@udecode/plate-block-quote/react';\nimport { SingleLinePlugin } from '@udecode/plate-break/react';\nimport { CaptionPlugin } from '@udecode/plate-caption/react';\nimport { CodeBlockPlugin } from '@udecode/plate-code-block/react';\nimport { CommentsPlugin } from '@udecode/plate-comments/react';\nimport {\n ParagraphPlugin,\n Plate,\n usePlateEditor,\n} from '@udecode/plate-common/react';\nimport { DatePlugin } from '@udecode/plate-date/react';\nimport { DndPlugin } from '@udecode/plate-dnd';\nimport { DocxPlugin } from '@udecode/plate-docx';\nimport { EmojiPlugin } from '@udecode/plate-emoji/react';\nimport { ExcalidrawPlugin } from '@udecode/plate-excalidraw/react';\nimport {\n FontBackgroundColorPlugin,\n FontColorPlugin,\n FontSizePlugin,\n} from '@udecode/plate-font/react';\nimport { HEADING_KEYS } from '@udecode/plate-heading';\nimport { HeadingPlugin, TocPlugin } from '@udecode/plate-heading/react';\nimport { HighlightPlugin } from '@udecode/plate-highlight/react';\nimport { HorizontalRulePlugin } from '@udecode/plate-horizontal-rule/react';\nimport { IndentPlugin } from '@udecode/plate-indent/react';\nimport { IndentListPlugin } from '@udecode/plate-indent-list/react';\nimport { JuicePlugin } from '@udecode/plate-juice';\nimport { KbdPlugin } from '@udecode/plate-kbd/react';\nimport { ColumnPlugin } from '@udecode/plate-layout/react';\nimport { LineHeightPlugin } from '@udecode/plate-line-height/react';\nimport { LinkPlugin } from '@udecode/plate-link/react';\nimport { ListPlugin, TodoListPlugin } from '@udecode/plate-list/react';\nimport { MarkdownPlugin } from '@udecode/plate-markdown';\nimport { ImagePlugin, MediaEmbedPlugin } from '@udecode/plate-media/react';\nimport { MentionPlugin } from '@udecode/plate-mention/react';\nimport { NodeIdPlugin } from '@udecode/plate-node-id';\nimport { NormalizeTypesPlugin } from '@udecode/plate-normalizers';\nimport { PlaywrightPlugin } from '@udecode/plate-playwright';\nimport { DeletePlugin, SelectOnBackspacePlugin } from '@udecode/plate-select';\nimport {\n BlockMenuPlugin,\n BlockSelectionPlugin,\n} from '@udecode/plate-selection/react';\nimport { SlashPlugin } from '@udecode/plate-slash-command/react';\nimport { TablePlugin } from '@udecode/plate-table/react';\nimport { TogglePlugin } from '@udecode/plate-toggle/react';\nimport { TrailingBlockPlugin } from '@udecode/plate-trailing-block';\nimport Prism from 'prismjs';\n\nimport { CheckPlugin } from '@/components/context/check-plugin';\nimport { settingsStore } from '@/components/context/settings-store';\nimport { aiPlugins } from '@/lib/plate/demo/plugins/ai-plugins';\nimport { getAutoformatOptions } from '@/lib/plate/demo/plugins/autoformatOptions';\nimport { copilotPlugins } from '@/lib/plate/demo/plugins/copilot-plugins';\nimport { createPlateUI } from '@/plate/create-plate-ui';\nimport { editableProps } from '@/plate/demo/editableProps';\nimport { isEnabled } from '@/plate/demo/is-enabled';\nimport { DragOverCursorPlugin } from '@/plate/demo/plugins/DragOverCursorPlugin';\nimport { exitBreakPlugin } from '@/plate/demo/plugins/exitBreakPlugin';\nimport { resetBlockTypePlugin } from '@/plate/demo/plugins/resetBlockTypePlugin';\nimport { softBreakPlugin } from '@/plate/demo/plugins/softBreakPlugin';\nimport { tabbablePlugin } from '@/plate/demo/plugins/tabbablePlugin';\nimport { commentsData, usersData } from '@/plate/demo/values/commentsValue';\nimport { usePlaygroundValue } from '@/plate/demo/values/usePlaygroundValue';\nimport { BlockContextMenu } from '@/components/plate-ui/block-context-menu';\nimport { CommentsPopover } from '@/components/plate-ui/comments-popover';\nimport {\n CursorOverlay,\n SelectionOverlayPlugin,\n} from '@/components/plate-ui/cursor-overlay';\nimport { Editor, EditorContainer } from '@/components/plate-ui/editor';\nimport { FixedToolbar } from '@/components/plate-ui/fixed-toolbar';\nimport { FixedToolbarButtons } from '@/components/plate-ui/fixed-toolbar-buttons';\nimport { FloatingToolbar } from '@/components/plate-ui/floating-toolbar';\nimport { FloatingToolbarButtons } from '@/components/plate-ui/floating-toolbar-buttons';\nimport { ImagePreview } from '@/components/plate-ui/image-preview';\nimport {\n FireLiComponent,\n FireMarker,\n} from '@/components/plate-ui/indent-fire-marker';\nimport {\n TodoLi,\n TodoMarker,\n} from '@/components/plate-ui/indent-todo-marker';\nimport { LinkFloatingToolbar } from '@/components/plate-ui/link-floating-toolbar';\n\nimport { usePlaygroundEnabled } from './usePlaygroundEnabled';\n\nexport const usePlaygroundEditor = (id: any = '', scrollSelector?: string) => {\n const enabledPlugins = settingsStore.use.checkedPlugins();\n const overridePlugins = usePlaygroundEnabled(id);\n const autoformatOptions = getAutoformatOptions(id, enabledPlugins);\n\n const value = usePlaygroundValue(id);\n const key = settingsStore.use.version();\n const editorId = id || 'playground-' + key;\n\n return usePlateEditor(\n {\n id: editorId,\n override: {\n components: createPlateUI({\n draggable: isEnabled('dnd', id),\n placeholder: isEnabled('placeholder', id),\n }),\n plugins: overridePlugins,\n },\n plugins: [\n // AI\n ...(id === 'ai' || enabledPlugins[AIChatPlugin.key] ? aiPlugins : []),\n ...(id === 'copilot' || enabledPlugins[CopilotPlugin.key]\n ? copilotPlugins\n : []),\n // Nodes\n HeadingPlugin,\n TocPlugin.configure({\n options: {\n scrollContainerSelector: `#${scrollSelector}`,\n topOffset: 80,\n },\n }),\n BlockquotePlugin,\n CodeBlockPlugin.configure({\n options: {\n prism: Prism,\n },\n }),\n HorizontalRulePlugin,\n LinkPlugin.extend({\n render: { afterEditable: () => },\n }),\n ...(id === 'list' ? [ListPlugin] : []),\n ImagePlugin.extend({\n options: {\n disableUploadInsert: true,\n },\n render: { afterEditable: ImagePreview },\n }),\n MediaEmbedPlugin,\n CaptionPlugin.configure({\n options: {\n plugins: [ImagePlugin, MediaEmbedPlugin],\n },\n }),\n DatePlugin,\n MentionPlugin.configure({\n options: {\n triggerPreviousCharPattern: /^$|^[\\s\"']$/,\n },\n }),\n SlashPlugin,\n TablePlugin.configure({\n options: {\n enableMerging: id === 'tableMerge',\n },\n }),\n ColumnPlugin,\n SelectionOverlayPlugin,\n\n TodoListPlugin,\n TogglePlugin,\n ExcalidrawPlugin,\n // Marks\n BoldPlugin,\n ItalicPlugin,\n UnderlinePlugin,\n StrikethroughPlugin,\n CodePlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n FontColorPlugin,\n FontBackgroundColorPlugin,\n FontSizePlugin,\n HighlightPlugin,\n KbdPlugin,\n\n // Block Style\n AlignPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n MediaEmbedPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n ImagePlugin.key,\n HEADING_KEYS.h6,\n ],\n },\n }),\n IndentPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n }),\n IndentListPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n options: {\n listStyleTypes: {\n fire: {\n liComponent: FireLiComponent,\n markerComponent: FireMarker,\n type: 'fire',\n },\n todo: {\n liComponent: TodoLi,\n markerComponent: TodoMarker,\n type: 'todo',\n },\n },\n },\n }),\n LineHeightPlugin.extend({\n inject: {\n nodeProps: {\n defaultNodeValue: 1.5,\n validNodeValues: [1, 1.2, 1.5, 2, 3],\n },\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n ],\n },\n }),\n\n // Functionality\n AutoformatPlugin.configure({\n options: autoformatOptions,\n }),\n BlockSelectionPlugin.configure({\n options: {\n areaOptions: {\n behaviour: {\n scrolling: {\n speedDivider: 1.5,\n },\n startThreshold: 10,\n },\n boundaries: `#${scrollSelector}`,\n container: `#${scrollSelector}`,\n selectables: [`#${scrollSelector} .slate-selectable`],\n selectionAreaClass: 'slate-selection-area',\n },\n enableContextMenu: true,\n },\n }),\n BlockMenuPlugin.configure({\n render: { aboveEditable: BlockContextMenu },\n }),\n DndPlugin.configure({\n options: {\n enableScroller: true,\n onDropFiles: ({ dragItem, editor, target }) => {\n editor\n .getTransforms(ImagePlugin)\n .insertImageFromFiles(dragItem.files, {\n at: target,\n nextBlock: false,\n });\n },\n },\n }),\n EmojiPlugin,\n exitBreakPlugin,\n NodeIdPlugin,\n NormalizeTypesPlugin.configure({\n options: {\n rules: [{ path: [0], strictType: HEADING_KEYS.h1 }],\n },\n }),\n resetBlockTypePlugin,\n SelectOnBackspacePlugin.configure({\n options: {\n query: {\n allow: [ImagePlugin.key, HorizontalRulePlugin.key],\n },\n },\n }),\n DeletePlugin,\n SingleLinePlugin,\n softBreakPlugin,\n tabbablePlugin,\n TrailingBlockPlugin.configure({\n options: { type: ParagraphPlugin.key },\n }),\n DragOverCursorPlugin,\n\n // Collaboration\n CommentsPlugin.configure({\n options: {\n comments: commentsData,\n myUserId: '1',\n users: usersData,\n },\n }),\n\n // Deserialization\n DocxPlugin,\n MarkdownPlugin.configure({ options: { indentList: true } }),\n JuicePlugin,\n\n // Testing\n PlaywrightPlugin.configure({\n enabled: process.env.NODE_ENV !== 'production',\n }),\n ],\n value: value,\n },\n []\n );\n};\n\nexport default function PlaygroundDemo({\n id,\n className,\n scrollSelector,\n}: {\n id?: ValueId;\n className?: string;\n scrollSelector?: string;\n}) {\n const containerRef = useRef(null);\n const enabled = settingsStore.use.checkedComponents();\n\n const editor = usePlaygroundEditor(\n id,\n scrollSelector ?? `blockSelection-${id}`\n );\n\n return (\n \n \n \n \n \n \n \n \n \n\n
\n \n \n\n \n \n \n \n \n \n \n\n \n \n \n \n\n \n \n \n
\n
\n
\n );\n}\n\nconst DemoIdContext = React.createContext(undefined);\n\nexport function DemoId({\n id,\n children,\n}: {\n children: React.ReactNode;\n id?: string;\n}) {\n return {children};\n}\n\nexport function useDemoId() {\n return React.useContext(DemoIdContext);\n}\n", "path": "example/playground-demo.tsx", "target": "components/playground-demo.tsx", "type": "registry:example" diff --git a/apps/www/public/r/styles/default/toc-demo.json b/apps/www/public/r/styles/default/toc-demo.json index 2c811f7f29..1a6bc925ed 100644 --- a/apps/www/public/r/styles/default/toc-demo.json +++ b/apps/www/public/r/styles/default/toc-demo.json @@ -4,7 +4,7 @@ }, "files": [ { - "content": "'use client';\n\nimport React, { useRef } from 'react';\n\nimport type { ValueId } from '@/config/customizer-plugins';\n\nimport { cn } from '@udecode/cn';\nimport { AIChatPlugin, CopilotPlugin } from '@udecode/plate-ai/react';\nimport { AlignPlugin } from '@udecode/plate-alignment/react';\nimport { AutoformatPlugin } from '@udecode/plate-autoformat/react';\nimport {\n BoldPlugin,\n CodePlugin,\n ItalicPlugin,\n StrikethroughPlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n UnderlinePlugin,\n} from '@udecode/plate-basic-marks/react';\nimport { BlockquotePlugin } from '@udecode/plate-block-quote/react';\nimport { SingleLinePlugin } from '@udecode/plate-break/react';\nimport { CaptionPlugin } from '@udecode/plate-caption/react';\nimport { CodeBlockPlugin } from '@udecode/plate-code-block/react';\nimport { CommentsPlugin } from '@udecode/plate-comments/react';\nimport {\n ParagraphPlugin,\n Plate,\n usePlateEditor,\n} from '@udecode/plate-common/react';\nimport { DatePlugin } from '@udecode/plate-date/react';\nimport { DndPlugin } from '@udecode/plate-dnd';\nimport { DocxPlugin } from '@udecode/plate-docx';\nimport { EmojiPlugin } from '@udecode/plate-emoji/react';\nimport { ExcalidrawPlugin } from '@udecode/plate-excalidraw/react';\nimport {\n FontBackgroundColorPlugin,\n FontColorPlugin,\n FontSizePlugin,\n} from '@udecode/plate-font/react';\nimport { HEADING_KEYS } from '@udecode/plate-heading';\nimport { HeadingPlugin, TocPlugin } from '@udecode/plate-heading/react';\nimport { HighlightPlugin } from '@udecode/plate-highlight/react';\nimport { HorizontalRulePlugin } from '@udecode/plate-horizontal-rule/react';\nimport { IndentPlugin } from '@udecode/plate-indent/react';\nimport { IndentListPlugin } from '@udecode/plate-indent-list/react';\nimport { JuicePlugin } from '@udecode/plate-juice';\nimport { KbdPlugin } from '@udecode/plate-kbd/react';\nimport { ColumnPlugin } from '@udecode/plate-layout/react';\nimport { LineHeightPlugin } from '@udecode/plate-line-height/react';\nimport { LinkPlugin } from '@udecode/plate-link/react';\nimport { ListPlugin, TodoListPlugin } from '@udecode/plate-list/react';\nimport { MarkdownPlugin } from '@udecode/plate-markdown';\nimport { ImagePlugin, MediaEmbedPlugin } from '@udecode/plate-media/react';\nimport { MentionPlugin } from '@udecode/plate-mention/react';\nimport { NodeIdPlugin } from '@udecode/plate-node-id';\nimport { NormalizeTypesPlugin } from '@udecode/plate-normalizers';\nimport { PlaywrightPlugin } from '@udecode/plate-playwright';\nimport { DeletePlugin, SelectOnBackspacePlugin } from '@udecode/plate-select';\nimport {\n BlockMenuPlugin,\n BlockSelectionPlugin,\n} from '@udecode/plate-selection/react';\nimport { SlashPlugin } from '@udecode/plate-slash-command/react';\nimport { TablePlugin } from '@udecode/plate-table/react';\nimport { TogglePlugin } from '@udecode/plate-toggle/react';\nimport { TrailingBlockPlugin } from '@udecode/plate-trailing-block';\nimport Prism from 'prismjs';\n\nimport { CheckPlugin } from '@/components/context/check-plugin';\nimport { settingsStore } from '@/components/context/settings-store';\nimport { aiPlugins } from '@/lib/plate/demo/plugins/ai-plugins';\nimport { getAutoformatOptions } from '@/lib/plate/demo/plugins/autoformatOptions';\nimport { copilotPlugins } from '@/lib/plate/demo/plugins/copilot-plugins';\nimport { createPlateUI } from '@/plate/create-plate-ui';\nimport { editableProps } from '@/plate/demo/editableProps';\nimport { isEnabled } from '@/plate/demo/is-enabled';\nimport { DragOverCursorPlugin } from '@/plate/demo/plugins/DragOverCursorPlugin';\nimport { exitBreakPlugin } from '@/plate/demo/plugins/exitBreakPlugin';\nimport { resetBlockTypePlugin } from '@/plate/demo/plugins/resetBlockTypePlugin';\nimport { softBreakPlugin } from '@/plate/demo/plugins/softBreakPlugin';\nimport { tabbablePlugin } from '@/plate/demo/plugins/tabbablePlugin';\nimport { commentsData, usersData } from '@/plate/demo/values/commentsValue';\nimport { usePlaygroundValue } from '@/plate/demo/values/usePlaygroundValue';\nimport { BlockContextMenu } from '@/components/plate-ui/block-context-menu';\nimport { CommentsPopover } from '@/components/plate-ui/comments-popover';\nimport {\n CursorOverlay,\n SelectionOverlayPlugin,\n} from '@/components/plate-ui/cursor-overlay';\nimport { Editor, EditorContainer } from '@/components/plate-ui/editor';\nimport { FixedToolbar } from '@/components/plate-ui/fixed-toolbar';\nimport { FixedToolbarButtons } from '@/components/plate-ui/fixed-toolbar-buttons';\nimport { FloatingToolbar } from '@/components/plate-ui/floating-toolbar';\nimport { FloatingToolbarButtons } from '@/components/plate-ui/floating-toolbar-buttons';\nimport { ImagePreview } from '@/components/plate-ui/image-preview';\nimport {\n FireLiComponent,\n FireMarker,\n} from '@/components/plate-ui/indent-fire-marker';\nimport {\n TodoLi,\n TodoMarker,\n} from '@/components/plate-ui/indent-todo-marker';\nimport { LinkFloatingToolbar } from '@/components/plate-ui/link-floating-toolbar';\n\nimport { usePlaygroundEnabled } from './usePlaygroundEnabled';\n\nexport const usePlaygroundEditor = (id: any = '', scrollSelector?: string) => {\n const enabledPlugins = settingsStore.use.checkedPlugins();\n const overridePlugins = usePlaygroundEnabled(id);\n const autoformatOptions = getAutoformatOptions(id, enabledPlugins);\n\n const value = usePlaygroundValue(id);\n const key = settingsStore.use.version();\n const editorId = id || 'playground-' + key;\n\n return usePlateEditor(\n {\n id: editorId,\n override: {\n components: createPlateUI({\n draggable: isEnabled('dnd', id),\n placeholder: isEnabled('placeholder', id),\n }),\n plugins: overridePlugins,\n },\n plugins: [\n // AI\n ...(id === 'ai' || enabledPlugins[AIChatPlugin.key] ? aiPlugins : []),\n ...(id === 'copilot' || enabledPlugins[CopilotPlugin.key]\n ? copilotPlugins\n : []),\n // Nodes\n HeadingPlugin,\n TocPlugin.configure({\n options: {\n scrollContainerSelector: `#${scrollSelector}`,\n topOffset: 80,\n },\n }),\n BlockquotePlugin,\n CodeBlockPlugin.configure({\n options: {\n prism: Prism,\n },\n }),\n HorizontalRulePlugin,\n LinkPlugin.extend({\n render: { afterEditable: () => },\n }),\n ...(id === 'list' ? [ListPlugin] : []),\n ImagePlugin.extend({\n render: { afterEditable: ImagePreview },\n }),\n MediaEmbedPlugin,\n CaptionPlugin.configure({\n options: {\n plugins: [ImagePlugin, MediaEmbedPlugin],\n },\n }),\n DatePlugin,\n MentionPlugin.configure({\n options: {\n triggerPreviousCharPattern: /^$|^[\\s\"']$/,\n },\n }),\n SlashPlugin,\n TablePlugin.configure({\n options: {\n enableMerging: id === 'tableMerge',\n },\n }),\n ColumnPlugin,\n SelectionOverlayPlugin,\n\n TodoListPlugin,\n TogglePlugin,\n ExcalidrawPlugin,\n // Marks\n BoldPlugin,\n ItalicPlugin,\n UnderlinePlugin,\n StrikethroughPlugin,\n CodePlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n FontColorPlugin,\n FontBackgroundColorPlugin,\n FontSizePlugin,\n HighlightPlugin,\n KbdPlugin,\n\n // Block Style\n AlignPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n MediaEmbedPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n ImagePlugin.key,\n HEADING_KEYS.h6,\n ],\n },\n }),\n IndentPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n }),\n IndentListPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n options: {\n listStyleTypes: {\n fire: {\n liComponent: FireLiComponent,\n markerComponent: FireMarker,\n type: 'fire',\n },\n todo: {\n liComponent: TodoLi,\n markerComponent: TodoMarker,\n type: 'todo',\n },\n },\n },\n }),\n LineHeightPlugin.extend({\n inject: {\n nodeProps: {\n defaultNodeValue: 1.5,\n validNodeValues: [1, 1.2, 1.5, 2, 3],\n },\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n ],\n },\n }),\n\n // Functionality\n AutoformatPlugin.configure({\n options: autoformatOptions,\n }),\n BlockSelectionPlugin.configure({\n options: {\n areaOptions: {\n behaviour: {\n scrolling: {\n speedDivider: 1.5,\n },\n startThreshold: 10,\n },\n boundaries: `#${scrollSelector}`,\n container: `#${scrollSelector}`,\n selectables: [`#${scrollSelector} .slate-selectable`],\n selectionAreaClass: 'slate-selection-area',\n },\n enableContextMenu: true,\n },\n }),\n BlockMenuPlugin.configure({\n render: { aboveEditable: BlockContextMenu },\n }),\n DndPlugin.configure({ options: { enableScroller: true } }),\n EmojiPlugin,\n exitBreakPlugin,\n NodeIdPlugin,\n NormalizeTypesPlugin.configure({\n options: {\n rules: [{ path: [0], strictType: HEADING_KEYS.h1 }],\n },\n }),\n resetBlockTypePlugin,\n SelectOnBackspacePlugin.configure({\n options: {\n query: {\n allow: [ImagePlugin.key, HorizontalRulePlugin.key],\n },\n },\n }),\n DeletePlugin,\n SingleLinePlugin,\n softBreakPlugin,\n tabbablePlugin,\n TrailingBlockPlugin.configure({\n options: { type: ParagraphPlugin.key },\n }),\n DragOverCursorPlugin,\n\n // Collaboration\n CommentsPlugin.configure({\n options: {\n comments: commentsData,\n myUserId: '1',\n users: usersData,\n },\n }),\n\n // Deserialization\n DocxPlugin,\n MarkdownPlugin.configure({ options: { indentList: true } }),\n JuicePlugin,\n\n // Testing\n PlaywrightPlugin.configure({\n enabled: process.env.NODE_ENV !== 'production',\n }),\n ],\n value: value,\n },\n []\n );\n};\n\nexport default function PlaygroundDemo({\n id,\n className,\n scrollSelector,\n}: {\n id?: ValueId;\n className?: string;\n scrollSelector?: string;\n}) {\n const containerRef = useRef(null);\n const enabled = settingsStore.use.checkedComponents();\n\n const editor = usePlaygroundEditor(\n id,\n scrollSelector ?? `blockSelection-${id}`\n );\n\n return (\n \n \n \n \n \n \n \n \n \n\n
\n \n \n\n \n \n \n \n \n \n \n\n \n \n \n \n\n \n \n \n
\n
\n
\n );\n}\n\nconst DemoIdContext = React.createContext(undefined);\n\nexport function DemoId({\n id,\n children,\n}: {\n children: React.ReactNode;\n id?: string;\n}) {\n return {children};\n}\n\nexport function useDemoId() {\n return React.useContext(DemoIdContext);\n}\n", + "content": "'use client';\n\nimport React, { useRef } from 'react';\n\nimport type { ValueId } from '@/config/customizer-plugins';\n\nimport { cn } from '@udecode/cn';\nimport { AIChatPlugin, CopilotPlugin } from '@udecode/plate-ai/react';\nimport { AlignPlugin } from '@udecode/plate-alignment/react';\nimport { AutoformatPlugin } from '@udecode/plate-autoformat/react';\nimport {\n BoldPlugin,\n CodePlugin,\n ItalicPlugin,\n StrikethroughPlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n UnderlinePlugin,\n} from '@udecode/plate-basic-marks/react';\nimport { BlockquotePlugin } from '@udecode/plate-block-quote/react';\nimport { SingleLinePlugin } from '@udecode/plate-break/react';\nimport { CaptionPlugin } from '@udecode/plate-caption/react';\nimport { CodeBlockPlugin } from '@udecode/plate-code-block/react';\nimport { CommentsPlugin } from '@udecode/plate-comments/react';\nimport {\n ParagraphPlugin,\n Plate,\n usePlateEditor,\n} from '@udecode/plate-common/react';\nimport { DatePlugin } from '@udecode/plate-date/react';\nimport { DndPlugin } from '@udecode/plate-dnd';\nimport { DocxPlugin } from '@udecode/plate-docx';\nimport { EmojiPlugin } from '@udecode/plate-emoji/react';\nimport { ExcalidrawPlugin } from '@udecode/plate-excalidraw/react';\nimport {\n FontBackgroundColorPlugin,\n FontColorPlugin,\n FontSizePlugin,\n} from '@udecode/plate-font/react';\nimport { HEADING_KEYS } from '@udecode/plate-heading';\nimport { HeadingPlugin, TocPlugin } from '@udecode/plate-heading/react';\nimport { HighlightPlugin } from '@udecode/plate-highlight/react';\nimport { HorizontalRulePlugin } from '@udecode/plate-horizontal-rule/react';\nimport { IndentPlugin } from '@udecode/plate-indent/react';\nimport { IndentListPlugin } from '@udecode/plate-indent-list/react';\nimport { JuicePlugin } from '@udecode/plate-juice';\nimport { KbdPlugin } from '@udecode/plate-kbd/react';\nimport { ColumnPlugin } from '@udecode/plate-layout/react';\nimport { LineHeightPlugin } from '@udecode/plate-line-height/react';\nimport { LinkPlugin } from '@udecode/plate-link/react';\nimport { ListPlugin, TodoListPlugin } from '@udecode/plate-list/react';\nimport { MarkdownPlugin } from '@udecode/plate-markdown';\nimport { ImagePlugin, MediaEmbedPlugin } from '@udecode/plate-media/react';\nimport { MentionPlugin } from '@udecode/plate-mention/react';\nimport { NodeIdPlugin } from '@udecode/plate-node-id';\nimport { NormalizeTypesPlugin } from '@udecode/plate-normalizers';\nimport { PlaywrightPlugin } from '@udecode/plate-playwright';\nimport { DeletePlugin, SelectOnBackspacePlugin } from '@udecode/plate-select';\nimport {\n BlockMenuPlugin,\n BlockSelectionPlugin,\n} from '@udecode/plate-selection/react';\nimport { SlashPlugin } from '@udecode/plate-slash-command/react';\nimport { TablePlugin } from '@udecode/plate-table/react';\nimport { TogglePlugin } from '@udecode/plate-toggle/react';\nimport { TrailingBlockPlugin } from '@udecode/plate-trailing-block';\nimport Prism from 'prismjs';\n\nimport { CheckPlugin } from '@/components/context/check-plugin';\nimport { settingsStore } from '@/components/context/settings-store';\nimport { aiPlugins } from '@/lib/plate/demo/plugins/ai-plugins';\nimport { getAutoformatOptions } from '@/lib/plate/demo/plugins/autoformatOptions';\nimport { copilotPlugins } from '@/lib/plate/demo/plugins/copilot-plugins';\nimport { createPlateUI } from '@/plate/create-plate-ui';\nimport { editableProps } from '@/plate/demo/editableProps';\nimport { isEnabled } from '@/plate/demo/is-enabled';\nimport { DragOverCursorPlugin } from '@/plate/demo/plugins/DragOverCursorPlugin';\nimport { exitBreakPlugin } from '@/plate/demo/plugins/exitBreakPlugin';\nimport { resetBlockTypePlugin } from '@/plate/demo/plugins/resetBlockTypePlugin';\nimport { softBreakPlugin } from '@/plate/demo/plugins/softBreakPlugin';\nimport { tabbablePlugin } from '@/plate/demo/plugins/tabbablePlugin';\nimport { commentsData, usersData } from '@/plate/demo/values/commentsValue';\nimport { usePlaygroundValue } from '@/plate/demo/values/usePlaygroundValue';\nimport { BlockContextMenu } from '@/components/plate-ui/block-context-menu';\nimport { CommentsPopover } from '@/components/plate-ui/comments-popover';\nimport {\n CursorOverlay,\n SelectionOverlayPlugin,\n} from '@/components/plate-ui/cursor-overlay';\nimport { Editor, EditorContainer } from '@/components/plate-ui/editor';\nimport { FixedToolbar } from '@/components/plate-ui/fixed-toolbar';\nimport { FixedToolbarButtons } from '@/components/plate-ui/fixed-toolbar-buttons';\nimport { FloatingToolbar } from '@/components/plate-ui/floating-toolbar';\nimport { FloatingToolbarButtons } from '@/components/plate-ui/floating-toolbar-buttons';\nimport { ImagePreview } from '@/components/plate-ui/image-preview';\nimport {\n FireLiComponent,\n FireMarker,\n} from '@/components/plate-ui/indent-fire-marker';\nimport {\n TodoLi,\n TodoMarker,\n} from '@/components/plate-ui/indent-todo-marker';\nimport { LinkFloatingToolbar } from '@/components/plate-ui/link-floating-toolbar';\n\nimport { usePlaygroundEnabled } from './usePlaygroundEnabled';\n\nexport const usePlaygroundEditor = (id: any = '', scrollSelector?: string) => {\n const enabledPlugins = settingsStore.use.checkedPlugins();\n const overridePlugins = usePlaygroundEnabled(id);\n const autoformatOptions = getAutoformatOptions(id, enabledPlugins);\n\n const value = usePlaygroundValue(id);\n const key = settingsStore.use.version();\n const editorId = id || 'playground-' + key;\n\n return usePlateEditor(\n {\n id: editorId,\n override: {\n components: createPlateUI({\n draggable: isEnabled('dnd', id),\n placeholder: isEnabled('placeholder', id),\n }),\n plugins: overridePlugins,\n },\n plugins: [\n // AI\n ...(id === 'ai' || enabledPlugins[AIChatPlugin.key] ? aiPlugins : []),\n ...(id === 'copilot' || enabledPlugins[CopilotPlugin.key]\n ? copilotPlugins\n : []),\n // Nodes\n HeadingPlugin,\n TocPlugin.configure({\n options: {\n scrollContainerSelector: `#${scrollSelector}`,\n topOffset: 80,\n },\n }),\n BlockquotePlugin,\n CodeBlockPlugin.configure({\n options: {\n prism: Prism,\n },\n }),\n HorizontalRulePlugin,\n LinkPlugin.extend({\n render: { afterEditable: () => },\n }),\n ...(id === 'list' ? [ListPlugin] : []),\n ImagePlugin.extend({\n options: {\n disableUploadInsert: true,\n },\n render: { afterEditable: ImagePreview },\n }),\n MediaEmbedPlugin,\n CaptionPlugin.configure({\n options: {\n plugins: [ImagePlugin, MediaEmbedPlugin],\n },\n }),\n DatePlugin,\n MentionPlugin.configure({\n options: {\n triggerPreviousCharPattern: /^$|^[\\s\"']$/,\n },\n }),\n SlashPlugin,\n TablePlugin.configure({\n options: {\n enableMerging: id === 'tableMerge',\n },\n }),\n ColumnPlugin,\n SelectionOverlayPlugin,\n\n TodoListPlugin,\n TogglePlugin,\n ExcalidrawPlugin,\n // Marks\n BoldPlugin,\n ItalicPlugin,\n UnderlinePlugin,\n StrikethroughPlugin,\n CodePlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n FontColorPlugin,\n FontBackgroundColorPlugin,\n FontSizePlugin,\n HighlightPlugin,\n KbdPlugin,\n\n // Block Style\n AlignPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n MediaEmbedPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n ImagePlugin.key,\n HEADING_KEYS.h6,\n ],\n },\n }),\n IndentPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n }),\n IndentListPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n options: {\n listStyleTypes: {\n fire: {\n liComponent: FireLiComponent,\n markerComponent: FireMarker,\n type: 'fire',\n },\n todo: {\n liComponent: TodoLi,\n markerComponent: TodoMarker,\n type: 'todo',\n },\n },\n },\n }),\n LineHeightPlugin.extend({\n inject: {\n nodeProps: {\n defaultNodeValue: 1.5,\n validNodeValues: [1, 1.2, 1.5, 2, 3],\n },\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n ],\n },\n }),\n\n // Functionality\n AutoformatPlugin.configure({\n options: autoformatOptions,\n }),\n BlockSelectionPlugin.configure({\n options: {\n areaOptions: {\n behaviour: {\n scrolling: {\n speedDivider: 1.5,\n },\n startThreshold: 10,\n },\n boundaries: `#${scrollSelector}`,\n container: `#${scrollSelector}`,\n selectables: [`#${scrollSelector} .slate-selectable`],\n selectionAreaClass: 'slate-selection-area',\n },\n enableContextMenu: true,\n },\n }),\n BlockMenuPlugin.configure({\n render: { aboveEditable: BlockContextMenu },\n }),\n DndPlugin.configure({\n options: {\n enableScroller: true,\n onDropFiles: ({ dragItem, editor, target }) => {\n editor\n .getTransforms(ImagePlugin)\n .insertImageFromFiles(dragItem.files, {\n at: target,\n nextBlock: false,\n });\n },\n },\n }),\n EmojiPlugin,\n exitBreakPlugin,\n NodeIdPlugin,\n NormalizeTypesPlugin.configure({\n options: {\n rules: [{ path: [0], strictType: HEADING_KEYS.h1 }],\n },\n }),\n resetBlockTypePlugin,\n SelectOnBackspacePlugin.configure({\n options: {\n query: {\n allow: [ImagePlugin.key, HorizontalRulePlugin.key],\n },\n },\n }),\n DeletePlugin,\n SingleLinePlugin,\n softBreakPlugin,\n tabbablePlugin,\n TrailingBlockPlugin.configure({\n options: { type: ParagraphPlugin.key },\n }),\n DragOverCursorPlugin,\n\n // Collaboration\n CommentsPlugin.configure({\n options: {\n comments: commentsData,\n myUserId: '1',\n users: usersData,\n },\n }),\n\n // Deserialization\n DocxPlugin,\n MarkdownPlugin.configure({ options: { indentList: true } }),\n JuicePlugin,\n\n // Testing\n PlaywrightPlugin.configure({\n enabled: process.env.NODE_ENV !== 'production',\n }),\n ],\n value: value,\n },\n []\n );\n};\n\nexport default function PlaygroundDemo({\n id,\n className,\n scrollSelector,\n}: {\n id?: ValueId;\n className?: string;\n scrollSelector?: string;\n}) {\n const containerRef = useRef(null);\n const enabled = settingsStore.use.checkedComponents();\n\n const editor = usePlaygroundEditor(\n id,\n scrollSelector ?? `blockSelection-${id}`\n );\n\n return (\n \n \n \n \n \n \n \n \n \n\n
\n \n \n\n \n \n \n \n \n \n \n\n \n \n \n \n\n \n \n \n
\n
\n
\n );\n}\n\nconst DemoIdContext = React.createContext(undefined);\n\nexport function DemoId({\n id,\n children,\n}: {\n children: React.ReactNode;\n id?: string;\n}) {\n return {children};\n}\n\nexport function useDemoId() {\n return React.useContext(DemoIdContext);\n}\n", "path": "example/playground-demo.tsx", "target": "components/playground-demo.tsx", "type": "registry:example" diff --git a/apps/www/public/r/styles/default/toggle-demo.json b/apps/www/public/r/styles/default/toggle-demo.json index 65644be55e..30c8528c65 100644 --- a/apps/www/public/r/styles/default/toggle-demo.json +++ b/apps/www/public/r/styles/default/toggle-demo.json @@ -4,7 +4,7 @@ }, "files": [ { - "content": "'use client';\n\nimport React, { useRef } from 'react';\n\nimport type { ValueId } from '@/config/customizer-plugins';\n\nimport { cn } from '@udecode/cn';\nimport { AIChatPlugin, CopilotPlugin } from '@udecode/plate-ai/react';\nimport { AlignPlugin } from '@udecode/plate-alignment/react';\nimport { AutoformatPlugin } from '@udecode/plate-autoformat/react';\nimport {\n BoldPlugin,\n CodePlugin,\n ItalicPlugin,\n StrikethroughPlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n UnderlinePlugin,\n} from '@udecode/plate-basic-marks/react';\nimport { BlockquotePlugin } from '@udecode/plate-block-quote/react';\nimport { SingleLinePlugin } from '@udecode/plate-break/react';\nimport { CaptionPlugin } from '@udecode/plate-caption/react';\nimport { CodeBlockPlugin } from '@udecode/plate-code-block/react';\nimport { CommentsPlugin } from '@udecode/plate-comments/react';\nimport {\n ParagraphPlugin,\n Plate,\n usePlateEditor,\n} from '@udecode/plate-common/react';\nimport { DatePlugin } from '@udecode/plate-date/react';\nimport { DndPlugin } from '@udecode/plate-dnd';\nimport { DocxPlugin } from '@udecode/plate-docx';\nimport { EmojiPlugin } from '@udecode/plate-emoji/react';\nimport { ExcalidrawPlugin } from '@udecode/plate-excalidraw/react';\nimport {\n FontBackgroundColorPlugin,\n FontColorPlugin,\n FontSizePlugin,\n} from '@udecode/plate-font/react';\nimport { HEADING_KEYS } from '@udecode/plate-heading';\nimport { HeadingPlugin, TocPlugin } from '@udecode/plate-heading/react';\nimport { HighlightPlugin } from '@udecode/plate-highlight/react';\nimport { HorizontalRulePlugin } from '@udecode/plate-horizontal-rule/react';\nimport { IndentPlugin } from '@udecode/plate-indent/react';\nimport { IndentListPlugin } from '@udecode/plate-indent-list/react';\nimport { JuicePlugin } from '@udecode/plate-juice';\nimport { KbdPlugin } from '@udecode/plate-kbd/react';\nimport { ColumnPlugin } from '@udecode/plate-layout/react';\nimport { LineHeightPlugin } from '@udecode/plate-line-height/react';\nimport { LinkPlugin } from '@udecode/plate-link/react';\nimport { ListPlugin, TodoListPlugin } from '@udecode/plate-list/react';\nimport { MarkdownPlugin } from '@udecode/plate-markdown';\nimport { ImagePlugin, MediaEmbedPlugin } from '@udecode/plate-media/react';\nimport { MentionPlugin } from '@udecode/plate-mention/react';\nimport { NodeIdPlugin } from '@udecode/plate-node-id';\nimport { NormalizeTypesPlugin } from '@udecode/plate-normalizers';\nimport { PlaywrightPlugin } from '@udecode/plate-playwright';\nimport { DeletePlugin, SelectOnBackspacePlugin } from '@udecode/plate-select';\nimport {\n BlockMenuPlugin,\n BlockSelectionPlugin,\n} from '@udecode/plate-selection/react';\nimport { SlashPlugin } from '@udecode/plate-slash-command/react';\nimport { TablePlugin } from '@udecode/plate-table/react';\nimport { TogglePlugin } from '@udecode/plate-toggle/react';\nimport { TrailingBlockPlugin } from '@udecode/plate-trailing-block';\nimport Prism from 'prismjs';\n\nimport { CheckPlugin } from '@/components/context/check-plugin';\nimport { settingsStore } from '@/components/context/settings-store';\nimport { aiPlugins } from '@/lib/plate/demo/plugins/ai-plugins';\nimport { getAutoformatOptions } from '@/lib/plate/demo/plugins/autoformatOptions';\nimport { copilotPlugins } from '@/lib/plate/demo/plugins/copilot-plugins';\nimport { createPlateUI } from '@/plate/create-plate-ui';\nimport { editableProps } from '@/plate/demo/editableProps';\nimport { isEnabled } from '@/plate/demo/is-enabled';\nimport { DragOverCursorPlugin } from '@/plate/demo/plugins/DragOverCursorPlugin';\nimport { exitBreakPlugin } from '@/plate/demo/plugins/exitBreakPlugin';\nimport { resetBlockTypePlugin } from '@/plate/demo/plugins/resetBlockTypePlugin';\nimport { softBreakPlugin } from '@/plate/demo/plugins/softBreakPlugin';\nimport { tabbablePlugin } from '@/plate/demo/plugins/tabbablePlugin';\nimport { commentsData, usersData } from '@/plate/demo/values/commentsValue';\nimport { usePlaygroundValue } from '@/plate/demo/values/usePlaygroundValue';\nimport { BlockContextMenu } from '@/components/plate-ui/block-context-menu';\nimport { CommentsPopover } from '@/components/plate-ui/comments-popover';\nimport {\n CursorOverlay,\n SelectionOverlayPlugin,\n} from '@/components/plate-ui/cursor-overlay';\nimport { Editor, EditorContainer } from '@/components/plate-ui/editor';\nimport { FixedToolbar } from '@/components/plate-ui/fixed-toolbar';\nimport { FixedToolbarButtons } from '@/components/plate-ui/fixed-toolbar-buttons';\nimport { FloatingToolbar } from '@/components/plate-ui/floating-toolbar';\nimport { FloatingToolbarButtons } from '@/components/plate-ui/floating-toolbar-buttons';\nimport { ImagePreview } from '@/components/plate-ui/image-preview';\nimport {\n FireLiComponent,\n FireMarker,\n} from '@/components/plate-ui/indent-fire-marker';\nimport {\n TodoLi,\n TodoMarker,\n} from '@/components/plate-ui/indent-todo-marker';\nimport { LinkFloatingToolbar } from '@/components/plate-ui/link-floating-toolbar';\n\nimport { usePlaygroundEnabled } from './usePlaygroundEnabled';\n\nexport const usePlaygroundEditor = (id: any = '', scrollSelector?: string) => {\n const enabledPlugins = settingsStore.use.checkedPlugins();\n const overridePlugins = usePlaygroundEnabled(id);\n const autoformatOptions = getAutoformatOptions(id, enabledPlugins);\n\n const value = usePlaygroundValue(id);\n const key = settingsStore.use.version();\n const editorId = id || 'playground-' + key;\n\n return usePlateEditor(\n {\n id: editorId,\n override: {\n components: createPlateUI({\n draggable: isEnabled('dnd', id),\n placeholder: isEnabled('placeholder', id),\n }),\n plugins: overridePlugins,\n },\n plugins: [\n // AI\n ...(id === 'ai' || enabledPlugins[AIChatPlugin.key] ? aiPlugins : []),\n ...(id === 'copilot' || enabledPlugins[CopilotPlugin.key]\n ? copilotPlugins\n : []),\n // Nodes\n HeadingPlugin,\n TocPlugin.configure({\n options: {\n scrollContainerSelector: `#${scrollSelector}`,\n topOffset: 80,\n },\n }),\n BlockquotePlugin,\n CodeBlockPlugin.configure({\n options: {\n prism: Prism,\n },\n }),\n HorizontalRulePlugin,\n LinkPlugin.extend({\n render: { afterEditable: () => },\n }),\n ...(id === 'list' ? [ListPlugin] : []),\n ImagePlugin.extend({\n render: { afterEditable: ImagePreview },\n }),\n MediaEmbedPlugin,\n CaptionPlugin.configure({\n options: {\n plugins: [ImagePlugin, MediaEmbedPlugin],\n },\n }),\n DatePlugin,\n MentionPlugin.configure({\n options: {\n triggerPreviousCharPattern: /^$|^[\\s\"']$/,\n },\n }),\n SlashPlugin,\n TablePlugin.configure({\n options: {\n enableMerging: id === 'tableMerge',\n },\n }),\n ColumnPlugin,\n SelectionOverlayPlugin,\n\n TodoListPlugin,\n TogglePlugin,\n ExcalidrawPlugin,\n // Marks\n BoldPlugin,\n ItalicPlugin,\n UnderlinePlugin,\n StrikethroughPlugin,\n CodePlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n FontColorPlugin,\n FontBackgroundColorPlugin,\n FontSizePlugin,\n HighlightPlugin,\n KbdPlugin,\n\n // Block Style\n AlignPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n MediaEmbedPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n ImagePlugin.key,\n HEADING_KEYS.h6,\n ],\n },\n }),\n IndentPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n }),\n IndentListPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n options: {\n listStyleTypes: {\n fire: {\n liComponent: FireLiComponent,\n markerComponent: FireMarker,\n type: 'fire',\n },\n todo: {\n liComponent: TodoLi,\n markerComponent: TodoMarker,\n type: 'todo',\n },\n },\n },\n }),\n LineHeightPlugin.extend({\n inject: {\n nodeProps: {\n defaultNodeValue: 1.5,\n validNodeValues: [1, 1.2, 1.5, 2, 3],\n },\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n ],\n },\n }),\n\n // Functionality\n AutoformatPlugin.configure({\n options: autoformatOptions,\n }),\n BlockSelectionPlugin.configure({\n options: {\n areaOptions: {\n behaviour: {\n scrolling: {\n speedDivider: 1.5,\n },\n startThreshold: 10,\n },\n boundaries: `#${scrollSelector}`,\n container: `#${scrollSelector}`,\n selectables: [`#${scrollSelector} .slate-selectable`],\n selectionAreaClass: 'slate-selection-area',\n },\n enableContextMenu: true,\n },\n }),\n BlockMenuPlugin.configure({\n render: { aboveEditable: BlockContextMenu },\n }),\n DndPlugin.configure({ options: { enableScroller: true } }),\n EmojiPlugin,\n exitBreakPlugin,\n NodeIdPlugin,\n NormalizeTypesPlugin.configure({\n options: {\n rules: [{ path: [0], strictType: HEADING_KEYS.h1 }],\n },\n }),\n resetBlockTypePlugin,\n SelectOnBackspacePlugin.configure({\n options: {\n query: {\n allow: [ImagePlugin.key, HorizontalRulePlugin.key],\n },\n },\n }),\n DeletePlugin,\n SingleLinePlugin,\n softBreakPlugin,\n tabbablePlugin,\n TrailingBlockPlugin.configure({\n options: { type: ParagraphPlugin.key },\n }),\n DragOverCursorPlugin,\n\n // Collaboration\n CommentsPlugin.configure({\n options: {\n comments: commentsData,\n myUserId: '1',\n users: usersData,\n },\n }),\n\n // Deserialization\n DocxPlugin,\n MarkdownPlugin.configure({ options: { indentList: true } }),\n JuicePlugin,\n\n // Testing\n PlaywrightPlugin.configure({\n enabled: process.env.NODE_ENV !== 'production',\n }),\n ],\n value: value,\n },\n []\n );\n};\n\nexport default function PlaygroundDemo({\n id,\n className,\n scrollSelector,\n}: {\n id?: ValueId;\n className?: string;\n scrollSelector?: string;\n}) {\n const containerRef = useRef(null);\n const enabled = settingsStore.use.checkedComponents();\n\n const editor = usePlaygroundEditor(\n id,\n scrollSelector ?? `blockSelection-${id}`\n );\n\n return (\n \n \n \n \n \n \n \n \n \n\n
\n \n \n\n \n \n \n \n \n \n \n\n \n \n \n \n\n \n \n \n
\n
\n
\n );\n}\n\nconst DemoIdContext = React.createContext(undefined);\n\nexport function DemoId({\n id,\n children,\n}: {\n children: React.ReactNode;\n id?: string;\n}) {\n return {children};\n}\n\nexport function useDemoId() {\n return React.useContext(DemoIdContext);\n}\n", + "content": "'use client';\n\nimport React, { useRef } from 'react';\n\nimport type { ValueId } from '@/config/customizer-plugins';\n\nimport { cn } from '@udecode/cn';\nimport { AIChatPlugin, CopilotPlugin } from '@udecode/plate-ai/react';\nimport { AlignPlugin } from '@udecode/plate-alignment/react';\nimport { AutoformatPlugin } from '@udecode/plate-autoformat/react';\nimport {\n BoldPlugin,\n CodePlugin,\n ItalicPlugin,\n StrikethroughPlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n UnderlinePlugin,\n} from '@udecode/plate-basic-marks/react';\nimport { BlockquotePlugin } from '@udecode/plate-block-quote/react';\nimport { SingleLinePlugin } from '@udecode/plate-break/react';\nimport { CaptionPlugin } from '@udecode/plate-caption/react';\nimport { CodeBlockPlugin } from '@udecode/plate-code-block/react';\nimport { CommentsPlugin } from '@udecode/plate-comments/react';\nimport {\n ParagraphPlugin,\n Plate,\n usePlateEditor,\n} from '@udecode/plate-common/react';\nimport { DatePlugin } from '@udecode/plate-date/react';\nimport { DndPlugin } from '@udecode/plate-dnd';\nimport { DocxPlugin } from '@udecode/plate-docx';\nimport { EmojiPlugin } from '@udecode/plate-emoji/react';\nimport { ExcalidrawPlugin } from '@udecode/plate-excalidraw/react';\nimport {\n FontBackgroundColorPlugin,\n FontColorPlugin,\n FontSizePlugin,\n} from '@udecode/plate-font/react';\nimport { HEADING_KEYS } from '@udecode/plate-heading';\nimport { HeadingPlugin, TocPlugin } from '@udecode/plate-heading/react';\nimport { HighlightPlugin } from '@udecode/plate-highlight/react';\nimport { HorizontalRulePlugin } from '@udecode/plate-horizontal-rule/react';\nimport { IndentPlugin } from '@udecode/plate-indent/react';\nimport { IndentListPlugin } from '@udecode/plate-indent-list/react';\nimport { JuicePlugin } from '@udecode/plate-juice';\nimport { KbdPlugin } from '@udecode/plate-kbd/react';\nimport { ColumnPlugin } from '@udecode/plate-layout/react';\nimport { LineHeightPlugin } from '@udecode/plate-line-height/react';\nimport { LinkPlugin } from '@udecode/plate-link/react';\nimport { ListPlugin, TodoListPlugin } from '@udecode/plate-list/react';\nimport { MarkdownPlugin } from '@udecode/plate-markdown';\nimport { ImagePlugin, MediaEmbedPlugin } from '@udecode/plate-media/react';\nimport { MentionPlugin } from '@udecode/plate-mention/react';\nimport { NodeIdPlugin } from '@udecode/plate-node-id';\nimport { NormalizeTypesPlugin } from '@udecode/plate-normalizers';\nimport { PlaywrightPlugin } from '@udecode/plate-playwright';\nimport { DeletePlugin, SelectOnBackspacePlugin } from '@udecode/plate-select';\nimport {\n BlockMenuPlugin,\n BlockSelectionPlugin,\n} from '@udecode/plate-selection/react';\nimport { SlashPlugin } from '@udecode/plate-slash-command/react';\nimport { TablePlugin } from '@udecode/plate-table/react';\nimport { TogglePlugin } from '@udecode/plate-toggle/react';\nimport { TrailingBlockPlugin } from '@udecode/plate-trailing-block';\nimport Prism from 'prismjs';\n\nimport { CheckPlugin } from '@/components/context/check-plugin';\nimport { settingsStore } from '@/components/context/settings-store';\nimport { aiPlugins } from '@/lib/plate/demo/plugins/ai-plugins';\nimport { getAutoformatOptions } from '@/lib/plate/demo/plugins/autoformatOptions';\nimport { copilotPlugins } from '@/lib/plate/demo/plugins/copilot-plugins';\nimport { createPlateUI } from '@/plate/create-plate-ui';\nimport { editableProps } from '@/plate/demo/editableProps';\nimport { isEnabled } from '@/plate/demo/is-enabled';\nimport { DragOverCursorPlugin } from '@/plate/demo/plugins/DragOverCursorPlugin';\nimport { exitBreakPlugin } from '@/plate/demo/plugins/exitBreakPlugin';\nimport { resetBlockTypePlugin } from '@/plate/demo/plugins/resetBlockTypePlugin';\nimport { softBreakPlugin } from '@/plate/demo/plugins/softBreakPlugin';\nimport { tabbablePlugin } from '@/plate/demo/plugins/tabbablePlugin';\nimport { commentsData, usersData } from '@/plate/demo/values/commentsValue';\nimport { usePlaygroundValue } from '@/plate/demo/values/usePlaygroundValue';\nimport { BlockContextMenu } from '@/components/plate-ui/block-context-menu';\nimport { CommentsPopover } from '@/components/plate-ui/comments-popover';\nimport {\n CursorOverlay,\n SelectionOverlayPlugin,\n} from '@/components/plate-ui/cursor-overlay';\nimport { Editor, EditorContainer } from '@/components/plate-ui/editor';\nimport { FixedToolbar } from '@/components/plate-ui/fixed-toolbar';\nimport { FixedToolbarButtons } from '@/components/plate-ui/fixed-toolbar-buttons';\nimport { FloatingToolbar } from '@/components/plate-ui/floating-toolbar';\nimport { FloatingToolbarButtons } from '@/components/plate-ui/floating-toolbar-buttons';\nimport { ImagePreview } from '@/components/plate-ui/image-preview';\nimport {\n FireLiComponent,\n FireMarker,\n} from '@/components/plate-ui/indent-fire-marker';\nimport {\n TodoLi,\n TodoMarker,\n} from '@/components/plate-ui/indent-todo-marker';\nimport { LinkFloatingToolbar } from '@/components/plate-ui/link-floating-toolbar';\n\nimport { usePlaygroundEnabled } from './usePlaygroundEnabled';\n\nexport const usePlaygroundEditor = (id: any = '', scrollSelector?: string) => {\n const enabledPlugins = settingsStore.use.checkedPlugins();\n const overridePlugins = usePlaygroundEnabled(id);\n const autoformatOptions = getAutoformatOptions(id, enabledPlugins);\n\n const value = usePlaygroundValue(id);\n const key = settingsStore.use.version();\n const editorId = id || 'playground-' + key;\n\n return usePlateEditor(\n {\n id: editorId,\n override: {\n components: createPlateUI({\n draggable: isEnabled('dnd', id),\n placeholder: isEnabled('placeholder', id),\n }),\n plugins: overridePlugins,\n },\n plugins: [\n // AI\n ...(id === 'ai' || enabledPlugins[AIChatPlugin.key] ? aiPlugins : []),\n ...(id === 'copilot' || enabledPlugins[CopilotPlugin.key]\n ? copilotPlugins\n : []),\n // Nodes\n HeadingPlugin,\n TocPlugin.configure({\n options: {\n scrollContainerSelector: `#${scrollSelector}`,\n topOffset: 80,\n },\n }),\n BlockquotePlugin,\n CodeBlockPlugin.configure({\n options: {\n prism: Prism,\n },\n }),\n HorizontalRulePlugin,\n LinkPlugin.extend({\n render: { afterEditable: () => },\n }),\n ...(id === 'list' ? [ListPlugin] : []),\n ImagePlugin.extend({\n options: {\n disableUploadInsert: true,\n },\n render: { afterEditable: ImagePreview },\n }),\n MediaEmbedPlugin,\n CaptionPlugin.configure({\n options: {\n plugins: [ImagePlugin, MediaEmbedPlugin],\n },\n }),\n DatePlugin,\n MentionPlugin.configure({\n options: {\n triggerPreviousCharPattern: /^$|^[\\s\"']$/,\n },\n }),\n SlashPlugin,\n TablePlugin.configure({\n options: {\n enableMerging: id === 'tableMerge',\n },\n }),\n ColumnPlugin,\n SelectionOverlayPlugin,\n\n TodoListPlugin,\n TogglePlugin,\n ExcalidrawPlugin,\n // Marks\n BoldPlugin,\n ItalicPlugin,\n UnderlinePlugin,\n StrikethroughPlugin,\n CodePlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n FontColorPlugin,\n FontBackgroundColorPlugin,\n FontSizePlugin,\n HighlightPlugin,\n KbdPlugin,\n\n // Block Style\n AlignPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n MediaEmbedPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n ImagePlugin.key,\n HEADING_KEYS.h6,\n ],\n },\n }),\n IndentPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n }),\n IndentListPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n options: {\n listStyleTypes: {\n fire: {\n liComponent: FireLiComponent,\n markerComponent: FireMarker,\n type: 'fire',\n },\n todo: {\n liComponent: TodoLi,\n markerComponent: TodoMarker,\n type: 'todo',\n },\n },\n },\n }),\n LineHeightPlugin.extend({\n inject: {\n nodeProps: {\n defaultNodeValue: 1.5,\n validNodeValues: [1, 1.2, 1.5, 2, 3],\n },\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n ],\n },\n }),\n\n // Functionality\n AutoformatPlugin.configure({\n options: autoformatOptions,\n }),\n BlockSelectionPlugin.configure({\n options: {\n areaOptions: {\n behaviour: {\n scrolling: {\n speedDivider: 1.5,\n },\n startThreshold: 10,\n },\n boundaries: `#${scrollSelector}`,\n container: `#${scrollSelector}`,\n selectables: [`#${scrollSelector} .slate-selectable`],\n selectionAreaClass: 'slate-selection-area',\n },\n enableContextMenu: true,\n },\n }),\n BlockMenuPlugin.configure({\n render: { aboveEditable: BlockContextMenu },\n }),\n DndPlugin.configure({\n options: {\n enableScroller: true,\n onDropFiles: ({ dragItem, editor, target }) => {\n editor\n .getTransforms(ImagePlugin)\n .insertImageFromFiles(dragItem.files, {\n at: target,\n nextBlock: false,\n });\n },\n },\n }),\n EmojiPlugin,\n exitBreakPlugin,\n NodeIdPlugin,\n NormalizeTypesPlugin.configure({\n options: {\n rules: [{ path: [0], strictType: HEADING_KEYS.h1 }],\n },\n }),\n resetBlockTypePlugin,\n SelectOnBackspacePlugin.configure({\n options: {\n query: {\n allow: [ImagePlugin.key, HorizontalRulePlugin.key],\n },\n },\n }),\n DeletePlugin,\n SingleLinePlugin,\n softBreakPlugin,\n tabbablePlugin,\n TrailingBlockPlugin.configure({\n options: { type: ParagraphPlugin.key },\n }),\n DragOverCursorPlugin,\n\n // Collaboration\n CommentsPlugin.configure({\n options: {\n comments: commentsData,\n myUserId: '1',\n users: usersData,\n },\n }),\n\n // Deserialization\n DocxPlugin,\n MarkdownPlugin.configure({ options: { indentList: true } }),\n JuicePlugin,\n\n // Testing\n PlaywrightPlugin.configure({\n enabled: process.env.NODE_ENV !== 'production',\n }),\n ],\n value: value,\n },\n []\n );\n};\n\nexport default function PlaygroundDemo({\n id,\n className,\n scrollSelector,\n}: {\n id?: ValueId;\n className?: string;\n scrollSelector?: string;\n}) {\n const containerRef = useRef(null);\n const enabled = settingsStore.use.checkedComponents();\n\n const editor = usePlaygroundEditor(\n id,\n scrollSelector ?? `blockSelection-${id}`\n );\n\n return (\n \n \n \n \n \n \n \n \n \n\n
\n \n \n\n \n \n \n \n \n \n \n\n \n \n \n \n\n \n \n \n
\n
\n
\n );\n}\n\nconst DemoIdContext = React.createContext(undefined);\n\nexport function DemoId({\n id,\n children,\n}: {\n children: React.ReactNode;\n id?: string;\n}) {\n return {children};\n}\n\nexport function useDemoId() {\n return React.useContext(DemoIdContext);\n}\n", "path": "example/playground-demo.tsx", "target": "components/playground-demo.tsx", "type": "registry:example" diff --git a/apps/www/public/r/styles/default/toolbar-demo.json b/apps/www/public/r/styles/default/toolbar-demo.json index d956c00d27..c67da04bd8 100644 --- a/apps/www/public/r/styles/default/toolbar-demo.json +++ b/apps/www/public/r/styles/default/toolbar-demo.json @@ -4,7 +4,7 @@ }, "files": [ { - "content": "'use client';\n\nimport React, { useRef } from 'react';\n\nimport type { ValueId } from '@/config/customizer-plugins';\n\nimport { cn } from '@udecode/cn';\nimport { AIChatPlugin, CopilotPlugin } from '@udecode/plate-ai/react';\nimport { AlignPlugin } from '@udecode/plate-alignment/react';\nimport { AutoformatPlugin } from '@udecode/plate-autoformat/react';\nimport {\n BoldPlugin,\n CodePlugin,\n ItalicPlugin,\n StrikethroughPlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n UnderlinePlugin,\n} from '@udecode/plate-basic-marks/react';\nimport { BlockquotePlugin } from '@udecode/plate-block-quote/react';\nimport { SingleLinePlugin } from '@udecode/plate-break/react';\nimport { CaptionPlugin } from '@udecode/plate-caption/react';\nimport { CodeBlockPlugin } from '@udecode/plate-code-block/react';\nimport { CommentsPlugin } from '@udecode/plate-comments/react';\nimport {\n ParagraphPlugin,\n Plate,\n usePlateEditor,\n} from '@udecode/plate-common/react';\nimport { DatePlugin } from '@udecode/plate-date/react';\nimport { DndPlugin } from '@udecode/plate-dnd';\nimport { DocxPlugin } from '@udecode/plate-docx';\nimport { EmojiPlugin } from '@udecode/plate-emoji/react';\nimport { ExcalidrawPlugin } from '@udecode/plate-excalidraw/react';\nimport {\n FontBackgroundColorPlugin,\n FontColorPlugin,\n FontSizePlugin,\n} from '@udecode/plate-font/react';\nimport { HEADING_KEYS } from '@udecode/plate-heading';\nimport { HeadingPlugin, TocPlugin } from '@udecode/plate-heading/react';\nimport { HighlightPlugin } from '@udecode/plate-highlight/react';\nimport { HorizontalRulePlugin } from '@udecode/plate-horizontal-rule/react';\nimport { IndentPlugin } from '@udecode/plate-indent/react';\nimport { IndentListPlugin } from '@udecode/plate-indent-list/react';\nimport { JuicePlugin } from '@udecode/plate-juice';\nimport { KbdPlugin } from '@udecode/plate-kbd/react';\nimport { ColumnPlugin } from '@udecode/plate-layout/react';\nimport { LineHeightPlugin } from '@udecode/plate-line-height/react';\nimport { LinkPlugin } from '@udecode/plate-link/react';\nimport { ListPlugin, TodoListPlugin } from '@udecode/plate-list/react';\nimport { MarkdownPlugin } from '@udecode/plate-markdown';\nimport { ImagePlugin, MediaEmbedPlugin } from '@udecode/plate-media/react';\nimport { MentionPlugin } from '@udecode/plate-mention/react';\nimport { NodeIdPlugin } from '@udecode/plate-node-id';\nimport { NormalizeTypesPlugin } from '@udecode/plate-normalizers';\nimport { PlaywrightPlugin } from '@udecode/plate-playwright';\nimport { DeletePlugin, SelectOnBackspacePlugin } from '@udecode/plate-select';\nimport {\n BlockMenuPlugin,\n BlockSelectionPlugin,\n} from '@udecode/plate-selection/react';\nimport { SlashPlugin } from '@udecode/plate-slash-command/react';\nimport { TablePlugin } from '@udecode/plate-table/react';\nimport { TogglePlugin } from '@udecode/plate-toggle/react';\nimport { TrailingBlockPlugin } from '@udecode/plate-trailing-block';\nimport Prism from 'prismjs';\n\nimport { CheckPlugin } from '@/components/context/check-plugin';\nimport { settingsStore } from '@/components/context/settings-store';\nimport { aiPlugins } from '@/lib/plate/demo/plugins/ai-plugins';\nimport { getAutoformatOptions } from '@/lib/plate/demo/plugins/autoformatOptions';\nimport { copilotPlugins } from '@/lib/plate/demo/plugins/copilot-plugins';\nimport { createPlateUI } from '@/plate/create-plate-ui';\nimport { editableProps } from '@/plate/demo/editableProps';\nimport { isEnabled } from '@/plate/demo/is-enabled';\nimport { DragOverCursorPlugin } from '@/plate/demo/plugins/DragOverCursorPlugin';\nimport { exitBreakPlugin } from '@/plate/demo/plugins/exitBreakPlugin';\nimport { resetBlockTypePlugin } from '@/plate/demo/plugins/resetBlockTypePlugin';\nimport { softBreakPlugin } from '@/plate/demo/plugins/softBreakPlugin';\nimport { tabbablePlugin } from '@/plate/demo/plugins/tabbablePlugin';\nimport { commentsData, usersData } from '@/plate/demo/values/commentsValue';\nimport { usePlaygroundValue } from '@/plate/demo/values/usePlaygroundValue';\nimport { BlockContextMenu } from '@/components/plate-ui/block-context-menu';\nimport { CommentsPopover } from '@/components/plate-ui/comments-popover';\nimport {\n CursorOverlay,\n SelectionOverlayPlugin,\n} from '@/components/plate-ui/cursor-overlay';\nimport { Editor, EditorContainer } from '@/components/plate-ui/editor';\nimport { FixedToolbar } from '@/components/plate-ui/fixed-toolbar';\nimport { FixedToolbarButtons } from '@/components/plate-ui/fixed-toolbar-buttons';\nimport { FloatingToolbar } from '@/components/plate-ui/floating-toolbar';\nimport { FloatingToolbarButtons } from '@/components/plate-ui/floating-toolbar-buttons';\nimport { ImagePreview } from '@/components/plate-ui/image-preview';\nimport {\n FireLiComponent,\n FireMarker,\n} from '@/components/plate-ui/indent-fire-marker';\nimport {\n TodoLi,\n TodoMarker,\n} from '@/components/plate-ui/indent-todo-marker';\nimport { LinkFloatingToolbar } from '@/components/plate-ui/link-floating-toolbar';\n\nimport { usePlaygroundEnabled } from './usePlaygroundEnabled';\n\nexport const usePlaygroundEditor = (id: any = '', scrollSelector?: string) => {\n const enabledPlugins = settingsStore.use.checkedPlugins();\n const overridePlugins = usePlaygroundEnabled(id);\n const autoformatOptions = getAutoformatOptions(id, enabledPlugins);\n\n const value = usePlaygroundValue(id);\n const key = settingsStore.use.version();\n const editorId = id || 'playground-' + key;\n\n return usePlateEditor(\n {\n id: editorId,\n override: {\n components: createPlateUI({\n draggable: isEnabled('dnd', id),\n placeholder: isEnabled('placeholder', id),\n }),\n plugins: overridePlugins,\n },\n plugins: [\n // AI\n ...(id === 'ai' || enabledPlugins[AIChatPlugin.key] ? aiPlugins : []),\n ...(id === 'copilot' || enabledPlugins[CopilotPlugin.key]\n ? copilotPlugins\n : []),\n // Nodes\n HeadingPlugin,\n TocPlugin.configure({\n options: {\n scrollContainerSelector: `#${scrollSelector}`,\n topOffset: 80,\n },\n }),\n BlockquotePlugin,\n CodeBlockPlugin.configure({\n options: {\n prism: Prism,\n },\n }),\n HorizontalRulePlugin,\n LinkPlugin.extend({\n render: { afterEditable: () => },\n }),\n ...(id === 'list' ? [ListPlugin] : []),\n ImagePlugin.extend({\n render: { afterEditable: ImagePreview },\n }),\n MediaEmbedPlugin,\n CaptionPlugin.configure({\n options: {\n plugins: [ImagePlugin, MediaEmbedPlugin],\n },\n }),\n DatePlugin,\n MentionPlugin.configure({\n options: {\n triggerPreviousCharPattern: /^$|^[\\s\"']$/,\n },\n }),\n SlashPlugin,\n TablePlugin.configure({\n options: {\n enableMerging: id === 'tableMerge',\n },\n }),\n ColumnPlugin,\n SelectionOverlayPlugin,\n\n TodoListPlugin,\n TogglePlugin,\n ExcalidrawPlugin,\n // Marks\n BoldPlugin,\n ItalicPlugin,\n UnderlinePlugin,\n StrikethroughPlugin,\n CodePlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n FontColorPlugin,\n FontBackgroundColorPlugin,\n FontSizePlugin,\n HighlightPlugin,\n KbdPlugin,\n\n // Block Style\n AlignPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n MediaEmbedPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n ImagePlugin.key,\n HEADING_KEYS.h6,\n ],\n },\n }),\n IndentPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n }),\n IndentListPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n options: {\n listStyleTypes: {\n fire: {\n liComponent: FireLiComponent,\n markerComponent: FireMarker,\n type: 'fire',\n },\n todo: {\n liComponent: TodoLi,\n markerComponent: TodoMarker,\n type: 'todo',\n },\n },\n },\n }),\n LineHeightPlugin.extend({\n inject: {\n nodeProps: {\n defaultNodeValue: 1.5,\n validNodeValues: [1, 1.2, 1.5, 2, 3],\n },\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n ],\n },\n }),\n\n // Functionality\n AutoformatPlugin.configure({\n options: autoformatOptions,\n }),\n BlockSelectionPlugin.configure({\n options: {\n areaOptions: {\n behaviour: {\n scrolling: {\n speedDivider: 1.5,\n },\n startThreshold: 10,\n },\n boundaries: `#${scrollSelector}`,\n container: `#${scrollSelector}`,\n selectables: [`#${scrollSelector} .slate-selectable`],\n selectionAreaClass: 'slate-selection-area',\n },\n enableContextMenu: true,\n },\n }),\n BlockMenuPlugin.configure({\n render: { aboveEditable: BlockContextMenu },\n }),\n DndPlugin.configure({ options: { enableScroller: true } }),\n EmojiPlugin,\n exitBreakPlugin,\n NodeIdPlugin,\n NormalizeTypesPlugin.configure({\n options: {\n rules: [{ path: [0], strictType: HEADING_KEYS.h1 }],\n },\n }),\n resetBlockTypePlugin,\n SelectOnBackspacePlugin.configure({\n options: {\n query: {\n allow: [ImagePlugin.key, HorizontalRulePlugin.key],\n },\n },\n }),\n DeletePlugin,\n SingleLinePlugin,\n softBreakPlugin,\n tabbablePlugin,\n TrailingBlockPlugin.configure({\n options: { type: ParagraphPlugin.key },\n }),\n DragOverCursorPlugin,\n\n // Collaboration\n CommentsPlugin.configure({\n options: {\n comments: commentsData,\n myUserId: '1',\n users: usersData,\n },\n }),\n\n // Deserialization\n DocxPlugin,\n MarkdownPlugin.configure({ options: { indentList: true } }),\n JuicePlugin,\n\n // Testing\n PlaywrightPlugin.configure({\n enabled: process.env.NODE_ENV !== 'production',\n }),\n ],\n value: value,\n },\n []\n );\n};\n\nexport default function PlaygroundDemo({\n id,\n className,\n scrollSelector,\n}: {\n id?: ValueId;\n className?: string;\n scrollSelector?: string;\n}) {\n const containerRef = useRef(null);\n const enabled = settingsStore.use.checkedComponents();\n\n const editor = usePlaygroundEditor(\n id,\n scrollSelector ?? `blockSelection-${id}`\n );\n\n return (\n \n \n \n \n \n \n \n \n \n\n
\n \n \n\n \n \n \n \n \n \n \n\n \n \n \n \n\n \n \n \n
\n
\n
\n );\n}\n\nconst DemoIdContext = React.createContext(undefined);\n\nexport function DemoId({\n id,\n children,\n}: {\n children: React.ReactNode;\n id?: string;\n}) {\n return {children};\n}\n\nexport function useDemoId() {\n return React.useContext(DemoIdContext);\n}\n", + "content": "'use client';\n\nimport React, { useRef } from 'react';\n\nimport type { ValueId } from '@/config/customizer-plugins';\n\nimport { cn } from '@udecode/cn';\nimport { AIChatPlugin, CopilotPlugin } from '@udecode/plate-ai/react';\nimport { AlignPlugin } from '@udecode/plate-alignment/react';\nimport { AutoformatPlugin } from '@udecode/plate-autoformat/react';\nimport {\n BoldPlugin,\n CodePlugin,\n ItalicPlugin,\n StrikethroughPlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n UnderlinePlugin,\n} from '@udecode/plate-basic-marks/react';\nimport { BlockquotePlugin } from '@udecode/plate-block-quote/react';\nimport { SingleLinePlugin } from '@udecode/plate-break/react';\nimport { CaptionPlugin } from '@udecode/plate-caption/react';\nimport { CodeBlockPlugin } from '@udecode/plate-code-block/react';\nimport { CommentsPlugin } from '@udecode/plate-comments/react';\nimport {\n ParagraphPlugin,\n Plate,\n usePlateEditor,\n} from '@udecode/plate-common/react';\nimport { DatePlugin } from '@udecode/plate-date/react';\nimport { DndPlugin } from '@udecode/plate-dnd';\nimport { DocxPlugin } from '@udecode/plate-docx';\nimport { EmojiPlugin } from '@udecode/plate-emoji/react';\nimport { ExcalidrawPlugin } from '@udecode/plate-excalidraw/react';\nimport {\n FontBackgroundColorPlugin,\n FontColorPlugin,\n FontSizePlugin,\n} from '@udecode/plate-font/react';\nimport { HEADING_KEYS } from '@udecode/plate-heading';\nimport { HeadingPlugin, TocPlugin } from '@udecode/plate-heading/react';\nimport { HighlightPlugin } from '@udecode/plate-highlight/react';\nimport { HorizontalRulePlugin } from '@udecode/plate-horizontal-rule/react';\nimport { IndentPlugin } from '@udecode/plate-indent/react';\nimport { IndentListPlugin } from '@udecode/plate-indent-list/react';\nimport { JuicePlugin } from '@udecode/plate-juice';\nimport { KbdPlugin } from '@udecode/plate-kbd/react';\nimport { ColumnPlugin } from '@udecode/plate-layout/react';\nimport { LineHeightPlugin } from '@udecode/plate-line-height/react';\nimport { LinkPlugin } from '@udecode/plate-link/react';\nimport { ListPlugin, TodoListPlugin } from '@udecode/plate-list/react';\nimport { MarkdownPlugin } from '@udecode/plate-markdown';\nimport { ImagePlugin, MediaEmbedPlugin } from '@udecode/plate-media/react';\nimport { MentionPlugin } from '@udecode/plate-mention/react';\nimport { NodeIdPlugin } from '@udecode/plate-node-id';\nimport { NormalizeTypesPlugin } from '@udecode/plate-normalizers';\nimport { PlaywrightPlugin } from '@udecode/plate-playwright';\nimport { DeletePlugin, SelectOnBackspacePlugin } from '@udecode/plate-select';\nimport {\n BlockMenuPlugin,\n BlockSelectionPlugin,\n} from '@udecode/plate-selection/react';\nimport { SlashPlugin } from '@udecode/plate-slash-command/react';\nimport { TablePlugin } from '@udecode/plate-table/react';\nimport { TogglePlugin } from '@udecode/plate-toggle/react';\nimport { TrailingBlockPlugin } from '@udecode/plate-trailing-block';\nimport Prism from 'prismjs';\n\nimport { CheckPlugin } from '@/components/context/check-plugin';\nimport { settingsStore } from '@/components/context/settings-store';\nimport { aiPlugins } from '@/lib/plate/demo/plugins/ai-plugins';\nimport { getAutoformatOptions } from '@/lib/plate/demo/plugins/autoformatOptions';\nimport { copilotPlugins } from '@/lib/plate/demo/plugins/copilot-plugins';\nimport { createPlateUI } from '@/plate/create-plate-ui';\nimport { editableProps } from '@/plate/demo/editableProps';\nimport { isEnabled } from '@/plate/demo/is-enabled';\nimport { DragOverCursorPlugin } from '@/plate/demo/plugins/DragOverCursorPlugin';\nimport { exitBreakPlugin } from '@/plate/demo/plugins/exitBreakPlugin';\nimport { resetBlockTypePlugin } from '@/plate/demo/plugins/resetBlockTypePlugin';\nimport { softBreakPlugin } from '@/plate/demo/plugins/softBreakPlugin';\nimport { tabbablePlugin } from '@/plate/demo/plugins/tabbablePlugin';\nimport { commentsData, usersData } from '@/plate/demo/values/commentsValue';\nimport { usePlaygroundValue } from '@/plate/demo/values/usePlaygroundValue';\nimport { BlockContextMenu } from '@/components/plate-ui/block-context-menu';\nimport { CommentsPopover } from '@/components/plate-ui/comments-popover';\nimport {\n CursorOverlay,\n SelectionOverlayPlugin,\n} from '@/components/plate-ui/cursor-overlay';\nimport { Editor, EditorContainer } from '@/components/plate-ui/editor';\nimport { FixedToolbar } from '@/components/plate-ui/fixed-toolbar';\nimport { FixedToolbarButtons } from '@/components/plate-ui/fixed-toolbar-buttons';\nimport { FloatingToolbar } from '@/components/plate-ui/floating-toolbar';\nimport { FloatingToolbarButtons } from '@/components/plate-ui/floating-toolbar-buttons';\nimport { ImagePreview } from '@/components/plate-ui/image-preview';\nimport {\n FireLiComponent,\n FireMarker,\n} from '@/components/plate-ui/indent-fire-marker';\nimport {\n TodoLi,\n TodoMarker,\n} from '@/components/plate-ui/indent-todo-marker';\nimport { LinkFloatingToolbar } from '@/components/plate-ui/link-floating-toolbar';\n\nimport { usePlaygroundEnabled } from './usePlaygroundEnabled';\n\nexport const usePlaygroundEditor = (id: any = '', scrollSelector?: string) => {\n const enabledPlugins = settingsStore.use.checkedPlugins();\n const overridePlugins = usePlaygroundEnabled(id);\n const autoformatOptions = getAutoformatOptions(id, enabledPlugins);\n\n const value = usePlaygroundValue(id);\n const key = settingsStore.use.version();\n const editorId = id || 'playground-' + key;\n\n return usePlateEditor(\n {\n id: editorId,\n override: {\n components: createPlateUI({\n draggable: isEnabled('dnd', id),\n placeholder: isEnabled('placeholder', id),\n }),\n plugins: overridePlugins,\n },\n plugins: [\n // AI\n ...(id === 'ai' || enabledPlugins[AIChatPlugin.key] ? aiPlugins : []),\n ...(id === 'copilot' || enabledPlugins[CopilotPlugin.key]\n ? copilotPlugins\n : []),\n // Nodes\n HeadingPlugin,\n TocPlugin.configure({\n options: {\n scrollContainerSelector: `#${scrollSelector}`,\n topOffset: 80,\n },\n }),\n BlockquotePlugin,\n CodeBlockPlugin.configure({\n options: {\n prism: Prism,\n },\n }),\n HorizontalRulePlugin,\n LinkPlugin.extend({\n render: { afterEditable: () => },\n }),\n ...(id === 'list' ? [ListPlugin] : []),\n ImagePlugin.extend({\n options: {\n disableUploadInsert: true,\n },\n render: { afterEditable: ImagePreview },\n }),\n MediaEmbedPlugin,\n CaptionPlugin.configure({\n options: {\n plugins: [ImagePlugin, MediaEmbedPlugin],\n },\n }),\n DatePlugin,\n MentionPlugin.configure({\n options: {\n triggerPreviousCharPattern: /^$|^[\\s\"']$/,\n },\n }),\n SlashPlugin,\n TablePlugin.configure({\n options: {\n enableMerging: id === 'tableMerge',\n },\n }),\n ColumnPlugin,\n SelectionOverlayPlugin,\n\n TodoListPlugin,\n TogglePlugin,\n ExcalidrawPlugin,\n // Marks\n BoldPlugin,\n ItalicPlugin,\n UnderlinePlugin,\n StrikethroughPlugin,\n CodePlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n FontColorPlugin,\n FontBackgroundColorPlugin,\n FontSizePlugin,\n HighlightPlugin,\n KbdPlugin,\n\n // Block Style\n AlignPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n MediaEmbedPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n ImagePlugin.key,\n HEADING_KEYS.h6,\n ],\n },\n }),\n IndentPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n }),\n IndentListPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n options: {\n listStyleTypes: {\n fire: {\n liComponent: FireLiComponent,\n markerComponent: FireMarker,\n type: 'fire',\n },\n todo: {\n liComponent: TodoLi,\n markerComponent: TodoMarker,\n type: 'todo',\n },\n },\n },\n }),\n LineHeightPlugin.extend({\n inject: {\n nodeProps: {\n defaultNodeValue: 1.5,\n validNodeValues: [1, 1.2, 1.5, 2, 3],\n },\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n ],\n },\n }),\n\n // Functionality\n AutoformatPlugin.configure({\n options: autoformatOptions,\n }),\n BlockSelectionPlugin.configure({\n options: {\n areaOptions: {\n behaviour: {\n scrolling: {\n speedDivider: 1.5,\n },\n startThreshold: 10,\n },\n boundaries: `#${scrollSelector}`,\n container: `#${scrollSelector}`,\n selectables: [`#${scrollSelector} .slate-selectable`],\n selectionAreaClass: 'slate-selection-area',\n },\n enableContextMenu: true,\n },\n }),\n BlockMenuPlugin.configure({\n render: { aboveEditable: BlockContextMenu },\n }),\n DndPlugin.configure({\n options: {\n enableScroller: true,\n onDropFiles: ({ dragItem, editor, target }) => {\n editor\n .getTransforms(ImagePlugin)\n .insertImageFromFiles(dragItem.files, {\n at: target,\n nextBlock: false,\n });\n },\n },\n }),\n EmojiPlugin,\n exitBreakPlugin,\n NodeIdPlugin,\n NormalizeTypesPlugin.configure({\n options: {\n rules: [{ path: [0], strictType: HEADING_KEYS.h1 }],\n },\n }),\n resetBlockTypePlugin,\n SelectOnBackspacePlugin.configure({\n options: {\n query: {\n allow: [ImagePlugin.key, HorizontalRulePlugin.key],\n },\n },\n }),\n DeletePlugin,\n SingleLinePlugin,\n softBreakPlugin,\n tabbablePlugin,\n TrailingBlockPlugin.configure({\n options: { type: ParagraphPlugin.key },\n }),\n DragOverCursorPlugin,\n\n // Collaboration\n CommentsPlugin.configure({\n options: {\n comments: commentsData,\n myUserId: '1',\n users: usersData,\n },\n }),\n\n // Deserialization\n DocxPlugin,\n MarkdownPlugin.configure({ options: { indentList: true } }),\n JuicePlugin,\n\n // Testing\n PlaywrightPlugin.configure({\n enabled: process.env.NODE_ENV !== 'production',\n }),\n ],\n value: value,\n },\n []\n );\n};\n\nexport default function PlaygroundDemo({\n id,\n className,\n scrollSelector,\n}: {\n id?: ValueId;\n className?: string;\n scrollSelector?: string;\n}) {\n const containerRef = useRef(null);\n const enabled = settingsStore.use.checkedComponents();\n\n const editor = usePlaygroundEditor(\n id,\n scrollSelector ?? `blockSelection-${id}`\n );\n\n return (\n \n \n \n \n \n \n \n \n \n\n
\n \n \n\n \n \n \n \n \n \n \n\n \n \n \n \n\n \n \n \n
\n
\n
\n );\n}\n\nconst DemoIdContext = React.createContext(undefined);\n\nexport function DemoId({\n id,\n children,\n}: {\n children: React.ReactNode;\n id?: string;\n}) {\n return {children};\n}\n\nexport function useDemoId() {\n return React.useContext(DemoIdContext);\n}\n", "path": "example/playground-demo.tsx", "target": "components/playground-demo.tsx", "type": "registry:example" diff --git a/apps/www/public/r/styles/default/upload-demo.json b/apps/www/public/r/styles/default/upload-demo.json index bbf71ebbdb..8f8ba398f0 100644 --- a/apps/www/public/r/styles/default/upload-demo.json +++ b/apps/www/public/r/styles/default/upload-demo.json @@ -4,7 +4,7 @@ }, "files": [ { - "content": "'use client';\n\nimport React, { useRef } from 'react';\n\nimport type { ValueId } from '@/config/customizer-plugins';\n\nimport { cn } from '@udecode/cn';\nimport { AIChatPlugin, CopilotPlugin } from '@udecode/plate-ai/react';\nimport { AlignPlugin } from '@udecode/plate-alignment/react';\nimport { AutoformatPlugin } from '@udecode/plate-autoformat/react';\nimport {\n BoldPlugin,\n CodePlugin,\n ItalicPlugin,\n StrikethroughPlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n UnderlinePlugin,\n} from '@udecode/plate-basic-marks/react';\nimport { BlockquotePlugin } from '@udecode/plate-block-quote/react';\nimport { SingleLinePlugin } from '@udecode/plate-break/react';\nimport { CaptionPlugin } from '@udecode/plate-caption/react';\nimport { CodeBlockPlugin } from '@udecode/plate-code-block/react';\nimport { CommentsPlugin } from '@udecode/plate-comments/react';\nimport {\n ParagraphPlugin,\n Plate,\n usePlateEditor,\n} from '@udecode/plate-common/react';\nimport { DatePlugin } from '@udecode/plate-date/react';\nimport { DndPlugin } from '@udecode/plate-dnd';\nimport { DocxPlugin } from '@udecode/plate-docx';\nimport { EmojiPlugin } from '@udecode/plate-emoji/react';\nimport { ExcalidrawPlugin } from '@udecode/plate-excalidraw/react';\nimport {\n FontBackgroundColorPlugin,\n FontColorPlugin,\n FontSizePlugin,\n} from '@udecode/plate-font/react';\nimport { HEADING_KEYS } from '@udecode/plate-heading';\nimport { HeadingPlugin, TocPlugin } from '@udecode/plate-heading/react';\nimport { HighlightPlugin } from '@udecode/plate-highlight/react';\nimport { HorizontalRulePlugin } from '@udecode/plate-horizontal-rule/react';\nimport { IndentPlugin } from '@udecode/plate-indent/react';\nimport { IndentListPlugin } from '@udecode/plate-indent-list/react';\nimport { JuicePlugin } from '@udecode/plate-juice';\nimport { KbdPlugin } from '@udecode/plate-kbd/react';\nimport { ColumnPlugin } from '@udecode/plate-layout/react';\nimport { LineHeightPlugin } from '@udecode/plate-line-height/react';\nimport { LinkPlugin } from '@udecode/plate-link/react';\nimport { ListPlugin, TodoListPlugin } from '@udecode/plate-list/react';\nimport { MarkdownPlugin } from '@udecode/plate-markdown';\nimport { ImagePlugin, MediaEmbedPlugin } from '@udecode/plate-media/react';\nimport { MentionPlugin } from '@udecode/plate-mention/react';\nimport { NodeIdPlugin } from '@udecode/plate-node-id';\nimport { NormalizeTypesPlugin } from '@udecode/plate-normalizers';\nimport { PlaywrightPlugin } from '@udecode/plate-playwright';\nimport { DeletePlugin, SelectOnBackspacePlugin } from '@udecode/plate-select';\nimport {\n BlockMenuPlugin,\n BlockSelectionPlugin,\n} from '@udecode/plate-selection/react';\nimport { SlashPlugin } from '@udecode/plate-slash-command/react';\nimport { TablePlugin } from '@udecode/plate-table/react';\nimport { TogglePlugin } from '@udecode/plate-toggle/react';\nimport { TrailingBlockPlugin } from '@udecode/plate-trailing-block';\nimport Prism from 'prismjs';\n\nimport { CheckPlugin } from '@/components/context/check-plugin';\nimport { settingsStore } from '@/components/context/settings-store';\nimport { aiPlugins } from '@/lib/plate/demo/plugins/ai-plugins';\nimport { getAutoformatOptions } from '@/lib/plate/demo/plugins/autoformatOptions';\nimport { copilotPlugins } from '@/lib/plate/demo/plugins/copilot-plugins';\nimport { createPlateUI } from '@/plate/create-plate-ui';\nimport { editableProps } from '@/plate/demo/editableProps';\nimport { isEnabled } from '@/plate/demo/is-enabled';\nimport { DragOverCursorPlugin } from '@/plate/demo/plugins/DragOverCursorPlugin';\nimport { exitBreakPlugin } from '@/plate/demo/plugins/exitBreakPlugin';\nimport { resetBlockTypePlugin } from '@/plate/demo/plugins/resetBlockTypePlugin';\nimport { softBreakPlugin } from '@/plate/demo/plugins/softBreakPlugin';\nimport { tabbablePlugin } from '@/plate/demo/plugins/tabbablePlugin';\nimport { commentsData, usersData } from '@/plate/demo/values/commentsValue';\nimport { usePlaygroundValue } from '@/plate/demo/values/usePlaygroundValue';\nimport { BlockContextMenu } from '@/components/plate-ui/block-context-menu';\nimport { CommentsPopover } from '@/components/plate-ui/comments-popover';\nimport {\n CursorOverlay,\n SelectionOverlayPlugin,\n} from '@/components/plate-ui/cursor-overlay';\nimport { Editor, EditorContainer } from '@/components/plate-ui/editor';\nimport { FixedToolbar } from '@/components/plate-ui/fixed-toolbar';\nimport { FixedToolbarButtons } from '@/components/plate-ui/fixed-toolbar-buttons';\nimport { FloatingToolbar } from '@/components/plate-ui/floating-toolbar';\nimport { FloatingToolbarButtons } from '@/components/plate-ui/floating-toolbar-buttons';\nimport { ImagePreview } from '@/components/plate-ui/image-preview';\nimport {\n FireLiComponent,\n FireMarker,\n} from '@/components/plate-ui/indent-fire-marker';\nimport {\n TodoLi,\n TodoMarker,\n} from '@/components/plate-ui/indent-todo-marker';\nimport { LinkFloatingToolbar } from '@/components/plate-ui/link-floating-toolbar';\n\nimport { usePlaygroundEnabled } from './usePlaygroundEnabled';\n\nexport const usePlaygroundEditor = (id: any = '', scrollSelector?: string) => {\n const enabledPlugins = settingsStore.use.checkedPlugins();\n const overridePlugins = usePlaygroundEnabled(id);\n const autoformatOptions = getAutoformatOptions(id, enabledPlugins);\n\n const value = usePlaygroundValue(id);\n const key = settingsStore.use.version();\n const editorId = id || 'playground-' + key;\n\n return usePlateEditor(\n {\n id: editorId,\n override: {\n components: createPlateUI({\n draggable: isEnabled('dnd', id),\n placeholder: isEnabled('placeholder', id),\n }),\n plugins: overridePlugins,\n },\n plugins: [\n // AI\n ...(id === 'ai' || enabledPlugins[AIChatPlugin.key] ? aiPlugins : []),\n ...(id === 'copilot' || enabledPlugins[CopilotPlugin.key]\n ? copilotPlugins\n : []),\n // Nodes\n HeadingPlugin,\n TocPlugin.configure({\n options: {\n scrollContainerSelector: `#${scrollSelector}`,\n topOffset: 80,\n },\n }),\n BlockquotePlugin,\n CodeBlockPlugin.configure({\n options: {\n prism: Prism,\n },\n }),\n HorizontalRulePlugin,\n LinkPlugin.extend({\n render: { afterEditable: () => },\n }),\n ...(id === 'list' ? [ListPlugin] : []),\n ImagePlugin.extend({\n render: { afterEditable: ImagePreview },\n }),\n MediaEmbedPlugin,\n CaptionPlugin.configure({\n options: {\n plugins: [ImagePlugin, MediaEmbedPlugin],\n },\n }),\n DatePlugin,\n MentionPlugin.configure({\n options: {\n triggerPreviousCharPattern: /^$|^[\\s\"']$/,\n },\n }),\n SlashPlugin,\n TablePlugin.configure({\n options: {\n enableMerging: id === 'tableMerge',\n },\n }),\n ColumnPlugin,\n SelectionOverlayPlugin,\n\n TodoListPlugin,\n TogglePlugin,\n ExcalidrawPlugin,\n // Marks\n BoldPlugin,\n ItalicPlugin,\n UnderlinePlugin,\n StrikethroughPlugin,\n CodePlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n FontColorPlugin,\n FontBackgroundColorPlugin,\n FontSizePlugin,\n HighlightPlugin,\n KbdPlugin,\n\n // Block Style\n AlignPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n MediaEmbedPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n ImagePlugin.key,\n HEADING_KEYS.h6,\n ],\n },\n }),\n IndentPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n }),\n IndentListPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n options: {\n listStyleTypes: {\n fire: {\n liComponent: FireLiComponent,\n markerComponent: FireMarker,\n type: 'fire',\n },\n todo: {\n liComponent: TodoLi,\n markerComponent: TodoMarker,\n type: 'todo',\n },\n },\n },\n }),\n LineHeightPlugin.extend({\n inject: {\n nodeProps: {\n defaultNodeValue: 1.5,\n validNodeValues: [1, 1.2, 1.5, 2, 3],\n },\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n ],\n },\n }),\n\n // Functionality\n AutoformatPlugin.configure({\n options: autoformatOptions,\n }),\n BlockSelectionPlugin.configure({\n options: {\n areaOptions: {\n behaviour: {\n scrolling: {\n speedDivider: 1.5,\n },\n startThreshold: 10,\n },\n boundaries: `#${scrollSelector}`,\n container: `#${scrollSelector}`,\n selectables: [`#${scrollSelector} .slate-selectable`],\n selectionAreaClass: 'slate-selection-area',\n },\n enableContextMenu: true,\n },\n }),\n BlockMenuPlugin.configure({\n render: { aboveEditable: BlockContextMenu },\n }),\n DndPlugin.configure({ options: { enableScroller: true } }),\n EmojiPlugin,\n exitBreakPlugin,\n NodeIdPlugin,\n NormalizeTypesPlugin.configure({\n options: {\n rules: [{ path: [0], strictType: HEADING_KEYS.h1 }],\n },\n }),\n resetBlockTypePlugin,\n SelectOnBackspacePlugin.configure({\n options: {\n query: {\n allow: [ImagePlugin.key, HorizontalRulePlugin.key],\n },\n },\n }),\n DeletePlugin,\n SingleLinePlugin,\n softBreakPlugin,\n tabbablePlugin,\n TrailingBlockPlugin.configure({\n options: { type: ParagraphPlugin.key },\n }),\n DragOverCursorPlugin,\n\n // Collaboration\n CommentsPlugin.configure({\n options: {\n comments: commentsData,\n myUserId: '1',\n users: usersData,\n },\n }),\n\n // Deserialization\n DocxPlugin,\n MarkdownPlugin.configure({ options: { indentList: true } }),\n JuicePlugin,\n\n // Testing\n PlaywrightPlugin.configure({\n enabled: process.env.NODE_ENV !== 'production',\n }),\n ],\n value: value,\n },\n []\n );\n};\n\nexport default function PlaygroundDemo({\n id,\n className,\n scrollSelector,\n}: {\n id?: ValueId;\n className?: string;\n scrollSelector?: string;\n}) {\n const containerRef = useRef(null);\n const enabled = settingsStore.use.checkedComponents();\n\n const editor = usePlaygroundEditor(\n id,\n scrollSelector ?? `blockSelection-${id}`\n );\n\n return (\n \n \n \n \n \n \n \n \n \n\n
\n \n \n\n \n \n \n \n \n \n \n\n \n \n \n \n\n \n \n \n
\n
\n
\n );\n}\n\nconst DemoIdContext = React.createContext(undefined);\n\nexport function DemoId({\n id,\n children,\n}: {\n children: React.ReactNode;\n id?: string;\n}) {\n return {children};\n}\n\nexport function useDemoId() {\n return React.useContext(DemoIdContext);\n}\n", + "content": "'use client';\n\nimport React, { useRef } from 'react';\n\nimport type { ValueId } from '@/config/customizer-plugins';\n\nimport { cn } from '@udecode/cn';\nimport { AIChatPlugin, CopilotPlugin } from '@udecode/plate-ai/react';\nimport { AlignPlugin } from '@udecode/plate-alignment/react';\nimport { AutoformatPlugin } from '@udecode/plate-autoformat/react';\nimport {\n BoldPlugin,\n CodePlugin,\n ItalicPlugin,\n StrikethroughPlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n UnderlinePlugin,\n} from '@udecode/plate-basic-marks/react';\nimport { BlockquotePlugin } from '@udecode/plate-block-quote/react';\nimport { SingleLinePlugin } from '@udecode/plate-break/react';\nimport { CaptionPlugin } from '@udecode/plate-caption/react';\nimport { CodeBlockPlugin } from '@udecode/plate-code-block/react';\nimport { CommentsPlugin } from '@udecode/plate-comments/react';\nimport {\n ParagraphPlugin,\n Plate,\n usePlateEditor,\n} from '@udecode/plate-common/react';\nimport { DatePlugin } from '@udecode/plate-date/react';\nimport { DndPlugin } from '@udecode/plate-dnd';\nimport { DocxPlugin } from '@udecode/plate-docx';\nimport { EmojiPlugin } from '@udecode/plate-emoji/react';\nimport { ExcalidrawPlugin } from '@udecode/plate-excalidraw/react';\nimport {\n FontBackgroundColorPlugin,\n FontColorPlugin,\n FontSizePlugin,\n} from '@udecode/plate-font/react';\nimport { HEADING_KEYS } from '@udecode/plate-heading';\nimport { HeadingPlugin, TocPlugin } from '@udecode/plate-heading/react';\nimport { HighlightPlugin } from '@udecode/plate-highlight/react';\nimport { HorizontalRulePlugin } from '@udecode/plate-horizontal-rule/react';\nimport { IndentPlugin } from '@udecode/plate-indent/react';\nimport { IndentListPlugin } from '@udecode/plate-indent-list/react';\nimport { JuicePlugin } from '@udecode/plate-juice';\nimport { KbdPlugin } from '@udecode/plate-kbd/react';\nimport { ColumnPlugin } from '@udecode/plate-layout/react';\nimport { LineHeightPlugin } from '@udecode/plate-line-height/react';\nimport { LinkPlugin } from '@udecode/plate-link/react';\nimport { ListPlugin, TodoListPlugin } from '@udecode/plate-list/react';\nimport { MarkdownPlugin } from '@udecode/plate-markdown';\nimport { ImagePlugin, MediaEmbedPlugin } from '@udecode/plate-media/react';\nimport { MentionPlugin } from '@udecode/plate-mention/react';\nimport { NodeIdPlugin } from '@udecode/plate-node-id';\nimport { NormalizeTypesPlugin } from '@udecode/plate-normalizers';\nimport { PlaywrightPlugin } from '@udecode/plate-playwright';\nimport { DeletePlugin, SelectOnBackspacePlugin } from '@udecode/plate-select';\nimport {\n BlockMenuPlugin,\n BlockSelectionPlugin,\n} from '@udecode/plate-selection/react';\nimport { SlashPlugin } from '@udecode/plate-slash-command/react';\nimport { TablePlugin } from '@udecode/plate-table/react';\nimport { TogglePlugin } from '@udecode/plate-toggle/react';\nimport { TrailingBlockPlugin } from '@udecode/plate-trailing-block';\nimport Prism from 'prismjs';\n\nimport { CheckPlugin } from '@/components/context/check-plugin';\nimport { settingsStore } from '@/components/context/settings-store';\nimport { aiPlugins } from '@/lib/plate/demo/plugins/ai-plugins';\nimport { getAutoformatOptions } from '@/lib/plate/demo/plugins/autoformatOptions';\nimport { copilotPlugins } from '@/lib/plate/demo/plugins/copilot-plugins';\nimport { createPlateUI } from '@/plate/create-plate-ui';\nimport { editableProps } from '@/plate/demo/editableProps';\nimport { isEnabled } from '@/plate/demo/is-enabled';\nimport { DragOverCursorPlugin } from '@/plate/demo/plugins/DragOverCursorPlugin';\nimport { exitBreakPlugin } from '@/plate/demo/plugins/exitBreakPlugin';\nimport { resetBlockTypePlugin } from '@/plate/demo/plugins/resetBlockTypePlugin';\nimport { softBreakPlugin } from '@/plate/demo/plugins/softBreakPlugin';\nimport { tabbablePlugin } from '@/plate/demo/plugins/tabbablePlugin';\nimport { commentsData, usersData } from '@/plate/demo/values/commentsValue';\nimport { usePlaygroundValue } from '@/plate/demo/values/usePlaygroundValue';\nimport { BlockContextMenu } from '@/components/plate-ui/block-context-menu';\nimport { CommentsPopover } from '@/components/plate-ui/comments-popover';\nimport {\n CursorOverlay,\n SelectionOverlayPlugin,\n} from '@/components/plate-ui/cursor-overlay';\nimport { Editor, EditorContainer } from '@/components/plate-ui/editor';\nimport { FixedToolbar } from '@/components/plate-ui/fixed-toolbar';\nimport { FixedToolbarButtons } from '@/components/plate-ui/fixed-toolbar-buttons';\nimport { FloatingToolbar } from '@/components/plate-ui/floating-toolbar';\nimport { FloatingToolbarButtons } from '@/components/plate-ui/floating-toolbar-buttons';\nimport { ImagePreview } from '@/components/plate-ui/image-preview';\nimport {\n FireLiComponent,\n FireMarker,\n} from '@/components/plate-ui/indent-fire-marker';\nimport {\n TodoLi,\n TodoMarker,\n} from '@/components/plate-ui/indent-todo-marker';\nimport { LinkFloatingToolbar } from '@/components/plate-ui/link-floating-toolbar';\n\nimport { usePlaygroundEnabled } from './usePlaygroundEnabled';\n\nexport const usePlaygroundEditor = (id: any = '', scrollSelector?: string) => {\n const enabledPlugins = settingsStore.use.checkedPlugins();\n const overridePlugins = usePlaygroundEnabled(id);\n const autoformatOptions = getAutoformatOptions(id, enabledPlugins);\n\n const value = usePlaygroundValue(id);\n const key = settingsStore.use.version();\n const editorId = id || 'playground-' + key;\n\n return usePlateEditor(\n {\n id: editorId,\n override: {\n components: createPlateUI({\n draggable: isEnabled('dnd', id),\n placeholder: isEnabled('placeholder', id),\n }),\n plugins: overridePlugins,\n },\n plugins: [\n // AI\n ...(id === 'ai' || enabledPlugins[AIChatPlugin.key] ? aiPlugins : []),\n ...(id === 'copilot' || enabledPlugins[CopilotPlugin.key]\n ? copilotPlugins\n : []),\n // Nodes\n HeadingPlugin,\n TocPlugin.configure({\n options: {\n scrollContainerSelector: `#${scrollSelector}`,\n topOffset: 80,\n },\n }),\n BlockquotePlugin,\n CodeBlockPlugin.configure({\n options: {\n prism: Prism,\n },\n }),\n HorizontalRulePlugin,\n LinkPlugin.extend({\n render: { afterEditable: () => },\n }),\n ...(id === 'list' ? [ListPlugin] : []),\n ImagePlugin.extend({\n options: {\n disableUploadInsert: true,\n },\n render: { afterEditable: ImagePreview },\n }),\n MediaEmbedPlugin,\n CaptionPlugin.configure({\n options: {\n plugins: [ImagePlugin, MediaEmbedPlugin],\n },\n }),\n DatePlugin,\n MentionPlugin.configure({\n options: {\n triggerPreviousCharPattern: /^$|^[\\s\"']$/,\n },\n }),\n SlashPlugin,\n TablePlugin.configure({\n options: {\n enableMerging: id === 'tableMerge',\n },\n }),\n ColumnPlugin,\n SelectionOverlayPlugin,\n\n TodoListPlugin,\n TogglePlugin,\n ExcalidrawPlugin,\n // Marks\n BoldPlugin,\n ItalicPlugin,\n UnderlinePlugin,\n StrikethroughPlugin,\n CodePlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n FontColorPlugin,\n FontBackgroundColorPlugin,\n FontSizePlugin,\n HighlightPlugin,\n KbdPlugin,\n\n // Block Style\n AlignPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n MediaEmbedPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n ImagePlugin.key,\n HEADING_KEYS.h6,\n ],\n },\n }),\n IndentPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n }),\n IndentListPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n options: {\n listStyleTypes: {\n fire: {\n liComponent: FireLiComponent,\n markerComponent: FireMarker,\n type: 'fire',\n },\n todo: {\n liComponent: TodoLi,\n markerComponent: TodoMarker,\n type: 'todo',\n },\n },\n },\n }),\n LineHeightPlugin.extend({\n inject: {\n nodeProps: {\n defaultNodeValue: 1.5,\n validNodeValues: [1, 1.2, 1.5, 2, 3],\n },\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n ],\n },\n }),\n\n // Functionality\n AutoformatPlugin.configure({\n options: autoformatOptions,\n }),\n BlockSelectionPlugin.configure({\n options: {\n areaOptions: {\n behaviour: {\n scrolling: {\n speedDivider: 1.5,\n },\n startThreshold: 10,\n },\n boundaries: `#${scrollSelector}`,\n container: `#${scrollSelector}`,\n selectables: [`#${scrollSelector} .slate-selectable`],\n selectionAreaClass: 'slate-selection-area',\n },\n enableContextMenu: true,\n },\n }),\n BlockMenuPlugin.configure({\n render: { aboveEditable: BlockContextMenu },\n }),\n DndPlugin.configure({\n options: {\n enableScroller: true,\n onDropFiles: ({ dragItem, editor, target }) => {\n editor\n .getTransforms(ImagePlugin)\n .insertImageFromFiles(dragItem.files, {\n at: target,\n nextBlock: false,\n });\n },\n },\n }),\n EmojiPlugin,\n exitBreakPlugin,\n NodeIdPlugin,\n NormalizeTypesPlugin.configure({\n options: {\n rules: [{ path: [0], strictType: HEADING_KEYS.h1 }],\n },\n }),\n resetBlockTypePlugin,\n SelectOnBackspacePlugin.configure({\n options: {\n query: {\n allow: [ImagePlugin.key, HorizontalRulePlugin.key],\n },\n },\n }),\n DeletePlugin,\n SingleLinePlugin,\n softBreakPlugin,\n tabbablePlugin,\n TrailingBlockPlugin.configure({\n options: { type: ParagraphPlugin.key },\n }),\n DragOverCursorPlugin,\n\n // Collaboration\n CommentsPlugin.configure({\n options: {\n comments: commentsData,\n myUserId: '1',\n users: usersData,\n },\n }),\n\n // Deserialization\n DocxPlugin,\n MarkdownPlugin.configure({ options: { indentList: true } }),\n JuicePlugin,\n\n // Testing\n PlaywrightPlugin.configure({\n enabled: process.env.NODE_ENV !== 'production',\n }),\n ],\n value: value,\n },\n []\n );\n};\n\nexport default function PlaygroundDemo({\n id,\n className,\n scrollSelector,\n}: {\n id?: ValueId;\n className?: string;\n scrollSelector?: string;\n}) {\n const containerRef = useRef(null);\n const enabled = settingsStore.use.checkedComponents();\n\n const editor = usePlaygroundEditor(\n id,\n scrollSelector ?? `blockSelection-${id}`\n );\n\n return (\n \n \n \n \n \n \n \n \n \n\n
\n \n \n\n \n \n \n \n \n \n \n\n \n \n \n \n\n \n \n \n
\n
\n
\n );\n}\n\nconst DemoIdContext = React.createContext(undefined);\n\nexport function DemoId({\n id,\n children,\n}: {\n children: React.ReactNode;\n id?: string;\n}) {\n return {children};\n}\n\nexport function useDemoId() {\n return React.useContext(DemoIdContext);\n}\n", "path": "example/playground-demo.tsx", "target": "components/playground-demo.tsx", "type": "registry:example" diff --git a/apps/www/src/registry/default/example/playground-demo.tsx b/apps/www/src/registry/default/example/playground-demo.tsx index cd71d5cc3f..8a5ca7badb 100644 --- a/apps/www/src/registry/default/example/playground-demo.tsx +++ b/apps/www/src/registry/default/example/playground-demo.tsx @@ -300,11 +300,11 @@ export const usePlaygroundEditor = (id: any = '', scrollSelector?: string) => { DndPlugin.configure({ options: { enableScroller: true, - onDropFiles: (editor, props) => { + onDropFiles: ({ dragItem, editor, target }) => { editor .getTransforms(ImagePlugin) - .insertImageFromFiles(props.dragItem.files, { - at: props.dropPath, + .insert.imageFromFiles(dragItem.files, { + at: target, nextBlock: false, }); }, diff --git a/apps/www/src/registry/default/plate-ui/image-element.tsx b/apps/www/src/registry/default/plate-ui/image-element.tsx index 48129dd57b..c052329d2d 100644 --- a/apps/www/src/registry/default/plate-ui/image-element.tsx +++ b/apps/www/src/registry/default/plate-ui/image-element.tsx @@ -4,6 +4,7 @@ import React from 'react'; import { cn, withRef } from '@udecode/cn'; import { withHOC } from '@udecode/plate-common/react'; +import { useDraggable, useDraggableState } from '@udecode/plate-dnd'; import { Image, ImagePlugin, useMediaState } from '@udecode/plate-media/react'; import { ResizableProvider, useResizableStore } from '@udecode/plate-resizable'; @@ -24,6 +25,10 @@ export const ImageElement = withHOC( const width = useResizableStore().get.width(); + const state = useDraggableState({ element: props.element }); + const { isDragging } = state; + const { handleRef } = useDraggable(state); + return ( { + e.preventDefault(); + }} placeholder="Write a caption..." /> diff --git a/packages/dnd/src/DndPlugin.tsx b/packages/dnd/src/DndPlugin.tsx index a2f1bb6e4a..82753138c4 100644 --- a/packages/dnd/src/DndPlugin.tsx +++ b/packages/dnd/src/DndPlugin.tsx @@ -20,16 +20,14 @@ export type DndConfig = PluginConfig< enableScroller?: boolean; isDragging?: boolean; scrollerProps?: Partial; - onDropFiles?: ( - props: { - editor: PlateEditor; - id: string; - dragItem: FileDragItemNode; - monitor: DropTargetMonitor; - nodeRef: any; - dropPath?: Path; - } - ) => void; + onDropFiles?: (props: { + id: string; + dragItem: FileDragItemNode; + editor: PlateEditor; + monitor: DropTargetMonitor; + nodeRef: any; + target?: Path; + }) => void; } >; diff --git a/packages/dnd/src/hooks/useDropNode.ts b/packages/dnd/src/hooks/useDropNode.ts index bbaeb315fe..5f88c1ab7f 100644 --- a/packages/dnd/src/hooks/useDropNode.ts +++ b/packages/dnd/src/hooks/useDropNode.ts @@ -97,12 +97,13 @@ export const useDropNode = ( if (!result || !onDropFiles) return; - return onDropFiles(editor, { + return onDropFiles({ id, dragItem: dragItem as FileDragItemNode, - dropPath: result.to, + editor, monitor, nodeRef, + target: result.to, }); } diff --git a/packages/media/src/lib/image/BaseImagePlugin.ts b/packages/media/src/lib/image/BaseImagePlugin.ts index c99c69c249..0ff9d9a4c1 100644 --- a/packages/media/src/lib/image/BaseImagePlugin.ts +++ b/packages/media/src/lib/image/BaseImagePlugin.ts @@ -45,7 +45,9 @@ export const BaseImagePlugin = createTSlatePlugin({ }, }) .extendEditorTransforms(({ editor }) => ({ - insertImageFromFiles: bindFirst(insertImageFromFiles, editor), + insert: { + imageFromFiles: bindFirst(insertImageFromFiles, editor as any), + }, })) .extend(({ plugin }) => ({ parsers: { diff --git a/packages/media/src/lib/image/withImageEmbed.spec.tsx b/packages/media/src/lib/image/withImageEmbed.spec.tsx index 94edff4ceb..11f7bda11d 100644 --- a/packages/media/src/lib/image/withImageEmbed.spec.tsx +++ b/packages/media/src/lib/image/withImageEmbed.spec.tsx @@ -4,7 +4,7 @@ import { getEditorPlugin } from '@udecode/plate-common'; import { createSlateEditor } from '@udecode/plate-common'; import { jsx } from '@udecode/plate-test-utils'; -import { BaseImagePlugin } from './BaseImagePlugin'; +import { ImagePlugin } from '../../react'; import { withImageEmbed } from './withImageEmbed'; jsx; @@ -27,7 +27,7 @@ describe('withImageEmbed', () => { it('should insert image from the text', () => { const editor = withImageEmbed( - getEditorPlugin(createSlateEditor({ editor: input }), BaseImagePlugin) + getEditorPlugin(createSlateEditor({ editor: input }), ImagePlugin as any) ); const data = { diff --git a/packages/media/src/lib/image/withImageUpload.spec.tsx b/packages/media/src/lib/image/withImageUpload.spec.tsx index 0d2eb8135e..7576bc0d33 100644 --- a/packages/media/src/lib/image/withImageUpload.spec.tsx +++ b/packages/media/src/lib/image/withImageUpload.spec.tsx @@ -2,8 +2,8 @@ import { createPlateEditor } from '@udecode/plate-common/react'; import { jsx } from '@udecode/plate-test-utils'; +import { ImagePlugin } from '../../react'; -import { BaseImagePlugin } from './BaseImagePlugin'; jsx; @@ -24,7 +24,7 @@ describe('withImageUpload', () => { it('should insert image from the file(s)', () => { const editor = createPlateEditor({ editor: input, - plugins: [BaseImagePlugin], + plugins: [ImagePlugin], }); const data = { @@ -59,7 +59,7 @@ describe('withImageUpload', () => { const editor = createPlateEditor({ editor: input, - plugins: [BaseImagePlugin], + plugins: [ImagePlugin], }); const data = { @@ -87,7 +87,7 @@ describe('withImageUpload', () => { it('should insert image from the file(s)', () => { const editor = createPlateEditor({ editor: input, - plugins: [BaseImagePlugin], + plugins: [ImagePlugin], }); const data = { diff --git a/packages/media/src/lib/image/withImageUpload.ts b/packages/media/src/lib/image/withImageUpload.ts index f8a21db241..61c46bc645 100644 --- a/packages/media/src/lib/image/withImageUpload.ts +++ b/packages/media/src/lib/image/withImageUpload.ts @@ -39,7 +39,7 @@ export const withImageUpload: ExtendEditor = ({ return insertData(dataTransfer); } - editor.getTransforms(ImagePlugin).insertImageFromFiles(files); + editor.getTransforms(ImagePlugin).insert.imageFromFiles(files); } else { return insertData(dataTransfer); } From 1e6f440f94edb06d691f419c7e81a2473fa2d8c0 Mon Sep 17 00:00:00 2001 From: Felix Feng Date: Mon, 4 Nov 2024 14:29:01 +0800 Subject: [PATCH 17/25] test --- apps/www/src/registry/default/plate-ui/image-element.tsx | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/apps/www/src/registry/default/plate-ui/image-element.tsx b/apps/www/src/registry/default/plate-ui/image-element.tsx index c052329d2d..d5915ce915 100644 --- a/apps/www/src/registry/default/plate-ui/image-element.tsx +++ b/apps/www/src/registry/default/plate-ui/image-element.tsx @@ -4,7 +4,6 @@ import React from 'react'; import { cn, withRef } from '@udecode/cn'; import { withHOC } from '@udecode/plate-common/react'; -import { useDraggable, useDraggableState } from '@udecode/plate-dnd'; import { Image, ImagePlugin, useMediaState } from '@udecode/plate-media/react'; import { ResizableProvider, useResizableStore } from '@udecode/plate-resizable'; @@ -25,10 +24,6 @@ export const ImageElement = withHOC( const width = useResizableStore().get.width(); - const state = useDraggableState({ element: props.element }); - const { isDragging } = state; - const { handleRef } = useDraggable(state); - return ( Date: Mon, 4 Nov 2024 16:43:59 +0800 Subject: [PATCH 18/25] ci --- apps/www/public/r/styles/default/ai-demo.json | 2 +- apps/www/public/r/styles/default/align-demo.json | 2 +- apps/www/public/r/styles/default/basic-elements-demo.json | 2 +- apps/www/public/r/styles/default/basic-marks-demo.json | 2 +- apps/www/public/r/styles/default/basic-nodes-demo.json | 2 +- apps/www/public/r/styles/default/block-menu-demo.json | 2 +- .../www/public/r/styles/default/block-selection-demo.json | 2 +- apps/www/public/r/styles/default/column-demo.json | 2 +- apps/www/public/r/styles/default/comment-demo.json | 2 +- apps/www/public/r/styles/default/copilot-demo.json | 2 +- apps/www/public/r/styles/default/date-demo.json | 2 +- apps/www/public/r/styles/default/dnd-demo.json | 2 +- apps/www/public/r/styles/default/emoji-demo.json | 2 +- apps/www/public/r/styles/default/excalidraw-demo.json | 2 +- .../public/r/styles/default/floating-toolbar-demo.json | 2 +- apps/www/public/r/styles/default/font-demo.json | 2 +- apps/www/public/r/styles/default/highlight-demo.json | 2 +- apps/www/public/r/styles/default/hr-demo.json | 2 +- apps/www/public/r/styles/default/image-element.json | 2 +- apps/www/public/r/styles/default/indent-demo.json | 2 +- apps/www/public/r/styles/default/kbd-demo.json | 2 +- apps/www/public/r/styles/default/line-height-demo.json | 2 +- apps/www/public/r/styles/default/link-demo.json | 2 +- apps/www/public/r/styles/default/list-demo.json | 2 +- apps/www/public/r/styles/default/media-demo.json | 2 +- apps/www/public/r/styles/default/mention-demo.json | 2 +- apps/www/public/r/styles/default/mode-demo.json | 2 +- apps/www/public/r/styles/default/placeholder-demo.json | 2 +- apps/www/public/r/styles/default/playground-demo.json | 2 +- apps/www/public/r/styles/default/resizable-demo.json | 2 +- apps/www/public/r/styles/default/slash-command-demo.json | 2 +- apps/www/public/r/styles/default/table-demo.json | 2 +- apps/www/public/r/styles/default/toc-demo.json | 2 +- apps/www/public/r/styles/default/toggle-demo.json | 2 +- apps/www/public/r/styles/default/toolbar-demo.json | 2 +- apps/www/public/r/styles/default/upload-demo.json | 2 +- apps/www/src/registry/default/example/playground-demo.tsx | 3 ++- packages/media/src/lib/image/BaseImagePlugin.ts | 2 +- packages/media/src/lib/image/transforms/index.ts | 1 + .../src/lib/image/transforms/insertImageFromFiles.ts | 4 ++-- packages/media/src/lib/image/withImageEmbed.spec.tsx | 7 +++++-- packages/media/src/lib/image/withImageUpload.spec.tsx | 8 ++++---- packages/media/src/lib/image/withImageUpload.ts | 4 ++-- 43 files changed, 53 insertions(+), 48 deletions(-) diff --git a/apps/www/public/r/styles/default/ai-demo.json b/apps/www/public/r/styles/default/ai-demo.json index 72b02bfb82..cce9c651a0 100644 --- a/apps/www/public/r/styles/default/ai-demo.json +++ b/apps/www/public/r/styles/default/ai-demo.json @@ -9,7 +9,7 @@ }, "files": [ { - "content": "'use client';\n\nimport React, { useRef } from 'react';\n\nimport type { ValueId } from '@/config/customizer-plugins';\n\nimport { cn } from '@udecode/cn';\nimport { AIChatPlugin, CopilotPlugin } from '@udecode/plate-ai/react';\nimport { AlignPlugin } from '@udecode/plate-alignment/react';\nimport { AutoformatPlugin } from '@udecode/plate-autoformat/react';\nimport {\n BoldPlugin,\n CodePlugin,\n ItalicPlugin,\n StrikethroughPlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n UnderlinePlugin,\n} from '@udecode/plate-basic-marks/react';\nimport { BlockquotePlugin } from '@udecode/plate-block-quote/react';\nimport { SingleLinePlugin } from '@udecode/plate-break/react';\nimport { CaptionPlugin } from '@udecode/plate-caption/react';\nimport { CodeBlockPlugin } from '@udecode/plate-code-block/react';\nimport { CommentsPlugin } from '@udecode/plate-comments/react';\nimport {\n ParagraphPlugin,\n Plate,\n usePlateEditor,\n} from '@udecode/plate-common/react';\nimport { DatePlugin } from '@udecode/plate-date/react';\nimport { DndPlugin } from '@udecode/plate-dnd';\nimport { DocxPlugin } from '@udecode/plate-docx';\nimport { EmojiPlugin } from '@udecode/plate-emoji/react';\nimport { ExcalidrawPlugin } from '@udecode/plate-excalidraw/react';\nimport {\n FontBackgroundColorPlugin,\n FontColorPlugin,\n FontSizePlugin,\n} from '@udecode/plate-font/react';\nimport { HEADING_KEYS } from '@udecode/plate-heading';\nimport { HeadingPlugin, TocPlugin } from '@udecode/plate-heading/react';\nimport { HighlightPlugin } from '@udecode/plate-highlight/react';\nimport { HorizontalRulePlugin } from '@udecode/plate-horizontal-rule/react';\nimport { IndentPlugin } from '@udecode/plate-indent/react';\nimport { IndentListPlugin } from '@udecode/plate-indent-list/react';\nimport { JuicePlugin } from '@udecode/plate-juice';\nimport { KbdPlugin } from '@udecode/plate-kbd/react';\nimport { ColumnPlugin } from '@udecode/plate-layout/react';\nimport { LineHeightPlugin } from '@udecode/plate-line-height/react';\nimport { LinkPlugin } from '@udecode/plate-link/react';\nimport { ListPlugin, TodoListPlugin } from '@udecode/plate-list/react';\nimport { MarkdownPlugin } from '@udecode/plate-markdown';\nimport { ImagePlugin, MediaEmbedPlugin } from '@udecode/plate-media/react';\nimport { MentionPlugin } from '@udecode/plate-mention/react';\nimport { NodeIdPlugin } from '@udecode/plate-node-id';\nimport { NormalizeTypesPlugin } from '@udecode/plate-normalizers';\nimport { PlaywrightPlugin } from '@udecode/plate-playwright';\nimport { DeletePlugin, SelectOnBackspacePlugin } from '@udecode/plate-select';\nimport {\n BlockMenuPlugin,\n BlockSelectionPlugin,\n} from '@udecode/plate-selection/react';\nimport { SlashPlugin } from '@udecode/plate-slash-command/react';\nimport { TablePlugin } from '@udecode/plate-table/react';\nimport { TogglePlugin } from '@udecode/plate-toggle/react';\nimport { TrailingBlockPlugin } from '@udecode/plate-trailing-block';\nimport Prism from 'prismjs';\n\nimport { CheckPlugin } from '@/components/context/check-plugin';\nimport { settingsStore } from '@/components/context/settings-store';\nimport { aiPlugins } from '@/lib/plate/demo/plugins/ai-plugins';\nimport { getAutoformatOptions } from '@/lib/plate/demo/plugins/autoformatOptions';\nimport { copilotPlugins } from '@/lib/plate/demo/plugins/copilot-plugins';\nimport { createPlateUI } from '@/plate/create-plate-ui';\nimport { editableProps } from '@/plate/demo/editableProps';\nimport { isEnabled } from '@/plate/demo/is-enabled';\nimport { DragOverCursorPlugin } from '@/plate/demo/plugins/DragOverCursorPlugin';\nimport { exitBreakPlugin } from '@/plate/demo/plugins/exitBreakPlugin';\nimport { resetBlockTypePlugin } from '@/plate/demo/plugins/resetBlockTypePlugin';\nimport { softBreakPlugin } from '@/plate/demo/plugins/softBreakPlugin';\nimport { tabbablePlugin } from '@/plate/demo/plugins/tabbablePlugin';\nimport { commentsData, usersData } from '@/plate/demo/values/commentsValue';\nimport { usePlaygroundValue } from '@/plate/demo/values/usePlaygroundValue';\nimport { BlockContextMenu } from '@/components/plate-ui/block-context-menu';\nimport { CommentsPopover } from '@/components/plate-ui/comments-popover';\nimport {\n CursorOverlay,\n SelectionOverlayPlugin,\n} from '@/components/plate-ui/cursor-overlay';\nimport { Editor, EditorContainer } from '@/components/plate-ui/editor';\nimport { FixedToolbar } from '@/components/plate-ui/fixed-toolbar';\nimport { FixedToolbarButtons } from '@/components/plate-ui/fixed-toolbar-buttons';\nimport { FloatingToolbar } from '@/components/plate-ui/floating-toolbar';\nimport { FloatingToolbarButtons } from '@/components/plate-ui/floating-toolbar-buttons';\nimport { ImagePreview } from '@/components/plate-ui/image-preview';\nimport {\n FireLiComponent,\n FireMarker,\n} from '@/components/plate-ui/indent-fire-marker';\nimport {\n TodoLi,\n TodoMarker,\n} from '@/components/plate-ui/indent-todo-marker';\nimport { LinkFloatingToolbar } from '@/components/plate-ui/link-floating-toolbar';\n\nimport { usePlaygroundEnabled } from './usePlaygroundEnabled';\n\nexport const usePlaygroundEditor = (id: any = '', scrollSelector?: string) => {\n const enabledPlugins = settingsStore.use.checkedPlugins();\n const overridePlugins = usePlaygroundEnabled(id);\n const autoformatOptions = getAutoformatOptions(id, enabledPlugins);\n\n const value = usePlaygroundValue(id);\n const key = settingsStore.use.version();\n const editorId = id || 'playground-' + key;\n\n return usePlateEditor(\n {\n id: editorId,\n override: {\n components: createPlateUI({\n draggable: isEnabled('dnd', id),\n placeholder: isEnabled('placeholder', id),\n }),\n plugins: overridePlugins,\n },\n plugins: [\n // AI\n ...(id === 'ai' || enabledPlugins[AIChatPlugin.key] ? aiPlugins : []),\n ...(id === 'copilot' || enabledPlugins[CopilotPlugin.key]\n ? copilotPlugins\n : []),\n // Nodes\n HeadingPlugin,\n TocPlugin.configure({\n options: {\n scrollContainerSelector: `#${scrollSelector}`,\n topOffset: 80,\n },\n }),\n BlockquotePlugin,\n CodeBlockPlugin.configure({\n options: {\n prism: Prism,\n },\n }),\n HorizontalRulePlugin,\n LinkPlugin.extend({\n render: { afterEditable: () => },\n }),\n ...(id === 'list' ? [ListPlugin] : []),\n ImagePlugin.extend({\n options: {\n disableUploadInsert: true,\n },\n render: { afterEditable: ImagePreview },\n }),\n MediaEmbedPlugin,\n CaptionPlugin.configure({\n options: {\n plugins: [ImagePlugin, MediaEmbedPlugin],\n },\n }),\n DatePlugin,\n MentionPlugin.configure({\n options: {\n triggerPreviousCharPattern: /^$|^[\\s\"']$/,\n },\n }),\n SlashPlugin,\n TablePlugin.configure({\n options: {\n enableMerging: id === 'tableMerge',\n },\n }),\n ColumnPlugin,\n SelectionOverlayPlugin,\n\n TodoListPlugin,\n TogglePlugin,\n ExcalidrawPlugin,\n // Marks\n BoldPlugin,\n ItalicPlugin,\n UnderlinePlugin,\n StrikethroughPlugin,\n CodePlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n FontColorPlugin,\n FontBackgroundColorPlugin,\n FontSizePlugin,\n HighlightPlugin,\n KbdPlugin,\n\n // Block Style\n AlignPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n MediaEmbedPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n ImagePlugin.key,\n HEADING_KEYS.h6,\n ],\n },\n }),\n IndentPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n }),\n IndentListPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n options: {\n listStyleTypes: {\n fire: {\n liComponent: FireLiComponent,\n markerComponent: FireMarker,\n type: 'fire',\n },\n todo: {\n liComponent: TodoLi,\n markerComponent: TodoMarker,\n type: 'todo',\n },\n },\n },\n }),\n LineHeightPlugin.extend({\n inject: {\n nodeProps: {\n defaultNodeValue: 1.5,\n validNodeValues: [1, 1.2, 1.5, 2, 3],\n },\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n ],\n },\n }),\n\n // Functionality\n AutoformatPlugin.configure({\n options: autoformatOptions,\n }),\n BlockSelectionPlugin.configure({\n options: {\n areaOptions: {\n behaviour: {\n scrolling: {\n speedDivider: 1.5,\n },\n startThreshold: 10,\n },\n boundaries: `#${scrollSelector}`,\n container: `#${scrollSelector}`,\n selectables: [`#${scrollSelector} .slate-selectable`],\n selectionAreaClass: 'slate-selection-area',\n },\n enableContextMenu: true,\n },\n }),\n BlockMenuPlugin.configure({\n render: { aboveEditable: BlockContextMenu },\n }),\n DndPlugin.configure({\n options: {\n enableScroller: true,\n onDropFiles: ({ dragItem, editor, target }) => {\n editor\n .getTransforms(ImagePlugin)\n .insertImageFromFiles(dragItem.files, {\n at: target,\n nextBlock: false,\n });\n },\n },\n }),\n EmojiPlugin,\n exitBreakPlugin,\n NodeIdPlugin,\n NormalizeTypesPlugin.configure({\n options: {\n rules: [{ path: [0], strictType: HEADING_KEYS.h1 }],\n },\n }),\n resetBlockTypePlugin,\n SelectOnBackspacePlugin.configure({\n options: {\n query: {\n allow: [ImagePlugin.key, HorizontalRulePlugin.key],\n },\n },\n }),\n DeletePlugin,\n SingleLinePlugin,\n softBreakPlugin,\n tabbablePlugin,\n TrailingBlockPlugin.configure({\n options: { type: ParagraphPlugin.key },\n }),\n DragOverCursorPlugin,\n\n // Collaboration\n CommentsPlugin.configure({\n options: {\n comments: commentsData,\n myUserId: '1',\n users: usersData,\n },\n }),\n\n // Deserialization\n DocxPlugin,\n MarkdownPlugin.configure({ options: { indentList: true } }),\n JuicePlugin,\n\n // Testing\n PlaywrightPlugin.configure({\n enabled: process.env.NODE_ENV !== 'production',\n }),\n ],\n value: value,\n },\n []\n );\n};\n\nexport default function PlaygroundDemo({\n id,\n className,\n scrollSelector,\n}: {\n id?: ValueId;\n className?: string;\n scrollSelector?: string;\n}) {\n const containerRef = useRef(null);\n const enabled = settingsStore.use.checkedComponents();\n\n const editor = usePlaygroundEditor(\n id,\n scrollSelector ?? `blockSelection-${id}`\n );\n\n return (\n \n \n \n \n \n \n \n \n \n\n
\n \n \n\n \n \n \n \n \n \n \n\n \n \n \n \n\n \n \n \n
\n
\n
\n );\n}\n\nconst DemoIdContext = React.createContext(undefined);\n\nexport function DemoId({\n id,\n children,\n}: {\n children: React.ReactNode;\n id?: string;\n}) {\n return {children};\n}\n\nexport function useDemoId() {\n return React.useContext(DemoIdContext);\n}\n", + "content": "'use client';\n\nimport React, { useRef } from 'react';\n\nimport type { ValueId } from '@/config/customizer-plugins';\n\nimport { cn } from '@udecode/cn';\nimport { AIChatPlugin, CopilotPlugin } from '@udecode/plate-ai/react';\nimport { AlignPlugin } from '@udecode/plate-alignment/react';\nimport { AutoformatPlugin } from '@udecode/plate-autoformat/react';\nimport {\n BoldPlugin,\n CodePlugin,\n ItalicPlugin,\n StrikethroughPlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n UnderlinePlugin,\n} from '@udecode/plate-basic-marks/react';\nimport { BlockquotePlugin } from '@udecode/plate-block-quote/react';\nimport { SingleLinePlugin } from '@udecode/plate-break/react';\nimport { CaptionPlugin } from '@udecode/plate-caption/react';\nimport { CodeBlockPlugin } from '@udecode/plate-code-block/react';\nimport { CommentsPlugin } from '@udecode/plate-comments/react';\nimport {\n ParagraphPlugin,\n Plate,\n usePlateEditor,\n} from '@udecode/plate-common/react';\nimport { DatePlugin } from '@udecode/plate-date/react';\nimport { DndPlugin } from '@udecode/plate-dnd';\nimport { DocxPlugin } from '@udecode/plate-docx';\nimport { EmojiPlugin } from '@udecode/plate-emoji/react';\nimport { ExcalidrawPlugin } from '@udecode/plate-excalidraw/react';\nimport {\n FontBackgroundColorPlugin,\n FontColorPlugin,\n FontSizePlugin,\n} from '@udecode/plate-font/react';\nimport { HEADING_KEYS } from '@udecode/plate-heading';\nimport { HeadingPlugin, TocPlugin } from '@udecode/plate-heading/react';\nimport { HighlightPlugin } from '@udecode/plate-highlight/react';\nimport { HorizontalRulePlugin } from '@udecode/plate-horizontal-rule/react';\nimport { IndentPlugin } from '@udecode/plate-indent/react';\nimport { IndentListPlugin } from '@udecode/plate-indent-list/react';\nimport { JuicePlugin } from '@udecode/plate-juice';\nimport { KbdPlugin } from '@udecode/plate-kbd/react';\nimport { ColumnPlugin } from '@udecode/plate-layout/react';\nimport { LineHeightPlugin } from '@udecode/plate-line-height/react';\nimport { LinkPlugin } from '@udecode/plate-link/react';\nimport { ListPlugin, TodoListPlugin } from '@udecode/plate-list/react';\nimport { MarkdownPlugin } from '@udecode/plate-markdown';\nimport { BaseImagePlugin } from '@udecode/plate-media';\nimport { ImagePlugin, MediaEmbedPlugin } from '@udecode/plate-media/react';\nimport { MentionPlugin } from '@udecode/plate-mention/react';\nimport { NodeIdPlugin } from '@udecode/plate-node-id';\nimport { NormalizeTypesPlugin } from '@udecode/plate-normalizers';\nimport { PlaywrightPlugin } from '@udecode/plate-playwright';\nimport { DeletePlugin, SelectOnBackspacePlugin } from '@udecode/plate-select';\nimport {\n BlockMenuPlugin,\n BlockSelectionPlugin,\n} from '@udecode/plate-selection/react';\nimport { SlashPlugin } from '@udecode/plate-slash-command/react';\nimport { TablePlugin } from '@udecode/plate-table/react';\nimport { TogglePlugin } from '@udecode/plate-toggle/react';\nimport { TrailingBlockPlugin } from '@udecode/plate-trailing-block';\nimport Prism from 'prismjs';\n\nimport { CheckPlugin } from '@/components/context/check-plugin';\nimport { settingsStore } from '@/components/context/settings-store';\nimport { aiPlugins } from '@/lib/plate/demo/plugins/ai-plugins';\nimport { getAutoformatOptions } from '@/lib/plate/demo/plugins/autoformatOptions';\nimport { copilotPlugins } from '@/lib/plate/demo/plugins/copilot-plugins';\nimport { createPlateUI } from '@/plate/create-plate-ui';\nimport { editableProps } from '@/plate/demo/editableProps';\nimport { isEnabled } from '@/plate/demo/is-enabled';\nimport { DragOverCursorPlugin } from '@/plate/demo/plugins/DragOverCursorPlugin';\nimport { exitBreakPlugin } from '@/plate/demo/plugins/exitBreakPlugin';\nimport { resetBlockTypePlugin } from '@/plate/demo/plugins/resetBlockTypePlugin';\nimport { softBreakPlugin } from '@/plate/demo/plugins/softBreakPlugin';\nimport { tabbablePlugin } from '@/plate/demo/plugins/tabbablePlugin';\nimport { commentsData, usersData } from '@/plate/demo/values/commentsValue';\nimport { usePlaygroundValue } from '@/plate/demo/values/usePlaygroundValue';\nimport { BlockContextMenu } from '@/components/plate-ui/block-context-menu';\nimport { CommentsPopover } from '@/components/plate-ui/comments-popover';\nimport {\n CursorOverlay,\n SelectionOverlayPlugin,\n} from '@/components/plate-ui/cursor-overlay';\nimport { Editor, EditorContainer } from '@/components/plate-ui/editor';\nimport { FixedToolbar } from '@/components/plate-ui/fixed-toolbar';\nimport { FixedToolbarButtons } from '@/components/plate-ui/fixed-toolbar-buttons';\nimport { FloatingToolbar } from '@/components/plate-ui/floating-toolbar';\nimport { FloatingToolbarButtons } from '@/components/plate-ui/floating-toolbar-buttons';\nimport { ImagePreview } from '@/components/plate-ui/image-preview';\nimport {\n FireLiComponent,\n FireMarker,\n} from '@/components/plate-ui/indent-fire-marker';\nimport {\n TodoLi,\n TodoMarker,\n} from '@/components/plate-ui/indent-todo-marker';\nimport { LinkFloatingToolbar } from '@/components/plate-ui/link-floating-toolbar';\n\nimport { usePlaygroundEnabled } from './usePlaygroundEnabled';\n\nexport const usePlaygroundEditor = (id: any = '', scrollSelector?: string) => {\n const enabledPlugins = settingsStore.use.checkedPlugins();\n const overridePlugins = usePlaygroundEnabled(id);\n const autoformatOptions = getAutoformatOptions(id, enabledPlugins);\n\n const value = usePlaygroundValue(id);\n const key = settingsStore.use.version();\n const editorId = id || 'playground-' + key;\n\n return usePlateEditor(\n {\n id: editorId,\n override: {\n components: createPlateUI({\n draggable: isEnabled('dnd', id),\n placeholder: isEnabled('placeholder', id),\n }),\n plugins: overridePlugins,\n },\n plugins: [\n // AI\n ...(id === 'ai' || enabledPlugins[AIChatPlugin.key] ? aiPlugins : []),\n ...(id === 'copilot' || enabledPlugins[CopilotPlugin.key]\n ? copilotPlugins\n : []),\n // Nodes\n HeadingPlugin,\n TocPlugin.configure({\n options: {\n scrollContainerSelector: `#${scrollSelector}`,\n topOffset: 80,\n },\n }),\n BlockquotePlugin,\n CodeBlockPlugin.configure({\n options: {\n prism: Prism,\n },\n }),\n HorizontalRulePlugin,\n LinkPlugin.extend({\n render: { afterEditable: () => },\n }),\n ...(id === 'list' ? [ListPlugin] : []),\n ImagePlugin.extend({\n options: {\n disableUploadInsert: true,\n },\n render: { afterEditable: ImagePreview },\n }),\n MediaEmbedPlugin,\n CaptionPlugin.configure({\n options: {\n plugins: [ImagePlugin, MediaEmbedPlugin],\n },\n }),\n DatePlugin,\n MentionPlugin.configure({\n options: {\n triggerPreviousCharPattern: /^$|^[\\s\"']$/,\n },\n }),\n SlashPlugin,\n TablePlugin.configure({\n options: {\n enableMerging: id === 'tableMerge',\n },\n }),\n ColumnPlugin,\n SelectionOverlayPlugin,\n\n TodoListPlugin,\n TogglePlugin,\n ExcalidrawPlugin,\n // Marks\n BoldPlugin,\n ItalicPlugin,\n UnderlinePlugin,\n StrikethroughPlugin,\n CodePlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n FontColorPlugin,\n FontBackgroundColorPlugin,\n FontSizePlugin,\n HighlightPlugin,\n KbdPlugin,\n\n // Block Style\n AlignPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n MediaEmbedPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n ImagePlugin.key,\n HEADING_KEYS.h6,\n ],\n },\n }),\n IndentPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n }),\n IndentListPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n options: {\n listStyleTypes: {\n fire: {\n liComponent: FireLiComponent,\n markerComponent: FireMarker,\n type: 'fire',\n },\n todo: {\n liComponent: TodoLi,\n markerComponent: TodoMarker,\n type: 'todo',\n },\n },\n },\n }),\n LineHeightPlugin.extend({\n inject: {\n nodeProps: {\n defaultNodeValue: 1.5,\n validNodeValues: [1, 1.2, 1.5, 2, 3],\n },\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n ],\n },\n }),\n\n // Functionality\n AutoformatPlugin.configure({\n options: autoformatOptions,\n }),\n BlockSelectionPlugin.configure({\n options: {\n areaOptions: {\n behaviour: {\n scrolling: {\n speedDivider: 1.5,\n },\n startThreshold: 10,\n },\n boundaries: `#${scrollSelector}`,\n container: `#${scrollSelector}`,\n selectables: [`#${scrollSelector} .slate-selectable`],\n selectionAreaClass: 'slate-selection-area',\n },\n enableContextMenu: true,\n },\n }),\n BlockMenuPlugin.configure({\n render: { aboveEditable: BlockContextMenu },\n }),\n DndPlugin.configure({\n options: {\n enableScroller: true,\n onDropFiles: ({ dragItem, editor, target }) => {\n editor\n .getTransforms(BaseImagePlugin)\n .insert.imageFromFiles(dragItem.files, {\n at: target,\n nextBlock: false,\n });\n },\n },\n }),\n EmojiPlugin,\n exitBreakPlugin,\n NodeIdPlugin,\n NormalizeTypesPlugin.configure({\n options: {\n rules: [{ path: [0], strictType: HEADING_KEYS.h1 }],\n },\n }),\n resetBlockTypePlugin,\n SelectOnBackspacePlugin.configure({\n options: {\n query: {\n allow: [ImagePlugin.key, HorizontalRulePlugin.key],\n },\n },\n }),\n DeletePlugin,\n SingleLinePlugin,\n softBreakPlugin,\n tabbablePlugin,\n TrailingBlockPlugin.configure({\n options: { type: ParagraphPlugin.key },\n }),\n DragOverCursorPlugin,\n\n // Collaboration\n CommentsPlugin.configure({\n options: {\n comments: commentsData,\n myUserId: '1',\n users: usersData,\n },\n }),\n\n // Deserialization\n DocxPlugin,\n MarkdownPlugin.configure({ options: { indentList: true } }),\n JuicePlugin,\n\n // Testing\n PlaywrightPlugin.configure({\n enabled: process.env.NODE_ENV !== 'production',\n }),\n ],\n value: value,\n },\n []\n );\n};\n\nexport default function PlaygroundDemo({\n id,\n className,\n scrollSelector,\n}: {\n id?: ValueId;\n className?: string;\n scrollSelector?: string;\n}) {\n const containerRef = useRef(null);\n const enabled = settingsStore.use.checkedComponents();\n\n const editor = usePlaygroundEditor(\n id,\n scrollSelector ?? `blockSelection-${id}`\n );\n\n return (\n \n \n \n \n \n \n \n \n \n\n
\n \n \n\n \n \n \n \n \n \n \n\n \n \n \n \n\n \n \n \n
\n
\n
\n );\n}\n\nconst DemoIdContext = React.createContext(undefined);\n\nexport function DemoId({\n id,\n children,\n}: {\n children: React.ReactNode;\n id?: string;\n}) {\n return {children};\n}\n\nexport function useDemoId() {\n return React.useContext(DemoIdContext);\n}\n", "path": "example/playground-demo.tsx", "target": "components/playground-demo.tsx", "type": "registry:example" diff --git a/apps/www/public/r/styles/default/align-demo.json b/apps/www/public/r/styles/default/align-demo.json index fbbb2cf467..246bad5cc3 100644 --- a/apps/www/public/r/styles/default/align-demo.json +++ b/apps/www/public/r/styles/default/align-demo.json @@ -4,7 +4,7 @@ }, "files": [ { - "content": "'use client';\n\nimport React, { useRef } from 'react';\n\nimport type { ValueId } from '@/config/customizer-plugins';\n\nimport { cn } from '@udecode/cn';\nimport { AIChatPlugin, CopilotPlugin } from '@udecode/plate-ai/react';\nimport { AlignPlugin } from '@udecode/plate-alignment/react';\nimport { AutoformatPlugin } from '@udecode/plate-autoformat/react';\nimport {\n BoldPlugin,\n CodePlugin,\n ItalicPlugin,\n StrikethroughPlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n UnderlinePlugin,\n} from '@udecode/plate-basic-marks/react';\nimport { BlockquotePlugin } from '@udecode/plate-block-quote/react';\nimport { SingleLinePlugin } from '@udecode/plate-break/react';\nimport { CaptionPlugin } from '@udecode/plate-caption/react';\nimport { CodeBlockPlugin } from '@udecode/plate-code-block/react';\nimport { CommentsPlugin } from '@udecode/plate-comments/react';\nimport {\n ParagraphPlugin,\n Plate,\n usePlateEditor,\n} from '@udecode/plate-common/react';\nimport { DatePlugin } from '@udecode/plate-date/react';\nimport { DndPlugin } from '@udecode/plate-dnd';\nimport { DocxPlugin } from '@udecode/plate-docx';\nimport { EmojiPlugin } from '@udecode/plate-emoji/react';\nimport { ExcalidrawPlugin } from '@udecode/plate-excalidraw/react';\nimport {\n FontBackgroundColorPlugin,\n FontColorPlugin,\n FontSizePlugin,\n} from '@udecode/plate-font/react';\nimport { HEADING_KEYS } from '@udecode/plate-heading';\nimport { HeadingPlugin, TocPlugin } from '@udecode/plate-heading/react';\nimport { HighlightPlugin } from '@udecode/plate-highlight/react';\nimport { HorizontalRulePlugin } from '@udecode/plate-horizontal-rule/react';\nimport { IndentPlugin } from '@udecode/plate-indent/react';\nimport { IndentListPlugin } from '@udecode/plate-indent-list/react';\nimport { JuicePlugin } from '@udecode/plate-juice';\nimport { KbdPlugin } from '@udecode/plate-kbd/react';\nimport { ColumnPlugin } from '@udecode/plate-layout/react';\nimport { LineHeightPlugin } from '@udecode/plate-line-height/react';\nimport { LinkPlugin } from '@udecode/plate-link/react';\nimport { ListPlugin, TodoListPlugin } from '@udecode/plate-list/react';\nimport { MarkdownPlugin } from '@udecode/plate-markdown';\nimport { ImagePlugin, MediaEmbedPlugin } from '@udecode/plate-media/react';\nimport { MentionPlugin } from '@udecode/plate-mention/react';\nimport { NodeIdPlugin } from '@udecode/plate-node-id';\nimport { NormalizeTypesPlugin } from '@udecode/plate-normalizers';\nimport { PlaywrightPlugin } from '@udecode/plate-playwright';\nimport { DeletePlugin, SelectOnBackspacePlugin } from '@udecode/plate-select';\nimport {\n BlockMenuPlugin,\n BlockSelectionPlugin,\n} from '@udecode/plate-selection/react';\nimport { SlashPlugin } from '@udecode/plate-slash-command/react';\nimport { TablePlugin } from '@udecode/plate-table/react';\nimport { TogglePlugin } from '@udecode/plate-toggle/react';\nimport { TrailingBlockPlugin } from '@udecode/plate-trailing-block';\nimport Prism from 'prismjs';\n\nimport { CheckPlugin } from '@/components/context/check-plugin';\nimport { settingsStore } from '@/components/context/settings-store';\nimport { aiPlugins } from '@/lib/plate/demo/plugins/ai-plugins';\nimport { getAutoformatOptions } from '@/lib/plate/demo/plugins/autoformatOptions';\nimport { copilotPlugins } from '@/lib/plate/demo/plugins/copilot-plugins';\nimport { createPlateUI } from '@/plate/create-plate-ui';\nimport { editableProps } from '@/plate/demo/editableProps';\nimport { isEnabled } from '@/plate/demo/is-enabled';\nimport { DragOverCursorPlugin } from '@/plate/demo/plugins/DragOverCursorPlugin';\nimport { exitBreakPlugin } from '@/plate/demo/plugins/exitBreakPlugin';\nimport { resetBlockTypePlugin } from '@/plate/demo/plugins/resetBlockTypePlugin';\nimport { softBreakPlugin } from '@/plate/demo/plugins/softBreakPlugin';\nimport { tabbablePlugin } from '@/plate/demo/plugins/tabbablePlugin';\nimport { commentsData, usersData } from '@/plate/demo/values/commentsValue';\nimport { usePlaygroundValue } from '@/plate/demo/values/usePlaygroundValue';\nimport { BlockContextMenu } from '@/components/plate-ui/block-context-menu';\nimport { CommentsPopover } from '@/components/plate-ui/comments-popover';\nimport {\n CursorOverlay,\n SelectionOverlayPlugin,\n} from '@/components/plate-ui/cursor-overlay';\nimport { Editor, EditorContainer } from '@/components/plate-ui/editor';\nimport { FixedToolbar } from '@/components/plate-ui/fixed-toolbar';\nimport { FixedToolbarButtons } from '@/components/plate-ui/fixed-toolbar-buttons';\nimport { FloatingToolbar } from '@/components/plate-ui/floating-toolbar';\nimport { FloatingToolbarButtons } from '@/components/plate-ui/floating-toolbar-buttons';\nimport { ImagePreview } from '@/components/plate-ui/image-preview';\nimport {\n FireLiComponent,\n FireMarker,\n} from '@/components/plate-ui/indent-fire-marker';\nimport {\n TodoLi,\n TodoMarker,\n} from '@/components/plate-ui/indent-todo-marker';\nimport { LinkFloatingToolbar } from '@/components/plate-ui/link-floating-toolbar';\n\nimport { usePlaygroundEnabled } from './usePlaygroundEnabled';\n\nexport const usePlaygroundEditor = (id: any = '', scrollSelector?: string) => {\n const enabledPlugins = settingsStore.use.checkedPlugins();\n const overridePlugins = usePlaygroundEnabled(id);\n const autoformatOptions = getAutoformatOptions(id, enabledPlugins);\n\n const value = usePlaygroundValue(id);\n const key = settingsStore.use.version();\n const editorId = id || 'playground-' + key;\n\n return usePlateEditor(\n {\n id: editorId,\n override: {\n components: createPlateUI({\n draggable: isEnabled('dnd', id),\n placeholder: isEnabled('placeholder', id),\n }),\n plugins: overridePlugins,\n },\n plugins: [\n // AI\n ...(id === 'ai' || enabledPlugins[AIChatPlugin.key] ? aiPlugins : []),\n ...(id === 'copilot' || enabledPlugins[CopilotPlugin.key]\n ? copilotPlugins\n : []),\n // Nodes\n HeadingPlugin,\n TocPlugin.configure({\n options: {\n scrollContainerSelector: `#${scrollSelector}`,\n topOffset: 80,\n },\n }),\n BlockquotePlugin,\n CodeBlockPlugin.configure({\n options: {\n prism: Prism,\n },\n }),\n HorizontalRulePlugin,\n LinkPlugin.extend({\n render: { afterEditable: () => },\n }),\n ...(id === 'list' ? [ListPlugin] : []),\n ImagePlugin.extend({\n options: {\n disableUploadInsert: true,\n },\n render: { afterEditable: ImagePreview },\n }),\n MediaEmbedPlugin,\n CaptionPlugin.configure({\n options: {\n plugins: [ImagePlugin, MediaEmbedPlugin],\n },\n }),\n DatePlugin,\n MentionPlugin.configure({\n options: {\n triggerPreviousCharPattern: /^$|^[\\s\"']$/,\n },\n }),\n SlashPlugin,\n TablePlugin.configure({\n options: {\n enableMerging: id === 'tableMerge',\n },\n }),\n ColumnPlugin,\n SelectionOverlayPlugin,\n\n TodoListPlugin,\n TogglePlugin,\n ExcalidrawPlugin,\n // Marks\n BoldPlugin,\n ItalicPlugin,\n UnderlinePlugin,\n StrikethroughPlugin,\n CodePlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n FontColorPlugin,\n FontBackgroundColorPlugin,\n FontSizePlugin,\n HighlightPlugin,\n KbdPlugin,\n\n // Block Style\n AlignPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n MediaEmbedPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n ImagePlugin.key,\n HEADING_KEYS.h6,\n ],\n },\n }),\n IndentPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n }),\n IndentListPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n options: {\n listStyleTypes: {\n fire: {\n liComponent: FireLiComponent,\n markerComponent: FireMarker,\n type: 'fire',\n },\n todo: {\n liComponent: TodoLi,\n markerComponent: TodoMarker,\n type: 'todo',\n },\n },\n },\n }),\n LineHeightPlugin.extend({\n inject: {\n nodeProps: {\n defaultNodeValue: 1.5,\n validNodeValues: [1, 1.2, 1.5, 2, 3],\n },\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n ],\n },\n }),\n\n // Functionality\n AutoformatPlugin.configure({\n options: autoformatOptions,\n }),\n BlockSelectionPlugin.configure({\n options: {\n areaOptions: {\n behaviour: {\n scrolling: {\n speedDivider: 1.5,\n },\n startThreshold: 10,\n },\n boundaries: `#${scrollSelector}`,\n container: `#${scrollSelector}`,\n selectables: [`#${scrollSelector} .slate-selectable`],\n selectionAreaClass: 'slate-selection-area',\n },\n enableContextMenu: true,\n },\n }),\n BlockMenuPlugin.configure({\n render: { aboveEditable: BlockContextMenu },\n }),\n DndPlugin.configure({\n options: {\n enableScroller: true,\n onDropFiles: ({ dragItem, editor, target }) => {\n editor\n .getTransforms(ImagePlugin)\n .insertImageFromFiles(dragItem.files, {\n at: target,\n nextBlock: false,\n });\n },\n },\n }),\n EmojiPlugin,\n exitBreakPlugin,\n NodeIdPlugin,\n NormalizeTypesPlugin.configure({\n options: {\n rules: [{ path: [0], strictType: HEADING_KEYS.h1 }],\n },\n }),\n resetBlockTypePlugin,\n SelectOnBackspacePlugin.configure({\n options: {\n query: {\n allow: [ImagePlugin.key, HorizontalRulePlugin.key],\n },\n },\n }),\n DeletePlugin,\n SingleLinePlugin,\n softBreakPlugin,\n tabbablePlugin,\n TrailingBlockPlugin.configure({\n options: { type: ParagraphPlugin.key },\n }),\n DragOverCursorPlugin,\n\n // Collaboration\n CommentsPlugin.configure({\n options: {\n comments: commentsData,\n myUserId: '1',\n users: usersData,\n },\n }),\n\n // Deserialization\n DocxPlugin,\n MarkdownPlugin.configure({ options: { indentList: true } }),\n JuicePlugin,\n\n // Testing\n PlaywrightPlugin.configure({\n enabled: process.env.NODE_ENV !== 'production',\n }),\n ],\n value: value,\n },\n []\n );\n};\n\nexport default function PlaygroundDemo({\n id,\n className,\n scrollSelector,\n}: {\n id?: ValueId;\n className?: string;\n scrollSelector?: string;\n}) {\n const containerRef = useRef(null);\n const enabled = settingsStore.use.checkedComponents();\n\n const editor = usePlaygroundEditor(\n id,\n scrollSelector ?? `blockSelection-${id}`\n );\n\n return (\n \n \n \n \n \n \n \n \n \n\n
\n \n \n\n \n \n \n \n \n \n \n\n \n \n \n \n\n \n \n \n
\n
\n
\n );\n}\n\nconst DemoIdContext = React.createContext(undefined);\n\nexport function DemoId({\n id,\n children,\n}: {\n children: React.ReactNode;\n id?: string;\n}) {\n return {children};\n}\n\nexport function useDemoId() {\n return React.useContext(DemoIdContext);\n}\n", + "content": "'use client';\n\nimport React, { useRef } from 'react';\n\nimport type { ValueId } from '@/config/customizer-plugins';\n\nimport { cn } from '@udecode/cn';\nimport { AIChatPlugin, CopilotPlugin } from '@udecode/plate-ai/react';\nimport { AlignPlugin } from '@udecode/plate-alignment/react';\nimport { AutoformatPlugin } from '@udecode/plate-autoformat/react';\nimport {\n BoldPlugin,\n CodePlugin,\n ItalicPlugin,\n StrikethroughPlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n UnderlinePlugin,\n} from '@udecode/plate-basic-marks/react';\nimport { BlockquotePlugin } from '@udecode/plate-block-quote/react';\nimport { SingleLinePlugin } from '@udecode/plate-break/react';\nimport { CaptionPlugin } from '@udecode/plate-caption/react';\nimport { CodeBlockPlugin } from '@udecode/plate-code-block/react';\nimport { CommentsPlugin } from '@udecode/plate-comments/react';\nimport {\n ParagraphPlugin,\n Plate,\n usePlateEditor,\n} from '@udecode/plate-common/react';\nimport { DatePlugin } from '@udecode/plate-date/react';\nimport { DndPlugin } from '@udecode/plate-dnd';\nimport { DocxPlugin } from '@udecode/plate-docx';\nimport { EmojiPlugin } from '@udecode/plate-emoji/react';\nimport { ExcalidrawPlugin } from '@udecode/plate-excalidraw/react';\nimport {\n FontBackgroundColorPlugin,\n FontColorPlugin,\n FontSizePlugin,\n} from '@udecode/plate-font/react';\nimport { HEADING_KEYS } from '@udecode/plate-heading';\nimport { HeadingPlugin, TocPlugin } from '@udecode/plate-heading/react';\nimport { HighlightPlugin } from '@udecode/plate-highlight/react';\nimport { HorizontalRulePlugin } from '@udecode/plate-horizontal-rule/react';\nimport { IndentPlugin } from '@udecode/plate-indent/react';\nimport { IndentListPlugin } from '@udecode/plate-indent-list/react';\nimport { JuicePlugin } from '@udecode/plate-juice';\nimport { KbdPlugin } from '@udecode/plate-kbd/react';\nimport { ColumnPlugin } from '@udecode/plate-layout/react';\nimport { LineHeightPlugin } from '@udecode/plate-line-height/react';\nimport { LinkPlugin } from '@udecode/plate-link/react';\nimport { ListPlugin, TodoListPlugin } from '@udecode/plate-list/react';\nimport { MarkdownPlugin } from '@udecode/plate-markdown';\nimport { BaseImagePlugin } from '@udecode/plate-media';\nimport { ImagePlugin, MediaEmbedPlugin } from '@udecode/plate-media/react';\nimport { MentionPlugin } from '@udecode/plate-mention/react';\nimport { NodeIdPlugin } from '@udecode/plate-node-id';\nimport { NormalizeTypesPlugin } from '@udecode/plate-normalizers';\nimport { PlaywrightPlugin } from '@udecode/plate-playwright';\nimport { DeletePlugin, SelectOnBackspacePlugin } from '@udecode/plate-select';\nimport {\n BlockMenuPlugin,\n BlockSelectionPlugin,\n} from '@udecode/plate-selection/react';\nimport { SlashPlugin } from '@udecode/plate-slash-command/react';\nimport { TablePlugin } from '@udecode/plate-table/react';\nimport { TogglePlugin } from '@udecode/plate-toggle/react';\nimport { TrailingBlockPlugin } from '@udecode/plate-trailing-block';\nimport Prism from 'prismjs';\n\nimport { CheckPlugin } from '@/components/context/check-plugin';\nimport { settingsStore } from '@/components/context/settings-store';\nimport { aiPlugins } from '@/lib/plate/demo/plugins/ai-plugins';\nimport { getAutoformatOptions } from '@/lib/plate/demo/plugins/autoformatOptions';\nimport { copilotPlugins } from '@/lib/plate/demo/plugins/copilot-plugins';\nimport { createPlateUI } from '@/plate/create-plate-ui';\nimport { editableProps } from '@/plate/demo/editableProps';\nimport { isEnabled } from '@/plate/demo/is-enabled';\nimport { DragOverCursorPlugin } from '@/plate/demo/plugins/DragOverCursorPlugin';\nimport { exitBreakPlugin } from '@/plate/demo/plugins/exitBreakPlugin';\nimport { resetBlockTypePlugin } from '@/plate/demo/plugins/resetBlockTypePlugin';\nimport { softBreakPlugin } from '@/plate/demo/plugins/softBreakPlugin';\nimport { tabbablePlugin } from '@/plate/demo/plugins/tabbablePlugin';\nimport { commentsData, usersData } from '@/plate/demo/values/commentsValue';\nimport { usePlaygroundValue } from '@/plate/demo/values/usePlaygroundValue';\nimport { BlockContextMenu } from '@/components/plate-ui/block-context-menu';\nimport { CommentsPopover } from '@/components/plate-ui/comments-popover';\nimport {\n CursorOverlay,\n SelectionOverlayPlugin,\n} from '@/components/plate-ui/cursor-overlay';\nimport { Editor, EditorContainer } from '@/components/plate-ui/editor';\nimport { FixedToolbar } from '@/components/plate-ui/fixed-toolbar';\nimport { FixedToolbarButtons } from '@/components/plate-ui/fixed-toolbar-buttons';\nimport { FloatingToolbar } from '@/components/plate-ui/floating-toolbar';\nimport { FloatingToolbarButtons } from '@/components/plate-ui/floating-toolbar-buttons';\nimport { ImagePreview } from '@/components/plate-ui/image-preview';\nimport {\n FireLiComponent,\n FireMarker,\n} from '@/components/plate-ui/indent-fire-marker';\nimport {\n TodoLi,\n TodoMarker,\n} from '@/components/plate-ui/indent-todo-marker';\nimport { LinkFloatingToolbar } from '@/components/plate-ui/link-floating-toolbar';\n\nimport { usePlaygroundEnabled } from './usePlaygroundEnabled';\n\nexport const usePlaygroundEditor = (id: any = '', scrollSelector?: string) => {\n const enabledPlugins = settingsStore.use.checkedPlugins();\n const overridePlugins = usePlaygroundEnabled(id);\n const autoformatOptions = getAutoformatOptions(id, enabledPlugins);\n\n const value = usePlaygroundValue(id);\n const key = settingsStore.use.version();\n const editorId = id || 'playground-' + key;\n\n return usePlateEditor(\n {\n id: editorId,\n override: {\n components: createPlateUI({\n draggable: isEnabled('dnd', id),\n placeholder: isEnabled('placeholder', id),\n }),\n plugins: overridePlugins,\n },\n plugins: [\n // AI\n ...(id === 'ai' || enabledPlugins[AIChatPlugin.key] ? aiPlugins : []),\n ...(id === 'copilot' || enabledPlugins[CopilotPlugin.key]\n ? copilotPlugins\n : []),\n // Nodes\n HeadingPlugin,\n TocPlugin.configure({\n options: {\n scrollContainerSelector: `#${scrollSelector}`,\n topOffset: 80,\n },\n }),\n BlockquotePlugin,\n CodeBlockPlugin.configure({\n options: {\n prism: Prism,\n },\n }),\n HorizontalRulePlugin,\n LinkPlugin.extend({\n render: { afterEditable: () => },\n }),\n ...(id === 'list' ? [ListPlugin] : []),\n ImagePlugin.extend({\n options: {\n disableUploadInsert: true,\n },\n render: { afterEditable: ImagePreview },\n }),\n MediaEmbedPlugin,\n CaptionPlugin.configure({\n options: {\n plugins: [ImagePlugin, MediaEmbedPlugin],\n },\n }),\n DatePlugin,\n MentionPlugin.configure({\n options: {\n triggerPreviousCharPattern: /^$|^[\\s\"']$/,\n },\n }),\n SlashPlugin,\n TablePlugin.configure({\n options: {\n enableMerging: id === 'tableMerge',\n },\n }),\n ColumnPlugin,\n SelectionOverlayPlugin,\n\n TodoListPlugin,\n TogglePlugin,\n ExcalidrawPlugin,\n // Marks\n BoldPlugin,\n ItalicPlugin,\n UnderlinePlugin,\n StrikethroughPlugin,\n CodePlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n FontColorPlugin,\n FontBackgroundColorPlugin,\n FontSizePlugin,\n HighlightPlugin,\n KbdPlugin,\n\n // Block Style\n AlignPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n MediaEmbedPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n ImagePlugin.key,\n HEADING_KEYS.h6,\n ],\n },\n }),\n IndentPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n }),\n IndentListPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n options: {\n listStyleTypes: {\n fire: {\n liComponent: FireLiComponent,\n markerComponent: FireMarker,\n type: 'fire',\n },\n todo: {\n liComponent: TodoLi,\n markerComponent: TodoMarker,\n type: 'todo',\n },\n },\n },\n }),\n LineHeightPlugin.extend({\n inject: {\n nodeProps: {\n defaultNodeValue: 1.5,\n validNodeValues: [1, 1.2, 1.5, 2, 3],\n },\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n ],\n },\n }),\n\n // Functionality\n AutoformatPlugin.configure({\n options: autoformatOptions,\n }),\n BlockSelectionPlugin.configure({\n options: {\n areaOptions: {\n behaviour: {\n scrolling: {\n speedDivider: 1.5,\n },\n startThreshold: 10,\n },\n boundaries: `#${scrollSelector}`,\n container: `#${scrollSelector}`,\n selectables: [`#${scrollSelector} .slate-selectable`],\n selectionAreaClass: 'slate-selection-area',\n },\n enableContextMenu: true,\n },\n }),\n BlockMenuPlugin.configure({\n render: { aboveEditable: BlockContextMenu },\n }),\n DndPlugin.configure({\n options: {\n enableScroller: true,\n onDropFiles: ({ dragItem, editor, target }) => {\n editor\n .getTransforms(BaseImagePlugin)\n .insert.imageFromFiles(dragItem.files, {\n at: target,\n nextBlock: false,\n });\n },\n },\n }),\n EmojiPlugin,\n exitBreakPlugin,\n NodeIdPlugin,\n NormalizeTypesPlugin.configure({\n options: {\n rules: [{ path: [0], strictType: HEADING_KEYS.h1 }],\n },\n }),\n resetBlockTypePlugin,\n SelectOnBackspacePlugin.configure({\n options: {\n query: {\n allow: [ImagePlugin.key, HorizontalRulePlugin.key],\n },\n },\n }),\n DeletePlugin,\n SingleLinePlugin,\n softBreakPlugin,\n tabbablePlugin,\n TrailingBlockPlugin.configure({\n options: { type: ParagraphPlugin.key },\n }),\n DragOverCursorPlugin,\n\n // Collaboration\n CommentsPlugin.configure({\n options: {\n comments: commentsData,\n myUserId: '1',\n users: usersData,\n },\n }),\n\n // Deserialization\n DocxPlugin,\n MarkdownPlugin.configure({ options: { indentList: true } }),\n JuicePlugin,\n\n // Testing\n PlaywrightPlugin.configure({\n enabled: process.env.NODE_ENV !== 'production',\n }),\n ],\n value: value,\n },\n []\n );\n};\n\nexport default function PlaygroundDemo({\n id,\n className,\n scrollSelector,\n}: {\n id?: ValueId;\n className?: string;\n scrollSelector?: string;\n}) {\n const containerRef = useRef(null);\n const enabled = settingsStore.use.checkedComponents();\n\n const editor = usePlaygroundEditor(\n id,\n scrollSelector ?? `blockSelection-${id}`\n );\n\n return (\n \n \n \n \n \n \n \n \n \n\n
\n \n \n\n \n \n \n \n \n \n \n\n \n \n \n \n\n \n \n \n
\n
\n
\n );\n}\n\nconst DemoIdContext = React.createContext(undefined);\n\nexport function DemoId({\n id,\n children,\n}: {\n children: React.ReactNode;\n id?: string;\n}) {\n return {children};\n}\n\nexport function useDemoId() {\n return React.useContext(DemoIdContext);\n}\n", "path": "example/playground-demo.tsx", "target": "components/playground-demo.tsx", "type": "registry:example" diff --git a/apps/www/public/r/styles/default/basic-elements-demo.json b/apps/www/public/r/styles/default/basic-elements-demo.json index 2624ceceac..32762cd457 100644 --- a/apps/www/public/r/styles/default/basic-elements-demo.json +++ b/apps/www/public/r/styles/default/basic-elements-demo.json @@ -4,7 +4,7 @@ }, "files": [ { - "content": "'use client';\n\nimport React, { useRef } from 'react';\n\nimport type { ValueId } from '@/config/customizer-plugins';\n\nimport { cn } from '@udecode/cn';\nimport { AIChatPlugin, CopilotPlugin } from '@udecode/plate-ai/react';\nimport { AlignPlugin } from '@udecode/plate-alignment/react';\nimport { AutoformatPlugin } from '@udecode/plate-autoformat/react';\nimport {\n BoldPlugin,\n CodePlugin,\n ItalicPlugin,\n StrikethroughPlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n UnderlinePlugin,\n} from '@udecode/plate-basic-marks/react';\nimport { BlockquotePlugin } from '@udecode/plate-block-quote/react';\nimport { SingleLinePlugin } from '@udecode/plate-break/react';\nimport { CaptionPlugin } from '@udecode/plate-caption/react';\nimport { CodeBlockPlugin } from '@udecode/plate-code-block/react';\nimport { CommentsPlugin } from '@udecode/plate-comments/react';\nimport {\n ParagraphPlugin,\n Plate,\n usePlateEditor,\n} from '@udecode/plate-common/react';\nimport { DatePlugin } from '@udecode/plate-date/react';\nimport { DndPlugin } from '@udecode/plate-dnd';\nimport { DocxPlugin } from '@udecode/plate-docx';\nimport { EmojiPlugin } from '@udecode/plate-emoji/react';\nimport { ExcalidrawPlugin } from '@udecode/plate-excalidraw/react';\nimport {\n FontBackgroundColorPlugin,\n FontColorPlugin,\n FontSizePlugin,\n} from '@udecode/plate-font/react';\nimport { HEADING_KEYS } from '@udecode/plate-heading';\nimport { HeadingPlugin, TocPlugin } from '@udecode/plate-heading/react';\nimport { HighlightPlugin } from '@udecode/plate-highlight/react';\nimport { HorizontalRulePlugin } from '@udecode/plate-horizontal-rule/react';\nimport { IndentPlugin } from '@udecode/plate-indent/react';\nimport { IndentListPlugin } from '@udecode/plate-indent-list/react';\nimport { JuicePlugin } from '@udecode/plate-juice';\nimport { KbdPlugin } from '@udecode/plate-kbd/react';\nimport { ColumnPlugin } from '@udecode/plate-layout/react';\nimport { LineHeightPlugin } from '@udecode/plate-line-height/react';\nimport { LinkPlugin } from '@udecode/plate-link/react';\nimport { ListPlugin, TodoListPlugin } from '@udecode/plate-list/react';\nimport { MarkdownPlugin } from '@udecode/plate-markdown';\nimport { ImagePlugin, MediaEmbedPlugin } from '@udecode/plate-media/react';\nimport { MentionPlugin } from '@udecode/plate-mention/react';\nimport { NodeIdPlugin } from '@udecode/plate-node-id';\nimport { NormalizeTypesPlugin } from '@udecode/plate-normalizers';\nimport { PlaywrightPlugin } from '@udecode/plate-playwright';\nimport { DeletePlugin, SelectOnBackspacePlugin } from '@udecode/plate-select';\nimport {\n BlockMenuPlugin,\n BlockSelectionPlugin,\n} from '@udecode/plate-selection/react';\nimport { SlashPlugin } from '@udecode/plate-slash-command/react';\nimport { TablePlugin } from '@udecode/plate-table/react';\nimport { TogglePlugin } from '@udecode/plate-toggle/react';\nimport { TrailingBlockPlugin } from '@udecode/plate-trailing-block';\nimport Prism from 'prismjs';\n\nimport { CheckPlugin } from '@/components/context/check-plugin';\nimport { settingsStore } from '@/components/context/settings-store';\nimport { aiPlugins } from '@/lib/plate/demo/plugins/ai-plugins';\nimport { getAutoformatOptions } from '@/lib/plate/demo/plugins/autoformatOptions';\nimport { copilotPlugins } from '@/lib/plate/demo/plugins/copilot-plugins';\nimport { createPlateUI } from '@/plate/create-plate-ui';\nimport { editableProps } from '@/plate/demo/editableProps';\nimport { isEnabled } from '@/plate/demo/is-enabled';\nimport { DragOverCursorPlugin } from '@/plate/demo/plugins/DragOverCursorPlugin';\nimport { exitBreakPlugin } from '@/plate/demo/plugins/exitBreakPlugin';\nimport { resetBlockTypePlugin } from '@/plate/demo/plugins/resetBlockTypePlugin';\nimport { softBreakPlugin } from '@/plate/demo/plugins/softBreakPlugin';\nimport { tabbablePlugin } from '@/plate/demo/plugins/tabbablePlugin';\nimport { commentsData, usersData } from '@/plate/demo/values/commentsValue';\nimport { usePlaygroundValue } from '@/plate/demo/values/usePlaygroundValue';\nimport { BlockContextMenu } from '@/components/plate-ui/block-context-menu';\nimport { CommentsPopover } from '@/components/plate-ui/comments-popover';\nimport {\n CursorOverlay,\n SelectionOverlayPlugin,\n} from '@/components/plate-ui/cursor-overlay';\nimport { Editor, EditorContainer } from '@/components/plate-ui/editor';\nimport { FixedToolbar } from '@/components/plate-ui/fixed-toolbar';\nimport { FixedToolbarButtons } from '@/components/plate-ui/fixed-toolbar-buttons';\nimport { FloatingToolbar } from '@/components/plate-ui/floating-toolbar';\nimport { FloatingToolbarButtons } from '@/components/plate-ui/floating-toolbar-buttons';\nimport { ImagePreview } from '@/components/plate-ui/image-preview';\nimport {\n FireLiComponent,\n FireMarker,\n} from '@/components/plate-ui/indent-fire-marker';\nimport {\n TodoLi,\n TodoMarker,\n} from '@/components/plate-ui/indent-todo-marker';\nimport { LinkFloatingToolbar } from '@/components/plate-ui/link-floating-toolbar';\n\nimport { usePlaygroundEnabled } from './usePlaygroundEnabled';\n\nexport const usePlaygroundEditor = (id: any = '', scrollSelector?: string) => {\n const enabledPlugins = settingsStore.use.checkedPlugins();\n const overridePlugins = usePlaygroundEnabled(id);\n const autoformatOptions = getAutoformatOptions(id, enabledPlugins);\n\n const value = usePlaygroundValue(id);\n const key = settingsStore.use.version();\n const editorId = id || 'playground-' + key;\n\n return usePlateEditor(\n {\n id: editorId,\n override: {\n components: createPlateUI({\n draggable: isEnabled('dnd', id),\n placeholder: isEnabled('placeholder', id),\n }),\n plugins: overridePlugins,\n },\n plugins: [\n // AI\n ...(id === 'ai' || enabledPlugins[AIChatPlugin.key] ? aiPlugins : []),\n ...(id === 'copilot' || enabledPlugins[CopilotPlugin.key]\n ? copilotPlugins\n : []),\n // Nodes\n HeadingPlugin,\n TocPlugin.configure({\n options: {\n scrollContainerSelector: `#${scrollSelector}`,\n topOffset: 80,\n },\n }),\n BlockquotePlugin,\n CodeBlockPlugin.configure({\n options: {\n prism: Prism,\n },\n }),\n HorizontalRulePlugin,\n LinkPlugin.extend({\n render: { afterEditable: () => },\n }),\n ...(id === 'list' ? [ListPlugin] : []),\n ImagePlugin.extend({\n options: {\n disableUploadInsert: true,\n },\n render: { afterEditable: ImagePreview },\n }),\n MediaEmbedPlugin,\n CaptionPlugin.configure({\n options: {\n plugins: [ImagePlugin, MediaEmbedPlugin],\n },\n }),\n DatePlugin,\n MentionPlugin.configure({\n options: {\n triggerPreviousCharPattern: /^$|^[\\s\"']$/,\n },\n }),\n SlashPlugin,\n TablePlugin.configure({\n options: {\n enableMerging: id === 'tableMerge',\n },\n }),\n ColumnPlugin,\n SelectionOverlayPlugin,\n\n TodoListPlugin,\n TogglePlugin,\n ExcalidrawPlugin,\n // Marks\n BoldPlugin,\n ItalicPlugin,\n UnderlinePlugin,\n StrikethroughPlugin,\n CodePlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n FontColorPlugin,\n FontBackgroundColorPlugin,\n FontSizePlugin,\n HighlightPlugin,\n KbdPlugin,\n\n // Block Style\n AlignPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n MediaEmbedPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n ImagePlugin.key,\n HEADING_KEYS.h6,\n ],\n },\n }),\n IndentPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n }),\n IndentListPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n options: {\n listStyleTypes: {\n fire: {\n liComponent: FireLiComponent,\n markerComponent: FireMarker,\n type: 'fire',\n },\n todo: {\n liComponent: TodoLi,\n markerComponent: TodoMarker,\n type: 'todo',\n },\n },\n },\n }),\n LineHeightPlugin.extend({\n inject: {\n nodeProps: {\n defaultNodeValue: 1.5,\n validNodeValues: [1, 1.2, 1.5, 2, 3],\n },\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n ],\n },\n }),\n\n // Functionality\n AutoformatPlugin.configure({\n options: autoformatOptions,\n }),\n BlockSelectionPlugin.configure({\n options: {\n areaOptions: {\n behaviour: {\n scrolling: {\n speedDivider: 1.5,\n },\n startThreshold: 10,\n },\n boundaries: `#${scrollSelector}`,\n container: `#${scrollSelector}`,\n selectables: [`#${scrollSelector} .slate-selectable`],\n selectionAreaClass: 'slate-selection-area',\n },\n enableContextMenu: true,\n },\n }),\n BlockMenuPlugin.configure({\n render: { aboveEditable: BlockContextMenu },\n }),\n DndPlugin.configure({\n options: {\n enableScroller: true,\n onDropFiles: ({ dragItem, editor, target }) => {\n editor\n .getTransforms(ImagePlugin)\n .insertImageFromFiles(dragItem.files, {\n at: target,\n nextBlock: false,\n });\n },\n },\n }),\n EmojiPlugin,\n exitBreakPlugin,\n NodeIdPlugin,\n NormalizeTypesPlugin.configure({\n options: {\n rules: [{ path: [0], strictType: HEADING_KEYS.h1 }],\n },\n }),\n resetBlockTypePlugin,\n SelectOnBackspacePlugin.configure({\n options: {\n query: {\n allow: [ImagePlugin.key, HorizontalRulePlugin.key],\n },\n },\n }),\n DeletePlugin,\n SingleLinePlugin,\n softBreakPlugin,\n tabbablePlugin,\n TrailingBlockPlugin.configure({\n options: { type: ParagraphPlugin.key },\n }),\n DragOverCursorPlugin,\n\n // Collaboration\n CommentsPlugin.configure({\n options: {\n comments: commentsData,\n myUserId: '1',\n users: usersData,\n },\n }),\n\n // Deserialization\n DocxPlugin,\n MarkdownPlugin.configure({ options: { indentList: true } }),\n JuicePlugin,\n\n // Testing\n PlaywrightPlugin.configure({\n enabled: process.env.NODE_ENV !== 'production',\n }),\n ],\n value: value,\n },\n []\n );\n};\n\nexport default function PlaygroundDemo({\n id,\n className,\n scrollSelector,\n}: {\n id?: ValueId;\n className?: string;\n scrollSelector?: string;\n}) {\n const containerRef = useRef(null);\n const enabled = settingsStore.use.checkedComponents();\n\n const editor = usePlaygroundEditor(\n id,\n scrollSelector ?? `blockSelection-${id}`\n );\n\n return (\n \n \n \n \n \n \n \n \n \n\n
\n \n \n\n \n \n \n \n \n \n \n\n \n \n \n \n\n \n \n \n
\n
\n
\n );\n}\n\nconst DemoIdContext = React.createContext(undefined);\n\nexport function DemoId({\n id,\n children,\n}: {\n children: React.ReactNode;\n id?: string;\n}) {\n return {children};\n}\n\nexport function useDemoId() {\n return React.useContext(DemoIdContext);\n}\n", + "content": "'use client';\n\nimport React, { useRef } from 'react';\n\nimport type { ValueId } from '@/config/customizer-plugins';\n\nimport { cn } from '@udecode/cn';\nimport { AIChatPlugin, CopilotPlugin } from '@udecode/plate-ai/react';\nimport { AlignPlugin } from '@udecode/plate-alignment/react';\nimport { AutoformatPlugin } from '@udecode/plate-autoformat/react';\nimport {\n BoldPlugin,\n CodePlugin,\n ItalicPlugin,\n StrikethroughPlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n UnderlinePlugin,\n} from '@udecode/plate-basic-marks/react';\nimport { BlockquotePlugin } from '@udecode/plate-block-quote/react';\nimport { SingleLinePlugin } from '@udecode/plate-break/react';\nimport { CaptionPlugin } from '@udecode/plate-caption/react';\nimport { CodeBlockPlugin } from '@udecode/plate-code-block/react';\nimport { CommentsPlugin } from '@udecode/plate-comments/react';\nimport {\n ParagraphPlugin,\n Plate,\n usePlateEditor,\n} from '@udecode/plate-common/react';\nimport { DatePlugin } from '@udecode/plate-date/react';\nimport { DndPlugin } from '@udecode/plate-dnd';\nimport { DocxPlugin } from '@udecode/plate-docx';\nimport { EmojiPlugin } from '@udecode/plate-emoji/react';\nimport { ExcalidrawPlugin } from '@udecode/plate-excalidraw/react';\nimport {\n FontBackgroundColorPlugin,\n FontColorPlugin,\n FontSizePlugin,\n} from '@udecode/plate-font/react';\nimport { HEADING_KEYS } from '@udecode/plate-heading';\nimport { HeadingPlugin, TocPlugin } from '@udecode/plate-heading/react';\nimport { HighlightPlugin } from '@udecode/plate-highlight/react';\nimport { HorizontalRulePlugin } from '@udecode/plate-horizontal-rule/react';\nimport { IndentPlugin } from '@udecode/plate-indent/react';\nimport { IndentListPlugin } from '@udecode/plate-indent-list/react';\nimport { JuicePlugin } from '@udecode/plate-juice';\nimport { KbdPlugin } from '@udecode/plate-kbd/react';\nimport { ColumnPlugin } from '@udecode/plate-layout/react';\nimport { LineHeightPlugin } from '@udecode/plate-line-height/react';\nimport { LinkPlugin } from '@udecode/plate-link/react';\nimport { ListPlugin, TodoListPlugin } from '@udecode/plate-list/react';\nimport { MarkdownPlugin } from '@udecode/plate-markdown';\nimport { BaseImagePlugin } from '@udecode/plate-media';\nimport { ImagePlugin, MediaEmbedPlugin } from '@udecode/plate-media/react';\nimport { MentionPlugin } from '@udecode/plate-mention/react';\nimport { NodeIdPlugin } from '@udecode/plate-node-id';\nimport { NormalizeTypesPlugin } from '@udecode/plate-normalizers';\nimport { PlaywrightPlugin } from '@udecode/plate-playwright';\nimport { DeletePlugin, SelectOnBackspacePlugin } from '@udecode/plate-select';\nimport {\n BlockMenuPlugin,\n BlockSelectionPlugin,\n} from '@udecode/plate-selection/react';\nimport { SlashPlugin } from '@udecode/plate-slash-command/react';\nimport { TablePlugin } from '@udecode/plate-table/react';\nimport { TogglePlugin } from '@udecode/plate-toggle/react';\nimport { TrailingBlockPlugin } from '@udecode/plate-trailing-block';\nimport Prism from 'prismjs';\n\nimport { CheckPlugin } from '@/components/context/check-plugin';\nimport { settingsStore } from '@/components/context/settings-store';\nimport { aiPlugins } from '@/lib/plate/demo/plugins/ai-plugins';\nimport { getAutoformatOptions } from '@/lib/plate/demo/plugins/autoformatOptions';\nimport { copilotPlugins } from '@/lib/plate/demo/plugins/copilot-plugins';\nimport { createPlateUI } from '@/plate/create-plate-ui';\nimport { editableProps } from '@/plate/demo/editableProps';\nimport { isEnabled } from '@/plate/demo/is-enabled';\nimport { DragOverCursorPlugin } from '@/plate/demo/plugins/DragOverCursorPlugin';\nimport { exitBreakPlugin } from '@/plate/demo/plugins/exitBreakPlugin';\nimport { resetBlockTypePlugin } from '@/plate/demo/plugins/resetBlockTypePlugin';\nimport { softBreakPlugin } from '@/plate/demo/plugins/softBreakPlugin';\nimport { tabbablePlugin } from '@/plate/demo/plugins/tabbablePlugin';\nimport { commentsData, usersData } from '@/plate/demo/values/commentsValue';\nimport { usePlaygroundValue } from '@/plate/demo/values/usePlaygroundValue';\nimport { BlockContextMenu } from '@/components/plate-ui/block-context-menu';\nimport { CommentsPopover } from '@/components/plate-ui/comments-popover';\nimport {\n CursorOverlay,\n SelectionOverlayPlugin,\n} from '@/components/plate-ui/cursor-overlay';\nimport { Editor, EditorContainer } from '@/components/plate-ui/editor';\nimport { FixedToolbar } from '@/components/plate-ui/fixed-toolbar';\nimport { FixedToolbarButtons } from '@/components/plate-ui/fixed-toolbar-buttons';\nimport { FloatingToolbar } from '@/components/plate-ui/floating-toolbar';\nimport { FloatingToolbarButtons } from '@/components/plate-ui/floating-toolbar-buttons';\nimport { ImagePreview } from '@/components/plate-ui/image-preview';\nimport {\n FireLiComponent,\n FireMarker,\n} from '@/components/plate-ui/indent-fire-marker';\nimport {\n TodoLi,\n TodoMarker,\n} from '@/components/plate-ui/indent-todo-marker';\nimport { LinkFloatingToolbar } from '@/components/plate-ui/link-floating-toolbar';\n\nimport { usePlaygroundEnabled } from './usePlaygroundEnabled';\n\nexport const usePlaygroundEditor = (id: any = '', scrollSelector?: string) => {\n const enabledPlugins = settingsStore.use.checkedPlugins();\n const overridePlugins = usePlaygroundEnabled(id);\n const autoformatOptions = getAutoformatOptions(id, enabledPlugins);\n\n const value = usePlaygroundValue(id);\n const key = settingsStore.use.version();\n const editorId = id || 'playground-' + key;\n\n return usePlateEditor(\n {\n id: editorId,\n override: {\n components: createPlateUI({\n draggable: isEnabled('dnd', id),\n placeholder: isEnabled('placeholder', id),\n }),\n plugins: overridePlugins,\n },\n plugins: [\n // AI\n ...(id === 'ai' || enabledPlugins[AIChatPlugin.key] ? aiPlugins : []),\n ...(id === 'copilot' || enabledPlugins[CopilotPlugin.key]\n ? copilotPlugins\n : []),\n // Nodes\n HeadingPlugin,\n TocPlugin.configure({\n options: {\n scrollContainerSelector: `#${scrollSelector}`,\n topOffset: 80,\n },\n }),\n BlockquotePlugin,\n CodeBlockPlugin.configure({\n options: {\n prism: Prism,\n },\n }),\n HorizontalRulePlugin,\n LinkPlugin.extend({\n render: { afterEditable: () => },\n }),\n ...(id === 'list' ? [ListPlugin] : []),\n ImagePlugin.extend({\n options: {\n disableUploadInsert: true,\n },\n render: { afterEditable: ImagePreview },\n }),\n MediaEmbedPlugin,\n CaptionPlugin.configure({\n options: {\n plugins: [ImagePlugin, MediaEmbedPlugin],\n },\n }),\n DatePlugin,\n MentionPlugin.configure({\n options: {\n triggerPreviousCharPattern: /^$|^[\\s\"']$/,\n },\n }),\n SlashPlugin,\n TablePlugin.configure({\n options: {\n enableMerging: id === 'tableMerge',\n },\n }),\n ColumnPlugin,\n SelectionOverlayPlugin,\n\n TodoListPlugin,\n TogglePlugin,\n ExcalidrawPlugin,\n // Marks\n BoldPlugin,\n ItalicPlugin,\n UnderlinePlugin,\n StrikethroughPlugin,\n CodePlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n FontColorPlugin,\n FontBackgroundColorPlugin,\n FontSizePlugin,\n HighlightPlugin,\n KbdPlugin,\n\n // Block Style\n AlignPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n MediaEmbedPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n ImagePlugin.key,\n HEADING_KEYS.h6,\n ],\n },\n }),\n IndentPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n }),\n IndentListPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n options: {\n listStyleTypes: {\n fire: {\n liComponent: FireLiComponent,\n markerComponent: FireMarker,\n type: 'fire',\n },\n todo: {\n liComponent: TodoLi,\n markerComponent: TodoMarker,\n type: 'todo',\n },\n },\n },\n }),\n LineHeightPlugin.extend({\n inject: {\n nodeProps: {\n defaultNodeValue: 1.5,\n validNodeValues: [1, 1.2, 1.5, 2, 3],\n },\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n ],\n },\n }),\n\n // Functionality\n AutoformatPlugin.configure({\n options: autoformatOptions,\n }),\n BlockSelectionPlugin.configure({\n options: {\n areaOptions: {\n behaviour: {\n scrolling: {\n speedDivider: 1.5,\n },\n startThreshold: 10,\n },\n boundaries: `#${scrollSelector}`,\n container: `#${scrollSelector}`,\n selectables: [`#${scrollSelector} .slate-selectable`],\n selectionAreaClass: 'slate-selection-area',\n },\n enableContextMenu: true,\n },\n }),\n BlockMenuPlugin.configure({\n render: { aboveEditable: BlockContextMenu },\n }),\n DndPlugin.configure({\n options: {\n enableScroller: true,\n onDropFiles: ({ dragItem, editor, target }) => {\n editor\n .getTransforms(BaseImagePlugin)\n .insert.imageFromFiles(dragItem.files, {\n at: target,\n nextBlock: false,\n });\n },\n },\n }),\n EmojiPlugin,\n exitBreakPlugin,\n NodeIdPlugin,\n NormalizeTypesPlugin.configure({\n options: {\n rules: [{ path: [0], strictType: HEADING_KEYS.h1 }],\n },\n }),\n resetBlockTypePlugin,\n SelectOnBackspacePlugin.configure({\n options: {\n query: {\n allow: [ImagePlugin.key, HorizontalRulePlugin.key],\n },\n },\n }),\n DeletePlugin,\n SingleLinePlugin,\n softBreakPlugin,\n tabbablePlugin,\n TrailingBlockPlugin.configure({\n options: { type: ParagraphPlugin.key },\n }),\n DragOverCursorPlugin,\n\n // Collaboration\n CommentsPlugin.configure({\n options: {\n comments: commentsData,\n myUserId: '1',\n users: usersData,\n },\n }),\n\n // Deserialization\n DocxPlugin,\n MarkdownPlugin.configure({ options: { indentList: true } }),\n JuicePlugin,\n\n // Testing\n PlaywrightPlugin.configure({\n enabled: process.env.NODE_ENV !== 'production',\n }),\n ],\n value: value,\n },\n []\n );\n};\n\nexport default function PlaygroundDemo({\n id,\n className,\n scrollSelector,\n}: {\n id?: ValueId;\n className?: string;\n scrollSelector?: string;\n}) {\n const containerRef = useRef(null);\n const enabled = settingsStore.use.checkedComponents();\n\n const editor = usePlaygroundEditor(\n id,\n scrollSelector ?? `blockSelection-${id}`\n );\n\n return (\n \n \n \n \n \n \n \n \n \n\n
\n \n \n\n \n \n \n \n \n \n \n\n \n \n \n \n\n \n \n \n
\n
\n
\n );\n}\n\nconst DemoIdContext = React.createContext(undefined);\n\nexport function DemoId({\n id,\n children,\n}: {\n children: React.ReactNode;\n id?: string;\n}) {\n return {children};\n}\n\nexport function useDemoId() {\n return React.useContext(DemoIdContext);\n}\n", "path": "example/playground-demo.tsx", "target": "components/playground-demo.tsx", "type": "registry:example" diff --git a/apps/www/public/r/styles/default/basic-marks-demo.json b/apps/www/public/r/styles/default/basic-marks-demo.json index a5b58cd2c0..711fad838e 100644 --- a/apps/www/public/r/styles/default/basic-marks-demo.json +++ b/apps/www/public/r/styles/default/basic-marks-demo.json @@ -4,7 +4,7 @@ }, "files": [ { - "content": "'use client';\n\nimport React, { useRef } from 'react';\n\nimport type { ValueId } from '@/config/customizer-plugins';\n\nimport { cn } from '@udecode/cn';\nimport { AIChatPlugin, CopilotPlugin } from '@udecode/plate-ai/react';\nimport { AlignPlugin } from '@udecode/plate-alignment/react';\nimport { AutoformatPlugin } from '@udecode/plate-autoformat/react';\nimport {\n BoldPlugin,\n CodePlugin,\n ItalicPlugin,\n StrikethroughPlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n UnderlinePlugin,\n} from '@udecode/plate-basic-marks/react';\nimport { BlockquotePlugin } from '@udecode/plate-block-quote/react';\nimport { SingleLinePlugin } from '@udecode/plate-break/react';\nimport { CaptionPlugin } from '@udecode/plate-caption/react';\nimport { CodeBlockPlugin } from '@udecode/plate-code-block/react';\nimport { CommentsPlugin } from '@udecode/plate-comments/react';\nimport {\n ParagraphPlugin,\n Plate,\n usePlateEditor,\n} from '@udecode/plate-common/react';\nimport { DatePlugin } from '@udecode/plate-date/react';\nimport { DndPlugin } from '@udecode/plate-dnd';\nimport { DocxPlugin } from '@udecode/plate-docx';\nimport { EmojiPlugin } from '@udecode/plate-emoji/react';\nimport { ExcalidrawPlugin } from '@udecode/plate-excalidraw/react';\nimport {\n FontBackgroundColorPlugin,\n FontColorPlugin,\n FontSizePlugin,\n} from '@udecode/plate-font/react';\nimport { HEADING_KEYS } from '@udecode/plate-heading';\nimport { HeadingPlugin, TocPlugin } from '@udecode/plate-heading/react';\nimport { HighlightPlugin } from '@udecode/plate-highlight/react';\nimport { HorizontalRulePlugin } from '@udecode/plate-horizontal-rule/react';\nimport { IndentPlugin } from '@udecode/plate-indent/react';\nimport { IndentListPlugin } from '@udecode/plate-indent-list/react';\nimport { JuicePlugin } from '@udecode/plate-juice';\nimport { KbdPlugin } from '@udecode/plate-kbd/react';\nimport { ColumnPlugin } from '@udecode/plate-layout/react';\nimport { LineHeightPlugin } from '@udecode/plate-line-height/react';\nimport { LinkPlugin } from '@udecode/plate-link/react';\nimport { ListPlugin, TodoListPlugin } from '@udecode/plate-list/react';\nimport { MarkdownPlugin } from '@udecode/plate-markdown';\nimport { ImagePlugin, MediaEmbedPlugin } from '@udecode/plate-media/react';\nimport { MentionPlugin } from '@udecode/plate-mention/react';\nimport { NodeIdPlugin } from '@udecode/plate-node-id';\nimport { NormalizeTypesPlugin } from '@udecode/plate-normalizers';\nimport { PlaywrightPlugin } from '@udecode/plate-playwright';\nimport { DeletePlugin, SelectOnBackspacePlugin } from '@udecode/plate-select';\nimport {\n BlockMenuPlugin,\n BlockSelectionPlugin,\n} from '@udecode/plate-selection/react';\nimport { SlashPlugin } from '@udecode/plate-slash-command/react';\nimport { TablePlugin } from '@udecode/plate-table/react';\nimport { TogglePlugin } from '@udecode/plate-toggle/react';\nimport { TrailingBlockPlugin } from '@udecode/plate-trailing-block';\nimport Prism from 'prismjs';\n\nimport { CheckPlugin } from '@/components/context/check-plugin';\nimport { settingsStore } from '@/components/context/settings-store';\nimport { aiPlugins } from '@/lib/plate/demo/plugins/ai-plugins';\nimport { getAutoformatOptions } from '@/lib/plate/demo/plugins/autoformatOptions';\nimport { copilotPlugins } from '@/lib/plate/demo/plugins/copilot-plugins';\nimport { createPlateUI } from '@/plate/create-plate-ui';\nimport { editableProps } from '@/plate/demo/editableProps';\nimport { isEnabled } from '@/plate/demo/is-enabled';\nimport { DragOverCursorPlugin } from '@/plate/demo/plugins/DragOverCursorPlugin';\nimport { exitBreakPlugin } from '@/plate/demo/plugins/exitBreakPlugin';\nimport { resetBlockTypePlugin } from '@/plate/demo/plugins/resetBlockTypePlugin';\nimport { softBreakPlugin } from '@/plate/demo/plugins/softBreakPlugin';\nimport { tabbablePlugin } from '@/plate/demo/plugins/tabbablePlugin';\nimport { commentsData, usersData } from '@/plate/demo/values/commentsValue';\nimport { usePlaygroundValue } from '@/plate/demo/values/usePlaygroundValue';\nimport { BlockContextMenu } from '@/components/plate-ui/block-context-menu';\nimport { CommentsPopover } from '@/components/plate-ui/comments-popover';\nimport {\n CursorOverlay,\n SelectionOverlayPlugin,\n} from '@/components/plate-ui/cursor-overlay';\nimport { Editor, EditorContainer } from '@/components/plate-ui/editor';\nimport { FixedToolbar } from '@/components/plate-ui/fixed-toolbar';\nimport { FixedToolbarButtons } from '@/components/plate-ui/fixed-toolbar-buttons';\nimport { FloatingToolbar } from '@/components/plate-ui/floating-toolbar';\nimport { FloatingToolbarButtons } from '@/components/plate-ui/floating-toolbar-buttons';\nimport { ImagePreview } from '@/components/plate-ui/image-preview';\nimport {\n FireLiComponent,\n FireMarker,\n} from '@/components/plate-ui/indent-fire-marker';\nimport {\n TodoLi,\n TodoMarker,\n} from '@/components/plate-ui/indent-todo-marker';\nimport { LinkFloatingToolbar } from '@/components/plate-ui/link-floating-toolbar';\n\nimport { usePlaygroundEnabled } from './usePlaygroundEnabled';\n\nexport const usePlaygroundEditor = (id: any = '', scrollSelector?: string) => {\n const enabledPlugins = settingsStore.use.checkedPlugins();\n const overridePlugins = usePlaygroundEnabled(id);\n const autoformatOptions = getAutoformatOptions(id, enabledPlugins);\n\n const value = usePlaygroundValue(id);\n const key = settingsStore.use.version();\n const editorId = id || 'playground-' + key;\n\n return usePlateEditor(\n {\n id: editorId,\n override: {\n components: createPlateUI({\n draggable: isEnabled('dnd', id),\n placeholder: isEnabled('placeholder', id),\n }),\n plugins: overridePlugins,\n },\n plugins: [\n // AI\n ...(id === 'ai' || enabledPlugins[AIChatPlugin.key] ? aiPlugins : []),\n ...(id === 'copilot' || enabledPlugins[CopilotPlugin.key]\n ? copilotPlugins\n : []),\n // Nodes\n HeadingPlugin,\n TocPlugin.configure({\n options: {\n scrollContainerSelector: `#${scrollSelector}`,\n topOffset: 80,\n },\n }),\n BlockquotePlugin,\n CodeBlockPlugin.configure({\n options: {\n prism: Prism,\n },\n }),\n HorizontalRulePlugin,\n LinkPlugin.extend({\n render: { afterEditable: () => },\n }),\n ...(id === 'list' ? [ListPlugin] : []),\n ImagePlugin.extend({\n options: {\n disableUploadInsert: true,\n },\n render: { afterEditable: ImagePreview },\n }),\n MediaEmbedPlugin,\n CaptionPlugin.configure({\n options: {\n plugins: [ImagePlugin, MediaEmbedPlugin],\n },\n }),\n DatePlugin,\n MentionPlugin.configure({\n options: {\n triggerPreviousCharPattern: /^$|^[\\s\"']$/,\n },\n }),\n SlashPlugin,\n TablePlugin.configure({\n options: {\n enableMerging: id === 'tableMerge',\n },\n }),\n ColumnPlugin,\n SelectionOverlayPlugin,\n\n TodoListPlugin,\n TogglePlugin,\n ExcalidrawPlugin,\n // Marks\n BoldPlugin,\n ItalicPlugin,\n UnderlinePlugin,\n StrikethroughPlugin,\n CodePlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n FontColorPlugin,\n FontBackgroundColorPlugin,\n FontSizePlugin,\n HighlightPlugin,\n KbdPlugin,\n\n // Block Style\n AlignPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n MediaEmbedPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n ImagePlugin.key,\n HEADING_KEYS.h6,\n ],\n },\n }),\n IndentPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n }),\n IndentListPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n options: {\n listStyleTypes: {\n fire: {\n liComponent: FireLiComponent,\n markerComponent: FireMarker,\n type: 'fire',\n },\n todo: {\n liComponent: TodoLi,\n markerComponent: TodoMarker,\n type: 'todo',\n },\n },\n },\n }),\n LineHeightPlugin.extend({\n inject: {\n nodeProps: {\n defaultNodeValue: 1.5,\n validNodeValues: [1, 1.2, 1.5, 2, 3],\n },\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n ],\n },\n }),\n\n // Functionality\n AutoformatPlugin.configure({\n options: autoformatOptions,\n }),\n BlockSelectionPlugin.configure({\n options: {\n areaOptions: {\n behaviour: {\n scrolling: {\n speedDivider: 1.5,\n },\n startThreshold: 10,\n },\n boundaries: `#${scrollSelector}`,\n container: `#${scrollSelector}`,\n selectables: [`#${scrollSelector} .slate-selectable`],\n selectionAreaClass: 'slate-selection-area',\n },\n enableContextMenu: true,\n },\n }),\n BlockMenuPlugin.configure({\n render: { aboveEditable: BlockContextMenu },\n }),\n DndPlugin.configure({\n options: {\n enableScroller: true,\n onDropFiles: ({ dragItem, editor, target }) => {\n editor\n .getTransforms(ImagePlugin)\n .insertImageFromFiles(dragItem.files, {\n at: target,\n nextBlock: false,\n });\n },\n },\n }),\n EmojiPlugin,\n exitBreakPlugin,\n NodeIdPlugin,\n NormalizeTypesPlugin.configure({\n options: {\n rules: [{ path: [0], strictType: HEADING_KEYS.h1 }],\n },\n }),\n resetBlockTypePlugin,\n SelectOnBackspacePlugin.configure({\n options: {\n query: {\n allow: [ImagePlugin.key, HorizontalRulePlugin.key],\n },\n },\n }),\n DeletePlugin,\n SingleLinePlugin,\n softBreakPlugin,\n tabbablePlugin,\n TrailingBlockPlugin.configure({\n options: { type: ParagraphPlugin.key },\n }),\n DragOverCursorPlugin,\n\n // Collaboration\n CommentsPlugin.configure({\n options: {\n comments: commentsData,\n myUserId: '1',\n users: usersData,\n },\n }),\n\n // Deserialization\n DocxPlugin,\n MarkdownPlugin.configure({ options: { indentList: true } }),\n JuicePlugin,\n\n // Testing\n PlaywrightPlugin.configure({\n enabled: process.env.NODE_ENV !== 'production',\n }),\n ],\n value: value,\n },\n []\n );\n};\n\nexport default function PlaygroundDemo({\n id,\n className,\n scrollSelector,\n}: {\n id?: ValueId;\n className?: string;\n scrollSelector?: string;\n}) {\n const containerRef = useRef(null);\n const enabled = settingsStore.use.checkedComponents();\n\n const editor = usePlaygroundEditor(\n id,\n scrollSelector ?? `blockSelection-${id}`\n );\n\n return (\n \n \n \n \n \n \n \n \n \n\n
\n \n \n\n \n \n \n \n \n \n \n\n \n \n \n \n\n \n \n \n
\n
\n
\n );\n}\n\nconst DemoIdContext = React.createContext(undefined);\n\nexport function DemoId({\n id,\n children,\n}: {\n children: React.ReactNode;\n id?: string;\n}) {\n return {children};\n}\n\nexport function useDemoId() {\n return React.useContext(DemoIdContext);\n}\n", + "content": "'use client';\n\nimport React, { useRef } from 'react';\n\nimport type { ValueId } from '@/config/customizer-plugins';\n\nimport { cn } from '@udecode/cn';\nimport { AIChatPlugin, CopilotPlugin } from '@udecode/plate-ai/react';\nimport { AlignPlugin } from '@udecode/plate-alignment/react';\nimport { AutoformatPlugin } from '@udecode/plate-autoformat/react';\nimport {\n BoldPlugin,\n CodePlugin,\n ItalicPlugin,\n StrikethroughPlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n UnderlinePlugin,\n} from '@udecode/plate-basic-marks/react';\nimport { BlockquotePlugin } from '@udecode/plate-block-quote/react';\nimport { SingleLinePlugin } from '@udecode/plate-break/react';\nimport { CaptionPlugin } from '@udecode/plate-caption/react';\nimport { CodeBlockPlugin } from '@udecode/plate-code-block/react';\nimport { CommentsPlugin } from '@udecode/plate-comments/react';\nimport {\n ParagraphPlugin,\n Plate,\n usePlateEditor,\n} from '@udecode/plate-common/react';\nimport { DatePlugin } from '@udecode/plate-date/react';\nimport { DndPlugin } from '@udecode/plate-dnd';\nimport { DocxPlugin } from '@udecode/plate-docx';\nimport { EmojiPlugin } from '@udecode/plate-emoji/react';\nimport { ExcalidrawPlugin } from '@udecode/plate-excalidraw/react';\nimport {\n FontBackgroundColorPlugin,\n FontColorPlugin,\n FontSizePlugin,\n} from '@udecode/plate-font/react';\nimport { HEADING_KEYS } from '@udecode/plate-heading';\nimport { HeadingPlugin, TocPlugin } from '@udecode/plate-heading/react';\nimport { HighlightPlugin } from '@udecode/plate-highlight/react';\nimport { HorizontalRulePlugin } from '@udecode/plate-horizontal-rule/react';\nimport { IndentPlugin } from '@udecode/plate-indent/react';\nimport { IndentListPlugin } from '@udecode/plate-indent-list/react';\nimport { JuicePlugin } from '@udecode/plate-juice';\nimport { KbdPlugin } from '@udecode/plate-kbd/react';\nimport { ColumnPlugin } from '@udecode/plate-layout/react';\nimport { LineHeightPlugin } from '@udecode/plate-line-height/react';\nimport { LinkPlugin } from '@udecode/plate-link/react';\nimport { ListPlugin, TodoListPlugin } from '@udecode/plate-list/react';\nimport { MarkdownPlugin } from '@udecode/plate-markdown';\nimport { BaseImagePlugin } from '@udecode/plate-media';\nimport { ImagePlugin, MediaEmbedPlugin } from '@udecode/plate-media/react';\nimport { MentionPlugin } from '@udecode/plate-mention/react';\nimport { NodeIdPlugin } from '@udecode/plate-node-id';\nimport { NormalizeTypesPlugin } from '@udecode/plate-normalizers';\nimport { PlaywrightPlugin } from '@udecode/plate-playwright';\nimport { DeletePlugin, SelectOnBackspacePlugin } from '@udecode/plate-select';\nimport {\n BlockMenuPlugin,\n BlockSelectionPlugin,\n} from '@udecode/plate-selection/react';\nimport { SlashPlugin } from '@udecode/plate-slash-command/react';\nimport { TablePlugin } from '@udecode/plate-table/react';\nimport { TogglePlugin } from '@udecode/plate-toggle/react';\nimport { TrailingBlockPlugin } from '@udecode/plate-trailing-block';\nimport Prism from 'prismjs';\n\nimport { CheckPlugin } from '@/components/context/check-plugin';\nimport { settingsStore } from '@/components/context/settings-store';\nimport { aiPlugins } from '@/lib/plate/demo/plugins/ai-plugins';\nimport { getAutoformatOptions } from '@/lib/plate/demo/plugins/autoformatOptions';\nimport { copilotPlugins } from '@/lib/plate/demo/plugins/copilot-plugins';\nimport { createPlateUI } from '@/plate/create-plate-ui';\nimport { editableProps } from '@/plate/demo/editableProps';\nimport { isEnabled } from '@/plate/demo/is-enabled';\nimport { DragOverCursorPlugin } from '@/plate/demo/plugins/DragOverCursorPlugin';\nimport { exitBreakPlugin } from '@/plate/demo/plugins/exitBreakPlugin';\nimport { resetBlockTypePlugin } from '@/plate/demo/plugins/resetBlockTypePlugin';\nimport { softBreakPlugin } from '@/plate/demo/plugins/softBreakPlugin';\nimport { tabbablePlugin } from '@/plate/demo/plugins/tabbablePlugin';\nimport { commentsData, usersData } from '@/plate/demo/values/commentsValue';\nimport { usePlaygroundValue } from '@/plate/demo/values/usePlaygroundValue';\nimport { BlockContextMenu } from '@/components/plate-ui/block-context-menu';\nimport { CommentsPopover } from '@/components/plate-ui/comments-popover';\nimport {\n CursorOverlay,\n SelectionOverlayPlugin,\n} from '@/components/plate-ui/cursor-overlay';\nimport { Editor, EditorContainer } from '@/components/plate-ui/editor';\nimport { FixedToolbar } from '@/components/plate-ui/fixed-toolbar';\nimport { FixedToolbarButtons } from '@/components/plate-ui/fixed-toolbar-buttons';\nimport { FloatingToolbar } from '@/components/plate-ui/floating-toolbar';\nimport { FloatingToolbarButtons } from '@/components/plate-ui/floating-toolbar-buttons';\nimport { ImagePreview } from '@/components/plate-ui/image-preview';\nimport {\n FireLiComponent,\n FireMarker,\n} from '@/components/plate-ui/indent-fire-marker';\nimport {\n TodoLi,\n TodoMarker,\n} from '@/components/plate-ui/indent-todo-marker';\nimport { LinkFloatingToolbar } from '@/components/plate-ui/link-floating-toolbar';\n\nimport { usePlaygroundEnabled } from './usePlaygroundEnabled';\n\nexport const usePlaygroundEditor = (id: any = '', scrollSelector?: string) => {\n const enabledPlugins = settingsStore.use.checkedPlugins();\n const overridePlugins = usePlaygroundEnabled(id);\n const autoformatOptions = getAutoformatOptions(id, enabledPlugins);\n\n const value = usePlaygroundValue(id);\n const key = settingsStore.use.version();\n const editorId = id || 'playground-' + key;\n\n return usePlateEditor(\n {\n id: editorId,\n override: {\n components: createPlateUI({\n draggable: isEnabled('dnd', id),\n placeholder: isEnabled('placeholder', id),\n }),\n plugins: overridePlugins,\n },\n plugins: [\n // AI\n ...(id === 'ai' || enabledPlugins[AIChatPlugin.key] ? aiPlugins : []),\n ...(id === 'copilot' || enabledPlugins[CopilotPlugin.key]\n ? copilotPlugins\n : []),\n // Nodes\n HeadingPlugin,\n TocPlugin.configure({\n options: {\n scrollContainerSelector: `#${scrollSelector}`,\n topOffset: 80,\n },\n }),\n BlockquotePlugin,\n CodeBlockPlugin.configure({\n options: {\n prism: Prism,\n },\n }),\n HorizontalRulePlugin,\n LinkPlugin.extend({\n render: { afterEditable: () => },\n }),\n ...(id === 'list' ? [ListPlugin] : []),\n ImagePlugin.extend({\n options: {\n disableUploadInsert: true,\n },\n render: { afterEditable: ImagePreview },\n }),\n MediaEmbedPlugin,\n CaptionPlugin.configure({\n options: {\n plugins: [ImagePlugin, MediaEmbedPlugin],\n },\n }),\n DatePlugin,\n MentionPlugin.configure({\n options: {\n triggerPreviousCharPattern: /^$|^[\\s\"']$/,\n },\n }),\n SlashPlugin,\n TablePlugin.configure({\n options: {\n enableMerging: id === 'tableMerge',\n },\n }),\n ColumnPlugin,\n SelectionOverlayPlugin,\n\n TodoListPlugin,\n TogglePlugin,\n ExcalidrawPlugin,\n // Marks\n BoldPlugin,\n ItalicPlugin,\n UnderlinePlugin,\n StrikethroughPlugin,\n CodePlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n FontColorPlugin,\n FontBackgroundColorPlugin,\n FontSizePlugin,\n HighlightPlugin,\n KbdPlugin,\n\n // Block Style\n AlignPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n MediaEmbedPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n ImagePlugin.key,\n HEADING_KEYS.h6,\n ],\n },\n }),\n IndentPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n }),\n IndentListPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n options: {\n listStyleTypes: {\n fire: {\n liComponent: FireLiComponent,\n markerComponent: FireMarker,\n type: 'fire',\n },\n todo: {\n liComponent: TodoLi,\n markerComponent: TodoMarker,\n type: 'todo',\n },\n },\n },\n }),\n LineHeightPlugin.extend({\n inject: {\n nodeProps: {\n defaultNodeValue: 1.5,\n validNodeValues: [1, 1.2, 1.5, 2, 3],\n },\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n ],\n },\n }),\n\n // Functionality\n AutoformatPlugin.configure({\n options: autoformatOptions,\n }),\n BlockSelectionPlugin.configure({\n options: {\n areaOptions: {\n behaviour: {\n scrolling: {\n speedDivider: 1.5,\n },\n startThreshold: 10,\n },\n boundaries: `#${scrollSelector}`,\n container: `#${scrollSelector}`,\n selectables: [`#${scrollSelector} .slate-selectable`],\n selectionAreaClass: 'slate-selection-area',\n },\n enableContextMenu: true,\n },\n }),\n BlockMenuPlugin.configure({\n render: { aboveEditable: BlockContextMenu },\n }),\n DndPlugin.configure({\n options: {\n enableScroller: true,\n onDropFiles: ({ dragItem, editor, target }) => {\n editor\n .getTransforms(BaseImagePlugin)\n .insert.imageFromFiles(dragItem.files, {\n at: target,\n nextBlock: false,\n });\n },\n },\n }),\n EmojiPlugin,\n exitBreakPlugin,\n NodeIdPlugin,\n NormalizeTypesPlugin.configure({\n options: {\n rules: [{ path: [0], strictType: HEADING_KEYS.h1 }],\n },\n }),\n resetBlockTypePlugin,\n SelectOnBackspacePlugin.configure({\n options: {\n query: {\n allow: [ImagePlugin.key, HorizontalRulePlugin.key],\n },\n },\n }),\n DeletePlugin,\n SingleLinePlugin,\n softBreakPlugin,\n tabbablePlugin,\n TrailingBlockPlugin.configure({\n options: { type: ParagraphPlugin.key },\n }),\n DragOverCursorPlugin,\n\n // Collaboration\n CommentsPlugin.configure({\n options: {\n comments: commentsData,\n myUserId: '1',\n users: usersData,\n },\n }),\n\n // Deserialization\n DocxPlugin,\n MarkdownPlugin.configure({ options: { indentList: true } }),\n JuicePlugin,\n\n // Testing\n PlaywrightPlugin.configure({\n enabled: process.env.NODE_ENV !== 'production',\n }),\n ],\n value: value,\n },\n []\n );\n};\n\nexport default function PlaygroundDemo({\n id,\n className,\n scrollSelector,\n}: {\n id?: ValueId;\n className?: string;\n scrollSelector?: string;\n}) {\n const containerRef = useRef(null);\n const enabled = settingsStore.use.checkedComponents();\n\n const editor = usePlaygroundEditor(\n id,\n scrollSelector ?? `blockSelection-${id}`\n );\n\n return (\n \n \n \n \n \n \n \n \n \n\n
\n \n \n\n \n \n \n \n \n \n \n\n \n \n \n \n\n \n \n \n
\n
\n
\n );\n}\n\nconst DemoIdContext = React.createContext(undefined);\n\nexport function DemoId({\n id,\n children,\n}: {\n children: React.ReactNode;\n id?: string;\n}) {\n return {children};\n}\n\nexport function useDemoId() {\n return React.useContext(DemoIdContext);\n}\n", "path": "example/playground-demo.tsx", "target": "components/playground-demo.tsx", "type": "registry:example" diff --git a/apps/www/public/r/styles/default/basic-nodes-demo.json b/apps/www/public/r/styles/default/basic-nodes-demo.json index 191775580c..e2f9d1406f 100644 --- a/apps/www/public/r/styles/default/basic-nodes-demo.json +++ b/apps/www/public/r/styles/default/basic-nodes-demo.json @@ -8,7 +8,7 @@ }, "files": [ { - "content": "'use client';\n\nimport React, { useRef } from 'react';\n\nimport type { ValueId } from '@/config/customizer-plugins';\n\nimport { cn } from '@udecode/cn';\nimport { AIChatPlugin, CopilotPlugin } from '@udecode/plate-ai/react';\nimport { AlignPlugin } from '@udecode/plate-alignment/react';\nimport { AutoformatPlugin } from '@udecode/plate-autoformat/react';\nimport {\n BoldPlugin,\n CodePlugin,\n ItalicPlugin,\n StrikethroughPlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n UnderlinePlugin,\n} from '@udecode/plate-basic-marks/react';\nimport { BlockquotePlugin } from '@udecode/plate-block-quote/react';\nimport { SingleLinePlugin } from '@udecode/plate-break/react';\nimport { CaptionPlugin } from '@udecode/plate-caption/react';\nimport { CodeBlockPlugin } from '@udecode/plate-code-block/react';\nimport { CommentsPlugin } from '@udecode/plate-comments/react';\nimport {\n ParagraphPlugin,\n Plate,\n usePlateEditor,\n} from '@udecode/plate-common/react';\nimport { DatePlugin } from '@udecode/plate-date/react';\nimport { DndPlugin } from '@udecode/plate-dnd';\nimport { DocxPlugin } from '@udecode/plate-docx';\nimport { EmojiPlugin } from '@udecode/plate-emoji/react';\nimport { ExcalidrawPlugin } from '@udecode/plate-excalidraw/react';\nimport {\n FontBackgroundColorPlugin,\n FontColorPlugin,\n FontSizePlugin,\n} from '@udecode/plate-font/react';\nimport { HEADING_KEYS } from '@udecode/plate-heading';\nimport { HeadingPlugin, TocPlugin } from '@udecode/plate-heading/react';\nimport { HighlightPlugin } from '@udecode/plate-highlight/react';\nimport { HorizontalRulePlugin } from '@udecode/plate-horizontal-rule/react';\nimport { IndentPlugin } from '@udecode/plate-indent/react';\nimport { IndentListPlugin } from '@udecode/plate-indent-list/react';\nimport { JuicePlugin } from '@udecode/plate-juice';\nimport { KbdPlugin } from '@udecode/plate-kbd/react';\nimport { ColumnPlugin } from '@udecode/plate-layout/react';\nimport { LineHeightPlugin } from '@udecode/plate-line-height/react';\nimport { LinkPlugin } from '@udecode/plate-link/react';\nimport { ListPlugin, TodoListPlugin } from '@udecode/plate-list/react';\nimport { MarkdownPlugin } from '@udecode/plate-markdown';\nimport { ImagePlugin, MediaEmbedPlugin } from '@udecode/plate-media/react';\nimport { MentionPlugin } from '@udecode/plate-mention/react';\nimport { NodeIdPlugin } from '@udecode/plate-node-id';\nimport { NormalizeTypesPlugin } from '@udecode/plate-normalizers';\nimport { PlaywrightPlugin } from '@udecode/plate-playwright';\nimport { DeletePlugin, SelectOnBackspacePlugin } from '@udecode/plate-select';\nimport {\n BlockMenuPlugin,\n BlockSelectionPlugin,\n} from '@udecode/plate-selection/react';\nimport { SlashPlugin } from '@udecode/plate-slash-command/react';\nimport { TablePlugin } from '@udecode/plate-table/react';\nimport { TogglePlugin } from '@udecode/plate-toggle/react';\nimport { TrailingBlockPlugin } from '@udecode/plate-trailing-block';\nimport Prism from 'prismjs';\n\nimport { CheckPlugin } from '@/components/context/check-plugin';\nimport { settingsStore } from '@/components/context/settings-store';\nimport { aiPlugins } from '@/lib/plate/demo/plugins/ai-plugins';\nimport { getAutoformatOptions } from '@/lib/plate/demo/plugins/autoformatOptions';\nimport { copilotPlugins } from '@/lib/plate/demo/plugins/copilot-plugins';\nimport { createPlateUI } from '@/plate/create-plate-ui';\nimport { editableProps } from '@/plate/demo/editableProps';\nimport { isEnabled } from '@/plate/demo/is-enabled';\nimport { DragOverCursorPlugin } from '@/plate/demo/plugins/DragOverCursorPlugin';\nimport { exitBreakPlugin } from '@/plate/demo/plugins/exitBreakPlugin';\nimport { resetBlockTypePlugin } from '@/plate/demo/plugins/resetBlockTypePlugin';\nimport { softBreakPlugin } from '@/plate/demo/plugins/softBreakPlugin';\nimport { tabbablePlugin } from '@/plate/demo/plugins/tabbablePlugin';\nimport { commentsData, usersData } from '@/plate/demo/values/commentsValue';\nimport { usePlaygroundValue } from '@/plate/demo/values/usePlaygroundValue';\nimport { BlockContextMenu } from '@/components/plate-ui/block-context-menu';\nimport { CommentsPopover } from '@/components/plate-ui/comments-popover';\nimport {\n CursorOverlay,\n SelectionOverlayPlugin,\n} from '@/components/plate-ui/cursor-overlay';\nimport { Editor, EditorContainer } from '@/components/plate-ui/editor';\nimport { FixedToolbar } from '@/components/plate-ui/fixed-toolbar';\nimport { FixedToolbarButtons } from '@/components/plate-ui/fixed-toolbar-buttons';\nimport { FloatingToolbar } from '@/components/plate-ui/floating-toolbar';\nimport { FloatingToolbarButtons } from '@/components/plate-ui/floating-toolbar-buttons';\nimport { ImagePreview } from '@/components/plate-ui/image-preview';\nimport {\n FireLiComponent,\n FireMarker,\n} from '@/components/plate-ui/indent-fire-marker';\nimport {\n TodoLi,\n TodoMarker,\n} from '@/components/plate-ui/indent-todo-marker';\nimport { LinkFloatingToolbar } from '@/components/plate-ui/link-floating-toolbar';\n\nimport { usePlaygroundEnabled } from './usePlaygroundEnabled';\n\nexport const usePlaygroundEditor = (id: any = '', scrollSelector?: string) => {\n const enabledPlugins = settingsStore.use.checkedPlugins();\n const overridePlugins = usePlaygroundEnabled(id);\n const autoformatOptions = getAutoformatOptions(id, enabledPlugins);\n\n const value = usePlaygroundValue(id);\n const key = settingsStore.use.version();\n const editorId = id || 'playground-' + key;\n\n return usePlateEditor(\n {\n id: editorId,\n override: {\n components: createPlateUI({\n draggable: isEnabled('dnd', id),\n placeholder: isEnabled('placeholder', id),\n }),\n plugins: overridePlugins,\n },\n plugins: [\n // AI\n ...(id === 'ai' || enabledPlugins[AIChatPlugin.key] ? aiPlugins : []),\n ...(id === 'copilot' || enabledPlugins[CopilotPlugin.key]\n ? copilotPlugins\n : []),\n // Nodes\n HeadingPlugin,\n TocPlugin.configure({\n options: {\n scrollContainerSelector: `#${scrollSelector}`,\n topOffset: 80,\n },\n }),\n BlockquotePlugin,\n CodeBlockPlugin.configure({\n options: {\n prism: Prism,\n },\n }),\n HorizontalRulePlugin,\n LinkPlugin.extend({\n render: { afterEditable: () => },\n }),\n ...(id === 'list' ? [ListPlugin] : []),\n ImagePlugin.extend({\n options: {\n disableUploadInsert: true,\n },\n render: { afterEditable: ImagePreview },\n }),\n MediaEmbedPlugin,\n CaptionPlugin.configure({\n options: {\n plugins: [ImagePlugin, MediaEmbedPlugin],\n },\n }),\n DatePlugin,\n MentionPlugin.configure({\n options: {\n triggerPreviousCharPattern: /^$|^[\\s\"']$/,\n },\n }),\n SlashPlugin,\n TablePlugin.configure({\n options: {\n enableMerging: id === 'tableMerge',\n },\n }),\n ColumnPlugin,\n SelectionOverlayPlugin,\n\n TodoListPlugin,\n TogglePlugin,\n ExcalidrawPlugin,\n // Marks\n BoldPlugin,\n ItalicPlugin,\n UnderlinePlugin,\n StrikethroughPlugin,\n CodePlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n FontColorPlugin,\n FontBackgroundColorPlugin,\n FontSizePlugin,\n HighlightPlugin,\n KbdPlugin,\n\n // Block Style\n AlignPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n MediaEmbedPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n ImagePlugin.key,\n HEADING_KEYS.h6,\n ],\n },\n }),\n IndentPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n }),\n IndentListPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n options: {\n listStyleTypes: {\n fire: {\n liComponent: FireLiComponent,\n markerComponent: FireMarker,\n type: 'fire',\n },\n todo: {\n liComponent: TodoLi,\n markerComponent: TodoMarker,\n type: 'todo',\n },\n },\n },\n }),\n LineHeightPlugin.extend({\n inject: {\n nodeProps: {\n defaultNodeValue: 1.5,\n validNodeValues: [1, 1.2, 1.5, 2, 3],\n },\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n ],\n },\n }),\n\n // Functionality\n AutoformatPlugin.configure({\n options: autoformatOptions,\n }),\n BlockSelectionPlugin.configure({\n options: {\n areaOptions: {\n behaviour: {\n scrolling: {\n speedDivider: 1.5,\n },\n startThreshold: 10,\n },\n boundaries: `#${scrollSelector}`,\n container: `#${scrollSelector}`,\n selectables: [`#${scrollSelector} .slate-selectable`],\n selectionAreaClass: 'slate-selection-area',\n },\n enableContextMenu: true,\n },\n }),\n BlockMenuPlugin.configure({\n render: { aboveEditable: BlockContextMenu },\n }),\n DndPlugin.configure({\n options: {\n enableScroller: true,\n onDropFiles: ({ dragItem, editor, target }) => {\n editor\n .getTransforms(ImagePlugin)\n .insertImageFromFiles(dragItem.files, {\n at: target,\n nextBlock: false,\n });\n },\n },\n }),\n EmojiPlugin,\n exitBreakPlugin,\n NodeIdPlugin,\n NormalizeTypesPlugin.configure({\n options: {\n rules: [{ path: [0], strictType: HEADING_KEYS.h1 }],\n },\n }),\n resetBlockTypePlugin,\n SelectOnBackspacePlugin.configure({\n options: {\n query: {\n allow: [ImagePlugin.key, HorizontalRulePlugin.key],\n },\n },\n }),\n DeletePlugin,\n SingleLinePlugin,\n softBreakPlugin,\n tabbablePlugin,\n TrailingBlockPlugin.configure({\n options: { type: ParagraphPlugin.key },\n }),\n DragOverCursorPlugin,\n\n // Collaboration\n CommentsPlugin.configure({\n options: {\n comments: commentsData,\n myUserId: '1',\n users: usersData,\n },\n }),\n\n // Deserialization\n DocxPlugin,\n MarkdownPlugin.configure({ options: { indentList: true } }),\n JuicePlugin,\n\n // Testing\n PlaywrightPlugin.configure({\n enabled: process.env.NODE_ENV !== 'production',\n }),\n ],\n value: value,\n },\n []\n );\n};\n\nexport default function PlaygroundDemo({\n id,\n className,\n scrollSelector,\n}: {\n id?: ValueId;\n className?: string;\n scrollSelector?: string;\n}) {\n const containerRef = useRef(null);\n const enabled = settingsStore.use.checkedComponents();\n\n const editor = usePlaygroundEditor(\n id,\n scrollSelector ?? `blockSelection-${id}`\n );\n\n return (\n \n \n \n \n \n \n \n \n \n\n
\n \n \n\n \n \n \n \n \n \n \n\n \n \n \n \n\n \n \n \n
\n
\n
\n );\n}\n\nconst DemoIdContext = React.createContext(undefined);\n\nexport function DemoId({\n id,\n children,\n}: {\n children: React.ReactNode;\n id?: string;\n}) {\n return {children};\n}\n\nexport function useDemoId() {\n return React.useContext(DemoIdContext);\n}\n", + "content": "'use client';\n\nimport React, { useRef } from 'react';\n\nimport type { ValueId } from '@/config/customizer-plugins';\n\nimport { cn } from '@udecode/cn';\nimport { AIChatPlugin, CopilotPlugin } from '@udecode/plate-ai/react';\nimport { AlignPlugin } from '@udecode/plate-alignment/react';\nimport { AutoformatPlugin } from '@udecode/plate-autoformat/react';\nimport {\n BoldPlugin,\n CodePlugin,\n ItalicPlugin,\n StrikethroughPlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n UnderlinePlugin,\n} from '@udecode/plate-basic-marks/react';\nimport { BlockquotePlugin } from '@udecode/plate-block-quote/react';\nimport { SingleLinePlugin } from '@udecode/plate-break/react';\nimport { CaptionPlugin } from '@udecode/plate-caption/react';\nimport { CodeBlockPlugin } from '@udecode/plate-code-block/react';\nimport { CommentsPlugin } from '@udecode/plate-comments/react';\nimport {\n ParagraphPlugin,\n Plate,\n usePlateEditor,\n} from '@udecode/plate-common/react';\nimport { DatePlugin } from '@udecode/plate-date/react';\nimport { DndPlugin } from '@udecode/plate-dnd';\nimport { DocxPlugin } from '@udecode/plate-docx';\nimport { EmojiPlugin } from '@udecode/plate-emoji/react';\nimport { ExcalidrawPlugin } from '@udecode/plate-excalidraw/react';\nimport {\n FontBackgroundColorPlugin,\n FontColorPlugin,\n FontSizePlugin,\n} from '@udecode/plate-font/react';\nimport { HEADING_KEYS } from '@udecode/plate-heading';\nimport { HeadingPlugin, TocPlugin } from '@udecode/plate-heading/react';\nimport { HighlightPlugin } from '@udecode/plate-highlight/react';\nimport { HorizontalRulePlugin } from '@udecode/plate-horizontal-rule/react';\nimport { IndentPlugin } from '@udecode/plate-indent/react';\nimport { IndentListPlugin } from '@udecode/plate-indent-list/react';\nimport { JuicePlugin } from '@udecode/plate-juice';\nimport { KbdPlugin } from '@udecode/plate-kbd/react';\nimport { ColumnPlugin } from '@udecode/plate-layout/react';\nimport { LineHeightPlugin } from '@udecode/plate-line-height/react';\nimport { LinkPlugin } from '@udecode/plate-link/react';\nimport { ListPlugin, TodoListPlugin } from '@udecode/plate-list/react';\nimport { MarkdownPlugin } from '@udecode/plate-markdown';\nimport { BaseImagePlugin } from '@udecode/plate-media';\nimport { ImagePlugin, MediaEmbedPlugin } from '@udecode/plate-media/react';\nimport { MentionPlugin } from '@udecode/plate-mention/react';\nimport { NodeIdPlugin } from '@udecode/plate-node-id';\nimport { NormalizeTypesPlugin } from '@udecode/plate-normalizers';\nimport { PlaywrightPlugin } from '@udecode/plate-playwright';\nimport { DeletePlugin, SelectOnBackspacePlugin } from '@udecode/plate-select';\nimport {\n BlockMenuPlugin,\n BlockSelectionPlugin,\n} from '@udecode/plate-selection/react';\nimport { SlashPlugin } from '@udecode/plate-slash-command/react';\nimport { TablePlugin } from '@udecode/plate-table/react';\nimport { TogglePlugin } from '@udecode/plate-toggle/react';\nimport { TrailingBlockPlugin } from '@udecode/plate-trailing-block';\nimport Prism from 'prismjs';\n\nimport { CheckPlugin } from '@/components/context/check-plugin';\nimport { settingsStore } from '@/components/context/settings-store';\nimport { aiPlugins } from '@/lib/plate/demo/plugins/ai-plugins';\nimport { getAutoformatOptions } from '@/lib/plate/demo/plugins/autoformatOptions';\nimport { copilotPlugins } from '@/lib/plate/demo/plugins/copilot-plugins';\nimport { createPlateUI } from '@/plate/create-plate-ui';\nimport { editableProps } from '@/plate/demo/editableProps';\nimport { isEnabled } from '@/plate/demo/is-enabled';\nimport { DragOverCursorPlugin } from '@/plate/demo/plugins/DragOverCursorPlugin';\nimport { exitBreakPlugin } from '@/plate/demo/plugins/exitBreakPlugin';\nimport { resetBlockTypePlugin } from '@/plate/demo/plugins/resetBlockTypePlugin';\nimport { softBreakPlugin } from '@/plate/demo/plugins/softBreakPlugin';\nimport { tabbablePlugin } from '@/plate/demo/plugins/tabbablePlugin';\nimport { commentsData, usersData } from '@/plate/demo/values/commentsValue';\nimport { usePlaygroundValue } from '@/plate/demo/values/usePlaygroundValue';\nimport { BlockContextMenu } from '@/components/plate-ui/block-context-menu';\nimport { CommentsPopover } from '@/components/plate-ui/comments-popover';\nimport {\n CursorOverlay,\n SelectionOverlayPlugin,\n} from '@/components/plate-ui/cursor-overlay';\nimport { Editor, EditorContainer } from '@/components/plate-ui/editor';\nimport { FixedToolbar } from '@/components/plate-ui/fixed-toolbar';\nimport { FixedToolbarButtons } from '@/components/plate-ui/fixed-toolbar-buttons';\nimport { FloatingToolbar } from '@/components/plate-ui/floating-toolbar';\nimport { FloatingToolbarButtons } from '@/components/plate-ui/floating-toolbar-buttons';\nimport { ImagePreview } from '@/components/plate-ui/image-preview';\nimport {\n FireLiComponent,\n FireMarker,\n} from '@/components/plate-ui/indent-fire-marker';\nimport {\n TodoLi,\n TodoMarker,\n} from '@/components/plate-ui/indent-todo-marker';\nimport { LinkFloatingToolbar } from '@/components/plate-ui/link-floating-toolbar';\n\nimport { usePlaygroundEnabled } from './usePlaygroundEnabled';\n\nexport const usePlaygroundEditor = (id: any = '', scrollSelector?: string) => {\n const enabledPlugins = settingsStore.use.checkedPlugins();\n const overridePlugins = usePlaygroundEnabled(id);\n const autoformatOptions = getAutoformatOptions(id, enabledPlugins);\n\n const value = usePlaygroundValue(id);\n const key = settingsStore.use.version();\n const editorId = id || 'playground-' + key;\n\n return usePlateEditor(\n {\n id: editorId,\n override: {\n components: createPlateUI({\n draggable: isEnabled('dnd', id),\n placeholder: isEnabled('placeholder', id),\n }),\n plugins: overridePlugins,\n },\n plugins: [\n // AI\n ...(id === 'ai' || enabledPlugins[AIChatPlugin.key] ? aiPlugins : []),\n ...(id === 'copilot' || enabledPlugins[CopilotPlugin.key]\n ? copilotPlugins\n : []),\n // Nodes\n HeadingPlugin,\n TocPlugin.configure({\n options: {\n scrollContainerSelector: `#${scrollSelector}`,\n topOffset: 80,\n },\n }),\n BlockquotePlugin,\n CodeBlockPlugin.configure({\n options: {\n prism: Prism,\n },\n }),\n HorizontalRulePlugin,\n LinkPlugin.extend({\n render: { afterEditable: () => },\n }),\n ...(id === 'list' ? [ListPlugin] : []),\n ImagePlugin.extend({\n options: {\n disableUploadInsert: true,\n },\n render: { afterEditable: ImagePreview },\n }),\n MediaEmbedPlugin,\n CaptionPlugin.configure({\n options: {\n plugins: [ImagePlugin, MediaEmbedPlugin],\n },\n }),\n DatePlugin,\n MentionPlugin.configure({\n options: {\n triggerPreviousCharPattern: /^$|^[\\s\"']$/,\n },\n }),\n SlashPlugin,\n TablePlugin.configure({\n options: {\n enableMerging: id === 'tableMerge',\n },\n }),\n ColumnPlugin,\n SelectionOverlayPlugin,\n\n TodoListPlugin,\n TogglePlugin,\n ExcalidrawPlugin,\n // Marks\n BoldPlugin,\n ItalicPlugin,\n UnderlinePlugin,\n StrikethroughPlugin,\n CodePlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n FontColorPlugin,\n FontBackgroundColorPlugin,\n FontSizePlugin,\n HighlightPlugin,\n KbdPlugin,\n\n // Block Style\n AlignPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n MediaEmbedPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n ImagePlugin.key,\n HEADING_KEYS.h6,\n ],\n },\n }),\n IndentPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n }),\n IndentListPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n options: {\n listStyleTypes: {\n fire: {\n liComponent: FireLiComponent,\n markerComponent: FireMarker,\n type: 'fire',\n },\n todo: {\n liComponent: TodoLi,\n markerComponent: TodoMarker,\n type: 'todo',\n },\n },\n },\n }),\n LineHeightPlugin.extend({\n inject: {\n nodeProps: {\n defaultNodeValue: 1.5,\n validNodeValues: [1, 1.2, 1.5, 2, 3],\n },\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n ],\n },\n }),\n\n // Functionality\n AutoformatPlugin.configure({\n options: autoformatOptions,\n }),\n BlockSelectionPlugin.configure({\n options: {\n areaOptions: {\n behaviour: {\n scrolling: {\n speedDivider: 1.5,\n },\n startThreshold: 10,\n },\n boundaries: `#${scrollSelector}`,\n container: `#${scrollSelector}`,\n selectables: [`#${scrollSelector} .slate-selectable`],\n selectionAreaClass: 'slate-selection-area',\n },\n enableContextMenu: true,\n },\n }),\n BlockMenuPlugin.configure({\n render: { aboveEditable: BlockContextMenu },\n }),\n DndPlugin.configure({\n options: {\n enableScroller: true,\n onDropFiles: ({ dragItem, editor, target }) => {\n editor\n .getTransforms(BaseImagePlugin)\n .insert.imageFromFiles(dragItem.files, {\n at: target,\n nextBlock: false,\n });\n },\n },\n }),\n EmojiPlugin,\n exitBreakPlugin,\n NodeIdPlugin,\n NormalizeTypesPlugin.configure({\n options: {\n rules: [{ path: [0], strictType: HEADING_KEYS.h1 }],\n },\n }),\n resetBlockTypePlugin,\n SelectOnBackspacePlugin.configure({\n options: {\n query: {\n allow: [ImagePlugin.key, HorizontalRulePlugin.key],\n },\n },\n }),\n DeletePlugin,\n SingleLinePlugin,\n softBreakPlugin,\n tabbablePlugin,\n TrailingBlockPlugin.configure({\n options: { type: ParagraphPlugin.key },\n }),\n DragOverCursorPlugin,\n\n // Collaboration\n CommentsPlugin.configure({\n options: {\n comments: commentsData,\n myUserId: '1',\n users: usersData,\n },\n }),\n\n // Deserialization\n DocxPlugin,\n MarkdownPlugin.configure({ options: { indentList: true } }),\n JuicePlugin,\n\n // Testing\n PlaywrightPlugin.configure({\n enabled: process.env.NODE_ENV !== 'production',\n }),\n ],\n value: value,\n },\n []\n );\n};\n\nexport default function PlaygroundDemo({\n id,\n className,\n scrollSelector,\n}: {\n id?: ValueId;\n className?: string;\n scrollSelector?: string;\n}) {\n const containerRef = useRef(null);\n const enabled = settingsStore.use.checkedComponents();\n\n const editor = usePlaygroundEditor(\n id,\n scrollSelector ?? `blockSelection-${id}`\n );\n\n return (\n \n \n \n \n \n \n \n \n \n\n
\n \n \n\n \n \n \n \n \n \n \n\n \n \n \n \n\n \n \n \n
\n
\n
\n );\n}\n\nconst DemoIdContext = React.createContext(undefined);\n\nexport function DemoId({\n id,\n children,\n}: {\n children: React.ReactNode;\n id?: string;\n}) {\n return {children};\n}\n\nexport function useDemoId() {\n return React.useContext(DemoIdContext);\n}\n", "path": "example/playground-demo.tsx", "target": "components/playground-demo.tsx", "type": "registry:example" diff --git a/apps/www/public/r/styles/default/block-menu-demo.json b/apps/www/public/r/styles/default/block-menu-demo.json index 7f523b1d3e..e7341ac929 100644 --- a/apps/www/public/r/styles/default/block-menu-demo.json +++ b/apps/www/public/r/styles/default/block-menu-demo.json @@ -4,7 +4,7 @@ }, "files": [ { - "content": "'use client';\n\nimport React, { useRef } from 'react';\n\nimport type { ValueId } from '@/config/customizer-plugins';\n\nimport { cn } from '@udecode/cn';\nimport { AIChatPlugin, CopilotPlugin } from '@udecode/plate-ai/react';\nimport { AlignPlugin } from '@udecode/plate-alignment/react';\nimport { AutoformatPlugin } from '@udecode/plate-autoformat/react';\nimport {\n BoldPlugin,\n CodePlugin,\n ItalicPlugin,\n StrikethroughPlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n UnderlinePlugin,\n} from '@udecode/plate-basic-marks/react';\nimport { BlockquotePlugin } from '@udecode/plate-block-quote/react';\nimport { SingleLinePlugin } from '@udecode/plate-break/react';\nimport { CaptionPlugin } from '@udecode/plate-caption/react';\nimport { CodeBlockPlugin } from '@udecode/plate-code-block/react';\nimport { CommentsPlugin } from '@udecode/plate-comments/react';\nimport {\n ParagraphPlugin,\n Plate,\n usePlateEditor,\n} from '@udecode/plate-common/react';\nimport { DatePlugin } from '@udecode/plate-date/react';\nimport { DndPlugin } from '@udecode/plate-dnd';\nimport { DocxPlugin } from '@udecode/plate-docx';\nimport { EmojiPlugin } from '@udecode/plate-emoji/react';\nimport { ExcalidrawPlugin } from '@udecode/plate-excalidraw/react';\nimport {\n FontBackgroundColorPlugin,\n FontColorPlugin,\n FontSizePlugin,\n} from '@udecode/plate-font/react';\nimport { HEADING_KEYS } from '@udecode/plate-heading';\nimport { HeadingPlugin, TocPlugin } from '@udecode/plate-heading/react';\nimport { HighlightPlugin } from '@udecode/plate-highlight/react';\nimport { HorizontalRulePlugin } from '@udecode/plate-horizontal-rule/react';\nimport { IndentPlugin } from '@udecode/plate-indent/react';\nimport { IndentListPlugin } from '@udecode/plate-indent-list/react';\nimport { JuicePlugin } from '@udecode/plate-juice';\nimport { KbdPlugin } from '@udecode/plate-kbd/react';\nimport { ColumnPlugin } from '@udecode/plate-layout/react';\nimport { LineHeightPlugin } from '@udecode/plate-line-height/react';\nimport { LinkPlugin } from '@udecode/plate-link/react';\nimport { ListPlugin, TodoListPlugin } from '@udecode/plate-list/react';\nimport { MarkdownPlugin } from '@udecode/plate-markdown';\nimport { ImagePlugin, MediaEmbedPlugin } from '@udecode/plate-media/react';\nimport { MentionPlugin } from '@udecode/plate-mention/react';\nimport { NodeIdPlugin } from '@udecode/plate-node-id';\nimport { NormalizeTypesPlugin } from '@udecode/plate-normalizers';\nimport { PlaywrightPlugin } from '@udecode/plate-playwright';\nimport { DeletePlugin, SelectOnBackspacePlugin } from '@udecode/plate-select';\nimport {\n BlockMenuPlugin,\n BlockSelectionPlugin,\n} from '@udecode/plate-selection/react';\nimport { SlashPlugin } from '@udecode/plate-slash-command/react';\nimport { TablePlugin } from '@udecode/plate-table/react';\nimport { TogglePlugin } from '@udecode/plate-toggle/react';\nimport { TrailingBlockPlugin } from '@udecode/plate-trailing-block';\nimport Prism from 'prismjs';\n\nimport { CheckPlugin } from '@/components/context/check-plugin';\nimport { settingsStore } from '@/components/context/settings-store';\nimport { aiPlugins } from '@/lib/plate/demo/plugins/ai-plugins';\nimport { getAutoformatOptions } from '@/lib/plate/demo/plugins/autoformatOptions';\nimport { copilotPlugins } from '@/lib/plate/demo/plugins/copilot-plugins';\nimport { createPlateUI } from '@/plate/create-plate-ui';\nimport { editableProps } from '@/plate/demo/editableProps';\nimport { isEnabled } from '@/plate/demo/is-enabled';\nimport { DragOverCursorPlugin } from '@/plate/demo/plugins/DragOverCursorPlugin';\nimport { exitBreakPlugin } from '@/plate/demo/plugins/exitBreakPlugin';\nimport { resetBlockTypePlugin } from '@/plate/demo/plugins/resetBlockTypePlugin';\nimport { softBreakPlugin } from '@/plate/demo/plugins/softBreakPlugin';\nimport { tabbablePlugin } from '@/plate/demo/plugins/tabbablePlugin';\nimport { commentsData, usersData } from '@/plate/demo/values/commentsValue';\nimport { usePlaygroundValue } from '@/plate/demo/values/usePlaygroundValue';\nimport { BlockContextMenu } from '@/components/plate-ui/block-context-menu';\nimport { CommentsPopover } from '@/components/plate-ui/comments-popover';\nimport {\n CursorOverlay,\n SelectionOverlayPlugin,\n} from '@/components/plate-ui/cursor-overlay';\nimport { Editor, EditorContainer } from '@/components/plate-ui/editor';\nimport { FixedToolbar } from '@/components/plate-ui/fixed-toolbar';\nimport { FixedToolbarButtons } from '@/components/plate-ui/fixed-toolbar-buttons';\nimport { FloatingToolbar } from '@/components/plate-ui/floating-toolbar';\nimport { FloatingToolbarButtons } from '@/components/plate-ui/floating-toolbar-buttons';\nimport { ImagePreview } from '@/components/plate-ui/image-preview';\nimport {\n FireLiComponent,\n FireMarker,\n} from '@/components/plate-ui/indent-fire-marker';\nimport {\n TodoLi,\n TodoMarker,\n} from '@/components/plate-ui/indent-todo-marker';\nimport { LinkFloatingToolbar } from '@/components/plate-ui/link-floating-toolbar';\n\nimport { usePlaygroundEnabled } from './usePlaygroundEnabled';\n\nexport const usePlaygroundEditor = (id: any = '', scrollSelector?: string) => {\n const enabledPlugins = settingsStore.use.checkedPlugins();\n const overridePlugins = usePlaygroundEnabled(id);\n const autoformatOptions = getAutoformatOptions(id, enabledPlugins);\n\n const value = usePlaygroundValue(id);\n const key = settingsStore.use.version();\n const editorId = id || 'playground-' + key;\n\n return usePlateEditor(\n {\n id: editorId,\n override: {\n components: createPlateUI({\n draggable: isEnabled('dnd', id),\n placeholder: isEnabled('placeholder', id),\n }),\n plugins: overridePlugins,\n },\n plugins: [\n // AI\n ...(id === 'ai' || enabledPlugins[AIChatPlugin.key] ? aiPlugins : []),\n ...(id === 'copilot' || enabledPlugins[CopilotPlugin.key]\n ? copilotPlugins\n : []),\n // Nodes\n HeadingPlugin,\n TocPlugin.configure({\n options: {\n scrollContainerSelector: `#${scrollSelector}`,\n topOffset: 80,\n },\n }),\n BlockquotePlugin,\n CodeBlockPlugin.configure({\n options: {\n prism: Prism,\n },\n }),\n HorizontalRulePlugin,\n LinkPlugin.extend({\n render: { afterEditable: () => },\n }),\n ...(id === 'list' ? [ListPlugin] : []),\n ImagePlugin.extend({\n options: {\n disableUploadInsert: true,\n },\n render: { afterEditable: ImagePreview },\n }),\n MediaEmbedPlugin,\n CaptionPlugin.configure({\n options: {\n plugins: [ImagePlugin, MediaEmbedPlugin],\n },\n }),\n DatePlugin,\n MentionPlugin.configure({\n options: {\n triggerPreviousCharPattern: /^$|^[\\s\"']$/,\n },\n }),\n SlashPlugin,\n TablePlugin.configure({\n options: {\n enableMerging: id === 'tableMerge',\n },\n }),\n ColumnPlugin,\n SelectionOverlayPlugin,\n\n TodoListPlugin,\n TogglePlugin,\n ExcalidrawPlugin,\n // Marks\n BoldPlugin,\n ItalicPlugin,\n UnderlinePlugin,\n StrikethroughPlugin,\n CodePlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n FontColorPlugin,\n FontBackgroundColorPlugin,\n FontSizePlugin,\n HighlightPlugin,\n KbdPlugin,\n\n // Block Style\n AlignPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n MediaEmbedPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n ImagePlugin.key,\n HEADING_KEYS.h6,\n ],\n },\n }),\n IndentPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n }),\n IndentListPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n options: {\n listStyleTypes: {\n fire: {\n liComponent: FireLiComponent,\n markerComponent: FireMarker,\n type: 'fire',\n },\n todo: {\n liComponent: TodoLi,\n markerComponent: TodoMarker,\n type: 'todo',\n },\n },\n },\n }),\n LineHeightPlugin.extend({\n inject: {\n nodeProps: {\n defaultNodeValue: 1.5,\n validNodeValues: [1, 1.2, 1.5, 2, 3],\n },\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n ],\n },\n }),\n\n // Functionality\n AutoformatPlugin.configure({\n options: autoformatOptions,\n }),\n BlockSelectionPlugin.configure({\n options: {\n areaOptions: {\n behaviour: {\n scrolling: {\n speedDivider: 1.5,\n },\n startThreshold: 10,\n },\n boundaries: `#${scrollSelector}`,\n container: `#${scrollSelector}`,\n selectables: [`#${scrollSelector} .slate-selectable`],\n selectionAreaClass: 'slate-selection-area',\n },\n enableContextMenu: true,\n },\n }),\n BlockMenuPlugin.configure({\n render: { aboveEditable: BlockContextMenu },\n }),\n DndPlugin.configure({\n options: {\n enableScroller: true,\n onDropFiles: ({ dragItem, editor, target }) => {\n editor\n .getTransforms(ImagePlugin)\n .insertImageFromFiles(dragItem.files, {\n at: target,\n nextBlock: false,\n });\n },\n },\n }),\n EmojiPlugin,\n exitBreakPlugin,\n NodeIdPlugin,\n NormalizeTypesPlugin.configure({\n options: {\n rules: [{ path: [0], strictType: HEADING_KEYS.h1 }],\n },\n }),\n resetBlockTypePlugin,\n SelectOnBackspacePlugin.configure({\n options: {\n query: {\n allow: [ImagePlugin.key, HorizontalRulePlugin.key],\n },\n },\n }),\n DeletePlugin,\n SingleLinePlugin,\n softBreakPlugin,\n tabbablePlugin,\n TrailingBlockPlugin.configure({\n options: { type: ParagraphPlugin.key },\n }),\n DragOverCursorPlugin,\n\n // Collaboration\n CommentsPlugin.configure({\n options: {\n comments: commentsData,\n myUserId: '1',\n users: usersData,\n },\n }),\n\n // Deserialization\n DocxPlugin,\n MarkdownPlugin.configure({ options: { indentList: true } }),\n JuicePlugin,\n\n // Testing\n PlaywrightPlugin.configure({\n enabled: process.env.NODE_ENV !== 'production',\n }),\n ],\n value: value,\n },\n []\n );\n};\n\nexport default function PlaygroundDemo({\n id,\n className,\n scrollSelector,\n}: {\n id?: ValueId;\n className?: string;\n scrollSelector?: string;\n}) {\n const containerRef = useRef(null);\n const enabled = settingsStore.use.checkedComponents();\n\n const editor = usePlaygroundEditor(\n id,\n scrollSelector ?? `blockSelection-${id}`\n );\n\n return (\n \n \n \n \n \n \n \n \n \n\n
\n \n \n\n \n \n \n \n \n \n \n\n \n \n \n \n\n \n \n \n
\n
\n
\n );\n}\n\nconst DemoIdContext = React.createContext(undefined);\n\nexport function DemoId({\n id,\n children,\n}: {\n children: React.ReactNode;\n id?: string;\n}) {\n return {children};\n}\n\nexport function useDemoId() {\n return React.useContext(DemoIdContext);\n}\n", + "content": "'use client';\n\nimport React, { useRef } from 'react';\n\nimport type { ValueId } from '@/config/customizer-plugins';\n\nimport { cn } from '@udecode/cn';\nimport { AIChatPlugin, CopilotPlugin } from '@udecode/plate-ai/react';\nimport { AlignPlugin } from '@udecode/plate-alignment/react';\nimport { AutoformatPlugin } from '@udecode/plate-autoformat/react';\nimport {\n BoldPlugin,\n CodePlugin,\n ItalicPlugin,\n StrikethroughPlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n UnderlinePlugin,\n} from '@udecode/plate-basic-marks/react';\nimport { BlockquotePlugin } from '@udecode/plate-block-quote/react';\nimport { SingleLinePlugin } from '@udecode/plate-break/react';\nimport { CaptionPlugin } from '@udecode/plate-caption/react';\nimport { CodeBlockPlugin } from '@udecode/plate-code-block/react';\nimport { CommentsPlugin } from '@udecode/plate-comments/react';\nimport {\n ParagraphPlugin,\n Plate,\n usePlateEditor,\n} from '@udecode/plate-common/react';\nimport { DatePlugin } from '@udecode/plate-date/react';\nimport { DndPlugin } from '@udecode/plate-dnd';\nimport { DocxPlugin } from '@udecode/plate-docx';\nimport { EmojiPlugin } from '@udecode/plate-emoji/react';\nimport { ExcalidrawPlugin } from '@udecode/plate-excalidraw/react';\nimport {\n FontBackgroundColorPlugin,\n FontColorPlugin,\n FontSizePlugin,\n} from '@udecode/plate-font/react';\nimport { HEADING_KEYS } from '@udecode/plate-heading';\nimport { HeadingPlugin, TocPlugin } from '@udecode/plate-heading/react';\nimport { HighlightPlugin } from '@udecode/plate-highlight/react';\nimport { HorizontalRulePlugin } from '@udecode/plate-horizontal-rule/react';\nimport { IndentPlugin } from '@udecode/plate-indent/react';\nimport { IndentListPlugin } from '@udecode/plate-indent-list/react';\nimport { JuicePlugin } from '@udecode/plate-juice';\nimport { KbdPlugin } from '@udecode/plate-kbd/react';\nimport { ColumnPlugin } from '@udecode/plate-layout/react';\nimport { LineHeightPlugin } from '@udecode/plate-line-height/react';\nimport { LinkPlugin } from '@udecode/plate-link/react';\nimport { ListPlugin, TodoListPlugin } from '@udecode/plate-list/react';\nimport { MarkdownPlugin } from '@udecode/plate-markdown';\nimport { BaseImagePlugin } from '@udecode/plate-media';\nimport { ImagePlugin, MediaEmbedPlugin } from '@udecode/plate-media/react';\nimport { MentionPlugin } from '@udecode/plate-mention/react';\nimport { NodeIdPlugin } from '@udecode/plate-node-id';\nimport { NormalizeTypesPlugin } from '@udecode/plate-normalizers';\nimport { PlaywrightPlugin } from '@udecode/plate-playwright';\nimport { DeletePlugin, SelectOnBackspacePlugin } from '@udecode/plate-select';\nimport {\n BlockMenuPlugin,\n BlockSelectionPlugin,\n} from '@udecode/plate-selection/react';\nimport { SlashPlugin } from '@udecode/plate-slash-command/react';\nimport { TablePlugin } from '@udecode/plate-table/react';\nimport { TogglePlugin } from '@udecode/plate-toggle/react';\nimport { TrailingBlockPlugin } from '@udecode/plate-trailing-block';\nimport Prism from 'prismjs';\n\nimport { CheckPlugin } from '@/components/context/check-plugin';\nimport { settingsStore } from '@/components/context/settings-store';\nimport { aiPlugins } from '@/lib/plate/demo/plugins/ai-plugins';\nimport { getAutoformatOptions } from '@/lib/plate/demo/plugins/autoformatOptions';\nimport { copilotPlugins } from '@/lib/plate/demo/plugins/copilot-plugins';\nimport { createPlateUI } from '@/plate/create-plate-ui';\nimport { editableProps } from '@/plate/demo/editableProps';\nimport { isEnabled } from '@/plate/demo/is-enabled';\nimport { DragOverCursorPlugin } from '@/plate/demo/plugins/DragOverCursorPlugin';\nimport { exitBreakPlugin } from '@/plate/demo/plugins/exitBreakPlugin';\nimport { resetBlockTypePlugin } from '@/plate/demo/plugins/resetBlockTypePlugin';\nimport { softBreakPlugin } from '@/plate/demo/plugins/softBreakPlugin';\nimport { tabbablePlugin } from '@/plate/demo/plugins/tabbablePlugin';\nimport { commentsData, usersData } from '@/plate/demo/values/commentsValue';\nimport { usePlaygroundValue } from '@/plate/demo/values/usePlaygroundValue';\nimport { BlockContextMenu } from '@/components/plate-ui/block-context-menu';\nimport { CommentsPopover } from '@/components/plate-ui/comments-popover';\nimport {\n CursorOverlay,\n SelectionOverlayPlugin,\n} from '@/components/plate-ui/cursor-overlay';\nimport { Editor, EditorContainer } from '@/components/plate-ui/editor';\nimport { FixedToolbar } from '@/components/plate-ui/fixed-toolbar';\nimport { FixedToolbarButtons } from '@/components/plate-ui/fixed-toolbar-buttons';\nimport { FloatingToolbar } from '@/components/plate-ui/floating-toolbar';\nimport { FloatingToolbarButtons } from '@/components/plate-ui/floating-toolbar-buttons';\nimport { ImagePreview } from '@/components/plate-ui/image-preview';\nimport {\n FireLiComponent,\n FireMarker,\n} from '@/components/plate-ui/indent-fire-marker';\nimport {\n TodoLi,\n TodoMarker,\n} from '@/components/plate-ui/indent-todo-marker';\nimport { LinkFloatingToolbar } from '@/components/plate-ui/link-floating-toolbar';\n\nimport { usePlaygroundEnabled } from './usePlaygroundEnabled';\n\nexport const usePlaygroundEditor = (id: any = '', scrollSelector?: string) => {\n const enabledPlugins = settingsStore.use.checkedPlugins();\n const overridePlugins = usePlaygroundEnabled(id);\n const autoformatOptions = getAutoformatOptions(id, enabledPlugins);\n\n const value = usePlaygroundValue(id);\n const key = settingsStore.use.version();\n const editorId = id || 'playground-' + key;\n\n return usePlateEditor(\n {\n id: editorId,\n override: {\n components: createPlateUI({\n draggable: isEnabled('dnd', id),\n placeholder: isEnabled('placeholder', id),\n }),\n plugins: overridePlugins,\n },\n plugins: [\n // AI\n ...(id === 'ai' || enabledPlugins[AIChatPlugin.key] ? aiPlugins : []),\n ...(id === 'copilot' || enabledPlugins[CopilotPlugin.key]\n ? copilotPlugins\n : []),\n // Nodes\n HeadingPlugin,\n TocPlugin.configure({\n options: {\n scrollContainerSelector: `#${scrollSelector}`,\n topOffset: 80,\n },\n }),\n BlockquotePlugin,\n CodeBlockPlugin.configure({\n options: {\n prism: Prism,\n },\n }),\n HorizontalRulePlugin,\n LinkPlugin.extend({\n render: { afterEditable: () => },\n }),\n ...(id === 'list' ? [ListPlugin] : []),\n ImagePlugin.extend({\n options: {\n disableUploadInsert: true,\n },\n render: { afterEditable: ImagePreview },\n }),\n MediaEmbedPlugin,\n CaptionPlugin.configure({\n options: {\n plugins: [ImagePlugin, MediaEmbedPlugin],\n },\n }),\n DatePlugin,\n MentionPlugin.configure({\n options: {\n triggerPreviousCharPattern: /^$|^[\\s\"']$/,\n },\n }),\n SlashPlugin,\n TablePlugin.configure({\n options: {\n enableMerging: id === 'tableMerge',\n },\n }),\n ColumnPlugin,\n SelectionOverlayPlugin,\n\n TodoListPlugin,\n TogglePlugin,\n ExcalidrawPlugin,\n // Marks\n BoldPlugin,\n ItalicPlugin,\n UnderlinePlugin,\n StrikethroughPlugin,\n CodePlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n FontColorPlugin,\n FontBackgroundColorPlugin,\n FontSizePlugin,\n HighlightPlugin,\n KbdPlugin,\n\n // Block Style\n AlignPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n MediaEmbedPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n ImagePlugin.key,\n HEADING_KEYS.h6,\n ],\n },\n }),\n IndentPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n }),\n IndentListPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n options: {\n listStyleTypes: {\n fire: {\n liComponent: FireLiComponent,\n markerComponent: FireMarker,\n type: 'fire',\n },\n todo: {\n liComponent: TodoLi,\n markerComponent: TodoMarker,\n type: 'todo',\n },\n },\n },\n }),\n LineHeightPlugin.extend({\n inject: {\n nodeProps: {\n defaultNodeValue: 1.5,\n validNodeValues: [1, 1.2, 1.5, 2, 3],\n },\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n ],\n },\n }),\n\n // Functionality\n AutoformatPlugin.configure({\n options: autoformatOptions,\n }),\n BlockSelectionPlugin.configure({\n options: {\n areaOptions: {\n behaviour: {\n scrolling: {\n speedDivider: 1.5,\n },\n startThreshold: 10,\n },\n boundaries: `#${scrollSelector}`,\n container: `#${scrollSelector}`,\n selectables: [`#${scrollSelector} .slate-selectable`],\n selectionAreaClass: 'slate-selection-area',\n },\n enableContextMenu: true,\n },\n }),\n BlockMenuPlugin.configure({\n render: { aboveEditable: BlockContextMenu },\n }),\n DndPlugin.configure({\n options: {\n enableScroller: true,\n onDropFiles: ({ dragItem, editor, target }) => {\n editor\n .getTransforms(BaseImagePlugin)\n .insert.imageFromFiles(dragItem.files, {\n at: target,\n nextBlock: false,\n });\n },\n },\n }),\n EmojiPlugin,\n exitBreakPlugin,\n NodeIdPlugin,\n NormalizeTypesPlugin.configure({\n options: {\n rules: [{ path: [0], strictType: HEADING_KEYS.h1 }],\n },\n }),\n resetBlockTypePlugin,\n SelectOnBackspacePlugin.configure({\n options: {\n query: {\n allow: [ImagePlugin.key, HorizontalRulePlugin.key],\n },\n },\n }),\n DeletePlugin,\n SingleLinePlugin,\n softBreakPlugin,\n tabbablePlugin,\n TrailingBlockPlugin.configure({\n options: { type: ParagraphPlugin.key },\n }),\n DragOverCursorPlugin,\n\n // Collaboration\n CommentsPlugin.configure({\n options: {\n comments: commentsData,\n myUserId: '1',\n users: usersData,\n },\n }),\n\n // Deserialization\n DocxPlugin,\n MarkdownPlugin.configure({ options: { indentList: true } }),\n JuicePlugin,\n\n // Testing\n PlaywrightPlugin.configure({\n enabled: process.env.NODE_ENV !== 'production',\n }),\n ],\n value: value,\n },\n []\n );\n};\n\nexport default function PlaygroundDemo({\n id,\n className,\n scrollSelector,\n}: {\n id?: ValueId;\n className?: string;\n scrollSelector?: string;\n}) {\n const containerRef = useRef(null);\n const enabled = settingsStore.use.checkedComponents();\n\n const editor = usePlaygroundEditor(\n id,\n scrollSelector ?? `blockSelection-${id}`\n );\n\n return (\n \n \n \n \n \n \n \n \n \n\n
\n \n \n\n \n \n \n \n \n \n \n\n \n \n \n \n\n \n \n \n
\n
\n
\n );\n}\n\nconst DemoIdContext = React.createContext(undefined);\n\nexport function DemoId({\n id,\n children,\n}: {\n children: React.ReactNode;\n id?: string;\n}) {\n return {children};\n}\n\nexport function useDemoId() {\n return React.useContext(DemoIdContext);\n}\n", "path": "example/playground-demo.tsx", "target": "components/playground-demo.tsx", "type": "registry:example" diff --git a/apps/www/public/r/styles/default/block-selection-demo.json b/apps/www/public/r/styles/default/block-selection-demo.json index ac573d5563..0b02d31b7d 100644 --- a/apps/www/public/r/styles/default/block-selection-demo.json +++ b/apps/www/public/r/styles/default/block-selection-demo.json @@ -4,7 +4,7 @@ }, "files": [ { - "content": "'use client';\n\nimport React, { useRef } from 'react';\n\nimport type { ValueId } from '@/config/customizer-plugins';\n\nimport { cn } from '@udecode/cn';\nimport { AIChatPlugin, CopilotPlugin } from '@udecode/plate-ai/react';\nimport { AlignPlugin } from '@udecode/plate-alignment/react';\nimport { AutoformatPlugin } from '@udecode/plate-autoformat/react';\nimport {\n BoldPlugin,\n CodePlugin,\n ItalicPlugin,\n StrikethroughPlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n UnderlinePlugin,\n} from '@udecode/plate-basic-marks/react';\nimport { BlockquotePlugin } from '@udecode/plate-block-quote/react';\nimport { SingleLinePlugin } from '@udecode/plate-break/react';\nimport { CaptionPlugin } from '@udecode/plate-caption/react';\nimport { CodeBlockPlugin } from '@udecode/plate-code-block/react';\nimport { CommentsPlugin } from '@udecode/plate-comments/react';\nimport {\n ParagraphPlugin,\n Plate,\n usePlateEditor,\n} from '@udecode/plate-common/react';\nimport { DatePlugin } from '@udecode/plate-date/react';\nimport { DndPlugin } from '@udecode/plate-dnd';\nimport { DocxPlugin } from '@udecode/plate-docx';\nimport { EmojiPlugin } from '@udecode/plate-emoji/react';\nimport { ExcalidrawPlugin } from '@udecode/plate-excalidraw/react';\nimport {\n FontBackgroundColorPlugin,\n FontColorPlugin,\n FontSizePlugin,\n} from '@udecode/plate-font/react';\nimport { HEADING_KEYS } from '@udecode/plate-heading';\nimport { HeadingPlugin, TocPlugin } from '@udecode/plate-heading/react';\nimport { HighlightPlugin } from '@udecode/plate-highlight/react';\nimport { HorizontalRulePlugin } from '@udecode/plate-horizontal-rule/react';\nimport { IndentPlugin } from '@udecode/plate-indent/react';\nimport { IndentListPlugin } from '@udecode/plate-indent-list/react';\nimport { JuicePlugin } from '@udecode/plate-juice';\nimport { KbdPlugin } from '@udecode/plate-kbd/react';\nimport { ColumnPlugin } from '@udecode/plate-layout/react';\nimport { LineHeightPlugin } from '@udecode/plate-line-height/react';\nimport { LinkPlugin } from '@udecode/plate-link/react';\nimport { ListPlugin, TodoListPlugin } from '@udecode/plate-list/react';\nimport { MarkdownPlugin } from '@udecode/plate-markdown';\nimport { ImagePlugin, MediaEmbedPlugin } from '@udecode/plate-media/react';\nimport { MentionPlugin } from '@udecode/plate-mention/react';\nimport { NodeIdPlugin } from '@udecode/plate-node-id';\nimport { NormalizeTypesPlugin } from '@udecode/plate-normalizers';\nimport { PlaywrightPlugin } from '@udecode/plate-playwright';\nimport { DeletePlugin, SelectOnBackspacePlugin } from '@udecode/plate-select';\nimport {\n BlockMenuPlugin,\n BlockSelectionPlugin,\n} from '@udecode/plate-selection/react';\nimport { SlashPlugin } from '@udecode/plate-slash-command/react';\nimport { TablePlugin } from '@udecode/plate-table/react';\nimport { TogglePlugin } from '@udecode/plate-toggle/react';\nimport { TrailingBlockPlugin } from '@udecode/plate-trailing-block';\nimport Prism from 'prismjs';\n\nimport { CheckPlugin } from '@/components/context/check-plugin';\nimport { settingsStore } from '@/components/context/settings-store';\nimport { aiPlugins } from '@/lib/plate/demo/plugins/ai-plugins';\nimport { getAutoformatOptions } from '@/lib/plate/demo/plugins/autoformatOptions';\nimport { copilotPlugins } from '@/lib/plate/demo/plugins/copilot-plugins';\nimport { createPlateUI } from '@/plate/create-plate-ui';\nimport { editableProps } from '@/plate/demo/editableProps';\nimport { isEnabled } from '@/plate/demo/is-enabled';\nimport { DragOverCursorPlugin } from '@/plate/demo/plugins/DragOverCursorPlugin';\nimport { exitBreakPlugin } from '@/plate/demo/plugins/exitBreakPlugin';\nimport { resetBlockTypePlugin } from '@/plate/demo/plugins/resetBlockTypePlugin';\nimport { softBreakPlugin } from '@/plate/demo/plugins/softBreakPlugin';\nimport { tabbablePlugin } from '@/plate/demo/plugins/tabbablePlugin';\nimport { commentsData, usersData } from '@/plate/demo/values/commentsValue';\nimport { usePlaygroundValue } from '@/plate/demo/values/usePlaygroundValue';\nimport { BlockContextMenu } from '@/components/plate-ui/block-context-menu';\nimport { CommentsPopover } from '@/components/plate-ui/comments-popover';\nimport {\n CursorOverlay,\n SelectionOverlayPlugin,\n} from '@/components/plate-ui/cursor-overlay';\nimport { Editor, EditorContainer } from '@/components/plate-ui/editor';\nimport { FixedToolbar } from '@/components/plate-ui/fixed-toolbar';\nimport { FixedToolbarButtons } from '@/components/plate-ui/fixed-toolbar-buttons';\nimport { FloatingToolbar } from '@/components/plate-ui/floating-toolbar';\nimport { FloatingToolbarButtons } from '@/components/plate-ui/floating-toolbar-buttons';\nimport { ImagePreview } from '@/components/plate-ui/image-preview';\nimport {\n FireLiComponent,\n FireMarker,\n} from '@/components/plate-ui/indent-fire-marker';\nimport {\n TodoLi,\n TodoMarker,\n} from '@/components/plate-ui/indent-todo-marker';\nimport { LinkFloatingToolbar } from '@/components/plate-ui/link-floating-toolbar';\n\nimport { usePlaygroundEnabled } from './usePlaygroundEnabled';\n\nexport const usePlaygroundEditor = (id: any = '', scrollSelector?: string) => {\n const enabledPlugins = settingsStore.use.checkedPlugins();\n const overridePlugins = usePlaygroundEnabled(id);\n const autoformatOptions = getAutoformatOptions(id, enabledPlugins);\n\n const value = usePlaygroundValue(id);\n const key = settingsStore.use.version();\n const editorId = id || 'playground-' + key;\n\n return usePlateEditor(\n {\n id: editorId,\n override: {\n components: createPlateUI({\n draggable: isEnabled('dnd', id),\n placeholder: isEnabled('placeholder', id),\n }),\n plugins: overridePlugins,\n },\n plugins: [\n // AI\n ...(id === 'ai' || enabledPlugins[AIChatPlugin.key] ? aiPlugins : []),\n ...(id === 'copilot' || enabledPlugins[CopilotPlugin.key]\n ? copilotPlugins\n : []),\n // Nodes\n HeadingPlugin,\n TocPlugin.configure({\n options: {\n scrollContainerSelector: `#${scrollSelector}`,\n topOffset: 80,\n },\n }),\n BlockquotePlugin,\n CodeBlockPlugin.configure({\n options: {\n prism: Prism,\n },\n }),\n HorizontalRulePlugin,\n LinkPlugin.extend({\n render: { afterEditable: () => },\n }),\n ...(id === 'list' ? [ListPlugin] : []),\n ImagePlugin.extend({\n options: {\n disableUploadInsert: true,\n },\n render: { afterEditable: ImagePreview },\n }),\n MediaEmbedPlugin,\n CaptionPlugin.configure({\n options: {\n plugins: [ImagePlugin, MediaEmbedPlugin],\n },\n }),\n DatePlugin,\n MentionPlugin.configure({\n options: {\n triggerPreviousCharPattern: /^$|^[\\s\"']$/,\n },\n }),\n SlashPlugin,\n TablePlugin.configure({\n options: {\n enableMerging: id === 'tableMerge',\n },\n }),\n ColumnPlugin,\n SelectionOverlayPlugin,\n\n TodoListPlugin,\n TogglePlugin,\n ExcalidrawPlugin,\n // Marks\n BoldPlugin,\n ItalicPlugin,\n UnderlinePlugin,\n StrikethroughPlugin,\n CodePlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n FontColorPlugin,\n FontBackgroundColorPlugin,\n FontSizePlugin,\n HighlightPlugin,\n KbdPlugin,\n\n // Block Style\n AlignPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n MediaEmbedPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n ImagePlugin.key,\n HEADING_KEYS.h6,\n ],\n },\n }),\n IndentPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n }),\n IndentListPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n options: {\n listStyleTypes: {\n fire: {\n liComponent: FireLiComponent,\n markerComponent: FireMarker,\n type: 'fire',\n },\n todo: {\n liComponent: TodoLi,\n markerComponent: TodoMarker,\n type: 'todo',\n },\n },\n },\n }),\n LineHeightPlugin.extend({\n inject: {\n nodeProps: {\n defaultNodeValue: 1.5,\n validNodeValues: [1, 1.2, 1.5, 2, 3],\n },\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n ],\n },\n }),\n\n // Functionality\n AutoformatPlugin.configure({\n options: autoformatOptions,\n }),\n BlockSelectionPlugin.configure({\n options: {\n areaOptions: {\n behaviour: {\n scrolling: {\n speedDivider: 1.5,\n },\n startThreshold: 10,\n },\n boundaries: `#${scrollSelector}`,\n container: `#${scrollSelector}`,\n selectables: [`#${scrollSelector} .slate-selectable`],\n selectionAreaClass: 'slate-selection-area',\n },\n enableContextMenu: true,\n },\n }),\n BlockMenuPlugin.configure({\n render: { aboveEditable: BlockContextMenu },\n }),\n DndPlugin.configure({\n options: {\n enableScroller: true,\n onDropFiles: ({ dragItem, editor, target }) => {\n editor\n .getTransforms(ImagePlugin)\n .insertImageFromFiles(dragItem.files, {\n at: target,\n nextBlock: false,\n });\n },\n },\n }),\n EmojiPlugin,\n exitBreakPlugin,\n NodeIdPlugin,\n NormalizeTypesPlugin.configure({\n options: {\n rules: [{ path: [0], strictType: HEADING_KEYS.h1 }],\n },\n }),\n resetBlockTypePlugin,\n SelectOnBackspacePlugin.configure({\n options: {\n query: {\n allow: [ImagePlugin.key, HorizontalRulePlugin.key],\n },\n },\n }),\n DeletePlugin,\n SingleLinePlugin,\n softBreakPlugin,\n tabbablePlugin,\n TrailingBlockPlugin.configure({\n options: { type: ParagraphPlugin.key },\n }),\n DragOverCursorPlugin,\n\n // Collaboration\n CommentsPlugin.configure({\n options: {\n comments: commentsData,\n myUserId: '1',\n users: usersData,\n },\n }),\n\n // Deserialization\n DocxPlugin,\n MarkdownPlugin.configure({ options: { indentList: true } }),\n JuicePlugin,\n\n // Testing\n PlaywrightPlugin.configure({\n enabled: process.env.NODE_ENV !== 'production',\n }),\n ],\n value: value,\n },\n []\n );\n};\n\nexport default function PlaygroundDemo({\n id,\n className,\n scrollSelector,\n}: {\n id?: ValueId;\n className?: string;\n scrollSelector?: string;\n}) {\n const containerRef = useRef(null);\n const enabled = settingsStore.use.checkedComponents();\n\n const editor = usePlaygroundEditor(\n id,\n scrollSelector ?? `blockSelection-${id}`\n );\n\n return (\n \n \n \n \n \n \n \n \n \n\n
\n \n \n\n \n \n \n \n \n \n \n\n \n \n \n \n\n \n \n \n
\n
\n
\n );\n}\n\nconst DemoIdContext = React.createContext(undefined);\n\nexport function DemoId({\n id,\n children,\n}: {\n children: React.ReactNode;\n id?: string;\n}) {\n return {children};\n}\n\nexport function useDemoId() {\n return React.useContext(DemoIdContext);\n}\n", + "content": "'use client';\n\nimport React, { useRef } from 'react';\n\nimport type { ValueId } from '@/config/customizer-plugins';\n\nimport { cn } from '@udecode/cn';\nimport { AIChatPlugin, CopilotPlugin } from '@udecode/plate-ai/react';\nimport { AlignPlugin } from '@udecode/plate-alignment/react';\nimport { AutoformatPlugin } from '@udecode/plate-autoformat/react';\nimport {\n BoldPlugin,\n CodePlugin,\n ItalicPlugin,\n StrikethroughPlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n UnderlinePlugin,\n} from '@udecode/plate-basic-marks/react';\nimport { BlockquotePlugin } from '@udecode/plate-block-quote/react';\nimport { SingleLinePlugin } from '@udecode/plate-break/react';\nimport { CaptionPlugin } from '@udecode/plate-caption/react';\nimport { CodeBlockPlugin } from '@udecode/plate-code-block/react';\nimport { CommentsPlugin } from '@udecode/plate-comments/react';\nimport {\n ParagraphPlugin,\n Plate,\n usePlateEditor,\n} from '@udecode/plate-common/react';\nimport { DatePlugin } from '@udecode/plate-date/react';\nimport { DndPlugin } from '@udecode/plate-dnd';\nimport { DocxPlugin } from '@udecode/plate-docx';\nimport { EmojiPlugin } from '@udecode/plate-emoji/react';\nimport { ExcalidrawPlugin } from '@udecode/plate-excalidraw/react';\nimport {\n FontBackgroundColorPlugin,\n FontColorPlugin,\n FontSizePlugin,\n} from '@udecode/plate-font/react';\nimport { HEADING_KEYS } from '@udecode/plate-heading';\nimport { HeadingPlugin, TocPlugin } from '@udecode/plate-heading/react';\nimport { HighlightPlugin } from '@udecode/plate-highlight/react';\nimport { HorizontalRulePlugin } from '@udecode/plate-horizontal-rule/react';\nimport { IndentPlugin } from '@udecode/plate-indent/react';\nimport { IndentListPlugin } from '@udecode/plate-indent-list/react';\nimport { JuicePlugin } from '@udecode/plate-juice';\nimport { KbdPlugin } from '@udecode/plate-kbd/react';\nimport { ColumnPlugin } from '@udecode/plate-layout/react';\nimport { LineHeightPlugin } from '@udecode/plate-line-height/react';\nimport { LinkPlugin } from '@udecode/plate-link/react';\nimport { ListPlugin, TodoListPlugin } from '@udecode/plate-list/react';\nimport { MarkdownPlugin } from '@udecode/plate-markdown';\nimport { BaseImagePlugin } from '@udecode/plate-media';\nimport { ImagePlugin, MediaEmbedPlugin } from '@udecode/plate-media/react';\nimport { MentionPlugin } from '@udecode/plate-mention/react';\nimport { NodeIdPlugin } from '@udecode/plate-node-id';\nimport { NormalizeTypesPlugin } from '@udecode/plate-normalizers';\nimport { PlaywrightPlugin } from '@udecode/plate-playwright';\nimport { DeletePlugin, SelectOnBackspacePlugin } from '@udecode/plate-select';\nimport {\n BlockMenuPlugin,\n BlockSelectionPlugin,\n} from '@udecode/plate-selection/react';\nimport { SlashPlugin } from '@udecode/plate-slash-command/react';\nimport { TablePlugin } from '@udecode/plate-table/react';\nimport { TogglePlugin } from '@udecode/plate-toggle/react';\nimport { TrailingBlockPlugin } from '@udecode/plate-trailing-block';\nimport Prism from 'prismjs';\n\nimport { CheckPlugin } from '@/components/context/check-plugin';\nimport { settingsStore } from '@/components/context/settings-store';\nimport { aiPlugins } from '@/lib/plate/demo/plugins/ai-plugins';\nimport { getAutoformatOptions } from '@/lib/plate/demo/plugins/autoformatOptions';\nimport { copilotPlugins } from '@/lib/plate/demo/plugins/copilot-plugins';\nimport { createPlateUI } from '@/plate/create-plate-ui';\nimport { editableProps } from '@/plate/demo/editableProps';\nimport { isEnabled } from '@/plate/demo/is-enabled';\nimport { DragOverCursorPlugin } from '@/plate/demo/plugins/DragOverCursorPlugin';\nimport { exitBreakPlugin } from '@/plate/demo/plugins/exitBreakPlugin';\nimport { resetBlockTypePlugin } from '@/plate/demo/plugins/resetBlockTypePlugin';\nimport { softBreakPlugin } from '@/plate/demo/plugins/softBreakPlugin';\nimport { tabbablePlugin } from '@/plate/demo/plugins/tabbablePlugin';\nimport { commentsData, usersData } from '@/plate/demo/values/commentsValue';\nimport { usePlaygroundValue } from '@/plate/demo/values/usePlaygroundValue';\nimport { BlockContextMenu } from '@/components/plate-ui/block-context-menu';\nimport { CommentsPopover } from '@/components/plate-ui/comments-popover';\nimport {\n CursorOverlay,\n SelectionOverlayPlugin,\n} from '@/components/plate-ui/cursor-overlay';\nimport { Editor, EditorContainer } from '@/components/plate-ui/editor';\nimport { FixedToolbar } from '@/components/plate-ui/fixed-toolbar';\nimport { FixedToolbarButtons } from '@/components/plate-ui/fixed-toolbar-buttons';\nimport { FloatingToolbar } from '@/components/plate-ui/floating-toolbar';\nimport { FloatingToolbarButtons } from '@/components/plate-ui/floating-toolbar-buttons';\nimport { ImagePreview } from '@/components/plate-ui/image-preview';\nimport {\n FireLiComponent,\n FireMarker,\n} from '@/components/plate-ui/indent-fire-marker';\nimport {\n TodoLi,\n TodoMarker,\n} from '@/components/plate-ui/indent-todo-marker';\nimport { LinkFloatingToolbar } from '@/components/plate-ui/link-floating-toolbar';\n\nimport { usePlaygroundEnabled } from './usePlaygroundEnabled';\n\nexport const usePlaygroundEditor = (id: any = '', scrollSelector?: string) => {\n const enabledPlugins = settingsStore.use.checkedPlugins();\n const overridePlugins = usePlaygroundEnabled(id);\n const autoformatOptions = getAutoformatOptions(id, enabledPlugins);\n\n const value = usePlaygroundValue(id);\n const key = settingsStore.use.version();\n const editorId = id || 'playground-' + key;\n\n return usePlateEditor(\n {\n id: editorId,\n override: {\n components: createPlateUI({\n draggable: isEnabled('dnd', id),\n placeholder: isEnabled('placeholder', id),\n }),\n plugins: overridePlugins,\n },\n plugins: [\n // AI\n ...(id === 'ai' || enabledPlugins[AIChatPlugin.key] ? aiPlugins : []),\n ...(id === 'copilot' || enabledPlugins[CopilotPlugin.key]\n ? copilotPlugins\n : []),\n // Nodes\n HeadingPlugin,\n TocPlugin.configure({\n options: {\n scrollContainerSelector: `#${scrollSelector}`,\n topOffset: 80,\n },\n }),\n BlockquotePlugin,\n CodeBlockPlugin.configure({\n options: {\n prism: Prism,\n },\n }),\n HorizontalRulePlugin,\n LinkPlugin.extend({\n render: { afterEditable: () => },\n }),\n ...(id === 'list' ? [ListPlugin] : []),\n ImagePlugin.extend({\n options: {\n disableUploadInsert: true,\n },\n render: { afterEditable: ImagePreview },\n }),\n MediaEmbedPlugin,\n CaptionPlugin.configure({\n options: {\n plugins: [ImagePlugin, MediaEmbedPlugin],\n },\n }),\n DatePlugin,\n MentionPlugin.configure({\n options: {\n triggerPreviousCharPattern: /^$|^[\\s\"']$/,\n },\n }),\n SlashPlugin,\n TablePlugin.configure({\n options: {\n enableMerging: id === 'tableMerge',\n },\n }),\n ColumnPlugin,\n SelectionOverlayPlugin,\n\n TodoListPlugin,\n TogglePlugin,\n ExcalidrawPlugin,\n // Marks\n BoldPlugin,\n ItalicPlugin,\n UnderlinePlugin,\n StrikethroughPlugin,\n CodePlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n FontColorPlugin,\n FontBackgroundColorPlugin,\n FontSizePlugin,\n HighlightPlugin,\n KbdPlugin,\n\n // Block Style\n AlignPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n MediaEmbedPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n ImagePlugin.key,\n HEADING_KEYS.h6,\n ],\n },\n }),\n IndentPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n }),\n IndentListPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n options: {\n listStyleTypes: {\n fire: {\n liComponent: FireLiComponent,\n markerComponent: FireMarker,\n type: 'fire',\n },\n todo: {\n liComponent: TodoLi,\n markerComponent: TodoMarker,\n type: 'todo',\n },\n },\n },\n }),\n LineHeightPlugin.extend({\n inject: {\n nodeProps: {\n defaultNodeValue: 1.5,\n validNodeValues: [1, 1.2, 1.5, 2, 3],\n },\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n ],\n },\n }),\n\n // Functionality\n AutoformatPlugin.configure({\n options: autoformatOptions,\n }),\n BlockSelectionPlugin.configure({\n options: {\n areaOptions: {\n behaviour: {\n scrolling: {\n speedDivider: 1.5,\n },\n startThreshold: 10,\n },\n boundaries: `#${scrollSelector}`,\n container: `#${scrollSelector}`,\n selectables: [`#${scrollSelector} .slate-selectable`],\n selectionAreaClass: 'slate-selection-area',\n },\n enableContextMenu: true,\n },\n }),\n BlockMenuPlugin.configure({\n render: { aboveEditable: BlockContextMenu },\n }),\n DndPlugin.configure({\n options: {\n enableScroller: true,\n onDropFiles: ({ dragItem, editor, target }) => {\n editor\n .getTransforms(BaseImagePlugin)\n .insert.imageFromFiles(dragItem.files, {\n at: target,\n nextBlock: false,\n });\n },\n },\n }),\n EmojiPlugin,\n exitBreakPlugin,\n NodeIdPlugin,\n NormalizeTypesPlugin.configure({\n options: {\n rules: [{ path: [0], strictType: HEADING_KEYS.h1 }],\n },\n }),\n resetBlockTypePlugin,\n SelectOnBackspacePlugin.configure({\n options: {\n query: {\n allow: [ImagePlugin.key, HorizontalRulePlugin.key],\n },\n },\n }),\n DeletePlugin,\n SingleLinePlugin,\n softBreakPlugin,\n tabbablePlugin,\n TrailingBlockPlugin.configure({\n options: { type: ParagraphPlugin.key },\n }),\n DragOverCursorPlugin,\n\n // Collaboration\n CommentsPlugin.configure({\n options: {\n comments: commentsData,\n myUserId: '1',\n users: usersData,\n },\n }),\n\n // Deserialization\n DocxPlugin,\n MarkdownPlugin.configure({ options: { indentList: true } }),\n JuicePlugin,\n\n // Testing\n PlaywrightPlugin.configure({\n enabled: process.env.NODE_ENV !== 'production',\n }),\n ],\n value: value,\n },\n []\n );\n};\n\nexport default function PlaygroundDemo({\n id,\n className,\n scrollSelector,\n}: {\n id?: ValueId;\n className?: string;\n scrollSelector?: string;\n}) {\n const containerRef = useRef(null);\n const enabled = settingsStore.use.checkedComponents();\n\n const editor = usePlaygroundEditor(\n id,\n scrollSelector ?? `blockSelection-${id}`\n );\n\n return (\n \n \n \n \n \n \n \n \n \n\n
\n \n \n\n \n \n \n \n \n \n \n\n \n \n \n \n\n \n \n \n
\n
\n
\n );\n}\n\nconst DemoIdContext = React.createContext(undefined);\n\nexport function DemoId({\n id,\n children,\n}: {\n children: React.ReactNode;\n id?: string;\n}) {\n return {children};\n}\n\nexport function useDemoId() {\n return React.useContext(DemoIdContext);\n}\n", "path": "example/playground-demo.tsx", "target": "components/playground-demo.tsx", "type": "registry:example" diff --git a/apps/www/public/r/styles/default/column-demo.json b/apps/www/public/r/styles/default/column-demo.json index 645c7dd781..2d7022f2b3 100644 --- a/apps/www/public/r/styles/default/column-demo.json +++ b/apps/www/public/r/styles/default/column-demo.json @@ -4,7 +4,7 @@ }, "files": [ { - "content": "'use client';\n\nimport React, { useRef } from 'react';\n\nimport type { ValueId } from '@/config/customizer-plugins';\n\nimport { cn } from '@udecode/cn';\nimport { AIChatPlugin, CopilotPlugin } from '@udecode/plate-ai/react';\nimport { AlignPlugin } from '@udecode/plate-alignment/react';\nimport { AutoformatPlugin } from '@udecode/plate-autoformat/react';\nimport {\n BoldPlugin,\n CodePlugin,\n ItalicPlugin,\n StrikethroughPlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n UnderlinePlugin,\n} from '@udecode/plate-basic-marks/react';\nimport { BlockquotePlugin } from '@udecode/plate-block-quote/react';\nimport { SingleLinePlugin } from '@udecode/plate-break/react';\nimport { CaptionPlugin } from '@udecode/plate-caption/react';\nimport { CodeBlockPlugin } from '@udecode/plate-code-block/react';\nimport { CommentsPlugin } from '@udecode/plate-comments/react';\nimport {\n ParagraphPlugin,\n Plate,\n usePlateEditor,\n} from '@udecode/plate-common/react';\nimport { DatePlugin } from '@udecode/plate-date/react';\nimport { DndPlugin } from '@udecode/plate-dnd';\nimport { DocxPlugin } from '@udecode/plate-docx';\nimport { EmojiPlugin } from '@udecode/plate-emoji/react';\nimport { ExcalidrawPlugin } from '@udecode/plate-excalidraw/react';\nimport {\n FontBackgroundColorPlugin,\n FontColorPlugin,\n FontSizePlugin,\n} from '@udecode/plate-font/react';\nimport { HEADING_KEYS } from '@udecode/plate-heading';\nimport { HeadingPlugin, TocPlugin } from '@udecode/plate-heading/react';\nimport { HighlightPlugin } from '@udecode/plate-highlight/react';\nimport { HorizontalRulePlugin } from '@udecode/plate-horizontal-rule/react';\nimport { IndentPlugin } from '@udecode/plate-indent/react';\nimport { IndentListPlugin } from '@udecode/plate-indent-list/react';\nimport { JuicePlugin } from '@udecode/plate-juice';\nimport { KbdPlugin } from '@udecode/plate-kbd/react';\nimport { ColumnPlugin } from '@udecode/plate-layout/react';\nimport { LineHeightPlugin } from '@udecode/plate-line-height/react';\nimport { LinkPlugin } from '@udecode/plate-link/react';\nimport { ListPlugin, TodoListPlugin } from '@udecode/plate-list/react';\nimport { MarkdownPlugin } from '@udecode/plate-markdown';\nimport { ImagePlugin, MediaEmbedPlugin } from '@udecode/plate-media/react';\nimport { MentionPlugin } from '@udecode/plate-mention/react';\nimport { NodeIdPlugin } from '@udecode/plate-node-id';\nimport { NormalizeTypesPlugin } from '@udecode/plate-normalizers';\nimport { PlaywrightPlugin } from '@udecode/plate-playwright';\nimport { DeletePlugin, SelectOnBackspacePlugin } from '@udecode/plate-select';\nimport {\n BlockMenuPlugin,\n BlockSelectionPlugin,\n} from '@udecode/plate-selection/react';\nimport { SlashPlugin } from '@udecode/plate-slash-command/react';\nimport { TablePlugin } from '@udecode/plate-table/react';\nimport { TogglePlugin } from '@udecode/plate-toggle/react';\nimport { TrailingBlockPlugin } from '@udecode/plate-trailing-block';\nimport Prism from 'prismjs';\n\nimport { CheckPlugin } from '@/components/context/check-plugin';\nimport { settingsStore } from '@/components/context/settings-store';\nimport { aiPlugins } from '@/lib/plate/demo/plugins/ai-plugins';\nimport { getAutoformatOptions } from '@/lib/plate/demo/plugins/autoformatOptions';\nimport { copilotPlugins } from '@/lib/plate/demo/plugins/copilot-plugins';\nimport { createPlateUI } from '@/plate/create-plate-ui';\nimport { editableProps } from '@/plate/demo/editableProps';\nimport { isEnabled } from '@/plate/demo/is-enabled';\nimport { DragOverCursorPlugin } from '@/plate/demo/plugins/DragOverCursorPlugin';\nimport { exitBreakPlugin } from '@/plate/demo/plugins/exitBreakPlugin';\nimport { resetBlockTypePlugin } from '@/plate/demo/plugins/resetBlockTypePlugin';\nimport { softBreakPlugin } from '@/plate/demo/plugins/softBreakPlugin';\nimport { tabbablePlugin } from '@/plate/demo/plugins/tabbablePlugin';\nimport { commentsData, usersData } from '@/plate/demo/values/commentsValue';\nimport { usePlaygroundValue } from '@/plate/demo/values/usePlaygroundValue';\nimport { BlockContextMenu } from '@/components/plate-ui/block-context-menu';\nimport { CommentsPopover } from '@/components/plate-ui/comments-popover';\nimport {\n CursorOverlay,\n SelectionOverlayPlugin,\n} from '@/components/plate-ui/cursor-overlay';\nimport { Editor, EditorContainer } from '@/components/plate-ui/editor';\nimport { FixedToolbar } from '@/components/plate-ui/fixed-toolbar';\nimport { FixedToolbarButtons } from '@/components/plate-ui/fixed-toolbar-buttons';\nimport { FloatingToolbar } from '@/components/plate-ui/floating-toolbar';\nimport { FloatingToolbarButtons } from '@/components/plate-ui/floating-toolbar-buttons';\nimport { ImagePreview } from '@/components/plate-ui/image-preview';\nimport {\n FireLiComponent,\n FireMarker,\n} from '@/components/plate-ui/indent-fire-marker';\nimport {\n TodoLi,\n TodoMarker,\n} from '@/components/plate-ui/indent-todo-marker';\nimport { LinkFloatingToolbar } from '@/components/plate-ui/link-floating-toolbar';\n\nimport { usePlaygroundEnabled } from './usePlaygroundEnabled';\n\nexport const usePlaygroundEditor = (id: any = '', scrollSelector?: string) => {\n const enabledPlugins = settingsStore.use.checkedPlugins();\n const overridePlugins = usePlaygroundEnabled(id);\n const autoformatOptions = getAutoformatOptions(id, enabledPlugins);\n\n const value = usePlaygroundValue(id);\n const key = settingsStore.use.version();\n const editorId = id || 'playground-' + key;\n\n return usePlateEditor(\n {\n id: editorId,\n override: {\n components: createPlateUI({\n draggable: isEnabled('dnd', id),\n placeholder: isEnabled('placeholder', id),\n }),\n plugins: overridePlugins,\n },\n plugins: [\n // AI\n ...(id === 'ai' || enabledPlugins[AIChatPlugin.key] ? aiPlugins : []),\n ...(id === 'copilot' || enabledPlugins[CopilotPlugin.key]\n ? copilotPlugins\n : []),\n // Nodes\n HeadingPlugin,\n TocPlugin.configure({\n options: {\n scrollContainerSelector: `#${scrollSelector}`,\n topOffset: 80,\n },\n }),\n BlockquotePlugin,\n CodeBlockPlugin.configure({\n options: {\n prism: Prism,\n },\n }),\n HorizontalRulePlugin,\n LinkPlugin.extend({\n render: { afterEditable: () => },\n }),\n ...(id === 'list' ? [ListPlugin] : []),\n ImagePlugin.extend({\n options: {\n disableUploadInsert: true,\n },\n render: { afterEditable: ImagePreview },\n }),\n MediaEmbedPlugin,\n CaptionPlugin.configure({\n options: {\n plugins: [ImagePlugin, MediaEmbedPlugin],\n },\n }),\n DatePlugin,\n MentionPlugin.configure({\n options: {\n triggerPreviousCharPattern: /^$|^[\\s\"']$/,\n },\n }),\n SlashPlugin,\n TablePlugin.configure({\n options: {\n enableMerging: id === 'tableMerge',\n },\n }),\n ColumnPlugin,\n SelectionOverlayPlugin,\n\n TodoListPlugin,\n TogglePlugin,\n ExcalidrawPlugin,\n // Marks\n BoldPlugin,\n ItalicPlugin,\n UnderlinePlugin,\n StrikethroughPlugin,\n CodePlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n FontColorPlugin,\n FontBackgroundColorPlugin,\n FontSizePlugin,\n HighlightPlugin,\n KbdPlugin,\n\n // Block Style\n AlignPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n MediaEmbedPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n ImagePlugin.key,\n HEADING_KEYS.h6,\n ],\n },\n }),\n IndentPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n }),\n IndentListPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n options: {\n listStyleTypes: {\n fire: {\n liComponent: FireLiComponent,\n markerComponent: FireMarker,\n type: 'fire',\n },\n todo: {\n liComponent: TodoLi,\n markerComponent: TodoMarker,\n type: 'todo',\n },\n },\n },\n }),\n LineHeightPlugin.extend({\n inject: {\n nodeProps: {\n defaultNodeValue: 1.5,\n validNodeValues: [1, 1.2, 1.5, 2, 3],\n },\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n ],\n },\n }),\n\n // Functionality\n AutoformatPlugin.configure({\n options: autoformatOptions,\n }),\n BlockSelectionPlugin.configure({\n options: {\n areaOptions: {\n behaviour: {\n scrolling: {\n speedDivider: 1.5,\n },\n startThreshold: 10,\n },\n boundaries: `#${scrollSelector}`,\n container: `#${scrollSelector}`,\n selectables: [`#${scrollSelector} .slate-selectable`],\n selectionAreaClass: 'slate-selection-area',\n },\n enableContextMenu: true,\n },\n }),\n BlockMenuPlugin.configure({\n render: { aboveEditable: BlockContextMenu },\n }),\n DndPlugin.configure({\n options: {\n enableScroller: true,\n onDropFiles: ({ dragItem, editor, target }) => {\n editor\n .getTransforms(ImagePlugin)\n .insertImageFromFiles(dragItem.files, {\n at: target,\n nextBlock: false,\n });\n },\n },\n }),\n EmojiPlugin,\n exitBreakPlugin,\n NodeIdPlugin,\n NormalizeTypesPlugin.configure({\n options: {\n rules: [{ path: [0], strictType: HEADING_KEYS.h1 }],\n },\n }),\n resetBlockTypePlugin,\n SelectOnBackspacePlugin.configure({\n options: {\n query: {\n allow: [ImagePlugin.key, HorizontalRulePlugin.key],\n },\n },\n }),\n DeletePlugin,\n SingleLinePlugin,\n softBreakPlugin,\n tabbablePlugin,\n TrailingBlockPlugin.configure({\n options: { type: ParagraphPlugin.key },\n }),\n DragOverCursorPlugin,\n\n // Collaboration\n CommentsPlugin.configure({\n options: {\n comments: commentsData,\n myUserId: '1',\n users: usersData,\n },\n }),\n\n // Deserialization\n DocxPlugin,\n MarkdownPlugin.configure({ options: { indentList: true } }),\n JuicePlugin,\n\n // Testing\n PlaywrightPlugin.configure({\n enabled: process.env.NODE_ENV !== 'production',\n }),\n ],\n value: value,\n },\n []\n );\n};\n\nexport default function PlaygroundDemo({\n id,\n className,\n scrollSelector,\n}: {\n id?: ValueId;\n className?: string;\n scrollSelector?: string;\n}) {\n const containerRef = useRef(null);\n const enabled = settingsStore.use.checkedComponents();\n\n const editor = usePlaygroundEditor(\n id,\n scrollSelector ?? `blockSelection-${id}`\n );\n\n return (\n \n \n \n \n \n \n \n \n \n\n
\n \n \n\n \n \n \n \n \n \n \n\n \n \n \n \n\n \n \n \n
\n
\n
\n );\n}\n\nconst DemoIdContext = React.createContext(undefined);\n\nexport function DemoId({\n id,\n children,\n}: {\n children: React.ReactNode;\n id?: string;\n}) {\n return {children};\n}\n\nexport function useDemoId() {\n return React.useContext(DemoIdContext);\n}\n", + "content": "'use client';\n\nimport React, { useRef } from 'react';\n\nimport type { ValueId } from '@/config/customizer-plugins';\n\nimport { cn } from '@udecode/cn';\nimport { AIChatPlugin, CopilotPlugin } from '@udecode/plate-ai/react';\nimport { AlignPlugin } from '@udecode/plate-alignment/react';\nimport { AutoformatPlugin } from '@udecode/plate-autoformat/react';\nimport {\n BoldPlugin,\n CodePlugin,\n ItalicPlugin,\n StrikethroughPlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n UnderlinePlugin,\n} from '@udecode/plate-basic-marks/react';\nimport { BlockquotePlugin } from '@udecode/plate-block-quote/react';\nimport { SingleLinePlugin } from '@udecode/plate-break/react';\nimport { CaptionPlugin } from '@udecode/plate-caption/react';\nimport { CodeBlockPlugin } from '@udecode/plate-code-block/react';\nimport { CommentsPlugin } from '@udecode/plate-comments/react';\nimport {\n ParagraphPlugin,\n Plate,\n usePlateEditor,\n} from '@udecode/plate-common/react';\nimport { DatePlugin } from '@udecode/plate-date/react';\nimport { DndPlugin } from '@udecode/plate-dnd';\nimport { DocxPlugin } from '@udecode/plate-docx';\nimport { EmojiPlugin } from '@udecode/plate-emoji/react';\nimport { ExcalidrawPlugin } from '@udecode/plate-excalidraw/react';\nimport {\n FontBackgroundColorPlugin,\n FontColorPlugin,\n FontSizePlugin,\n} from '@udecode/plate-font/react';\nimport { HEADING_KEYS } from '@udecode/plate-heading';\nimport { HeadingPlugin, TocPlugin } from '@udecode/plate-heading/react';\nimport { HighlightPlugin } from '@udecode/plate-highlight/react';\nimport { HorizontalRulePlugin } from '@udecode/plate-horizontal-rule/react';\nimport { IndentPlugin } from '@udecode/plate-indent/react';\nimport { IndentListPlugin } from '@udecode/plate-indent-list/react';\nimport { JuicePlugin } from '@udecode/plate-juice';\nimport { KbdPlugin } from '@udecode/plate-kbd/react';\nimport { ColumnPlugin } from '@udecode/plate-layout/react';\nimport { LineHeightPlugin } from '@udecode/plate-line-height/react';\nimport { LinkPlugin } from '@udecode/plate-link/react';\nimport { ListPlugin, TodoListPlugin } from '@udecode/plate-list/react';\nimport { MarkdownPlugin } from '@udecode/plate-markdown';\nimport { BaseImagePlugin } from '@udecode/plate-media';\nimport { ImagePlugin, MediaEmbedPlugin } from '@udecode/plate-media/react';\nimport { MentionPlugin } from '@udecode/plate-mention/react';\nimport { NodeIdPlugin } from '@udecode/plate-node-id';\nimport { NormalizeTypesPlugin } from '@udecode/plate-normalizers';\nimport { PlaywrightPlugin } from '@udecode/plate-playwright';\nimport { DeletePlugin, SelectOnBackspacePlugin } from '@udecode/plate-select';\nimport {\n BlockMenuPlugin,\n BlockSelectionPlugin,\n} from '@udecode/plate-selection/react';\nimport { SlashPlugin } from '@udecode/plate-slash-command/react';\nimport { TablePlugin } from '@udecode/plate-table/react';\nimport { TogglePlugin } from '@udecode/plate-toggle/react';\nimport { TrailingBlockPlugin } from '@udecode/plate-trailing-block';\nimport Prism from 'prismjs';\n\nimport { CheckPlugin } from '@/components/context/check-plugin';\nimport { settingsStore } from '@/components/context/settings-store';\nimport { aiPlugins } from '@/lib/plate/demo/plugins/ai-plugins';\nimport { getAutoformatOptions } from '@/lib/plate/demo/plugins/autoformatOptions';\nimport { copilotPlugins } from '@/lib/plate/demo/plugins/copilot-plugins';\nimport { createPlateUI } from '@/plate/create-plate-ui';\nimport { editableProps } from '@/plate/demo/editableProps';\nimport { isEnabled } from '@/plate/demo/is-enabled';\nimport { DragOverCursorPlugin } from '@/plate/demo/plugins/DragOverCursorPlugin';\nimport { exitBreakPlugin } from '@/plate/demo/plugins/exitBreakPlugin';\nimport { resetBlockTypePlugin } from '@/plate/demo/plugins/resetBlockTypePlugin';\nimport { softBreakPlugin } from '@/plate/demo/plugins/softBreakPlugin';\nimport { tabbablePlugin } from '@/plate/demo/plugins/tabbablePlugin';\nimport { commentsData, usersData } from '@/plate/demo/values/commentsValue';\nimport { usePlaygroundValue } from '@/plate/demo/values/usePlaygroundValue';\nimport { BlockContextMenu } from '@/components/plate-ui/block-context-menu';\nimport { CommentsPopover } from '@/components/plate-ui/comments-popover';\nimport {\n CursorOverlay,\n SelectionOverlayPlugin,\n} from '@/components/plate-ui/cursor-overlay';\nimport { Editor, EditorContainer } from '@/components/plate-ui/editor';\nimport { FixedToolbar } from '@/components/plate-ui/fixed-toolbar';\nimport { FixedToolbarButtons } from '@/components/plate-ui/fixed-toolbar-buttons';\nimport { FloatingToolbar } from '@/components/plate-ui/floating-toolbar';\nimport { FloatingToolbarButtons } from '@/components/plate-ui/floating-toolbar-buttons';\nimport { ImagePreview } from '@/components/plate-ui/image-preview';\nimport {\n FireLiComponent,\n FireMarker,\n} from '@/components/plate-ui/indent-fire-marker';\nimport {\n TodoLi,\n TodoMarker,\n} from '@/components/plate-ui/indent-todo-marker';\nimport { LinkFloatingToolbar } from '@/components/plate-ui/link-floating-toolbar';\n\nimport { usePlaygroundEnabled } from './usePlaygroundEnabled';\n\nexport const usePlaygroundEditor = (id: any = '', scrollSelector?: string) => {\n const enabledPlugins = settingsStore.use.checkedPlugins();\n const overridePlugins = usePlaygroundEnabled(id);\n const autoformatOptions = getAutoformatOptions(id, enabledPlugins);\n\n const value = usePlaygroundValue(id);\n const key = settingsStore.use.version();\n const editorId = id || 'playground-' + key;\n\n return usePlateEditor(\n {\n id: editorId,\n override: {\n components: createPlateUI({\n draggable: isEnabled('dnd', id),\n placeholder: isEnabled('placeholder', id),\n }),\n plugins: overridePlugins,\n },\n plugins: [\n // AI\n ...(id === 'ai' || enabledPlugins[AIChatPlugin.key] ? aiPlugins : []),\n ...(id === 'copilot' || enabledPlugins[CopilotPlugin.key]\n ? copilotPlugins\n : []),\n // Nodes\n HeadingPlugin,\n TocPlugin.configure({\n options: {\n scrollContainerSelector: `#${scrollSelector}`,\n topOffset: 80,\n },\n }),\n BlockquotePlugin,\n CodeBlockPlugin.configure({\n options: {\n prism: Prism,\n },\n }),\n HorizontalRulePlugin,\n LinkPlugin.extend({\n render: { afterEditable: () => },\n }),\n ...(id === 'list' ? [ListPlugin] : []),\n ImagePlugin.extend({\n options: {\n disableUploadInsert: true,\n },\n render: { afterEditable: ImagePreview },\n }),\n MediaEmbedPlugin,\n CaptionPlugin.configure({\n options: {\n plugins: [ImagePlugin, MediaEmbedPlugin],\n },\n }),\n DatePlugin,\n MentionPlugin.configure({\n options: {\n triggerPreviousCharPattern: /^$|^[\\s\"']$/,\n },\n }),\n SlashPlugin,\n TablePlugin.configure({\n options: {\n enableMerging: id === 'tableMerge',\n },\n }),\n ColumnPlugin,\n SelectionOverlayPlugin,\n\n TodoListPlugin,\n TogglePlugin,\n ExcalidrawPlugin,\n // Marks\n BoldPlugin,\n ItalicPlugin,\n UnderlinePlugin,\n StrikethroughPlugin,\n CodePlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n FontColorPlugin,\n FontBackgroundColorPlugin,\n FontSizePlugin,\n HighlightPlugin,\n KbdPlugin,\n\n // Block Style\n AlignPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n MediaEmbedPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n ImagePlugin.key,\n HEADING_KEYS.h6,\n ],\n },\n }),\n IndentPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n }),\n IndentListPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n options: {\n listStyleTypes: {\n fire: {\n liComponent: FireLiComponent,\n markerComponent: FireMarker,\n type: 'fire',\n },\n todo: {\n liComponent: TodoLi,\n markerComponent: TodoMarker,\n type: 'todo',\n },\n },\n },\n }),\n LineHeightPlugin.extend({\n inject: {\n nodeProps: {\n defaultNodeValue: 1.5,\n validNodeValues: [1, 1.2, 1.5, 2, 3],\n },\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n ],\n },\n }),\n\n // Functionality\n AutoformatPlugin.configure({\n options: autoformatOptions,\n }),\n BlockSelectionPlugin.configure({\n options: {\n areaOptions: {\n behaviour: {\n scrolling: {\n speedDivider: 1.5,\n },\n startThreshold: 10,\n },\n boundaries: `#${scrollSelector}`,\n container: `#${scrollSelector}`,\n selectables: [`#${scrollSelector} .slate-selectable`],\n selectionAreaClass: 'slate-selection-area',\n },\n enableContextMenu: true,\n },\n }),\n BlockMenuPlugin.configure({\n render: { aboveEditable: BlockContextMenu },\n }),\n DndPlugin.configure({\n options: {\n enableScroller: true,\n onDropFiles: ({ dragItem, editor, target }) => {\n editor\n .getTransforms(BaseImagePlugin)\n .insert.imageFromFiles(dragItem.files, {\n at: target,\n nextBlock: false,\n });\n },\n },\n }),\n EmojiPlugin,\n exitBreakPlugin,\n NodeIdPlugin,\n NormalizeTypesPlugin.configure({\n options: {\n rules: [{ path: [0], strictType: HEADING_KEYS.h1 }],\n },\n }),\n resetBlockTypePlugin,\n SelectOnBackspacePlugin.configure({\n options: {\n query: {\n allow: [ImagePlugin.key, HorizontalRulePlugin.key],\n },\n },\n }),\n DeletePlugin,\n SingleLinePlugin,\n softBreakPlugin,\n tabbablePlugin,\n TrailingBlockPlugin.configure({\n options: { type: ParagraphPlugin.key },\n }),\n DragOverCursorPlugin,\n\n // Collaboration\n CommentsPlugin.configure({\n options: {\n comments: commentsData,\n myUserId: '1',\n users: usersData,\n },\n }),\n\n // Deserialization\n DocxPlugin,\n MarkdownPlugin.configure({ options: { indentList: true } }),\n JuicePlugin,\n\n // Testing\n PlaywrightPlugin.configure({\n enabled: process.env.NODE_ENV !== 'production',\n }),\n ],\n value: value,\n },\n []\n );\n};\n\nexport default function PlaygroundDemo({\n id,\n className,\n scrollSelector,\n}: {\n id?: ValueId;\n className?: string;\n scrollSelector?: string;\n}) {\n const containerRef = useRef(null);\n const enabled = settingsStore.use.checkedComponents();\n\n const editor = usePlaygroundEditor(\n id,\n scrollSelector ?? `blockSelection-${id}`\n );\n\n return (\n \n \n \n \n \n \n \n \n \n\n
\n \n \n\n \n \n \n \n \n \n \n\n \n \n \n \n\n \n \n \n
\n
\n
\n );\n}\n\nconst DemoIdContext = React.createContext(undefined);\n\nexport function DemoId({\n id,\n children,\n}: {\n children: React.ReactNode;\n id?: string;\n}) {\n return {children};\n}\n\nexport function useDemoId() {\n return React.useContext(DemoIdContext);\n}\n", "path": "example/playground-demo.tsx", "target": "components/playground-demo.tsx", "type": "registry:example" diff --git a/apps/www/public/r/styles/default/comment-demo.json b/apps/www/public/r/styles/default/comment-demo.json index d31b981889..9a5f1434af 100644 --- a/apps/www/public/r/styles/default/comment-demo.json +++ b/apps/www/public/r/styles/default/comment-demo.json @@ -4,7 +4,7 @@ }, "files": [ { - "content": "'use client';\n\nimport React, { useRef } from 'react';\n\nimport type { ValueId } from '@/config/customizer-plugins';\n\nimport { cn } from '@udecode/cn';\nimport { AIChatPlugin, CopilotPlugin } from '@udecode/plate-ai/react';\nimport { AlignPlugin } from '@udecode/plate-alignment/react';\nimport { AutoformatPlugin } from '@udecode/plate-autoformat/react';\nimport {\n BoldPlugin,\n CodePlugin,\n ItalicPlugin,\n StrikethroughPlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n UnderlinePlugin,\n} from '@udecode/plate-basic-marks/react';\nimport { BlockquotePlugin } from '@udecode/plate-block-quote/react';\nimport { SingleLinePlugin } from '@udecode/plate-break/react';\nimport { CaptionPlugin } from '@udecode/plate-caption/react';\nimport { CodeBlockPlugin } from '@udecode/plate-code-block/react';\nimport { CommentsPlugin } from '@udecode/plate-comments/react';\nimport {\n ParagraphPlugin,\n Plate,\n usePlateEditor,\n} from '@udecode/plate-common/react';\nimport { DatePlugin } from '@udecode/plate-date/react';\nimport { DndPlugin } from '@udecode/plate-dnd';\nimport { DocxPlugin } from '@udecode/plate-docx';\nimport { EmojiPlugin } from '@udecode/plate-emoji/react';\nimport { ExcalidrawPlugin } from '@udecode/plate-excalidraw/react';\nimport {\n FontBackgroundColorPlugin,\n FontColorPlugin,\n FontSizePlugin,\n} from '@udecode/plate-font/react';\nimport { HEADING_KEYS } from '@udecode/plate-heading';\nimport { HeadingPlugin, TocPlugin } from '@udecode/plate-heading/react';\nimport { HighlightPlugin } from '@udecode/plate-highlight/react';\nimport { HorizontalRulePlugin } from '@udecode/plate-horizontal-rule/react';\nimport { IndentPlugin } from '@udecode/plate-indent/react';\nimport { IndentListPlugin } from '@udecode/plate-indent-list/react';\nimport { JuicePlugin } from '@udecode/plate-juice';\nimport { KbdPlugin } from '@udecode/plate-kbd/react';\nimport { ColumnPlugin } from '@udecode/plate-layout/react';\nimport { LineHeightPlugin } from '@udecode/plate-line-height/react';\nimport { LinkPlugin } from '@udecode/plate-link/react';\nimport { ListPlugin, TodoListPlugin } from '@udecode/plate-list/react';\nimport { MarkdownPlugin } from '@udecode/plate-markdown';\nimport { ImagePlugin, MediaEmbedPlugin } from '@udecode/plate-media/react';\nimport { MentionPlugin } from '@udecode/plate-mention/react';\nimport { NodeIdPlugin } from '@udecode/plate-node-id';\nimport { NormalizeTypesPlugin } from '@udecode/plate-normalizers';\nimport { PlaywrightPlugin } from '@udecode/plate-playwright';\nimport { DeletePlugin, SelectOnBackspacePlugin } from '@udecode/plate-select';\nimport {\n BlockMenuPlugin,\n BlockSelectionPlugin,\n} from '@udecode/plate-selection/react';\nimport { SlashPlugin } from '@udecode/plate-slash-command/react';\nimport { TablePlugin } from '@udecode/plate-table/react';\nimport { TogglePlugin } from '@udecode/plate-toggle/react';\nimport { TrailingBlockPlugin } from '@udecode/plate-trailing-block';\nimport Prism from 'prismjs';\n\nimport { CheckPlugin } from '@/components/context/check-plugin';\nimport { settingsStore } from '@/components/context/settings-store';\nimport { aiPlugins } from '@/lib/plate/demo/plugins/ai-plugins';\nimport { getAutoformatOptions } from '@/lib/plate/demo/plugins/autoformatOptions';\nimport { copilotPlugins } from '@/lib/plate/demo/plugins/copilot-plugins';\nimport { createPlateUI } from '@/plate/create-plate-ui';\nimport { editableProps } from '@/plate/demo/editableProps';\nimport { isEnabled } from '@/plate/demo/is-enabled';\nimport { DragOverCursorPlugin } from '@/plate/demo/plugins/DragOverCursorPlugin';\nimport { exitBreakPlugin } from '@/plate/demo/plugins/exitBreakPlugin';\nimport { resetBlockTypePlugin } from '@/plate/demo/plugins/resetBlockTypePlugin';\nimport { softBreakPlugin } from '@/plate/demo/plugins/softBreakPlugin';\nimport { tabbablePlugin } from '@/plate/demo/plugins/tabbablePlugin';\nimport { commentsData, usersData } from '@/plate/demo/values/commentsValue';\nimport { usePlaygroundValue } from '@/plate/demo/values/usePlaygroundValue';\nimport { BlockContextMenu } from '@/components/plate-ui/block-context-menu';\nimport { CommentsPopover } from '@/components/plate-ui/comments-popover';\nimport {\n CursorOverlay,\n SelectionOverlayPlugin,\n} from '@/components/plate-ui/cursor-overlay';\nimport { Editor, EditorContainer } from '@/components/plate-ui/editor';\nimport { FixedToolbar } from '@/components/plate-ui/fixed-toolbar';\nimport { FixedToolbarButtons } from '@/components/plate-ui/fixed-toolbar-buttons';\nimport { FloatingToolbar } from '@/components/plate-ui/floating-toolbar';\nimport { FloatingToolbarButtons } from '@/components/plate-ui/floating-toolbar-buttons';\nimport { ImagePreview } from '@/components/plate-ui/image-preview';\nimport {\n FireLiComponent,\n FireMarker,\n} from '@/components/plate-ui/indent-fire-marker';\nimport {\n TodoLi,\n TodoMarker,\n} from '@/components/plate-ui/indent-todo-marker';\nimport { LinkFloatingToolbar } from '@/components/plate-ui/link-floating-toolbar';\n\nimport { usePlaygroundEnabled } from './usePlaygroundEnabled';\n\nexport const usePlaygroundEditor = (id: any = '', scrollSelector?: string) => {\n const enabledPlugins = settingsStore.use.checkedPlugins();\n const overridePlugins = usePlaygroundEnabled(id);\n const autoformatOptions = getAutoformatOptions(id, enabledPlugins);\n\n const value = usePlaygroundValue(id);\n const key = settingsStore.use.version();\n const editorId = id || 'playground-' + key;\n\n return usePlateEditor(\n {\n id: editorId,\n override: {\n components: createPlateUI({\n draggable: isEnabled('dnd', id),\n placeholder: isEnabled('placeholder', id),\n }),\n plugins: overridePlugins,\n },\n plugins: [\n // AI\n ...(id === 'ai' || enabledPlugins[AIChatPlugin.key] ? aiPlugins : []),\n ...(id === 'copilot' || enabledPlugins[CopilotPlugin.key]\n ? copilotPlugins\n : []),\n // Nodes\n HeadingPlugin,\n TocPlugin.configure({\n options: {\n scrollContainerSelector: `#${scrollSelector}`,\n topOffset: 80,\n },\n }),\n BlockquotePlugin,\n CodeBlockPlugin.configure({\n options: {\n prism: Prism,\n },\n }),\n HorizontalRulePlugin,\n LinkPlugin.extend({\n render: { afterEditable: () => },\n }),\n ...(id === 'list' ? [ListPlugin] : []),\n ImagePlugin.extend({\n options: {\n disableUploadInsert: true,\n },\n render: { afterEditable: ImagePreview },\n }),\n MediaEmbedPlugin,\n CaptionPlugin.configure({\n options: {\n plugins: [ImagePlugin, MediaEmbedPlugin],\n },\n }),\n DatePlugin,\n MentionPlugin.configure({\n options: {\n triggerPreviousCharPattern: /^$|^[\\s\"']$/,\n },\n }),\n SlashPlugin,\n TablePlugin.configure({\n options: {\n enableMerging: id === 'tableMerge',\n },\n }),\n ColumnPlugin,\n SelectionOverlayPlugin,\n\n TodoListPlugin,\n TogglePlugin,\n ExcalidrawPlugin,\n // Marks\n BoldPlugin,\n ItalicPlugin,\n UnderlinePlugin,\n StrikethroughPlugin,\n CodePlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n FontColorPlugin,\n FontBackgroundColorPlugin,\n FontSizePlugin,\n HighlightPlugin,\n KbdPlugin,\n\n // Block Style\n AlignPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n MediaEmbedPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n ImagePlugin.key,\n HEADING_KEYS.h6,\n ],\n },\n }),\n IndentPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n }),\n IndentListPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n options: {\n listStyleTypes: {\n fire: {\n liComponent: FireLiComponent,\n markerComponent: FireMarker,\n type: 'fire',\n },\n todo: {\n liComponent: TodoLi,\n markerComponent: TodoMarker,\n type: 'todo',\n },\n },\n },\n }),\n LineHeightPlugin.extend({\n inject: {\n nodeProps: {\n defaultNodeValue: 1.5,\n validNodeValues: [1, 1.2, 1.5, 2, 3],\n },\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n ],\n },\n }),\n\n // Functionality\n AutoformatPlugin.configure({\n options: autoformatOptions,\n }),\n BlockSelectionPlugin.configure({\n options: {\n areaOptions: {\n behaviour: {\n scrolling: {\n speedDivider: 1.5,\n },\n startThreshold: 10,\n },\n boundaries: `#${scrollSelector}`,\n container: `#${scrollSelector}`,\n selectables: [`#${scrollSelector} .slate-selectable`],\n selectionAreaClass: 'slate-selection-area',\n },\n enableContextMenu: true,\n },\n }),\n BlockMenuPlugin.configure({\n render: { aboveEditable: BlockContextMenu },\n }),\n DndPlugin.configure({\n options: {\n enableScroller: true,\n onDropFiles: ({ dragItem, editor, target }) => {\n editor\n .getTransforms(ImagePlugin)\n .insertImageFromFiles(dragItem.files, {\n at: target,\n nextBlock: false,\n });\n },\n },\n }),\n EmojiPlugin,\n exitBreakPlugin,\n NodeIdPlugin,\n NormalizeTypesPlugin.configure({\n options: {\n rules: [{ path: [0], strictType: HEADING_KEYS.h1 }],\n },\n }),\n resetBlockTypePlugin,\n SelectOnBackspacePlugin.configure({\n options: {\n query: {\n allow: [ImagePlugin.key, HorizontalRulePlugin.key],\n },\n },\n }),\n DeletePlugin,\n SingleLinePlugin,\n softBreakPlugin,\n tabbablePlugin,\n TrailingBlockPlugin.configure({\n options: { type: ParagraphPlugin.key },\n }),\n DragOverCursorPlugin,\n\n // Collaboration\n CommentsPlugin.configure({\n options: {\n comments: commentsData,\n myUserId: '1',\n users: usersData,\n },\n }),\n\n // Deserialization\n DocxPlugin,\n MarkdownPlugin.configure({ options: { indentList: true } }),\n JuicePlugin,\n\n // Testing\n PlaywrightPlugin.configure({\n enabled: process.env.NODE_ENV !== 'production',\n }),\n ],\n value: value,\n },\n []\n );\n};\n\nexport default function PlaygroundDemo({\n id,\n className,\n scrollSelector,\n}: {\n id?: ValueId;\n className?: string;\n scrollSelector?: string;\n}) {\n const containerRef = useRef(null);\n const enabled = settingsStore.use.checkedComponents();\n\n const editor = usePlaygroundEditor(\n id,\n scrollSelector ?? `blockSelection-${id}`\n );\n\n return (\n \n \n \n \n \n \n \n \n \n\n
\n \n \n\n \n \n \n \n \n \n \n\n \n \n \n \n\n \n \n \n
\n
\n
\n );\n}\n\nconst DemoIdContext = React.createContext(undefined);\n\nexport function DemoId({\n id,\n children,\n}: {\n children: React.ReactNode;\n id?: string;\n}) {\n return {children};\n}\n\nexport function useDemoId() {\n return React.useContext(DemoIdContext);\n}\n", + "content": "'use client';\n\nimport React, { useRef } from 'react';\n\nimport type { ValueId } from '@/config/customizer-plugins';\n\nimport { cn } from '@udecode/cn';\nimport { AIChatPlugin, CopilotPlugin } from '@udecode/plate-ai/react';\nimport { AlignPlugin } from '@udecode/plate-alignment/react';\nimport { AutoformatPlugin } from '@udecode/plate-autoformat/react';\nimport {\n BoldPlugin,\n CodePlugin,\n ItalicPlugin,\n StrikethroughPlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n UnderlinePlugin,\n} from '@udecode/plate-basic-marks/react';\nimport { BlockquotePlugin } from '@udecode/plate-block-quote/react';\nimport { SingleLinePlugin } from '@udecode/plate-break/react';\nimport { CaptionPlugin } from '@udecode/plate-caption/react';\nimport { CodeBlockPlugin } from '@udecode/plate-code-block/react';\nimport { CommentsPlugin } from '@udecode/plate-comments/react';\nimport {\n ParagraphPlugin,\n Plate,\n usePlateEditor,\n} from '@udecode/plate-common/react';\nimport { DatePlugin } from '@udecode/plate-date/react';\nimport { DndPlugin } from '@udecode/plate-dnd';\nimport { DocxPlugin } from '@udecode/plate-docx';\nimport { EmojiPlugin } from '@udecode/plate-emoji/react';\nimport { ExcalidrawPlugin } from '@udecode/plate-excalidraw/react';\nimport {\n FontBackgroundColorPlugin,\n FontColorPlugin,\n FontSizePlugin,\n} from '@udecode/plate-font/react';\nimport { HEADING_KEYS } from '@udecode/plate-heading';\nimport { HeadingPlugin, TocPlugin } from '@udecode/plate-heading/react';\nimport { HighlightPlugin } from '@udecode/plate-highlight/react';\nimport { HorizontalRulePlugin } from '@udecode/plate-horizontal-rule/react';\nimport { IndentPlugin } from '@udecode/plate-indent/react';\nimport { IndentListPlugin } from '@udecode/plate-indent-list/react';\nimport { JuicePlugin } from '@udecode/plate-juice';\nimport { KbdPlugin } from '@udecode/plate-kbd/react';\nimport { ColumnPlugin } from '@udecode/plate-layout/react';\nimport { LineHeightPlugin } from '@udecode/plate-line-height/react';\nimport { LinkPlugin } from '@udecode/plate-link/react';\nimport { ListPlugin, TodoListPlugin } from '@udecode/plate-list/react';\nimport { MarkdownPlugin } from '@udecode/plate-markdown';\nimport { BaseImagePlugin } from '@udecode/plate-media';\nimport { ImagePlugin, MediaEmbedPlugin } from '@udecode/plate-media/react';\nimport { MentionPlugin } from '@udecode/plate-mention/react';\nimport { NodeIdPlugin } from '@udecode/plate-node-id';\nimport { NormalizeTypesPlugin } from '@udecode/plate-normalizers';\nimport { PlaywrightPlugin } from '@udecode/plate-playwright';\nimport { DeletePlugin, SelectOnBackspacePlugin } from '@udecode/plate-select';\nimport {\n BlockMenuPlugin,\n BlockSelectionPlugin,\n} from '@udecode/plate-selection/react';\nimport { SlashPlugin } from '@udecode/plate-slash-command/react';\nimport { TablePlugin } from '@udecode/plate-table/react';\nimport { TogglePlugin } from '@udecode/plate-toggle/react';\nimport { TrailingBlockPlugin } from '@udecode/plate-trailing-block';\nimport Prism from 'prismjs';\n\nimport { CheckPlugin } from '@/components/context/check-plugin';\nimport { settingsStore } from '@/components/context/settings-store';\nimport { aiPlugins } from '@/lib/plate/demo/plugins/ai-plugins';\nimport { getAutoformatOptions } from '@/lib/plate/demo/plugins/autoformatOptions';\nimport { copilotPlugins } from '@/lib/plate/demo/plugins/copilot-plugins';\nimport { createPlateUI } from '@/plate/create-plate-ui';\nimport { editableProps } from '@/plate/demo/editableProps';\nimport { isEnabled } from '@/plate/demo/is-enabled';\nimport { DragOverCursorPlugin } from '@/plate/demo/plugins/DragOverCursorPlugin';\nimport { exitBreakPlugin } from '@/plate/demo/plugins/exitBreakPlugin';\nimport { resetBlockTypePlugin } from '@/plate/demo/plugins/resetBlockTypePlugin';\nimport { softBreakPlugin } from '@/plate/demo/plugins/softBreakPlugin';\nimport { tabbablePlugin } from '@/plate/demo/plugins/tabbablePlugin';\nimport { commentsData, usersData } from '@/plate/demo/values/commentsValue';\nimport { usePlaygroundValue } from '@/plate/demo/values/usePlaygroundValue';\nimport { BlockContextMenu } from '@/components/plate-ui/block-context-menu';\nimport { CommentsPopover } from '@/components/plate-ui/comments-popover';\nimport {\n CursorOverlay,\n SelectionOverlayPlugin,\n} from '@/components/plate-ui/cursor-overlay';\nimport { Editor, EditorContainer } from '@/components/plate-ui/editor';\nimport { FixedToolbar } from '@/components/plate-ui/fixed-toolbar';\nimport { FixedToolbarButtons } from '@/components/plate-ui/fixed-toolbar-buttons';\nimport { FloatingToolbar } from '@/components/plate-ui/floating-toolbar';\nimport { FloatingToolbarButtons } from '@/components/plate-ui/floating-toolbar-buttons';\nimport { ImagePreview } from '@/components/plate-ui/image-preview';\nimport {\n FireLiComponent,\n FireMarker,\n} from '@/components/plate-ui/indent-fire-marker';\nimport {\n TodoLi,\n TodoMarker,\n} from '@/components/plate-ui/indent-todo-marker';\nimport { LinkFloatingToolbar } from '@/components/plate-ui/link-floating-toolbar';\n\nimport { usePlaygroundEnabled } from './usePlaygroundEnabled';\n\nexport const usePlaygroundEditor = (id: any = '', scrollSelector?: string) => {\n const enabledPlugins = settingsStore.use.checkedPlugins();\n const overridePlugins = usePlaygroundEnabled(id);\n const autoformatOptions = getAutoformatOptions(id, enabledPlugins);\n\n const value = usePlaygroundValue(id);\n const key = settingsStore.use.version();\n const editorId = id || 'playground-' + key;\n\n return usePlateEditor(\n {\n id: editorId,\n override: {\n components: createPlateUI({\n draggable: isEnabled('dnd', id),\n placeholder: isEnabled('placeholder', id),\n }),\n plugins: overridePlugins,\n },\n plugins: [\n // AI\n ...(id === 'ai' || enabledPlugins[AIChatPlugin.key] ? aiPlugins : []),\n ...(id === 'copilot' || enabledPlugins[CopilotPlugin.key]\n ? copilotPlugins\n : []),\n // Nodes\n HeadingPlugin,\n TocPlugin.configure({\n options: {\n scrollContainerSelector: `#${scrollSelector}`,\n topOffset: 80,\n },\n }),\n BlockquotePlugin,\n CodeBlockPlugin.configure({\n options: {\n prism: Prism,\n },\n }),\n HorizontalRulePlugin,\n LinkPlugin.extend({\n render: { afterEditable: () => },\n }),\n ...(id === 'list' ? [ListPlugin] : []),\n ImagePlugin.extend({\n options: {\n disableUploadInsert: true,\n },\n render: { afterEditable: ImagePreview },\n }),\n MediaEmbedPlugin,\n CaptionPlugin.configure({\n options: {\n plugins: [ImagePlugin, MediaEmbedPlugin],\n },\n }),\n DatePlugin,\n MentionPlugin.configure({\n options: {\n triggerPreviousCharPattern: /^$|^[\\s\"']$/,\n },\n }),\n SlashPlugin,\n TablePlugin.configure({\n options: {\n enableMerging: id === 'tableMerge',\n },\n }),\n ColumnPlugin,\n SelectionOverlayPlugin,\n\n TodoListPlugin,\n TogglePlugin,\n ExcalidrawPlugin,\n // Marks\n BoldPlugin,\n ItalicPlugin,\n UnderlinePlugin,\n StrikethroughPlugin,\n CodePlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n FontColorPlugin,\n FontBackgroundColorPlugin,\n FontSizePlugin,\n HighlightPlugin,\n KbdPlugin,\n\n // Block Style\n AlignPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n MediaEmbedPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n ImagePlugin.key,\n HEADING_KEYS.h6,\n ],\n },\n }),\n IndentPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n }),\n IndentListPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n options: {\n listStyleTypes: {\n fire: {\n liComponent: FireLiComponent,\n markerComponent: FireMarker,\n type: 'fire',\n },\n todo: {\n liComponent: TodoLi,\n markerComponent: TodoMarker,\n type: 'todo',\n },\n },\n },\n }),\n LineHeightPlugin.extend({\n inject: {\n nodeProps: {\n defaultNodeValue: 1.5,\n validNodeValues: [1, 1.2, 1.5, 2, 3],\n },\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n ],\n },\n }),\n\n // Functionality\n AutoformatPlugin.configure({\n options: autoformatOptions,\n }),\n BlockSelectionPlugin.configure({\n options: {\n areaOptions: {\n behaviour: {\n scrolling: {\n speedDivider: 1.5,\n },\n startThreshold: 10,\n },\n boundaries: `#${scrollSelector}`,\n container: `#${scrollSelector}`,\n selectables: [`#${scrollSelector} .slate-selectable`],\n selectionAreaClass: 'slate-selection-area',\n },\n enableContextMenu: true,\n },\n }),\n BlockMenuPlugin.configure({\n render: { aboveEditable: BlockContextMenu },\n }),\n DndPlugin.configure({\n options: {\n enableScroller: true,\n onDropFiles: ({ dragItem, editor, target }) => {\n editor\n .getTransforms(BaseImagePlugin)\n .insert.imageFromFiles(dragItem.files, {\n at: target,\n nextBlock: false,\n });\n },\n },\n }),\n EmojiPlugin,\n exitBreakPlugin,\n NodeIdPlugin,\n NormalizeTypesPlugin.configure({\n options: {\n rules: [{ path: [0], strictType: HEADING_KEYS.h1 }],\n },\n }),\n resetBlockTypePlugin,\n SelectOnBackspacePlugin.configure({\n options: {\n query: {\n allow: [ImagePlugin.key, HorizontalRulePlugin.key],\n },\n },\n }),\n DeletePlugin,\n SingleLinePlugin,\n softBreakPlugin,\n tabbablePlugin,\n TrailingBlockPlugin.configure({\n options: { type: ParagraphPlugin.key },\n }),\n DragOverCursorPlugin,\n\n // Collaboration\n CommentsPlugin.configure({\n options: {\n comments: commentsData,\n myUserId: '1',\n users: usersData,\n },\n }),\n\n // Deserialization\n DocxPlugin,\n MarkdownPlugin.configure({ options: { indentList: true } }),\n JuicePlugin,\n\n // Testing\n PlaywrightPlugin.configure({\n enabled: process.env.NODE_ENV !== 'production',\n }),\n ],\n value: value,\n },\n []\n );\n};\n\nexport default function PlaygroundDemo({\n id,\n className,\n scrollSelector,\n}: {\n id?: ValueId;\n className?: string;\n scrollSelector?: string;\n}) {\n const containerRef = useRef(null);\n const enabled = settingsStore.use.checkedComponents();\n\n const editor = usePlaygroundEditor(\n id,\n scrollSelector ?? `blockSelection-${id}`\n );\n\n return (\n \n \n \n \n \n \n \n \n \n\n
\n \n \n\n \n \n \n \n \n \n \n\n \n \n \n \n\n \n \n \n
\n
\n
\n );\n}\n\nconst DemoIdContext = React.createContext(undefined);\n\nexport function DemoId({\n id,\n children,\n}: {\n children: React.ReactNode;\n id?: string;\n}) {\n return {children};\n}\n\nexport function useDemoId() {\n return React.useContext(DemoIdContext);\n}\n", "path": "example/playground-demo.tsx", "target": "components/playground-demo.tsx", "type": "registry:example" diff --git a/apps/www/public/r/styles/default/copilot-demo.json b/apps/www/public/r/styles/default/copilot-demo.json index 41ccfa8853..3ab59fe52d 100644 --- a/apps/www/public/r/styles/default/copilot-demo.json +++ b/apps/www/public/r/styles/default/copilot-demo.json @@ -4,7 +4,7 @@ }, "files": [ { - "content": "'use client';\n\nimport React, { useRef } from 'react';\n\nimport type { ValueId } from '@/config/customizer-plugins';\n\nimport { cn } from '@udecode/cn';\nimport { AIChatPlugin, CopilotPlugin } from '@udecode/plate-ai/react';\nimport { AlignPlugin } from '@udecode/plate-alignment/react';\nimport { AutoformatPlugin } from '@udecode/plate-autoformat/react';\nimport {\n BoldPlugin,\n CodePlugin,\n ItalicPlugin,\n StrikethroughPlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n UnderlinePlugin,\n} from '@udecode/plate-basic-marks/react';\nimport { BlockquotePlugin } from '@udecode/plate-block-quote/react';\nimport { SingleLinePlugin } from '@udecode/plate-break/react';\nimport { CaptionPlugin } from '@udecode/plate-caption/react';\nimport { CodeBlockPlugin } from '@udecode/plate-code-block/react';\nimport { CommentsPlugin } from '@udecode/plate-comments/react';\nimport {\n ParagraphPlugin,\n Plate,\n usePlateEditor,\n} from '@udecode/plate-common/react';\nimport { DatePlugin } from '@udecode/plate-date/react';\nimport { DndPlugin } from '@udecode/plate-dnd';\nimport { DocxPlugin } from '@udecode/plate-docx';\nimport { EmojiPlugin } from '@udecode/plate-emoji/react';\nimport { ExcalidrawPlugin } from '@udecode/plate-excalidraw/react';\nimport {\n FontBackgroundColorPlugin,\n FontColorPlugin,\n FontSizePlugin,\n} from '@udecode/plate-font/react';\nimport { HEADING_KEYS } from '@udecode/plate-heading';\nimport { HeadingPlugin, TocPlugin } from '@udecode/plate-heading/react';\nimport { HighlightPlugin } from '@udecode/plate-highlight/react';\nimport { HorizontalRulePlugin } from '@udecode/plate-horizontal-rule/react';\nimport { IndentPlugin } from '@udecode/plate-indent/react';\nimport { IndentListPlugin } from '@udecode/plate-indent-list/react';\nimport { JuicePlugin } from '@udecode/plate-juice';\nimport { KbdPlugin } from '@udecode/plate-kbd/react';\nimport { ColumnPlugin } from '@udecode/plate-layout/react';\nimport { LineHeightPlugin } from '@udecode/plate-line-height/react';\nimport { LinkPlugin } from '@udecode/plate-link/react';\nimport { ListPlugin, TodoListPlugin } from '@udecode/plate-list/react';\nimport { MarkdownPlugin } from '@udecode/plate-markdown';\nimport { ImagePlugin, MediaEmbedPlugin } from '@udecode/plate-media/react';\nimport { MentionPlugin } from '@udecode/plate-mention/react';\nimport { NodeIdPlugin } from '@udecode/plate-node-id';\nimport { NormalizeTypesPlugin } from '@udecode/plate-normalizers';\nimport { PlaywrightPlugin } from '@udecode/plate-playwright';\nimport { DeletePlugin, SelectOnBackspacePlugin } from '@udecode/plate-select';\nimport {\n BlockMenuPlugin,\n BlockSelectionPlugin,\n} from '@udecode/plate-selection/react';\nimport { SlashPlugin } from '@udecode/plate-slash-command/react';\nimport { TablePlugin } from '@udecode/plate-table/react';\nimport { TogglePlugin } from '@udecode/plate-toggle/react';\nimport { TrailingBlockPlugin } from '@udecode/plate-trailing-block';\nimport Prism from 'prismjs';\n\nimport { CheckPlugin } from '@/components/context/check-plugin';\nimport { settingsStore } from '@/components/context/settings-store';\nimport { aiPlugins } from '@/lib/plate/demo/plugins/ai-plugins';\nimport { getAutoformatOptions } from '@/lib/plate/demo/plugins/autoformatOptions';\nimport { copilotPlugins } from '@/lib/plate/demo/plugins/copilot-plugins';\nimport { createPlateUI } from '@/plate/create-plate-ui';\nimport { editableProps } from '@/plate/demo/editableProps';\nimport { isEnabled } from '@/plate/demo/is-enabled';\nimport { DragOverCursorPlugin } from '@/plate/demo/plugins/DragOverCursorPlugin';\nimport { exitBreakPlugin } from '@/plate/demo/plugins/exitBreakPlugin';\nimport { resetBlockTypePlugin } from '@/plate/demo/plugins/resetBlockTypePlugin';\nimport { softBreakPlugin } from '@/plate/demo/plugins/softBreakPlugin';\nimport { tabbablePlugin } from '@/plate/demo/plugins/tabbablePlugin';\nimport { commentsData, usersData } from '@/plate/demo/values/commentsValue';\nimport { usePlaygroundValue } from '@/plate/demo/values/usePlaygroundValue';\nimport { BlockContextMenu } from '@/components/plate-ui/block-context-menu';\nimport { CommentsPopover } from '@/components/plate-ui/comments-popover';\nimport {\n CursorOverlay,\n SelectionOverlayPlugin,\n} from '@/components/plate-ui/cursor-overlay';\nimport { Editor, EditorContainer } from '@/components/plate-ui/editor';\nimport { FixedToolbar } from '@/components/plate-ui/fixed-toolbar';\nimport { FixedToolbarButtons } from '@/components/plate-ui/fixed-toolbar-buttons';\nimport { FloatingToolbar } from '@/components/plate-ui/floating-toolbar';\nimport { FloatingToolbarButtons } from '@/components/plate-ui/floating-toolbar-buttons';\nimport { ImagePreview } from '@/components/plate-ui/image-preview';\nimport {\n FireLiComponent,\n FireMarker,\n} from '@/components/plate-ui/indent-fire-marker';\nimport {\n TodoLi,\n TodoMarker,\n} from '@/components/plate-ui/indent-todo-marker';\nimport { LinkFloatingToolbar } from '@/components/plate-ui/link-floating-toolbar';\n\nimport { usePlaygroundEnabled } from './usePlaygroundEnabled';\n\nexport const usePlaygroundEditor = (id: any = '', scrollSelector?: string) => {\n const enabledPlugins = settingsStore.use.checkedPlugins();\n const overridePlugins = usePlaygroundEnabled(id);\n const autoformatOptions = getAutoformatOptions(id, enabledPlugins);\n\n const value = usePlaygroundValue(id);\n const key = settingsStore.use.version();\n const editorId = id || 'playground-' + key;\n\n return usePlateEditor(\n {\n id: editorId,\n override: {\n components: createPlateUI({\n draggable: isEnabled('dnd', id),\n placeholder: isEnabled('placeholder', id),\n }),\n plugins: overridePlugins,\n },\n plugins: [\n // AI\n ...(id === 'ai' || enabledPlugins[AIChatPlugin.key] ? aiPlugins : []),\n ...(id === 'copilot' || enabledPlugins[CopilotPlugin.key]\n ? copilotPlugins\n : []),\n // Nodes\n HeadingPlugin,\n TocPlugin.configure({\n options: {\n scrollContainerSelector: `#${scrollSelector}`,\n topOffset: 80,\n },\n }),\n BlockquotePlugin,\n CodeBlockPlugin.configure({\n options: {\n prism: Prism,\n },\n }),\n HorizontalRulePlugin,\n LinkPlugin.extend({\n render: { afterEditable: () => },\n }),\n ...(id === 'list' ? [ListPlugin] : []),\n ImagePlugin.extend({\n options: {\n disableUploadInsert: true,\n },\n render: { afterEditable: ImagePreview },\n }),\n MediaEmbedPlugin,\n CaptionPlugin.configure({\n options: {\n plugins: [ImagePlugin, MediaEmbedPlugin],\n },\n }),\n DatePlugin,\n MentionPlugin.configure({\n options: {\n triggerPreviousCharPattern: /^$|^[\\s\"']$/,\n },\n }),\n SlashPlugin,\n TablePlugin.configure({\n options: {\n enableMerging: id === 'tableMerge',\n },\n }),\n ColumnPlugin,\n SelectionOverlayPlugin,\n\n TodoListPlugin,\n TogglePlugin,\n ExcalidrawPlugin,\n // Marks\n BoldPlugin,\n ItalicPlugin,\n UnderlinePlugin,\n StrikethroughPlugin,\n CodePlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n FontColorPlugin,\n FontBackgroundColorPlugin,\n FontSizePlugin,\n HighlightPlugin,\n KbdPlugin,\n\n // Block Style\n AlignPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n MediaEmbedPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n ImagePlugin.key,\n HEADING_KEYS.h6,\n ],\n },\n }),\n IndentPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n }),\n IndentListPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n options: {\n listStyleTypes: {\n fire: {\n liComponent: FireLiComponent,\n markerComponent: FireMarker,\n type: 'fire',\n },\n todo: {\n liComponent: TodoLi,\n markerComponent: TodoMarker,\n type: 'todo',\n },\n },\n },\n }),\n LineHeightPlugin.extend({\n inject: {\n nodeProps: {\n defaultNodeValue: 1.5,\n validNodeValues: [1, 1.2, 1.5, 2, 3],\n },\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n ],\n },\n }),\n\n // Functionality\n AutoformatPlugin.configure({\n options: autoformatOptions,\n }),\n BlockSelectionPlugin.configure({\n options: {\n areaOptions: {\n behaviour: {\n scrolling: {\n speedDivider: 1.5,\n },\n startThreshold: 10,\n },\n boundaries: `#${scrollSelector}`,\n container: `#${scrollSelector}`,\n selectables: [`#${scrollSelector} .slate-selectable`],\n selectionAreaClass: 'slate-selection-area',\n },\n enableContextMenu: true,\n },\n }),\n BlockMenuPlugin.configure({\n render: { aboveEditable: BlockContextMenu },\n }),\n DndPlugin.configure({\n options: {\n enableScroller: true,\n onDropFiles: ({ dragItem, editor, target }) => {\n editor\n .getTransforms(ImagePlugin)\n .insertImageFromFiles(dragItem.files, {\n at: target,\n nextBlock: false,\n });\n },\n },\n }),\n EmojiPlugin,\n exitBreakPlugin,\n NodeIdPlugin,\n NormalizeTypesPlugin.configure({\n options: {\n rules: [{ path: [0], strictType: HEADING_KEYS.h1 }],\n },\n }),\n resetBlockTypePlugin,\n SelectOnBackspacePlugin.configure({\n options: {\n query: {\n allow: [ImagePlugin.key, HorizontalRulePlugin.key],\n },\n },\n }),\n DeletePlugin,\n SingleLinePlugin,\n softBreakPlugin,\n tabbablePlugin,\n TrailingBlockPlugin.configure({\n options: { type: ParagraphPlugin.key },\n }),\n DragOverCursorPlugin,\n\n // Collaboration\n CommentsPlugin.configure({\n options: {\n comments: commentsData,\n myUserId: '1',\n users: usersData,\n },\n }),\n\n // Deserialization\n DocxPlugin,\n MarkdownPlugin.configure({ options: { indentList: true } }),\n JuicePlugin,\n\n // Testing\n PlaywrightPlugin.configure({\n enabled: process.env.NODE_ENV !== 'production',\n }),\n ],\n value: value,\n },\n []\n );\n};\n\nexport default function PlaygroundDemo({\n id,\n className,\n scrollSelector,\n}: {\n id?: ValueId;\n className?: string;\n scrollSelector?: string;\n}) {\n const containerRef = useRef(null);\n const enabled = settingsStore.use.checkedComponents();\n\n const editor = usePlaygroundEditor(\n id,\n scrollSelector ?? `blockSelection-${id}`\n );\n\n return (\n \n \n \n \n \n \n \n \n \n\n
\n \n \n\n \n \n \n \n \n \n \n\n \n \n \n \n\n \n \n \n
\n
\n
\n );\n}\n\nconst DemoIdContext = React.createContext(undefined);\n\nexport function DemoId({\n id,\n children,\n}: {\n children: React.ReactNode;\n id?: string;\n}) {\n return {children};\n}\n\nexport function useDemoId() {\n return React.useContext(DemoIdContext);\n}\n", + "content": "'use client';\n\nimport React, { useRef } from 'react';\n\nimport type { ValueId } from '@/config/customizer-plugins';\n\nimport { cn } from '@udecode/cn';\nimport { AIChatPlugin, CopilotPlugin } from '@udecode/plate-ai/react';\nimport { AlignPlugin } from '@udecode/plate-alignment/react';\nimport { AutoformatPlugin } from '@udecode/plate-autoformat/react';\nimport {\n BoldPlugin,\n CodePlugin,\n ItalicPlugin,\n StrikethroughPlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n UnderlinePlugin,\n} from '@udecode/plate-basic-marks/react';\nimport { BlockquotePlugin } from '@udecode/plate-block-quote/react';\nimport { SingleLinePlugin } from '@udecode/plate-break/react';\nimport { CaptionPlugin } from '@udecode/plate-caption/react';\nimport { CodeBlockPlugin } from '@udecode/plate-code-block/react';\nimport { CommentsPlugin } from '@udecode/plate-comments/react';\nimport {\n ParagraphPlugin,\n Plate,\n usePlateEditor,\n} from '@udecode/plate-common/react';\nimport { DatePlugin } from '@udecode/plate-date/react';\nimport { DndPlugin } from '@udecode/plate-dnd';\nimport { DocxPlugin } from '@udecode/plate-docx';\nimport { EmojiPlugin } from '@udecode/plate-emoji/react';\nimport { ExcalidrawPlugin } from '@udecode/plate-excalidraw/react';\nimport {\n FontBackgroundColorPlugin,\n FontColorPlugin,\n FontSizePlugin,\n} from '@udecode/plate-font/react';\nimport { HEADING_KEYS } from '@udecode/plate-heading';\nimport { HeadingPlugin, TocPlugin } from '@udecode/plate-heading/react';\nimport { HighlightPlugin } from '@udecode/plate-highlight/react';\nimport { HorizontalRulePlugin } from '@udecode/plate-horizontal-rule/react';\nimport { IndentPlugin } from '@udecode/plate-indent/react';\nimport { IndentListPlugin } from '@udecode/plate-indent-list/react';\nimport { JuicePlugin } from '@udecode/plate-juice';\nimport { KbdPlugin } from '@udecode/plate-kbd/react';\nimport { ColumnPlugin } from '@udecode/plate-layout/react';\nimport { LineHeightPlugin } from '@udecode/plate-line-height/react';\nimport { LinkPlugin } from '@udecode/plate-link/react';\nimport { ListPlugin, TodoListPlugin } from '@udecode/plate-list/react';\nimport { MarkdownPlugin } from '@udecode/plate-markdown';\nimport { BaseImagePlugin } from '@udecode/plate-media';\nimport { ImagePlugin, MediaEmbedPlugin } from '@udecode/plate-media/react';\nimport { MentionPlugin } from '@udecode/plate-mention/react';\nimport { NodeIdPlugin } from '@udecode/plate-node-id';\nimport { NormalizeTypesPlugin } from '@udecode/plate-normalizers';\nimport { PlaywrightPlugin } from '@udecode/plate-playwright';\nimport { DeletePlugin, SelectOnBackspacePlugin } from '@udecode/plate-select';\nimport {\n BlockMenuPlugin,\n BlockSelectionPlugin,\n} from '@udecode/plate-selection/react';\nimport { SlashPlugin } from '@udecode/plate-slash-command/react';\nimport { TablePlugin } from '@udecode/plate-table/react';\nimport { TogglePlugin } from '@udecode/plate-toggle/react';\nimport { TrailingBlockPlugin } from '@udecode/plate-trailing-block';\nimport Prism from 'prismjs';\n\nimport { CheckPlugin } from '@/components/context/check-plugin';\nimport { settingsStore } from '@/components/context/settings-store';\nimport { aiPlugins } from '@/lib/plate/demo/plugins/ai-plugins';\nimport { getAutoformatOptions } from '@/lib/plate/demo/plugins/autoformatOptions';\nimport { copilotPlugins } from '@/lib/plate/demo/plugins/copilot-plugins';\nimport { createPlateUI } from '@/plate/create-plate-ui';\nimport { editableProps } from '@/plate/demo/editableProps';\nimport { isEnabled } from '@/plate/demo/is-enabled';\nimport { DragOverCursorPlugin } from '@/plate/demo/plugins/DragOverCursorPlugin';\nimport { exitBreakPlugin } from '@/plate/demo/plugins/exitBreakPlugin';\nimport { resetBlockTypePlugin } from '@/plate/demo/plugins/resetBlockTypePlugin';\nimport { softBreakPlugin } from '@/plate/demo/plugins/softBreakPlugin';\nimport { tabbablePlugin } from '@/plate/demo/plugins/tabbablePlugin';\nimport { commentsData, usersData } from '@/plate/demo/values/commentsValue';\nimport { usePlaygroundValue } from '@/plate/demo/values/usePlaygroundValue';\nimport { BlockContextMenu } from '@/components/plate-ui/block-context-menu';\nimport { CommentsPopover } from '@/components/plate-ui/comments-popover';\nimport {\n CursorOverlay,\n SelectionOverlayPlugin,\n} from '@/components/plate-ui/cursor-overlay';\nimport { Editor, EditorContainer } from '@/components/plate-ui/editor';\nimport { FixedToolbar } from '@/components/plate-ui/fixed-toolbar';\nimport { FixedToolbarButtons } from '@/components/plate-ui/fixed-toolbar-buttons';\nimport { FloatingToolbar } from '@/components/plate-ui/floating-toolbar';\nimport { FloatingToolbarButtons } from '@/components/plate-ui/floating-toolbar-buttons';\nimport { ImagePreview } from '@/components/plate-ui/image-preview';\nimport {\n FireLiComponent,\n FireMarker,\n} from '@/components/plate-ui/indent-fire-marker';\nimport {\n TodoLi,\n TodoMarker,\n} from '@/components/plate-ui/indent-todo-marker';\nimport { LinkFloatingToolbar } from '@/components/plate-ui/link-floating-toolbar';\n\nimport { usePlaygroundEnabled } from './usePlaygroundEnabled';\n\nexport const usePlaygroundEditor = (id: any = '', scrollSelector?: string) => {\n const enabledPlugins = settingsStore.use.checkedPlugins();\n const overridePlugins = usePlaygroundEnabled(id);\n const autoformatOptions = getAutoformatOptions(id, enabledPlugins);\n\n const value = usePlaygroundValue(id);\n const key = settingsStore.use.version();\n const editorId = id || 'playground-' + key;\n\n return usePlateEditor(\n {\n id: editorId,\n override: {\n components: createPlateUI({\n draggable: isEnabled('dnd', id),\n placeholder: isEnabled('placeholder', id),\n }),\n plugins: overridePlugins,\n },\n plugins: [\n // AI\n ...(id === 'ai' || enabledPlugins[AIChatPlugin.key] ? aiPlugins : []),\n ...(id === 'copilot' || enabledPlugins[CopilotPlugin.key]\n ? copilotPlugins\n : []),\n // Nodes\n HeadingPlugin,\n TocPlugin.configure({\n options: {\n scrollContainerSelector: `#${scrollSelector}`,\n topOffset: 80,\n },\n }),\n BlockquotePlugin,\n CodeBlockPlugin.configure({\n options: {\n prism: Prism,\n },\n }),\n HorizontalRulePlugin,\n LinkPlugin.extend({\n render: { afterEditable: () => },\n }),\n ...(id === 'list' ? [ListPlugin] : []),\n ImagePlugin.extend({\n options: {\n disableUploadInsert: true,\n },\n render: { afterEditable: ImagePreview },\n }),\n MediaEmbedPlugin,\n CaptionPlugin.configure({\n options: {\n plugins: [ImagePlugin, MediaEmbedPlugin],\n },\n }),\n DatePlugin,\n MentionPlugin.configure({\n options: {\n triggerPreviousCharPattern: /^$|^[\\s\"']$/,\n },\n }),\n SlashPlugin,\n TablePlugin.configure({\n options: {\n enableMerging: id === 'tableMerge',\n },\n }),\n ColumnPlugin,\n SelectionOverlayPlugin,\n\n TodoListPlugin,\n TogglePlugin,\n ExcalidrawPlugin,\n // Marks\n BoldPlugin,\n ItalicPlugin,\n UnderlinePlugin,\n StrikethroughPlugin,\n CodePlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n FontColorPlugin,\n FontBackgroundColorPlugin,\n FontSizePlugin,\n HighlightPlugin,\n KbdPlugin,\n\n // Block Style\n AlignPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n MediaEmbedPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n ImagePlugin.key,\n HEADING_KEYS.h6,\n ],\n },\n }),\n IndentPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n }),\n IndentListPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n options: {\n listStyleTypes: {\n fire: {\n liComponent: FireLiComponent,\n markerComponent: FireMarker,\n type: 'fire',\n },\n todo: {\n liComponent: TodoLi,\n markerComponent: TodoMarker,\n type: 'todo',\n },\n },\n },\n }),\n LineHeightPlugin.extend({\n inject: {\n nodeProps: {\n defaultNodeValue: 1.5,\n validNodeValues: [1, 1.2, 1.5, 2, 3],\n },\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n ],\n },\n }),\n\n // Functionality\n AutoformatPlugin.configure({\n options: autoformatOptions,\n }),\n BlockSelectionPlugin.configure({\n options: {\n areaOptions: {\n behaviour: {\n scrolling: {\n speedDivider: 1.5,\n },\n startThreshold: 10,\n },\n boundaries: `#${scrollSelector}`,\n container: `#${scrollSelector}`,\n selectables: [`#${scrollSelector} .slate-selectable`],\n selectionAreaClass: 'slate-selection-area',\n },\n enableContextMenu: true,\n },\n }),\n BlockMenuPlugin.configure({\n render: { aboveEditable: BlockContextMenu },\n }),\n DndPlugin.configure({\n options: {\n enableScroller: true,\n onDropFiles: ({ dragItem, editor, target }) => {\n editor\n .getTransforms(BaseImagePlugin)\n .insert.imageFromFiles(dragItem.files, {\n at: target,\n nextBlock: false,\n });\n },\n },\n }),\n EmojiPlugin,\n exitBreakPlugin,\n NodeIdPlugin,\n NormalizeTypesPlugin.configure({\n options: {\n rules: [{ path: [0], strictType: HEADING_KEYS.h1 }],\n },\n }),\n resetBlockTypePlugin,\n SelectOnBackspacePlugin.configure({\n options: {\n query: {\n allow: [ImagePlugin.key, HorizontalRulePlugin.key],\n },\n },\n }),\n DeletePlugin,\n SingleLinePlugin,\n softBreakPlugin,\n tabbablePlugin,\n TrailingBlockPlugin.configure({\n options: { type: ParagraphPlugin.key },\n }),\n DragOverCursorPlugin,\n\n // Collaboration\n CommentsPlugin.configure({\n options: {\n comments: commentsData,\n myUserId: '1',\n users: usersData,\n },\n }),\n\n // Deserialization\n DocxPlugin,\n MarkdownPlugin.configure({ options: { indentList: true } }),\n JuicePlugin,\n\n // Testing\n PlaywrightPlugin.configure({\n enabled: process.env.NODE_ENV !== 'production',\n }),\n ],\n value: value,\n },\n []\n );\n};\n\nexport default function PlaygroundDemo({\n id,\n className,\n scrollSelector,\n}: {\n id?: ValueId;\n className?: string;\n scrollSelector?: string;\n}) {\n const containerRef = useRef(null);\n const enabled = settingsStore.use.checkedComponents();\n\n const editor = usePlaygroundEditor(\n id,\n scrollSelector ?? `blockSelection-${id}`\n );\n\n return (\n \n \n \n \n \n \n \n \n \n\n
\n \n \n\n \n \n \n \n \n \n \n\n \n \n \n \n\n \n \n \n
\n
\n
\n );\n}\n\nconst DemoIdContext = React.createContext(undefined);\n\nexport function DemoId({\n id,\n children,\n}: {\n children: React.ReactNode;\n id?: string;\n}) {\n return {children};\n}\n\nexport function useDemoId() {\n return React.useContext(DemoIdContext);\n}\n", "path": "example/playground-demo.tsx", "target": "components/playground-demo.tsx", "type": "registry:example" diff --git a/apps/www/public/r/styles/default/date-demo.json b/apps/www/public/r/styles/default/date-demo.json index 0d3d98040b..9f10a29f44 100644 --- a/apps/www/public/r/styles/default/date-demo.json +++ b/apps/www/public/r/styles/default/date-demo.json @@ -5,7 +5,7 @@ }, "files": [ { - "content": "'use client';\n\nimport React, { useRef } from 'react';\n\nimport type { ValueId } from '@/config/customizer-plugins';\n\nimport { cn } from '@udecode/cn';\nimport { AIChatPlugin, CopilotPlugin } from '@udecode/plate-ai/react';\nimport { AlignPlugin } from '@udecode/plate-alignment/react';\nimport { AutoformatPlugin } from '@udecode/plate-autoformat/react';\nimport {\n BoldPlugin,\n CodePlugin,\n ItalicPlugin,\n StrikethroughPlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n UnderlinePlugin,\n} from '@udecode/plate-basic-marks/react';\nimport { BlockquotePlugin } from '@udecode/plate-block-quote/react';\nimport { SingleLinePlugin } from '@udecode/plate-break/react';\nimport { CaptionPlugin } from '@udecode/plate-caption/react';\nimport { CodeBlockPlugin } from '@udecode/plate-code-block/react';\nimport { CommentsPlugin } from '@udecode/plate-comments/react';\nimport {\n ParagraphPlugin,\n Plate,\n usePlateEditor,\n} from '@udecode/plate-common/react';\nimport { DatePlugin } from '@udecode/plate-date/react';\nimport { DndPlugin } from '@udecode/plate-dnd';\nimport { DocxPlugin } from '@udecode/plate-docx';\nimport { EmojiPlugin } from '@udecode/plate-emoji/react';\nimport { ExcalidrawPlugin } from '@udecode/plate-excalidraw/react';\nimport {\n FontBackgroundColorPlugin,\n FontColorPlugin,\n FontSizePlugin,\n} from '@udecode/plate-font/react';\nimport { HEADING_KEYS } from '@udecode/plate-heading';\nimport { HeadingPlugin, TocPlugin } from '@udecode/plate-heading/react';\nimport { HighlightPlugin } from '@udecode/plate-highlight/react';\nimport { HorizontalRulePlugin } from '@udecode/plate-horizontal-rule/react';\nimport { IndentPlugin } from '@udecode/plate-indent/react';\nimport { IndentListPlugin } from '@udecode/plate-indent-list/react';\nimport { JuicePlugin } from '@udecode/plate-juice';\nimport { KbdPlugin } from '@udecode/plate-kbd/react';\nimport { ColumnPlugin } from '@udecode/plate-layout/react';\nimport { LineHeightPlugin } from '@udecode/plate-line-height/react';\nimport { LinkPlugin } from '@udecode/plate-link/react';\nimport { ListPlugin, TodoListPlugin } from '@udecode/plate-list/react';\nimport { MarkdownPlugin } from '@udecode/plate-markdown';\nimport { ImagePlugin, MediaEmbedPlugin } from '@udecode/plate-media/react';\nimport { MentionPlugin } from '@udecode/plate-mention/react';\nimport { NodeIdPlugin } from '@udecode/plate-node-id';\nimport { NormalizeTypesPlugin } from '@udecode/plate-normalizers';\nimport { PlaywrightPlugin } from '@udecode/plate-playwright';\nimport { DeletePlugin, SelectOnBackspacePlugin } from '@udecode/plate-select';\nimport {\n BlockMenuPlugin,\n BlockSelectionPlugin,\n} from '@udecode/plate-selection/react';\nimport { SlashPlugin } from '@udecode/plate-slash-command/react';\nimport { TablePlugin } from '@udecode/plate-table/react';\nimport { TogglePlugin } from '@udecode/plate-toggle/react';\nimport { TrailingBlockPlugin } from '@udecode/plate-trailing-block';\nimport Prism from 'prismjs';\n\nimport { CheckPlugin } from '@/components/context/check-plugin';\nimport { settingsStore } from '@/components/context/settings-store';\nimport { aiPlugins } from '@/lib/plate/demo/plugins/ai-plugins';\nimport { getAutoformatOptions } from '@/lib/plate/demo/plugins/autoformatOptions';\nimport { copilotPlugins } from '@/lib/plate/demo/plugins/copilot-plugins';\nimport { createPlateUI } from '@/plate/create-plate-ui';\nimport { editableProps } from '@/plate/demo/editableProps';\nimport { isEnabled } from '@/plate/demo/is-enabled';\nimport { DragOverCursorPlugin } from '@/plate/demo/plugins/DragOverCursorPlugin';\nimport { exitBreakPlugin } from '@/plate/demo/plugins/exitBreakPlugin';\nimport { resetBlockTypePlugin } from '@/plate/demo/plugins/resetBlockTypePlugin';\nimport { softBreakPlugin } from '@/plate/demo/plugins/softBreakPlugin';\nimport { tabbablePlugin } from '@/plate/demo/plugins/tabbablePlugin';\nimport { commentsData, usersData } from '@/plate/demo/values/commentsValue';\nimport { usePlaygroundValue } from '@/plate/demo/values/usePlaygroundValue';\nimport { BlockContextMenu } from '@/components/plate-ui/block-context-menu';\nimport { CommentsPopover } from '@/components/plate-ui/comments-popover';\nimport {\n CursorOverlay,\n SelectionOverlayPlugin,\n} from '@/components/plate-ui/cursor-overlay';\nimport { Editor, EditorContainer } from '@/components/plate-ui/editor';\nimport { FixedToolbar } from '@/components/plate-ui/fixed-toolbar';\nimport { FixedToolbarButtons } from '@/components/plate-ui/fixed-toolbar-buttons';\nimport { FloatingToolbar } from '@/components/plate-ui/floating-toolbar';\nimport { FloatingToolbarButtons } from '@/components/plate-ui/floating-toolbar-buttons';\nimport { ImagePreview } from '@/components/plate-ui/image-preview';\nimport {\n FireLiComponent,\n FireMarker,\n} from '@/components/plate-ui/indent-fire-marker';\nimport {\n TodoLi,\n TodoMarker,\n} from '@/components/plate-ui/indent-todo-marker';\nimport { LinkFloatingToolbar } from '@/components/plate-ui/link-floating-toolbar';\n\nimport { usePlaygroundEnabled } from './usePlaygroundEnabled';\n\nexport const usePlaygroundEditor = (id: any = '', scrollSelector?: string) => {\n const enabledPlugins = settingsStore.use.checkedPlugins();\n const overridePlugins = usePlaygroundEnabled(id);\n const autoformatOptions = getAutoformatOptions(id, enabledPlugins);\n\n const value = usePlaygroundValue(id);\n const key = settingsStore.use.version();\n const editorId = id || 'playground-' + key;\n\n return usePlateEditor(\n {\n id: editorId,\n override: {\n components: createPlateUI({\n draggable: isEnabled('dnd', id),\n placeholder: isEnabled('placeholder', id),\n }),\n plugins: overridePlugins,\n },\n plugins: [\n // AI\n ...(id === 'ai' || enabledPlugins[AIChatPlugin.key] ? aiPlugins : []),\n ...(id === 'copilot' || enabledPlugins[CopilotPlugin.key]\n ? copilotPlugins\n : []),\n // Nodes\n HeadingPlugin,\n TocPlugin.configure({\n options: {\n scrollContainerSelector: `#${scrollSelector}`,\n topOffset: 80,\n },\n }),\n BlockquotePlugin,\n CodeBlockPlugin.configure({\n options: {\n prism: Prism,\n },\n }),\n HorizontalRulePlugin,\n LinkPlugin.extend({\n render: { afterEditable: () => },\n }),\n ...(id === 'list' ? [ListPlugin] : []),\n ImagePlugin.extend({\n options: {\n disableUploadInsert: true,\n },\n render: { afterEditable: ImagePreview },\n }),\n MediaEmbedPlugin,\n CaptionPlugin.configure({\n options: {\n plugins: [ImagePlugin, MediaEmbedPlugin],\n },\n }),\n DatePlugin,\n MentionPlugin.configure({\n options: {\n triggerPreviousCharPattern: /^$|^[\\s\"']$/,\n },\n }),\n SlashPlugin,\n TablePlugin.configure({\n options: {\n enableMerging: id === 'tableMerge',\n },\n }),\n ColumnPlugin,\n SelectionOverlayPlugin,\n\n TodoListPlugin,\n TogglePlugin,\n ExcalidrawPlugin,\n // Marks\n BoldPlugin,\n ItalicPlugin,\n UnderlinePlugin,\n StrikethroughPlugin,\n CodePlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n FontColorPlugin,\n FontBackgroundColorPlugin,\n FontSizePlugin,\n HighlightPlugin,\n KbdPlugin,\n\n // Block Style\n AlignPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n MediaEmbedPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n ImagePlugin.key,\n HEADING_KEYS.h6,\n ],\n },\n }),\n IndentPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n }),\n IndentListPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n options: {\n listStyleTypes: {\n fire: {\n liComponent: FireLiComponent,\n markerComponent: FireMarker,\n type: 'fire',\n },\n todo: {\n liComponent: TodoLi,\n markerComponent: TodoMarker,\n type: 'todo',\n },\n },\n },\n }),\n LineHeightPlugin.extend({\n inject: {\n nodeProps: {\n defaultNodeValue: 1.5,\n validNodeValues: [1, 1.2, 1.5, 2, 3],\n },\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n ],\n },\n }),\n\n // Functionality\n AutoformatPlugin.configure({\n options: autoformatOptions,\n }),\n BlockSelectionPlugin.configure({\n options: {\n areaOptions: {\n behaviour: {\n scrolling: {\n speedDivider: 1.5,\n },\n startThreshold: 10,\n },\n boundaries: `#${scrollSelector}`,\n container: `#${scrollSelector}`,\n selectables: [`#${scrollSelector} .slate-selectable`],\n selectionAreaClass: 'slate-selection-area',\n },\n enableContextMenu: true,\n },\n }),\n BlockMenuPlugin.configure({\n render: { aboveEditable: BlockContextMenu },\n }),\n DndPlugin.configure({\n options: {\n enableScroller: true,\n onDropFiles: ({ dragItem, editor, target }) => {\n editor\n .getTransforms(ImagePlugin)\n .insertImageFromFiles(dragItem.files, {\n at: target,\n nextBlock: false,\n });\n },\n },\n }),\n EmojiPlugin,\n exitBreakPlugin,\n NodeIdPlugin,\n NormalizeTypesPlugin.configure({\n options: {\n rules: [{ path: [0], strictType: HEADING_KEYS.h1 }],\n },\n }),\n resetBlockTypePlugin,\n SelectOnBackspacePlugin.configure({\n options: {\n query: {\n allow: [ImagePlugin.key, HorizontalRulePlugin.key],\n },\n },\n }),\n DeletePlugin,\n SingleLinePlugin,\n softBreakPlugin,\n tabbablePlugin,\n TrailingBlockPlugin.configure({\n options: { type: ParagraphPlugin.key },\n }),\n DragOverCursorPlugin,\n\n // Collaboration\n CommentsPlugin.configure({\n options: {\n comments: commentsData,\n myUserId: '1',\n users: usersData,\n },\n }),\n\n // Deserialization\n DocxPlugin,\n MarkdownPlugin.configure({ options: { indentList: true } }),\n JuicePlugin,\n\n // Testing\n PlaywrightPlugin.configure({\n enabled: process.env.NODE_ENV !== 'production',\n }),\n ],\n value: value,\n },\n []\n );\n};\n\nexport default function PlaygroundDemo({\n id,\n className,\n scrollSelector,\n}: {\n id?: ValueId;\n className?: string;\n scrollSelector?: string;\n}) {\n const containerRef = useRef(null);\n const enabled = settingsStore.use.checkedComponents();\n\n const editor = usePlaygroundEditor(\n id,\n scrollSelector ?? `blockSelection-${id}`\n );\n\n return (\n \n \n \n \n \n \n \n \n \n\n
\n \n \n\n \n \n \n \n \n \n \n\n \n \n \n \n\n \n \n \n
\n
\n
\n );\n}\n\nconst DemoIdContext = React.createContext(undefined);\n\nexport function DemoId({\n id,\n children,\n}: {\n children: React.ReactNode;\n id?: string;\n}) {\n return {children};\n}\n\nexport function useDemoId() {\n return React.useContext(DemoIdContext);\n}\n", + "content": "'use client';\n\nimport React, { useRef } from 'react';\n\nimport type { ValueId } from '@/config/customizer-plugins';\n\nimport { cn } from '@udecode/cn';\nimport { AIChatPlugin, CopilotPlugin } from '@udecode/plate-ai/react';\nimport { AlignPlugin } from '@udecode/plate-alignment/react';\nimport { AutoformatPlugin } from '@udecode/plate-autoformat/react';\nimport {\n BoldPlugin,\n CodePlugin,\n ItalicPlugin,\n StrikethroughPlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n UnderlinePlugin,\n} from '@udecode/plate-basic-marks/react';\nimport { BlockquotePlugin } from '@udecode/plate-block-quote/react';\nimport { SingleLinePlugin } from '@udecode/plate-break/react';\nimport { CaptionPlugin } from '@udecode/plate-caption/react';\nimport { CodeBlockPlugin } from '@udecode/plate-code-block/react';\nimport { CommentsPlugin } from '@udecode/plate-comments/react';\nimport {\n ParagraphPlugin,\n Plate,\n usePlateEditor,\n} from '@udecode/plate-common/react';\nimport { DatePlugin } from '@udecode/plate-date/react';\nimport { DndPlugin } from '@udecode/plate-dnd';\nimport { DocxPlugin } from '@udecode/plate-docx';\nimport { EmojiPlugin } from '@udecode/plate-emoji/react';\nimport { ExcalidrawPlugin } from '@udecode/plate-excalidraw/react';\nimport {\n FontBackgroundColorPlugin,\n FontColorPlugin,\n FontSizePlugin,\n} from '@udecode/plate-font/react';\nimport { HEADING_KEYS } from '@udecode/plate-heading';\nimport { HeadingPlugin, TocPlugin } from '@udecode/plate-heading/react';\nimport { HighlightPlugin } from '@udecode/plate-highlight/react';\nimport { HorizontalRulePlugin } from '@udecode/plate-horizontal-rule/react';\nimport { IndentPlugin } from '@udecode/plate-indent/react';\nimport { IndentListPlugin } from '@udecode/plate-indent-list/react';\nimport { JuicePlugin } from '@udecode/plate-juice';\nimport { KbdPlugin } from '@udecode/plate-kbd/react';\nimport { ColumnPlugin } from '@udecode/plate-layout/react';\nimport { LineHeightPlugin } from '@udecode/plate-line-height/react';\nimport { LinkPlugin } from '@udecode/plate-link/react';\nimport { ListPlugin, TodoListPlugin } from '@udecode/plate-list/react';\nimport { MarkdownPlugin } from '@udecode/plate-markdown';\nimport { BaseImagePlugin } from '@udecode/plate-media';\nimport { ImagePlugin, MediaEmbedPlugin } from '@udecode/plate-media/react';\nimport { MentionPlugin } from '@udecode/plate-mention/react';\nimport { NodeIdPlugin } from '@udecode/plate-node-id';\nimport { NormalizeTypesPlugin } from '@udecode/plate-normalizers';\nimport { PlaywrightPlugin } from '@udecode/plate-playwright';\nimport { DeletePlugin, SelectOnBackspacePlugin } from '@udecode/plate-select';\nimport {\n BlockMenuPlugin,\n BlockSelectionPlugin,\n} from '@udecode/plate-selection/react';\nimport { SlashPlugin } from '@udecode/plate-slash-command/react';\nimport { TablePlugin } from '@udecode/plate-table/react';\nimport { TogglePlugin } from '@udecode/plate-toggle/react';\nimport { TrailingBlockPlugin } from '@udecode/plate-trailing-block';\nimport Prism from 'prismjs';\n\nimport { CheckPlugin } from '@/components/context/check-plugin';\nimport { settingsStore } from '@/components/context/settings-store';\nimport { aiPlugins } from '@/lib/plate/demo/plugins/ai-plugins';\nimport { getAutoformatOptions } from '@/lib/plate/demo/plugins/autoformatOptions';\nimport { copilotPlugins } from '@/lib/plate/demo/plugins/copilot-plugins';\nimport { createPlateUI } from '@/plate/create-plate-ui';\nimport { editableProps } from '@/plate/demo/editableProps';\nimport { isEnabled } from '@/plate/demo/is-enabled';\nimport { DragOverCursorPlugin } from '@/plate/demo/plugins/DragOverCursorPlugin';\nimport { exitBreakPlugin } from '@/plate/demo/plugins/exitBreakPlugin';\nimport { resetBlockTypePlugin } from '@/plate/demo/plugins/resetBlockTypePlugin';\nimport { softBreakPlugin } from '@/plate/demo/plugins/softBreakPlugin';\nimport { tabbablePlugin } from '@/plate/demo/plugins/tabbablePlugin';\nimport { commentsData, usersData } from '@/plate/demo/values/commentsValue';\nimport { usePlaygroundValue } from '@/plate/demo/values/usePlaygroundValue';\nimport { BlockContextMenu } from '@/components/plate-ui/block-context-menu';\nimport { CommentsPopover } from '@/components/plate-ui/comments-popover';\nimport {\n CursorOverlay,\n SelectionOverlayPlugin,\n} from '@/components/plate-ui/cursor-overlay';\nimport { Editor, EditorContainer } from '@/components/plate-ui/editor';\nimport { FixedToolbar } from '@/components/plate-ui/fixed-toolbar';\nimport { FixedToolbarButtons } from '@/components/plate-ui/fixed-toolbar-buttons';\nimport { FloatingToolbar } from '@/components/plate-ui/floating-toolbar';\nimport { FloatingToolbarButtons } from '@/components/plate-ui/floating-toolbar-buttons';\nimport { ImagePreview } from '@/components/plate-ui/image-preview';\nimport {\n FireLiComponent,\n FireMarker,\n} from '@/components/plate-ui/indent-fire-marker';\nimport {\n TodoLi,\n TodoMarker,\n} from '@/components/plate-ui/indent-todo-marker';\nimport { LinkFloatingToolbar } from '@/components/plate-ui/link-floating-toolbar';\n\nimport { usePlaygroundEnabled } from './usePlaygroundEnabled';\n\nexport const usePlaygroundEditor = (id: any = '', scrollSelector?: string) => {\n const enabledPlugins = settingsStore.use.checkedPlugins();\n const overridePlugins = usePlaygroundEnabled(id);\n const autoformatOptions = getAutoformatOptions(id, enabledPlugins);\n\n const value = usePlaygroundValue(id);\n const key = settingsStore.use.version();\n const editorId = id || 'playground-' + key;\n\n return usePlateEditor(\n {\n id: editorId,\n override: {\n components: createPlateUI({\n draggable: isEnabled('dnd', id),\n placeholder: isEnabled('placeholder', id),\n }),\n plugins: overridePlugins,\n },\n plugins: [\n // AI\n ...(id === 'ai' || enabledPlugins[AIChatPlugin.key] ? aiPlugins : []),\n ...(id === 'copilot' || enabledPlugins[CopilotPlugin.key]\n ? copilotPlugins\n : []),\n // Nodes\n HeadingPlugin,\n TocPlugin.configure({\n options: {\n scrollContainerSelector: `#${scrollSelector}`,\n topOffset: 80,\n },\n }),\n BlockquotePlugin,\n CodeBlockPlugin.configure({\n options: {\n prism: Prism,\n },\n }),\n HorizontalRulePlugin,\n LinkPlugin.extend({\n render: { afterEditable: () => },\n }),\n ...(id === 'list' ? [ListPlugin] : []),\n ImagePlugin.extend({\n options: {\n disableUploadInsert: true,\n },\n render: { afterEditable: ImagePreview },\n }),\n MediaEmbedPlugin,\n CaptionPlugin.configure({\n options: {\n plugins: [ImagePlugin, MediaEmbedPlugin],\n },\n }),\n DatePlugin,\n MentionPlugin.configure({\n options: {\n triggerPreviousCharPattern: /^$|^[\\s\"']$/,\n },\n }),\n SlashPlugin,\n TablePlugin.configure({\n options: {\n enableMerging: id === 'tableMerge',\n },\n }),\n ColumnPlugin,\n SelectionOverlayPlugin,\n\n TodoListPlugin,\n TogglePlugin,\n ExcalidrawPlugin,\n // Marks\n BoldPlugin,\n ItalicPlugin,\n UnderlinePlugin,\n StrikethroughPlugin,\n CodePlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n FontColorPlugin,\n FontBackgroundColorPlugin,\n FontSizePlugin,\n HighlightPlugin,\n KbdPlugin,\n\n // Block Style\n AlignPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n MediaEmbedPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n ImagePlugin.key,\n HEADING_KEYS.h6,\n ],\n },\n }),\n IndentPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n }),\n IndentListPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n options: {\n listStyleTypes: {\n fire: {\n liComponent: FireLiComponent,\n markerComponent: FireMarker,\n type: 'fire',\n },\n todo: {\n liComponent: TodoLi,\n markerComponent: TodoMarker,\n type: 'todo',\n },\n },\n },\n }),\n LineHeightPlugin.extend({\n inject: {\n nodeProps: {\n defaultNodeValue: 1.5,\n validNodeValues: [1, 1.2, 1.5, 2, 3],\n },\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n ],\n },\n }),\n\n // Functionality\n AutoformatPlugin.configure({\n options: autoformatOptions,\n }),\n BlockSelectionPlugin.configure({\n options: {\n areaOptions: {\n behaviour: {\n scrolling: {\n speedDivider: 1.5,\n },\n startThreshold: 10,\n },\n boundaries: `#${scrollSelector}`,\n container: `#${scrollSelector}`,\n selectables: [`#${scrollSelector} .slate-selectable`],\n selectionAreaClass: 'slate-selection-area',\n },\n enableContextMenu: true,\n },\n }),\n BlockMenuPlugin.configure({\n render: { aboveEditable: BlockContextMenu },\n }),\n DndPlugin.configure({\n options: {\n enableScroller: true,\n onDropFiles: ({ dragItem, editor, target }) => {\n editor\n .getTransforms(BaseImagePlugin)\n .insert.imageFromFiles(dragItem.files, {\n at: target,\n nextBlock: false,\n });\n },\n },\n }),\n EmojiPlugin,\n exitBreakPlugin,\n NodeIdPlugin,\n NormalizeTypesPlugin.configure({\n options: {\n rules: [{ path: [0], strictType: HEADING_KEYS.h1 }],\n },\n }),\n resetBlockTypePlugin,\n SelectOnBackspacePlugin.configure({\n options: {\n query: {\n allow: [ImagePlugin.key, HorizontalRulePlugin.key],\n },\n },\n }),\n DeletePlugin,\n SingleLinePlugin,\n softBreakPlugin,\n tabbablePlugin,\n TrailingBlockPlugin.configure({\n options: { type: ParagraphPlugin.key },\n }),\n DragOverCursorPlugin,\n\n // Collaboration\n CommentsPlugin.configure({\n options: {\n comments: commentsData,\n myUserId: '1',\n users: usersData,\n },\n }),\n\n // Deserialization\n DocxPlugin,\n MarkdownPlugin.configure({ options: { indentList: true } }),\n JuicePlugin,\n\n // Testing\n PlaywrightPlugin.configure({\n enabled: process.env.NODE_ENV !== 'production',\n }),\n ],\n value: value,\n },\n []\n );\n};\n\nexport default function PlaygroundDemo({\n id,\n className,\n scrollSelector,\n}: {\n id?: ValueId;\n className?: string;\n scrollSelector?: string;\n}) {\n const containerRef = useRef(null);\n const enabled = settingsStore.use.checkedComponents();\n\n const editor = usePlaygroundEditor(\n id,\n scrollSelector ?? `blockSelection-${id}`\n );\n\n return (\n \n \n \n \n \n \n \n \n \n\n
\n \n \n\n \n \n \n \n \n \n \n\n \n \n \n \n\n \n \n \n
\n
\n
\n );\n}\n\nconst DemoIdContext = React.createContext(undefined);\n\nexport function DemoId({\n id,\n children,\n}: {\n children: React.ReactNode;\n id?: string;\n}) {\n return {children};\n}\n\nexport function useDemoId() {\n return React.useContext(DemoIdContext);\n}\n", "path": "example/playground-demo.tsx", "target": "components/playground-demo.tsx", "type": "registry:example" diff --git a/apps/www/public/r/styles/default/dnd-demo.json b/apps/www/public/r/styles/default/dnd-demo.json index a94cca653f..5adad760fd 100644 --- a/apps/www/public/r/styles/default/dnd-demo.json +++ b/apps/www/public/r/styles/default/dnd-demo.json @@ -5,7 +5,7 @@ }, "files": [ { - "content": "'use client';\n\nimport React, { useRef } from 'react';\n\nimport type { ValueId } from '@/config/customizer-plugins';\n\nimport { cn } from '@udecode/cn';\nimport { AIChatPlugin, CopilotPlugin } from '@udecode/plate-ai/react';\nimport { AlignPlugin } from '@udecode/plate-alignment/react';\nimport { AutoformatPlugin } from '@udecode/plate-autoformat/react';\nimport {\n BoldPlugin,\n CodePlugin,\n ItalicPlugin,\n StrikethroughPlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n UnderlinePlugin,\n} from '@udecode/plate-basic-marks/react';\nimport { BlockquotePlugin } from '@udecode/plate-block-quote/react';\nimport { SingleLinePlugin } from '@udecode/plate-break/react';\nimport { CaptionPlugin } from '@udecode/plate-caption/react';\nimport { CodeBlockPlugin } from '@udecode/plate-code-block/react';\nimport { CommentsPlugin } from '@udecode/plate-comments/react';\nimport {\n ParagraphPlugin,\n Plate,\n usePlateEditor,\n} from '@udecode/plate-common/react';\nimport { DatePlugin } from '@udecode/plate-date/react';\nimport { DndPlugin } from '@udecode/plate-dnd';\nimport { DocxPlugin } from '@udecode/plate-docx';\nimport { EmojiPlugin } from '@udecode/plate-emoji/react';\nimport { ExcalidrawPlugin } from '@udecode/plate-excalidraw/react';\nimport {\n FontBackgroundColorPlugin,\n FontColorPlugin,\n FontSizePlugin,\n} from '@udecode/plate-font/react';\nimport { HEADING_KEYS } from '@udecode/plate-heading';\nimport { HeadingPlugin, TocPlugin } from '@udecode/plate-heading/react';\nimport { HighlightPlugin } from '@udecode/plate-highlight/react';\nimport { HorizontalRulePlugin } from '@udecode/plate-horizontal-rule/react';\nimport { IndentPlugin } from '@udecode/plate-indent/react';\nimport { IndentListPlugin } from '@udecode/plate-indent-list/react';\nimport { JuicePlugin } from '@udecode/plate-juice';\nimport { KbdPlugin } from '@udecode/plate-kbd/react';\nimport { ColumnPlugin } from '@udecode/plate-layout/react';\nimport { LineHeightPlugin } from '@udecode/plate-line-height/react';\nimport { LinkPlugin } from '@udecode/plate-link/react';\nimport { ListPlugin, TodoListPlugin } from '@udecode/plate-list/react';\nimport { MarkdownPlugin } from '@udecode/plate-markdown';\nimport { ImagePlugin, MediaEmbedPlugin } from '@udecode/plate-media/react';\nimport { MentionPlugin } from '@udecode/plate-mention/react';\nimport { NodeIdPlugin } from '@udecode/plate-node-id';\nimport { NormalizeTypesPlugin } from '@udecode/plate-normalizers';\nimport { PlaywrightPlugin } from '@udecode/plate-playwright';\nimport { DeletePlugin, SelectOnBackspacePlugin } from '@udecode/plate-select';\nimport {\n BlockMenuPlugin,\n BlockSelectionPlugin,\n} from '@udecode/plate-selection/react';\nimport { SlashPlugin } from '@udecode/plate-slash-command/react';\nimport { TablePlugin } from '@udecode/plate-table/react';\nimport { TogglePlugin } from '@udecode/plate-toggle/react';\nimport { TrailingBlockPlugin } from '@udecode/plate-trailing-block';\nimport Prism from 'prismjs';\n\nimport { CheckPlugin } from '@/components/context/check-plugin';\nimport { settingsStore } from '@/components/context/settings-store';\nimport { aiPlugins } from '@/lib/plate/demo/plugins/ai-plugins';\nimport { getAutoformatOptions } from '@/lib/plate/demo/plugins/autoformatOptions';\nimport { copilotPlugins } from '@/lib/plate/demo/plugins/copilot-plugins';\nimport { createPlateUI } from '@/plate/create-plate-ui';\nimport { editableProps } from '@/plate/demo/editableProps';\nimport { isEnabled } from '@/plate/demo/is-enabled';\nimport { DragOverCursorPlugin } from '@/plate/demo/plugins/DragOverCursorPlugin';\nimport { exitBreakPlugin } from '@/plate/demo/plugins/exitBreakPlugin';\nimport { resetBlockTypePlugin } from '@/plate/demo/plugins/resetBlockTypePlugin';\nimport { softBreakPlugin } from '@/plate/demo/plugins/softBreakPlugin';\nimport { tabbablePlugin } from '@/plate/demo/plugins/tabbablePlugin';\nimport { commentsData, usersData } from '@/plate/demo/values/commentsValue';\nimport { usePlaygroundValue } from '@/plate/demo/values/usePlaygroundValue';\nimport { BlockContextMenu } from '@/components/plate-ui/block-context-menu';\nimport { CommentsPopover } from '@/components/plate-ui/comments-popover';\nimport {\n CursorOverlay,\n SelectionOverlayPlugin,\n} from '@/components/plate-ui/cursor-overlay';\nimport { Editor, EditorContainer } from '@/components/plate-ui/editor';\nimport { FixedToolbar } from '@/components/plate-ui/fixed-toolbar';\nimport { FixedToolbarButtons } from '@/components/plate-ui/fixed-toolbar-buttons';\nimport { FloatingToolbar } from '@/components/plate-ui/floating-toolbar';\nimport { FloatingToolbarButtons } from '@/components/plate-ui/floating-toolbar-buttons';\nimport { ImagePreview } from '@/components/plate-ui/image-preview';\nimport {\n FireLiComponent,\n FireMarker,\n} from '@/components/plate-ui/indent-fire-marker';\nimport {\n TodoLi,\n TodoMarker,\n} from '@/components/plate-ui/indent-todo-marker';\nimport { LinkFloatingToolbar } from '@/components/plate-ui/link-floating-toolbar';\n\nimport { usePlaygroundEnabled } from './usePlaygroundEnabled';\n\nexport const usePlaygroundEditor = (id: any = '', scrollSelector?: string) => {\n const enabledPlugins = settingsStore.use.checkedPlugins();\n const overridePlugins = usePlaygroundEnabled(id);\n const autoformatOptions = getAutoformatOptions(id, enabledPlugins);\n\n const value = usePlaygroundValue(id);\n const key = settingsStore.use.version();\n const editorId = id || 'playground-' + key;\n\n return usePlateEditor(\n {\n id: editorId,\n override: {\n components: createPlateUI({\n draggable: isEnabled('dnd', id),\n placeholder: isEnabled('placeholder', id),\n }),\n plugins: overridePlugins,\n },\n plugins: [\n // AI\n ...(id === 'ai' || enabledPlugins[AIChatPlugin.key] ? aiPlugins : []),\n ...(id === 'copilot' || enabledPlugins[CopilotPlugin.key]\n ? copilotPlugins\n : []),\n // Nodes\n HeadingPlugin,\n TocPlugin.configure({\n options: {\n scrollContainerSelector: `#${scrollSelector}`,\n topOffset: 80,\n },\n }),\n BlockquotePlugin,\n CodeBlockPlugin.configure({\n options: {\n prism: Prism,\n },\n }),\n HorizontalRulePlugin,\n LinkPlugin.extend({\n render: { afterEditable: () => },\n }),\n ...(id === 'list' ? [ListPlugin] : []),\n ImagePlugin.extend({\n options: {\n disableUploadInsert: true,\n },\n render: { afterEditable: ImagePreview },\n }),\n MediaEmbedPlugin,\n CaptionPlugin.configure({\n options: {\n plugins: [ImagePlugin, MediaEmbedPlugin],\n },\n }),\n DatePlugin,\n MentionPlugin.configure({\n options: {\n triggerPreviousCharPattern: /^$|^[\\s\"']$/,\n },\n }),\n SlashPlugin,\n TablePlugin.configure({\n options: {\n enableMerging: id === 'tableMerge',\n },\n }),\n ColumnPlugin,\n SelectionOverlayPlugin,\n\n TodoListPlugin,\n TogglePlugin,\n ExcalidrawPlugin,\n // Marks\n BoldPlugin,\n ItalicPlugin,\n UnderlinePlugin,\n StrikethroughPlugin,\n CodePlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n FontColorPlugin,\n FontBackgroundColorPlugin,\n FontSizePlugin,\n HighlightPlugin,\n KbdPlugin,\n\n // Block Style\n AlignPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n MediaEmbedPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n ImagePlugin.key,\n HEADING_KEYS.h6,\n ],\n },\n }),\n IndentPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n }),\n IndentListPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n options: {\n listStyleTypes: {\n fire: {\n liComponent: FireLiComponent,\n markerComponent: FireMarker,\n type: 'fire',\n },\n todo: {\n liComponent: TodoLi,\n markerComponent: TodoMarker,\n type: 'todo',\n },\n },\n },\n }),\n LineHeightPlugin.extend({\n inject: {\n nodeProps: {\n defaultNodeValue: 1.5,\n validNodeValues: [1, 1.2, 1.5, 2, 3],\n },\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n ],\n },\n }),\n\n // Functionality\n AutoformatPlugin.configure({\n options: autoformatOptions,\n }),\n BlockSelectionPlugin.configure({\n options: {\n areaOptions: {\n behaviour: {\n scrolling: {\n speedDivider: 1.5,\n },\n startThreshold: 10,\n },\n boundaries: `#${scrollSelector}`,\n container: `#${scrollSelector}`,\n selectables: [`#${scrollSelector} .slate-selectable`],\n selectionAreaClass: 'slate-selection-area',\n },\n enableContextMenu: true,\n },\n }),\n BlockMenuPlugin.configure({\n render: { aboveEditable: BlockContextMenu },\n }),\n DndPlugin.configure({\n options: {\n enableScroller: true,\n onDropFiles: ({ dragItem, editor, target }) => {\n editor\n .getTransforms(ImagePlugin)\n .insertImageFromFiles(dragItem.files, {\n at: target,\n nextBlock: false,\n });\n },\n },\n }),\n EmojiPlugin,\n exitBreakPlugin,\n NodeIdPlugin,\n NormalizeTypesPlugin.configure({\n options: {\n rules: [{ path: [0], strictType: HEADING_KEYS.h1 }],\n },\n }),\n resetBlockTypePlugin,\n SelectOnBackspacePlugin.configure({\n options: {\n query: {\n allow: [ImagePlugin.key, HorizontalRulePlugin.key],\n },\n },\n }),\n DeletePlugin,\n SingleLinePlugin,\n softBreakPlugin,\n tabbablePlugin,\n TrailingBlockPlugin.configure({\n options: { type: ParagraphPlugin.key },\n }),\n DragOverCursorPlugin,\n\n // Collaboration\n CommentsPlugin.configure({\n options: {\n comments: commentsData,\n myUserId: '1',\n users: usersData,\n },\n }),\n\n // Deserialization\n DocxPlugin,\n MarkdownPlugin.configure({ options: { indentList: true } }),\n JuicePlugin,\n\n // Testing\n PlaywrightPlugin.configure({\n enabled: process.env.NODE_ENV !== 'production',\n }),\n ],\n value: value,\n },\n []\n );\n};\n\nexport default function PlaygroundDemo({\n id,\n className,\n scrollSelector,\n}: {\n id?: ValueId;\n className?: string;\n scrollSelector?: string;\n}) {\n const containerRef = useRef(null);\n const enabled = settingsStore.use.checkedComponents();\n\n const editor = usePlaygroundEditor(\n id,\n scrollSelector ?? `blockSelection-${id}`\n );\n\n return (\n \n \n \n \n \n \n \n \n \n\n
\n \n \n\n \n \n \n \n \n \n \n\n \n \n \n \n\n \n \n \n
\n
\n
\n );\n}\n\nconst DemoIdContext = React.createContext(undefined);\n\nexport function DemoId({\n id,\n children,\n}: {\n children: React.ReactNode;\n id?: string;\n}) {\n return {children};\n}\n\nexport function useDemoId() {\n return React.useContext(DemoIdContext);\n}\n", + "content": "'use client';\n\nimport React, { useRef } from 'react';\n\nimport type { ValueId } from '@/config/customizer-plugins';\n\nimport { cn } from '@udecode/cn';\nimport { AIChatPlugin, CopilotPlugin } from '@udecode/plate-ai/react';\nimport { AlignPlugin } from '@udecode/plate-alignment/react';\nimport { AutoformatPlugin } from '@udecode/plate-autoformat/react';\nimport {\n BoldPlugin,\n CodePlugin,\n ItalicPlugin,\n StrikethroughPlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n UnderlinePlugin,\n} from '@udecode/plate-basic-marks/react';\nimport { BlockquotePlugin } from '@udecode/plate-block-quote/react';\nimport { SingleLinePlugin } from '@udecode/plate-break/react';\nimport { CaptionPlugin } from '@udecode/plate-caption/react';\nimport { CodeBlockPlugin } from '@udecode/plate-code-block/react';\nimport { CommentsPlugin } from '@udecode/plate-comments/react';\nimport {\n ParagraphPlugin,\n Plate,\n usePlateEditor,\n} from '@udecode/plate-common/react';\nimport { DatePlugin } from '@udecode/plate-date/react';\nimport { DndPlugin } from '@udecode/plate-dnd';\nimport { DocxPlugin } from '@udecode/plate-docx';\nimport { EmojiPlugin } from '@udecode/plate-emoji/react';\nimport { ExcalidrawPlugin } from '@udecode/plate-excalidraw/react';\nimport {\n FontBackgroundColorPlugin,\n FontColorPlugin,\n FontSizePlugin,\n} from '@udecode/plate-font/react';\nimport { HEADING_KEYS } from '@udecode/plate-heading';\nimport { HeadingPlugin, TocPlugin } from '@udecode/plate-heading/react';\nimport { HighlightPlugin } from '@udecode/plate-highlight/react';\nimport { HorizontalRulePlugin } from '@udecode/plate-horizontal-rule/react';\nimport { IndentPlugin } from '@udecode/plate-indent/react';\nimport { IndentListPlugin } from '@udecode/plate-indent-list/react';\nimport { JuicePlugin } from '@udecode/plate-juice';\nimport { KbdPlugin } from '@udecode/plate-kbd/react';\nimport { ColumnPlugin } from '@udecode/plate-layout/react';\nimport { LineHeightPlugin } from '@udecode/plate-line-height/react';\nimport { LinkPlugin } from '@udecode/plate-link/react';\nimport { ListPlugin, TodoListPlugin } from '@udecode/plate-list/react';\nimport { MarkdownPlugin } from '@udecode/plate-markdown';\nimport { BaseImagePlugin } from '@udecode/plate-media';\nimport { ImagePlugin, MediaEmbedPlugin } from '@udecode/plate-media/react';\nimport { MentionPlugin } from '@udecode/plate-mention/react';\nimport { NodeIdPlugin } from '@udecode/plate-node-id';\nimport { NormalizeTypesPlugin } from '@udecode/plate-normalizers';\nimport { PlaywrightPlugin } from '@udecode/plate-playwright';\nimport { DeletePlugin, SelectOnBackspacePlugin } from '@udecode/plate-select';\nimport {\n BlockMenuPlugin,\n BlockSelectionPlugin,\n} from '@udecode/plate-selection/react';\nimport { SlashPlugin } from '@udecode/plate-slash-command/react';\nimport { TablePlugin } from '@udecode/plate-table/react';\nimport { TogglePlugin } from '@udecode/plate-toggle/react';\nimport { TrailingBlockPlugin } from '@udecode/plate-trailing-block';\nimport Prism from 'prismjs';\n\nimport { CheckPlugin } from '@/components/context/check-plugin';\nimport { settingsStore } from '@/components/context/settings-store';\nimport { aiPlugins } from '@/lib/plate/demo/plugins/ai-plugins';\nimport { getAutoformatOptions } from '@/lib/plate/demo/plugins/autoformatOptions';\nimport { copilotPlugins } from '@/lib/plate/demo/plugins/copilot-plugins';\nimport { createPlateUI } from '@/plate/create-plate-ui';\nimport { editableProps } from '@/plate/demo/editableProps';\nimport { isEnabled } from '@/plate/demo/is-enabled';\nimport { DragOverCursorPlugin } from '@/plate/demo/plugins/DragOverCursorPlugin';\nimport { exitBreakPlugin } from '@/plate/demo/plugins/exitBreakPlugin';\nimport { resetBlockTypePlugin } from '@/plate/demo/plugins/resetBlockTypePlugin';\nimport { softBreakPlugin } from '@/plate/demo/plugins/softBreakPlugin';\nimport { tabbablePlugin } from '@/plate/demo/plugins/tabbablePlugin';\nimport { commentsData, usersData } from '@/plate/demo/values/commentsValue';\nimport { usePlaygroundValue } from '@/plate/demo/values/usePlaygroundValue';\nimport { BlockContextMenu } from '@/components/plate-ui/block-context-menu';\nimport { CommentsPopover } from '@/components/plate-ui/comments-popover';\nimport {\n CursorOverlay,\n SelectionOverlayPlugin,\n} from '@/components/plate-ui/cursor-overlay';\nimport { Editor, EditorContainer } from '@/components/plate-ui/editor';\nimport { FixedToolbar } from '@/components/plate-ui/fixed-toolbar';\nimport { FixedToolbarButtons } from '@/components/plate-ui/fixed-toolbar-buttons';\nimport { FloatingToolbar } from '@/components/plate-ui/floating-toolbar';\nimport { FloatingToolbarButtons } from '@/components/plate-ui/floating-toolbar-buttons';\nimport { ImagePreview } from '@/components/plate-ui/image-preview';\nimport {\n FireLiComponent,\n FireMarker,\n} from '@/components/plate-ui/indent-fire-marker';\nimport {\n TodoLi,\n TodoMarker,\n} from '@/components/plate-ui/indent-todo-marker';\nimport { LinkFloatingToolbar } from '@/components/plate-ui/link-floating-toolbar';\n\nimport { usePlaygroundEnabled } from './usePlaygroundEnabled';\n\nexport const usePlaygroundEditor = (id: any = '', scrollSelector?: string) => {\n const enabledPlugins = settingsStore.use.checkedPlugins();\n const overridePlugins = usePlaygroundEnabled(id);\n const autoformatOptions = getAutoformatOptions(id, enabledPlugins);\n\n const value = usePlaygroundValue(id);\n const key = settingsStore.use.version();\n const editorId = id || 'playground-' + key;\n\n return usePlateEditor(\n {\n id: editorId,\n override: {\n components: createPlateUI({\n draggable: isEnabled('dnd', id),\n placeholder: isEnabled('placeholder', id),\n }),\n plugins: overridePlugins,\n },\n plugins: [\n // AI\n ...(id === 'ai' || enabledPlugins[AIChatPlugin.key] ? aiPlugins : []),\n ...(id === 'copilot' || enabledPlugins[CopilotPlugin.key]\n ? copilotPlugins\n : []),\n // Nodes\n HeadingPlugin,\n TocPlugin.configure({\n options: {\n scrollContainerSelector: `#${scrollSelector}`,\n topOffset: 80,\n },\n }),\n BlockquotePlugin,\n CodeBlockPlugin.configure({\n options: {\n prism: Prism,\n },\n }),\n HorizontalRulePlugin,\n LinkPlugin.extend({\n render: { afterEditable: () => },\n }),\n ...(id === 'list' ? [ListPlugin] : []),\n ImagePlugin.extend({\n options: {\n disableUploadInsert: true,\n },\n render: { afterEditable: ImagePreview },\n }),\n MediaEmbedPlugin,\n CaptionPlugin.configure({\n options: {\n plugins: [ImagePlugin, MediaEmbedPlugin],\n },\n }),\n DatePlugin,\n MentionPlugin.configure({\n options: {\n triggerPreviousCharPattern: /^$|^[\\s\"']$/,\n },\n }),\n SlashPlugin,\n TablePlugin.configure({\n options: {\n enableMerging: id === 'tableMerge',\n },\n }),\n ColumnPlugin,\n SelectionOverlayPlugin,\n\n TodoListPlugin,\n TogglePlugin,\n ExcalidrawPlugin,\n // Marks\n BoldPlugin,\n ItalicPlugin,\n UnderlinePlugin,\n StrikethroughPlugin,\n CodePlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n FontColorPlugin,\n FontBackgroundColorPlugin,\n FontSizePlugin,\n HighlightPlugin,\n KbdPlugin,\n\n // Block Style\n AlignPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n MediaEmbedPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n ImagePlugin.key,\n HEADING_KEYS.h6,\n ],\n },\n }),\n IndentPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n }),\n IndentListPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n options: {\n listStyleTypes: {\n fire: {\n liComponent: FireLiComponent,\n markerComponent: FireMarker,\n type: 'fire',\n },\n todo: {\n liComponent: TodoLi,\n markerComponent: TodoMarker,\n type: 'todo',\n },\n },\n },\n }),\n LineHeightPlugin.extend({\n inject: {\n nodeProps: {\n defaultNodeValue: 1.5,\n validNodeValues: [1, 1.2, 1.5, 2, 3],\n },\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n ],\n },\n }),\n\n // Functionality\n AutoformatPlugin.configure({\n options: autoformatOptions,\n }),\n BlockSelectionPlugin.configure({\n options: {\n areaOptions: {\n behaviour: {\n scrolling: {\n speedDivider: 1.5,\n },\n startThreshold: 10,\n },\n boundaries: `#${scrollSelector}`,\n container: `#${scrollSelector}`,\n selectables: [`#${scrollSelector} .slate-selectable`],\n selectionAreaClass: 'slate-selection-area',\n },\n enableContextMenu: true,\n },\n }),\n BlockMenuPlugin.configure({\n render: { aboveEditable: BlockContextMenu },\n }),\n DndPlugin.configure({\n options: {\n enableScroller: true,\n onDropFiles: ({ dragItem, editor, target }) => {\n editor\n .getTransforms(BaseImagePlugin)\n .insert.imageFromFiles(dragItem.files, {\n at: target,\n nextBlock: false,\n });\n },\n },\n }),\n EmojiPlugin,\n exitBreakPlugin,\n NodeIdPlugin,\n NormalizeTypesPlugin.configure({\n options: {\n rules: [{ path: [0], strictType: HEADING_KEYS.h1 }],\n },\n }),\n resetBlockTypePlugin,\n SelectOnBackspacePlugin.configure({\n options: {\n query: {\n allow: [ImagePlugin.key, HorizontalRulePlugin.key],\n },\n },\n }),\n DeletePlugin,\n SingleLinePlugin,\n softBreakPlugin,\n tabbablePlugin,\n TrailingBlockPlugin.configure({\n options: { type: ParagraphPlugin.key },\n }),\n DragOverCursorPlugin,\n\n // Collaboration\n CommentsPlugin.configure({\n options: {\n comments: commentsData,\n myUserId: '1',\n users: usersData,\n },\n }),\n\n // Deserialization\n DocxPlugin,\n MarkdownPlugin.configure({ options: { indentList: true } }),\n JuicePlugin,\n\n // Testing\n PlaywrightPlugin.configure({\n enabled: process.env.NODE_ENV !== 'production',\n }),\n ],\n value: value,\n },\n []\n );\n};\n\nexport default function PlaygroundDemo({\n id,\n className,\n scrollSelector,\n}: {\n id?: ValueId;\n className?: string;\n scrollSelector?: string;\n}) {\n const containerRef = useRef(null);\n const enabled = settingsStore.use.checkedComponents();\n\n const editor = usePlaygroundEditor(\n id,\n scrollSelector ?? `blockSelection-${id}`\n );\n\n return (\n \n \n \n \n \n \n \n \n \n\n
\n \n \n\n \n \n \n \n \n \n \n\n \n \n \n \n\n \n \n \n
\n
\n
\n );\n}\n\nconst DemoIdContext = React.createContext(undefined);\n\nexport function DemoId({\n id,\n children,\n}: {\n children: React.ReactNode;\n id?: string;\n}) {\n return {children};\n}\n\nexport function useDemoId() {\n return React.useContext(DemoIdContext);\n}\n", "path": "example/playground-demo.tsx", "target": "components/playground-demo.tsx", "type": "registry:example" diff --git a/apps/www/public/r/styles/default/emoji-demo.json b/apps/www/public/r/styles/default/emoji-demo.json index ab4cc9118a..be8331da22 100644 --- a/apps/www/public/r/styles/default/emoji-demo.json +++ b/apps/www/public/r/styles/default/emoji-demo.json @@ -4,7 +4,7 @@ }, "files": [ { - "content": "'use client';\n\nimport React, { useRef } from 'react';\n\nimport type { ValueId } from '@/config/customizer-plugins';\n\nimport { cn } from '@udecode/cn';\nimport { AIChatPlugin, CopilotPlugin } from '@udecode/plate-ai/react';\nimport { AlignPlugin } from '@udecode/plate-alignment/react';\nimport { AutoformatPlugin } from '@udecode/plate-autoformat/react';\nimport {\n BoldPlugin,\n CodePlugin,\n ItalicPlugin,\n StrikethroughPlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n UnderlinePlugin,\n} from '@udecode/plate-basic-marks/react';\nimport { BlockquotePlugin } from '@udecode/plate-block-quote/react';\nimport { SingleLinePlugin } from '@udecode/plate-break/react';\nimport { CaptionPlugin } from '@udecode/plate-caption/react';\nimport { CodeBlockPlugin } from '@udecode/plate-code-block/react';\nimport { CommentsPlugin } from '@udecode/plate-comments/react';\nimport {\n ParagraphPlugin,\n Plate,\n usePlateEditor,\n} from '@udecode/plate-common/react';\nimport { DatePlugin } from '@udecode/plate-date/react';\nimport { DndPlugin } from '@udecode/plate-dnd';\nimport { DocxPlugin } from '@udecode/plate-docx';\nimport { EmojiPlugin } from '@udecode/plate-emoji/react';\nimport { ExcalidrawPlugin } from '@udecode/plate-excalidraw/react';\nimport {\n FontBackgroundColorPlugin,\n FontColorPlugin,\n FontSizePlugin,\n} from '@udecode/plate-font/react';\nimport { HEADING_KEYS } from '@udecode/plate-heading';\nimport { HeadingPlugin, TocPlugin } from '@udecode/plate-heading/react';\nimport { HighlightPlugin } from '@udecode/plate-highlight/react';\nimport { HorizontalRulePlugin } from '@udecode/plate-horizontal-rule/react';\nimport { IndentPlugin } from '@udecode/plate-indent/react';\nimport { IndentListPlugin } from '@udecode/plate-indent-list/react';\nimport { JuicePlugin } from '@udecode/plate-juice';\nimport { KbdPlugin } from '@udecode/plate-kbd/react';\nimport { ColumnPlugin } from '@udecode/plate-layout/react';\nimport { LineHeightPlugin } from '@udecode/plate-line-height/react';\nimport { LinkPlugin } from '@udecode/plate-link/react';\nimport { ListPlugin, TodoListPlugin } from '@udecode/plate-list/react';\nimport { MarkdownPlugin } from '@udecode/plate-markdown';\nimport { ImagePlugin, MediaEmbedPlugin } from '@udecode/plate-media/react';\nimport { MentionPlugin } from '@udecode/plate-mention/react';\nimport { NodeIdPlugin } from '@udecode/plate-node-id';\nimport { NormalizeTypesPlugin } from '@udecode/plate-normalizers';\nimport { PlaywrightPlugin } from '@udecode/plate-playwright';\nimport { DeletePlugin, SelectOnBackspacePlugin } from '@udecode/plate-select';\nimport {\n BlockMenuPlugin,\n BlockSelectionPlugin,\n} from '@udecode/plate-selection/react';\nimport { SlashPlugin } from '@udecode/plate-slash-command/react';\nimport { TablePlugin } from '@udecode/plate-table/react';\nimport { TogglePlugin } from '@udecode/plate-toggle/react';\nimport { TrailingBlockPlugin } from '@udecode/plate-trailing-block';\nimport Prism from 'prismjs';\n\nimport { CheckPlugin } from '@/components/context/check-plugin';\nimport { settingsStore } from '@/components/context/settings-store';\nimport { aiPlugins } from '@/lib/plate/demo/plugins/ai-plugins';\nimport { getAutoformatOptions } from '@/lib/plate/demo/plugins/autoformatOptions';\nimport { copilotPlugins } from '@/lib/plate/demo/plugins/copilot-plugins';\nimport { createPlateUI } from '@/plate/create-plate-ui';\nimport { editableProps } from '@/plate/demo/editableProps';\nimport { isEnabled } from '@/plate/demo/is-enabled';\nimport { DragOverCursorPlugin } from '@/plate/demo/plugins/DragOverCursorPlugin';\nimport { exitBreakPlugin } from '@/plate/demo/plugins/exitBreakPlugin';\nimport { resetBlockTypePlugin } from '@/plate/demo/plugins/resetBlockTypePlugin';\nimport { softBreakPlugin } from '@/plate/demo/plugins/softBreakPlugin';\nimport { tabbablePlugin } from '@/plate/demo/plugins/tabbablePlugin';\nimport { commentsData, usersData } from '@/plate/demo/values/commentsValue';\nimport { usePlaygroundValue } from '@/plate/demo/values/usePlaygroundValue';\nimport { BlockContextMenu } from '@/components/plate-ui/block-context-menu';\nimport { CommentsPopover } from '@/components/plate-ui/comments-popover';\nimport {\n CursorOverlay,\n SelectionOverlayPlugin,\n} from '@/components/plate-ui/cursor-overlay';\nimport { Editor, EditorContainer } from '@/components/plate-ui/editor';\nimport { FixedToolbar } from '@/components/plate-ui/fixed-toolbar';\nimport { FixedToolbarButtons } from '@/components/plate-ui/fixed-toolbar-buttons';\nimport { FloatingToolbar } from '@/components/plate-ui/floating-toolbar';\nimport { FloatingToolbarButtons } from '@/components/plate-ui/floating-toolbar-buttons';\nimport { ImagePreview } from '@/components/plate-ui/image-preview';\nimport {\n FireLiComponent,\n FireMarker,\n} from '@/components/plate-ui/indent-fire-marker';\nimport {\n TodoLi,\n TodoMarker,\n} from '@/components/plate-ui/indent-todo-marker';\nimport { LinkFloatingToolbar } from '@/components/plate-ui/link-floating-toolbar';\n\nimport { usePlaygroundEnabled } from './usePlaygroundEnabled';\n\nexport const usePlaygroundEditor = (id: any = '', scrollSelector?: string) => {\n const enabledPlugins = settingsStore.use.checkedPlugins();\n const overridePlugins = usePlaygroundEnabled(id);\n const autoformatOptions = getAutoformatOptions(id, enabledPlugins);\n\n const value = usePlaygroundValue(id);\n const key = settingsStore.use.version();\n const editorId = id || 'playground-' + key;\n\n return usePlateEditor(\n {\n id: editorId,\n override: {\n components: createPlateUI({\n draggable: isEnabled('dnd', id),\n placeholder: isEnabled('placeholder', id),\n }),\n plugins: overridePlugins,\n },\n plugins: [\n // AI\n ...(id === 'ai' || enabledPlugins[AIChatPlugin.key] ? aiPlugins : []),\n ...(id === 'copilot' || enabledPlugins[CopilotPlugin.key]\n ? copilotPlugins\n : []),\n // Nodes\n HeadingPlugin,\n TocPlugin.configure({\n options: {\n scrollContainerSelector: `#${scrollSelector}`,\n topOffset: 80,\n },\n }),\n BlockquotePlugin,\n CodeBlockPlugin.configure({\n options: {\n prism: Prism,\n },\n }),\n HorizontalRulePlugin,\n LinkPlugin.extend({\n render: { afterEditable: () => },\n }),\n ...(id === 'list' ? [ListPlugin] : []),\n ImagePlugin.extend({\n options: {\n disableUploadInsert: true,\n },\n render: { afterEditable: ImagePreview },\n }),\n MediaEmbedPlugin,\n CaptionPlugin.configure({\n options: {\n plugins: [ImagePlugin, MediaEmbedPlugin],\n },\n }),\n DatePlugin,\n MentionPlugin.configure({\n options: {\n triggerPreviousCharPattern: /^$|^[\\s\"']$/,\n },\n }),\n SlashPlugin,\n TablePlugin.configure({\n options: {\n enableMerging: id === 'tableMerge',\n },\n }),\n ColumnPlugin,\n SelectionOverlayPlugin,\n\n TodoListPlugin,\n TogglePlugin,\n ExcalidrawPlugin,\n // Marks\n BoldPlugin,\n ItalicPlugin,\n UnderlinePlugin,\n StrikethroughPlugin,\n CodePlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n FontColorPlugin,\n FontBackgroundColorPlugin,\n FontSizePlugin,\n HighlightPlugin,\n KbdPlugin,\n\n // Block Style\n AlignPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n MediaEmbedPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n ImagePlugin.key,\n HEADING_KEYS.h6,\n ],\n },\n }),\n IndentPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n }),\n IndentListPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n options: {\n listStyleTypes: {\n fire: {\n liComponent: FireLiComponent,\n markerComponent: FireMarker,\n type: 'fire',\n },\n todo: {\n liComponent: TodoLi,\n markerComponent: TodoMarker,\n type: 'todo',\n },\n },\n },\n }),\n LineHeightPlugin.extend({\n inject: {\n nodeProps: {\n defaultNodeValue: 1.5,\n validNodeValues: [1, 1.2, 1.5, 2, 3],\n },\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n ],\n },\n }),\n\n // Functionality\n AutoformatPlugin.configure({\n options: autoformatOptions,\n }),\n BlockSelectionPlugin.configure({\n options: {\n areaOptions: {\n behaviour: {\n scrolling: {\n speedDivider: 1.5,\n },\n startThreshold: 10,\n },\n boundaries: `#${scrollSelector}`,\n container: `#${scrollSelector}`,\n selectables: [`#${scrollSelector} .slate-selectable`],\n selectionAreaClass: 'slate-selection-area',\n },\n enableContextMenu: true,\n },\n }),\n BlockMenuPlugin.configure({\n render: { aboveEditable: BlockContextMenu },\n }),\n DndPlugin.configure({\n options: {\n enableScroller: true,\n onDropFiles: ({ dragItem, editor, target }) => {\n editor\n .getTransforms(ImagePlugin)\n .insertImageFromFiles(dragItem.files, {\n at: target,\n nextBlock: false,\n });\n },\n },\n }),\n EmojiPlugin,\n exitBreakPlugin,\n NodeIdPlugin,\n NormalizeTypesPlugin.configure({\n options: {\n rules: [{ path: [0], strictType: HEADING_KEYS.h1 }],\n },\n }),\n resetBlockTypePlugin,\n SelectOnBackspacePlugin.configure({\n options: {\n query: {\n allow: [ImagePlugin.key, HorizontalRulePlugin.key],\n },\n },\n }),\n DeletePlugin,\n SingleLinePlugin,\n softBreakPlugin,\n tabbablePlugin,\n TrailingBlockPlugin.configure({\n options: { type: ParagraphPlugin.key },\n }),\n DragOverCursorPlugin,\n\n // Collaboration\n CommentsPlugin.configure({\n options: {\n comments: commentsData,\n myUserId: '1',\n users: usersData,\n },\n }),\n\n // Deserialization\n DocxPlugin,\n MarkdownPlugin.configure({ options: { indentList: true } }),\n JuicePlugin,\n\n // Testing\n PlaywrightPlugin.configure({\n enabled: process.env.NODE_ENV !== 'production',\n }),\n ],\n value: value,\n },\n []\n );\n};\n\nexport default function PlaygroundDemo({\n id,\n className,\n scrollSelector,\n}: {\n id?: ValueId;\n className?: string;\n scrollSelector?: string;\n}) {\n const containerRef = useRef(null);\n const enabled = settingsStore.use.checkedComponents();\n\n const editor = usePlaygroundEditor(\n id,\n scrollSelector ?? `blockSelection-${id}`\n );\n\n return (\n \n \n \n \n \n \n \n \n \n\n
\n \n \n\n \n \n \n \n \n \n \n\n \n \n \n \n\n \n \n \n
\n
\n
\n );\n}\n\nconst DemoIdContext = React.createContext(undefined);\n\nexport function DemoId({\n id,\n children,\n}: {\n children: React.ReactNode;\n id?: string;\n}) {\n return {children};\n}\n\nexport function useDemoId() {\n return React.useContext(DemoIdContext);\n}\n", + "content": "'use client';\n\nimport React, { useRef } from 'react';\n\nimport type { ValueId } from '@/config/customizer-plugins';\n\nimport { cn } from '@udecode/cn';\nimport { AIChatPlugin, CopilotPlugin } from '@udecode/plate-ai/react';\nimport { AlignPlugin } from '@udecode/plate-alignment/react';\nimport { AutoformatPlugin } from '@udecode/plate-autoformat/react';\nimport {\n BoldPlugin,\n CodePlugin,\n ItalicPlugin,\n StrikethroughPlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n UnderlinePlugin,\n} from '@udecode/plate-basic-marks/react';\nimport { BlockquotePlugin } from '@udecode/plate-block-quote/react';\nimport { SingleLinePlugin } from '@udecode/plate-break/react';\nimport { CaptionPlugin } from '@udecode/plate-caption/react';\nimport { CodeBlockPlugin } from '@udecode/plate-code-block/react';\nimport { CommentsPlugin } from '@udecode/plate-comments/react';\nimport {\n ParagraphPlugin,\n Plate,\n usePlateEditor,\n} from '@udecode/plate-common/react';\nimport { DatePlugin } from '@udecode/plate-date/react';\nimport { DndPlugin } from '@udecode/plate-dnd';\nimport { DocxPlugin } from '@udecode/plate-docx';\nimport { EmojiPlugin } from '@udecode/plate-emoji/react';\nimport { ExcalidrawPlugin } from '@udecode/plate-excalidraw/react';\nimport {\n FontBackgroundColorPlugin,\n FontColorPlugin,\n FontSizePlugin,\n} from '@udecode/plate-font/react';\nimport { HEADING_KEYS } from '@udecode/plate-heading';\nimport { HeadingPlugin, TocPlugin } from '@udecode/plate-heading/react';\nimport { HighlightPlugin } from '@udecode/plate-highlight/react';\nimport { HorizontalRulePlugin } from '@udecode/plate-horizontal-rule/react';\nimport { IndentPlugin } from '@udecode/plate-indent/react';\nimport { IndentListPlugin } from '@udecode/plate-indent-list/react';\nimport { JuicePlugin } from '@udecode/plate-juice';\nimport { KbdPlugin } from '@udecode/plate-kbd/react';\nimport { ColumnPlugin } from '@udecode/plate-layout/react';\nimport { LineHeightPlugin } from '@udecode/plate-line-height/react';\nimport { LinkPlugin } from '@udecode/plate-link/react';\nimport { ListPlugin, TodoListPlugin } from '@udecode/plate-list/react';\nimport { MarkdownPlugin } from '@udecode/plate-markdown';\nimport { BaseImagePlugin } from '@udecode/plate-media';\nimport { ImagePlugin, MediaEmbedPlugin } from '@udecode/plate-media/react';\nimport { MentionPlugin } from '@udecode/plate-mention/react';\nimport { NodeIdPlugin } from '@udecode/plate-node-id';\nimport { NormalizeTypesPlugin } from '@udecode/plate-normalizers';\nimport { PlaywrightPlugin } from '@udecode/plate-playwright';\nimport { DeletePlugin, SelectOnBackspacePlugin } from '@udecode/plate-select';\nimport {\n BlockMenuPlugin,\n BlockSelectionPlugin,\n} from '@udecode/plate-selection/react';\nimport { SlashPlugin } from '@udecode/plate-slash-command/react';\nimport { TablePlugin } from '@udecode/plate-table/react';\nimport { TogglePlugin } from '@udecode/plate-toggle/react';\nimport { TrailingBlockPlugin } from '@udecode/plate-trailing-block';\nimport Prism from 'prismjs';\n\nimport { CheckPlugin } from '@/components/context/check-plugin';\nimport { settingsStore } from '@/components/context/settings-store';\nimport { aiPlugins } from '@/lib/plate/demo/plugins/ai-plugins';\nimport { getAutoformatOptions } from '@/lib/plate/demo/plugins/autoformatOptions';\nimport { copilotPlugins } from '@/lib/plate/demo/plugins/copilot-plugins';\nimport { createPlateUI } from '@/plate/create-plate-ui';\nimport { editableProps } from '@/plate/demo/editableProps';\nimport { isEnabled } from '@/plate/demo/is-enabled';\nimport { DragOverCursorPlugin } from '@/plate/demo/plugins/DragOverCursorPlugin';\nimport { exitBreakPlugin } from '@/plate/demo/plugins/exitBreakPlugin';\nimport { resetBlockTypePlugin } from '@/plate/demo/plugins/resetBlockTypePlugin';\nimport { softBreakPlugin } from '@/plate/demo/plugins/softBreakPlugin';\nimport { tabbablePlugin } from '@/plate/demo/plugins/tabbablePlugin';\nimport { commentsData, usersData } from '@/plate/demo/values/commentsValue';\nimport { usePlaygroundValue } from '@/plate/demo/values/usePlaygroundValue';\nimport { BlockContextMenu } from '@/components/plate-ui/block-context-menu';\nimport { CommentsPopover } from '@/components/plate-ui/comments-popover';\nimport {\n CursorOverlay,\n SelectionOverlayPlugin,\n} from '@/components/plate-ui/cursor-overlay';\nimport { Editor, EditorContainer } from '@/components/plate-ui/editor';\nimport { FixedToolbar } from '@/components/plate-ui/fixed-toolbar';\nimport { FixedToolbarButtons } from '@/components/plate-ui/fixed-toolbar-buttons';\nimport { FloatingToolbar } from '@/components/plate-ui/floating-toolbar';\nimport { FloatingToolbarButtons } from '@/components/plate-ui/floating-toolbar-buttons';\nimport { ImagePreview } from '@/components/plate-ui/image-preview';\nimport {\n FireLiComponent,\n FireMarker,\n} from '@/components/plate-ui/indent-fire-marker';\nimport {\n TodoLi,\n TodoMarker,\n} from '@/components/plate-ui/indent-todo-marker';\nimport { LinkFloatingToolbar } from '@/components/plate-ui/link-floating-toolbar';\n\nimport { usePlaygroundEnabled } from './usePlaygroundEnabled';\n\nexport const usePlaygroundEditor = (id: any = '', scrollSelector?: string) => {\n const enabledPlugins = settingsStore.use.checkedPlugins();\n const overridePlugins = usePlaygroundEnabled(id);\n const autoformatOptions = getAutoformatOptions(id, enabledPlugins);\n\n const value = usePlaygroundValue(id);\n const key = settingsStore.use.version();\n const editorId = id || 'playground-' + key;\n\n return usePlateEditor(\n {\n id: editorId,\n override: {\n components: createPlateUI({\n draggable: isEnabled('dnd', id),\n placeholder: isEnabled('placeholder', id),\n }),\n plugins: overridePlugins,\n },\n plugins: [\n // AI\n ...(id === 'ai' || enabledPlugins[AIChatPlugin.key] ? aiPlugins : []),\n ...(id === 'copilot' || enabledPlugins[CopilotPlugin.key]\n ? copilotPlugins\n : []),\n // Nodes\n HeadingPlugin,\n TocPlugin.configure({\n options: {\n scrollContainerSelector: `#${scrollSelector}`,\n topOffset: 80,\n },\n }),\n BlockquotePlugin,\n CodeBlockPlugin.configure({\n options: {\n prism: Prism,\n },\n }),\n HorizontalRulePlugin,\n LinkPlugin.extend({\n render: { afterEditable: () => },\n }),\n ...(id === 'list' ? [ListPlugin] : []),\n ImagePlugin.extend({\n options: {\n disableUploadInsert: true,\n },\n render: { afterEditable: ImagePreview },\n }),\n MediaEmbedPlugin,\n CaptionPlugin.configure({\n options: {\n plugins: [ImagePlugin, MediaEmbedPlugin],\n },\n }),\n DatePlugin,\n MentionPlugin.configure({\n options: {\n triggerPreviousCharPattern: /^$|^[\\s\"']$/,\n },\n }),\n SlashPlugin,\n TablePlugin.configure({\n options: {\n enableMerging: id === 'tableMerge',\n },\n }),\n ColumnPlugin,\n SelectionOverlayPlugin,\n\n TodoListPlugin,\n TogglePlugin,\n ExcalidrawPlugin,\n // Marks\n BoldPlugin,\n ItalicPlugin,\n UnderlinePlugin,\n StrikethroughPlugin,\n CodePlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n FontColorPlugin,\n FontBackgroundColorPlugin,\n FontSizePlugin,\n HighlightPlugin,\n KbdPlugin,\n\n // Block Style\n AlignPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n MediaEmbedPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n ImagePlugin.key,\n HEADING_KEYS.h6,\n ],\n },\n }),\n IndentPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n }),\n IndentListPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n options: {\n listStyleTypes: {\n fire: {\n liComponent: FireLiComponent,\n markerComponent: FireMarker,\n type: 'fire',\n },\n todo: {\n liComponent: TodoLi,\n markerComponent: TodoMarker,\n type: 'todo',\n },\n },\n },\n }),\n LineHeightPlugin.extend({\n inject: {\n nodeProps: {\n defaultNodeValue: 1.5,\n validNodeValues: [1, 1.2, 1.5, 2, 3],\n },\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n ],\n },\n }),\n\n // Functionality\n AutoformatPlugin.configure({\n options: autoformatOptions,\n }),\n BlockSelectionPlugin.configure({\n options: {\n areaOptions: {\n behaviour: {\n scrolling: {\n speedDivider: 1.5,\n },\n startThreshold: 10,\n },\n boundaries: `#${scrollSelector}`,\n container: `#${scrollSelector}`,\n selectables: [`#${scrollSelector} .slate-selectable`],\n selectionAreaClass: 'slate-selection-area',\n },\n enableContextMenu: true,\n },\n }),\n BlockMenuPlugin.configure({\n render: { aboveEditable: BlockContextMenu },\n }),\n DndPlugin.configure({\n options: {\n enableScroller: true,\n onDropFiles: ({ dragItem, editor, target }) => {\n editor\n .getTransforms(BaseImagePlugin)\n .insert.imageFromFiles(dragItem.files, {\n at: target,\n nextBlock: false,\n });\n },\n },\n }),\n EmojiPlugin,\n exitBreakPlugin,\n NodeIdPlugin,\n NormalizeTypesPlugin.configure({\n options: {\n rules: [{ path: [0], strictType: HEADING_KEYS.h1 }],\n },\n }),\n resetBlockTypePlugin,\n SelectOnBackspacePlugin.configure({\n options: {\n query: {\n allow: [ImagePlugin.key, HorizontalRulePlugin.key],\n },\n },\n }),\n DeletePlugin,\n SingleLinePlugin,\n softBreakPlugin,\n tabbablePlugin,\n TrailingBlockPlugin.configure({\n options: { type: ParagraphPlugin.key },\n }),\n DragOverCursorPlugin,\n\n // Collaboration\n CommentsPlugin.configure({\n options: {\n comments: commentsData,\n myUserId: '1',\n users: usersData,\n },\n }),\n\n // Deserialization\n DocxPlugin,\n MarkdownPlugin.configure({ options: { indentList: true } }),\n JuicePlugin,\n\n // Testing\n PlaywrightPlugin.configure({\n enabled: process.env.NODE_ENV !== 'production',\n }),\n ],\n value: value,\n },\n []\n );\n};\n\nexport default function PlaygroundDemo({\n id,\n className,\n scrollSelector,\n}: {\n id?: ValueId;\n className?: string;\n scrollSelector?: string;\n}) {\n const containerRef = useRef(null);\n const enabled = settingsStore.use.checkedComponents();\n\n const editor = usePlaygroundEditor(\n id,\n scrollSelector ?? `blockSelection-${id}`\n );\n\n return (\n \n \n \n \n \n \n \n \n \n\n
\n \n \n\n \n \n \n \n \n \n \n\n \n \n \n \n\n \n \n \n
\n
\n
\n );\n}\n\nconst DemoIdContext = React.createContext(undefined);\n\nexport function DemoId({\n id,\n children,\n}: {\n children: React.ReactNode;\n id?: string;\n}) {\n return {children};\n}\n\nexport function useDemoId() {\n return React.useContext(DemoIdContext);\n}\n", "path": "example/playground-demo.tsx", "target": "components/playground-demo.tsx", "type": "registry:example" diff --git a/apps/www/public/r/styles/default/excalidraw-demo.json b/apps/www/public/r/styles/default/excalidraw-demo.json index fdc01f0220..483dfdf8b4 100644 --- a/apps/www/public/r/styles/default/excalidraw-demo.json +++ b/apps/www/public/r/styles/default/excalidraw-demo.json @@ -5,7 +5,7 @@ }, "files": [ { - "content": "'use client';\n\nimport React, { useRef } from 'react';\n\nimport type { ValueId } from '@/config/customizer-plugins';\n\nimport { cn } from '@udecode/cn';\nimport { AIChatPlugin, CopilotPlugin } from '@udecode/plate-ai/react';\nimport { AlignPlugin } from '@udecode/plate-alignment/react';\nimport { AutoformatPlugin } from '@udecode/plate-autoformat/react';\nimport {\n BoldPlugin,\n CodePlugin,\n ItalicPlugin,\n StrikethroughPlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n UnderlinePlugin,\n} from '@udecode/plate-basic-marks/react';\nimport { BlockquotePlugin } from '@udecode/plate-block-quote/react';\nimport { SingleLinePlugin } from '@udecode/plate-break/react';\nimport { CaptionPlugin } from '@udecode/plate-caption/react';\nimport { CodeBlockPlugin } from '@udecode/plate-code-block/react';\nimport { CommentsPlugin } from '@udecode/plate-comments/react';\nimport {\n ParagraphPlugin,\n Plate,\n usePlateEditor,\n} from '@udecode/plate-common/react';\nimport { DatePlugin } from '@udecode/plate-date/react';\nimport { DndPlugin } from '@udecode/plate-dnd';\nimport { DocxPlugin } from '@udecode/plate-docx';\nimport { EmojiPlugin } from '@udecode/plate-emoji/react';\nimport { ExcalidrawPlugin } from '@udecode/plate-excalidraw/react';\nimport {\n FontBackgroundColorPlugin,\n FontColorPlugin,\n FontSizePlugin,\n} from '@udecode/plate-font/react';\nimport { HEADING_KEYS } from '@udecode/plate-heading';\nimport { HeadingPlugin, TocPlugin } from '@udecode/plate-heading/react';\nimport { HighlightPlugin } from '@udecode/plate-highlight/react';\nimport { HorizontalRulePlugin } from '@udecode/plate-horizontal-rule/react';\nimport { IndentPlugin } from '@udecode/plate-indent/react';\nimport { IndentListPlugin } from '@udecode/plate-indent-list/react';\nimport { JuicePlugin } from '@udecode/plate-juice';\nimport { KbdPlugin } from '@udecode/plate-kbd/react';\nimport { ColumnPlugin } from '@udecode/plate-layout/react';\nimport { LineHeightPlugin } from '@udecode/plate-line-height/react';\nimport { LinkPlugin } from '@udecode/plate-link/react';\nimport { ListPlugin, TodoListPlugin } from '@udecode/plate-list/react';\nimport { MarkdownPlugin } from '@udecode/plate-markdown';\nimport { ImagePlugin, MediaEmbedPlugin } from '@udecode/plate-media/react';\nimport { MentionPlugin } from '@udecode/plate-mention/react';\nimport { NodeIdPlugin } from '@udecode/plate-node-id';\nimport { NormalizeTypesPlugin } from '@udecode/plate-normalizers';\nimport { PlaywrightPlugin } from '@udecode/plate-playwright';\nimport { DeletePlugin, SelectOnBackspacePlugin } from '@udecode/plate-select';\nimport {\n BlockMenuPlugin,\n BlockSelectionPlugin,\n} from '@udecode/plate-selection/react';\nimport { SlashPlugin } from '@udecode/plate-slash-command/react';\nimport { TablePlugin } from '@udecode/plate-table/react';\nimport { TogglePlugin } from '@udecode/plate-toggle/react';\nimport { TrailingBlockPlugin } from '@udecode/plate-trailing-block';\nimport Prism from 'prismjs';\n\nimport { CheckPlugin } from '@/components/context/check-plugin';\nimport { settingsStore } from '@/components/context/settings-store';\nimport { aiPlugins } from '@/lib/plate/demo/plugins/ai-plugins';\nimport { getAutoformatOptions } from '@/lib/plate/demo/plugins/autoformatOptions';\nimport { copilotPlugins } from '@/lib/plate/demo/plugins/copilot-plugins';\nimport { createPlateUI } from '@/plate/create-plate-ui';\nimport { editableProps } from '@/plate/demo/editableProps';\nimport { isEnabled } from '@/plate/demo/is-enabled';\nimport { DragOverCursorPlugin } from '@/plate/demo/plugins/DragOverCursorPlugin';\nimport { exitBreakPlugin } from '@/plate/demo/plugins/exitBreakPlugin';\nimport { resetBlockTypePlugin } from '@/plate/demo/plugins/resetBlockTypePlugin';\nimport { softBreakPlugin } from '@/plate/demo/plugins/softBreakPlugin';\nimport { tabbablePlugin } from '@/plate/demo/plugins/tabbablePlugin';\nimport { commentsData, usersData } from '@/plate/demo/values/commentsValue';\nimport { usePlaygroundValue } from '@/plate/demo/values/usePlaygroundValue';\nimport { BlockContextMenu } from '@/components/plate-ui/block-context-menu';\nimport { CommentsPopover } from '@/components/plate-ui/comments-popover';\nimport {\n CursorOverlay,\n SelectionOverlayPlugin,\n} from '@/components/plate-ui/cursor-overlay';\nimport { Editor, EditorContainer } from '@/components/plate-ui/editor';\nimport { FixedToolbar } from '@/components/plate-ui/fixed-toolbar';\nimport { FixedToolbarButtons } from '@/components/plate-ui/fixed-toolbar-buttons';\nimport { FloatingToolbar } from '@/components/plate-ui/floating-toolbar';\nimport { FloatingToolbarButtons } from '@/components/plate-ui/floating-toolbar-buttons';\nimport { ImagePreview } from '@/components/plate-ui/image-preview';\nimport {\n FireLiComponent,\n FireMarker,\n} from '@/components/plate-ui/indent-fire-marker';\nimport {\n TodoLi,\n TodoMarker,\n} from '@/components/plate-ui/indent-todo-marker';\nimport { LinkFloatingToolbar } from '@/components/plate-ui/link-floating-toolbar';\n\nimport { usePlaygroundEnabled } from './usePlaygroundEnabled';\n\nexport const usePlaygroundEditor = (id: any = '', scrollSelector?: string) => {\n const enabledPlugins = settingsStore.use.checkedPlugins();\n const overridePlugins = usePlaygroundEnabled(id);\n const autoformatOptions = getAutoformatOptions(id, enabledPlugins);\n\n const value = usePlaygroundValue(id);\n const key = settingsStore.use.version();\n const editorId = id || 'playground-' + key;\n\n return usePlateEditor(\n {\n id: editorId,\n override: {\n components: createPlateUI({\n draggable: isEnabled('dnd', id),\n placeholder: isEnabled('placeholder', id),\n }),\n plugins: overridePlugins,\n },\n plugins: [\n // AI\n ...(id === 'ai' || enabledPlugins[AIChatPlugin.key] ? aiPlugins : []),\n ...(id === 'copilot' || enabledPlugins[CopilotPlugin.key]\n ? copilotPlugins\n : []),\n // Nodes\n HeadingPlugin,\n TocPlugin.configure({\n options: {\n scrollContainerSelector: `#${scrollSelector}`,\n topOffset: 80,\n },\n }),\n BlockquotePlugin,\n CodeBlockPlugin.configure({\n options: {\n prism: Prism,\n },\n }),\n HorizontalRulePlugin,\n LinkPlugin.extend({\n render: { afterEditable: () => },\n }),\n ...(id === 'list' ? [ListPlugin] : []),\n ImagePlugin.extend({\n options: {\n disableUploadInsert: true,\n },\n render: { afterEditable: ImagePreview },\n }),\n MediaEmbedPlugin,\n CaptionPlugin.configure({\n options: {\n plugins: [ImagePlugin, MediaEmbedPlugin],\n },\n }),\n DatePlugin,\n MentionPlugin.configure({\n options: {\n triggerPreviousCharPattern: /^$|^[\\s\"']$/,\n },\n }),\n SlashPlugin,\n TablePlugin.configure({\n options: {\n enableMerging: id === 'tableMerge',\n },\n }),\n ColumnPlugin,\n SelectionOverlayPlugin,\n\n TodoListPlugin,\n TogglePlugin,\n ExcalidrawPlugin,\n // Marks\n BoldPlugin,\n ItalicPlugin,\n UnderlinePlugin,\n StrikethroughPlugin,\n CodePlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n FontColorPlugin,\n FontBackgroundColorPlugin,\n FontSizePlugin,\n HighlightPlugin,\n KbdPlugin,\n\n // Block Style\n AlignPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n MediaEmbedPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n ImagePlugin.key,\n HEADING_KEYS.h6,\n ],\n },\n }),\n IndentPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n }),\n IndentListPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n options: {\n listStyleTypes: {\n fire: {\n liComponent: FireLiComponent,\n markerComponent: FireMarker,\n type: 'fire',\n },\n todo: {\n liComponent: TodoLi,\n markerComponent: TodoMarker,\n type: 'todo',\n },\n },\n },\n }),\n LineHeightPlugin.extend({\n inject: {\n nodeProps: {\n defaultNodeValue: 1.5,\n validNodeValues: [1, 1.2, 1.5, 2, 3],\n },\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n ],\n },\n }),\n\n // Functionality\n AutoformatPlugin.configure({\n options: autoformatOptions,\n }),\n BlockSelectionPlugin.configure({\n options: {\n areaOptions: {\n behaviour: {\n scrolling: {\n speedDivider: 1.5,\n },\n startThreshold: 10,\n },\n boundaries: `#${scrollSelector}`,\n container: `#${scrollSelector}`,\n selectables: [`#${scrollSelector} .slate-selectable`],\n selectionAreaClass: 'slate-selection-area',\n },\n enableContextMenu: true,\n },\n }),\n BlockMenuPlugin.configure({\n render: { aboveEditable: BlockContextMenu },\n }),\n DndPlugin.configure({\n options: {\n enableScroller: true,\n onDropFiles: ({ dragItem, editor, target }) => {\n editor\n .getTransforms(ImagePlugin)\n .insertImageFromFiles(dragItem.files, {\n at: target,\n nextBlock: false,\n });\n },\n },\n }),\n EmojiPlugin,\n exitBreakPlugin,\n NodeIdPlugin,\n NormalizeTypesPlugin.configure({\n options: {\n rules: [{ path: [0], strictType: HEADING_KEYS.h1 }],\n },\n }),\n resetBlockTypePlugin,\n SelectOnBackspacePlugin.configure({\n options: {\n query: {\n allow: [ImagePlugin.key, HorizontalRulePlugin.key],\n },\n },\n }),\n DeletePlugin,\n SingleLinePlugin,\n softBreakPlugin,\n tabbablePlugin,\n TrailingBlockPlugin.configure({\n options: { type: ParagraphPlugin.key },\n }),\n DragOverCursorPlugin,\n\n // Collaboration\n CommentsPlugin.configure({\n options: {\n comments: commentsData,\n myUserId: '1',\n users: usersData,\n },\n }),\n\n // Deserialization\n DocxPlugin,\n MarkdownPlugin.configure({ options: { indentList: true } }),\n JuicePlugin,\n\n // Testing\n PlaywrightPlugin.configure({\n enabled: process.env.NODE_ENV !== 'production',\n }),\n ],\n value: value,\n },\n []\n );\n};\n\nexport default function PlaygroundDemo({\n id,\n className,\n scrollSelector,\n}: {\n id?: ValueId;\n className?: string;\n scrollSelector?: string;\n}) {\n const containerRef = useRef(null);\n const enabled = settingsStore.use.checkedComponents();\n\n const editor = usePlaygroundEditor(\n id,\n scrollSelector ?? `blockSelection-${id}`\n );\n\n return (\n \n \n \n \n \n \n \n \n \n\n
\n \n \n\n \n \n \n \n \n \n \n\n \n \n \n \n\n \n \n \n
\n
\n
\n );\n}\n\nconst DemoIdContext = React.createContext(undefined);\n\nexport function DemoId({\n id,\n children,\n}: {\n children: React.ReactNode;\n id?: string;\n}) {\n return {children};\n}\n\nexport function useDemoId() {\n return React.useContext(DemoIdContext);\n}\n", + "content": "'use client';\n\nimport React, { useRef } from 'react';\n\nimport type { ValueId } from '@/config/customizer-plugins';\n\nimport { cn } from '@udecode/cn';\nimport { AIChatPlugin, CopilotPlugin } from '@udecode/plate-ai/react';\nimport { AlignPlugin } from '@udecode/plate-alignment/react';\nimport { AutoformatPlugin } from '@udecode/plate-autoformat/react';\nimport {\n BoldPlugin,\n CodePlugin,\n ItalicPlugin,\n StrikethroughPlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n UnderlinePlugin,\n} from '@udecode/plate-basic-marks/react';\nimport { BlockquotePlugin } from '@udecode/plate-block-quote/react';\nimport { SingleLinePlugin } from '@udecode/plate-break/react';\nimport { CaptionPlugin } from '@udecode/plate-caption/react';\nimport { CodeBlockPlugin } from '@udecode/plate-code-block/react';\nimport { CommentsPlugin } from '@udecode/plate-comments/react';\nimport {\n ParagraphPlugin,\n Plate,\n usePlateEditor,\n} from '@udecode/plate-common/react';\nimport { DatePlugin } from '@udecode/plate-date/react';\nimport { DndPlugin } from '@udecode/plate-dnd';\nimport { DocxPlugin } from '@udecode/plate-docx';\nimport { EmojiPlugin } from '@udecode/plate-emoji/react';\nimport { ExcalidrawPlugin } from '@udecode/plate-excalidraw/react';\nimport {\n FontBackgroundColorPlugin,\n FontColorPlugin,\n FontSizePlugin,\n} from '@udecode/plate-font/react';\nimport { HEADING_KEYS } from '@udecode/plate-heading';\nimport { HeadingPlugin, TocPlugin } from '@udecode/plate-heading/react';\nimport { HighlightPlugin } from '@udecode/plate-highlight/react';\nimport { HorizontalRulePlugin } from '@udecode/plate-horizontal-rule/react';\nimport { IndentPlugin } from '@udecode/plate-indent/react';\nimport { IndentListPlugin } from '@udecode/plate-indent-list/react';\nimport { JuicePlugin } from '@udecode/plate-juice';\nimport { KbdPlugin } from '@udecode/plate-kbd/react';\nimport { ColumnPlugin } from '@udecode/plate-layout/react';\nimport { LineHeightPlugin } from '@udecode/plate-line-height/react';\nimport { LinkPlugin } from '@udecode/plate-link/react';\nimport { ListPlugin, TodoListPlugin } from '@udecode/plate-list/react';\nimport { MarkdownPlugin } from '@udecode/plate-markdown';\nimport { BaseImagePlugin } from '@udecode/plate-media';\nimport { ImagePlugin, MediaEmbedPlugin } from '@udecode/plate-media/react';\nimport { MentionPlugin } from '@udecode/plate-mention/react';\nimport { NodeIdPlugin } from '@udecode/plate-node-id';\nimport { NormalizeTypesPlugin } from '@udecode/plate-normalizers';\nimport { PlaywrightPlugin } from '@udecode/plate-playwright';\nimport { DeletePlugin, SelectOnBackspacePlugin } from '@udecode/plate-select';\nimport {\n BlockMenuPlugin,\n BlockSelectionPlugin,\n} from '@udecode/plate-selection/react';\nimport { SlashPlugin } from '@udecode/plate-slash-command/react';\nimport { TablePlugin } from '@udecode/plate-table/react';\nimport { TogglePlugin } from '@udecode/plate-toggle/react';\nimport { TrailingBlockPlugin } from '@udecode/plate-trailing-block';\nimport Prism from 'prismjs';\n\nimport { CheckPlugin } from '@/components/context/check-plugin';\nimport { settingsStore } from '@/components/context/settings-store';\nimport { aiPlugins } from '@/lib/plate/demo/plugins/ai-plugins';\nimport { getAutoformatOptions } from '@/lib/plate/demo/plugins/autoformatOptions';\nimport { copilotPlugins } from '@/lib/plate/demo/plugins/copilot-plugins';\nimport { createPlateUI } from '@/plate/create-plate-ui';\nimport { editableProps } from '@/plate/demo/editableProps';\nimport { isEnabled } from '@/plate/demo/is-enabled';\nimport { DragOverCursorPlugin } from '@/plate/demo/plugins/DragOverCursorPlugin';\nimport { exitBreakPlugin } from '@/plate/demo/plugins/exitBreakPlugin';\nimport { resetBlockTypePlugin } from '@/plate/demo/plugins/resetBlockTypePlugin';\nimport { softBreakPlugin } from '@/plate/demo/plugins/softBreakPlugin';\nimport { tabbablePlugin } from '@/plate/demo/plugins/tabbablePlugin';\nimport { commentsData, usersData } from '@/plate/demo/values/commentsValue';\nimport { usePlaygroundValue } from '@/plate/demo/values/usePlaygroundValue';\nimport { BlockContextMenu } from '@/components/plate-ui/block-context-menu';\nimport { CommentsPopover } from '@/components/plate-ui/comments-popover';\nimport {\n CursorOverlay,\n SelectionOverlayPlugin,\n} from '@/components/plate-ui/cursor-overlay';\nimport { Editor, EditorContainer } from '@/components/plate-ui/editor';\nimport { FixedToolbar } from '@/components/plate-ui/fixed-toolbar';\nimport { FixedToolbarButtons } from '@/components/plate-ui/fixed-toolbar-buttons';\nimport { FloatingToolbar } from '@/components/plate-ui/floating-toolbar';\nimport { FloatingToolbarButtons } from '@/components/plate-ui/floating-toolbar-buttons';\nimport { ImagePreview } from '@/components/plate-ui/image-preview';\nimport {\n FireLiComponent,\n FireMarker,\n} from '@/components/plate-ui/indent-fire-marker';\nimport {\n TodoLi,\n TodoMarker,\n} from '@/components/plate-ui/indent-todo-marker';\nimport { LinkFloatingToolbar } from '@/components/plate-ui/link-floating-toolbar';\n\nimport { usePlaygroundEnabled } from './usePlaygroundEnabled';\n\nexport const usePlaygroundEditor = (id: any = '', scrollSelector?: string) => {\n const enabledPlugins = settingsStore.use.checkedPlugins();\n const overridePlugins = usePlaygroundEnabled(id);\n const autoformatOptions = getAutoformatOptions(id, enabledPlugins);\n\n const value = usePlaygroundValue(id);\n const key = settingsStore.use.version();\n const editorId = id || 'playground-' + key;\n\n return usePlateEditor(\n {\n id: editorId,\n override: {\n components: createPlateUI({\n draggable: isEnabled('dnd', id),\n placeholder: isEnabled('placeholder', id),\n }),\n plugins: overridePlugins,\n },\n plugins: [\n // AI\n ...(id === 'ai' || enabledPlugins[AIChatPlugin.key] ? aiPlugins : []),\n ...(id === 'copilot' || enabledPlugins[CopilotPlugin.key]\n ? copilotPlugins\n : []),\n // Nodes\n HeadingPlugin,\n TocPlugin.configure({\n options: {\n scrollContainerSelector: `#${scrollSelector}`,\n topOffset: 80,\n },\n }),\n BlockquotePlugin,\n CodeBlockPlugin.configure({\n options: {\n prism: Prism,\n },\n }),\n HorizontalRulePlugin,\n LinkPlugin.extend({\n render: { afterEditable: () => },\n }),\n ...(id === 'list' ? [ListPlugin] : []),\n ImagePlugin.extend({\n options: {\n disableUploadInsert: true,\n },\n render: { afterEditable: ImagePreview },\n }),\n MediaEmbedPlugin,\n CaptionPlugin.configure({\n options: {\n plugins: [ImagePlugin, MediaEmbedPlugin],\n },\n }),\n DatePlugin,\n MentionPlugin.configure({\n options: {\n triggerPreviousCharPattern: /^$|^[\\s\"']$/,\n },\n }),\n SlashPlugin,\n TablePlugin.configure({\n options: {\n enableMerging: id === 'tableMerge',\n },\n }),\n ColumnPlugin,\n SelectionOverlayPlugin,\n\n TodoListPlugin,\n TogglePlugin,\n ExcalidrawPlugin,\n // Marks\n BoldPlugin,\n ItalicPlugin,\n UnderlinePlugin,\n StrikethroughPlugin,\n CodePlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n FontColorPlugin,\n FontBackgroundColorPlugin,\n FontSizePlugin,\n HighlightPlugin,\n KbdPlugin,\n\n // Block Style\n AlignPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n MediaEmbedPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n ImagePlugin.key,\n HEADING_KEYS.h6,\n ],\n },\n }),\n IndentPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n }),\n IndentListPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n options: {\n listStyleTypes: {\n fire: {\n liComponent: FireLiComponent,\n markerComponent: FireMarker,\n type: 'fire',\n },\n todo: {\n liComponent: TodoLi,\n markerComponent: TodoMarker,\n type: 'todo',\n },\n },\n },\n }),\n LineHeightPlugin.extend({\n inject: {\n nodeProps: {\n defaultNodeValue: 1.5,\n validNodeValues: [1, 1.2, 1.5, 2, 3],\n },\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n ],\n },\n }),\n\n // Functionality\n AutoformatPlugin.configure({\n options: autoformatOptions,\n }),\n BlockSelectionPlugin.configure({\n options: {\n areaOptions: {\n behaviour: {\n scrolling: {\n speedDivider: 1.5,\n },\n startThreshold: 10,\n },\n boundaries: `#${scrollSelector}`,\n container: `#${scrollSelector}`,\n selectables: [`#${scrollSelector} .slate-selectable`],\n selectionAreaClass: 'slate-selection-area',\n },\n enableContextMenu: true,\n },\n }),\n BlockMenuPlugin.configure({\n render: { aboveEditable: BlockContextMenu },\n }),\n DndPlugin.configure({\n options: {\n enableScroller: true,\n onDropFiles: ({ dragItem, editor, target }) => {\n editor\n .getTransforms(BaseImagePlugin)\n .insert.imageFromFiles(dragItem.files, {\n at: target,\n nextBlock: false,\n });\n },\n },\n }),\n EmojiPlugin,\n exitBreakPlugin,\n NodeIdPlugin,\n NormalizeTypesPlugin.configure({\n options: {\n rules: [{ path: [0], strictType: HEADING_KEYS.h1 }],\n },\n }),\n resetBlockTypePlugin,\n SelectOnBackspacePlugin.configure({\n options: {\n query: {\n allow: [ImagePlugin.key, HorizontalRulePlugin.key],\n },\n },\n }),\n DeletePlugin,\n SingleLinePlugin,\n softBreakPlugin,\n tabbablePlugin,\n TrailingBlockPlugin.configure({\n options: { type: ParagraphPlugin.key },\n }),\n DragOverCursorPlugin,\n\n // Collaboration\n CommentsPlugin.configure({\n options: {\n comments: commentsData,\n myUserId: '1',\n users: usersData,\n },\n }),\n\n // Deserialization\n DocxPlugin,\n MarkdownPlugin.configure({ options: { indentList: true } }),\n JuicePlugin,\n\n // Testing\n PlaywrightPlugin.configure({\n enabled: process.env.NODE_ENV !== 'production',\n }),\n ],\n value: value,\n },\n []\n );\n};\n\nexport default function PlaygroundDemo({\n id,\n className,\n scrollSelector,\n}: {\n id?: ValueId;\n className?: string;\n scrollSelector?: string;\n}) {\n const containerRef = useRef(null);\n const enabled = settingsStore.use.checkedComponents();\n\n const editor = usePlaygroundEditor(\n id,\n scrollSelector ?? `blockSelection-${id}`\n );\n\n return (\n \n \n \n \n \n \n \n \n \n\n
\n \n \n\n \n \n \n \n \n \n \n\n \n \n \n \n\n \n \n \n
\n
\n
\n );\n}\n\nconst DemoIdContext = React.createContext(undefined);\n\nexport function DemoId({\n id,\n children,\n}: {\n children: React.ReactNode;\n id?: string;\n}) {\n return {children};\n}\n\nexport function useDemoId() {\n return React.useContext(DemoIdContext);\n}\n", "path": "example/playground-demo.tsx", "target": "components/playground-demo.tsx", "type": "registry:example" diff --git a/apps/www/public/r/styles/default/floating-toolbar-demo.json b/apps/www/public/r/styles/default/floating-toolbar-demo.json index d8ad642643..6a4e3f647b 100644 --- a/apps/www/public/r/styles/default/floating-toolbar-demo.json +++ b/apps/www/public/r/styles/default/floating-toolbar-demo.json @@ -4,7 +4,7 @@ }, "files": [ { - "content": "'use client';\n\nimport React, { useRef } from 'react';\n\nimport type { ValueId } from '@/config/customizer-plugins';\n\nimport { cn } from '@udecode/cn';\nimport { AIChatPlugin, CopilotPlugin } from '@udecode/plate-ai/react';\nimport { AlignPlugin } from '@udecode/plate-alignment/react';\nimport { AutoformatPlugin } from '@udecode/plate-autoformat/react';\nimport {\n BoldPlugin,\n CodePlugin,\n ItalicPlugin,\n StrikethroughPlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n UnderlinePlugin,\n} from '@udecode/plate-basic-marks/react';\nimport { BlockquotePlugin } from '@udecode/plate-block-quote/react';\nimport { SingleLinePlugin } from '@udecode/plate-break/react';\nimport { CaptionPlugin } from '@udecode/plate-caption/react';\nimport { CodeBlockPlugin } from '@udecode/plate-code-block/react';\nimport { CommentsPlugin } from '@udecode/plate-comments/react';\nimport {\n ParagraphPlugin,\n Plate,\n usePlateEditor,\n} from '@udecode/plate-common/react';\nimport { DatePlugin } from '@udecode/plate-date/react';\nimport { DndPlugin } from '@udecode/plate-dnd';\nimport { DocxPlugin } from '@udecode/plate-docx';\nimport { EmojiPlugin } from '@udecode/plate-emoji/react';\nimport { ExcalidrawPlugin } from '@udecode/plate-excalidraw/react';\nimport {\n FontBackgroundColorPlugin,\n FontColorPlugin,\n FontSizePlugin,\n} from '@udecode/plate-font/react';\nimport { HEADING_KEYS } from '@udecode/plate-heading';\nimport { HeadingPlugin, TocPlugin } from '@udecode/plate-heading/react';\nimport { HighlightPlugin } from '@udecode/plate-highlight/react';\nimport { HorizontalRulePlugin } from '@udecode/plate-horizontal-rule/react';\nimport { IndentPlugin } from '@udecode/plate-indent/react';\nimport { IndentListPlugin } from '@udecode/plate-indent-list/react';\nimport { JuicePlugin } from '@udecode/plate-juice';\nimport { KbdPlugin } from '@udecode/plate-kbd/react';\nimport { ColumnPlugin } from '@udecode/plate-layout/react';\nimport { LineHeightPlugin } from '@udecode/plate-line-height/react';\nimport { LinkPlugin } from '@udecode/plate-link/react';\nimport { ListPlugin, TodoListPlugin } from '@udecode/plate-list/react';\nimport { MarkdownPlugin } from '@udecode/plate-markdown';\nimport { ImagePlugin, MediaEmbedPlugin } from '@udecode/plate-media/react';\nimport { MentionPlugin } from '@udecode/plate-mention/react';\nimport { NodeIdPlugin } from '@udecode/plate-node-id';\nimport { NormalizeTypesPlugin } from '@udecode/plate-normalizers';\nimport { PlaywrightPlugin } from '@udecode/plate-playwright';\nimport { DeletePlugin, SelectOnBackspacePlugin } from '@udecode/plate-select';\nimport {\n BlockMenuPlugin,\n BlockSelectionPlugin,\n} from '@udecode/plate-selection/react';\nimport { SlashPlugin } from '@udecode/plate-slash-command/react';\nimport { TablePlugin } from '@udecode/plate-table/react';\nimport { TogglePlugin } from '@udecode/plate-toggle/react';\nimport { TrailingBlockPlugin } from '@udecode/plate-trailing-block';\nimport Prism from 'prismjs';\n\nimport { CheckPlugin } from '@/components/context/check-plugin';\nimport { settingsStore } from '@/components/context/settings-store';\nimport { aiPlugins } from '@/lib/plate/demo/plugins/ai-plugins';\nimport { getAutoformatOptions } from '@/lib/plate/demo/plugins/autoformatOptions';\nimport { copilotPlugins } from '@/lib/plate/demo/plugins/copilot-plugins';\nimport { createPlateUI } from '@/plate/create-plate-ui';\nimport { editableProps } from '@/plate/demo/editableProps';\nimport { isEnabled } from '@/plate/demo/is-enabled';\nimport { DragOverCursorPlugin } from '@/plate/demo/plugins/DragOverCursorPlugin';\nimport { exitBreakPlugin } from '@/plate/demo/plugins/exitBreakPlugin';\nimport { resetBlockTypePlugin } from '@/plate/demo/plugins/resetBlockTypePlugin';\nimport { softBreakPlugin } from '@/plate/demo/plugins/softBreakPlugin';\nimport { tabbablePlugin } from '@/plate/demo/plugins/tabbablePlugin';\nimport { commentsData, usersData } from '@/plate/demo/values/commentsValue';\nimport { usePlaygroundValue } from '@/plate/demo/values/usePlaygroundValue';\nimport { BlockContextMenu } from '@/components/plate-ui/block-context-menu';\nimport { CommentsPopover } from '@/components/plate-ui/comments-popover';\nimport {\n CursorOverlay,\n SelectionOverlayPlugin,\n} from '@/components/plate-ui/cursor-overlay';\nimport { Editor, EditorContainer } from '@/components/plate-ui/editor';\nimport { FixedToolbar } from '@/components/plate-ui/fixed-toolbar';\nimport { FixedToolbarButtons } from '@/components/plate-ui/fixed-toolbar-buttons';\nimport { FloatingToolbar } from '@/components/plate-ui/floating-toolbar';\nimport { FloatingToolbarButtons } from '@/components/plate-ui/floating-toolbar-buttons';\nimport { ImagePreview } from '@/components/plate-ui/image-preview';\nimport {\n FireLiComponent,\n FireMarker,\n} from '@/components/plate-ui/indent-fire-marker';\nimport {\n TodoLi,\n TodoMarker,\n} from '@/components/plate-ui/indent-todo-marker';\nimport { LinkFloatingToolbar } from '@/components/plate-ui/link-floating-toolbar';\n\nimport { usePlaygroundEnabled } from './usePlaygroundEnabled';\n\nexport const usePlaygroundEditor = (id: any = '', scrollSelector?: string) => {\n const enabledPlugins = settingsStore.use.checkedPlugins();\n const overridePlugins = usePlaygroundEnabled(id);\n const autoformatOptions = getAutoformatOptions(id, enabledPlugins);\n\n const value = usePlaygroundValue(id);\n const key = settingsStore.use.version();\n const editorId = id || 'playground-' + key;\n\n return usePlateEditor(\n {\n id: editorId,\n override: {\n components: createPlateUI({\n draggable: isEnabled('dnd', id),\n placeholder: isEnabled('placeholder', id),\n }),\n plugins: overridePlugins,\n },\n plugins: [\n // AI\n ...(id === 'ai' || enabledPlugins[AIChatPlugin.key] ? aiPlugins : []),\n ...(id === 'copilot' || enabledPlugins[CopilotPlugin.key]\n ? copilotPlugins\n : []),\n // Nodes\n HeadingPlugin,\n TocPlugin.configure({\n options: {\n scrollContainerSelector: `#${scrollSelector}`,\n topOffset: 80,\n },\n }),\n BlockquotePlugin,\n CodeBlockPlugin.configure({\n options: {\n prism: Prism,\n },\n }),\n HorizontalRulePlugin,\n LinkPlugin.extend({\n render: { afterEditable: () => },\n }),\n ...(id === 'list' ? [ListPlugin] : []),\n ImagePlugin.extend({\n options: {\n disableUploadInsert: true,\n },\n render: { afterEditable: ImagePreview },\n }),\n MediaEmbedPlugin,\n CaptionPlugin.configure({\n options: {\n plugins: [ImagePlugin, MediaEmbedPlugin],\n },\n }),\n DatePlugin,\n MentionPlugin.configure({\n options: {\n triggerPreviousCharPattern: /^$|^[\\s\"']$/,\n },\n }),\n SlashPlugin,\n TablePlugin.configure({\n options: {\n enableMerging: id === 'tableMerge',\n },\n }),\n ColumnPlugin,\n SelectionOverlayPlugin,\n\n TodoListPlugin,\n TogglePlugin,\n ExcalidrawPlugin,\n // Marks\n BoldPlugin,\n ItalicPlugin,\n UnderlinePlugin,\n StrikethroughPlugin,\n CodePlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n FontColorPlugin,\n FontBackgroundColorPlugin,\n FontSizePlugin,\n HighlightPlugin,\n KbdPlugin,\n\n // Block Style\n AlignPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n MediaEmbedPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n ImagePlugin.key,\n HEADING_KEYS.h6,\n ],\n },\n }),\n IndentPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n }),\n IndentListPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n options: {\n listStyleTypes: {\n fire: {\n liComponent: FireLiComponent,\n markerComponent: FireMarker,\n type: 'fire',\n },\n todo: {\n liComponent: TodoLi,\n markerComponent: TodoMarker,\n type: 'todo',\n },\n },\n },\n }),\n LineHeightPlugin.extend({\n inject: {\n nodeProps: {\n defaultNodeValue: 1.5,\n validNodeValues: [1, 1.2, 1.5, 2, 3],\n },\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n ],\n },\n }),\n\n // Functionality\n AutoformatPlugin.configure({\n options: autoformatOptions,\n }),\n BlockSelectionPlugin.configure({\n options: {\n areaOptions: {\n behaviour: {\n scrolling: {\n speedDivider: 1.5,\n },\n startThreshold: 10,\n },\n boundaries: `#${scrollSelector}`,\n container: `#${scrollSelector}`,\n selectables: [`#${scrollSelector} .slate-selectable`],\n selectionAreaClass: 'slate-selection-area',\n },\n enableContextMenu: true,\n },\n }),\n BlockMenuPlugin.configure({\n render: { aboveEditable: BlockContextMenu },\n }),\n DndPlugin.configure({\n options: {\n enableScroller: true,\n onDropFiles: ({ dragItem, editor, target }) => {\n editor\n .getTransforms(ImagePlugin)\n .insertImageFromFiles(dragItem.files, {\n at: target,\n nextBlock: false,\n });\n },\n },\n }),\n EmojiPlugin,\n exitBreakPlugin,\n NodeIdPlugin,\n NormalizeTypesPlugin.configure({\n options: {\n rules: [{ path: [0], strictType: HEADING_KEYS.h1 }],\n },\n }),\n resetBlockTypePlugin,\n SelectOnBackspacePlugin.configure({\n options: {\n query: {\n allow: [ImagePlugin.key, HorizontalRulePlugin.key],\n },\n },\n }),\n DeletePlugin,\n SingleLinePlugin,\n softBreakPlugin,\n tabbablePlugin,\n TrailingBlockPlugin.configure({\n options: { type: ParagraphPlugin.key },\n }),\n DragOverCursorPlugin,\n\n // Collaboration\n CommentsPlugin.configure({\n options: {\n comments: commentsData,\n myUserId: '1',\n users: usersData,\n },\n }),\n\n // Deserialization\n DocxPlugin,\n MarkdownPlugin.configure({ options: { indentList: true } }),\n JuicePlugin,\n\n // Testing\n PlaywrightPlugin.configure({\n enabled: process.env.NODE_ENV !== 'production',\n }),\n ],\n value: value,\n },\n []\n );\n};\n\nexport default function PlaygroundDemo({\n id,\n className,\n scrollSelector,\n}: {\n id?: ValueId;\n className?: string;\n scrollSelector?: string;\n}) {\n const containerRef = useRef(null);\n const enabled = settingsStore.use.checkedComponents();\n\n const editor = usePlaygroundEditor(\n id,\n scrollSelector ?? `blockSelection-${id}`\n );\n\n return (\n \n \n \n \n \n \n \n \n \n\n
\n \n \n\n \n \n \n \n \n \n \n\n \n \n \n \n\n \n \n \n
\n
\n
\n );\n}\n\nconst DemoIdContext = React.createContext(undefined);\n\nexport function DemoId({\n id,\n children,\n}: {\n children: React.ReactNode;\n id?: string;\n}) {\n return {children};\n}\n\nexport function useDemoId() {\n return React.useContext(DemoIdContext);\n}\n", + "content": "'use client';\n\nimport React, { useRef } from 'react';\n\nimport type { ValueId } from '@/config/customizer-plugins';\n\nimport { cn } from '@udecode/cn';\nimport { AIChatPlugin, CopilotPlugin } from '@udecode/plate-ai/react';\nimport { AlignPlugin } from '@udecode/plate-alignment/react';\nimport { AutoformatPlugin } from '@udecode/plate-autoformat/react';\nimport {\n BoldPlugin,\n CodePlugin,\n ItalicPlugin,\n StrikethroughPlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n UnderlinePlugin,\n} from '@udecode/plate-basic-marks/react';\nimport { BlockquotePlugin } from '@udecode/plate-block-quote/react';\nimport { SingleLinePlugin } from '@udecode/plate-break/react';\nimport { CaptionPlugin } from '@udecode/plate-caption/react';\nimport { CodeBlockPlugin } from '@udecode/plate-code-block/react';\nimport { CommentsPlugin } from '@udecode/plate-comments/react';\nimport {\n ParagraphPlugin,\n Plate,\n usePlateEditor,\n} from '@udecode/plate-common/react';\nimport { DatePlugin } from '@udecode/plate-date/react';\nimport { DndPlugin } from '@udecode/plate-dnd';\nimport { DocxPlugin } from '@udecode/plate-docx';\nimport { EmojiPlugin } from '@udecode/plate-emoji/react';\nimport { ExcalidrawPlugin } from '@udecode/plate-excalidraw/react';\nimport {\n FontBackgroundColorPlugin,\n FontColorPlugin,\n FontSizePlugin,\n} from '@udecode/plate-font/react';\nimport { HEADING_KEYS } from '@udecode/plate-heading';\nimport { HeadingPlugin, TocPlugin } from '@udecode/plate-heading/react';\nimport { HighlightPlugin } from '@udecode/plate-highlight/react';\nimport { HorizontalRulePlugin } from '@udecode/plate-horizontal-rule/react';\nimport { IndentPlugin } from '@udecode/plate-indent/react';\nimport { IndentListPlugin } from '@udecode/plate-indent-list/react';\nimport { JuicePlugin } from '@udecode/plate-juice';\nimport { KbdPlugin } from '@udecode/plate-kbd/react';\nimport { ColumnPlugin } from '@udecode/plate-layout/react';\nimport { LineHeightPlugin } from '@udecode/plate-line-height/react';\nimport { LinkPlugin } from '@udecode/plate-link/react';\nimport { ListPlugin, TodoListPlugin } from '@udecode/plate-list/react';\nimport { MarkdownPlugin } from '@udecode/plate-markdown';\nimport { BaseImagePlugin } from '@udecode/plate-media';\nimport { ImagePlugin, MediaEmbedPlugin } from '@udecode/plate-media/react';\nimport { MentionPlugin } from '@udecode/plate-mention/react';\nimport { NodeIdPlugin } from '@udecode/plate-node-id';\nimport { NormalizeTypesPlugin } from '@udecode/plate-normalizers';\nimport { PlaywrightPlugin } from '@udecode/plate-playwright';\nimport { DeletePlugin, SelectOnBackspacePlugin } from '@udecode/plate-select';\nimport {\n BlockMenuPlugin,\n BlockSelectionPlugin,\n} from '@udecode/plate-selection/react';\nimport { SlashPlugin } from '@udecode/plate-slash-command/react';\nimport { TablePlugin } from '@udecode/plate-table/react';\nimport { TogglePlugin } from '@udecode/plate-toggle/react';\nimport { TrailingBlockPlugin } from '@udecode/plate-trailing-block';\nimport Prism from 'prismjs';\n\nimport { CheckPlugin } from '@/components/context/check-plugin';\nimport { settingsStore } from '@/components/context/settings-store';\nimport { aiPlugins } from '@/lib/plate/demo/plugins/ai-plugins';\nimport { getAutoformatOptions } from '@/lib/plate/demo/plugins/autoformatOptions';\nimport { copilotPlugins } from '@/lib/plate/demo/plugins/copilot-plugins';\nimport { createPlateUI } from '@/plate/create-plate-ui';\nimport { editableProps } from '@/plate/demo/editableProps';\nimport { isEnabled } from '@/plate/demo/is-enabled';\nimport { DragOverCursorPlugin } from '@/plate/demo/plugins/DragOverCursorPlugin';\nimport { exitBreakPlugin } from '@/plate/demo/plugins/exitBreakPlugin';\nimport { resetBlockTypePlugin } from '@/plate/demo/plugins/resetBlockTypePlugin';\nimport { softBreakPlugin } from '@/plate/demo/plugins/softBreakPlugin';\nimport { tabbablePlugin } from '@/plate/demo/plugins/tabbablePlugin';\nimport { commentsData, usersData } from '@/plate/demo/values/commentsValue';\nimport { usePlaygroundValue } from '@/plate/demo/values/usePlaygroundValue';\nimport { BlockContextMenu } from '@/components/plate-ui/block-context-menu';\nimport { CommentsPopover } from '@/components/plate-ui/comments-popover';\nimport {\n CursorOverlay,\n SelectionOverlayPlugin,\n} from '@/components/plate-ui/cursor-overlay';\nimport { Editor, EditorContainer } from '@/components/plate-ui/editor';\nimport { FixedToolbar } from '@/components/plate-ui/fixed-toolbar';\nimport { FixedToolbarButtons } from '@/components/plate-ui/fixed-toolbar-buttons';\nimport { FloatingToolbar } from '@/components/plate-ui/floating-toolbar';\nimport { FloatingToolbarButtons } from '@/components/plate-ui/floating-toolbar-buttons';\nimport { ImagePreview } from '@/components/plate-ui/image-preview';\nimport {\n FireLiComponent,\n FireMarker,\n} from '@/components/plate-ui/indent-fire-marker';\nimport {\n TodoLi,\n TodoMarker,\n} from '@/components/plate-ui/indent-todo-marker';\nimport { LinkFloatingToolbar } from '@/components/plate-ui/link-floating-toolbar';\n\nimport { usePlaygroundEnabled } from './usePlaygroundEnabled';\n\nexport const usePlaygroundEditor = (id: any = '', scrollSelector?: string) => {\n const enabledPlugins = settingsStore.use.checkedPlugins();\n const overridePlugins = usePlaygroundEnabled(id);\n const autoformatOptions = getAutoformatOptions(id, enabledPlugins);\n\n const value = usePlaygroundValue(id);\n const key = settingsStore.use.version();\n const editorId = id || 'playground-' + key;\n\n return usePlateEditor(\n {\n id: editorId,\n override: {\n components: createPlateUI({\n draggable: isEnabled('dnd', id),\n placeholder: isEnabled('placeholder', id),\n }),\n plugins: overridePlugins,\n },\n plugins: [\n // AI\n ...(id === 'ai' || enabledPlugins[AIChatPlugin.key] ? aiPlugins : []),\n ...(id === 'copilot' || enabledPlugins[CopilotPlugin.key]\n ? copilotPlugins\n : []),\n // Nodes\n HeadingPlugin,\n TocPlugin.configure({\n options: {\n scrollContainerSelector: `#${scrollSelector}`,\n topOffset: 80,\n },\n }),\n BlockquotePlugin,\n CodeBlockPlugin.configure({\n options: {\n prism: Prism,\n },\n }),\n HorizontalRulePlugin,\n LinkPlugin.extend({\n render: { afterEditable: () => },\n }),\n ...(id === 'list' ? [ListPlugin] : []),\n ImagePlugin.extend({\n options: {\n disableUploadInsert: true,\n },\n render: { afterEditable: ImagePreview },\n }),\n MediaEmbedPlugin,\n CaptionPlugin.configure({\n options: {\n plugins: [ImagePlugin, MediaEmbedPlugin],\n },\n }),\n DatePlugin,\n MentionPlugin.configure({\n options: {\n triggerPreviousCharPattern: /^$|^[\\s\"']$/,\n },\n }),\n SlashPlugin,\n TablePlugin.configure({\n options: {\n enableMerging: id === 'tableMerge',\n },\n }),\n ColumnPlugin,\n SelectionOverlayPlugin,\n\n TodoListPlugin,\n TogglePlugin,\n ExcalidrawPlugin,\n // Marks\n BoldPlugin,\n ItalicPlugin,\n UnderlinePlugin,\n StrikethroughPlugin,\n CodePlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n FontColorPlugin,\n FontBackgroundColorPlugin,\n FontSizePlugin,\n HighlightPlugin,\n KbdPlugin,\n\n // Block Style\n AlignPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n MediaEmbedPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n ImagePlugin.key,\n HEADING_KEYS.h6,\n ],\n },\n }),\n IndentPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n }),\n IndentListPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n options: {\n listStyleTypes: {\n fire: {\n liComponent: FireLiComponent,\n markerComponent: FireMarker,\n type: 'fire',\n },\n todo: {\n liComponent: TodoLi,\n markerComponent: TodoMarker,\n type: 'todo',\n },\n },\n },\n }),\n LineHeightPlugin.extend({\n inject: {\n nodeProps: {\n defaultNodeValue: 1.5,\n validNodeValues: [1, 1.2, 1.5, 2, 3],\n },\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n ],\n },\n }),\n\n // Functionality\n AutoformatPlugin.configure({\n options: autoformatOptions,\n }),\n BlockSelectionPlugin.configure({\n options: {\n areaOptions: {\n behaviour: {\n scrolling: {\n speedDivider: 1.5,\n },\n startThreshold: 10,\n },\n boundaries: `#${scrollSelector}`,\n container: `#${scrollSelector}`,\n selectables: [`#${scrollSelector} .slate-selectable`],\n selectionAreaClass: 'slate-selection-area',\n },\n enableContextMenu: true,\n },\n }),\n BlockMenuPlugin.configure({\n render: { aboveEditable: BlockContextMenu },\n }),\n DndPlugin.configure({\n options: {\n enableScroller: true,\n onDropFiles: ({ dragItem, editor, target }) => {\n editor\n .getTransforms(BaseImagePlugin)\n .insert.imageFromFiles(dragItem.files, {\n at: target,\n nextBlock: false,\n });\n },\n },\n }),\n EmojiPlugin,\n exitBreakPlugin,\n NodeIdPlugin,\n NormalizeTypesPlugin.configure({\n options: {\n rules: [{ path: [0], strictType: HEADING_KEYS.h1 }],\n },\n }),\n resetBlockTypePlugin,\n SelectOnBackspacePlugin.configure({\n options: {\n query: {\n allow: [ImagePlugin.key, HorizontalRulePlugin.key],\n },\n },\n }),\n DeletePlugin,\n SingleLinePlugin,\n softBreakPlugin,\n tabbablePlugin,\n TrailingBlockPlugin.configure({\n options: { type: ParagraphPlugin.key },\n }),\n DragOverCursorPlugin,\n\n // Collaboration\n CommentsPlugin.configure({\n options: {\n comments: commentsData,\n myUserId: '1',\n users: usersData,\n },\n }),\n\n // Deserialization\n DocxPlugin,\n MarkdownPlugin.configure({ options: { indentList: true } }),\n JuicePlugin,\n\n // Testing\n PlaywrightPlugin.configure({\n enabled: process.env.NODE_ENV !== 'production',\n }),\n ],\n value: value,\n },\n []\n );\n};\n\nexport default function PlaygroundDemo({\n id,\n className,\n scrollSelector,\n}: {\n id?: ValueId;\n className?: string;\n scrollSelector?: string;\n}) {\n const containerRef = useRef(null);\n const enabled = settingsStore.use.checkedComponents();\n\n const editor = usePlaygroundEditor(\n id,\n scrollSelector ?? `blockSelection-${id}`\n );\n\n return (\n \n \n \n \n \n \n \n \n \n\n
\n \n \n\n \n \n \n \n \n \n \n\n \n \n \n \n\n \n \n \n
\n
\n
\n );\n}\n\nconst DemoIdContext = React.createContext(undefined);\n\nexport function DemoId({\n id,\n children,\n}: {\n children: React.ReactNode;\n id?: string;\n}) {\n return {children};\n}\n\nexport function useDemoId() {\n return React.useContext(DemoIdContext);\n}\n", "path": "example/playground-demo.tsx", "target": "components/playground-demo.tsx", "type": "registry:example" diff --git a/apps/www/public/r/styles/default/font-demo.json b/apps/www/public/r/styles/default/font-demo.json index 9a403575df..339d0836f5 100644 --- a/apps/www/public/r/styles/default/font-demo.json +++ b/apps/www/public/r/styles/default/font-demo.json @@ -4,7 +4,7 @@ }, "files": [ { - "content": "'use client';\n\nimport React, { useRef } from 'react';\n\nimport type { ValueId } from '@/config/customizer-plugins';\n\nimport { cn } from '@udecode/cn';\nimport { AIChatPlugin, CopilotPlugin } from '@udecode/plate-ai/react';\nimport { AlignPlugin } from '@udecode/plate-alignment/react';\nimport { AutoformatPlugin } from '@udecode/plate-autoformat/react';\nimport {\n BoldPlugin,\n CodePlugin,\n ItalicPlugin,\n StrikethroughPlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n UnderlinePlugin,\n} from '@udecode/plate-basic-marks/react';\nimport { BlockquotePlugin } from '@udecode/plate-block-quote/react';\nimport { SingleLinePlugin } from '@udecode/plate-break/react';\nimport { CaptionPlugin } from '@udecode/plate-caption/react';\nimport { CodeBlockPlugin } from '@udecode/plate-code-block/react';\nimport { CommentsPlugin } from '@udecode/plate-comments/react';\nimport {\n ParagraphPlugin,\n Plate,\n usePlateEditor,\n} from '@udecode/plate-common/react';\nimport { DatePlugin } from '@udecode/plate-date/react';\nimport { DndPlugin } from '@udecode/plate-dnd';\nimport { DocxPlugin } from '@udecode/plate-docx';\nimport { EmojiPlugin } from '@udecode/plate-emoji/react';\nimport { ExcalidrawPlugin } from '@udecode/plate-excalidraw/react';\nimport {\n FontBackgroundColorPlugin,\n FontColorPlugin,\n FontSizePlugin,\n} from '@udecode/plate-font/react';\nimport { HEADING_KEYS } from '@udecode/plate-heading';\nimport { HeadingPlugin, TocPlugin } from '@udecode/plate-heading/react';\nimport { HighlightPlugin } from '@udecode/plate-highlight/react';\nimport { HorizontalRulePlugin } from '@udecode/plate-horizontal-rule/react';\nimport { IndentPlugin } from '@udecode/plate-indent/react';\nimport { IndentListPlugin } from '@udecode/plate-indent-list/react';\nimport { JuicePlugin } from '@udecode/plate-juice';\nimport { KbdPlugin } from '@udecode/plate-kbd/react';\nimport { ColumnPlugin } from '@udecode/plate-layout/react';\nimport { LineHeightPlugin } from '@udecode/plate-line-height/react';\nimport { LinkPlugin } from '@udecode/plate-link/react';\nimport { ListPlugin, TodoListPlugin } from '@udecode/plate-list/react';\nimport { MarkdownPlugin } from '@udecode/plate-markdown';\nimport { ImagePlugin, MediaEmbedPlugin } from '@udecode/plate-media/react';\nimport { MentionPlugin } from '@udecode/plate-mention/react';\nimport { NodeIdPlugin } from '@udecode/plate-node-id';\nimport { NormalizeTypesPlugin } from '@udecode/plate-normalizers';\nimport { PlaywrightPlugin } from '@udecode/plate-playwright';\nimport { DeletePlugin, SelectOnBackspacePlugin } from '@udecode/plate-select';\nimport {\n BlockMenuPlugin,\n BlockSelectionPlugin,\n} from '@udecode/plate-selection/react';\nimport { SlashPlugin } from '@udecode/plate-slash-command/react';\nimport { TablePlugin } from '@udecode/plate-table/react';\nimport { TogglePlugin } from '@udecode/plate-toggle/react';\nimport { TrailingBlockPlugin } from '@udecode/plate-trailing-block';\nimport Prism from 'prismjs';\n\nimport { CheckPlugin } from '@/components/context/check-plugin';\nimport { settingsStore } from '@/components/context/settings-store';\nimport { aiPlugins } from '@/lib/plate/demo/plugins/ai-plugins';\nimport { getAutoformatOptions } from '@/lib/plate/demo/plugins/autoformatOptions';\nimport { copilotPlugins } from '@/lib/plate/demo/plugins/copilot-plugins';\nimport { createPlateUI } from '@/plate/create-plate-ui';\nimport { editableProps } from '@/plate/demo/editableProps';\nimport { isEnabled } from '@/plate/demo/is-enabled';\nimport { DragOverCursorPlugin } from '@/plate/demo/plugins/DragOverCursorPlugin';\nimport { exitBreakPlugin } from '@/plate/demo/plugins/exitBreakPlugin';\nimport { resetBlockTypePlugin } from '@/plate/demo/plugins/resetBlockTypePlugin';\nimport { softBreakPlugin } from '@/plate/demo/plugins/softBreakPlugin';\nimport { tabbablePlugin } from '@/plate/demo/plugins/tabbablePlugin';\nimport { commentsData, usersData } from '@/plate/demo/values/commentsValue';\nimport { usePlaygroundValue } from '@/plate/demo/values/usePlaygroundValue';\nimport { BlockContextMenu } from '@/components/plate-ui/block-context-menu';\nimport { CommentsPopover } from '@/components/plate-ui/comments-popover';\nimport {\n CursorOverlay,\n SelectionOverlayPlugin,\n} from '@/components/plate-ui/cursor-overlay';\nimport { Editor, EditorContainer } from '@/components/plate-ui/editor';\nimport { FixedToolbar } from '@/components/plate-ui/fixed-toolbar';\nimport { FixedToolbarButtons } from '@/components/plate-ui/fixed-toolbar-buttons';\nimport { FloatingToolbar } from '@/components/plate-ui/floating-toolbar';\nimport { FloatingToolbarButtons } from '@/components/plate-ui/floating-toolbar-buttons';\nimport { ImagePreview } from '@/components/plate-ui/image-preview';\nimport {\n FireLiComponent,\n FireMarker,\n} from '@/components/plate-ui/indent-fire-marker';\nimport {\n TodoLi,\n TodoMarker,\n} from '@/components/plate-ui/indent-todo-marker';\nimport { LinkFloatingToolbar } from '@/components/plate-ui/link-floating-toolbar';\n\nimport { usePlaygroundEnabled } from './usePlaygroundEnabled';\n\nexport const usePlaygroundEditor = (id: any = '', scrollSelector?: string) => {\n const enabledPlugins = settingsStore.use.checkedPlugins();\n const overridePlugins = usePlaygroundEnabled(id);\n const autoformatOptions = getAutoformatOptions(id, enabledPlugins);\n\n const value = usePlaygroundValue(id);\n const key = settingsStore.use.version();\n const editorId = id || 'playground-' + key;\n\n return usePlateEditor(\n {\n id: editorId,\n override: {\n components: createPlateUI({\n draggable: isEnabled('dnd', id),\n placeholder: isEnabled('placeholder', id),\n }),\n plugins: overridePlugins,\n },\n plugins: [\n // AI\n ...(id === 'ai' || enabledPlugins[AIChatPlugin.key] ? aiPlugins : []),\n ...(id === 'copilot' || enabledPlugins[CopilotPlugin.key]\n ? copilotPlugins\n : []),\n // Nodes\n HeadingPlugin,\n TocPlugin.configure({\n options: {\n scrollContainerSelector: `#${scrollSelector}`,\n topOffset: 80,\n },\n }),\n BlockquotePlugin,\n CodeBlockPlugin.configure({\n options: {\n prism: Prism,\n },\n }),\n HorizontalRulePlugin,\n LinkPlugin.extend({\n render: { afterEditable: () => },\n }),\n ...(id === 'list' ? [ListPlugin] : []),\n ImagePlugin.extend({\n options: {\n disableUploadInsert: true,\n },\n render: { afterEditable: ImagePreview },\n }),\n MediaEmbedPlugin,\n CaptionPlugin.configure({\n options: {\n plugins: [ImagePlugin, MediaEmbedPlugin],\n },\n }),\n DatePlugin,\n MentionPlugin.configure({\n options: {\n triggerPreviousCharPattern: /^$|^[\\s\"']$/,\n },\n }),\n SlashPlugin,\n TablePlugin.configure({\n options: {\n enableMerging: id === 'tableMerge',\n },\n }),\n ColumnPlugin,\n SelectionOverlayPlugin,\n\n TodoListPlugin,\n TogglePlugin,\n ExcalidrawPlugin,\n // Marks\n BoldPlugin,\n ItalicPlugin,\n UnderlinePlugin,\n StrikethroughPlugin,\n CodePlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n FontColorPlugin,\n FontBackgroundColorPlugin,\n FontSizePlugin,\n HighlightPlugin,\n KbdPlugin,\n\n // Block Style\n AlignPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n MediaEmbedPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n ImagePlugin.key,\n HEADING_KEYS.h6,\n ],\n },\n }),\n IndentPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n }),\n IndentListPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n options: {\n listStyleTypes: {\n fire: {\n liComponent: FireLiComponent,\n markerComponent: FireMarker,\n type: 'fire',\n },\n todo: {\n liComponent: TodoLi,\n markerComponent: TodoMarker,\n type: 'todo',\n },\n },\n },\n }),\n LineHeightPlugin.extend({\n inject: {\n nodeProps: {\n defaultNodeValue: 1.5,\n validNodeValues: [1, 1.2, 1.5, 2, 3],\n },\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n ],\n },\n }),\n\n // Functionality\n AutoformatPlugin.configure({\n options: autoformatOptions,\n }),\n BlockSelectionPlugin.configure({\n options: {\n areaOptions: {\n behaviour: {\n scrolling: {\n speedDivider: 1.5,\n },\n startThreshold: 10,\n },\n boundaries: `#${scrollSelector}`,\n container: `#${scrollSelector}`,\n selectables: [`#${scrollSelector} .slate-selectable`],\n selectionAreaClass: 'slate-selection-area',\n },\n enableContextMenu: true,\n },\n }),\n BlockMenuPlugin.configure({\n render: { aboveEditable: BlockContextMenu },\n }),\n DndPlugin.configure({\n options: {\n enableScroller: true,\n onDropFiles: ({ dragItem, editor, target }) => {\n editor\n .getTransforms(ImagePlugin)\n .insertImageFromFiles(dragItem.files, {\n at: target,\n nextBlock: false,\n });\n },\n },\n }),\n EmojiPlugin,\n exitBreakPlugin,\n NodeIdPlugin,\n NormalizeTypesPlugin.configure({\n options: {\n rules: [{ path: [0], strictType: HEADING_KEYS.h1 }],\n },\n }),\n resetBlockTypePlugin,\n SelectOnBackspacePlugin.configure({\n options: {\n query: {\n allow: [ImagePlugin.key, HorizontalRulePlugin.key],\n },\n },\n }),\n DeletePlugin,\n SingleLinePlugin,\n softBreakPlugin,\n tabbablePlugin,\n TrailingBlockPlugin.configure({\n options: { type: ParagraphPlugin.key },\n }),\n DragOverCursorPlugin,\n\n // Collaboration\n CommentsPlugin.configure({\n options: {\n comments: commentsData,\n myUserId: '1',\n users: usersData,\n },\n }),\n\n // Deserialization\n DocxPlugin,\n MarkdownPlugin.configure({ options: { indentList: true } }),\n JuicePlugin,\n\n // Testing\n PlaywrightPlugin.configure({\n enabled: process.env.NODE_ENV !== 'production',\n }),\n ],\n value: value,\n },\n []\n );\n};\n\nexport default function PlaygroundDemo({\n id,\n className,\n scrollSelector,\n}: {\n id?: ValueId;\n className?: string;\n scrollSelector?: string;\n}) {\n const containerRef = useRef(null);\n const enabled = settingsStore.use.checkedComponents();\n\n const editor = usePlaygroundEditor(\n id,\n scrollSelector ?? `blockSelection-${id}`\n );\n\n return (\n \n \n \n \n \n \n \n \n \n\n
\n \n \n\n \n \n \n \n \n \n \n\n \n \n \n \n\n \n \n \n
\n
\n
\n );\n}\n\nconst DemoIdContext = React.createContext(undefined);\n\nexport function DemoId({\n id,\n children,\n}: {\n children: React.ReactNode;\n id?: string;\n}) {\n return {children};\n}\n\nexport function useDemoId() {\n return React.useContext(DemoIdContext);\n}\n", + "content": "'use client';\n\nimport React, { useRef } from 'react';\n\nimport type { ValueId } from '@/config/customizer-plugins';\n\nimport { cn } from '@udecode/cn';\nimport { AIChatPlugin, CopilotPlugin } from '@udecode/plate-ai/react';\nimport { AlignPlugin } from '@udecode/plate-alignment/react';\nimport { AutoformatPlugin } from '@udecode/plate-autoformat/react';\nimport {\n BoldPlugin,\n CodePlugin,\n ItalicPlugin,\n StrikethroughPlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n UnderlinePlugin,\n} from '@udecode/plate-basic-marks/react';\nimport { BlockquotePlugin } from '@udecode/plate-block-quote/react';\nimport { SingleLinePlugin } from '@udecode/plate-break/react';\nimport { CaptionPlugin } from '@udecode/plate-caption/react';\nimport { CodeBlockPlugin } from '@udecode/plate-code-block/react';\nimport { CommentsPlugin } from '@udecode/plate-comments/react';\nimport {\n ParagraphPlugin,\n Plate,\n usePlateEditor,\n} from '@udecode/plate-common/react';\nimport { DatePlugin } from '@udecode/plate-date/react';\nimport { DndPlugin } from '@udecode/plate-dnd';\nimport { DocxPlugin } from '@udecode/plate-docx';\nimport { EmojiPlugin } from '@udecode/plate-emoji/react';\nimport { ExcalidrawPlugin } from '@udecode/plate-excalidraw/react';\nimport {\n FontBackgroundColorPlugin,\n FontColorPlugin,\n FontSizePlugin,\n} from '@udecode/plate-font/react';\nimport { HEADING_KEYS } from '@udecode/plate-heading';\nimport { HeadingPlugin, TocPlugin } from '@udecode/plate-heading/react';\nimport { HighlightPlugin } from '@udecode/plate-highlight/react';\nimport { HorizontalRulePlugin } from '@udecode/plate-horizontal-rule/react';\nimport { IndentPlugin } from '@udecode/plate-indent/react';\nimport { IndentListPlugin } from '@udecode/plate-indent-list/react';\nimport { JuicePlugin } from '@udecode/plate-juice';\nimport { KbdPlugin } from '@udecode/plate-kbd/react';\nimport { ColumnPlugin } from '@udecode/plate-layout/react';\nimport { LineHeightPlugin } from '@udecode/plate-line-height/react';\nimport { LinkPlugin } from '@udecode/plate-link/react';\nimport { ListPlugin, TodoListPlugin } from '@udecode/plate-list/react';\nimport { MarkdownPlugin } from '@udecode/plate-markdown';\nimport { BaseImagePlugin } from '@udecode/plate-media';\nimport { ImagePlugin, MediaEmbedPlugin } from '@udecode/plate-media/react';\nimport { MentionPlugin } from '@udecode/plate-mention/react';\nimport { NodeIdPlugin } from '@udecode/plate-node-id';\nimport { NormalizeTypesPlugin } from '@udecode/plate-normalizers';\nimport { PlaywrightPlugin } from '@udecode/plate-playwright';\nimport { DeletePlugin, SelectOnBackspacePlugin } from '@udecode/plate-select';\nimport {\n BlockMenuPlugin,\n BlockSelectionPlugin,\n} from '@udecode/plate-selection/react';\nimport { SlashPlugin } from '@udecode/plate-slash-command/react';\nimport { TablePlugin } from '@udecode/plate-table/react';\nimport { TogglePlugin } from '@udecode/plate-toggle/react';\nimport { TrailingBlockPlugin } from '@udecode/plate-trailing-block';\nimport Prism from 'prismjs';\n\nimport { CheckPlugin } from '@/components/context/check-plugin';\nimport { settingsStore } from '@/components/context/settings-store';\nimport { aiPlugins } from '@/lib/plate/demo/plugins/ai-plugins';\nimport { getAutoformatOptions } from '@/lib/plate/demo/plugins/autoformatOptions';\nimport { copilotPlugins } from '@/lib/plate/demo/plugins/copilot-plugins';\nimport { createPlateUI } from '@/plate/create-plate-ui';\nimport { editableProps } from '@/plate/demo/editableProps';\nimport { isEnabled } from '@/plate/demo/is-enabled';\nimport { DragOverCursorPlugin } from '@/plate/demo/plugins/DragOverCursorPlugin';\nimport { exitBreakPlugin } from '@/plate/demo/plugins/exitBreakPlugin';\nimport { resetBlockTypePlugin } from '@/plate/demo/plugins/resetBlockTypePlugin';\nimport { softBreakPlugin } from '@/plate/demo/plugins/softBreakPlugin';\nimport { tabbablePlugin } from '@/plate/demo/plugins/tabbablePlugin';\nimport { commentsData, usersData } from '@/plate/demo/values/commentsValue';\nimport { usePlaygroundValue } from '@/plate/demo/values/usePlaygroundValue';\nimport { BlockContextMenu } from '@/components/plate-ui/block-context-menu';\nimport { CommentsPopover } from '@/components/plate-ui/comments-popover';\nimport {\n CursorOverlay,\n SelectionOverlayPlugin,\n} from '@/components/plate-ui/cursor-overlay';\nimport { Editor, EditorContainer } from '@/components/plate-ui/editor';\nimport { FixedToolbar } from '@/components/plate-ui/fixed-toolbar';\nimport { FixedToolbarButtons } from '@/components/plate-ui/fixed-toolbar-buttons';\nimport { FloatingToolbar } from '@/components/plate-ui/floating-toolbar';\nimport { FloatingToolbarButtons } from '@/components/plate-ui/floating-toolbar-buttons';\nimport { ImagePreview } from '@/components/plate-ui/image-preview';\nimport {\n FireLiComponent,\n FireMarker,\n} from '@/components/plate-ui/indent-fire-marker';\nimport {\n TodoLi,\n TodoMarker,\n} from '@/components/plate-ui/indent-todo-marker';\nimport { LinkFloatingToolbar } from '@/components/plate-ui/link-floating-toolbar';\n\nimport { usePlaygroundEnabled } from './usePlaygroundEnabled';\n\nexport const usePlaygroundEditor = (id: any = '', scrollSelector?: string) => {\n const enabledPlugins = settingsStore.use.checkedPlugins();\n const overridePlugins = usePlaygroundEnabled(id);\n const autoformatOptions = getAutoformatOptions(id, enabledPlugins);\n\n const value = usePlaygroundValue(id);\n const key = settingsStore.use.version();\n const editorId = id || 'playground-' + key;\n\n return usePlateEditor(\n {\n id: editorId,\n override: {\n components: createPlateUI({\n draggable: isEnabled('dnd', id),\n placeholder: isEnabled('placeholder', id),\n }),\n plugins: overridePlugins,\n },\n plugins: [\n // AI\n ...(id === 'ai' || enabledPlugins[AIChatPlugin.key] ? aiPlugins : []),\n ...(id === 'copilot' || enabledPlugins[CopilotPlugin.key]\n ? copilotPlugins\n : []),\n // Nodes\n HeadingPlugin,\n TocPlugin.configure({\n options: {\n scrollContainerSelector: `#${scrollSelector}`,\n topOffset: 80,\n },\n }),\n BlockquotePlugin,\n CodeBlockPlugin.configure({\n options: {\n prism: Prism,\n },\n }),\n HorizontalRulePlugin,\n LinkPlugin.extend({\n render: { afterEditable: () => },\n }),\n ...(id === 'list' ? [ListPlugin] : []),\n ImagePlugin.extend({\n options: {\n disableUploadInsert: true,\n },\n render: { afterEditable: ImagePreview },\n }),\n MediaEmbedPlugin,\n CaptionPlugin.configure({\n options: {\n plugins: [ImagePlugin, MediaEmbedPlugin],\n },\n }),\n DatePlugin,\n MentionPlugin.configure({\n options: {\n triggerPreviousCharPattern: /^$|^[\\s\"']$/,\n },\n }),\n SlashPlugin,\n TablePlugin.configure({\n options: {\n enableMerging: id === 'tableMerge',\n },\n }),\n ColumnPlugin,\n SelectionOverlayPlugin,\n\n TodoListPlugin,\n TogglePlugin,\n ExcalidrawPlugin,\n // Marks\n BoldPlugin,\n ItalicPlugin,\n UnderlinePlugin,\n StrikethroughPlugin,\n CodePlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n FontColorPlugin,\n FontBackgroundColorPlugin,\n FontSizePlugin,\n HighlightPlugin,\n KbdPlugin,\n\n // Block Style\n AlignPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n MediaEmbedPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n ImagePlugin.key,\n HEADING_KEYS.h6,\n ],\n },\n }),\n IndentPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n }),\n IndentListPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n options: {\n listStyleTypes: {\n fire: {\n liComponent: FireLiComponent,\n markerComponent: FireMarker,\n type: 'fire',\n },\n todo: {\n liComponent: TodoLi,\n markerComponent: TodoMarker,\n type: 'todo',\n },\n },\n },\n }),\n LineHeightPlugin.extend({\n inject: {\n nodeProps: {\n defaultNodeValue: 1.5,\n validNodeValues: [1, 1.2, 1.5, 2, 3],\n },\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n ],\n },\n }),\n\n // Functionality\n AutoformatPlugin.configure({\n options: autoformatOptions,\n }),\n BlockSelectionPlugin.configure({\n options: {\n areaOptions: {\n behaviour: {\n scrolling: {\n speedDivider: 1.5,\n },\n startThreshold: 10,\n },\n boundaries: `#${scrollSelector}`,\n container: `#${scrollSelector}`,\n selectables: [`#${scrollSelector} .slate-selectable`],\n selectionAreaClass: 'slate-selection-area',\n },\n enableContextMenu: true,\n },\n }),\n BlockMenuPlugin.configure({\n render: { aboveEditable: BlockContextMenu },\n }),\n DndPlugin.configure({\n options: {\n enableScroller: true,\n onDropFiles: ({ dragItem, editor, target }) => {\n editor\n .getTransforms(BaseImagePlugin)\n .insert.imageFromFiles(dragItem.files, {\n at: target,\n nextBlock: false,\n });\n },\n },\n }),\n EmojiPlugin,\n exitBreakPlugin,\n NodeIdPlugin,\n NormalizeTypesPlugin.configure({\n options: {\n rules: [{ path: [0], strictType: HEADING_KEYS.h1 }],\n },\n }),\n resetBlockTypePlugin,\n SelectOnBackspacePlugin.configure({\n options: {\n query: {\n allow: [ImagePlugin.key, HorizontalRulePlugin.key],\n },\n },\n }),\n DeletePlugin,\n SingleLinePlugin,\n softBreakPlugin,\n tabbablePlugin,\n TrailingBlockPlugin.configure({\n options: { type: ParagraphPlugin.key },\n }),\n DragOverCursorPlugin,\n\n // Collaboration\n CommentsPlugin.configure({\n options: {\n comments: commentsData,\n myUserId: '1',\n users: usersData,\n },\n }),\n\n // Deserialization\n DocxPlugin,\n MarkdownPlugin.configure({ options: { indentList: true } }),\n JuicePlugin,\n\n // Testing\n PlaywrightPlugin.configure({\n enabled: process.env.NODE_ENV !== 'production',\n }),\n ],\n value: value,\n },\n []\n );\n};\n\nexport default function PlaygroundDemo({\n id,\n className,\n scrollSelector,\n}: {\n id?: ValueId;\n className?: string;\n scrollSelector?: string;\n}) {\n const containerRef = useRef(null);\n const enabled = settingsStore.use.checkedComponents();\n\n const editor = usePlaygroundEditor(\n id,\n scrollSelector ?? `blockSelection-${id}`\n );\n\n return (\n \n \n \n \n \n \n \n \n \n\n
\n \n \n\n \n \n \n \n \n \n \n\n \n \n \n \n\n \n \n \n
\n
\n
\n );\n}\n\nconst DemoIdContext = React.createContext(undefined);\n\nexport function DemoId({\n id,\n children,\n}: {\n children: React.ReactNode;\n id?: string;\n}) {\n return {children};\n}\n\nexport function useDemoId() {\n return React.useContext(DemoIdContext);\n}\n", "path": "example/playground-demo.tsx", "target": "components/playground-demo.tsx", "type": "registry:example" diff --git a/apps/www/public/r/styles/default/highlight-demo.json b/apps/www/public/r/styles/default/highlight-demo.json index 2a32c44967..028ad7a93f 100644 --- a/apps/www/public/r/styles/default/highlight-demo.json +++ b/apps/www/public/r/styles/default/highlight-demo.json @@ -4,7 +4,7 @@ }, "files": [ { - "content": "'use client';\n\nimport React, { useRef } from 'react';\n\nimport type { ValueId } from '@/config/customizer-plugins';\n\nimport { cn } from '@udecode/cn';\nimport { AIChatPlugin, CopilotPlugin } from '@udecode/plate-ai/react';\nimport { AlignPlugin } from '@udecode/plate-alignment/react';\nimport { AutoformatPlugin } from '@udecode/plate-autoformat/react';\nimport {\n BoldPlugin,\n CodePlugin,\n ItalicPlugin,\n StrikethroughPlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n UnderlinePlugin,\n} from '@udecode/plate-basic-marks/react';\nimport { BlockquotePlugin } from '@udecode/plate-block-quote/react';\nimport { SingleLinePlugin } from '@udecode/plate-break/react';\nimport { CaptionPlugin } from '@udecode/plate-caption/react';\nimport { CodeBlockPlugin } from '@udecode/plate-code-block/react';\nimport { CommentsPlugin } from '@udecode/plate-comments/react';\nimport {\n ParagraphPlugin,\n Plate,\n usePlateEditor,\n} from '@udecode/plate-common/react';\nimport { DatePlugin } from '@udecode/plate-date/react';\nimport { DndPlugin } from '@udecode/plate-dnd';\nimport { DocxPlugin } from '@udecode/plate-docx';\nimport { EmojiPlugin } from '@udecode/plate-emoji/react';\nimport { ExcalidrawPlugin } from '@udecode/plate-excalidraw/react';\nimport {\n FontBackgroundColorPlugin,\n FontColorPlugin,\n FontSizePlugin,\n} from '@udecode/plate-font/react';\nimport { HEADING_KEYS } from '@udecode/plate-heading';\nimport { HeadingPlugin, TocPlugin } from '@udecode/plate-heading/react';\nimport { HighlightPlugin } from '@udecode/plate-highlight/react';\nimport { HorizontalRulePlugin } from '@udecode/plate-horizontal-rule/react';\nimport { IndentPlugin } from '@udecode/plate-indent/react';\nimport { IndentListPlugin } from '@udecode/plate-indent-list/react';\nimport { JuicePlugin } from '@udecode/plate-juice';\nimport { KbdPlugin } from '@udecode/plate-kbd/react';\nimport { ColumnPlugin } from '@udecode/plate-layout/react';\nimport { LineHeightPlugin } from '@udecode/plate-line-height/react';\nimport { LinkPlugin } from '@udecode/plate-link/react';\nimport { ListPlugin, TodoListPlugin } from '@udecode/plate-list/react';\nimport { MarkdownPlugin } from '@udecode/plate-markdown';\nimport { ImagePlugin, MediaEmbedPlugin } from '@udecode/plate-media/react';\nimport { MentionPlugin } from '@udecode/plate-mention/react';\nimport { NodeIdPlugin } from '@udecode/plate-node-id';\nimport { NormalizeTypesPlugin } from '@udecode/plate-normalizers';\nimport { PlaywrightPlugin } from '@udecode/plate-playwright';\nimport { DeletePlugin, SelectOnBackspacePlugin } from '@udecode/plate-select';\nimport {\n BlockMenuPlugin,\n BlockSelectionPlugin,\n} from '@udecode/plate-selection/react';\nimport { SlashPlugin } from '@udecode/plate-slash-command/react';\nimport { TablePlugin } from '@udecode/plate-table/react';\nimport { TogglePlugin } from '@udecode/plate-toggle/react';\nimport { TrailingBlockPlugin } from '@udecode/plate-trailing-block';\nimport Prism from 'prismjs';\n\nimport { CheckPlugin } from '@/components/context/check-plugin';\nimport { settingsStore } from '@/components/context/settings-store';\nimport { aiPlugins } from '@/lib/plate/demo/plugins/ai-plugins';\nimport { getAutoformatOptions } from '@/lib/plate/demo/plugins/autoformatOptions';\nimport { copilotPlugins } from '@/lib/plate/demo/plugins/copilot-plugins';\nimport { createPlateUI } from '@/plate/create-plate-ui';\nimport { editableProps } from '@/plate/demo/editableProps';\nimport { isEnabled } from '@/plate/demo/is-enabled';\nimport { DragOverCursorPlugin } from '@/plate/demo/plugins/DragOverCursorPlugin';\nimport { exitBreakPlugin } from '@/plate/demo/plugins/exitBreakPlugin';\nimport { resetBlockTypePlugin } from '@/plate/demo/plugins/resetBlockTypePlugin';\nimport { softBreakPlugin } from '@/plate/demo/plugins/softBreakPlugin';\nimport { tabbablePlugin } from '@/plate/demo/plugins/tabbablePlugin';\nimport { commentsData, usersData } from '@/plate/demo/values/commentsValue';\nimport { usePlaygroundValue } from '@/plate/demo/values/usePlaygroundValue';\nimport { BlockContextMenu } from '@/components/plate-ui/block-context-menu';\nimport { CommentsPopover } from '@/components/plate-ui/comments-popover';\nimport {\n CursorOverlay,\n SelectionOverlayPlugin,\n} from '@/components/plate-ui/cursor-overlay';\nimport { Editor, EditorContainer } from '@/components/plate-ui/editor';\nimport { FixedToolbar } from '@/components/plate-ui/fixed-toolbar';\nimport { FixedToolbarButtons } from '@/components/plate-ui/fixed-toolbar-buttons';\nimport { FloatingToolbar } from '@/components/plate-ui/floating-toolbar';\nimport { FloatingToolbarButtons } from '@/components/plate-ui/floating-toolbar-buttons';\nimport { ImagePreview } from '@/components/plate-ui/image-preview';\nimport {\n FireLiComponent,\n FireMarker,\n} from '@/components/plate-ui/indent-fire-marker';\nimport {\n TodoLi,\n TodoMarker,\n} from '@/components/plate-ui/indent-todo-marker';\nimport { LinkFloatingToolbar } from '@/components/plate-ui/link-floating-toolbar';\n\nimport { usePlaygroundEnabled } from './usePlaygroundEnabled';\n\nexport const usePlaygroundEditor = (id: any = '', scrollSelector?: string) => {\n const enabledPlugins = settingsStore.use.checkedPlugins();\n const overridePlugins = usePlaygroundEnabled(id);\n const autoformatOptions = getAutoformatOptions(id, enabledPlugins);\n\n const value = usePlaygroundValue(id);\n const key = settingsStore.use.version();\n const editorId = id || 'playground-' + key;\n\n return usePlateEditor(\n {\n id: editorId,\n override: {\n components: createPlateUI({\n draggable: isEnabled('dnd', id),\n placeholder: isEnabled('placeholder', id),\n }),\n plugins: overridePlugins,\n },\n plugins: [\n // AI\n ...(id === 'ai' || enabledPlugins[AIChatPlugin.key] ? aiPlugins : []),\n ...(id === 'copilot' || enabledPlugins[CopilotPlugin.key]\n ? copilotPlugins\n : []),\n // Nodes\n HeadingPlugin,\n TocPlugin.configure({\n options: {\n scrollContainerSelector: `#${scrollSelector}`,\n topOffset: 80,\n },\n }),\n BlockquotePlugin,\n CodeBlockPlugin.configure({\n options: {\n prism: Prism,\n },\n }),\n HorizontalRulePlugin,\n LinkPlugin.extend({\n render: { afterEditable: () => },\n }),\n ...(id === 'list' ? [ListPlugin] : []),\n ImagePlugin.extend({\n options: {\n disableUploadInsert: true,\n },\n render: { afterEditable: ImagePreview },\n }),\n MediaEmbedPlugin,\n CaptionPlugin.configure({\n options: {\n plugins: [ImagePlugin, MediaEmbedPlugin],\n },\n }),\n DatePlugin,\n MentionPlugin.configure({\n options: {\n triggerPreviousCharPattern: /^$|^[\\s\"']$/,\n },\n }),\n SlashPlugin,\n TablePlugin.configure({\n options: {\n enableMerging: id === 'tableMerge',\n },\n }),\n ColumnPlugin,\n SelectionOverlayPlugin,\n\n TodoListPlugin,\n TogglePlugin,\n ExcalidrawPlugin,\n // Marks\n BoldPlugin,\n ItalicPlugin,\n UnderlinePlugin,\n StrikethroughPlugin,\n CodePlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n FontColorPlugin,\n FontBackgroundColorPlugin,\n FontSizePlugin,\n HighlightPlugin,\n KbdPlugin,\n\n // Block Style\n AlignPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n MediaEmbedPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n ImagePlugin.key,\n HEADING_KEYS.h6,\n ],\n },\n }),\n IndentPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n }),\n IndentListPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n options: {\n listStyleTypes: {\n fire: {\n liComponent: FireLiComponent,\n markerComponent: FireMarker,\n type: 'fire',\n },\n todo: {\n liComponent: TodoLi,\n markerComponent: TodoMarker,\n type: 'todo',\n },\n },\n },\n }),\n LineHeightPlugin.extend({\n inject: {\n nodeProps: {\n defaultNodeValue: 1.5,\n validNodeValues: [1, 1.2, 1.5, 2, 3],\n },\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n ],\n },\n }),\n\n // Functionality\n AutoformatPlugin.configure({\n options: autoformatOptions,\n }),\n BlockSelectionPlugin.configure({\n options: {\n areaOptions: {\n behaviour: {\n scrolling: {\n speedDivider: 1.5,\n },\n startThreshold: 10,\n },\n boundaries: `#${scrollSelector}`,\n container: `#${scrollSelector}`,\n selectables: [`#${scrollSelector} .slate-selectable`],\n selectionAreaClass: 'slate-selection-area',\n },\n enableContextMenu: true,\n },\n }),\n BlockMenuPlugin.configure({\n render: { aboveEditable: BlockContextMenu },\n }),\n DndPlugin.configure({\n options: {\n enableScroller: true,\n onDropFiles: ({ dragItem, editor, target }) => {\n editor\n .getTransforms(ImagePlugin)\n .insertImageFromFiles(dragItem.files, {\n at: target,\n nextBlock: false,\n });\n },\n },\n }),\n EmojiPlugin,\n exitBreakPlugin,\n NodeIdPlugin,\n NormalizeTypesPlugin.configure({\n options: {\n rules: [{ path: [0], strictType: HEADING_KEYS.h1 }],\n },\n }),\n resetBlockTypePlugin,\n SelectOnBackspacePlugin.configure({\n options: {\n query: {\n allow: [ImagePlugin.key, HorizontalRulePlugin.key],\n },\n },\n }),\n DeletePlugin,\n SingleLinePlugin,\n softBreakPlugin,\n tabbablePlugin,\n TrailingBlockPlugin.configure({\n options: { type: ParagraphPlugin.key },\n }),\n DragOverCursorPlugin,\n\n // Collaboration\n CommentsPlugin.configure({\n options: {\n comments: commentsData,\n myUserId: '1',\n users: usersData,\n },\n }),\n\n // Deserialization\n DocxPlugin,\n MarkdownPlugin.configure({ options: { indentList: true } }),\n JuicePlugin,\n\n // Testing\n PlaywrightPlugin.configure({\n enabled: process.env.NODE_ENV !== 'production',\n }),\n ],\n value: value,\n },\n []\n );\n};\n\nexport default function PlaygroundDemo({\n id,\n className,\n scrollSelector,\n}: {\n id?: ValueId;\n className?: string;\n scrollSelector?: string;\n}) {\n const containerRef = useRef(null);\n const enabled = settingsStore.use.checkedComponents();\n\n const editor = usePlaygroundEditor(\n id,\n scrollSelector ?? `blockSelection-${id}`\n );\n\n return (\n \n \n \n \n \n \n \n \n \n\n
\n \n \n\n \n \n \n \n \n \n \n\n \n \n \n \n\n \n \n \n
\n
\n
\n );\n}\n\nconst DemoIdContext = React.createContext(undefined);\n\nexport function DemoId({\n id,\n children,\n}: {\n children: React.ReactNode;\n id?: string;\n}) {\n return {children};\n}\n\nexport function useDemoId() {\n return React.useContext(DemoIdContext);\n}\n", + "content": "'use client';\n\nimport React, { useRef } from 'react';\n\nimport type { ValueId } from '@/config/customizer-plugins';\n\nimport { cn } from '@udecode/cn';\nimport { AIChatPlugin, CopilotPlugin } from '@udecode/plate-ai/react';\nimport { AlignPlugin } from '@udecode/plate-alignment/react';\nimport { AutoformatPlugin } from '@udecode/plate-autoformat/react';\nimport {\n BoldPlugin,\n CodePlugin,\n ItalicPlugin,\n StrikethroughPlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n UnderlinePlugin,\n} from '@udecode/plate-basic-marks/react';\nimport { BlockquotePlugin } from '@udecode/plate-block-quote/react';\nimport { SingleLinePlugin } from '@udecode/plate-break/react';\nimport { CaptionPlugin } from '@udecode/plate-caption/react';\nimport { CodeBlockPlugin } from '@udecode/plate-code-block/react';\nimport { CommentsPlugin } from '@udecode/plate-comments/react';\nimport {\n ParagraphPlugin,\n Plate,\n usePlateEditor,\n} from '@udecode/plate-common/react';\nimport { DatePlugin } from '@udecode/plate-date/react';\nimport { DndPlugin } from '@udecode/plate-dnd';\nimport { DocxPlugin } from '@udecode/plate-docx';\nimport { EmojiPlugin } from '@udecode/plate-emoji/react';\nimport { ExcalidrawPlugin } from '@udecode/plate-excalidraw/react';\nimport {\n FontBackgroundColorPlugin,\n FontColorPlugin,\n FontSizePlugin,\n} from '@udecode/plate-font/react';\nimport { HEADING_KEYS } from '@udecode/plate-heading';\nimport { HeadingPlugin, TocPlugin } from '@udecode/plate-heading/react';\nimport { HighlightPlugin } from '@udecode/plate-highlight/react';\nimport { HorizontalRulePlugin } from '@udecode/plate-horizontal-rule/react';\nimport { IndentPlugin } from '@udecode/plate-indent/react';\nimport { IndentListPlugin } from '@udecode/plate-indent-list/react';\nimport { JuicePlugin } from '@udecode/plate-juice';\nimport { KbdPlugin } from '@udecode/plate-kbd/react';\nimport { ColumnPlugin } from '@udecode/plate-layout/react';\nimport { LineHeightPlugin } from '@udecode/plate-line-height/react';\nimport { LinkPlugin } from '@udecode/plate-link/react';\nimport { ListPlugin, TodoListPlugin } from '@udecode/plate-list/react';\nimport { MarkdownPlugin } from '@udecode/plate-markdown';\nimport { BaseImagePlugin } from '@udecode/plate-media';\nimport { ImagePlugin, MediaEmbedPlugin } from '@udecode/plate-media/react';\nimport { MentionPlugin } from '@udecode/plate-mention/react';\nimport { NodeIdPlugin } from '@udecode/plate-node-id';\nimport { NormalizeTypesPlugin } from '@udecode/plate-normalizers';\nimport { PlaywrightPlugin } from '@udecode/plate-playwright';\nimport { DeletePlugin, SelectOnBackspacePlugin } from '@udecode/plate-select';\nimport {\n BlockMenuPlugin,\n BlockSelectionPlugin,\n} from '@udecode/plate-selection/react';\nimport { SlashPlugin } from '@udecode/plate-slash-command/react';\nimport { TablePlugin } from '@udecode/plate-table/react';\nimport { TogglePlugin } from '@udecode/plate-toggle/react';\nimport { TrailingBlockPlugin } from '@udecode/plate-trailing-block';\nimport Prism from 'prismjs';\n\nimport { CheckPlugin } from '@/components/context/check-plugin';\nimport { settingsStore } from '@/components/context/settings-store';\nimport { aiPlugins } from '@/lib/plate/demo/plugins/ai-plugins';\nimport { getAutoformatOptions } from '@/lib/plate/demo/plugins/autoformatOptions';\nimport { copilotPlugins } from '@/lib/plate/demo/plugins/copilot-plugins';\nimport { createPlateUI } from '@/plate/create-plate-ui';\nimport { editableProps } from '@/plate/demo/editableProps';\nimport { isEnabled } from '@/plate/demo/is-enabled';\nimport { DragOverCursorPlugin } from '@/plate/demo/plugins/DragOverCursorPlugin';\nimport { exitBreakPlugin } from '@/plate/demo/plugins/exitBreakPlugin';\nimport { resetBlockTypePlugin } from '@/plate/demo/plugins/resetBlockTypePlugin';\nimport { softBreakPlugin } from '@/plate/demo/plugins/softBreakPlugin';\nimport { tabbablePlugin } from '@/plate/demo/plugins/tabbablePlugin';\nimport { commentsData, usersData } from '@/plate/demo/values/commentsValue';\nimport { usePlaygroundValue } from '@/plate/demo/values/usePlaygroundValue';\nimport { BlockContextMenu } from '@/components/plate-ui/block-context-menu';\nimport { CommentsPopover } from '@/components/plate-ui/comments-popover';\nimport {\n CursorOverlay,\n SelectionOverlayPlugin,\n} from '@/components/plate-ui/cursor-overlay';\nimport { Editor, EditorContainer } from '@/components/plate-ui/editor';\nimport { FixedToolbar } from '@/components/plate-ui/fixed-toolbar';\nimport { FixedToolbarButtons } from '@/components/plate-ui/fixed-toolbar-buttons';\nimport { FloatingToolbar } from '@/components/plate-ui/floating-toolbar';\nimport { FloatingToolbarButtons } from '@/components/plate-ui/floating-toolbar-buttons';\nimport { ImagePreview } from '@/components/plate-ui/image-preview';\nimport {\n FireLiComponent,\n FireMarker,\n} from '@/components/plate-ui/indent-fire-marker';\nimport {\n TodoLi,\n TodoMarker,\n} from '@/components/plate-ui/indent-todo-marker';\nimport { LinkFloatingToolbar } from '@/components/plate-ui/link-floating-toolbar';\n\nimport { usePlaygroundEnabled } from './usePlaygroundEnabled';\n\nexport const usePlaygroundEditor = (id: any = '', scrollSelector?: string) => {\n const enabledPlugins = settingsStore.use.checkedPlugins();\n const overridePlugins = usePlaygroundEnabled(id);\n const autoformatOptions = getAutoformatOptions(id, enabledPlugins);\n\n const value = usePlaygroundValue(id);\n const key = settingsStore.use.version();\n const editorId = id || 'playground-' + key;\n\n return usePlateEditor(\n {\n id: editorId,\n override: {\n components: createPlateUI({\n draggable: isEnabled('dnd', id),\n placeholder: isEnabled('placeholder', id),\n }),\n plugins: overridePlugins,\n },\n plugins: [\n // AI\n ...(id === 'ai' || enabledPlugins[AIChatPlugin.key] ? aiPlugins : []),\n ...(id === 'copilot' || enabledPlugins[CopilotPlugin.key]\n ? copilotPlugins\n : []),\n // Nodes\n HeadingPlugin,\n TocPlugin.configure({\n options: {\n scrollContainerSelector: `#${scrollSelector}`,\n topOffset: 80,\n },\n }),\n BlockquotePlugin,\n CodeBlockPlugin.configure({\n options: {\n prism: Prism,\n },\n }),\n HorizontalRulePlugin,\n LinkPlugin.extend({\n render: { afterEditable: () => },\n }),\n ...(id === 'list' ? [ListPlugin] : []),\n ImagePlugin.extend({\n options: {\n disableUploadInsert: true,\n },\n render: { afterEditable: ImagePreview },\n }),\n MediaEmbedPlugin,\n CaptionPlugin.configure({\n options: {\n plugins: [ImagePlugin, MediaEmbedPlugin],\n },\n }),\n DatePlugin,\n MentionPlugin.configure({\n options: {\n triggerPreviousCharPattern: /^$|^[\\s\"']$/,\n },\n }),\n SlashPlugin,\n TablePlugin.configure({\n options: {\n enableMerging: id === 'tableMerge',\n },\n }),\n ColumnPlugin,\n SelectionOverlayPlugin,\n\n TodoListPlugin,\n TogglePlugin,\n ExcalidrawPlugin,\n // Marks\n BoldPlugin,\n ItalicPlugin,\n UnderlinePlugin,\n StrikethroughPlugin,\n CodePlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n FontColorPlugin,\n FontBackgroundColorPlugin,\n FontSizePlugin,\n HighlightPlugin,\n KbdPlugin,\n\n // Block Style\n AlignPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n MediaEmbedPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n ImagePlugin.key,\n HEADING_KEYS.h6,\n ],\n },\n }),\n IndentPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n }),\n IndentListPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n options: {\n listStyleTypes: {\n fire: {\n liComponent: FireLiComponent,\n markerComponent: FireMarker,\n type: 'fire',\n },\n todo: {\n liComponent: TodoLi,\n markerComponent: TodoMarker,\n type: 'todo',\n },\n },\n },\n }),\n LineHeightPlugin.extend({\n inject: {\n nodeProps: {\n defaultNodeValue: 1.5,\n validNodeValues: [1, 1.2, 1.5, 2, 3],\n },\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n ],\n },\n }),\n\n // Functionality\n AutoformatPlugin.configure({\n options: autoformatOptions,\n }),\n BlockSelectionPlugin.configure({\n options: {\n areaOptions: {\n behaviour: {\n scrolling: {\n speedDivider: 1.5,\n },\n startThreshold: 10,\n },\n boundaries: `#${scrollSelector}`,\n container: `#${scrollSelector}`,\n selectables: [`#${scrollSelector} .slate-selectable`],\n selectionAreaClass: 'slate-selection-area',\n },\n enableContextMenu: true,\n },\n }),\n BlockMenuPlugin.configure({\n render: { aboveEditable: BlockContextMenu },\n }),\n DndPlugin.configure({\n options: {\n enableScroller: true,\n onDropFiles: ({ dragItem, editor, target }) => {\n editor\n .getTransforms(BaseImagePlugin)\n .insert.imageFromFiles(dragItem.files, {\n at: target,\n nextBlock: false,\n });\n },\n },\n }),\n EmojiPlugin,\n exitBreakPlugin,\n NodeIdPlugin,\n NormalizeTypesPlugin.configure({\n options: {\n rules: [{ path: [0], strictType: HEADING_KEYS.h1 }],\n },\n }),\n resetBlockTypePlugin,\n SelectOnBackspacePlugin.configure({\n options: {\n query: {\n allow: [ImagePlugin.key, HorizontalRulePlugin.key],\n },\n },\n }),\n DeletePlugin,\n SingleLinePlugin,\n softBreakPlugin,\n tabbablePlugin,\n TrailingBlockPlugin.configure({\n options: { type: ParagraphPlugin.key },\n }),\n DragOverCursorPlugin,\n\n // Collaboration\n CommentsPlugin.configure({\n options: {\n comments: commentsData,\n myUserId: '1',\n users: usersData,\n },\n }),\n\n // Deserialization\n DocxPlugin,\n MarkdownPlugin.configure({ options: { indentList: true } }),\n JuicePlugin,\n\n // Testing\n PlaywrightPlugin.configure({\n enabled: process.env.NODE_ENV !== 'production',\n }),\n ],\n value: value,\n },\n []\n );\n};\n\nexport default function PlaygroundDemo({\n id,\n className,\n scrollSelector,\n}: {\n id?: ValueId;\n className?: string;\n scrollSelector?: string;\n}) {\n const containerRef = useRef(null);\n const enabled = settingsStore.use.checkedComponents();\n\n const editor = usePlaygroundEditor(\n id,\n scrollSelector ?? `blockSelection-${id}`\n );\n\n return (\n \n \n \n \n \n \n \n \n \n\n
\n \n \n\n \n \n \n \n \n \n \n\n \n \n \n \n\n \n \n \n
\n
\n
\n );\n}\n\nconst DemoIdContext = React.createContext(undefined);\n\nexport function DemoId({\n id,\n children,\n}: {\n children: React.ReactNode;\n id?: string;\n}) {\n return {children};\n}\n\nexport function useDemoId() {\n return React.useContext(DemoIdContext);\n}\n", "path": "example/playground-demo.tsx", "target": "components/playground-demo.tsx", "type": "registry:example" diff --git a/apps/www/public/r/styles/default/hr-demo.json b/apps/www/public/r/styles/default/hr-demo.json index e3cbb00b88..52829371d9 100644 --- a/apps/www/public/r/styles/default/hr-demo.json +++ b/apps/www/public/r/styles/default/hr-demo.json @@ -5,7 +5,7 @@ }, "files": [ { - "content": "'use client';\n\nimport React, { useRef } from 'react';\n\nimport type { ValueId } from '@/config/customizer-plugins';\n\nimport { cn } from '@udecode/cn';\nimport { AIChatPlugin, CopilotPlugin } from '@udecode/plate-ai/react';\nimport { AlignPlugin } from '@udecode/plate-alignment/react';\nimport { AutoformatPlugin } from '@udecode/plate-autoformat/react';\nimport {\n BoldPlugin,\n CodePlugin,\n ItalicPlugin,\n StrikethroughPlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n UnderlinePlugin,\n} from '@udecode/plate-basic-marks/react';\nimport { BlockquotePlugin } from '@udecode/plate-block-quote/react';\nimport { SingleLinePlugin } from '@udecode/plate-break/react';\nimport { CaptionPlugin } from '@udecode/plate-caption/react';\nimport { CodeBlockPlugin } from '@udecode/plate-code-block/react';\nimport { CommentsPlugin } from '@udecode/plate-comments/react';\nimport {\n ParagraphPlugin,\n Plate,\n usePlateEditor,\n} from '@udecode/plate-common/react';\nimport { DatePlugin } from '@udecode/plate-date/react';\nimport { DndPlugin } from '@udecode/plate-dnd';\nimport { DocxPlugin } from '@udecode/plate-docx';\nimport { EmojiPlugin } from '@udecode/plate-emoji/react';\nimport { ExcalidrawPlugin } from '@udecode/plate-excalidraw/react';\nimport {\n FontBackgroundColorPlugin,\n FontColorPlugin,\n FontSizePlugin,\n} from '@udecode/plate-font/react';\nimport { HEADING_KEYS } from '@udecode/plate-heading';\nimport { HeadingPlugin, TocPlugin } from '@udecode/plate-heading/react';\nimport { HighlightPlugin } from '@udecode/plate-highlight/react';\nimport { HorizontalRulePlugin } from '@udecode/plate-horizontal-rule/react';\nimport { IndentPlugin } from '@udecode/plate-indent/react';\nimport { IndentListPlugin } from '@udecode/plate-indent-list/react';\nimport { JuicePlugin } from '@udecode/plate-juice';\nimport { KbdPlugin } from '@udecode/plate-kbd/react';\nimport { ColumnPlugin } from '@udecode/plate-layout/react';\nimport { LineHeightPlugin } from '@udecode/plate-line-height/react';\nimport { LinkPlugin } from '@udecode/plate-link/react';\nimport { ListPlugin, TodoListPlugin } from '@udecode/plate-list/react';\nimport { MarkdownPlugin } from '@udecode/plate-markdown';\nimport { ImagePlugin, MediaEmbedPlugin } from '@udecode/plate-media/react';\nimport { MentionPlugin } from '@udecode/plate-mention/react';\nimport { NodeIdPlugin } from '@udecode/plate-node-id';\nimport { NormalizeTypesPlugin } from '@udecode/plate-normalizers';\nimport { PlaywrightPlugin } from '@udecode/plate-playwright';\nimport { DeletePlugin, SelectOnBackspacePlugin } from '@udecode/plate-select';\nimport {\n BlockMenuPlugin,\n BlockSelectionPlugin,\n} from '@udecode/plate-selection/react';\nimport { SlashPlugin } from '@udecode/plate-slash-command/react';\nimport { TablePlugin } from '@udecode/plate-table/react';\nimport { TogglePlugin } from '@udecode/plate-toggle/react';\nimport { TrailingBlockPlugin } from '@udecode/plate-trailing-block';\nimport Prism from 'prismjs';\n\nimport { CheckPlugin } from '@/components/context/check-plugin';\nimport { settingsStore } from '@/components/context/settings-store';\nimport { aiPlugins } from '@/lib/plate/demo/plugins/ai-plugins';\nimport { getAutoformatOptions } from '@/lib/plate/demo/plugins/autoformatOptions';\nimport { copilotPlugins } from '@/lib/plate/demo/plugins/copilot-plugins';\nimport { createPlateUI } from '@/plate/create-plate-ui';\nimport { editableProps } from '@/plate/demo/editableProps';\nimport { isEnabled } from '@/plate/demo/is-enabled';\nimport { DragOverCursorPlugin } from '@/plate/demo/plugins/DragOverCursorPlugin';\nimport { exitBreakPlugin } from '@/plate/demo/plugins/exitBreakPlugin';\nimport { resetBlockTypePlugin } from '@/plate/demo/plugins/resetBlockTypePlugin';\nimport { softBreakPlugin } from '@/plate/demo/plugins/softBreakPlugin';\nimport { tabbablePlugin } from '@/plate/demo/plugins/tabbablePlugin';\nimport { commentsData, usersData } from '@/plate/demo/values/commentsValue';\nimport { usePlaygroundValue } from '@/plate/demo/values/usePlaygroundValue';\nimport { BlockContextMenu } from '@/components/plate-ui/block-context-menu';\nimport { CommentsPopover } from '@/components/plate-ui/comments-popover';\nimport {\n CursorOverlay,\n SelectionOverlayPlugin,\n} from '@/components/plate-ui/cursor-overlay';\nimport { Editor, EditorContainer } from '@/components/plate-ui/editor';\nimport { FixedToolbar } from '@/components/plate-ui/fixed-toolbar';\nimport { FixedToolbarButtons } from '@/components/plate-ui/fixed-toolbar-buttons';\nimport { FloatingToolbar } from '@/components/plate-ui/floating-toolbar';\nimport { FloatingToolbarButtons } from '@/components/plate-ui/floating-toolbar-buttons';\nimport { ImagePreview } from '@/components/plate-ui/image-preview';\nimport {\n FireLiComponent,\n FireMarker,\n} from '@/components/plate-ui/indent-fire-marker';\nimport {\n TodoLi,\n TodoMarker,\n} from '@/components/plate-ui/indent-todo-marker';\nimport { LinkFloatingToolbar } from '@/components/plate-ui/link-floating-toolbar';\n\nimport { usePlaygroundEnabled } from './usePlaygroundEnabled';\n\nexport const usePlaygroundEditor = (id: any = '', scrollSelector?: string) => {\n const enabledPlugins = settingsStore.use.checkedPlugins();\n const overridePlugins = usePlaygroundEnabled(id);\n const autoformatOptions = getAutoformatOptions(id, enabledPlugins);\n\n const value = usePlaygroundValue(id);\n const key = settingsStore.use.version();\n const editorId = id || 'playground-' + key;\n\n return usePlateEditor(\n {\n id: editorId,\n override: {\n components: createPlateUI({\n draggable: isEnabled('dnd', id),\n placeholder: isEnabled('placeholder', id),\n }),\n plugins: overridePlugins,\n },\n plugins: [\n // AI\n ...(id === 'ai' || enabledPlugins[AIChatPlugin.key] ? aiPlugins : []),\n ...(id === 'copilot' || enabledPlugins[CopilotPlugin.key]\n ? copilotPlugins\n : []),\n // Nodes\n HeadingPlugin,\n TocPlugin.configure({\n options: {\n scrollContainerSelector: `#${scrollSelector}`,\n topOffset: 80,\n },\n }),\n BlockquotePlugin,\n CodeBlockPlugin.configure({\n options: {\n prism: Prism,\n },\n }),\n HorizontalRulePlugin,\n LinkPlugin.extend({\n render: { afterEditable: () => },\n }),\n ...(id === 'list' ? [ListPlugin] : []),\n ImagePlugin.extend({\n options: {\n disableUploadInsert: true,\n },\n render: { afterEditable: ImagePreview },\n }),\n MediaEmbedPlugin,\n CaptionPlugin.configure({\n options: {\n plugins: [ImagePlugin, MediaEmbedPlugin],\n },\n }),\n DatePlugin,\n MentionPlugin.configure({\n options: {\n triggerPreviousCharPattern: /^$|^[\\s\"']$/,\n },\n }),\n SlashPlugin,\n TablePlugin.configure({\n options: {\n enableMerging: id === 'tableMerge',\n },\n }),\n ColumnPlugin,\n SelectionOverlayPlugin,\n\n TodoListPlugin,\n TogglePlugin,\n ExcalidrawPlugin,\n // Marks\n BoldPlugin,\n ItalicPlugin,\n UnderlinePlugin,\n StrikethroughPlugin,\n CodePlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n FontColorPlugin,\n FontBackgroundColorPlugin,\n FontSizePlugin,\n HighlightPlugin,\n KbdPlugin,\n\n // Block Style\n AlignPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n MediaEmbedPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n ImagePlugin.key,\n HEADING_KEYS.h6,\n ],\n },\n }),\n IndentPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n }),\n IndentListPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n options: {\n listStyleTypes: {\n fire: {\n liComponent: FireLiComponent,\n markerComponent: FireMarker,\n type: 'fire',\n },\n todo: {\n liComponent: TodoLi,\n markerComponent: TodoMarker,\n type: 'todo',\n },\n },\n },\n }),\n LineHeightPlugin.extend({\n inject: {\n nodeProps: {\n defaultNodeValue: 1.5,\n validNodeValues: [1, 1.2, 1.5, 2, 3],\n },\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n ],\n },\n }),\n\n // Functionality\n AutoformatPlugin.configure({\n options: autoformatOptions,\n }),\n BlockSelectionPlugin.configure({\n options: {\n areaOptions: {\n behaviour: {\n scrolling: {\n speedDivider: 1.5,\n },\n startThreshold: 10,\n },\n boundaries: `#${scrollSelector}`,\n container: `#${scrollSelector}`,\n selectables: [`#${scrollSelector} .slate-selectable`],\n selectionAreaClass: 'slate-selection-area',\n },\n enableContextMenu: true,\n },\n }),\n BlockMenuPlugin.configure({\n render: { aboveEditable: BlockContextMenu },\n }),\n DndPlugin.configure({\n options: {\n enableScroller: true,\n onDropFiles: ({ dragItem, editor, target }) => {\n editor\n .getTransforms(ImagePlugin)\n .insertImageFromFiles(dragItem.files, {\n at: target,\n nextBlock: false,\n });\n },\n },\n }),\n EmojiPlugin,\n exitBreakPlugin,\n NodeIdPlugin,\n NormalizeTypesPlugin.configure({\n options: {\n rules: [{ path: [0], strictType: HEADING_KEYS.h1 }],\n },\n }),\n resetBlockTypePlugin,\n SelectOnBackspacePlugin.configure({\n options: {\n query: {\n allow: [ImagePlugin.key, HorizontalRulePlugin.key],\n },\n },\n }),\n DeletePlugin,\n SingleLinePlugin,\n softBreakPlugin,\n tabbablePlugin,\n TrailingBlockPlugin.configure({\n options: { type: ParagraphPlugin.key },\n }),\n DragOverCursorPlugin,\n\n // Collaboration\n CommentsPlugin.configure({\n options: {\n comments: commentsData,\n myUserId: '1',\n users: usersData,\n },\n }),\n\n // Deserialization\n DocxPlugin,\n MarkdownPlugin.configure({ options: { indentList: true } }),\n JuicePlugin,\n\n // Testing\n PlaywrightPlugin.configure({\n enabled: process.env.NODE_ENV !== 'production',\n }),\n ],\n value: value,\n },\n []\n );\n};\n\nexport default function PlaygroundDemo({\n id,\n className,\n scrollSelector,\n}: {\n id?: ValueId;\n className?: string;\n scrollSelector?: string;\n}) {\n const containerRef = useRef(null);\n const enabled = settingsStore.use.checkedComponents();\n\n const editor = usePlaygroundEditor(\n id,\n scrollSelector ?? `blockSelection-${id}`\n );\n\n return (\n \n \n \n \n \n \n \n \n \n\n
\n \n \n\n \n \n \n \n \n \n \n\n \n \n \n \n\n \n \n \n
\n
\n
\n );\n}\n\nconst DemoIdContext = React.createContext(undefined);\n\nexport function DemoId({\n id,\n children,\n}: {\n children: React.ReactNode;\n id?: string;\n}) {\n return {children};\n}\n\nexport function useDemoId() {\n return React.useContext(DemoIdContext);\n}\n", + "content": "'use client';\n\nimport React, { useRef } from 'react';\n\nimport type { ValueId } from '@/config/customizer-plugins';\n\nimport { cn } from '@udecode/cn';\nimport { AIChatPlugin, CopilotPlugin } from '@udecode/plate-ai/react';\nimport { AlignPlugin } from '@udecode/plate-alignment/react';\nimport { AutoformatPlugin } from '@udecode/plate-autoformat/react';\nimport {\n BoldPlugin,\n CodePlugin,\n ItalicPlugin,\n StrikethroughPlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n UnderlinePlugin,\n} from '@udecode/plate-basic-marks/react';\nimport { BlockquotePlugin } from '@udecode/plate-block-quote/react';\nimport { SingleLinePlugin } from '@udecode/plate-break/react';\nimport { CaptionPlugin } from '@udecode/plate-caption/react';\nimport { CodeBlockPlugin } from '@udecode/plate-code-block/react';\nimport { CommentsPlugin } from '@udecode/plate-comments/react';\nimport {\n ParagraphPlugin,\n Plate,\n usePlateEditor,\n} from '@udecode/plate-common/react';\nimport { DatePlugin } from '@udecode/plate-date/react';\nimport { DndPlugin } from '@udecode/plate-dnd';\nimport { DocxPlugin } from '@udecode/plate-docx';\nimport { EmojiPlugin } from '@udecode/plate-emoji/react';\nimport { ExcalidrawPlugin } from '@udecode/plate-excalidraw/react';\nimport {\n FontBackgroundColorPlugin,\n FontColorPlugin,\n FontSizePlugin,\n} from '@udecode/plate-font/react';\nimport { HEADING_KEYS } from '@udecode/plate-heading';\nimport { HeadingPlugin, TocPlugin } from '@udecode/plate-heading/react';\nimport { HighlightPlugin } from '@udecode/plate-highlight/react';\nimport { HorizontalRulePlugin } from '@udecode/plate-horizontal-rule/react';\nimport { IndentPlugin } from '@udecode/plate-indent/react';\nimport { IndentListPlugin } from '@udecode/plate-indent-list/react';\nimport { JuicePlugin } from '@udecode/plate-juice';\nimport { KbdPlugin } from '@udecode/plate-kbd/react';\nimport { ColumnPlugin } from '@udecode/plate-layout/react';\nimport { LineHeightPlugin } from '@udecode/plate-line-height/react';\nimport { LinkPlugin } from '@udecode/plate-link/react';\nimport { ListPlugin, TodoListPlugin } from '@udecode/plate-list/react';\nimport { MarkdownPlugin } from '@udecode/plate-markdown';\nimport { BaseImagePlugin } from '@udecode/plate-media';\nimport { ImagePlugin, MediaEmbedPlugin } from '@udecode/plate-media/react';\nimport { MentionPlugin } from '@udecode/plate-mention/react';\nimport { NodeIdPlugin } from '@udecode/plate-node-id';\nimport { NormalizeTypesPlugin } from '@udecode/plate-normalizers';\nimport { PlaywrightPlugin } from '@udecode/plate-playwright';\nimport { DeletePlugin, SelectOnBackspacePlugin } from '@udecode/plate-select';\nimport {\n BlockMenuPlugin,\n BlockSelectionPlugin,\n} from '@udecode/plate-selection/react';\nimport { SlashPlugin } from '@udecode/plate-slash-command/react';\nimport { TablePlugin } from '@udecode/plate-table/react';\nimport { TogglePlugin } from '@udecode/plate-toggle/react';\nimport { TrailingBlockPlugin } from '@udecode/plate-trailing-block';\nimport Prism from 'prismjs';\n\nimport { CheckPlugin } from '@/components/context/check-plugin';\nimport { settingsStore } from '@/components/context/settings-store';\nimport { aiPlugins } from '@/lib/plate/demo/plugins/ai-plugins';\nimport { getAutoformatOptions } from '@/lib/plate/demo/plugins/autoformatOptions';\nimport { copilotPlugins } from '@/lib/plate/demo/plugins/copilot-plugins';\nimport { createPlateUI } from '@/plate/create-plate-ui';\nimport { editableProps } from '@/plate/demo/editableProps';\nimport { isEnabled } from '@/plate/demo/is-enabled';\nimport { DragOverCursorPlugin } from '@/plate/demo/plugins/DragOverCursorPlugin';\nimport { exitBreakPlugin } from '@/plate/demo/plugins/exitBreakPlugin';\nimport { resetBlockTypePlugin } from '@/plate/demo/plugins/resetBlockTypePlugin';\nimport { softBreakPlugin } from '@/plate/demo/plugins/softBreakPlugin';\nimport { tabbablePlugin } from '@/plate/demo/plugins/tabbablePlugin';\nimport { commentsData, usersData } from '@/plate/demo/values/commentsValue';\nimport { usePlaygroundValue } from '@/plate/demo/values/usePlaygroundValue';\nimport { BlockContextMenu } from '@/components/plate-ui/block-context-menu';\nimport { CommentsPopover } from '@/components/plate-ui/comments-popover';\nimport {\n CursorOverlay,\n SelectionOverlayPlugin,\n} from '@/components/plate-ui/cursor-overlay';\nimport { Editor, EditorContainer } from '@/components/plate-ui/editor';\nimport { FixedToolbar } from '@/components/plate-ui/fixed-toolbar';\nimport { FixedToolbarButtons } from '@/components/plate-ui/fixed-toolbar-buttons';\nimport { FloatingToolbar } from '@/components/plate-ui/floating-toolbar';\nimport { FloatingToolbarButtons } from '@/components/plate-ui/floating-toolbar-buttons';\nimport { ImagePreview } from '@/components/plate-ui/image-preview';\nimport {\n FireLiComponent,\n FireMarker,\n} from '@/components/plate-ui/indent-fire-marker';\nimport {\n TodoLi,\n TodoMarker,\n} from '@/components/plate-ui/indent-todo-marker';\nimport { LinkFloatingToolbar } from '@/components/plate-ui/link-floating-toolbar';\n\nimport { usePlaygroundEnabled } from './usePlaygroundEnabled';\n\nexport const usePlaygroundEditor = (id: any = '', scrollSelector?: string) => {\n const enabledPlugins = settingsStore.use.checkedPlugins();\n const overridePlugins = usePlaygroundEnabled(id);\n const autoformatOptions = getAutoformatOptions(id, enabledPlugins);\n\n const value = usePlaygroundValue(id);\n const key = settingsStore.use.version();\n const editorId = id || 'playground-' + key;\n\n return usePlateEditor(\n {\n id: editorId,\n override: {\n components: createPlateUI({\n draggable: isEnabled('dnd', id),\n placeholder: isEnabled('placeholder', id),\n }),\n plugins: overridePlugins,\n },\n plugins: [\n // AI\n ...(id === 'ai' || enabledPlugins[AIChatPlugin.key] ? aiPlugins : []),\n ...(id === 'copilot' || enabledPlugins[CopilotPlugin.key]\n ? copilotPlugins\n : []),\n // Nodes\n HeadingPlugin,\n TocPlugin.configure({\n options: {\n scrollContainerSelector: `#${scrollSelector}`,\n topOffset: 80,\n },\n }),\n BlockquotePlugin,\n CodeBlockPlugin.configure({\n options: {\n prism: Prism,\n },\n }),\n HorizontalRulePlugin,\n LinkPlugin.extend({\n render: { afterEditable: () => },\n }),\n ...(id === 'list' ? [ListPlugin] : []),\n ImagePlugin.extend({\n options: {\n disableUploadInsert: true,\n },\n render: { afterEditable: ImagePreview },\n }),\n MediaEmbedPlugin,\n CaptionPlugin.configure({\n options: {\n plugins: [ImagePlugin, MediaEmbedPlugin],\n },\n }),\n DatePlugin,\n MentionPlugin.configure({\n options: {\n triggerPreviousCharPattern: /^$|^[\\s\"']$/,\n },\n }),\n SlashPlugin,\n TablePlugin.configure({\n options: {\n enableMerging: id === 'tableMerge',\n },\n }),\n ColumnPlugin,\n SelectionOverlayPlugin,\n\n TodoListPlugin,\n TogglePlugin,\n ExcalidrawPlugin,\n // Marks\n BoldPlugin,\n ItalicPlugin,\n UnderlinePlugin,\n StrikethroughPlugin,\n CodePlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n FontColorPlugin,\n FontBackgroundColorPlugin,\n FontSizePlugin,\n HighlightPlugin,\n KbdPlugin,\n\n // Block Style\n AlignPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n MediaEmbedPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n ImagePlugin.key,\n HEADING_KEYS.h6,\n ],\n },\n }),\n IndentPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n }),\n IndentListPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n options: {\n listStyleTypes: {\n fire: {\n liComponent: FireLiComponent,\n markerComponent: FireMarker,\n type: 'fire',\n },\n todo: {\n liComponent: TodoLi,\n markerComponent: TodoMarker,\n type: 'todo',\n },\n },\n },\n }),\n LineHeightPlugin.extend({\n inject: {\n nodeProps: {\n defaultNodeValue: 1.5,\n validNodeValues: [1, 1.2, 1.5, 2, 3],\n },\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n ],\n },\n }),\n\n // Functionality\n AutoformatPlugin.configure({\n options: autoformatOptions,\n }),\n BlockSelectionPlugin.configure({\n options: {\n areaOptions: {\n behaviour: {\n scrolling: {\n speedDivider: 1.5,\n },\n startThreshold: 10,\n },\n boundaries: `#${scrollSelector}`,\n container: `#${scrollSelector}`,\n selectables: [`#${scrollSelector} .slate-selectable`],\n selectionAreaClass: 'slate-selection-area',\n },\n enableContextMenu: true,\n },\n }),\n BlockMenuPlugin.configure({\n render: { aboveEditable: BlockContextMenu },\n }),\n DndPlugin.configure({\n options: {\n enableScroller: true,\n onDropFiles: ({ dragItem, editor, target }) => {\n editor\n .getTransforms(BaseImagePlugin)\n .insert.imageFromFiles(dragItem.files, {\n at: target,\n nextBlock: false,\n });\n },\n },\n }),\n EmojiPlugin,\n exitBreakPlugin,\n NodeIdPlugin,\n NormalizeTypesPlugin.configure({\n options: {\n rules: [{ path: [0], strictType: HEADING_KEYS.h1 }],\n },\n }),\n resetBlockTypePlugin,\n SelectOnBackspacePlugin.configure({\n options: {\n query: {\n allow: [ImagePlugin.key, HorizontalRulePlugin.key],\n },\n },\n }),\n DeletePlugin,\n SingleLinePlugin,\n softBreakPlugin,\n tabbablePlugin,\n TrailingBlockPlugin.configure({\n options: { type: ParagraphPlugin.key },\n }),\n DragOverCursorPlugin,\n\n // Collaboration\n CommentsPlugin.configure({\n options: {\n comments: commentsData,\n myUserId: '1',\n users: usersData,\n },\n }),\n\n // Deserialization\n DocxPlugin,\n MarkdownPlugin.configure({ options: { indentList: true } }),\n JuicePlugin,\n\n // Testing\n PlaywrightPlugin.configure({\n enabled: process.env.NODE_ENV !== 'production',\n }),\n ],\n value: value,\n },\n []\n );\n};\n\nexport default function PlaygroundDemo({\n id,\n className,\n scrollSelector,\n}: {\n id?: ValueId;\n className?: string;\n scrollSelector?: string;\n}) {\n const containerRef = useRef(null);\n const enabled = settingsStore.use.checkedComponents();\n\n const editor = usePlaygroundEditor(\n id,\n scrollSelector ?? `blockSelection-${id}`\n );\n\n return (\n \n \n \n \n \n \n \n \n \n\n
\n \n \n\n \n \n \n \n \n \n \n\n \n \n \n \n\n \n \n \n
\n
\n
\n );\n}\n\nconst DemoIdContext = React.createContext(undefined);\n\nexport function DemoId({\n id,\n children,\n}: {\n children: React.ReactNode;\n id?: string;\n}) {\n return {children};\n}\n\nexport function useDemoId() {\n return React.useContext(DemoIdContext);\n}\n", "path": "example/playground-demo.tsx", "target": "components/playground-demo.tsx", "type": "registry:example" diff --git a/apps/www/public/r/styles/default/image-element.json b/apps/www/public/r/styles/default/image-element.json index 5f56dfc54f..fff20059b4 100644 --- a/apps/www/public/r/styles/default/image-element.json +++ b/apps/www/public/r/styles/default/image-element.json @@ -20,7 +20,7 @@ }, "files": [ { - "content": "'use client';\n\nimport React from 'react';\n\nimport { cn, withRef } from '@udecode/cn';\nimport { withHOC } from '@udecode/plate-common/react';\nimport { useDraggable, useDraggableState } from '@udecode/plate-dnd';\nimport { Image, ImagePlugin, useMediaState } from '@udecode/plate-media/react';\nimport { ResizableProvider, useResizableStore } from '@udecode/plate-resizable';\n\nimport { Caption, CaptionTextarea } from './caption';\nimport { MediaPopover } from './media-popover';\nimport { PlateElement } from './plate-element';\nimport {\n Resizable,\n ResizeHandle,\n mediaResizeHandleVariants,\n} from './resizable';\n\nexport const ImageElement = withHOC(\n ResizableProvider,\n withRef(\n ({ children, className, nodeProps, ...props }, ref) => {\n const { align = 'center', focused, readOnly, selected } = useMediaState();\n\n const width = useResizableStore().get.width();\n\n const state = useDraggableState({ element: props.element });\n const { isDragging } = state;\n const { handleRef } = useDraggable(state);\n\n return (\n \n \n
\n \n \n \n \n \n\n \n {\n e.preventDefault();\n }}\n placeholder=\"Write a caption...\"\n />\n \n
\n\n {children}\n
\n
\n );\n }\n )\n);\n", + "content": "'use client';\n\nimport React from 'react';\n\nimport { cn, withRef } from '@udecode/cn';\nimport { withHOC } from '@udecode/plate-common/react';\nimport { Image, ImagePlugin, useMediaState } from '@udecode/plate-media/react';\nimport { ResizableProvider, useResizableStore } from '@udecode/plate-resizable';\n\nimport { Caption, CaptionTextarea } from './caption';\nimport { MediaPopover } from './media-popover';\nimport { PlateElement } from './plate-element';\nimport {\n Resizable,\n ResizeHandle,\n mediaResizeHandleVariants,\n} from './resizable';\n\nexport const ImageElement = withHOC(\n ResizableProvider,\n withRef(\n ({ children, className, nodeProps, ...props }, ref) => {\n const { align = 'center', focused, readOnly, selected } = useMediaState();\n\n const width = useResizableStore().get.width();\n\n return (\n \n \n
\n \n \n \n \n \n\n \n {\n e.preventDefault();\n }}\n placeholder=\"Write a caption...\"\n />\n \n
\n\n {children}\n
\n
\n );\n }\n )\n);\n", "path": "plate-ui/image-element.tsx", "target": "components/plate-ui/image-element.tsx", "type": "registry:ui" diff --git a/apps/www/public/r/styles/default/indent-demo.json b/apps/www/public/r/styles/default/indent-demo.json index 456b956bcf..18196b42a1 100644 --- a/apps/www/public/r/styles/default/indent-demo.json +++ b/apps/www/public/r/styles/default/indent-demo.json @@ -4,7 +4,7 @@ }, "files": [ { - "content": "'use client';\n\nimport React, { useRef } from 'react';\n\nimport type { ValueId } from '@/config/customizer-plugins';\n\nimport { cn } from '@udecode/cn';\nimport { AIChatPlugin, CopilotPlugin } from '@udecode/plate-ai/react';\nimport { AlignPlugin } from '@udecode/plate-alignment/react';\nimport { AutoformatPlugin } from '@udecode/plate-autoformat/react';\nimport {\n BoldPlugin,\n CodePlugin,\n ItalicPlugin,\n StrikethroughPlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n UnderlinePlugin,\n} from '@udecode/plate-basic-marks/react';\nimport { BlockquotePlugin } from '@udecode/plate-block-quote/react';\nimport { SingleLinePlugin } from '@udecode/plate-break/react';\nimport { CaptionPlugin } from '@udecode/plate-caption/react';\nimport { CodeBlockPlugin } from '@udecode/plate-code-block/react';\nimport { CommentsPlugin } from '@udecode/plate-comments/react';\nimport {\n ParagraphPlugin,\n Plate,\n usePlateEditor,\n} from '@udecode/plate-common/react';\nimport { DatePlugin } from '@udecode/plate-date/react';\nimport { DndPlugin } from '@udecode/plate-dnd';\nimport { DocxPlugin } from '@udecode/plate-docx';\nimport { EmojiPlugin } from '@udecode/plate-emoji/react';\nimport { ExcalidrawPlugin } from '@udecode/plate-excalidraw/react';\nimport {\n FontBackgroundColorPlugin,\n FontColorPlugin,\n FontSizePlugin,\n} from '@udecode/plate-font/react';\nimport { HEADING_KEYS } from '@udecode/plate-heading';\nimport { HeadingPlugin, TocPlugin } from '@udecode/plate-heading/react';\nimport { HighlightPlugin } from '@udecode/plate-highlight/react';\nimport { HorizontalRulePlugin } from '@udecode/plate-horizontal-rule/react';\nimport { IndentPlugin } from '@udecode/plate-indent/react';\nimport { IndentListPlugin } from '@udecode/plate-indent-list/react';\nimport { JuicePlugin } from '@udecode/plate-juice';\nimport { KbdPlugin } from '@udecode/plate-kbd/react';\nimport { ColumnPlugin } from '@udecode/plate-layout/react';\nimport { LineHeightPlugin } from '@udecode/plate-line-height/react';\nimport { LinkPlugin } from '@udecode/plate-link/react';\nimport { ListPlugin, TodoListPlugin } from '@udecode/plate-list/react';\nimport { MarkdownPlugin } from '@udecode/plate-markdown';\nimport { ImagePlugin, MediaEmbedPlugin } from '@udecode/plate-media/react';\nimport { MentionPlugin } from '@udecode/plate-mention/react';\nimport { NodeIdPlugin } from '@udecode/plate-node-id';\nimport { NormalizeTypesPlugin } from '@udecode/plate-normalizers';\nimport { PlaywrightPlugin } from '@udecode/plate-playwright';\nimport { DeletePlugin, SelectOnBackspacePlugin } from '@udecode/plate-select';\nimport {\n BlockMenuPlugin,\n BlockSelectionPlugin,\n} from '@udecode/plate-selection/react';\nimport { SlashPlugin } from '@udecode/plate-slash-command/react';\nimport { TablePlugin } from '@udecode/plate-table/react';\nimport { TogglePlugin } from '@udecode/plate-toggle/react';\nimport { TrailingBlockPlugin } from '@udecode/plate-trailing-block';\nimport Prism from 'prismjs';\n\nimport { CheckPlugin } from '@/components/context/check-plugin';\nimport { settingsStore } from '@/components/context/settings-store';\nimport { aiPlugins } from '@/lib/plate/demo/plugins/ai-plugins';\nimport { getAutoformatOptions } from '@/lib/plate/demo/plugins/autoformatOptions';\nimport { copilotPlugins } from '@/lib/plate/demo/plugins/copilot-plugins';\nimport { createPlateUI } from '@/plate/create-plate-ui';\nimport { editableProps } from '@/plate/demo/editableProps';\nimport { isEnabled } from '@/plate/demo/is-enabled';\nimport { DragOverCursorPlugin } from '@/plate/demo/plugins/DragOverCursorPlugin';\nimport { exitBreakPlugin } from '@/plate/demo/plugins/exitBreakPlugin';\nimport { resetBlockTypePlugin } from '@/plate/demo/plugins/resetBlockTypePlugin';\nimport { softBreakPlugin } from '@/plate/demo/plugins/softBreakPlugin';\nimport { tabbablePlugin } from '@/plate/demo/plugins/tabbablePlugin';\nimport { commentsData, usersData } from '@/plate/demo/values/commentsValue';\nimport { usePlaygroundValue } from '@/plate/demo/values/usePlaygroundValue';\nimport { BlockContextMenu } from '@/components/plate-ui/block-context-menu';\nimport { CommentsPopover } from '@/components/plate-ui/comments-popover';\nimport {\n CursorOverlay,\n SelectionOverlayPlugin,\n} from '@/components/plate-ui/cursor-overlay';\nimport { Editor, EditorContainer } from '@/components/plate-ui/editor';\nimport { FixedToolbar } from '@/components/plate-ui/fixed-toolbar';\nimport { FixedToolbarButtons } from '@/components/plate-ui/fixed-toolbar-buttons';\nimport { FloatingToolbar } from '@/components/plate-ui/floating-toolbar';\nimport { FloatingToolbarButtons } from '@/components/plate-ui/floating-toolbar-buttons';\nimport { ImagePreview } from '@/components/plate-ui/image-preview';\nimport {\n FireLiComponent,\n FireMarker,\n} from '@/components/plate-ui/indent-fire-marker';\nimport {\n TodoLi,\n TodoMarker,\n} from '@/components/plate-ui/indent-todo-marker';\nimport { LinkFloatingToolbar } from '@/components/plate-ui/link-floating-toolbar';\n\nimport { usePlaygroundEnabled } from './usePlaygroundEnabled';\n\nexport const usePlaygroundEditor = (id: any = '', scrollSelector?: string) => {\n const enabledPlugins = settingsStore.use.checkedPlugins();\n const overridePlugins = usePlaygroundEnabled(id);\n const autoformatOptions = getAutoformatOptions(id, enabledPlugins);\n\n const value = usePlaygroundValue(id);\n const key = settingsStore.use.version();\n const editorId = id || 'playground-' + key;\n\n return usePlateEditor(\n {\n id: editorId,\n override: {\n components: createPlateUI({\n draggable: isEnabled('dnd', id),\n placeholder: isEnabled('placeholder', id),\n }),\n plugins: overridePlugins,\n },\n plugins: [\n // AI\n ...(id === 'ai' || enabledPlugins[AIChatPlugin.key] ? aiPlugins : []),\n ...(id === 'copilot' || enabledPlugins[CopilotPlugin.key]\n ? copilotPlugins\n : []),\n // Nodes\n HeadingPlugin,\n TocPlugin.configure({\n options: {\n scrollContainerSelector: `#${scrollSelector}`,\n topOffset: 80,\n },\n }),\n BlockquotePlugin,\n CodeBlockPlugin.configure({\n options: {\n prism: Prism,\n },\n }),\n HorizontalRulePlugin,\n LinkPlugin.extend({\n render: { afterEditable: () => },\n }),\n ...(id === 'list' ? [ListPlugin] : []),\n ImagePlugin.extend({\n options: {\n disableUploadInsert: true,\n },\n render: { afterEditable: ImagePreview },\n }),\n MediaEmbedPlugin,\n CaptionPlugin.configure({\n options: {\n plugins: [ImagePlugin, MediaEmbedPlugin],\n },\n }),\n DatePlugin,\n MentionPlugin.configure({\n options: {\n triggerPreviousCharPattern: /^$|^[\\s\"']$/,\n },\n }),\n SlashPlugin,\n TablePlugin.configure({\n options: {\n enableMerging: id === 'tableMerge',\n },\n }),\n ColumnPlugin,\n SelectionOverlayPlugin,\n\n TodoListPlugin,\n TogglePlugin,\n ExcalidrawPlugin,\n // Marks\n BoldPlugin,\n ItalicPlugin,\n UnderlinePlugin,\n StrikethroughPlugin,\n CodePlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n FontColorPlugin,\n FontBackgroundColorPlugin,\n FontSizePlugin,\n HighlightPlugin,\n KbdPlugin,\n\n // Block Style\n AlignPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n MediaEmbedPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n ImagePlugin.key,\n HEADING_KEYS.h6,\n ],\n },\n }),\n IndentPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n }),\n IndentListPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n options: {\n listStyleTypes: {\n fire: {\n liComponent: FireLiComponent,\n markerComponent: FireMarker,\n type: 'fire',\n },\n todo: {\n liComponent: TodoLi,\n markerComponent: TodoMarker,\n type: 'todo',\n },\n },\n },\n }),\n LineHeightPlugin.extend({\n inject: {\n nodeProps: {\n defaultNodeValue: 1.5,\n validNodeValues: [1, 1.2, 1.5, 2, 3],\n },\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n ],\n },\n }),\n\n // Functionality\n AutoformatPlugin.configure({\n options: autoformatOptions,\n }),\n BlockSelectionPlugin.configure({\n options: {\n areaOptions: {\n behaviour: {\n scrolling: {\n speedDivider: 1.5,\n },\n startThreshold: 10,\n },\n boundaries: `#${scrollSelector}`,\n container: `#${scrollSelector}`,\n selectables: [`#${scrollSelector} .slate-selectable`],\n selectionAreaClass: 'slate-selection-area',\n },\n enableContextMenu: true,\n },\n }),\n BlockMenuPlugin.configure({\n render: { aboveEditable: BlockContextMenu },\n }),\n DndPlugin.configure({\n options: {\n enableScroller: true,\n onDropFiles: ({ dragItem, editor, target }) => {\n editor\n .getTransforms(ImagePlugin)\n .insertImageFromFiles(dragItem.files, {\n at: target,\n nextBlock: false,\n });\n },\n },\n }),\n EmojiPlugin,\n exitBreakPlugin,\n NodeIdPlugin,\n NormalizeTypesPlugin.configure({\n options: {\n rules: [{ path: [0], strictType: HEADING_KEYS.h1 }],\n },\n }),\n resetBlockTypePlugin,\n SelectOnBackspacePlugin.configure({\n options: {\n query: {\n allow: [ImagePlugin.key, HorizontalRulePlugin.key],\n },\n },\n }),\n DeletePlugin,\n SingleLinePlugin,\n softBreakPlugin,\n tabbablePlugin,\n TrailingBlockPlugin.configure({\n options: { type: ParagraphPlugin.key },\n }),\n DragOverCursorPlugin,\n\n // Collaboration\n CommentsPlugin.configure({\n options: {\n comments: commentsData,\n myUserId: '1',\n users: usersData,\n },\n }),\n\n // Deserialization\n DocxPlugin,\n MarkdownPlugin.configure({ options: { indentList: true } }),\n JuicePlugin,\n\n // Testing\n PlaywrightPlugin.configure({\n enabled: process.env.NODE_ENV !== 'production',\n }),\n ],\n value: value,\n },\n []\n );\n};\n\nexport default function PlaygroundDemo({\n id,\n className,\n scrollSelector,\n}: {\n id?: ValueId;\n className?: string;\n scrollSelector?: string;\n}) {\n const containerRef = useRef(null);\n const enabled = settingsStore.use.checkedComponents();\n\n const editor = usePlaygroundEditor(\n id,\n scrollSelector ?? `blockSelection-${id}`\n );\n\n return (\n \n \n \n \n \n \n \n \n \n\n
\n \n \n\n \n \n \n \n \n \n \n\n \n \n \n \n\n \n \n \n
\n
\n
\n );\n}\n\nconst DemoIdContext = React.createContext(undefined);\n\nexport function DemoId({\n id,\n children,\n}: {\n children: React.ReactNode;\n id?: string;\n}) {\n return {children};\n}\n\nexport function useDemoId() {\n return React.useContext(DemoIdContext);\n}\n", + "content": "'use client';\n\nimport React, { useRef } from 'react';\n\nimport type { ValueId } from '@/config/customizer-plugins';\n\nimport { cn } from '@udecode/cn';\nimport { AIChatPlugin, CopilotPlugin } from '@udecode/plate-ai/react';\nimport { AlignPlugin } from '@udecode/plate-alignment/react';\nimport { AutoformatPlugin } from '@udecode/plate-autoformat/react';\nimport {\n BoldPlugin,\n CodePlugin,\n ItalicPlugin,\n StrikethroughPlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n UnderlinePlugin,\n} from '@udecode/plate-basic-marks/react';\nimport { BlockquotePlugin } from '@udecode/plate-block-quote/react';\nimport { SingleLinePlugin } from '@udecode/plate-break/react';\nimport { CaptionPlugin } from '@udecode/plate-caption/react';\nimport { CodeBlockPlugin } from '@udecode/plate-code-block/react';\nimport { CommentsPlugin } from '@udecode/plate-comments/react';\nimport {\n ParagraphPlugin,\n Plate,\n usePlateEditor,\n} from '@udecode/plate-common/react';\nimport { DatePlugin } from '@udecode/plate-date/react';\nimport { DndPlugin } from '@udecode/plate-dnd';\nimport { DocxPlugin } from '@udecode/plate-docx';\nimport { EmojiPlugin } from '@udecode/plate-emoji/react';\nimport { ExcalidrawPlugin } from '@udecode/plate-excalidraw/react';\nimport {\n FontBackgroundColorPlugin,\n FontColorPlugin,\n FontSizePlugin,\n} from '@udecode/plate-font/react';\nimport { HEADING_KEYS } from '@udecode/plate-heading';\nimport { HeadingPlugin, TocPlugin } from '@udecode/plate-heading/react';\nimport { HighlightPlugin } from '@udecode/plate-highlight/react';\nimport { HorizontalRulePlugin } from '@udecode/plate-horizontal-rule/react';\nimport { IndentPlugin } from '@udecode/plate-indent/react';\nimport { IndentListPlugin } from '@udecode/plate-indent-list/react';\nimport { JuicePlugin } from '@udecode/plate-juice';\nimport { KbdPlugin } from '@udecode/plate-kbd/react';\nimport { ColumnPlugin } from '@udecode/plate-layout/react';\nimport { LineHeightPlugin } from '@udecode/plate-line-height/react';\nimport { LinkPlugin } from '@udecode/plate-link/react';\nimport { ListPlugin, TodoListPlugin } from '@udecode/plate-list/react';\nimport { MarkdownPlugin } from '@udecode/plate-markdown';\nimport { BaseImagePlugin } from '@udecode/plate-media';\nimport { ImagePlugin, MediaEmbedPlugin } from '@udecode/plate-media/react';\nimport { MentionPlugin } from '@udecode/plate-mention/react';\nimport { NodeIdPlugin } from '@udecode/plate-node-id';\nimport { NormalizeTypesPlugin } from '@udecode/plate-normalizers';\nimport { PlaywrightPlugin } from '@udecode/plate-playwright';\nimport { DeletePlugin, SelectOnBackspacePlugin } from '@udecode/plate-select';\nimport {\n BlockMenuPlugin,\n BlockSelectionPlugin,\n} from '@udecode/plate-selection/react';\nimport { SlashPlugin } from '@udecode/plate-slash-command/react';\nimport { TablePlugin } from '@udecode/plate-table/react';\nimport { TogglePlugin } from '@udecode/plate-toggle/react';\nimport { TrailingBlockPlugin } from '@udecode/plate-trailing-block';\nimport Prism from 'prismjs';\n\nimport { CheckPlugin } from '@/components/context/check-plugin';\nimport { settingsStore } from '@/components/context/settings-store';\nimport { aiPlugins } from '@/lib/plate/demo/plugins/ai-plugins';\nimport { getAutoformatOptions } from '@/lib/plate/demo/plugins/autoformatOptions';\nimport { copilotPlugins } from '@/lib/plate/demo/plugins/copilot-plugins';\nimport { createPlateUI } from '@/plate/create-plate-ui';\nimport { editableProps } from '@/plate/demo/editableProps';\nimport { isEnabled } from '@/plate/demo/is-enabled';\nimport { DragOverCursorPlugin } from '@/plate/demo/plugins/DragOverCursorPlugin';\nimport { exitBreakPlugin } from '@/plate/demo/plugins/exitBreakPlugin';\nimport { resetBlockTypePlugin } from '@/plate/demo/plugins/resetBlockTypePlugin';\nimport { softBreakPlugin } from '@/plate/demo/plugins/softBreakPlugin';\nimport { tabbablePlugin } from '@/plate/demo/plugins/tabbablePlugin';\nimport { commentsData, usersData } from '@/plate/demo/values/commentsValue';\nimport { usePlaygroundValue } from '@/plate/demo/values/usePlaygroundValue';\nimport { BlockContextMenu } from '@/components/plate-ui/block-context-menu';\nimport { CommentsPopover } from '@/components/plate-ui/comments-popover';\nimport {\n CursorOverlay,\n SelectionOverlayPlugin,\n} from '@/components/plate-ui/cursor-overlay';\nimport { Editor, EditorContainer } from '@/components/plate-ui/editor';\nimport { FixedToolbar } from '@/components/plate-ui/fixed-toolbar';\nimport { FixedToolbarButtons } from '@/components/plate-ui/fixed-toolbar-buttons';\nimport { FloatingToolbar } from '@/components/plate-ui/floating-toolbar';\nimport { FloatingToolbarButtons } from '@/components/plate-ui/floating-toolbar-buttons';\nimport { ImagePreview } from '@/components/plate-ui/image-preview';\nimport {\n FireLiComponent,\n FireMarker,\n} from '@/components/plate-ui/indent-fire-marker';\nimport {\n TodoLi,\n TodoMarker,\n} from '@/components/plate-ui/indent-todo-marker';\nimport { LinkFloatingToolbar } from '@/components/plate-ui/link-floating-toolbar';\n\nimport { usePlaygroundEnabled } from './usePlaygroundEnabled';\n\nexport const usePlaygroundEditor = (id: any = '', scrollSelector?: string) => {\n const enabledPlugins = settingsStore.use.checkedPlugins();\n const overridePlugins = usePlaygroundEnabled(id);\n const autoformatOptions = getAutoformatOptions(id, enabledPlugins);\n\n const value = usePlaygroundValue(id);\n const key = settingsStore.use.version();\n const editorId = id || 'playground-' + key;\n\n return usePlateEditor(\n {\n id: editorId,\n override: {\n components: createPlateUI({\n draggable: isEnabled('dnd', id),\n placeholder: isEnabled('placeholder', id),\n }),\n plugins: overridePlugins,\n },\n plugins: [\n // AI\n ...(id === 'ai' || enabledPlugins[AIChatPlugin.key] ? aiPlugins : []),\n ...(id === 'copilot' || enabledPlugins[CopilotPlugin.key]\n ? copilotPlugins\n : []),\n // Nodes\n HeadingPlugin,\n TocPlugin.configure({\n options: {\n scrollContainerSelector: `#${scrollSelector}`,\n topOffset: 80,\n },\n }),\n BlockquotePlugin,\n CodeBlockPlugin.configure({\n options: {\n prism: Prism,\n },\n }),\n HorizontalRulePlugin,\n LinkPlugin.extend({\n render: { afterEditable: () => },\n }),\n ...(id === 'list' ? [ListPlugin] : []),\n ImagePlugin.extend({\n options: {\n disableUploadInsert: true,\n },\n render: { afterEditable: ImagePreview },\n }),\n MediaEmbedPlugin,\n CaptionPlugin.configure({\n options: {\n plugins: [ImagePlugin, MediaEmbedPlugin],\n },\n }),\n DatePlugin,\n MentionPlugin.configure({\n options: {\n triggerPreviousCharPattern: /^$|^[\\s\"']$/,\n },\n }),\n SlashPlugin,\n TablePlugin.configure({\n options: {\n enableMerging: id === 'tableMerge',\n },\n }),\n ColumnPlugin,\n SelectionOverlayPlugin,\n\n TodoListPlugin,\n TogglePlugin,\n ExcalidrawPlugin,\n // Marks\n BoldPlugin,\n ItalicPlugin,\n UnderlinePlugin,\n StrikethroughPlugin,\n CodePlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n FontColorPlugin,\n FontBackgroundColorPlugin,\n FontSizePlugin,\n HighlightPlugin,\n KbdPlugin,\n\n // Block Style\n AlignPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n MediaEmbedPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n ImagePlugin.key,\n HEADING_KEYS.h6,\n ],\n },\n }),\n IndentPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n }),\n IndentListPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n options: {\n listStyleTypes: {\n fire: {\n liComponent: FireLiComponent,\n markerComponent: FireMarker,\n type: 'fire',\n },\n todo: {\n liComponent: TodoLi,\n markerComponent: TodoMarker,\n type: 'todo',\n },\n },\n },\n }),\n LineHeightPlugin.extend({\n inject: {\n nodeProps: {\n defaultNodeValue: 1.5,\n validNodeValues: [1, 1.2, 1.5, 2, 3],\n },\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n ],\n },\n }),\n\n // Functionality\n AutoformatPlugin.configure({\n options: autoformatOptions,\n }),\n BlockSelectionPlugin.configure({\n options: {\n areaOptions: {\n behaviour: {\n scrolling: {\n speedDivider: 1.5,\n },\n startThreshold: 10,\n },\n boundaries: `#${scrollSelector}`,\n container: `#${scrollSelector}`,\n selectables: [`#${scrollSelector} .slate-selectable`],\n selectionAreaClass: 'slate-selection-area',\n },\n enableContextMenu: true,\n },\n }),\n BlockMenuPlugin.configure({\n render: { aboveEditable: BlockContextMenu },\n }),\n DndPlugin.configure({\n options: {\n enableScroller: true,\n onDropFiles: ({ dragItem, editor, target }) => {\n editor\n .getTransforms(BaseImagePlugin)\n .insert.imageFromFiles(dragItem.files, {\n at: target,\n nextBlock: false,\n });\n },\n },\n }),\n EmojiPlugin,\n exitBreakPlugin,\n NodeIdPlugin,\n NormalizeTypesPlugin.configure({\n options: {\n rules: [{ path: [0], strictType: HEADING_KEYS.h1 }],\n },\n }),\n resetBlockTypePlugin,\n SelectOnBackspacePlugin.configure({\n options: {\n query: {\n allow: [ImagePlugin.key, HorizontalRulePlugin.key],\n },\n },\n }),\n DeletePlugin,\n SingleLinePlugin,\n softBreakPlugin,\n tabbablePlugin,\n TrailingBlockPlugin.configure({\n options: { type: ParagraphPlugin.key },\n }),\n DragOverCursorPlugin,\n\n // Collaboration\n CommentsPlugin.configure({\n options: {\n comments: commentsData,\n myUserId: '1',\n users: usersData,\n },\n }),\n\n // Deserialization\n DocxPlugin,\n MarkdownPlugin.configure({ options: { indentList: true } }),\n JuicePlugin,\n\n // Testing\n PlaywrightPlugin.configure({\n enabled: process.env.NODE_ENV !== 'production',\n }),\n ],\n value: value,\n },\n []\n );\n};\n\nexport default function PlaygroundDemo({\n id,\n className,\n scrollSelector,\n}: {\n id?: ValueId;\n className?: string;\n scrollSelector?: string;\n}) {\n const containerRef = useRef(null);\n const enabled = settingsStore.use.checkedComponents();\n\n const editor = usePlaygroundEditor(\n id,\n scrollSelector ?? `blockSelection-${id}`\n );\n\n return (\n \n \n \n \n \n \n \n \n \n\n
\n \n \n\n \n \n \n \n \n \n \n\n \n \n \n \n\n \n \n \n
\n
\n
\n );\n}\n\nconst DemoIdContext = React.createContext(undefined);\n\nexport function DemoId({\n id,\n children,\n}: {\n children: React.ReactNode;\n id?: string;\n}) {\n return {children};\n}\n\nexport function useDemoId() {\n return React.useContext(DemoIdContext);\n}\n", "path": "example/playground-demo.tsx", "target": "components/playground-demo.tsx", "type": "registry:example" diff --git a/apps/www/public/r/styles/default/kbd-demo.json b/apps/www/public/r/styles/default/kbd-demo.json index 42fe130014..60156a5318 100644 --- a/apps/www/public/r/styles/default/kbd-demo.json +++ b/apps/www/public/r/styles/default/kbd-demo.json @@ -4,7 +4,7 @@ }, "files": [ { - "content": "'use client';\n\nimport React, { useRef } from 'react';\n\nimport type { ValueId } from '@/config/customizer-plugins';\n\nimport { cn } from '@udecode/cn';\nimport { AIChatPlugin, CopilotPlugin } from '@udecode/plate-ai/react';\nimport { AlignPlugin } from '@udecode/plate-alignment/react';\nimport { AutoformatPlugin } from '@udecode/plate-autoformat/react';\nimport {\n BoldPlugin,\n CodePlugin,\n ItalicPlugin,\n StrikethroughPlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n UnderlinePlugin,\n} from '@udecode/plate-basic-marks/react';\nimport { BlockquotePlugin } from '@udecode/plate-block-quote/react';\nimport { SingleLinePlugin } from '@udecode/plate-break/react';\nimport { CaptionPlugin } from '@udecode/plate-caption/react';\nimport { CodeBlockPlugin } from '@udecode/plate-code-block/react';\nimport { CommentsPlugin } from '@udecode/plate-comments/react';\nimport {\n ParagraphPlugin,\n Plate,\n usePlateEditor,\n} from '@udecode/plate-common/react';\nimport { DatePlugin } from '@udecode/plate-date/react';\nimport { DndPlugin } from '@udecode/plate-dnd';\nimport { DocxPlugin } from '@udecode/plate-docx';\nimport { EmojiPlugin } from '@udecode/plate-emoji/react';\nimport { ExcalidrawPlugin } from '@udecode/plate-excalidraw/react';\nimport {\n FontBackgroundColorPlugin,\n FontColorPlugin,\n FontSizePlugin,\n} from '@udecode/plate-font/react';\nimport { HEADING_KEYS } from '@udecode/plate-heading';\nimport { HeadingPlugin, TocPlugin } from '@udecode/plate-heading/react';\nimport { HighlightPlugin } from '@udecode/plate-highlight/react';\nimport { HorizontalRulePlugin } from '@udecode/plate-horizontal-rule/react';\nimport { IndentPlugin } from '@udecode/plate-indent/react';\nimport { IndentListPlugin } from '@udecode/plate-indent-list/react';\nimport { JuicePlugin } from '@udecode/plate-juice';\nimport { KbdPlugin } from '@udecode/plate-kbd/react';\nimport { ColumnPlugin } from '@udecode/plate-layout/react';\nimport { LineHeightPlugin } from '@udecode/plate-line-height/react';\nimport { LinkPlugin } from '@udecode/plate-link/react';\nimport { ListPlugin, TodoListPlugin } from '@udecode/plate-list/react';\nimport { MarkdownPlugin } from '@udecode/plate-markdown';\nimport { ImagePlugin, MediaEmbedPlugin } from '@udecode/plate-media/react';\nimport { MentionPlugin } from '@udecode/plate-mention/react';\nimport { NodeIdPlugin } from '@udecode/plate-node-id';\nimport { NormalizeTypesPlugin } from '@udecode/plate-normalizers';\nimport { PlaywrightPlugin } from '@udecode/plate-playwright';\nimport { DeletePlugin, SelectOnBackspacePlugin } from '@udecode/plate-select';\nimport {\n BlockMenuPlugin,\n BlockSelectionPlugin,\n} from '@udecode/plate-selection/react';\nimport { SlashPlugin } from '@udecode/plate-slash-command/react';\nimport { TablePlugin } from '@udecode/plate-table/react';\nimport { TogglePlugin } from '@udecode/plate-toggle/react';\nimport { TrailingBlockPlugin } from '@udecode/plate-trailing-block';\nimport Prism from 'prismjs';\n\nimport { CheckPlugin } from '@/components/context/check-plugin';\nimport { settingsStore } from '@/components/context/settings-store';\nimport { aiPlugins } from '@/lib/plate/demo/plugins/ai-plugins';\nimport { getAutoformatOptions } from '@/lib/plate/demo/plugins/autoformatOptions';\nimport { copilotPlugins } from '@/lib/plate/demo/plugins/copilot-plugins';\nimport { createPlateUI } from '@/plate/create-plate-ui';\nimport { editableProps } from '@/plate/demo/editableProps';\nimport { isEnabled } from '@/plate/demo/is-enabled';\nimport { DragOverCursorPlugin } from '@/plate/demo/plugins/DragOverCursorPlugin';\nimport { exitBreakPlugin } from '@/plate/demo/plugins/exitBreakPlugin';\nimport { resetBlockTypePlugin } from '@/plate/demo/plugins/resetBlockTypePlugin';\nimport { softBreakPlugin } from '@/plate/demo/plugins/softBreakPlugin';\nimport { tabbablePlugin } from '@/plate/demo/plugins/tabbablePlugin';\nimport { commentsData, usersData } from '@/plate/demo/values/commentsValue';\nimport { usePlaygroundValue } from '@/plate/demo/values/usePlaygroundValue';\nimport { BlockContextMenu } from '@/components/plate-ui/block-context-menu';\nimport { CommentsPopover } from '@/components/plate-ui/comments-popover';\nimport {\n CursorOverlay,\n SelectionOverlayPlugin,\n} from '@/components/plate-ui/cursor-overlay';\nimport { Editor, EditorContainer } from '@/components/plate-ui/editor';\nimport { FixedToolbar } from '@/components/plate-ui/fixed-toolbar';\nimport { FixedToolbarButtons } from '@/components/plate-ui/fixed-toolbar-buttons';\nimport { FloatingToolbar } from '@/components/plate-ui/floating-toolbar';\nimport { FloatingToolbarButtons } from '@/components/plate-ui/floating-toolbar-buttons';\nimport { ImagePreview } from '@/components/plate-ui/image-preview';\nimport {\n FireLiComponent,\n FireMarker,\n} from '@/components/plate-ui/indent-fire-marker';\nimport {\n TodoLi,\n TodoMarker,\n} from '@/components/plate-ui/indent-todo-marker';\nimport { LinkFloatingToolbar } from '@/components/plate-ui/link-floating-toolbar';\n\nimport { usePlaygroundEnabled } from './usePlaygroundEnabled';\n\nexport const usePlaygroundEditor = (id: any = '', scrollSelector?: string) => {\n const enabledPlugins = settingsStore.use.checkedPlugins();\n const overridePlugins = usePlaygroundEnabled(id);\n const autoformatOptions = getAutoformatOptions(id, enabledPlugins);\n\n const value = usePlaygroundValue(id);\n const key = settingsStore.use.version();\n const editorId = id || 'playground-' + key;\n\n return usePlateEditor(\n {\n id: editorId,\n override: {\n components: createPlateUI({\n draggable: isEnabled('dnd', id),\n placeholder: isEnabled('placeholder', id),\n }),\n plugins: overridePlugins,\n },\n plugins: [\n // AI\n ...(id === 'ai' || enabledPlugins[AIChatPlugin.key] ? aiPlugins : []),\n ...(id === 'copilot' || enabledPlugins[CopilotPlugin.key]\n ? copilotPlugins\n : []),\n // Nodes\n HeadingPlugin,\n TocPlugin.configure({\n options: {\n scrollContainerSelector: `#${scrollSelector}`,\n topOffset: 80,\n },\n }),\n BlockquotePlugin,\n CodeBlockPlugin.configure({\n options: {\n prism: Prism,\n },\n }),\n HorizontalRulePlugin,\n LinkPlugin.extend({\n render: { afterEditable: () => },\n }),\n ...(id === 'list' ? [ListPlugin] : []),\n ImagePlugin.extend({\n options: {\n disableUploadInsert: true,\n },\n render: { afterEditable: ImagePreview },\n }),\n MediaEmbedPlugin,\n CaptionPlugin.configure({\n options: {\n plugins: [ImagePlugin, MediaEmbedPlugin],\n },\n }),\n DatePlugin,\n MentionPlugin.configure({\n options: {\n triggerPreviousCharPattern: /^$|^[\\s\"']$/,\n },\n }),\n SlashPlugin,\n TablePlugin.configure({\n options: {\n enableMerging: id === 'tableMerge',\n },\n }),\n ColumnPlugin,\n SelectionOverlayPlugin,\n\n TodoListPlugin,\n TogglePlugin,\n ExcalidrawPlugin,\n // Marks\n BoldPlugin,\n ItalicPlugin,\n UnderlinePlugin,\n StrikethroughPlugin,\n CodePlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n FontColorPlugin,\n FontBackgroundColorPlugin,\n FontSizePlugin,\n HighlightPlugin,\n KbdPlugin,\n\n // Block Style\n AlignPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n MediaEmbedPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n ImagePlugin.key,\n HEADING_KEYS.h6,\n ],\n },\n }),\n IndentPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n }),\n IndentListPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n options: {\n listStyleTypes: {\n fire: {\n liComponent: FireLiComponent,\n markerComponent: FireMarker,\n type: 'fire',\n },\n todo: {\n liComponent: TodoLi,\n markerComponent: TodoMarker,\n type: 'todo',\n },\n },\n },\n }),\n LineHeightPlugin.extend({\n inject: {\n nodeProps: {\n defaultNodeValue: 1.5,\n validNodeValues: [1, 1.2, 1.5, 2, 3],\n },\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n ],\n },\n }),\n\n // Functionality\n AutoformatPlugin.configure({\n options: autoformatOptions,\n }),\n BlockSelectionPlugin.configure({\n options: {\n areaOptions: {\n behaviour: {\n scrolling: {\n speedDivider: 1.5,\n },\n startThreshold: 10,\n },\n boundaries: `#${scrollSelector}`,\n container: `#${scrollSelector}`,\n selectables: [`#${scrollSelector} .slate-selectable`],\n selectionAreaClass: 'slate-selection-area',\n },\n enableContextMenu: true,\n },\n }),\n BlockMenuPlugin.configure({\n render: { aboveEditable: BlockContextMenu },\n }),\n DndPlugin.configure({\n options: {\n enableScroller: true,\n onDropFiles: ({ dragItem, editor, target }) => {\n editor\n .getTransforms(ImagePlugin)\n .insertImageFromFiles(dragItem.files, {\n at: target,\n nextBlock: false,\n });\n },\n },\n }),\n EmojiPlugin,\n exitBreakPlugin,\n NodeIdPlugin,\n NormalizeTypesPlugin.configure({\n options: {\n rules: [{ path: [0], strictType: HEADING_KEYS.h1 }],\n },\n }),\n resetBlockTypePlugin,\n SelectOnBackspacePlugin.configure({\n options: {\n query: {\n allow: [ImagePlugin.key, HorizontalRulePlugin.key],\n },\n },\n }),\n DeletePlugin,\n SingleLinePlugin,\n softBreakPlugin,\n tabbablePlugin,\n TrailingBlockPlugin.configure({\n options: { type: ParagraphPlugin.key },\n }),\n DragOverCursorPlugin,\n\n // Collaboration\n CommentsPlugin.configure({\n options: {\n comments: commentsData,\n myUserId: '1',\n users: usersData,\n },\n }),\n\n // Deserialization\n DocxPlugin,\n MarkdownPlugin.configure({ options: { indentList: true } }),\n JuicePlugin,\n\n // Testing\n PlaywrightPlugin.configure({\n enabled: process.env.NODE_ENV !== 'production',\n }),\n ],\n value: value,\n },\n []\n );\n};\n\nexport default function PlaygroundDemo({\n id,\n className,\n scrollSelector,\n}: {\n id?: ValueId;\n className?: string;\n scrollSelector?: string;\n}) {\n const containerRef = useRef(null);\n const enabled = settingsStore.use.checkedComponents();\n\n const editor = usePlaygroundEditor(\n id,\n scrollSelector ?? `blockSelection-${id}`\n );\n\n return (\n \n \n \n \n \n \n \n \n \n\n
\n \n \n\n \n \n \n \n \n \n \n\n \n \n \n \n\n \n \n \n
\n
\n
\n );\n}\n\nconst DemoIdContext = React.createContext(undefined);\n\nexport function DemoId({\n id,\n children,\n}: {\n children: React.ReactNode;\n id?: string;\n}) {\n return {children};\n}\n\nexport function useDemoId() {\n return React.useContext(DemoIdContext);\n}\n", + "content": "'use client';\n\nimport React, { useRef } from 'react';\n\nimport type { ValueId } from '@/config/customizer-plugins';\n\nimport { cn } from '@udecode/cn';\nimport { AIChatPlugin, CopilotPlugin } from '@udecode/plate-ai/react';\nimport { AlignPlugin } from '@udecode/plate-alignment/react';\nimport { AutoformatPlugin } from '@udecode/plate-autoformat/react';\nimport {\n BoldPlugin,\n CodePlugin,\n ItalicPlugin,\n StrikethroughPlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n UnderlinePlugin,\n} from '@udecode/plate-basic-marks/react';\nimport { BlockquotePlugin } from '@udecode/plate-block-quote/react';\nimport { SingleLinePlugin } from '@udecode/plate-break/react';\nimport { CaptionPlugin } from '@udecode/plate-caption/react';\nimport { CodeBlockPlugin } from '@udecode/plate-code-block/react';\nimport { CommentsPlugin } from '@udecode/plate-comments/react';\nimport {\n ParagraphPlugin,\n Plate,\n usePlateEditor,\n} from '@udecode/plate-common/react';\nimport { DatePlugin } from '@udecode/plate-date/react';\nimport { DndPlugin } from '@udecode/plate-dnd';\nimport { DocxPlugin } from '@udecode/plate-docx';\nimport { EmojiPlugin } from '@udecode/plate-emoji/react';\nimport { ExcalidrawPlugin } from '@udecode/plate-excalidraw/react';\nimport {\n FontBackgroundColorPlugin,\n FontColorPlugin,\n FontSizePlugin,\n} from '@udecode/plate-font/react';\nimport { HEADING_KEYS } from '@udecode/plate-heading';\nimport { HeadingPlugin, TocPlugin } from '@udecode/plate-heading/react';\nimport { HighlightPlugin } from '@udecode/plate-highlight/react';\nimport { HorizontalRulePlugin } from '@udecode/plate-horizontal-rule/react';\nimport { IndentPlugin } from '@udecode/plate-indent/react';\nimport { IndentListPlugin } from '@udecode/plate-indent-list/react';\nimport { JuicePlugin } from '@udecode/plate-juice';\nimport { KbdPlugin } from '@udecode/plate-kbd/react';\nimport { ColumnPlugin } from '@udecode/plate-layout/react';\nimport { LineHeightPlugin } from '@udecode/plate-line-height/react';\nimport { LinkPlugin } from '@udecode/plate-link/react';\nimport { ListPlugin, TodoListPlugin } from '@udecode/plate-list/react';\nimport { MarkdownPlugin } from '@udecode/plate-markdown';\nimport { BaseImagePlugin } from '@udecode/plate-media';\nimport { ImagePlugin, MediaEmbedPlugin } from '@udecode/plate-media/react';\nimport { MentionPlugin } from '@udecode/plate-mention/react';\nimport { NodeIdPlugin } from '@udecode/plate-node-id';\nimport { NormalizeTypesPlugin } from '@udecode/plate-normalizers';\nimport { PlaywrightPlugin } from '@udecode/plate-playwright';\nimport { DeletePlugin, SelectOnBackspacePlugin } from '@udecode/plate-select';\nimport {\n BlockMenuPlugin,\n BlockSelectionPlugin,\n} from '@udecode/plate-selection/react';\nimport { SlashPlugin } from '@udecode/plate-slash-command/react';\nimport { TablePlugin } from '@udecode/plate-table/react';\nimport { TogglePlugin } from '@udecode/plate-toggle/react';\nimport { TrailingBlockPlugin } from '@udecode/plate-trailing-block';\nimport Prism from 'prismjs';\n\nimport { CheckPlugin } from '@/components/context/check-plugin';\nimport { settingsStore } from '@/components/context/settings-store';\nimport { aiPlugins } from '@/lib/plate/demo/plugins/ai-plugins';\nimport { getAutoformatOptions } from '@/lib/plate/demo/plugins/autoformatOptions';\nimport { copilotPlugins } from '@/lib/plate/demo/plugins/copilot-plugins';\nimport { createPlateUI } from '@/plate/create-plate-ui';\nimport { editableProps } from '@/plate/demo/editableProps';\nimport { isEnabled } from '@/plate/demo/is-enabled';\nimport { DragOverCursorPlugin } from '@/plate/demo/plugins/DragOverCursorPlugin';\nimport { exitBreakPlugin } from '@/plate/demo/plugins/exitBreakPlugin';\nimport { resetBlockTypePlugin } from '@/plate/demo/plugins/resetBlockTypePlugin';\nimport { softBreakPlugin } from '@/plate/demo/plugins/softBreakPlugin';\nimport { tabbablePlugin } from '@/plate/demo/plugins/tabbablePlugin';\nimport { commentsData, usersData } from '@/plate/demo/values/commentsValue';\nimport { usePlaygroundValue } from '@/plate/demo/values/usePlaygroundValue';\nimport { BlockContextMenu } from '@/components/plate-ui/block-context-menu';\nimport { CommentsPopover } from '@/components/plate-ui/comments-popover';\nimport {\n CursorOverlay,\n SelectionOverlayPlugin,\n} from '@/components/plate-ui/cursor-overlay';\nimport { Editor, EditorContainer } from '@/components/plate-ui/editor';\nimport { FixedToolbar } from '@/components/plate-ui/fixed-toolbar';\nimport { FixedToolbarButtons } from '@/components/plate-ui/fixed-toolbar-buttons';\nimport { FloatingToolbar } from '@/components/plate-ui/floating-toolbar';\nimport { FloatingToolbarButtons } from '@/components/plate-ui/floating-toolbar-buttons';\nimport { ImagePreview } from '@/components/plate-ui/image-preview';\nimport {\n FireLiComponent,\n FireMarker,\n} from '@/components/plate-ui/indent-fire-marker';\nimport {\n TodoLi,\n TodoMarker,\n} from '@/components/plate-ui/indent-todo-marker';\nimport { LinkFloatingToolbar } from '@/components/plate-ui/link-floating-toolbar';\n\nimport { usePlaygroundEnabled } from './usePlaygroundEnabled';\n\nexport const usePlaygroundEditor = (id: any = '', scrollSelector?: string) => {\n const enabledPlugins = settingsStore.use.checkedPlugins();\n const overridePlugins = usePlaygroundEnabled(id);\n const autoformatOptions = getAutoformatOptions(id, enabledPlugins);\n\n const value = usePlaygroundValue(id);\n const key = settingsStore.use.version();\n const editorId = id || 'playground-' + key;\n\n return usePlateEditor(\n {\n id: editorId,\n override: {\n components: createPlateUI({\n draggable: isEnabled('dnd', id),\n placeholder: isEnabled('placeholder', id),\n }),\n plugins: overridePlugins,\n },\n plugins: [\n // AI\n ...(id === 'ai' || enabledPlugins[AIChatPlugin.key] ? aiPlugins : []),\n ...(id === 'copilot' || enabledPlugins[CopilotPlugin.key]\n ? copilotPlugins\n : []),\n // Nodes\n HeadingPlugin,\n TocPlugin.configure({\n options: {\n scrollContainerSelector: `#${scrollSelector}`,\n topOffset: 80,\n },\n }),\n BlockquotePlugin,\n CodeBlockPlugin.configure({\n options: {\n prism: Prism,\n },\n }),\n HorizontalRulePlugin,\n LinkPlugin.extend({\n render: { afterEditable: () => },\n }),\n ...(id === 'list' ? [ListPlugin] : []),\n ImagePlugin.extend({\n options: {\n disableUploadInsert: true,\n },\n render: { afterEditable: ImagePreview },\n }),\n MediaEmbedPlugin,\n CaptionPlugin.configure({\n options: {\n plugins: [ImagePlugin, MediaEmbedPlugin],\n },\n }),\n DatePlugin,\n MentionPlugin.configure({\n options: {\n triggerPreviousCharPattern: /^$|^[\\s\"']$/,\n },\n }),\n SlashPlugin,\n TablePlugin.configure({\n options: {\n enableMerging: id === 'tableMerge',\n },\n }),\n ColumnPlugin,\n SelectionOverlayPlugin,\n\n TodoListPlugin,\n TogglePlugin,\n ExcalidrawPlugin,\n // Marks\n BoldPlugin,\n ItalicPlugin,\n UnderlinePlugin,\n StrikethroughPlugin,\n CodePlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n FontColorPlugin,\n FontBackgroundColorPlugin,\n FontSizePlugin,\n HighlightPlugin,\n KbdPlugin,\n\n // Block Style\n AlignPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n MediaEmbedPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n ImagePlugin.key,\n HEADING_KEYS.h6,\n ],\n },\n }),\n IndentPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n }),\n IndentListPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n options: {\n listStyleTypes: {\n fire: {\n liComponent: FireLiComponent,\n markerComponent: FireMarker,\n type: 'fire',\n },\n todo: {\n liComponent: TodoLi,\n markerComponent: TodoMarker,\n type: 'todo',\n },\n },\n },\n }),\n LineHeightPlugin.extend({\n inject: {\n nodeProps: {\n defaultNodeValue: 1.5,\n validNodeValues: [1, 1.2, 1.5, 2, 3],\n },\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n ],\n },\n }),\n\n // Functionality\n AutoformatPlugin.configure({\n options: autoformatOptions,\n }),\n BlockSelectionPlugin.configure({\n options: {\n areaOptions: {\n behaviour: {\n scrolling: {\n speedDivider: 1.5,\n },\n startThreshold: 10,\n },\n boundaries: `#${scrollSelector}`,\n container: `#${scrollSelector}`,\n selectables: [`#${scrollSelector} .slate-selectable`],\n selectionAreaClass: 'slate-selection-area',\n },\n enableContextMenu: true,\n },\n }),\n BlockMenuPlugin.configure({\n render: { aboveEditable: BlockContextMenu },\n }),\n DndPlugin.configure({\n options: {\n enableScroller: true,\n onDropFiles: ({ dragItem, editor, target }) => {\n editor\n .getTransforms(BaseImagePlugin)\n .insert.imageFromFiles(dragItem.files, {\n at: target,\n nextBlock: false,\n });\n },\n },\n }),\n EmojiPlugin,\n exitBreakPlugin,\n NodeIdPlugin,\n NormalizeTypesPlugin.configure({\n options: {\n rules: [{ path: [0], strictType: HEADING_KEYS.h1 }],\n },\n }),\n resetBlockTypePlugin,\n SelectOnBackspacePlugin.configure({\n options: {\n query: {\n allow: [ImagePlugin.key, HorizontalRulePlugin.key],\n },\n },\n }),\n DeletePlugin,\n SingleLinePlugin,\n softBreakPlugin,\n tabbablePlugin,\n TrailingBlockPlugin.configure({\n options: { type: ParagraphPlugin.key },\n }),\n DragOverCursorPlugin,\n\n // Collaboration\n CommentsPlugin.configure({\n options: {\n comments: commentsData,\n myUserId: '1',\n users: usersData,\n },\n }),\n\n // Deserialization\n DocxPlugin,\n MarkdownPlugin.configure({ options: { indentList: true } }),\n JuicePlugin,\n\n // Testing\n PlaywrightPlugin.configure({\n enabled: process.env.NODE_ENV !== 'production',\n }),\n ],\n value: value,\n },\n []\n );\n};\n\nexport default function PlaygroundDemo({\n id,\n className,\n scrollSelector,\n}: {\n id?: ValueId;\n className?: string;\n scrollSelector?: string;\n}) {\n const containerRef = useRef(null);\n const enabled = settingsStore.use.checkedComponents();\n\n const editor = usePlaygroundEditor(\n id,\n scrollSelector ?? `blockSelection-${id}`\n );\n\n return (\n \n \n \n \n \n \n \n \n \n\n
\n \n \n\n \n \n \n \n \n \n \n\n \n \n \n \n\n \n \n \n
\n
\n
\n );\n}\n\nconst DemoIdContext = React.createContext(undefined);\n\nexport function DemoId({\n id,\n children,\n}: {\n children: React.ReactNode;\n id?: string;\n}) {\n return {children};\n}\n\nexport function useDemoId() {\n return React.useContext(DemoIdContext);\n}\n", "path": "example/playground-demo.tsx", "target": "components/playground-demo.tsx", "type": "registry:example" diff --git a/apps/www/public/r/styles/default/line-height-demo.json b/apps/www/public/r/styles/default/line-height-demo.json index 01f209d824..1f04e4b158 100644 --- a/apps/www/public/r/styles/default/line-height-demo.json +++ b/apps/www/public/r/styles/default/line-height-demo.json @@ -4,7 +4,7 @@ }, "files": [ { - "content": "'use client';\n\nimport React, { useRef } from 'react';\n\nimport type { ValueId } from '@/config/customizer-plugins';\n\nimport { cn } from '@udecode/cn';\nimport { AIChatPlugin, CopilotPlugin } from '@udecode/plate-ai/react';\nimport { AlignPlugin } from '@udecode/plate-alignment/react';\nimport { AutoformatPlugin } from '@udecode/plate-autoformat/react';\nimport {\n BoldPlugin,\n CodePlugin,\n ItalicPlugin,\n StrikethroughPlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n UnderlinePlugin,\n} from '@udecode/plate-basic-marks/react';\nimport { BlockquotePlugin } from '@udecode/plate-block-quote/react';\nimport { SingleLinePlugin } from '@udecode/plate-break/react';\nimport { CaptionPlugin } from '@udecode/plate-caption/react';\nimport { CodeBlockPlugin } from '@udecode/plate-code-block/react';\nimport { CommentsPlugin } from '@udecode/plate-comments/react';\nimport {\n ParagraphPlugin,\n Plate,\n usePlateEditor,\n} from '@udecode/plate-common/react';\nimport { DatePlugin } from '@udecode/plate-date/react';\nimport { DndPlugin } from '@udecode/plate-dnd';\nimport { DocxPlugin } from '@udecode/plate-docx';\nimport { EmojiPlugin } from '@udecode/plate-emoji/react';\nimport { ExcalidrawPlugin } from '@udecode/plate-excalidraw/react';\nimport {\n FontBackgroundColorPlugin,\n FontColorPlugin,\n FontSizePlugin,\n} from '@udecode/plate-font/react';\nimport { HEADING_KEYS } from '@udecode/plate-heading';\nimport { HeadingPlugin, TocPlugin } from '@udecode/plate-heading/react';\nimport { HighlightPlugin } from '@udecode/plate-highlight/react';\nimport { HorizontalRulePlugin } from '@udecode/plate-horizontal-rule/react';\nimport { IndentPlugin } from '@udecode/plate-indent/react';\nimport { IndentListPlugin } from '@udecode/plate-indent-list/react';\nimport { JuicePlugin } from '@udecode/plate-juice';\nimport { KbdPlugin } from '@udecode/plate-kbd/react';\nimport { ColumnPlugin } from '@udecode/plate-layout/react';\nimport { LineHeightPlugin } from '@udecode/plate-line-height/react';\nimport { LinkPlugin } from '@udecode/plate-link/react';\nimport { ListPlugin, TodoListPlugin } from '@udecode/plate-list/react';\nimport { MarkdownPlugin } from '@udecode/plate-markdown';\nimport { ImagePlugin, MediaEmbedPlugin } from '@udecode/plate-media/react';\nimport { MentionPlugin } from '@udecode/plate-mention/react';\nimport { NodeIdPlugin } from '@udecode/plate-node-id';\nimport { NormalizeTypesPlugin } from '@udecode/plate-normalizers';\nimport { PlaywrightPlugin } from '@udecode/plate-playwright';\nimport { DeletePlugin, SelectOnBackspacePlugin } from '@udecode/plate-select';\nimport {\n BlockMenuPlugin,\n BlockSelectionPlugin,\n} from '@udecode/plate-selection/react';\nimport { SlashPlugin } from '@udecode/plate-slash-command/react';\nimport { TablePlugin } from '@udecode/plate-table/react';\nimport { TogglePlugin } from '@udecode/plate-toggle/react';\nimport { TrailingBlockPlugin } from '@udecode/plate-trailing-block';\nimport Prism from 'prismjs';\n\nimport { CheckPlugin } from '@/components/context/check-plugin';\nimport { settingsStore } from '@/components/context/settings-store';\nimport { aiPlugins } from '@/lib/plate/demo/plugins/ai-plugins';\nimport { getAutoformatOptions } from '@/lib/plate/demo/plugins/autoformatOptions';\nimport { copilotPlugins } from '@/lib/plate/demo/plugins/copilot-plugins';\nimport { createPlateUI } from '@/plate/create-plate-ui';\nimport { editableProps } from '@/plate/demo/editableProps';\nimport { isEnabled } from '@/plate/demo/is-enabled';\nimport { DragOverCursorPlugin } from '@/plate/demo/plugins/DragOverCursorPlugin';\nimport { exitBreakPlugin } from '@/plate/demo/plugins/exitBreakPlugin';\nimport { resetBlockTypePlugin } from '@/plate/demo/plugins/resetBlockTypePlugin';\nimport { softBreakPlugin } from '@/plate/demo/plugins/softBreakPlugin';\nimport { tabbablePlugin } from '@/plate/demo/plugins/tabbablePlugin';\nimport { commentsData, usersData } from '@/plate/demo/values/commentsValue';\nimport { usePlaygroundValue } from '@/plate/demo/values/usePlaygroundValue';\nimport { BlockContextMenu } from '@/components/plate-ui/block-context-menu';\nimport { CommentsPopover } from '@/components/plate-ui/comments-popover';\nimport {\n CursorOverlay,\n SelectionOverlayPlugin,\n} from '@/components/plate-ui/cursor-overlay';\nimport { Editor, EditorContainer } from '@/components/plate-ui/editor';\nimport { FixedToolbar } from '@/components/plate-ui/fixed-toolbar';\nimport { FixedToolbarButtons } from '@/components/plate-ui/fixed-toolbar-buttons';\nimport { FloatingToolbar } from '@/components/plate-ui/floating-toolbar';\nimport { FloatingToolbarButtons } from '@/components/plate-ui/floating-toolbar-buttons';\nimport { ImagePreview } from '@/components/plate-ui/image-preview';\nimport {\n FireLiComponent,\n FireMarker,\n} from '@/components/plate-ui/indent-fire-marker';\nimport {\n TodoLi,\n TodoMarker,\n} from '@/components/plate-ui/indent-todo-marker';\nimport { LinkFloatingToolbar } from '@/components/plate-ui/link-floating-toolbar';\n\nimport { usePlaygroundEnabled } from './usePlaygroundEnabled';\n\nexport const usePlaygroundEditor = (id: any = '', scrollSelector?: string) => {\n const enabledPlugins = settingsStore.use.checkedPlugins();\n const overridePlugins = usePlaygroundEnabled(id);\n const autoformatOptions = getAutoformatOptions(id, enabledPlugins);\n\n const value = usePlaygroundValue(id);\n const key = settingsStore.use.version();\n const editorId = id || 'playground-' + key;\n\n return usePlateEditor(\n {\n id: editorId,\n override: {\n components: createPlateUI({\n draggable: isEnabled('dnd', id),\n placeholder: isEnabled('placeholder', id),\n }),\n plugins: overridePlugins,\n },\n plugins: [\n // AI\n ...(id === 'ai' || enabledPlugins[AIChatPlugin.key] ? aiPlugins : []),\n ...(id === 'copilot' || enabledPlugins[CopilotPlugin.key]\n ? copilotPlugins\n : []),\n // Nodes\n HeadingPlugin,\n TocPlugin.configure({\n options: {\n scrollContainerSelector: `#${scrollSelector}`,\n topOffset: 80,\n },\n }),\n BlockquotePlugin,\n CodeBlockPlugin.configure({\n options: {\n prism: Prism,\n },\n }),\n HorizontalRulePlugin,\n LinkPlugin.extend({\n render: { afterEditable: () => },\n }),\n ...(id === 'list' ? [ListPlugin] : []),\n ImagePlugin.extend({\n options: {\n disableUploadInsert: true,\n },\n render: { afterEditable: ImagePreview },\n }),\n MediaEmbedPlugin,\n CaptionPlugin.configure({\n options: {\n plugins: [ImagePlugin, MediaEmbedPlugin],\n },\n }),\n DatePlugin,\n MentionPlugin.configure({\n options: {\n triggerPreviousCharPattern: /^$|^[\\s\"']$/,\n },\n }),\n SlashPlugin,\n TablePlugin.configure({\n options: {\n enableMerging: id === 'tableMerge',\n },\n }),\n ColumnPlugin,\n SelectionOverlayPlugin,\n\n TodoListPlugin,\n TogglePlugin,\n ExcalidrawPlugin,\n // Marks\n BoldPlugin,\n ItalicPlugin,\n UnderlinePlugin,\n StrikethroughPlugin,\n CodePlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n FontColorPlugin,\n FontBackgroundColorPlugin,\n FontSizePlugin,\n HighlightPlugin,\n KbdPlugin,\n\n // Block Style\n AlignPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n MediaEmbedPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n ImagePlugin.key,\n HEADING_KEYS.h6,\n ],\n },\n }),\n IndentPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n }),\n IndentListPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n options: {\n listStyleTypes: {\n fire: {\n liComponent: FireLiComponent,\n markerComponent: FireMarker,\n type: 'fire',\n },\n todo: {\n liComponent: TodoLi,\n markerComponent: TodoMarker,\n type: 'todo',\n },\n },\n },\n }),\n LineHeightPlugin.extend({\n inject: {\n nodeProps: {\n defaultNodeValue: 1.5,\n validNodeValues: [1, 1.2, 1.5, 2, 3],\n },\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n ],\n },\n }),\n\n // Functionality\n AutoformatPlugin.configure({\n options: autoformatOptions,\n }),\n BlockSelectionPlugin.configure({\n options: {\n areaOptions: {\n behaviour: {\n scrolling: {\n speedDivider: 1.5,\n },\n startThreshold: 10,\n },\n boundaries: `#${scrollSelector}`,\n container: `#${scrollSelector}`,\n selectables: [`#${scrollSelector} .slate-selectable`],\n selectionAreaClass: 'slate-selection-area',\n },\n enableContextMenu: true,\n },\n }),\n BlockMenuPlugin.configure({\n render: { aboveEditable: BlockContextMenu },\n }),\n DndPlugin.configure({\n options: {\n enableScroller: true,\n onDropFiles: ({ dragItem, editor, target }) => {\n editor\n .getTransforms(ImagePlugin)\n .insertImageFromFiles(dragItem.files, {\n at: target,\n nextBlock: false,\n });\n },\n },\n }),\n EmojiPlugin,\n exitBreakPlugin,\n NodeIdPlugin,\n NormalizeTypesPlugin.configure({\n options: {\n rules: [{ path: [0], strictType: HEADING_KEYS.h1 }],\n },\n }),\n resetBlockTypePlugin,\n SelectOnBackspacePlugin.configure({\n options: {\n query: {\n allow: [ImagePlugin.key, HorizontalRulePlugin.key],\n },\n },\n }),\n DeletePlugin,\n SingleLinePlugin,\n softBreakPlugin,\n tabbablePlugin,\n TrailingBlockPlugin.configure({\n options: { type: ParagraphPlugin.key },\n }),\n DragOverCursorPlugin,\n\n // Collaboration\n CommentsPlugin.configure({\n options: {\n comments: commentsData,\n myUserId: '1',\n users: usersData,\n },\n }),\n\n // Deserialization\n DocxPlugin,\n MarkdownPlugin.configure({ options: { indentList: true } }),\n JuicePlugin,\n\n // Testing\n PlaywrightPlugin.configure({\n enabled: process.env.NODE_ENV !== 'production',\n }),\n ],\n value: value,\n },\n []\n );\n};\n\nexport default function PlaygroundDemo({\n id,\n className,\n scrollSelector,\n}: {\n id?: ValueId;\n className?: string;\n scrollSelector?: string;\n}) {\n const containerRef = useRef(null);\n const enabled = settingsStore.use.checkedComponents();\n\n const editor = usePlaygroundEditor(\n id,\n scrollSelector ?? `blockSelection-${id}`\n );\n\n return (\n \n \n \n \n \n \n \n \n \n\n
\n \n \n\n \n \n \n \n \n \n \n\n \n \n \n \n\n \n \n \n
\n
\n
\n );\n}\n\nconst DemoIdContext = React.createContext(undefined);\n\nexport function DemoId({\n id,\n children,\n}: {\n children: React.ReactNode;\n id?: string;\n}) {\n return {children};\n}\n\nexport function useDemoId() {\n return React.useContext(DemoIdContext);\n}\n", + "content": "'use client';\n\nimport React, { useRef } from 'react';\n\nimport type { ValueId } from '@/config/customizer-plugins';\n\nimport { cn } from '@udecode/cn';\nimport { AIChatPlugin, CopilotPlugin } from '@udecode/plate-ai/react';\nimport { AlignPlugin } from '@udecode/plate-alignment/react';\nimport { AutoformatPlugin } from '@udecode/plate-autoformat/react';\nimport {\n BoldPlugin,\n CodePlugin,\n ItalicPlugin,\n StrikethroughPlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n UnderlinePlugin,\n} from '@udecode/plate-basic-marks/react';\nimport { BlockquotePlugin } from '@udecode/plate-block-quote/react';\nimport { SingleLinePlugin } from '@udecode/plate-break/react';\nimport { CaptionPlugin } from '@udecode/plate-caption/react';\nimport { CodeBlockPlugin } from '@udecode/plate-code-block/react';\nimport { CommentsPlugin } from '@udecode/plate-comments/react';\nimport {\n ParagraphPlugin,\n Plate,\n usePlateEditor,\n} from '@udecode/plate-common/react';\nimport { DatePlugin } from '@udecode/plate-date/react';\nimport { DndPlugin } from '@udecode/plate-dnd';\nimport { DocxPlugin } from '@udecode/plate-docx';\nimport { EmojiPlugin } from '@udecode/plate-emoji/react';\nimport { ExcalidrawPlugin } from '@udecode/plate-excalidraw/react';\nimport {\n FontBackgroundColorPlugin,\n FontColorPlugin,\n FontSizePlugin,\n} from '@udecode/plate-font/react';\nimport { HEADING_KEYS } from '@udecode/plate-heading';\nimport { HeadingPlugin, TocPlugin } from '@udecode/plate-heading/react';\nimport { HighlightPlugin } from '@udecode/plate-highlight/react';\nimport { HorizontalRulePlugin } from '@udecode/plate-horizontal-rule/react';\nimport { IndentPlugin } from '@udecode/plate-indent/react';\nimport { IndentListPlugin } from '@udecode/plate-indent-list/react';\nimport { JuicePlugin } from '@udecode/plate-juice';\nimport { KbdPlugin } from '@udecode/plate-kbd/react';\nimport { ColumnPlugin } from '@udecode/plate-layout/react';\nimport { LineHeightPlugin } from '@udecode/plate-line-height/react';\nimport { LinkPlugin } from '@udecode/plate-link/react';\nimport { ListPlugin, TodoListPlugin } from '@udecode/plate-list/react';\nimport { MarkdownPlugin } from '@udecode/plate-markdown';\nimport { BaseImagePlugin } from '@udecode/plate-media';\nimport { ImagePlugin, MediaEmbedPlugin } from '@udecode/plate-media/react';\nimport { MentionPlugin } from '@udecode/plate-mention/react';\nimport { NodeIdPlugin } from '@udecode/plate-node-id';\nimport { NormalizeTypesPlugin } from '@udecode/plate-normalizers';\nimport { PlaywrightPlugin } from '@udecode/plate-playwright';\nimport { DeletePlugin, SelectOnBackspacePlugin } from '@udecode/plate-select';\nimport {\n BlockMenuPlugin,\n BlockSelectionPlugin,\n} from '@udecode/plate-selection/react';\nimport { SlashPlugin } from '@udecode/plate-slash-command/react';\nimport { TablePlugin } from '@udecode/plate-table/react';\nimport { TogglePlugin } from '@udecode/plate-toggle/react';\nimport { TrailingBlockPlugin } from '@udecode/plate-trailing-block';\nimport Prism from 'prismjs';\n\nimport { CheckPlugin } from '@/components/context/check-plugin';\nimport { settingsStore } from '@/components/context/settings-store';\nimport { aiPlugins } from '@/lib/plate/demo/plugins/ai-plugins';\nimport { getAutoformatOptions } from '@/lib/plate/demo/plugins/autoformatOptions';\nimport { copilotPlugins } from '@/lib/plate/demo/plugins/copilot-plugins';\nimport { createPlateUI } from '@/plate/create-plate-ui';\nimport { editableProps } from '@/plate/demo/editableProps';\nimport { isEnabled } from '@/plate/demo/is-enabled';\nimport { DragOverCursorPlugin } from '@/plate/demo/plugins/DragOverCursorPlugin';\nimport { exitBreakPlugin } from '@/plate/demo/plugins/exitBreakPlugin';\nimport { resetBlockTypePlugin } from '@/plate/demo/plugins/resetBlockTypePlugin';\nimport { softBreakPlugin } from '@/plate/demo/plugins/softBreakPlugin';\nimport { tabbablePlugin } from '@/plate/demo/plugins/tabbablePlugin';\nimport { commentsData, usersData } from '@/plate/demo/values/commentsValue';\nimport { usePlaygroundValue } from '@/plate/demo/values/usePlaygroundValue';\nimport { BlockContextMenu } from '@/components/plate-ui/block-context-menu';\nimport { CommentsPopover } from '@/components/plate-ui/comments-popover';\nimport {\n CursorOverlay,\n SelectionOverlayPlugin,\n} from '@/components/plate-ui/cursor-overlay';\nimport { Editor, EditorContainer } from '@/components/plate-ui/editor';\nimport { FixedToolbar } from '@/components/plate-ui/fixed-toolbar';\nimport { FixedToolbarButtons } from '@/components/plate-ui/fixed-toolbar-buttons';\nimport { FloatingToolbar } from '@/components/plate-ui/floating-toolbar';\nimport { FloatingToolbarButtons } from '@/components/plate-ui/floating-toolbar-buttons';\nimport { ImagePreview } from '@/components/plate-ui/image-preview';\nimport {\n FireLiComponent,\n FireMarker,\n} from '@/components/plate-ui/indent-fire-marker';\nimport {\n TodoLi,\n TodoMarker,\n} from '@/components/plate-ui/indent-todo-marker';\nimport { LinkFloatingToolbar } from '@/components/plate-ui/link-floating-toolbar';\n\nimport { usePlaygroundEnabled } from './usePlaygroundEnabled';\n\nexport const usePlaygroundEditor = (id: any = '', scrollSelector?: string) => {\n const enabledPlugins = settingsStore.use.checkedPlugins();\n const overridePlugins = usePlaygroundEnabled(id);\n const autoformatOptions = getAutoformatOptions(id, enabledPlugins);\n\n const value = usePlaygroundValue(id);\n const key = settingsStore.use.version();\n const editorId = id || 'playground-' + key;\n\n return usePlateEditor(\n {\n id: editorId,\n override: {\n components: createPlateUI({\n draggable: isEnabled('dnd', id),\n placeholder: isEnabled('placeholder', id),\n }),\n plugins: overridePlugins,\n },\n plugins: [\n // AI\n ...(id === 'ai' || enabledPlugins[AIChatPlugin.key] ? aiPlugins : []),\n ...(id === 'copilot' || enabledPlugins[CopilotPlugin.key]\n ? copilotPlugins\n : []),\n // Nodes\n HeadingPlugin,\n TocPlugin.configure({\n options: {\n scrollContainerSelector: `#${scrollSelector}`,\n topOffset: 80,\n },\n }),\n BlockquotePlugin,\n CodeBlockPlugin.configure({\n options: {\n prism: Prism,\n },\n }),\n HorizontalRulePlugin,\n LinkPlugin.extend({\n render: { afterEditable: () => },\n }),\n ...(id === 'list' ? [ListPlugin] : []),\n ImagePlugin.extend({\n options: {\n disableUploadInsert: true,\n },\n render: { afterEditable: ImagePreview },\n }),\n MediaEmbedPlugin,\n CaptionPlugin.configure({\n options: {\n plugins: [ImagePlugin, MediaEmbedPlugin],\n },\n }),\n DatePlugin,\n MentionPlugin.configure({\n options: {\n triggerPreviousCharPattern: /^$|^[\\s\"']$/,\n },\n }),\n SlashPlugin,\n TablePlugin.configure({\n options: {\n enableMerging: id === 'tableMerge',\n },\n }),\n ColumnPlugin,\n SelectionOverlayPlugin,\n\n TodoListPlugin,\n TogglePlugin,\n ExcalidrawPlugin,\n // Marks\n BoldPlugin,\n ItalicPlugin,\n UnderlinePlugin,\n StrikethroughPlugin,\n CodePlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n FontColorPlugin,\n FontBackgroundColorPlugin,\n FontSizePlugin,\n HighlightPlugin,\n KbdPlugin,\n\n // Block Style\n AlignPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n MediaEmbedPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n ImagePlugin.key,\n HEADING_KEYS.h6,\n ],\n },\n }),\n IndentPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n }),\n IndentListPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n options: {\n listStyleTypes: {\n fire: {\n liComponent: FireLiComponent,\n markerComponent: FireMarker,\n type: 'fire',\n },\n todo: {\n liComponent: TodoLi,\n markerComponent: TodoMarker,\n type: 'todo',\n },\n },\n },\n }),\n LineHeightPlugin.extend({\n inject: {\n nodeProps: {\n defaultNodeValue: 1.5,\n validNodeValues: [1, 1.2, 1.5, 2, 3],\n },\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n ],\n },\n }),\n\n // Functionality\n AutoformatPlugin.configure({\n options: autoformatOptions,\n }),\n BlockSelectionPlugin.configure({\n options: {\n areaOptions: {\n behaviour: {\n scrolling: {\n speedDivider: 1.5,\n },\n startThreshold: 10,\n },\n boundaries: `#${scrollSelector}`,\n container: `#${scrollSelector}`,\n selectables: [`#${scrollSelector} .slate-selectable`],\n selectionAreaClass: 'slate-selection-area',\n },\n enableContextMenu: true,\n },\n }),\n BlockMenuPlugin.configure({\n render: { aboveEditable: BlockContextMenu },\n }),\n DndPlugin.configure({\n options: {\n enableScroller: true,\n onDropFiles: ({ dragItem, editor, target }) => {\n editor\n .getTransforms(BaseImagePlugin)\n .insert.imageFromFiles(dragItem.files, {\n at: target,\n nextBlock: false,\n });\n },\n },\n }),\n EmojiPlugin,\n exitBreakPlugin,\n NodeIdPlugin,\n NormalizeTypesPlugin.configure({\n options: {\n rules: [{ path: [0], strictType: HEADING_KEYS.h1 }],\n },\n }),\n resetBlockTypePlugin,\n SelectOnBackspacePlugin.configure({\n options: {\n query: {\n allow: [ImagePlugin.key, HorizontalRulePlugin.key],\n },\n },\n }),\n DeletePlugin,\n SingleLinePlugin,\n softBreakPlugin,\n tabbablePlugin,\n TrailingBlockPlugin.configure({\n options: { type: ParagraphPlugin.key },\n }),\n DragOverCursorPlugin,\n\n // Collaboration\n CommentsPlugin.configure({\n options: {\n comments: commentsData,\n myUserId: '1',\n users: usersData,\n },\n }),\n\n // Deserialization\n DocxPlugin,\n MarkdownPlugin.configure({ options: { indentList: true } }),\n JuicePlugin,\n\n // Testing\n PlaywrightPlugin.configure({\n enabled: process.env.NODE_ENV !== 'production',\n }),\n ],\n value: value,\n },\n []\n );\n};\n\nexport default function PlaygroundDemo({\n id,\n className,\n scrollSelector,\n}: {\n id?: ValueId;\n className?: string;\n scrollSelector?: string;\n}) {\n const containerRef = useRef(null);\n const enabled = settingsStore.use.checkedComponents();\n\n const editor = usePlaygroundEditor(\n id,\n scrollSelector ?? `blockSelection-${id}`\n );\n\n return (\n \n \n \n \n \n \n \n \n \n\n
\n \n \n\n \n \n \n \n \n \n \n\n \n \n \n \n\n \n \n \n
\n
\n
\n );\n}\n\nconst DemoIdContext = React.createContext(undefined);\n\nexport function DemoId({\n id,\n children,\n}: {\n children: React.ReactNode;\n id?: string;\n}) {\n return {children};\n}\n\nexport function useDemoId() {\n return React.useContext(DemoIdContext);\n}\n", "path": "example/playground-demo.tsx", "target": "components/playground-demo.tsx", "type": "registry:example" diff --git a/apps/www/public/r/styles/default/link-demo.json b/apps/www/public/r/styles/default/link-demo.json index b3f619f9e8..95caf0998c 100644 --- a/apps/www/public/r/styles/default/link-demo.json +++ b/apps/www/public/r/styles/default/link-demo.json @@ -4,7 +4,7 @@ }, "files": [ { - "content": "'use client';\n\nimport React, { useRef } from 'react';\n\nimport type { ValueId } from '@/config/customizer-plugins';\n\nimport { cn } from '@udecode/cn';\nimport { AIChatPlugin, CopilotPlugin } from '@udecode/plate-ai/react';\nimport { AlignPlugin } from '@udecode/plate-alignment/react';\nimport { AutoformatPlugin } from '@udecode/plate-autoformat/react';\nimport {\n BoldPlugin,\n CodePlugin,\n ItalicPlugin,\n StrikethroughPlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n UnderlinePlugin,\n} from '@udecode/plate-basic-marks/react';\nimport { BlockquotePlugin } from '@udecode/plate-block-quote/react';\nimport { SingleLinePlugin } from '@udecode/plate-break/react';\nimport { CaptionPlugin } from '@udecode/plate-caption/react';\nimport { CodeBlockPlugin } from '@udecode/plate-code-block/react';\nimport { CommentsPlugin } from '@udecode/plate-comments/react';\nimport {\n ParagraphPlugin,\n Plate,\n usePlateEditor,\n} from '@udecode/plate-common/react';\nimport { DatePlugin } from '@udecode/plate-date/react';\nimport { DndPlugin } from '@udecode/plate-dnd';\nimport { DocxPlugin } from '@udecode/plate-docx';\nimport { EmojiPlugin } from '@udecode/plate-emoji/react';\nimport { ExcalidrawPlugin } from '@udecode/plate-excalidraw/react';\nimport {\n FontBackgroundColorPlugin,\n FontColorPlugin,\n FontSizePlugin,\n} from '@udecode/plate-font/react';\nimport { HEADING_KEYS } from '@udecode/plate-heading';\nimport { HeadingPlugin, TocPlugin } from '@udecode/plate-heading/react';\nimport { HighlightPlugin } from '@udecode/plate-highlight/react';\nimport { HorizontalRulePlugin } from '@udecode/plate-horizontal-rule/react';\nimport { IndentPlugin } from '@udecode/plate-indent/react';\nimport { IndentListPlugin } from '@udecode/plate-indent-list/react';\nimport { JuicePlugin } from '@udecode/plate-juice';\nimport { KbdPlugin } from '@udecode/plate-kbd/react';\nimport { ColumnPlugin } from '@udecode/plate-layout/react';\nimport { LineHeightPlugin } from '@udecode/plate-line-height/react';\nimport { LinkPlugin } from '@udecode/plate-link/react';\nimport { ListPlugin, TodoListPlugin } from '@udecode/plate-list/react';\nimport { MarkdownPlugin } from '@udecode/plate-markdown';\nimport { ImagePlugin, MediaEmbedPlugin } from '@udecode/plate-media/react';\nimport { MentionPlugin } from '@udecode/plate-mention/react';\nimport { NodeIdPlugin } from '@udecode/plate-node-id';\nimport { NormalizeTypesPlugin } from '@udecode/plate-normalizers';\nimport { PlaywrightPlugin } from '@udecode/plate-playwright';\nimport { DeletePlugin, SelectOnBackspacePlugin } from '@udecode/plate-select';\nimport {\n BlockMenuPlugin,\n BlockSelectionPlugin,\n} from '@udecode/plate-selection/react';\nimport { SlashPlugin } from '@udecode/plate-slash-command/react';\nimport { TablePlugin } from '@udecode/plate-table/react';\nimport { TogglePlugin } from '@udecode/plate-toggle/react';\nimport { TrailingBlockPlugin } from '@udecode/plate-trailing-block';\nimport Prism from 'prismjs';\n\nimport { CheckPlugin } from '@/components/context/check-plugin';\nimport { settingsStore } from '@/components/context/settings-store';\nimport { aiPlugins } from '@/lib/plate/demo/plugins/ai-plugins';\nimport { getAutoformatOptions } from '@/lib/plate/demo/plugins/autoformatOptions';\nimport { copilotPlugins } from '@/lib/plate/demo/plugins/copilot-plugins';\nimport { createPlateUI } from '@/plate/create-plate-ui';\nimport { editableProps } from '@/plate/demo/editableProps';\nimport { isEnabled } from '@/plate/demo/is-enabled';\nimport { DragOverCursorPlugin } from '@/plate/demo/plugins/DragOverCursorPlugin';\nimport { exitBreakPlugin } from '@/plate/demo/plugins/exitBreakPlugin';\nimport { resetBlockTypePlugin } from '@/plate/demo/plugins/resetBlockTypePlugin';\nimport { softBreakPlugin } from '@/plate/demo/plugins/softBreakPlugin';\nimport { tabbablePlugin } from '@/plate/demo/plugins/tabbablePlugin';\nimport { commentsData, usersData } from '@/plate/demo/values/commentsValue';\nimport { usePlaygroundValue } from '@/plate/demo/values/usePlaygroundValue';\nimport { BlockContextMenu } from '@/components/plate-ui/block-context-menu';\nimport { CommentsPopover } from '@/components/plate-ui/comments-popover';\nimport {\n CursorOverlay,\n SelectionOverlayPlugin,\n} from '@/components/plate-ui/cursor-overlay';\nimport { Editor, EditorContainer } from '@/components/plate-ui/editor';\nimport { FixedToolbar } from '@/components/plate-ui/fixed-toolbar';\nimport { FixedToolbarButtons } from '@/components/plate-ui/fixed-toolbar-buttons';\nimport { FloatingToolbar } from '@/components/plate-ui/floating-toolbar';\nimport { FloatingToolbarButtons } from '@/components/plate-ui/floating-toolbar-buttons';\nimport { ImagePreview } from '@/components/plate-ui/image-preview';\nimport {\n FireLiComponent,\n FireMarker,\n} from '@/components/plate-ui/indent-fire-marker';\nimport {\n TodoLi,\n TodoMarker,\n} from '@/components/plate-ui/indent-todo-marker';\nimport { LinkFloatingToolbar } from '@/components/plate-ui/link-floating-toolbar';\n\nimport { usePlaygroundEnabled } from './usePlaygroundEnabled';\n\nexport const usePlaygroundEditor = (id: any = '', scrollSelector?: string) => {\n const enabledPlugins = settingsStore.use.checkedPlugins();\n const overridePlugins = usePlaygroundEnabled(id);\n const autoformatOptions = getAutoformatOptions(id, enabledPlugins);\n\n const value = usePlaygroundValue(id);\n const key = settingsStore.use.version();\n const editorId = id || 'playground-' + key;\n\n return usePlateEditor(\n {\n id: editorId,\n override: {\n components: createPlateUI({\n draggable: isEnabled('dnd', id),\n placeholder: isEnabled('placeholder', id),\n }),\n plugins: overridePlugins,\n },\n plugins: [\n // AI\n ...(id === 'ai' || enabledPlugins[AIChatPlugin.key] ? aiPlugins : []),\n ...(id === 'copilot' || enabledPlugins[CopilotPlugin.key]\n ? copilotPlugins\n : []),\n // Nodes\n HeadingPlugin,\n TocPlugin.configure({\n options: {\n scrollContainerSelector: `#${scrollSelector}`,\n topOffset: 80,\n },\n }),\n BlockquotePlugin,\n CodeBlockPlugin.configure({\n options: {\n prism: Prism,\n },\n }),\n HorizontalRulePlugin,\n LinkPlugin.extend({\n render: { afterEditable: () => },\n }),\n ...(id === 'list' ? [ListPlugin] : []),\n ImagePlugin.extend({\n options: {\n disableUploadInsert: true,\n },\n render: { afterEditable: ImagePreview },\n }),\n MediaEmbedPlugin,\n CaptionPlugin.configure({\n options: {\n plugins: [ImagePlugin, MediaEmbedPlugin],\n },\n }),\n DatePlugin,\n MentionPlugin.configure({\n options: {\n triggerPreviousCharPattern: /^$|^[\\s\"']$/,\n },\n }),\n SlashPlugin,\n TablePlugin.configure({\n options: {\n enableMerging: id === 'tableMerge',\n },\n }),\n ColumnPlugin,\n SelectionOverlayPlugin,\n\n TodoListPlugin,\n TogglePlugin,\n ExcalidrawPlugin,\n // Marks\n BoldPlugin,\n ItalicPlugin,\n UnderlinePlugin,\n StrikethroughPlugin,\n CodePlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n FontColorPlugin,\n FontBackgroundColorPlugin,\n FontSizePlugin,\n HighlightPlugin,\n KbdPlugin,\n\n // Block Style\n AlignPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n MediaEmbedPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n ImagePlugin.key,\n HEADING_KEYS.h6,\n ],\n },\n }),\n IndentPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n }),\n IndentListPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n options: {\n listStyleTypes: {\n fire: {\n liComponent: FireLiComponent,\n markerComponent: FireMarker,\n type: 'fire',\n },\n todo: {\n liComponent: TodoLi,\n markerComponent: TodoMarker,\n type: 'todo',\n },\n },\n },\n }),\n LineHeightPlugin.extend({\n inject: {\n nodeProps: {\n defaultNodeValue: 1.5,\n validNodeValues: [1, 1.2, 1.5, 2, 3],\n },\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n ],\n },\n }),\n\n // Functionality\n AutoformatPlugin.configure({\n options: autoformatOptions,\n }),\n BlockSelectionPlugin.configure({\n options: {\n areaOptions: {\n behaviour: {\n scrolling: {\n speedDivider: 1.5,\n },\n startThreshold: 10,\n },\n boundaries: `#${scrollSelector}`,\n container: `#${scrollSelector}`,\n selectables: [`#${scrollSelector} .slate-selectable`],\n selectionAreaClass: 'slate-selection-area',\n },\n enableContextMenu: true,\n },\n }),\n BlockMenuPlugin.configure({\n render: { aboveEditable: BlockContextMenu },\n }),\n DndPlugin.configure({\n options: {\n enableScroller: true,\n onDropFiles: ({ dragItem, editor, target }) => {\n editor\n .getTransforms(ImagePlugin)\n .insertImageFromFiles(dragItem.files, {\n at: target,\n nextBlock: false,\n });\n },\n },\n }),\n EmojiPlugin,\n exitBreakPlugin,\n NodeIdPlugin,\n NormalizeTypesPlugin.configure({\n options: {\n rules: [{ path: [0], strictType: HEADING_KEYS.h1 }],\n },\n }),\n resetBlockTypePlugin,\n SelectOnBackspacePlugin.configure({\n options: {\n query: {\n allow: [ImagePlugin.key, HorizontalRulePlugin.key],\n },\n },\n }),\n DeletePlugin,\n SingleLinePlugin,\n softBreakPlugin,\n tabbablePlugin,\n TrailingBlockPlugin.configure({\n options: { type: ParagraphPlugin.key },\n }),\n DragOverCursorPlugin,\n\n // Collaboration\n CommentsPlugin.configure({\n options: {\n comments: commentsData,\n myUserId: '1',\n users: usersData,\n },\n }),\n\n // Deserialization\n DocxPlugin,\n MarkdownPlugin.configure({ options: { indentList: true } }),\n JuicePlugin,\n\n // Testing\n PlaywrightPlugin.configure({\n enabled: process.env.NODE_ENV !== 'production',\n }),\n ],\n value: value,\n },\n []\n );\n};\n\nexport default function PlaygroundDemo({\n id,\n className,\n scrollSelector,\n}: {\n id?: ValueId;\n className?: string;\n scrollSelector?: string;\n}) {\n const containerRef = useRef(null);\n const enabled = settingsStore.use.checkedComponents();\n\n const editor = usePlaygroundEditor(\n id,\n scrollSelector ?? `blockSelection-${id}`\n );\n\n return (\n \n \n \n \n \n \n \n \n \n\n
\n \n \n\n \n \n \n \n \n \n \n\n \n \n \n \n\n \n \n \n
\n
\n
\n );\n}\n\nconst DemoIdContext = React.createContext(undefined);\n\nexport function DemoId({\n id,\n children,\n}: {\n children: React.ReactNode;\n id?: string;\n}) {\n return {children};\n}\n\nexport function useDemoId() {\n return React.useContext(DemoIdContext);\n}\n", + "content": "'use client';\n\nimport React, { useRef } from 'react';\n\nimport type { ValueId } from '@/config/customizer-plugins';\n\nimport { cn } from '@udecode/cn';\nimport { AIChatPlugin, CopilotPlugin } from '@udecode/plate-ai/react';\nimport { AlignPlugin } from '@udecode/plate-alignment/react';\nimport { AutoformatPlugin } from '@udecode/plate-autoformat/react';\nimport {\n BoldPlugin,\n CodePlugin,\n ItalicPlugin,\n StrikethroughPlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n UnderlinePlugin,\n} from '@udecode/plate-basic-marks/react';\nimport { BlockquotePlugin } from '@udecode/plate-block-quote/react';\nimport { SingleLinePlugin } from '@udecode/plate-break/react';\nimport { CaptionPlugin } from '@udecode/plate-caption/react';\nimport { CodeBlockPlugin } from '@udecode/plate-code-block/react';\nimport { CommentsPlugin } from '@udecode/plate-comments/react';\nimport {\n ParagraphPlugin,\n Plate,\n usePlateEditor,\n} from '@udecode/plate-common/react';\nimport { DatePlugin } from '@udecode/plate-date/react';\nimport { DndPlugin } from '@udecode/plate-dnd';\nimport { DocxPlugin } from '@udecode/plate-docx';\nimport { EmojiPlugin } from '@udecode/plate-emoji/react';\nimport { ExcalidrawPlugin } from '@udecode/plate-excalidraw/react';\nimport {\n FontBackgroundColorPlugin,\n FontColorPlugin,\n FontSizePlugin,\n} from '@udecode/plate-font/react';\nimport { HEADING_KEYS } from '@udecode/plate-heading';\nimport { HeadingPlugin, TocPlugin } from '@udecode/plate-heading/react';\nimport { HighlightPlugin } from '@udecode/plate-highlight/react';\nimport { HorizontalRulePlugin } from '@udecode/plate-horizontal-rule/react';\nimport { IndentPlugin } from '@udecode/plate-indent/react';\nimport { IndentListPlugin } from '@udecode/plate-indent-list/react';\nimport { JuicePlugin } from '@udecode/plate-juice';\nimport { KbdPlugin } from '@udecode/plate-kbd/react';\nimport { ColumnPlugin } from '@udecode/plate-layout/react';\nimport { LineHeightPlugin } from '@udecode/plate-line-height/react';\nimport { LinkPlugin } from '@udecode/plate-link/react';\nimport { ListPlugin, TodoListPlugin } from '@udecode/plate-list/react';\nimport { MarkdownPlugin } from '@udecode/plate-markdown';\nimport { BaseImagePlugin } from '@udecode/plate-media';\nimport { ImagePlugin, MediaEmbedPlugin } from '@udecode/plate-media/react';\nimport { MentionPlugin } from '@udecode/plate-mention/react';\nimport { NodeIdPlugin } from '@udecode/plate-node-id';\nimport { NormalizeTypesPlugin } from '@udecode/plate-normalizers';\nimport { PlaywrightPlugin } from '@udecode/plate-playwright';\nimport { DeletePlugin, SelectOnBackspacePlugin } from '@udecode/plate-select';\nimport {\n BlockMenuPlugin,\n BlockSelectionPlugin,\n} from '@udecode/plate-selection/react';\nimport { SlashPlugin } from '@udecode/plate-slash-command/react';\nimport { TablePlugin } from '@udecode/plate-table/react';\nimport { TogglePlugin } from '@udecode/plate-toggle/react';\nimport { TrailingBlockPlugin } from '@udecode/plate-trailing-block';\nimport Prism from 'prismjs';\n\nimport { CheckPlugin } from '@/components/context/check-plugin';\nimport { settingsStore } from '@/components/context/settings-store';\nimport { aiPlugins } from '@/lib/plate/demo/plugins/ai-plugins';\nimport { getAutoformatOptions } from '@/lib/plate/demo/plugins/autoformatOptions';\nimport { copilotPlugins } from '@/lib/plate/demo/plugins/copilot-plugins';\nimport { createPlateUI } from '@/plate/create-plate-ui';\nimport { editableProps } from '@/plate/demo/editableProps';\nimport { isEnabled } from '@/plate/demo/is-enabled';\nimport { DragOverCursorPlugin } from '@/plate/demo/plugins/DragOverCursorPlugin';\nimport { exitBreakPlugin } from '@/plate/demo/plugins/exitBreakPlugin';\nimport { resetBlockTypePlugin } from '@/plate/demo/plugins/resetBlockTypePlugin';\nimport { softBreakPlugin } from '@/plate/demo/plugins/softBreakPlugin';\nimport { tabbablePlugin } from '@/plate/demo/plugins/tabbablePlugin';\nimport { commentsData, usersData } from '@/plate/demo/values/commentsValue';\nimport { usePlaygroundValue } from '@/plate/demo/values/usePlaygroundValue';\nimport { BlockContextMenu } from '@/components/plate-ui/block-context-menu';\nimport { CommentsPopover } from '@/components/plate-ui/comments-popover';\nimport {\n CursorOverlay,\n SelectionOverlayPlugin,\n} from '@/components/plate-ui/cursor-overlay';\nimport { Editor, EditorContainer } from '@/components/plate-ui/editor';\nimport { FixedToolbar } from '@/components/plate-ui/fixed-toolbar';\nimport { FixedToolbarButtons } from '@/components/plate-ui/fixed-toolbar-buttons';\nimport { FloatingToolbar } from '@/components/plate-ui/floating-toolbar';\nimport { FloatingToolbarButtons } from '@/components/plate-ui/floating-toolbar-buttons';\nimport { ImagePreview } from '@/components/plate-ui/image-preview';\nimport {\n FireLiComponent,\n FireMarker,\n} from '@/components/plate-ui/indent-fire-marker';\nimport {\n TodoLi,\n TodoMarker,\n} from '@/components/plate-ui/indent-todo-marker';\nimport { LinkFloatingToolbar } from '@/components/plate-ui/link-floating-toolbar';\n\nimport { usePlaygroundEnabled } from './usePlaygroundEnabled';\n\nexport const usePlaygroundEditor = (id: any = '', scrollSelector?: string) => {\n const enabledPlugins = settingsStore.use.checkedPlugins();\n const overridePlugins = usePlaygroundEnabled(id);\n const autoformatOptions = getAutoformatOptions(id, enabledPlugins);\n\n const value = usePlaygroundValue(id);\n const key = settingsStore.use.version();\n const editorId = id || 'playground-' + key;\n\n return usePlateEditor(\n {\n id: editorId,\n override: {\n components: createPlateUI({\n draggable: isEnabled('dnd', id),\n placeholder: isEnabled('placeholder', id),\n }),\n plugins: overridePlugins,\n },\n plugins: [\n // AI\n ...(id === 'ai' || enabledPlugins[AIChatPlugin.key] ? aiPlugins : []),\n ...(id === 'copilot' || enabledPlugins[CopilotPlugin.key]\n ? copilotPlugins\n : []),\n // Nodes\n HeadingPlugin,\n TocPlugin.configure({\n options: {\n scrollContainerSelector: `#${scrollSelector}`,\n topOffset: 80,\n },\n }),\n BlockquotePlugin,\n CodeBlockPlugin.configure({\n options: {\n prism: Prism,\n },\n }),\n HorizontalRulePlugin,\n LinkPlugin.extend({\n render: { afterEditable: () => },\n }),\n ...(id === 'list' ? [ListPlugin] : []),\n ImagePlugin.extend({\n options: {\n disableUploadInsert: true,\n },\n render: { afterEditable: ImagePreview },\n }),\n MediaEmbedPlugin,\n CaptionPlugin.configure({\n options: {\n plugins: [ImagePlugin, MediaEmbedPlugin],\n },\n }),\n DatePlugin,\n MentionPlugin.configure({\n options: {\n triggerPreviousCharPattern: /^$|^[\\s\"']$/,\n },\n }),\n SlashPlugin,\n TablePlugin.configure({\n options: {\n enableMerging: id === 'tableMerge',\n },\n }),\n ColumnPlugin,\n SelectionOverlayPlugin,\n\n TodoListPlugin,\n TogglePlugin,\n ExcalidrawPlugin,\n // Marks\n BoldPlugin,\n ItalicPlugin,\n UnderlinePlugin,\n StrikethroughPlugin,\n CodePlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n FontColorPlugin,\n FontBackgroundColorPlugin,\n FontSizePlugin,\n HighlightPlugin,\n KbdPlugin,\n\n // Block Style\n AlignPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n MediaEmbedPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n ImagePlugin.key,\n HEADING_KEYS.h6,\n ],\n },\n }),\n IndentPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n }),\n IndentListPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n options: {\n listStyleTypes: {\n fire: {\n liComponent: FireLiComponent,\n markerComponent: FireMarker,\n type: 'fire',\n },\n todo: {\n liComponent: TodoLi,\n markerComponent: TodoMarker,\n type: 'todo',\n },\n },\n },\n }),\n LineHeightPlugin.extend({\n inject: {\n nodeProps: {\n defaultNodeValue: 1.5,\n validNodeValues: [1, 1.2, 1.5, 2, 3],\n },\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n ],\n },\n }),\n\n // Functionality\n AutoformatPlugin.configure({\n options: autoformatOptions,\n }),\n BlockSelectionPlugin.configure({\n options: {\n areaOptions: {\n behaviour: {\n scrolling: {\n speedDivider: 1.5,\n },\n startThreshold: 10,\n },\n boundaries: `#${scrollSelector}`,\n container: `#${scrollSelector}`,\n selectables: [`#${scrollSelector} .slate-selectable`],\n selectionAreaClass: 'slate-selection-area',\n },\n enableContextMenu: true,\n },\n }),\n BlockMenuPlugin.configure({\n render: { aboveEditable: BlockContextMenu },\n }),\n DndPlugin.configure({\n options: {\n enableScroller: true,\n onDropFiles: ({ dragItem, editor, target }) => {\n editor\n .getTransforms(BaseImagePlugin)\n .insert.imageFromFiles(dragItem.files, {\n at: target,\n nextBlock: false,\n });\n },\n },\n }),\n EmojiPlugin,\n exitBreakPlugin,\n NodeIdPlugin,\n NormalizeTypesPlugin.configure({\n options: {\n rules: [{ path: [0], strictType: HEADING_KEYS.h1 }],\n },\n }),\n resetBlockTypePlugin,\n SelectOnBackspacePlugin.configure({\n options: {\n query: {\n allow: [ImagePlugin.key, HorizontalRulePlugin.key],\n },\n },\n }),\n DeletePlugin,\n SingleLinePlugin,\n softBreakPlugin,\n tabbablePlugin,\n TrailingBlockPlugin.configure({\n options: { type: ParagraphPlugin.key },\n }),\n DragOverCursorPlugin,\n\n // Collaboration\n CommentsPlugin.configure({\n options: {\n comments: commentsData,\n myUserId: '1',\n users: usersData,\n },\n }),\n\n // Deserialization\n DocxPlugin,\n MarkdownPlugin.configure({ options: { indentList: true } }),\n JuicePlugin,\n\n // Testing\n PlaywrightPlugin.configure({\n enabled: process.env.NODE_ENV !== 'production',\n }),\n ],\n value: value,\n },\n []\n );\n};\n\nexport default function PlaygroundDemo({\n id,\n className,\n scrollSelector,\n}: {\n id?: ValueId;\n className?: string;\n scrollSelector?: string;\n}) {\n const containerRef = useRef(null);\n const enabled = settingsStore.use.checkedComponents();\n\n const editor = usePlaygroundEditor(\n id,\n scrollSelector ?? `blockSelection-${id}`\n );\n\n return (\n \n \n \n \n \n \n \n \n \n\n
\n \n \n\n \n \n \n \n \n \n \n\n \n \n \n \n\n \n \n \n
\n
\n
\n );\n}\n\nconst DemoIdContext = React.createContext(undefined);\n\nexport function DemoId({\n id,\n children,\n}: {\n children: React.ReactNode;\n id?: string;\n}) {\n return {children};\n}\n\nexport function useDemoId() {\n return React.useContext(DemoIdContext);\n}\n", "path": "example/playground-demo.tsx", "target": "components/playground-demo.tsx", "type": "registry:example" diff --git a/apps/www/public/r/styles/default/list-demo.json b/apps/www/public/r/styles/default/list-demo.json index d27499fc66..c3fb8fddf3 100644 --- a/apps/www/public/r/styles/default/list-demo.json +++ b/apps/www/public/r/styles/default/list-demo.json @@ -4,7 +4,7 @@ }, "files": [ { - "content": "'use client';\n\nimport React, { useRef } from 'react';\n\nimport type { ValueId } from '@/config/customizer-plugins';\n\nimport { cn } from '@udecode/cn';\nimport { AIChatPlugin, CopilotPlugin } from '@udecode/plate-ai/react';\nimport { AlignPlugin } from '@udecode/plate-alignment/react';\nimport { AutoformatPlugin } from '@udecode/plate-autoformat/react';\nimport {\n BoldPlugin,\n CodePlugin,\n ItalicPlugin,\n StrikethroughPlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n UnderlinePlugin,\n} from '@udecode/plate-basic-marks/react';\nimport { BlockquotePlugin } from '@udecode/plate-block-quote/react';\nimport { SingleLinePlugin } from '@udecode/plate-break/react';\nimport { CaptionPlugin } from '@udecode/plate-caption/react';\nimport { CodeBlockPlugin } from '@udecode/plate-code-block/react';\nimport { CommentsPlugin } from '@udecode/plate-comments/react';\nimport {\n ParagraphPlugin,\n Plate,\n usePlateEditor,\n} from '@udecode/plate-common/react';\nimport { DatePlugin } from '@udecode/plate-date/react';\nimport { DndPlugin } from '@udecode/plate-dnd';\nimport { DocxPlugin } from '@udecode/plate-docx';\nimport { EmojiPlugin } from '@udecode/plate-emoji/react';\nimport { ExcalidrawPlugin } from '@udecode/plate-excalidraw/react';\nimport {\n FontBackgroundColorPlugin,\n FontColorPlugin,\n FontSizePlugin,\n} from '@udecode/plate-font/react';\nimport { HEADING_KEYS } from '@udecode/plate-heading';\nimport { HeadingPlugin, TocPlugin } from '@udecode/plate-heading/react';\nimport { HighlightPlugin } from '@udecode/plate-highlight/react';\nimport { HorizontalRulePlugin } from '@udecode/plate-horizontal-rule/react';\nimport { IndentPlugin } from '@udecode/plate-indent/react';\nimport { IndentListPlugin } from '@udecode/plate-indent-list/react';\nimport { JuicePlugin } from '@udecode/plate-juice';\nimport { KbdPlugin } from '@udecode/plate-kbd/react';\nimport { ColumnPlugin } from '@udecode/plate-layout/react';\nimport { LineHeightPlugin } from '@udecode/plate-line-height/react';\nimport { LinkPlugin } from '@udecode/plate-link/react';\nimport { ListPlugin, TodoListPlugin } from '@udecode/plate-list/react';\nimport { MarkdownPlugin } from '@udecode/plate-markdown';\nimport { ImagePlugin, MediaEmbedPlugin } from '@udecode/plate-media/react';\nimport { MentionPlugin } from '@udecode/plate-mention/react';\nimport { NodeIdPlugin } from '@udecode/plate-node-id';\nimport { NormalizeTypesPlugin } from '@udecode/plate-normalizers';\nimport { PlaywrightPlugin } from '@udecode/plate-playwright';\nimport { DeletePlugin, SelectOnBackspacePlugin } from '@udecode/plate-select';\nimport {\n BlockMenuPlugin,\n BlockSelectionPlugin,\n} from '@udecode/plate-selection/react';\nimport { SlashPlugin } from '@udecode/plate-slash-command/react';\nimport { TablePlugin } from '@udecode/plate-table/react';\nimport { TogglePlugin } from '@udecode/plate-toggle/react';\nimport { TrailingBlockPlugin } from '@udecode/plate-trailing-block';\nimport Prism from 'prismjs';\n\nimport { CheckPlugin } from '@/components/context/check-plugin';\nimport { settingsStore } from '@/components/context/settings-store';\nimport { aiPlugins } from '@/lib/plate/demo/plugins/ai-plugins';\nimport { getAutoformatOptions } from '@/lib/plate/demo/plugins/autoformatOptions';\nimport { copilotPlugins } from '@/lib/plate/demo/plugins/copilot-plugins';\nimport { createPlateUI } from '@/plate/create-plate-ui';\nimport { editableProps } from '@/plate/demo/editableProps';\nimport { isEnabled } from '@/plate/demo/is-enabled';\nimport { DragOverCursorPlugin } from '@/plate/demo/plugins/DragOverCursorPlugin';\nimport { exitBreakPlugin } from '@/plate/demo/plugins/exitBreakPlugin';\nimport { resetBlockTypePlugin } from '@/plate/demo/plugins/resetBlockTypePlugin';\nimport { softBreakPlugin } from '@/plate/demo/plugins/softBreakPlugin';\nimport { tabbablePlugin } from '@/plate/demo/plugins/tabbablePlugin';\nimport { commentsData, usersData } from '@/plate/demo/values/commentsValue';\nimport { usePlaygroundValue } from '@/plate/demo/values/usePlaygroundValue';\nimport { BlockContextMenu } from '@/components/plate-ui/block-context-menu';\nimport { CommentsPopover } from '@/components/plate-ui/comments-popover';\nimport {\n CursorOverlay,\n SelectionOverlayPlugin,\n} from '@/components/plate-ui/cursor-overlay';\nimport { Editor, EditorContainer } from '@/components/plate-ui/editor';\nimport { FixedToolbar } from '@/components/plate-ui/fixed-toolbar';\nimport { FixedToolbarButtons } from '@/components/plate-ui/fixed-toolbar-buttons';\nimport { FloatingToolbar } from '@/components/plate-ui/floating-toolbar';\nimport { FloatingToolbarButtons } from '@/components/plate-ui/floating-toolbar-buttons';\nimport { ImagePreview } from '@/components/plate-ui/image-preview';\nimport {\n FireLiComponent,\n FireMarker,\n} from '@/components/plate-ui/indent-fire-marker';\nimport {\n TodoLi,\n TodoMarker,\n} from '@/components/plate-ui/indent-todo-marker';\nimport { LinkFloatingToolbar } from '@/components/plate-ui/link-floating-toolbar';\n\nimport { usePlaygroundEnabled } from './usePlaygroundEnabled';\n\nexport const usePlaygroundEditor = (id: any = '', scrollSelector?: string) => {\n const enabledPlugins = settingsStore.use.checkedPlugins();\n const overridePlugins = usePlaygroundEnabled(id);\n const autoformatOptions = getAutoformatOptions(id, enabledPlugins);\n\n const value = usePlaygroundValue(id);\n const key = settingsStore.use.version();\n const editorId = id || 'playground-' + key;\n\n return usePlateEditor(\n {\n id: editorId,\n override: {\n components: createPlateUI({\n draggable: isEnabled('dnd', id),\n placeholder: isEnabled('placeholder', id),\n }),\n plugins: overridePlugins,\n },\n plugins: [\n // AI\n ...(id === 'ai' || enabledPlugins[AIChatPlugin.key] ? aiPlugins : []),\n ...(id === 'copilot' || enabledPlugins[CopilotPlugin.key]\n ? copilotPlugins\n : []),\n // Nodes\n HeadingPlugin,\n TocPlugin.configure({\n options: {\n scrollContainerSelector: `#${scrollSelector}`,\n topOffset: 80,\n },\n }),\n BlockquotePlugin,\n CodeBlockPlugin.configure({\n options: {\n prism: Prism,\n },\n }),\n HorizontalRulePlugin,\n LinkPlugin.extend({\n render: { afterEditable: () => },\n }),\n ...(id === 'list' ? [ListPlugin] : []),\n ImagePlugin.extend({\n options: {\n disableUploadInsert: true,\n },\n render: { afterEditable: ImagePreview },\n }),\n MediaEmbedPlugin,\n CaptionPlugin.configure({\n options: {\n plugins: [ImagePlugin, MediaEmbedPlugin],\n },\n }),\n DatePlugin,\n MentionPlugin.configure({\n options: {\n triggerPreviousCharPattern: /^$|^[\\s\"']$/,\n },\n }),\n SlashPlugin,\n TablePlugin.configure({\n options: {\n enableMerging: id === 'tableMerge',\n },\n }),\n ColumnPlugin,\n SelectionOverlayPlugin,\n\n TodoListPlugin,\n TogglePlugin,\n ExcalidrawPlugin,\n // Marks\n BoldPlugin,\n ItalicPlugin,\n UnderlinePlugin,\n StrikethroughPlugin,\n CodePlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n FontColorPlugin,\n FontBackgroundColorPlugin,\n FontSizePlugin,\n HighlightPlugin,\n KbdPlugin,\n\n // Block Style\n AlignPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n MediaEmbedPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n ImagePlugin.key,\n HEADING_KEYS.h6,\n ],\n },\n }),\n IndentPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n }),\n IndentListPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n options: {\n listStyleTypes: {\n fire: {\n liComponent: FireLiComponent,\n markerComponent: FireMarker,\n type: 'fire',\n },\n todo: {\n liComponent: TodoLi,\n markerComponent: TodoMarker,\n type: 'todo',\n },\n },\n },\n }),\n LineHeightPlugin.extend({\n inject: {\n nodeProps: {\n defaultNodeValue: 1.5,\n validNodeValues: [1, 1.2, 1.5, 2, 3],\n },\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n ],\n },\n }),\n\n // Functionality\n AutoformatPlugin.configure({\n options: autoformatOptions,\n }),\n BlockSelectionPlugin.configure({\n options: {\n areaOptions: {\n behaviour: {\n scrolling: {\n speedDivider: 1.5,\n },\n startThreshold: 10,\n },\n boundaries: `#${scrollSelector}`,\n container: `#${scrollSelector}`,\n selectables: [`#${scrollSelector} .slate-selectable`],\n selectionAreaClass: 'slate-selection-area',\n },\n enableContextMenu: true,\n },\n }),\n BlockMenuPlugin.configure({\n render: { aboveEditable: BlockContextMenu },\n }),\n DndPlugin.configure({\n options: {\n enableScroller: true,\n onDropFiles: ({ dragItem, editor, target }) => {\n editor\n .getTransforms(ImagePlugin)\n .insertImageFromFiles(dragItem.files, {\n at: target,\n nextBlock: false,\n });\n },\n },\n }),\n EmojiPlugin,\n exitBreakPlugin,\n NodeIdPlugin,\n NormalizeTypesPlugin.configure({\n options: {\n rules: [{ path: [0], strictType: HEADING_KEYS.h1 }],\n },\n }),\n resetBlockTypePlugin,\n SelectOnBackspacePlugin.configure({\n options: {\n query: {\n allow: [ImagePlugin.key, HorizontalRulePlugin.key],\n },\n },\n }),\n DeletePlugin,\n SingleLinePlugin,\n softBreakPlugin,\n tabbablePlugin,\n TrailingBlockPlugin.configure({\n options: { type: ParagraphPlugin.key },\n }),\n DragOverCursorPlugin,\n\n // Collaboration\n CommentsPlugin.configure({\n options: {\n comments: commentsData,\n myUserId: '1',\n users: usersData,\n },\n }),\n\n // Deserialization\n DocxPlugin,\n MarkdownPlugin.configure({ options: { indentList: true } }),\n JuicePlugin,\n\n // Testing\n PlaywrightPlugin.configure({\n enabled: process.env.NODE_ENV !== 'production',\n }),\n ],\n value: value,\n },\n []\n );\n};\n\nexport default function PlaygroundDemo({\n id,\n className,\n scrollSelector,\n}: {\n id?: ValueId;\n className?: string;\n scrollSelector?: string;\n}) {\n const containerRef = useRef(null);\n const enabled = settingsStore.use.checkedComponents();\n\n const editor = usePlaygroundEditor(\n id,\n scrollSelector ?? `blockSelection-${id}`\n );\n\n return (\n \n \n \n \n \n \n \n \n \n\n
\n \n \n\n \n \n \n \n \n \n \n\n \n \n \n \n\n \n \n \n
\n
\n
\n );\n}\n\nconst DemoIdContext = React.createContext(undefined);\n\nexport function DemoId({\n id,\n children,\n}: {\n children: React.ReactNode;\n id?: string;\n}) {\n return {children};\n}\n\nexport function useDemoId() {\n return React.useContext(DemoIdContext);\n}\n", + "content": "'use client';\n\nimport React, { useRef } from 'react';\n\nimport type { ValueId } from '@/config/customizer-plugins';\n\nimport { cn } from '@udecode/cn';\nimport { AIChatPlugin, CopilotPlugin } from '@udecode/plate-ai/react';\nimport { AlignPlugin } from '@udecode/plate-alignment/react';\nimport { AutoformatPlugin } from '@udecode/plate-autoformat/react';\nimport {\n BoldPlugin,\n CodePlugin,\n ItalicPlugin,\n StrikethroughPlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n UnderlinePlugin,\n} from '@udecode/plate-basic-marks/react';\nimport { BlockquotePlugin } from '@udecode/plate-block-quote/react';\nimport { SingleLinePlugin } from '@udecode/plate-break/react';\nimport { CaptionPlugin } from '@udecode/plate-caption/react';\nimport { CodeBlockPlugin } from '@udecode/plate-code-block/react';\nimport { CommentsPlugin } from '@udecode/plate-comments/react';\nimport {\n ParagraphPlugin,\n Plate,\n usePlateEditor,\n} from '@udecode/plate-common/react';\nimport { DatePlugin } from '@udecode/plate-date/react';\nimport { DndPlugin } from '@udecode/plate-dnd';\nimport { DocxPlugin } from '@udecode/plate-docx';\nimport { EmojiPlugin } from '@udecode/plate-emoji/react';\nimport { ExcalidrawPlugin } from '@udecode/plate-excalidraw/react';\nimport {\n FontBackgroundColorPlugin,\n FontColorPlugin,\n FontSizePlugin,\n} from '@udecode/plate-font/react';\nimport { HEADING_KEYS } from '@udecode/plate-heading';\nimport { HeadingPlugin, TocPlugin } from '@udecode/plate-heading/react';\nimport { HighlightPlugin } from '@udecode/plate-highlight/react';\nimport { HorizontalRulePlugin } from '@udecode/plate-horizontal-rule/react';\nimport { IndentPlugin } from '@udecode/plate-indent/react';\nimport { IndentListPlugin } from '@udecode/plate-indent-list/react';\nimport { JuicePlugin } from '@udecode/plate-juice';\nimport { KbdPlugin } from '@udecode/plate-kbd/react';\nimport { ColumnPlugin } from '@udecode/plate-layout/react';\nimport { LineHeightPlugin } from '@udecode/plate-line-height/react';\nimport { LinkPlugin } from '@udecode/plate-link/react';\nimport { ListPlugin, TodoListPlugin } from '@udecode/plate-list/react';\nimport { MarkdownPlugin } from '@udecode/plate-markdown';\nimport { BaseImagePlugin } from '@udecode/plate-media';\nimport { ImagePlugin, MediaEmbedPlugin } from '@udecode/plate-media/react';\nimport { MentionPlugin } from '@udecode/plate-mention/react';\nimport { NodeIdPlugin } from '@udecode/plate-node-id';\nimport { NormalizeTypesPlugin } from '@udecode/plate-normalizers';\nimport { PlaywrightPlugin } from '@udecode/plate-playwright';\nimport { DeletePlugin, SelectOnBackspacePlugin } from '@udecode/plate-select';\nimport {\n BlockMenuPlugin,\n BlockSelectionPlugin,\n} from '@udecode/plate-selection/react';\nimport { SlashPlugin } from '@udecode/plate-slash-command/react';\nimport { TablePlugin } from '@udecode/plate-table/react';\nimport { TogglePlugin } from '@udecode/plate-toggle/react';\nimport { TrailingBlockPlugin } from '@udecode/plate-trailing-block';\nimport Prism from 'prismjs';\n\nimport { CheckPlugin } from '@/components/context/check-plugin';\nimport { settingsStore } from '@/components/context/settings-store';\nimport { aiPlugins } from '@/lib/plate/demo/plugins/ai-plugins';\nimport { getAutoformatOptions } from '@/lib/plate/demo/plugins/autoformatOptions';\nimport { copilotPlugins } from '@/lib/plate/demo/plugins/copilot-plugins';\nimport { createPlateUI } from '@/plate/create-plate-ui';\nimport { editableProps } from '@/plate/demo/editableProps';\nimport { isEnabled } from '@/plate/demo/is-enabled';\nimport { DragOverCursorPlugin } from '@/plate/demo/plugins/DragOverCursorPlugin';\nimport { exitBreakPlugin } from '@/plate/demo/plugins/exitBreakPlugin';\nimport { resetBlockTypePlugin } from '@/plate/demo/plugins/resetBlockTypePlugin';\nimport { softBreakPlugin } from '@/plate/demo/plugins/softBreakPlugin';\nimport { tabbablePlugin } from '@/plate/demo/plugins/tabbablePlugin';\nimport { commentsData, usersData } from '@/plate/demo/values/commentsValue';\nimport { usePlaygroundValue } from '@/plate/demo/values/usePlaygroundValue';\nimport { BlockContextMenu } from '@/components/plate-ui/block-context-menu';\nimport { CommentsPopover } from '@/components/plate-ui/comments-popover';\nimport {\n CursorOverlay,\n SelectionOverlayPlugin,\n} from '@/components/plate-ui/cursor-overlay';\nimport { Editor, EditorContainer } from '@/components/plate-ui/editor';\nimport { FixedToolbar } from '@/components/plate-ui/fixed-toolbar';\nimport { FixedToolbarButtons } from '@/components/plate-ui/fixed-toolbar-buttons';\nimport { FloatingToolbar } from '@/components/plate-ui/floating-toolbar';\nimport { FloatingToolbarButtons } from '@/components/plate-ui/floating-toolbar-buttons';\nimport { ImagePreview } from '@/components/plate-ui/image-preview';\nimport {\n FireLiComponent,\n FireMarker,\n} from '@/components/plate-ui/indent-fire-marker';\nimport {\n TodoLi,\n TodoMarker,\n} from '@/components/plate-ui/indent-todo-marker';\nimport { LinkFloatingToolbar } from '@/components/plate-ui/link-floating-toolbar';\n\nimport { usePlaygroundEnabled } from './usePlaygroundEnabled';\n\nexport const usePlaygroundEditor = (id: any = '', scrollSelector?: string) => {\n const enabledPlugins = settingsStore.use.checkedPlugins();\n const overridePlugins = usePlaygroundEnabled(id);\n const autoformatOptions = getAutoformatOptions(id, enabledPlugins);\n\n const value = usePlaygroundValue(id);\n const key = settingsStore.use.version();\n const editorId = id || 'playground-' + key;\n\n return usePlateEditor(\n {\n id: editorId,\n override: {\n components: createPlateUI({\n draggable: isEnabled('dnd', id),\n placeholder: isEnabled('placeholder', id),\n }),\n plugins: overridePlugins,\n },\n plugins: [\n // AI\n ...(id === 'ai' || enabledPlugins[AIChatPlugin.key] ? aiPlugins : []),\n ...(id === 'copilot' || enabledPlugins[CopilotPlugin.key]\n ? copilotPlugins\n : []),\n // Nodes\n HeadingPlugin,\n TocPlugin.configure({\n options: {\n scrollContainerSelector: `#${scrollSelector}`,\n topOffset: 80,\n },\n }),\n BlockquotePlugin,\n CodeBlockPlugin.configure({\n options: {\n prism: Prism,\n },\n }),\n HorizontalRulePlugin,\n LinkPlugin.extend({\n render: { afterEditable: () => },\n }),\n ...(id === 'list' ? [ListPlugin] : []),\n ImagePlugin.extend({\n options: {\n disableUploadInsert: true,\n },\n render: { afterEditable: ImagePreview },\n }),\n MediaEmbedPlugin,\n CaptionPlugin.configure({\n options: {\n plugins: [ImagePlugin, MediaEmbedPlugin],\n },\n }),\n DatePlugin,\n MentionPlugin.configure({\n options: {\n triggerPreviousCharPattern: /^$|^[\\s\"']$/,\n },\n }),\n SlashPlugin,\n TablePlugin.configure({\n options: {\n enableMerging: id === 'tableMerge',\n },\n }),\n ColumnPlugin,\n SelectionOverlayPlugin,\n\n TodoListPlugin,\n TogglePlugin,\n ExcalidrawPlugin,\n // Marks\n BoldPlugin,\n ItalicPlugin,\n UnderlinePlugin,\n StrikethroughPlugin,\n CodePlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n FontColorPlugin,\n FontBackgroundColorPlugin,\n FontSizePlugin,\n HighlightPlugin,\n KbdPlugin,\n\n // Block Style\n AlignPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n MediaEmbedPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n ImagePlugin.key,\n HEADING_KEYS.h6,\n ],\n },\n }),\n IndentPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n }),\n IndentListPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n options: {\n listStyleTypes: {\n fire: {\n liComponent: FireLiComponent,\n markerComponent: FireMarker,\n type: 'fire',\n },\n todo: {\n liComponent: TodoLi,\n markerComponent: TodoMarker,\n type: 'todo',\n },\n },\n },\n }),\n LineHeightPlugin.extend({\n inject: {\n nodeProps: {\n defaultNodeValue: 1.5,\n validNodeValues: [1, 1.2, 1.5, 2, 3],\n },\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n ],\n },\n }),\n\n // Functionality\n AutoformatPlugin.configure({\n options: autoformatOptions,\n }),\n BlockSelectionPlugin.configure({\n options: {\n areaOptions: {\n behaviour: {\n scrolling: {\n speedDivider: 1.5,\n },\n startThreshold: 10,\n },\n boundaries: `#${scrollSelector}`,\n container: `#${scrollSelector}`,\n selectables: [`#${scrollSelector} .slate-selectable`],\n selectionAreaClass: 'slate-selection-area',\n },\n enableContextMenu: true,\n },\n }),\n BlockMenuPlugin.configure({\n render: { aboveEditable: BlockContextMenu },\n }),\n DndPlugin.configure({\n options: {\n enableScroller: true,\n onDropFiles: ({ dragItem, editor, target }) => {\n editor\n .getTransforms(BaseImagePlugin)\n .insert.imageFromFiles(dragItem.files, {\n at: target,\n nextBlock: false,\n });\n },\n },\n }),\n EmojiPlugin,\n exitBreakPlugin,\n NodeIdPlugin,\n NormalizeTypesPlugin.configure({\n options: {\n rules: [{ path: [0], strictType: HEADING_KEYS.h1 }],\n },\n }),\n resetBlockTypePlugin,\n SelectOnBackspacePlugin.configure({\n options: {\n query: {\n allow: [ImagePlugin.key, HorizontalRulePlugin.key],\n },\n },\n }),\n DeletePlugin,\n SingleLinePlugin,\n softBreakPlugin,\n tabbablePlugin,\n TrailingBlockPlugin.configure({\n options: { type: ParagraphPlugin.key },\n }),\n DragOverCursorPlugin,\n\n // Collaboration\n CommentsPlugin.configure({\n options: {\n comments: commentsData,\n myUserId: '1',\n users: usersData,\n },\n }),\n\n // Deserialization\n DocxPlugin,\n MarkdownPlugin.configure({ options: { indentList: true } }),\n JuicePlugin,\n\n // Testing\n PlaywrightPlugin.configure({\n enabled: process.env.NODE_ENV !== 'production',\n }),\n ],\n value: value,\n },\n []\n );\n};\n\nexport default function PlaygroundDemo({\n id,\n className,\n scrollSelector,\n}: {\n id?: ValueId;\n className?: string;\n scrollSelector?: string;\n}) {\n const containerRef = useRef(null);\n const enabled = settingsStore.use.checkedComponents();\n\n const editor = usePlaygroundEditor(\n id,\n scrollSelector ?? `blockSelection-${id}`\n );\n\n return (\n \n \n \n \n \n \n \n \n \n\n
\n \n \n\n \n \n \n \n \n \n \n\n \n \n \n \n\n \n \n \n
\n
\n
\n );\n}\n\nconst DemoIdContext = React.createContext(undefined);\n\nexport function DemoId({\n id,\n children,\n}: {\n children: React.ReactNode;\n id?: string;\n}) {\n return {children};\n}\n\nexport function useDemoId() {\n return React.useContext(DemoIdContext);\n}\n", "path": "example/playground-demo.tsx", "target": "components/playground-demo.tsx", "type": "registry:example" diff --git a/apps/www/public/r/styles/default/media-demo.json b/apps/www/public/r/styles/default/media-demo.json index 0c13504d57..c0a0dd5d85 100644 --- a/apps/www/public/r/styles/default/media-demo.json +++ b/apps/www/public/r/styles/default/media-demo.json @@ -4,7 +4,7 @@ }, "files": [ { - "content": "'use client';\n\nimport React, { useRef } from 'react';\n\nimport type { ValueId } from '@/config/customizer-plugins';\n\nimport { cn } from '@udecode/cn';\nimport { AIChatPlugin, CopilotPlugin } from '@udecode/plate-ai/react';\nimport { AlignPlugin } from '@udecode/plate-alignment/react';\nimport { AutoformatPlugin } from '@udecode/plate-autoformat/react';\nimport {\n BoldPlugin,\n CodePlugin,\n ItalicPlugin,\n StrikethroughPlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n UnderlinePlugin,\n} from '@udecode/plate-basic-marks/react';\nimport { BlockquotePlugin } from '@udecode/plate-block-quote/react';\nimport { SingleLinePlugin } from '@udecode/plate-break/react';\nimport { CaptionPlugin } from '@udecode/plate-caption/react';\nimport { CodeBlockPlugin } from '@udecode/plate-code-block/react';\nimport { CommentsPlugin } from '@udecode/plate-comments/react';\nimport {\n ParagraphPlugin,\n Plate,\n usePlateEditor,\n} from '@udecode/plate-common/react';\nimport { DatePlugin } from '@udecode/plate-date/react';\nimport { DndPlugin } from '@udecode/plate-dnd';\nimport { DocxPlugin } from '@udecode/plate-docx';\nimport { EmojiPlugin } from '@udecode/plate-emoji/react';\nimport { ExcalidrawPlugin } from '@udecode/plate-excalidraw/react';\nimport {\n FontBackgroundColorPlugin,\n FontColorPlugin,\n FontSizePlugin,\n} from '@udecode/plate-font/react';\nimport { HEADING_KEYS } from '@udecode/plate-heading';\nimport { HeadingPlugin, TocPlugin } from '@udecode/plate-heading/react';\nimport { HighlightPlugin } from '@udecode/plate-highlight/react';\nimport { HorizontalRulePlugin } from '@udecode/plate-horizontal-rule/react';\nimport { IndentPlugin } from '@udecode/plate-indent/react';\nimport { IndentListPlugin } from '@udecode/plate-indent-list/react';\nimport { JuicePlugin } from '@udecode/plate-juice';\nimport { KbdPlugin } from '@udecode/plate-kbd/react';\nimport { ColumnPlugin } from '@udecode/plate-layout/react';\nimport { LineHeightPlugin } from '@udecode/plate-line-height/react';\nimport { LinkPlugin } from '@udecode/plate-link/react';\nimport { ListPlugin, TodoListPlugin } from '@udecode/plate-list/react';\nimport { MarkdownPlugin } from '@udecode/plate-markdown';\nimport { ImagePlugin, MediaEmbedPlugin } from '@udecode/plate-media/react';\nimport { MentionPlugin } from '@udecode/plate-mention/react';\nimport { NodeIdPlugin } from '@udecode/plate-node-id';\nimport { NormalizeTypesPlugin } from '@udecode/plate-normalizers';\nimport { PlaywrightPlugin } from '@udecode/plate-playwright';\nimport { DeletePlugin, SelectOnBackspacePlugin } from '@udecode/plate-select';\nimport {\n BlockMenuPlugin,\n BlockSelectionPlugin,\n} from '@udecode/plate-selection/react';\nimport { SlashPlugin } from '@udecode/plate-slash-command/react';\nimport { TablePlugin } from '@udecode/plate-table/react';\nimport { TogglePlugin } from '@udecode/plate-toggle/react';\nimport { TrailingBlockPlugin } from '@udecode/plate-trailing-block';\nimport Prism from 'prismjs';\n\nimport { CheckPlugin } from '@/components/context/check-plugin';\nimport { settingsStore } from '@/components/context/settings-store';\nimport { aiPlugins } from '@/lib/plate/demo/plugins/ai-plugins';\nimport { getAutoformatOptions } from '@/lib/plate/demo/plugins/autoformatOptions';\nimport { copilotPlugins } from '@/lib/plate/demo/plugins/copilot-plugins';\nimport { createPlateUI } from '@/plate/create-plate-ui';\nimport { editableProps } from '@/plate/demo/editableProps';\nimport { isEnabled } from '@/plate/demo/is-enabled';\nimport { DragOverCursorPlugin } from '@/plate/demo/plugins/DragOverCursorPlugin';\nimport { exitBreakPlugin } from '@/plate/demo/plugins/exitBreakPlugin';\nimport { resetBlockTypePlugin } from '@/plate/demo/plugins/resetBlockTypePlugin';\nimport { softBreakPlugin } from '@/plate/demo/plugins/softBreakPlugin';\nimport { tabbablePlugin } from '@/plate/demo/plugins/tabbablePlugin';\nimport { commentsData, usersData } from '@/plate/demo/values/commentsValue';\nimport { usePlaygroundValue } from '@/plate/demo/values/usePlaygroundValue';\nimport { BlockContextMenu } from '@/components/plate-ui/block-context-menu';\nimport { CommentsPopover } from '@/components/plate-ui/comments-popover';\nimport {\n CursorOverlay,\n SelectionOverlayPlugin,\n} from '@/components/plate-ui/cursor-overlay';\nimport { Editor, EditorContainer } from '@/components/plate-ui/editor';\nimport { FixedToolbar } from '@/components/plate-ui/fixed-toolbar';\nimport { FixedToolbarButtons } from '@/components/plate-ui/fixed-toolbar-buttons';\nimport { FloatingToolbar } from '@/components/plate-ui/floating-toolbar';\nimport { FloatingToolbarButtons } from '@/components/plate-ui/floating-toolbar-buttons';\nimport { ImagePreview } from '@/components/plate-ui/image-preview';\nimport {\n FireLiComponent,\n FireMarker,\n} from '@/components/plate-ui/indent-fire-marker';\nimport {\n TodoLi,\n TodoMarker,\n} from '@/components/plate-ui/indent-todo-marker';\nimport { LinkFloatingToolbar } from '@/components/plate-ui/link-floating-toolbar';\n\nimport { usePlaygroundEnabled } from './usePlaygroundEnabled';\n\nexport const usePlaygroundEditor = (id: any = '', scrollSelector?: string) => {\n const enabledPlugins = settingsStore.use.checkedPlugins();\n const overridePlugins = usePlaygroundEnabled(id);\n const autoformatOptions = getAutoformatOptions(id, enabledPlugins);\n\n const value = usePlaygroundValue(id);\n const key = settingsStore.use.version();\n const editorId = id || 'playground-' + key;\n\n return usePlateEditor(\n {\n id: editorId,\n override: {\n components: createPlateUI({\n draggable: isEnabled('dnd', id),\n placeholder: isEnabled('placeholder', id),\n }),\n plugins: overridePlugins,\n },\n plugins: [\n // AI\n ...(id === 'ai' || enabledPlugins[AIChatPlugin.key] ? aiPlugins : []),\n ...(id === 'copilot' || enabledPlugins[CopilotPlugin.key]\n ? copilotPlugins\n : []),\n // Nodes\n HeadingPlugin,\n TocPlugin.configure({\n options: {\n scrollContainerSelector: `#${scrollSelector}`,\n topOffset: 80,\n },\n }),\n BlockquotePlugin,\n CodeBlockPlugin.configure({\n options: {\n prism: Prism,\n },\n }),\n HorizontalRulePlugin,\n LinkPlugin.extend({\n render: { afterEditable: () => },\n }),\n ...(id === 'list' ? [ListPlugin] : []),\n ImagePlugin.extend({\n options: {\n disableUploadInsert: true,\n },\n render: { afterEditable: ImagePreview },\n }),\n MediaEmbedPlugin,\n CaptionPlugin.configure({\n options: {\n plugins: [ImagePlugin, MediaEmbedPlugin],\n },\n }),\n DatePlugin,\n MentionPlugin.configure({\n options: {\n triggerPreviousCharPattern: /^$|^[\\s\"']$/,\n },\n }),\n SlashPlugin,\n TablePlugin.configure({\n options: {\n enableMerging: id === 'tableMerge',\n },\n }),\n ColumnPlugin,\n SelectionOverlayPlugin,\n\n TodoListPlugin,\n TogglePlugin,\n ExcalidrawPlugin,\n // Marks\n BoldPlugin,\n ItalicPlugin,\n UnderlinePlugin,\n StrikethroughPlugin,\n CodePlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n FontColorPlugin,\n FontBackgroundColorPlugin,\n FontSizePlugin,\n HighlightPlugin,\n KbdPlugin,\n\n // Block Style\n AlignPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n MediaEmbedPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n ImagePlugin.key,\n HEADING_KEYS.h6,\n ],\n },\n }),\n IndentPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n }),\n IndentListPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n options: {\n listStyleTypes: {\n fire: {\n liComponent: FireLiComponent,\n markerComponent: FireMarker,\n type: 'fire',\n },\n todo: {\n liComponent: TodoLi,\n markerComponent: TodoMarker,\n type: 'todo',\n },\n },\n },\n }),\n LineHeightPlugin.extend({\n inject: {\n nodeProps: {\n defaultNodeValue: 1.5,\n validNodeValues: [1, 1.2, 1.5, 2, 3],\n },\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n ],\n },\n }),\n\n // Functionality\n AutoformatPlugin.configure({\n options: autoformatOptions,\n }),\n BlockSelectionPlugin.configure({\n options: {\n areaOptions: {\n behaviour: {\n scrolling: {\n speedDivider: 1.5,\n },\n startThreshold: 10,\n },\n boundaries: `#${scrollSelector}`,\n container: `#${scrollSelector}`,\n selectables: [`#${scrollSelector} .slate-selectable`],\n selectionAreaClass: 'slate-selection-area',\n },\n enableContextMenu: true,\n },\n }),\n BlockMenuPlugin.configure({\n render: { aboveEditable: BlockContextMenu },\n }),\n DndPlugin.configure({\n options: {\n enableScroller: true,\n onDropFiles: ({ dragItem, editor, target }) => {\n editor\n .getTransforms(ImagePlugin)\n .insertImageFromFiles(dragItem.files, {\n at: target,\n nextBlock: false,\n });\n },\n },\n }),\n EmojiPlugin,\n exitBreakPlugin,\n NodeIdPlugin,\n NormalizeTypesPlugin.configure({\n options: {\n rules: [{ path: [0], strictType: HEADING_KEYS.h1 }],\n },\n }),\n resetBlockTypePlugin,\n SelectOnBackspacePlugin.configure({\n options: {\n query: {\n allow: [ImagePlugin.key, HorizontalRulePlugin.key],\n },\n },\n }),\n DeletePlugin,\n SingleLinePlugin,\n softBreakPlugin,\n tabbablePlugin,\n TrailingBlockPlugin.configure({\n options: { type: ParagraphPlugin.key },\n }),\n DragOverCursorPlugin,\n\n // Collaboration\n CommentsPlugin.configure({\n options: {\n comments: commentsData,\n myUserId: '1',\n users: usersData,\n },\n }),\n\n // Deserialization\n DocxPlugin,\n MarkdownPlugin.configure({ options: { indentList: true } }),\n JuicePlugin,\n\n // Testing\n PlaywrightPlugin.configure({\n enabled: process.env.NODE_ENV !== 'production',\n }),\n ],\n value: value,\n },\n []\n );\n};\n\nexport default function PlaygroundDemo({\n id,\n className,\n scrollSelector,\n}: {\n id?: ValueId;\n className?: string;\n scrollSelector?: string;\n}) {\n const containerRef = useRef(null);\n const enabled = settingsStore.use.checkedComponents();\n\n const editor = usePlaygroundEditor(\n id,\n scrollSelector ?? `blockSelection-${id}`\n );\n\n return (\n \n \n \n \n \n \n \n \n \n\n
\n \n \n\n \n \n \n \n \n \n \n\n \n \n \n \n\n \n \n \n
\n
\n
\n );\n}\n\nconst DemoIdContext = React.createContext(undefined);\n\nexport function DemoId({\n id,\n children,\n}: {\n children: React.ReactNode;\n id?: string;\n}) {\n return {children};\n}\n\nexport function useDemoId() {\n return React.useContext(DemoIdContext);\n}\n", + "content": "'use client';\n\nimport React, { useRef } from 'react';\n\nimport type { ValueId } from '@/config/customizer-plugins';\n\nimport { cn } from '@udecode/cn';\nimport { AIChatPlugin, CopilotPlugin } from '@udecode/plate-ai/react';\nimport { AlignPlugin } from '@udecode/plate-alignment/react';\nimport { AutoformatPlugin } from '@udecode/plate-autoformat/react';\nimport {\n BoldPlugin,\n CodePlugin,\n ItalicPlugin,\n StrikethroughPlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n UnderlinePlugin,\n} from '@udecode/plate-basic-marks/react';\nimport { BlockquotePlugin } from '@udecode/plate-block-quote/react';\nimport { SingleLinePlugin } from '@udecode/plate-break/react';\nimport { CaptionPlugin } from '@udecode/plate-caption/react';\nimport { CodeBlockPlugin } from '@udecode/plate-code-block/react';\nimport { CommentsPlugin } from '@udecode/plate-comments/react';\nimport {\n ParagraphPlugin,\n Plate,\n usePlateEditor,\n} from '@udecode/plate-common/react';\nimport { DatePlugin } from '@udecode/plate-date/react';\nimport { DndPlugin } from '@udecode/plate-dnd';\nimport { DocxPlugin } from '@udecode/plate-docx';\nimport { EmojiPlugin } from '@udecode/plate-emoji/react';\nimport { ExcalidrawPlugin } from '@udecode/plate-excalidraw/react';\nimport {\n FontBackgroundColorPlugin,\n FontColorPlugin,\n FontSizePlugin,\n} from '@udecode/plate-font/react';\nimport { HEADING_KEYS } from '@udecode/plate-heading';\nimport { HeadingPlugin, TocPlugin } from '@udecode/plate-heading/react';\nimport { HighlightPlugin } from '@udecode/plate-highlight/react';\nimport { HorizontalRulePlugin } from '@udecode/plate-horizontal-rule/react';\nimport { IndentPlugin } from '@udecode/plate-indent/react';\nimport { IndentListPlugin } from '@udecode/plate-indent-list/react';\nimport { JuicePlugin } from '@udecode/plate-juice';\nimport { KbdPlugin } from '@udecode/plate-kbd/react';\nimport { ColumnPlugin } from '@udecode/plate-layout/react';\nimport { LineHeightPlugin } from '@udecode/plate-line-height/react';\nimport { LinkPlugin } from '@udecode/plate-link/react';\nimport { ListPlugin, TodoListPlugin } from '@udecode/plate-list/react';\nimport { MarkdownPlugin } from '@udecode/plate-markdown';\nimport { BaseImagePlugin } from '@udecode/plate-media';\nimport { ImagePlugin, MediaEmbedPlugin } from '@udecode/plate-media/react';\nimport { MentionPlugin } from '@udecode/plate-mention/react';\nimport { NodeIdPlugin } from '@udecode/plate-node-id';\nimport { NormalizeTypesPlugin } from '@udecode/plate-normalizers';\nimport { PlaywrightPlugin } from '@udecode/plate-playwright';\nimport { DeletePlugin, SelectOnBackspacePlugin } from '@udecode/plate-select';\nimport {\n BlockMenuPlugin,\n BlockSelectionPlugin,\n} from '@udecode/plate-selection/react';\nimport { SlashPlugin } from '@udecode/plate-slash-command/react';\nimport { TablePlugin } from '@udecode/plate-table/react';\nimport { TogglePlugin } from '@udecode/plate-toggle/react';\nimport { TrailingBlockPlugin } from '@udecode/plate-trailing-block';\nimport Prism from 'prismjs';\n\nimport { CheckPlugin } from '@/components/context/check-plugin';\nimport { settingsStore } from '@/components/context/settings-store';\nimport { aiPlugins } from '@/lib/plate/demo/plugins/ai-plugins';\nimport { getAutoformatOptions } from '@/lib/plate/demo/plugins/autoformatOptions';\nimport { copilotPlugins } from '@/lib/plate/demo/plugins/copilot-plugins';\nimport { createPlateUI } from '@/plate/create-plate-ui';\nimport { editableProps } from '@/plate/demo/editableProps';\nimport { isEnabled } from '@/plate/demo/is-enabled';\nimport { DragOverCursorPlugin } from '@/plate/demo/plugins/DragOverCursorPlugin';\nimport { exitBreakPlugin } from '@/plate/demo/plugins/exitBreakPlugin';\nimport { resetBlockTypePlugin } from '@/plate/demo/plugins/resetBlockTypePlugin';\nimport { softBreakPlugin } from '@/plate/demo/plugins/softBreakPlugin';\nimport { tabbablePlugin } from '@/plate/demo/plugins/tabbablePlugin';\nimport { commentsData, usersData } from '@/plate/demo/values/commentsValue';\nimport { usePlaygroundValue } from '@/plate/demo/values/usePlaygroundValue';\nimport { BlockContextMenu } from '@/components/plate-ui/block-context-menu';\nimport { CommentsPopover } from '@/components/plate-ui/comments-popover';\nimport {\n CursorOverlay,\n SelectionOverlayPlugin,\n} from '@/components/plate-ui/cursor-overlay';\nimport { Editor, EditorContainer } from '@/components/plate-ui/editor';\nimport { FixedToolbar } from '@/components/plate-ui/fixed-toolbar';\nimport { FixedToolbarButtons } from '@/components/plate-ui/fixed-toolbar-buttons';\nimport { FloatingToolbar } from '@/components/plate-ui/floating-toolbar';\nimport { FloatingToolbarButtons } from '@/components/plate-ui/floating-toolbar-buttons';\nimport { ImagePreview } from '@/components/plate-ui/image-preview';\nimport {\n FireLiComponent,\n FireMarker,\n} from '@/components/plate-ui/indent-fire-marker';\nimport {\n TodoLi,\n TodoMarker,\n} from '@/components/plate-ui/indent-todo-marker';\nimport { LinkFloatingToolbar } from '@/components/plate-ui/link-floating-toolbar';\n\nimport { usePlaygroundEnabled } from './usePlaygroundEnabled';\n\nexport const usePlaygroundEditor = (id: any = '', scrollSelector?: string) => {\n const enabledPlugins = settingsStore.use.checkedPlugins();\n const overridePlugins = usePlaygroundEnabled(id);\n const autoformatOptions = getAutoformatOptions(id, enabledPlugins);\n\n const value = usePlaygroundValue(id);\n const key = settingsStore.use.version();\n const editorId = id || 'playground-' + key;\n\n return usePlateEditor(\n {\n id: editorId,\n override: {\n components: createPlateUI({\n draggable: isEnabled('dnd', id),\n placeholder: isEnabled('placeholder', id),\n }),\n plugins: overridePlugins,\n },\n plugins: [\n // AI\n ...(id === 'ai' || enabledPlugins[AIChatPlugin.key] ? aiPlugins : []),\n ...(id === 'copilot' || enabledPlugins[CopilotPlugin.key]\n ? copilotPlugins\n : []),\n // Nodes\n HeadingPlugin,\n TocPlugin.configure({\n options: {\n scrollContainerSelector: `#${scrollSelector}`,\n topOffset: 80,\n },\n }),\n BlockquotePlugin,\n CodeBlockPlugin.configure({\n options: {\n prism: Prism,\n },\n }),\n HorizontalRulePlugin,\n LinkPlugin.extend({\n render: { afterEditable: () => },\n }),\n ...(id === 'list' ? [ListPlugin] : []),\n ImagePlugin.extend({\n options: {\n disableUploadInsert: true,\n },\n render: { afterEditable: ImagePreview },\n }),\n MediaEmbedPlugin,\n CaptionPlugin.configure({\n options: {\n plugins: [ImagePlugin, MediaEmbedPlugin],\n },\n }),\n DatePlugin,\n MentionPlugin.configure({\n options: {\n triggerPreviousCharPattern: /^$|^[\\s\"']$/,\n },\n }),\n SlashPlugin,\n TablePlugin.configure({\n options: {\n enableMerging: id === 'tableMerge',\n },\n }),\n ColumnPlugin,\n SelectionOverlayPlugin,\n\n TodoListPlugin,\n TogglePlugin,\n ExcalidrawPlugin,\n // Marks\n BoldPlugin,\n ItalicPlugin,\n UnderlinePlugin,\n StrikethroughPlugin,\n CodePlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n FontColorPlugin,\n FontBackgroundColorPlugin,\n FontSizePlugin,\n HighlightPlugin,\n KbdPlugin,\n\n // Block Style\n AlignPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n MediaEmbedPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n ImagePlugin.key,\n HEADING_KEYS.h6,\n ],\n },\n }),\n IndentPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n }),\n IndentListPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n options: {\n listStyleTypes: {\n fire: {\n liComponent: FireLiComponent,\n markerComponent: FireMarker,\n type: 'fire',\n },\n todo: {\n liComponent: TodoLi,\n markerComponent: TodoMarker,\n type: 'todo',\n },\n },\n },\n }),\n LineHeightPlugin.extend({\n inject: {\n nodeProps: {\n defaultNodeValue: 1.5,\n validNodeValues: [1, 1.2, 1.5, 2, 3],\n },\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n ],\n },\n }),\n\n // Functionality\n AutoformatPlugin.configure({\n options: autoformatOptions,\n }),\n BlockSelectionPlugin.configure({\n options: {\n areaOptions: {\n behaviour: {\n scrolling: {\n speedDivider: 1.5,\n },\n startThreshold: 10,\n },\n boundaries: `#${scrollSelector}`,\n container: `#${scrollSelector}`,\n selectables: [`#${scrollSelector} .slate-selectable`],\n selectionAreaClass: 'slate-selection-area',\n },\n enableContextMenu: true,\n },\n }),\n BlockMenuPlugin.configure({\n render: { aboveEditable: BlockContextMenu },\n }),\n DndPlugin.configure({\n options: {\n enableScroller: true,\n onDropFiles: ({ dragItem, editor, target }) => {\n editor\n .getTransforms(BaseImagePlugin)\n .insert.imageFromFiles(dragItem.files, {\n at: target,\n nextBlock: false,\n });\n },\n },\n }),\n EmojiPlugin,\n exitBreakPlugin,\n NodeIdPlugin,\n NormalizeTypesPlugin.configure({\n options: {\n rules: [{ path: [0], strictType: HEADING_KEYS.h1 }],\n },\n }),\n resetBlockTypePlugin,\n SelectOnBackspacePlugin.configure({\n options: {\n query: {\n allow: [ImagePlugin.key, HorizontalRulePlugin.key],\n },\n },\n }),\n DeletePlugin,\n SingleLinePlugin,\n softBreakPlugin,\n tabbablePlugin,\n TrailingBlockPlugin.configure({\n options: { type: ParagraphPlugin.key },\n }),\n DragOverCursorPlugin,\n\n // Collaboration\n CommentsPlugin.configure({\n options: {\n comments: commentsData,\n myUserId: '1',\n users: usersData,\n },\n }),\n\n // Deserialization\n DocxPlugin,\n MarkdownPlugin.configure({ options: { indentList: true } }),\n JuicePlugin,\n\n // Testing\n PlaywrightPlugin.configure({\n enabled: process.env.NODE_ENV !== 'production',\n }),\n ],\n value: value,\n },\n []\n );\n};\n\nexport default function PlaygroundDemo({\n id,\n className,\n scrollSelector,\n}: {\n id?: ValueId;\n className?: string;\n scrollSelector?: string;\n}) {\n const containerRef = useRef(null);\n const enabled = settingsStore.use.checkedComponents();\n\n const editor = usePlaygroundEditor(\n id,\n scrollSelector ?? `blockSelection-${id}`\n );\n\n return (\n \n \n \n \n \n \n \n \n \n\n
\n \n \n\n \n \n \n \n \n \n \n\n \n \n \n \n\n \n \n \n
\n
\n
\n );\n}\n\nconst DemoIdContext = React.createContext(undefined);\n\nexport function DemoId({\n id,\n children,\n}: {\n children: React.ReactNode;\n id?: string;\n}) {\n return {children};\n}\n\nexport function useDemoId() {\n return React.useContext(DemoIdContext);\n}\n", "path": "example/playground-demo.tsx", "target": "components/playground-demo.tsx", "type": "registry:example" diff --git a/apps/www/public/r/styles/default/mention-demo.json b/apps/www/public/r/styles/default/mention-demo.json index 4ec689b387..280d360a46 100644 --- a/apps/www/public/r/styles/default/mention-demo.json +++ b/apps/www/public/r/styles/default/mention-demo.json @@ -4,7 +4,7 @@ }, "files": [ { - "content": "'use client';\n\nimport React, { useRef } from 'react';\n\nimport type { ValueId } from '@/config/customizer-plugins';\n\nimport { cn } from '@udecode/cn';\nimport { AIChatPlugin, CopilotPlugin } from '@udecode/plate-ai/react';\nimport { AlignPlugin } from '@udecode/plate-alignment/react';\nimport { AutoformatPlugin } from '@udecode/plate-autoformat/react';\nimport {\n BoldPlugin,\n CodePlugin,\n ItalicPlugin,\n StrikethroughPlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n UnderlinePlugin,\n} from '@udecode/plate-basic-marks/react';\nimport { BlockquotePlugin } from '@udecode/plate-block-quote/react';\nimport { SingleLinePlugin } from '@udecode/plate-break/react';\nimport { CaptionPlugin } from '@udecode/plate-caption/react';\nimport { CodeBlockPlugin } from '@udecode/plate-code-block/react';\nimport { CommentsPlugin } from '@udecode/plate-comments/react';\nimport {\n ParagraphPlugin,\n Plate,\n usePlateEditor,\n} from '@udecode/plate-common/react';\nimport { DatePlugin } from '@udecode/plate-date/react';\nimport { DndPlugin } from '@udecode/plate-dnd';\nimport { DocxPlugin } from '@udecode/plate-docx';\nimport { EmojiPlugin } from '@udecode/plate-emoji/react';\nimport { ExcalidrawPlugin } from '@udecode/plate-excalidraw/react';\nimport {\n FontBackgroundColorPlugin,\n FontColorPlugin,\n FontSizePlugin,\n} from '@udecode/plate-font/react';\nimport { HEADING_KEYS } from '@udecode/plate-heading';\nimport { HeadingPlugin, TocPlugin } from '@udecode/plate-heading/react';\nimport { HighlightPlugin } from '@udecode/plate-highlight/react';\nimport { HorizontalRulePlugin } from '@udecode/plate-horizontal-rule/react';\nimport { IndentPlugin } from '@udecode/plate-indent/react';\nimport { IndentListPlugin } from '@udecode/plate-indent-list/react';\nimport { JuicePlugin } from '@udecode/plate-juice';\nimport { KbdPlugin } from '@udecode/plate-kbd/react';\nimport { ColumnPlugin } from '@udecode/plate-layout/react';\nimport { LineHeightPlugin } from '@udecode/plate-line-height/react';\nimport { LinkPlugin } from '@udecode/plate-link/react';\nimport { ListPlugin, TodoListPlugin } from '@udecode/plate-list/react';\nimport { MarkdownPlugin } from '@udecode/plate-markdown';\nimport { ImagePlugin, MediaEmbedPlugin } from '@udecode/plate-media/react';\nimport { MentionPlugin } from '@udecode/plate-mention/react';\nimport { NodeIdPlugin } from '@udecode/plate-node-id';\nimport { NormalizeTypesPlugin } from '@udecode/plate-normalizers';\nimport { PlaywrightPlugin } from '@udecode/plate-playwright';\nimport { DeletePlugin, SelectOnBackspacePlugin } from '@udecode/plate-select';\nimport {\n BlockMenuPlugin,\n BlockSelectionPlugin,\n} from '@udecode/plate-selection/react';\nimport { SlashPlugin } from '@udecode/plate-slash-command/react';\nimport { TablePlugin } from '@udecode/plate-table/react';\nimport { TogglePlugin } from '@udecode/plate-toggle/react';\nimport { TrailingBlockPlugin } from '@udecode/plate-trailing-block';\nimport Prism from 'prismjs';\n\nimport { CheckPlugin } from '@/components/context/check-plugin';\nimport { settingsStore } from '@/components/context/settings-store';\nimport { aiPlugins } from '@/lib/plate/demo/plugins/ai-plugins';\nimport { getAutoformatOptions } from '@/lib/plate/demo/plugins/autoformatOptions';\nimport { copilotPlugins } from '@/lib/plate/demo/plugins/copilot-plugins';\nimport { createPlateUI } from '@/plate/create-plate-ui';\nimport { editableProps } from '@/plate/demo/editableProps';\nimport { isEnabled } from '@/plate/demo/is-enabled';\nimport { DragOverCursorPlugin } from '@/plate/demo/plugins/DragOverCursorPlugin';\nimport { exitBreakPlugin } from '@/plate/demo/plugins/exitBreakPlugin';\nimport { resetBlockTypePlugin } from '@/plate/demo/plugins/resetBlockTypePlugin';\nimport { softBreakPlugin } from '@/plate/demo/plugins/softBreakPlugin';\nimport { tabbablePlugin } from '@/plate/demo/plugins/tabbablePlugin';\nimport { commentsData, usersData } from '@/plate/demo/values/commentsValue';\nimport { usePlaygroundValue } from '@/plate/demo/values/usePlaygroundValue';\nimport { BlockContextMenu } from '@/components/plate-ui/block-context-menu';\nimport { CommentsPopover } from '@/components/plate-ui/comments-popover';\nimport {\n CursorOverlay,\n SelectionOverlayPlugin,\n} from '@/components/plate-ui/cursor-overlay';\nimport { Editor, EditorContainer } from '@/components/plate-ui/editor';\nimport { FixedToolbar } from '@/components/plate-ui/fixed-toolbar';\nimport { FixedToolbarButtons } from '@/components/plate-ui/fixed-toolbar-buttons';\nimport { FloatingToolbar } from '@/components/plate-ui/floating-toolbar';\nimport { FloatingToolbarButtons } from '@/components/plate-ui/floating-toolbar-buttons';\nimport { ImagePreview } from '@/components/plate-ui/image-preview';\nimport {\n FireLiComponent,\n FireMarker,\n} from '@/components/plate-ui/indent-fire-marker';\nimport {\n TodoLi,\n TodoMarker,\n} from '@/components/plate-ui/indent-todo-marker';\nimport { LinkFloatingToolbar } from '@/components/plate-ui/link-floating-toolbar';\n\nimport { usePlaygroundEnabled } from './usePlaygroundEnabled';\n\nexport const usePlaygroundEditor = (id: any = '', scrollSelector?: string) => {\n const enabledPlugins = settingsStore.use.checkedPlugins();\n const overridePlugins = usePlaygroundEnabled(id);\n const autoformatOptions = getAutoformatOptions(id, enabledPlugins);\n\n const value = usePlaygroundValue(id);\n const key = settingsStore.use.version();\n const editorId = id || 'playground-' + key;\n\n return usePlateEditor(\n {\n id: editorId,\n override: {\n components: createPlateUI({\n draggable: isEnabled('dnd', id),\n placeholder: isEnabled('placeholder', id),\n }),\n plugins: overridePlugins,\n },\n plugins: [\n // AI\n ...(id === 'ai' || enabledPlugins[AIChatPlugin.key] ? aiPlugins : []),\n ...(id === 'copilot' || enabledPlugins[CopilotPlugin.key]\n ? copilotPlugins\n : []),\n // Nodes\n HeadingPlugin,\n TocPlugin.configure({\n options: {\n scrollContainerSelector: `#${scrollSelector}`,\n topOffset: 80,\n },\n }),\n BlockquotePlugin,\n CodeBlockPlugin.configure({\n options: {\n prism: Prism,\n },\n }),\n HorizontalRulePlugin,\n LinkPlugin.extend({\n render: { afterEditable: () => },\n }),\n ...(id === 'list' ? [ListPlugin] : []),\n ImagePlugin.extend({\n options: {\n disableUploadInsert: true,\n },\n render: { afterEditable: ImagePreview },\n }),\n MediaEmbedPlugin,\n CaptionPlugin.configure({\n options: {\n plugins: [ImagePlugin, MediaEmbedPlugin],\n },\n }),\n DatePlugin,\n MentionPlugin.configure({\n options: {\n triggerPreviousCharPattern: /^$|^[\\s\"']$/,\n },\n }),\n SlashPlugin,\n TablePlugin.configure({\n options: {\n enableMerging: id === 'tableMerge',\n },\n }),\n ColumnPlugin,\n SelectionOverlayPlugin,\n\n TodoListPlugin,\n TogglePlugin,\n ExcalidrawPlugin,\n // Marks\n BoldPlugin,\n ItalicPlugin,\n UnderlinePlugin,\n StrikethroughPlugin,\n CodePlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n FontColorPlugin,\n FontBackgroundColorPlugin,\n FontSizePlugin,\n HighlightPlugin,\n KbdPlugin,\n\n // Block Style\n AlignPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n MediaEmbedPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n ImagePlugin.key,\n HEADING_KEYS.h6,\n ],\n },\n }),\n IndentPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n }),\n IndentListPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n options: {\n listStyleTypes: {\n fire: {\n liComponent: FireLiComponent,\n markerComponent: FireMarker,\n type: 'fire',\n },\n todo: {\n liComponent: TodoLi,\n markerComponent: TodoMarker,\n type: 'todo',\n },\n },\n },\n }),\n LineHeightPlugin.extend({\n inject: {\n nodeProps: {\n defaultNodeValue: 1.5,\n validNodeValues: [1, 1.2, 1.5, 2, 3],\n },\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n ],\n },\n }),\n\n // Functionality\n AutoformatPlugin.configure({\n options: autoformatOptions,\n }),\n BlockSelectionPlugin.configure({\n options: {\n areaOptions: {\n behaviour: {\n scrolling: {\n speedDivider: 1.5,\n },\n startThreshold: 10,\n },\n boundaries: `#${scrollSelector}`,\n container: `#${scrollSelector}`,\n selectables: [`#${scrollSelector} .slate-selectable`],\n selectionAreaClass: 'slate-selection-area',\n },\n enableContextMenu: true,\n },\n }),\n BlockMenuPlugin.configure({\n render: { aboveEditable: BlockContextMenu },\n }),\n DndPlugin.configure({\n options: {\n enableScroller: true,\n onDropFiles: ({ dragItem, editor, target }) => {\n editor\n .getTransforms(ImagePlugin)\n .insertImageFromFiles(dragItem.files, {\n at: target,\n nextBlock: false,\n });\n },\n },\n }),\n EmojiPlugin,\n exitBreakPlugin,\n NodeIdPlugin,\n NormalizeTypesPlugin.configure({\n options: {\n rules: [{ path: [0], strictType: HEADING_KEYS.h1 }],\n },\n }),\n resetBlockTypePlugin,\n SelectOnBackspacePlugin.configure({\n options: {\n query: {\n allow: [ImagePlugin.key, HorizontalRulePlugin.key],\n },\n },\n }),\n DeletePlugin,\n SingleLinePlugin,\n softBreakPlugin,\n tabbablePlugin,\n TrailingBlockPlugin.configure({\n options: { type: ParagraphPlugin.key },\n }),\n DragOverCursorPlugin,\n\n // Collaboration\n CommentsPlugin.configure({\n options: {\n comments: commentsData,\n myUserId: '1',\n users: usersData,\n },\n }),\n\n // Deserialization\n DocxPlugin,\n MarkdownPlugin.configure({ options: { indentList: true } }),\n JuicePlugin,\n\n // Testing\n PlaywrightPlugin.configure({\n enabled: process.env.NODE_ENV !== 'production',\n }),\n ],\n value: value,\n },\n []\n );\n};\n\nexport default function PlaygroundDemo({\n id,\n className,\n scrollSelector,\n}: {\n id?: ValueId;\n className?: string;\n scrollSelector?: string;\n}) {\n const containerRef = useRef(null);\n const enabled = settingsStore.use.checkedComponents();\n\n const editor = usePlaygroundEditor(\n id,\n scrollSelector ?? `blockSelection-${id}`\n );\n\n return (\n \n \n \n \n \n \n \n \n \n\n
\n \n \n\n \n \n \n \n \n \n \n\n \n \n \n \n\n \n \n \n
\n
\n
\n );\n}\n\nconst DemoIdContext = React.createContext(undefined);\n\nexport function DemoId({\n id,\n children,\n}: {\n children: React.ReactNode;\n id?: string;\n}) {\n return {children};\n}\n\nexport function useDemoId() {\n return React.useContext(DemoIdContext);\n}\n", + "content": "'use client';\n\nimport React, { useRef } from 'react';\n\nimport type { ValueId } from '@/config/customizer-plugins';\n\nimport { cn } from '@udecode/cn';\nimport { AIChatPlugin, CopilotPlugin } from '@udecode/plate-ai/react';\nimport { AlignPlugin } from '@udecode/plate-alignment/react';\nimport { AutoformatPlugin } from '@udecode/plate-autoformat/react';\nimport {\n BoldPlugin,\n CodePlugin,\n ItalicPlugin,\n StrikethroughPlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n UnderlinePlugin,\n} from '@udecode/plate-basic-marks/react';\nimport { BlockquotePlugin } from '@udecode/plate-block-quote/react';\nimport { SingleLinePlugin } from '@udecode/plate-break/react';\nimport { CaptionPlugin } from '@udecode/plate-caption/react';\nimport { CodeBlockPlugin } from '@udecode/plate-code-block/react';\nimport { CommentsPlugin } from '@udecode/plate-comments/react';\nimport {\n ParagraphPlugin,\n Plate,\n usePlateEditor,\n} from '@udecode/plate-common/react';\nimport { DatePlugin } from '@udecode/plate-date/react';\nimport { DndPlugin } from '@udecode/plate-dnd';\nimport { DocxPlugin } from '@udecode/plate-docx';\nimport { EmojiPlugin } from '@udecode/plate-emoji/react';\nimport { ExcalidrawPlugin } from '@udecode/plate-excalidraw/react';\nimport {\n FontBackgroundColorPlugin,\n FontColorPlugin,\n FontSizePlugin,\n} from '@udecode/plate-font/react';\nimport { HEADING_KEYS } from '@udecode/plate-heading';\nimport { HeadingPlugin, TocPlugin } from '@udecode/plate-heading/react';\nimport { HighlightPlugin } from '@udecode/plate-highlight/react';\nimport { HorizontalRulePlugin } from '@udecode/plate-horizontal-rule/react';\nimport { IndentPlugin } from '@udecode/plate-indent/react';\nimport { IndentListPlugin } from '@udecode/plate-indent-list/react';\nimport { JuicePlugin } from '@udecode/plate-juice';\nimport { KbdPlugin } from '@udecode/plate-kbd/react';\nimport { ColumnPlugin } from '@udecode/plate-layout/react';\nimport { LineHeightPlugin } from '@udecode/plate-line-height/react';\nimport { LinkPlugin } from '@udecode/plate-link/react';\nimport { ListPlugin, TodoListPlugin } from '@udecode/plate-list/react';\nimport { MarkdownPlugin } from '@udecode/plate-markdown';\nimport { BaseImagePlugin } from '@udecode/plate-media';\nimport { ImagePlugin, MediaEmbedPlugin } from '@udecode/plate-media/react';\nimport { MentionPlugin } from '@udecode/plate-mention/react';\nimport { NodeIdPlugin } from '@udecode/plate-node-id';\nimport { NormalizeTypesPlugin } from '@udecode/plate-normalizers';\nimport { PlaywrightPlugin } from '@udecode/plate-playwright';\nimport { DeletePlugin, SelectOnBackspacePlugin } from '@udecode/plate-select';\nimport {\n BlockMenuPlugin,\n BlockSelectionPlugin,\n} from '@udecode/plate-selection/react';\nimport { SlashPlugin } from '@udecode/plate-slash-command/react';\nimport { TablePlugin } from '@udecode/plate-table/react';\nimport { TogglePlugin } from '@udecode/plate-toggle/react';\nimport { TrailingBlockPlugin } from '@udecode/plate-trailing-block';\nimport Prism from 'prismjs';\n\nimport { CheckPlugin } from '@/components/context/check-plugin';\nimport { settingsStore } from '@/components/context/settings-store';\nimport { aiPlugins } from '@/lib/plate/demo/plugins/ai-plugins';\nimport { getAutoformatOptions } from '@/lib/plate/demo/plugins/autoformatOptions';\nimport { copilotPlugins } from '@/lib/plate/demo/plugins/copilot-plugins';\nimport { createPlateUI } from '@/plate/create-plate-ui';\nimport { editableProps } from '@/plate/demo/editableProps';\nimport { isEnabled } from '@/plate/demo/is-enabled';\nimport { DragOverCursorPlugin } from '@/plate/demo/plugins/DragOverCursorPlugin';\nimport { exitBreakPlugin } from '@/plate/demo/plugins/exitBreakPlugin';\nimport { resetBlockTypePlugin } from '@/plate/demo/plugins/resetBlockTypePlugin';\nimport { softBreakPlugin } from '@/plate/demo/plugins/softBreakPlugin';\nimport { tabbablePlugin } from '@/plate/demo/plugins/tabbablePlugin';\nimport { commentsData, usersData } from '@/plate/demo/values/commentsValue';\nimport { usePlaygroundValue } from '@/plate/demo/values/usePlaygroundValue';\nimport { BlockContextMenu } from '@/components/plate-ui/block-context-menu';\nimport { CommentsPopover } from '@/components/plate-ui/comments-popover';\nimport {\n CursorOverlay,\n SelectionOverlayPlugin,\n} from '@/components/plate-ui/cursor-overlay';\nimport { Editor, EditorContainer } from '@/components/plate-ui/editor';\nimport { FixedToolbar } from '@/components/plate-ui/fixed-toolbar';\nimport { FixedToolbarButtons } from '@/components/plate-ui/fixed-toolbar-buttons';\nimport { FloatingToolbar } from '@/components/plate-ui/floating-toolbar';\nimport { FloatingToolbarButtons } from '@/components/plate-ui/floating-toolbar-buttons';\nimport { ImagePreview } from '@/components/plate-ui/image-preview';\nimport {\n FireLiComponent,\n FireMarker,\n} from '@/components/plate-ui/indent-fire-marker';\nimport {\n TodoLi,\n TodoMarker,\n} from '@/components/plate-ui/indent-todo-marker';\nimport { LinkFloatingToolbar } from '@/components/plate-ui/link-floating-toolbar';\n\nimport { usePlaygroundEnabled } from './usePlaygroundEnabled';\n\nexport const usePlaygroundEditor = (id: any = '', scrollSelector?: string) => {\n const enabledPlugins = settingsStore.use.checkedPlugins();\n const overridePlugins = usePlaygroundEnabled(id);\n const autoformatOptions = getAutoformatOptions(id, enabledPlugins);\n\n const value = usePlaygroundValue(id);\n const key = settingsStore.use.version();\n const editorId = id || 'playground-' + key;\n\n return usePlateEditor(\n {\n id: editorId,\n override: {\n components: createPlateUI({\n draggable: isEnabled('dnd', id),\n placeholder: isEnabled('placeholder', id),\n }),\n plugins: overridePlugins,\n },\n plugins: [\n // AI\n ...(id === 'ai' || enabledPlugins[AIChatPlugin.key] ? aiPlugins : []),\n ...(id === 'copilot' || enabledPlugins[CopilotPlugin.key]\n ? copilotPlugins\n : []),\n // Nodes\n HeadingPlugin,\n TocPlugin.configure({\n options: {\n scrollContainerSelector: `#${scrollSelector}`,\n topOffset: 80,\n },\n }),\n BlockquotePlugin,\n CodeBlockPlugin.configure({\n options: {\n prism: Prism,\n },\n }),\n HorizontalRulePlugin,\n LinkPlugin.extend({\n render: { afterEditable: () => },\n }),\n ...(id === 'list' ? [ListPlugin] : []),\n ImagePlugin.extend({\n options: {\n disableUploadInsert: true,\n },\n render: { afterEditable: ImagePreview },\n }),\n MediaEmbedPlugin,\n CaptionPlugin.configure({\n options: {\n plugins: [ImagePlugin, MediaEmbedPlugin],\n },\n }),\n DatePlugin,\n MentionPlugin.configure({\n options: {\n triggerPreviousCharPattern: /^$|^[\\s\"']$/,\n },\n }),\n SlashPlugin,\n TablePlugin.configure({\n options: {\n enableMerging: id === 'tableMerge',\n },\n }),\n ColumnPlugin,\n SelectionOverlayPlugin,\n\n TodoListPlugin,\n TogglePlugin,\n ExcalidrawPlugin,\n // Marks\n BoldPlugin,\n ItalicPlugin,\n UnderlinePlugin,\n StrikethroughPlugin,\n CodePlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n FontColorPlugin,\n FontBackgroundColorPlugin,\n FontSizePlugin,\n HighlightPlugin,\n KbdPlugin,\n\n // Block Style\n AlignPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n MediaEmbedPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n ImagePlugin.key,\n HEADING_KEYS.h6,\n ],\n },\n }),\n IndentPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n }),\n IndentListPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n options: {\n listStyleTypes: {\n fire: {\n liComponent: FireLiComponent,\n markerComponent: FireMarker,\n type: 'fire',\n },\n todo: {\n liComponent: TodoLi,\n markerComponent: TodoMarker,\n type: 'todo',\n },\n },\n },\n }),\n LineHeightPlugin.extend({\n inject: {\n nodeProps: {\n defaultNodeValue: 1.5,\n validNodeValues: [1, 1.2, 1.5, 2, 3],\n },\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n ],\n },\n }),\n\n // Functionality\n AutoformatPlugin.configure({\n options: autoformatOptions,\n }),\n BlockSelectionPlugin.configure({\n options: {\n areaOptions: {\n behaviour: {\n scrolling: {\n speedDivider: 1.5,\n },\n startThreshold: 10,\n },\n boundaries: `#${scrollSelector}`,\n container: `#${scrollSelector}`,\n selectables: [`#${scrollSelector} .slate-selectable`],\n selectionAreaClass: 'slate-selection-area',\n },\n enableContextMenu: true,\n },\n }),\n BlockMenuPlugin.configure({\n render: { aboveEditable: BlockContextMenu },\n }),\n DndPlugin.configure({\n options: {\n enableScroller: true,\n onDropFiles: ({ dragItem, editor, target }) => {\n editor\n .getTransforms(BaseImagePlugin)\n .insert.imageFromFiles(dragItem.files, {\n at: target,\n nextBlock: false,\n });\n },\n },\n }),\n EmojiPlugin,\n exitBreakPlugin,\n NodeIdPlugin,\n NormalizeTypesPlugin.configure({\n options: {\n rules: [{ path: [0], strictType: HEADING_KEYS.h1 }],\n },\n }),\n resetBlockTypePlugin,\n SelectOnBackspacePlugin.configure({\n options: {\n query: {\n allow: [ImagePlugin.key, HorizontalRulePlugin.key],\n },\n },\n }),\n DeletePlugin,\n SingleLinePlugin,\n softBreakPlugin,\n tabbablePlugin,\n TrailingBlockPlugin.configure({\n options: { type: ParagraphPlugin.key },\n }),\n DragOverCursorPlugin,\n\n // Collaboration\n CommentsPlugin.configure({\n options: {\n comments: commentsData,\n myUserId: '1',\n users: usersData,\n },\n }),\n\n // Deserialization\n DocxPlugin,\n MarkdownPlugin.configure({ options: { indentList: true } }),\n JuicePlugin,\n\n // Testing\n PlaywrightPlugin.configure({\n enabled: process.env.NODE_ENV !== 'production',\n }),\n ],\n value: value,\n },\n []\n );\n};\n\nexport default function PlaygroundDemo({\n id,\n className,\n scrollSelector,\n}: {\n id?: ValueId;\n className?: string;\n scrollSelector?: string;\n}) {\n const containerRef = useRef(null);\n const enabled = settingsStore.use.checkedComponents();\n\n const editor = usePlaygroundEditor(\n id,\n scrollSelector ?? `blockSelection-${id}`\n );\n\n return (\n \n \n \n \n \n \n \n \n \n\n
\n \n \n\n \n \n \n \n \n \n \n\n \n \n \n \n\n \n \n \n
\n
\n
\n );\n}\n\nconst DemoIdContext = React.createContext(undefined);\n\nexport function DemoId({\n id,\n children,\n}: {\n children: React.ReactNode;\n id?: string;\n}) {\n return {children};\n}\n\nexport function useDemoId() {\n return React.useContext(DemoIdContext);\n}\n", "path": "example/playground-demo.tsx", "target": "components/playground-demo.tsx", "type": "registry:example" diff --git a/apps/www/public/r/styles/default/mode-demo.json b/apps/www/public/r/styles/default/mode-demo.json index e71ca9f9f0..75e9ab694d 100644 --- a/apps/www/public/r/styles/default/mode-demo.json +++ b/apps/www/public/r/styles/default/mode-demo.json @@ -4,7 +4,7 @@ }, "files": [ { - "content": "'use client';\n\nimport React, { useRef } from 'react';\n\nimport type { ValueId } from '@/config/customizer-plugins';\n\nimport { cn } from '@udecode/cn';\nimport { AIChatPlugin, CopilotPlugin } from '@udecode/plate-ai/react';\nimport { AlignPlugin } from '@udecode/plate-alignment/react';\nimport { AutoformatPlugin } from '@udecode/plate-autoformat/react';\nimport {\n BoldPlugin,\n CodePlugin,\n ItalicPlugin,\n StrikethroughPlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n UnderlinePlugin,\n} from '@udecode/plate-basic-marks/react';\nimport { BlockquotePlugin } from '@udecode/plate-block-quote/react';\nimport { SingleLinePlugin } from '@udecode/plate-break/react';\nimport { CaptionPlugin } from '@udecode/plate-caption/react';\nimport { CodeBlockPlugin } from '@udecode/plate-code-block/react';\nimport { CommentsPlugin } from '@udecode/plate-comments/react';\nimport {\n ParagraphPlugin,\n Plate,\n usePlateEditor,\n} from '@udecode/plate-common/react';\nimport { DatePlugin } from '@udecode/plate-date/react';\nimport { DndPlugin } from '@udecode/plate-dnd';\nimport { DocxPlugin } from '@udecode/plate-docx';\nimport { EmojiPlugin } from '@udecode/plate-emoji/react';\nimport { ExcalidrawPlugin } from '@udecode/plate-excalidraw/react';\nimport {\n FontBackgroundColorPlugin,\n FontColorPlugin,\n FontSizePlugin,\n} from '@udecode/plate-font/react';\nimport { HEADING_KEYS } from '@udecode/plate-heading';\nimport { HeadingPlugin, TocPlugin } from '@udecode/plate-heading/react';\nimport { HighlightPlugin } from '@udecode/plate-highlight/react';\nimport { HorizontalRulePlugin } from '@udecode/plate-horizontal-rule/react';\nimport { IndentPlugin } from '@udecode/plate-indent/react';\nimport { IndentListPlugin } from '@udecode/plate-indent-list/react';\nimport { JuicePlugin } from '@udecode/plate-juice';\nimport { KbdPlugin } from '@udecode/plate-kbd/react';\nimport { ColumnPlugin } from '@udecode/plate-layout/react';\nimport { LineHeightPlugin } from '@udecode/plate-line-height/react';\nimport { LinkPlugin } from '@udecode/plate-link/react';\nimport { ListPlugin, TodoListPlugin } from '@udecode/plate-list/react';\nimport { MarkdownPlugin } from '@udecode/plate-markdown';\nimport { ImagePlugin, MediaEmbedPlugin } from '@udecode/plate-media/react';\nimport { MentionPlugin } from '@udecode/plate-mention/react';\nimport { NodeIdPlugin } from '@udecode/plate-node-id';\nimport { NormalizeTypesPlugin } from '@udecode/plate-normalizers';\nimport { PlaywrightPlugin } from '@udecode/plate-playwright';\nimport { DeletePlugin, SelectOnBackspacePlugin } from '@udecode/plate-select';\nimport {\n BlockMenuPlugin,\n BlockSelectionPlugin,\n} from '@udecode/plate-selection/react';\nimport { SlashPlugin } from '@udecode/plate-slash-command/react';\nimport { TablePlugin } from '@udecode/plate-table/react';\nimport { TogglePlugin } from '@udecode/plate-toggle/react';\nimport { TrailingBlockPlugin } from '@udecode/plate-trailing-block';\nimport Prism from 'prismjs';\n\nimport { CheckPlugin } from '@/components/context/check-plugin';\nimport { settingsStore } from '@/components/context/settings-store';\nimport { aiPlugins } from '@/lib/plate/demo/plugins/ai-plugins';\nimport { getAutoformatOptions } from '@/lib/plate/demo/plugins/autoformatOptions';\nimport { copilotPlugins } from '@/lib/plate/demo/plugins/copilot-plugins';\nimport { createPlateUI } from '@/plate/create-plate-ui';\nimport { editableProps } from '@/plate/demo/editableProps';\nimport { isEnabled } from '@/plate/demo/is-enabled';\nimport { DragOverCursorPlugin } from '@/plate/demo/plugins/DragOverCursorPlugin';\nimport { exitBreakPlugin } from '@/plate/demo/plugins/exitBreakPlugin';\nimport { resetBlockTypePlugin } from '@/plate/demo/plugins/resetBlockTypePlugin';\nimport { softBreakPlugin } from '@/plate/demo/plugins/softBreakPlugin';\nimport { tabbablePlugin } from '@/plate/demo/plugins/tabbablePlugin';\nimport { commentsData, usersData } from '@/plate/demo/values/commentsValue';\nimport { usePlaygroundValue } from '@/plate/demo/values/usePlaygroundValue';\nimport { BlockContextMenu } from '@/components/plate-ui/block-context-menu';\nimport { CommentsPopover } from '@/components/plate-ui/comments-popover';\nimport {\n CursorOverlay,\n SelectionOverlayPlugin,\n} from '@/components/plate-ui/cursor-overlay';\nimport { Editor, EditorContainer } from '@/components/plate-ui/editor';\nimport { FixedToolbar } from '@/components/plate-ui/fixed-toolbar';\nimport { FixedToolbarButtons } from '@/components/plate-ui/fixed-toolbar-buttons';\nimport { FloatingToolbar } from '@/components/plate-ui/floating-toolbar';\nimport { FloatingToolbarButtons } from '@/components/plate-ui/floating-toolbar-buttons';\nimport { ImagePreview } from '@/components/plate-ui/image-preview';\nimport {\n FireLiComponent,\n FireMarker,\n} from '@/components/plate-ui/indent-fire-marker';\nimport {\n TodoLi,\n TodoMarker,\n} from '@/components/plate-ui/indent-todo-marker';\nimport { LinkFloatingToolbar } from '@/components/plate-ui/link-floating-toolbar';\n\nimport { usePlaygroundEnabled } from './usePlaygroundEnabled';\n\nexport const usePlaygroundEditor = (id: any = '', scrollSelector?: string) => {\n const enabledPlugins = settingsStore.use.checkedPlugins();\n const overridePlugins = usePlaygroundEnabled(id);\n const autoformatOptions = getAutoformatOptions(id, enabledPlugins);\n\n const value = usePlaygroundValue(id);\n const key = settingsStore.use.version();\n const editorId = id || 'playground-' + key;\n\n return usePlateEditor(\n {\n id: editorId,\n override: {\n components: createPlateUI({\n draggable: isEnabled('dnd', id),\n placeholder: isEnabled('placeholder', id),\n }),\n plugins: overridePlugins,\n },\n plugins: [\n // AI\n ...(id === 'ai' || enabledPlugins[AIChatPlugin.key] ? aiPlugins : []),\n ...(id === 'copilot' || enabledPlugins[CopilotPlugin.key]\n ? copilotPlugins\n : []),\n // Nodes\n HeadingPlugin,\n TocPlugin.configure({\n options: {\n scrollContainerSelector: `#${scrollSelector}`,\n topOffset: 80,\n },\n }),\n BlockquotePlugin,\n CodeBlockPlugin.configure({\n options: {\n prism: Prism,\n },\n }),\n HorizontalRulePlugin,\n LinkPlugin.extend({\n render: { afterEditable: () => },\n }),\n ...(id === 'list' ? [ListPlugin] : []),\n ImagePlugin.extend({\n options: {\n disableUploadInsert: true,\n },\n render: { afterEditable: ImagePreview },\n }),\n MediaEmbedPlugin,\n CaptionPlugin.configure({\n options: {\n plugins: [ImagePlugin, MediaEmbedPlugin],\n },\n }),\n DatePlugin,\n MentionPlugin.configure({\n options: {\n triggerPreviousCharPattern: /^$|^[\\s\"']$/,\n },\n }),\n SlashPlugin,\n TablePlugin.configure({\n options: {\n enableMerging: id === 'tableMerge',\n },\n }),\n ColumnPlugin,\n SelectionOverlayPlugin,\n\n TodoListPlugin,\n TogglePlugin,\n ExcalidrawPlugin,\n // Marks\n BoldPlugin,\n ItalicPlugin,\n UnderlinePlugin,\n StrikethroughPlugin,\n CodePlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n FontColorPlugin,\n FontBackgroundColorPlugin,\n FontSizePlugin,\n HighlightPlugin,\n KbdPlugin,\n\n // Block Style\n AlignPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n MediaEmbedPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n ImagePlugin.key,\n HEADING_KEYS.h6,\n ],\n },\n }),\n IndentPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n }),\n IndentListPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n options: {\n listStyleTypes: {\n fire: {\n liComponent: FireLiComponent,\n markerComponent: FireMarker,\n type: 'fire',\n },\n todo: {\n liComponent: TodoLi,\n markerComponent: TodoMarker,\n type: 'todo',\n },\n },\n },\n }),\n LineHeightPlugin.extend({\n inject: {\n nodeProps: {\n defaultNodeValue: 1.5,\n validNodeValues: [1, 1.2, 1.5, 2, 3],\n },\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n ],\n },\n }),\n\n // Functionality\n AutoformatPlugin.configure({\n options: autoformatOptions,\n }),\n BlockSelectionPlugin.configure({\n options: {\n areaOptions: {\n behaviour: {\n scrolling: {\n speedDivider: 1.5,\n },\n startThreshold: 10,\n },\n boundaries: `#${scrollSelector}`,\n container: `#${scrollSelector}`,\n selectables: [`#${scrollSelector} .slate-selectable`],\n selectionAreaClass: 'slate-selection-area',\n },\n enableContextMenu: true,\n },\n }),\n BlockMenuPlugin.configure({\n render: { aboveEditable: BlockContextMenu },\n }),\n DndPlugin.configure({\n options: {\n enableScroller: true,\n onDropFiles: ({ dragItem, editor, target }) => {\n editor\n .getTransforms(ImagePlugin)\n .insertImageFromFiles(dragItem.files, {\n at: target,\n nextBlock: false,\n });\n },\n },\n }),\n EmojiPlugin,\n exitBreakPlugin,\n NodeIdPlugin,\n NormalizeTypesPlugin.configure({\n options: {\n rules: [{ path: [0], strictType: HEADING_KEYS.h1 }],\n },\n }),\n resetBlockTypePlugin,\n SelectOnBackspacePlugin.configure({\n options: {\n query: {\n allow: [ImagePlugin.key, HorizontalRulePlugin.key],\n },\n },\n }),\n DeletePlugin,\n SingleLinePlugin,\n softBreakPlugin,\n tabbablePlugin,\n TrailingBlockPlugin.configure({\n options: { type: ParagraphPlugin.key },\n }),\n DragOverCursorPlugin,\n\n // Collaboration\n CommentsPlugin.configure({\n options: {\n comments: commentsData,\n myUserId: '1',\n users: usersData,\n },\n }),\n\n // Deserialization\n DocxPlugin,\n MarkdownPlugin.configure({ options: { indentList: true } }),\n JuicePlugin,\n\n // Testing\n PlaywrightPlugin.configure({\n enabled: process.env.NODE_ENV !== 'production',\n }),\n ],\n value: value,\n },\n []\n );\n};\n\nexport default function PlaygroundDemo({\n id,\n className,\n scrollSelector,\n}: {\n id?: ValueId;\n className?: string;\n scrollSelector?: string;\n}) {\n const containerRef = useRef(null);\n const enabled = settingsStore.use.checkedComponents();\n\n const editor = usePlaygroundEditor(\n id,\n scrollSelector ?? `blockSelection-${id}`\n );\n\n return (\n \n \n \n \n \n \n \n \n \n\n
\n \n \n\n \n \n \n \n \n \n \n\n \n \n \n \n\n \n \n \n
\n
\n
\n );\n}\n\nconst DemoIdContext = React.createContext(undefined);\n\nexport function DemoId({\n id,\n children,\n}: {\n children: React.ReactNode;\n id?: string;\n}) {\n return {children};\n}\n\nexport function useDemoId() {\n return React.useContext(DemoIdContext);\n}\n", + "content": "'use client';\n\nimport React, { useRef } from 'react';\n\nimport type { ValueId } from '@/config/customizer-plugins';\n\nimport { cn } from '@udecode/cn';\nimport { AIChatPlugin, CopilotPlugin } from '@udecode/plate-ai/react';\nimport { AlignPlugin } from '@udecode/plate-alignment/react';\nimport { AutoformatPlugin } from '@udecode/plate-autoformat/react';\nimport {\n BoldPlugin,\n CodePlugin,\n ItalicPlugin,\n StrikethroughPlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n UnderlinePlugin,\n} from '@udecode/plate-basic-marks/react';\nimport { BlockquotePlugin } from '@udecode/plate-block-quote/react';\nimport { SingleLinePlugin } from '@udecode/plate-break/react';\nimport { CaptionPlugin } from '@udecode/plate-caption/react';\nimport { CodeBlockPlugin } from '@udecode/plate-code-block/react';\nimport { CommentsPlugin } from '@udecode/plate-comments/react';\nimport {\n ParagraphPlugin,\n Plate,\n usePlateEditor,\n} from '@udecode/plate-common/react';\nimport { DatePlugin } from '@udecode/plate-date/react';\nimport { DndPlugin } from '@udecode/plate-dnd';\nimport { DocxPlugin } from '@udecode/plate-docx';\nimport { EmojiPlugin } from '@udecode/plate-emoji/react';\nimport { ExcalidrawPlugin } from '@udecode/plate-excalidraw/react';\nimport {\n FontBackgroundColorPlugin,\n FontColorPlugin,\n FontSizePlugin,\n} from '@udecode/plate-font/react';\nimport { HEADING_KEYS } from '@udecode/plate-heading';\nimport { HeadingPlugin, TocPlugin } from '@udecode/plate-heading/react';\nimport { HighlightPlugin } from '@udecode/plate-highlight/react';\nimport { HorizontalRulePlugin } from '@udecode/plate-horizontal-rule/react';\nimport { IndentPlugin } from '@udecode/plate-indent/react';\nimport { IndentListPlugin } from '@udecode/plate-indent-list/react';\nimport { JuicePlugin } from '@udecode/plate-juice';\nimport { KbdPlugin } from '@udecode/plate-kbd/react';\nimport { ColumnPlugin } from '@udecode/plate-layout/react';\nimport { LineHeightPlugin } from '@udecode/plate-line-height/react';\nimport { LinkPlugin } from '@udecode/plate-link/react';\nimport { ListPlugin, TodoListPlugin } from '@udecode/plate-list/react';\nimport { MarkdownPlugin } from '@udecode/plate-markdown';\nimport { BaseImagePlugin } from '@udecode/plate-media';\nimport { ImagePlugin, MediaEmbedPlugin } from '@udecode/plate-media/react';\nimport { MentionPlugin } from '@udecode/plate-mention/react';\nimport { NodeIdPlugin } from '@udecode/plate-node-id';\nimport { NormalizeTypesPlugin } from '@udecode/plate-normalizers';\nimport { PlaywrightPlugin } from '@udecode/plate-playwright';\nimport { DeletePlugin, SelectOnBackspacePlugin } from '@udecode/plate-select';\nimport {\n BlockMenuPlugin,\n BlockSelectionPlugin,\n} from '@udecode/plate-selection/react';\nimport { SlashPlugin } from '@udecode/plate-slash-command/react';\nimport { TablePlugin } from '@udecode/plate-table/react';\nimport { TogglePlugin } from '@udecode/plate-toggle/react';\nimport { TrailingBlockPlugin } from '@udecode/plate-trailing-block';\nimport Prism from 'prismjs';\n\nimport { CheckPlugin } from '@/components/context/check-plugin';\nimport { settingsStore } from '@/components/context/settings-store';\nimport { aiPlugins } from '@/lib/plate/demo/plugins/ai-plugins';\nimport { getAutoformatOptions } from '@/lib/plate/demo/plugins/autoformatOptions';\nimport { copilotPlugins } from '@/lib/plate/demo/plugins/copilot-plugins';\nimport { createPlateUI } from '@/plate/create-plate-ui';\nimport { editableProps } from '@/plate/demo/editableProps';\nimport { isEnabled } from '@/plate/demo/is-enabled';\nimport { DragOverCursorPlugin } from '@/plate/demo/plugins/DragOverCursorPlugin';\nimport { exitBreakPlugin } from '@/plate/demo/plugins/exitBreakPlugin';\nimport { resetBlockTypePlugin } from '@/plate/demo/plugins/resetBlockTypePlugin';\nimport { softBreakPlugin } from '@/plate/demo/plugins/softBreakPlugin';\nimport { tabbablePlugin } from '@/plate/demo/plugins/tabbablePlugin';\nimport { commentsData, usersData } from '@/plate/demo/values/commentsValue';\nimport { usePlaygroundValue } from '@/plate/demo/values/usePlaygroundValue';\nimport { BlockContextMenu } from '@/components/plate-ui/block-context-menu';\nimport { CommentsPopover } from '@/components/plate-ui/comments-popover';\nimport {\n CursorOverlay,\n SelectionOverlayPlugin,\n} from '@/components/plate-ui/cursor-overlay';\nimport { Editor, EditorContainer } from '@/components/plate-ui/editor';\nimport { FixedToolbar } from '@/components/plate-ui/fixed-toolbar';\nimport { FixedToolbarButtons } from '@/components/plate-ui/fixed-toolbar-buttons';\nimport { FloatingToolbar } from '@/components/plate-ui/floating-toolbar';\nimport { FloatingToolbarButtons } from '@/components/plate-ui/floating-toolbar-buttons';\nimport { ImagePreview } from '@/components/plate-ui/image-preview';\nimport {\n FireLiComponent,\n FireMarker,\n} from '@/components/plate-ui/indent-fire-marker';\nimport {\n TodoLi,\n TodoMarker,\n} from '@/components/plate-ui/indent-todo-marker';\nimport { LinkFloatingToolbar } from '@/components/plate-ui/link-floating-toolbar';\n\nimport { usePlaygroundEnabled } from './usePlaygroundEnabled';\n\nexport const usePlaygroundEditor = (id: any = '', scrollSelector?: string) => {\n const enabledPlugins = settingsStore.use.checkedPlugins();\n const overridePlugins = usePlaygroundEnabled(id);\n const autoformatOptions = getAutoformatOptions(id, enabledPlugins);\n\n const value = usePlaygroundValue(id);\n const key = settingsStore.use.version();\n const editorId = id || 'playground-' + key;\n\n return usePlateEditor(\n {\n id: editorId,\n override: {\n components: createPlateUI({\n draggable: isEnabled('dnd', id),\n placeholder: isEnabled('placeholder', id),\n }),\n plugins: overridePlugins,\n },\n plugins: [\n // AI\n ...(id === 'ai' || enabledPlugins[AIChatPlugin.key] ? aiPlugins : []),\n ...(id === 'copilot' || enabledPlugins[CopilotPlugin.key]\n ? copilotPlugins\n : []),\n // Nodes\n HeadingPlugin,\n TocPlugin.configure({\n options: {\n scrollContainerSelector: `#${scrollSelector}`,\n topOffset: 80,\n },\n }),\n BlockquotePlugin,\n CodeBlockPlugin.configure({\n options: {\n prism: Prism,\n },\n }),\n HorizontalRulePlugin,\n LinkPlugin.extend({\n render: { afterEditable: () => },\n }),\n ...(id === 'list' ? [ListPlugin] : []),\n ImagePlugin.extend({\n options: {\n disableUploadInsert: true,\n },\n render: { afterEditable: ImagePreview },\n }),\n MediaEmbedPlugin,\n CaptionPlugin.configure({\n options: {\n plugins: [ImagePlugin, MediaEmbedPlugin],\n },\n }),\n DatePlugin,\n MentionPlugin.configure({\n options: {\n triggerPreviousCharPattern: /^$|^[\\s\"']$/,\n },\n }),\n SlashPlugin,\n TablePlugin.configure({\n options: {\n enableMerging: id === 'tableMerge',\n },\n }),\n ColumnPlugin,\n SelectionOverlayPlugin,\n\n TodoListPlugin,\n TogglePlugin,\n ExcalidrawPlugin,\n // Marks\n BoldPlugin,\n ItalicPlugin,\n UnderlinePlugin,\n StrikethroughPlugin,\n CodePlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n FontColorPlugin,\n FontBackgroundColorPlugin,\n FontSizePlugin,\n HighlightPlugin,\n KbdPlugin,\n\n // Block Style\n AlignPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n MediaEmbedPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n ImagePlugin.key,\n HEADING_KEYS.h6,\n ],\n },\n }),\n IndentPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n }),\n IndentListPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n options: {\n listStyleTypes: {\n fire: {\n liComponent: FireLiComponent,\n markerComponent: FireMarker,\n type: 'fire',\n },\n todo: {\n liComponent: TodoLi,\n markerComponent: TodoMarker,\n type: 'todo',\n },\n },\n },\n }),\n LineHeightPlugin.extend({\n inject: {\n nodeProps: {\n defaultNodeValue: 1.5,\n validNodeValues: [1, 1.2, 1.5, 2, 3],\n },\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n ],\n },\n }),\n\n // Functionality\n AutoformatPlugin.configure({\n options: autoformatOptions,\n }),\n BlockSelectionPlugin.configure({\n options: {\n areaOptions: {\n behaviour: {\n scrolling: {\n speedDivider: 1.5,\n },\n startThreshold: 10,\n },\n boundaries: `#${scrollSelector}`,\n container: `#${scrollSelector}`,\n selectables: [`#${scrollSelector} .slate-selectable`],\n selectionAreaClass: 'slate-selection-area',\n },\n enableContextMenu: true,\n },\n }),\n BlockMenuPlugin.configure({\n render: { aboveEditable: BlockContextMenu },\n }),\n DndPlugin.configure({\n options: {\n enableScroller: true,\n onDropFiles: ({ dragItem, editor, target }) => {\n editor\n .getTransforms(BaseImagePlugin)\n .insert.imageFromFiles(dragItem.files, {\n at: target,\n nextBlock: false,\n });\n },\n },\n }),\n EmojiPlugin,\n exitBreakPlugin,\n NodeIdPlugin,\n NormalizeTypesPlugin.configure({\n options: {\n rules: [{ path: [0], strictType: HEADING_KEYS.h1 }],\n },\n }),\n resetBlockTypePlugin,\n SelectOnBackspacePlugin.configure({\n options: {\n query: {\n allow: [ImagePlugin.key, HorizontalRulePlugin.key],\n },\n },\n }),\n DeletePlugin,\n SingleLinePlugin,\n softBreakPlugin,\n tabbablePlugin,\n TrailingBlockPlugin.configure({\n options: { type: ParagraphPlugin.key },\n }),\n DragOverCursorPlugin,\n\n // Collaboration\n CommentsPlugin.configure({\n options: {\n comments: commentsData,\n myUserId: '1',\n users: usersData,\n },\n }),\n\n // Deserialization\n DocxPlugin,\n MarkdownPlugin.configure({ options: { indentList: true } }),\n JuicePlugin,\n\n // Testing\n PlaywrightPlugin.configure({\n enabled: process.env.NODE_ENV !== 'production',\n }),\n ],\n value: value,\n },\n []\n );\n};\n\nexport default function PlaygroundDemo({\n id,\n className,\n scrollSelector,\n}: {\n id?: ValueId;\n className?: string;\n scrollSelector?: string;\n}) {\n const containerRef = useRef(null);\n const enabled = settingsStore.use.checkedComponents();\n\n const editor = usePlaygroundEditor(\n id,\n scrollSelector ?? `blockSelection-${id}`\n );\n\n return (\n \n \n \n \n \n \n \n \n \n\n
\n \n \n\n \n \n \n \n \n \n \n\n \n \n \n \n\n \n \n \n
\n
\n
\n );\n}\n\nconst DemoIdContext = React.createContext(undefined);\n\nexport function DemoId({\n id,\n children,\n}: {\n children: React.ReactNode;\n id?: string;\n}) {\n return {children};\n}\n\nexport function useDemoId() {\n return React.useContext(DemoIdContext);\n}\n", "path": "example/playground-demo.tsx", "target": "components/playground-demo.tsx", "type": "registry:example" diff --git a/apps/www/public/r/styles/default/placeholder-demo.json b/apps/www/public/r/styles/default/placeholder-demo.json index 2fe089de42..f51c1454f1 100644 --- a/apps/www/public/r/styles/default/placeholder-demo.json +++ b/apps/www/public/r/styles/default/placeholder-demo.json @@ -4,7 +4,7 @@ }, "files": [ { - "content": "'use client';\n\nimport React, { useRef } from 'react';\n\nimport type { ValueId } from '@/config/customizer-plugins';\n\nimport { cn } from '@udecode/cn';\nimport { AIChatPlugin, CopilotPlugin } from '@udecode/plate-ai/react';\nimport { AlignPlugin } from '@udecode/plate-alignment/react';\nimport { AutoformatPlugin } from '@udecode/plate-autoformat/react';\nimport {\n BoldPlugin,\n CodePlugin,\n ItalicPlugin,\n StrikethroughPlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n UnderlinePlugin,\n} from '@udecode/plate-basic-marks/react';\nimport { BlockquotePlugin } from '@udecode/plate-block-quote/react';\nimport { SingleLinePlugin } from '@udecode/plate-break/react';\nimport { CaptionPlugin } from '@udecode/plate-caption/react';\nimport { CodeBlockPlugin } from '@udecode/plate-code-block/react';\nimport { CommentsPlugin } from '@udecode/plate-comments/react';\nimport {\n ParagraphPlugin,\n Plate,\n usePlateEditor,\n} from '@udecode/plate-common/react';\nimport { DatePlugin } from '@udecode/plate-date/react';\nimport { DndPlugin } from '@udecode/plate-dnd';\nimport { DocxPlugin } from '@udecode/plate-docx';\nimport { EmojiPlugin } from '@udecode/plate-emoji/react';\nimport { ExcalidrawPlugin } from '@udecode/plate-excalidraw/react';\nimport {\n FontBackgroundColorPlugin,\n FontColorPlugin,\n FontSizePlugin,\n} from '@udecode/plate-font/react';\nimport { HEADING_KEYS } from '@udecode/plate-heading';\nimport { HeadingPlugin, TocPlugin } from '@udecode/plate-heading/react';\nimport { HighlightPlugin } from '@udecode/plate-highlight/react';\nimport { HorizontalRulePlugin } from '@udecode/plate-horizontal-rule/react';\nimport { IndentPlugin } from '@udecode/plate-indent/react';\nimport { IndentListPlugin } from '@udecode/plate-indent-list/react';\nimport { JuicePlugin } from '@udecode/plate-juice';\nimport { KbdPlugin } from '@udecode/plate-kbd/react';\nimport { ColumnPlugin } from '@udecode/plate-layout/react';\nimport { LineHeightPlugin } from '@udecode/plate-line-height/react';\nimport { LinkPlugin } from '@udecode/plate-link/react';\nimport { ListPlugin, TodoListPlugin } from '@udecode/plate-list/react';\nimport { MarkdownPlugin } from '@udecode/plate-markdown';\nimport { ImagePlugin, MediaEmbedPlugin } from '@udecode/plate-media/react';\nimport { MentionPlugin } from '@udecode/plate-mention/react';\nimport { NodeIdPlugin } from '@udecode/plate-node-id';\nimport { NormalizeTypesPlugin } from '@udecode/plate-normalizers';\nimport { PlaywrightPlugin } from '@udecode/plate-playwright';\nimport { DeletePlugin, SelectOnBackspacePlugin } from '@udecode/plate-select';\nimport {\n BlockMenuPlugin,\n BlockSelectionPlugin,\n} from '@udecode/plate-selection/react';\nimport { SlashPlugin } from '@udecode/plate-slash-command/react';\nimport { TablePlugin } from '@udecode/plate-table/react';\nimport { TogglePlugin } from '@udecode/plate-toggle/react';\nimport { TrailingBlockPlugin } from '@udecode/plate-trailing-block';\nimport Prism from 'prismjs';\n\nimport { CheckPlugin } from '@/components/context/check-plugin';\nimport { settingsStore } from '@/components/context/settings-store';\nimport { aiPlugins } from '@/lib/plate/demo/plugins/ai-plugins';\nimport { getAutoformatOptions } from '@/lib/plate/demo/plugins/autoformatOptions';\nimport { copilotPlugins } from '@/lib/plate/demo/plugins/copilot-plugins';\nimport { createPlateUI } from '@/plate/create-plate-ui';\nimport { editableProps } from '@/plate/demo/editableProps';\nimport { isEnabled } from '@/plate/demo/is-enabled';\nimport { DragOverCursorPlugin } from '@/plate/demo/plugins/DragOverCursorPlugin';\nimport { exitBreakPlugin } from '@/plate/demo/plugins/exitBreakPlugin';\nimport { resetBlockTypePlugin } from '@/plate/demo/plugins/resetBlockTypePlugin';\nimport { softBreakPlugin } from '@/plate/demo/plugins/softBreakPlugin';\nimport { tabbablePlugin } from '@/plate/demo/plugins/tabbablePlugin';\nimport { commentsData, usersData } from '@/plate/demo/values/commentsValue';\nimport { usePlaygroundValue } from '@/plate/demo/values/usePlaygroundValue';\nimport { BlockContextMenu } from '@/components/plate-ui/block-context-menu';\nimport { CommentsPopover } from '@/components/plate-ui/comments-popover';\nimport {\n CursorOverlay,\n SelectionOverlayPlugin,\n} from '@/components/plate-ui/cursor-overlay';\nimport { Editor, EditorContainer } from '@/components/plate-ui/editor';\nimport { FixedToolbar } from '@/components/plate-ui/fixed-toolbar';\nimport { FixedToolbarButtons } from '@/components/plate-ui/fixed-toolbar-buttons';\nimport { FloatingToolbar } from '@/components/plate-ui/floating-toolbar';\nimport { FloatingToolbarButtons } from '@/components/plate-ui/floating-toolbar-buttons';\nimport { ImagePreview } from '@/components/plate-ui/image-preview';\nimport {\n FireLiComponent,\n FireMarker,\n} from '@/components/plate-ui/indent-fire-marker';\nimport {\n TodoLi,\n TodoMarker,\n} from '@/components/plate-ui/indent-todo-marker';\nimport { LinkFloatingToolbar } from '@/components/plate-ui/link-floating-toolbar';\n\nimport { usePlaygroundEnabled } from './usePlaygroundEnabled';\n\nexport const usePlaygroundEditor = (id: any = '', scrollSelector?: string) => {\n const enabledPlugins = settingsStore.use.checkedPlugins();\n const overridePlugins = usePlaygroundEnabled(id);\n const autoformatOptions = getAutoformatOptions(id, enabledPlugins);\n\n const value = usePlaygroundValue(id);\n const key = settingsStore.use.version();\n const editorId = id || 'playground-' + key;\n\n return usePlateEditor(\n {\n id: editorId,\n override: {\n components: createPlateUI({\n draggable: isEnabled('dnd', id),\n placeholder: isEnabled('placeholder', id),\n }),\n plugins: overridePlugins,\n },\n plugins: [\n // AI\n ...(id === 'ai' || enabledPlugins[AIChatPlugin.key] ? aiPlugins : []),\n ...(id === 'copilot' || enabledPlugins[CopilotPlugin.key]\n ? copilotPlugins\n : []),\n // Nodes\n HeadingPlugin,\n TocPlugin.configure({\n options: {\n scrollContainerSelector: `#${scrollSelector}`,\n topOffset: 80,\n },\n }),\n BlockquotePlugin,\n CodeBlockPlugin.configure({\n options: {\n prism: Prism,\n },\n }),\n HorizontalRulePlugin,\n LinkPlugin.extend({\n render: { afterEditable: () => },\n }),\n ...(id === 'list' ? [ListPlugin] : []),\n ImagePlugin.extend({\n options: {\n disableUploadInsert: true,\n },\n render: { afterEditable: ImagePreview },\n }),\n MediaEmbedPlugin,\n CaptionPlugin.configure({\n options: {\n plugins: [ImagePlugin, MediaEmbedPlugin],\n },\n }),\n DatePlugin,\n MentionPlugin.configure({\n options: {\n triggerPreviousCharPattern: /^$|^[\\s\"']$/,\n },\n }),\n SlashPlugin,\n TablePlugin.configure({\n options: {\n enableMerging: id === 'tableMerge',\n },\n }),\n ColumnPlugin,\n SelectionOverlayPlugin,\n\n TodoListPlugin,\n TogglePlugin,\n ExcalidrawPlugin,\n // Marks\n BoldPlugin,\n ItalicPlugin,\n UnderlinePlugin,\n StrikethroughPlugin,\n CodePlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n FontColorPlugin,\n FontBackgroundColorPlugin,\n FontSizePlugin,\n HighlightPlugin,\n KbdPlugin,\n\n // Block Style\n AlignPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n MediaEmbedPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n ImagePlugin.key,\n HEADING_KEYS.h6,\n ],\n },\n }),\n IndentPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n }),\n IndentListPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n options: {\n listStyleTypes: {\n fire: {\n liComponent: FireLiComponent,\n markerComponent: FireMarker,\n type: 'fire',\n },\n todo: {\n liComponent: TodoLi,\n markerComponent: TodoMarker,\n type: 'todo',\n },\n },\n },\n }),\n LineHeightPlugin.extend({\n inject: {\n nodeProps: {\n defaultNodeValue: 1.5,\n validNodeValues: [1, 1.2, 1.5, 2, 3],\n },\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n ],\n },\n }),\n\n // Functionality\n AutoformatPlugin.configure({\n options: autoformatOptions,\n }),\n BlockSelectionPlugin.configure({\n options: {\n areaOptions: {\n behaviour: {\n scrolling: {\n speedDivider: 1.5,\n },\n startThreshold: 10,\n },\n boundaries: `#${scrollSelector}`,\n container: `#${scrollSelector}`,\n selectables: [`#${scrollSelector} .slate-selectable`],\n selectionAreaClass: 'slate-selection-area',\n },\n enableContextMenu: true,\n },\n }),\n BlockMenuPlugin.configure({\n render: { aboveEditable: BlockContextMenu },\n }),\n DndPlugin.configure({\n options: {\n enableScroller: true,\n onDropFiles: ({ dragItem, editor, target }) => {\n editor\n .getTransforms(ImagePlugin)\n .insertImageFromFiles(dragItem.files, {\n at: target,\n nextBlock: false,\n });\n },\n },\n }),\n EmojiPlugin,\n exitBreakPlugin,\n NodeIdPlugin,\n NormalizeTypesPlugin.configure({\n options: {\n rules: [{ path: [0], strictType: HEADING_KEYS.h1 }],\n },\n }),\n resetBlockTypePlugin,\n SelectOnBackspacePlugin.configure({\n options: {\n query: {\n allow: [ImagePlugin.key, HorizontalRulePlugin.key],\n },\n },\n }),\n DeletePlugin,\n SingleLinePlugin,\n softBreakPlugin,\n tabbablePlugin,\n TrailingBlockPlugin.configure({\n options: { type: ParagraphPlugin.key },\n }),\n DragOverCursorPlugin,\n\n // Collaboration\n CommentsPlugin.configure({\n options: {\n comments: commentsData,\n myUserId: '1',\n users: usersData,\n },\n }),\n\n // Deserialization\n DocxPlugin,\n MarkdownPlugin.configure({ options: { indentList: true } }),\n JuicePlugin,\n\n // Testing\n PlaywrightPlugin.configure({\n enabled: process.env.NODE_ENV !== 'production',\n }),\n ],\n value: value,\n },\n []\n );\n};\n\nexport default function PlaygroundDemo({\n id,\n className,\n scrollSelector,\n}: {\n id?: ValueId;\n className?: string;\n scrollSelector?: string;\n}) {\n const containerRef = useRef(null);\n const enabled = settingsStore.use.checkedComponents();\n\n const editor = usePlaygroundEditor(\n id,\n scrollSelector ?? `blockSelection-${id}`\n );\n\n return (\n \n \n \n \n \n \n \n \n \n\n
\n \n \n\n \n \n \n \n \n \n \n\n \n \n \n \n\n \n \n \n
\n
\n
\n );\n}\n\nconst DemoIdContext = React.createContext(undefined);\n\nexport function DemoId({\n id,\n children,\n}: {\n children: React.ReactNode;\n id?: string;\n}) {\n return {children};\n}\n\nexport function useDemoId() {\n return React.useContext(DemoIdContext);\n}\n", + "content": "'use client';\n\nimport React, { useRef } from 'react';\n\nimport type { ValueId } from '@/config/customizer-plugins';\n\nimport { cn } from '@udecode/cn';\nimport { AIChatPlugin, CopilotPlugin } from '@udecode/plate-ai/react';\nimport { AlignPlugin } from '@udecode/plate-alignment/react';\nimport { AutoformatPlugin } from '@udecode/plate-autoformat/react';\nimport {\n BoldPlugin,\n CodePlugin,\n ItalicPlugin,\n StrikethroughPlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n UnderlinePlugin,\n} from '@udecode/plate-basic-marks/react';\nimport { BlockquotePlugin } from '@udecode/plate-block-quote/react';\nimport { SingleLinePlugin } from '@udecode/plate-break/react';\nimport { CaptionPlugin } from '@udecode/plate-caption/react';\nimport { CodeBlockPlugin } from '@udecode/plate-code-block/react';\nimport { CommentsPlugin } from '@udecode/plate-comments/react';\nimport {\n ParagraphPlugin,\n Plate,\n usePlateEditor,\n} from '@udecode/plate-common/react';\nimport { DatePlugin } from '@udecode/plate-date/react';\nimport { DndPlugin } from '@udecode/plate-dnd';\nimport { DocxPlugin } from '@udecode/plate-docx';\nimport { EmojiPlugin } from '@udecode/plate-emoji/react';\nimport { ExcalidrawPlugin } from '@udecode/plate-excalidraw/react';\nimport {\n FontBackgroundColorPlugin,\n FontColorPlugin,\n FontSizePlugin,\n} from '@udecode/plate-font/react';\nimport { HEADING_KEYS } from '@udecode/plate-heading';\nimport { HeadingPlugin, TocPlugin } from '@udecode/plate-heading/react';\nimport { HighlightPlugin } from '@udecode/plate-highlight/react';\nimport { HorizontalRulePlugin } from '@udecode/plate-horizontal-rule/react';\nimport { IndentPlugin } from '@udecode/plate-indent/react';\nimport { IndentListPlugin } from '@udecode/plate-indent-list/react';\nimport { JuicePlugin } from '@udecode/plate-juice';\nimport { KbdPlugin } from '@udecode/plate-kbd/react';\nimport { ColumnPlugin } from '@udecode/plate-layout/react';\nimport { LineHeightPlugin } from '@udecode/plate-line-height/react';\nimport { LinkPlugin } from '@udecode/plate-link/react';\nimport { ListPlugin, TodoListPlugin } from '@udecode/plate-list/react';\nimport { MarkdownPlugin } from '@udecode/plate-markdown';\nimport { BaseImagePlugin } from '@udecode/plate-media';\nimport { ImagePlugin, MediaEmbedPlugin } from '@udecode/plate-media/react';\nimport { MentionPlugin } from '@udecode/plate-mention/react';\nimport { NodeIdPlugin } from '@udecode/plate-node-id';\nimport { NormalizeTypesPlugin } from '@udecode/plate-normalizers';\nimport { PlaywrightPlugin } from '@udecode/plate-playwright';\nimport { DeletePlugin, SelectOnBackspacePlugin } from '@udecode/plate-select';\nimport {\n BlockMenuPlugin,\n BlockSelectionPlugin,\n} from '@udecode/plate-selection/react';\nimport { SlashPlugin } from '@udecode/plate-slash-command/react';\nimport { TablePlugin } from '@udecode/plate-table/react';\nimport { TogglePlugin } from '@udecode/plate-toggle/react';\nimport { TrailingBlockPlugin } from '@udecode/plate-trailing-block';\nimport Prism from 'prismjs';\n\nimport { CheckPlugin } from '@/components/context/check-plugin';\nimport { settingsStore } from '@/components/context/settings-store';\nimport { aiPlugins } from '@/lib/plate/demo/plugins/ai-plugins';\nimport { getAutoformatOptions } from '@/lib/plate/demo/plugins/autoformatOptions';\nimport { copilotPlugins } from '@/lib/plate/demo/plugins/copilot-plugins';\nimport { createPlateUI } from '@/plate/create-plate-ui';\nimport { editableProps } from '@/plate/demo/editableProps';\nimport { isEnabled } from '@/plate/demo/is-enabled';\nimport { DragOverCursorPlugin } from '@/plate/demo/plugins/DragOverCursorPlugin';\nimport { exitBreakPlugin } from '@/plate/demo/plugins/exitBreakPlugin';\nimport { resetBlockTypePlugin } from '@/plate/demo/plugins/resetBlockTypePlugin';\nimport { softBreakPlugin } from '@/plate/demo/plugins/softBreakPlugin';\nimport { tabbablePlugin } from '@/plate/demo/plugins/tabbablePlugin';\nimport { commentsData, usersData } from '@/plate/demo/values/commentsValue';\nimport { usePlaygroundValue } from '@/plate/demo/values/usePlaygroundValue';\nimport { BlockContextMenu } from '@/components/plate-ui/block-context-menu';\nimport { CommentsPopover } from '@/components/plate-ui/comments-popover';\nimport {\n CursorOverlay,\n SelectionOverlayPlugin,\n} from '@/components/plate-ui/cursor-overlay';\nimport { Editor, EditorContainer } from '@/components/plate-ui/editor';\nimport { FixedToolbar } from '@/components/plate-ui/fixed-toolbar';\nimport { FixedToolbarButtons } from '@/components/plate-ui/fixed-toolbar-buttons';\nimport { FloatingToolbar } from '@/components/plate-ui/floating-toolbar';\nimport { FloatingToolbarButtons } from '@/components/plate-ui/floating-toolbar-buttons';\nimport { ImagePreview } from '@/components/plate-ui/image-preview';\nimport {\n FireLiComponent,\n FireMarker,\n} from '@/components/plate-ui/indent-fire-marker';\nimport {\n TodoLi,\n TodoMarker,\n} from '@/components/plate-ui/indent-todo-marker';\nimport { LinkFloatingToolbar } from '@/components/plate-ui/link-floating-toolbar';\n\nimport { usePlaygroundEnabled } from './usePlaygroundEnabled';\n\nexport const usePlaygroundEditor = (id: any = '', scrollSelector?: string) => {\n const enabledPlugins = settingsStore.use.checkedPlugins();\n const overridePlugins = usePlaygroundEnabled(id);\n const autoformatOptions = getAutoformatOptions(id, enabledPlugins);\n\n const value = usePlaygroundValue(id);\n const key = settingsStore.use.version();\n const editorId = id || 'playground-' + key;\n\n return usePlateEditor(\n {\n id: editorId,\n override: {\n components: createPlateUI({\n draggable: isEnabled('dnd', id),\n placeholder: isEnabled('placeholder', id),\n }),\n plugins: overridePlugins,\n },\n plugins: [\n // AI\n ...(id === 'ai' || enabledPlugins[AIChatPlugin.key] ? aiPlugins : []),\n ...(id === 'copilot' || enabledPlugins[CopilotPlugin.key]\n ? copilotPlugins\n : []),\n // Nodes\n HeadingPlugin,\n TocPlugin.configure({\n options: {\n scrollContainerSelector: `#${scrollSelector}`,\n topOffset: 80,\n },\n }),\n BlockquotePlugin,\n CodeBlockPlugin.configure({\n options: {\n prism: Prism,\n },\n }),\n HorizontalRulePlugin,\n LinkPlugin.extend({\n render: { afterEditable: () => },\n }),\n ...(id === 'list' ? [ListPlugin] : []),\n ImagePlugin.extend({\n options: {\n disableUploadInsert: true,\n },\n render: { afterEditable: ImagePreview },\n }),\n MediaEmbedPlugin,\n CaptionPlugin.configure({\n options: {\n plugins: [ImagePlugin, MediaEmbedPlugin],\n },\n }),\n DatePlugin,\n MentionPlugin.configure({\n options: {\n triggerPreviousCharPattern: /^$|^[\\s\"']$/,\n },\n }),\n SlashPlugin,\n TablePlugin.configure({\n options: {\n enableMerging: id === 'tableMerge',\n },\n }),\n ColumnPlugin,\n SelectionOverlayPlugin,\n\n TodoListPlugin,\n TogglePlugin,\n ExcalidrawPlugin,\n // Marks\n BoldPlugin,\n ItalicPlugin,\n UnderlinePlugin,\n StrikethroughPlugin,\n CodePlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n FontColorPlugin,\n FontBackgroundColorPlugin,\n FontSizePlugin,\n HighlightPlugin,\n KbdPlugin,\n\n // Block Style\n AlignPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n MediaEmbedPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n ImagePlugin.key,\n HEADING_KEYS.h6,\n ],\n },\n }),\n IndentPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n }),\n IndentListPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n options: {\n listStyleTypes: {\n fire: {\n liComponent: FireLiComponent,\n markerComponent: FireMarker,\n type: 'fire',\n },\n todo: {\n liComponent: TodoLi,\n markerComponent: TodoMarker,\n type: 'todo',\n },\n },\n },\n }),\n LineHeightPlugin.extend({\n inject: {\n nodeProps: {\n defaultNodeValue: 1.5,\n validNodeValues: [1, 1.2, 1.5, 2, 3],\n },\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n ],\n },\n }),\n\n // Functionality\n AutoformatPlugin.configure({\n options: autoformatOptions,\n }),\n BlockSelectionPlugin.configure({\n options: {\n areaOptions: {\n behaviour: {\n scrolling: {\n speedDivider: 1.5,\n },\n startThreshold: 10,\n },\n boundaries: `#${scrollSelector}`,\n container: `#${scrollSelector}`,\n selectables: [`#${scrollSelector} .slate-selectable`],\n selectionAreaClass: 'slate-selection-area',\n },\n enableContextMenu: true,\n },\n }),\n BlockMenuPlugin.configure({\n render: { aboveEditable: BlockContextMenu },\n }),\n DndPlugin.configure({\n options: {\n enableScroller: true,\n onDropFiles: ({ dragItem, editor, target }) => {\n editor\n .getTransforms(BaseImagePlugin)\n .insert.imageFromFiles(dragItem.files, {\n at: target,\n nextBlock: false,\n });\n },\n },\n }),\n EmojiPlugin,\n exitBreakPlugin,\n NodeIdPlugin,\n NormalizeTypesPlugin.configure({\n options: {\n rules: [{ path: [0], strictType: HEADING_KEYS.h1 }],\n },\n }),\n resetBlockTypePlugin,\n SelectOnBackspacePlugin.configure({\n options: {\n query: {\n allow: [ImagePlugin.key, HorizontalRulePlugin.key],\n },\n },\n }),\n DeletePlugin,\n SingleLinePlugin,\n softBreakPlugin,\n tabbablePlugin,\n TrailingBlockPlugin.configure({\n options: { type: ParagraphPlugin.key },\n }),\n DragOverCursorPlugin,\n\n // Collaboration\n CommentsPlugin.configure({\n options: {\n comments: commentsData,\n myUserId: '1',\n users: usersData,\n },\n }),\n\n // Deserialization\n DocxPlugin,\n MarkdownPlugin.configure({ options: { indentList: true } }),\n JuicePlugin,\n\n // Testing\n PlaywrightPlugin.configure({\n enabled: process.env.NODE_ENV !== 'production',\n }),\n ],\n value: value,\n },\n []\n );\n};\n\nexport default function PlaygroundDemo({\n id,\n className,\n scrollSelector,\n}: {\n id?: ValueId;\n className?: string;\n scrollSelector?: string;\n}) {\n const containerRef = useRef(null);\n const enabled = settingsStore.use.checkedComponents();\n\n const editor = usePlaygroundEditor(\n id,\n scrollSelector ?? `blockSelection-${id}`\n );\n\n return (\n \n \n \n \n \n \n \n \n \n\n
\n \n \n\n \n \n \n \n \n \n \n\n \n \n \n \n\n \n \n \n
\n
\n
\n );\n}\n\nconst DemoIdContext = React.createContext(undefined);\n\nexport function DemoId({\n id,\n children,\n}: {\n children: React.ReactNode;\n id?: string;\n}) {\n return {children};\n}\n\nexport function useDemoId() {\n return React.useContext(DemoIdContext);\n}\n", "path": "example/playground-demo.tsx", "target": "components/playground-demo.tsx", "type": "registry:example" diff --git a/apps/www/public/r/styles/default/playground-demo.json b/apps/www/public/r/styles/default/playground-demo.json index 8027bbb752..aa7ce31453 100644 --- a/apps/www/public/r/styles/default/playground-demo.json +++ b/apps/www/public/r/styles/default/playground-demo.json @@ -1,7 +1,7 @@ { "files": [ { - "content": "'use client';\n\nimport React, { useRef } from 'react';\n\nimport type { ValueId } from '@/config/customizer-plugins';\n\nimport { cn } from '@udecode/cn';\nimport { AIChatPlugin, CopilotPlugin } from '@udecode/plate-ai/react';\nimport { AlignPlugin } from '@udecode/plate-alignment/react';\nimport { AutoformatPlugin } from '@udecode/plate-autoformat/react';\nimport {\n BoldPlugin,\n CodePlugin,\n ItalicPlugin,\n StrikethroughPlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n UnderlinePlugin,\n} from '@udecode/plate-basic-marks/react';\nimport { BlockquotePlugin } from '@udecode/plate-block-quote/react';\nimport { SingleLinePlugin } from '@udecode/plate-break/react';\nimport { CaptionPlugin } from '@udecode/plate-caption/react';\nimport { CodeBlockPlugin } from '@udecode/plate-code-block/react';\nimport { CommentsPlugin } from '@udecode/plate-comments/react';\nimport {\n ParagraphPlugin,\n Plate,\n usePlateEditor,\n} from '@udecode/plate-common/react';\nimport { DatePlugin } from '@udecode/plate-date/react';\nimport { DndPlugin } from '@udecode/plate-dnd';\nimport { DocxPlugin } from '@udecode/plate-docx';\nimport { EmojiPlugin } from '@udecode/plate-emoji/react';\nimport { ExcalidrawPlugin } from '@udecode/plate-excalidraw/react';\nimport {\n FontBackgroundColorPlugin,\n FontColorPlugin,\n FontSizePlugin,\n} from '@udecode/plate-font/react';\nimport { HEADING_KEYS } from '@udecode/plate-heading';\nimport { HeadingPlugin, TocPlugin } from '@udecode/plate-heading/react';\nimport { HighlightPlugin } from '@udecode/plate-highlight/react';\nimport { HorizontalRulePlugin } from '@udecode/plate-horizontal-rule/react';\nimport { IndentPlugin } from '@udecode/plate-indent/react';\nimport { IndentListPlugin } from '@udecode/plate-indent-list/react';\nimport { JuicePlugin } from '@udecode/plate-juice';\nimport { KbdPlugin } from '@udecode/plate-kbd/react';\nimport { ColumnPlugin } from '@udecode/plate-layout/react';\nimport { LineHeightPlugin } from '@udecode/plate-line-height/react';\nimport { LinkPlugin } from '@udecode/plate-link/react';\nimport { ListPlugin, TodoListPlugin } from '@udecode/plate-list/react';\nimport { MarkdownPlugin } from '@udecode/plate-markdown';\nimport { ImagePlugin, MediaEmbedPlugin } from '@udecode/plate-media/react';\nimport { MentionPlugin } from '@udecode/plate-mention/react';\nimport { NodeIdPlugin } from '@udecode/plate-node-id';\nimport { NormalizeTypesPlugin } from '@udecode/plate-normalizers';\nimport { PlaywrightPlugin } from '@udecode/plate-playwright';\nimport { DeletePlugin, SelectOnBackspacePlugin } from '@udecode/plate-select';\nimport {\n BlockMenuPlugin,\n BlockSelectionPlugin,\n} from '@udecode/plate-selection/react';\nimport { SlashPlugin } from '@udecode/plate-slash-command/react';\nimport { TablePlugin } from '@udecode/plate-table/react';\nimport { TogglePlugin } from '@udecode/plate-toggle/react';\nimport { TrailingBlockPlugin } from '@udecode/plate-trailing-block';\nimport Prism from 'prismjs';\n\nimport { CheckPlugin } from '@/components/context/check-plugin';\nimport { settingsStore } from '@/components/context/settings-store';\nimport { aiPlugins } from '@/lib/plate/demo/plugins/ai-plugins';\nimport { getAutoformatOptions } from '@/lib/plate/demo/plugins/autoformatOptions';\nimport { copilotPlugins } from '@/lib/plate/demo/plugins/copilot-plugins';\nimport { createPlateUI } from '@/plate/create-plate-ui';\nimport { editableProps } from '@/plate/demo/editableProps';\nimport { isEnabled } from '@/plate/demo/is-enabled';\nimport { DragOverCursorPlugin } from '@/plate/demo/plugins/DragOverCursorPlugin';\nimport { exitBreakPlugin } from '@/plate/demo/plugins/exitBreakPlugin';\nimport { resetBlockTypePlugin } from '@/plate/demo/plugins/resetBlockTypePlugin';\nimport { softBreakPlugin } from '@/plate/demo/plugins/softBreakPlugin';\nimport { tabbablePlugin } from '@/plate/demo/plugins/tabbablePlugin';\nimport { commentsData, usersData } from '@/plate/demo/values/commentsValue';\nimport { usePlaygroundValue } from '@/plate/demo/values/usePlaygroundValue';\nimport { BlockContextMenu } from '@/components/plate-ui/block-context-menu';\nimport { CommentsPopover } from '@/components/plate-ui/comments-popover';\nimport {\n CursorOverlay,\n SelectionOverlayPlugin,\n} from '@/components/plate-ui/cursor-overlay';\nimport { Editor, EditorContainer } from '@/components/plate-ui/editor';\nimport { FixedToolbar } from '@/components/plate-ui/fixed-toolbar';\nimport { FixedToolbarButtons } from '@/components/plate-ui/fixed-toolbar-buttons';\nimport { FloatingToolbar } from '@/components/plate-ui/floating-toolbar';\nimport { FloatingToolbarButtons } from '@/components/plate-ui/floating-toolbar-buttons';\nimport { ImagePreview } from '@/components/plate-ui/image-preview';\nimport {\n FireLiComponent,\n FireMarker,\n} from '@/components/plate-ui/indent-fire-marker';\nimport {\n TodoLi,\n TodoMarker,\n} from '@/components/plate-ui/indent-todo-marker';\nimport { LinkFloatingToolbar } from '@/components/plate-ui/link-floating-toolbar';\n\nimport { usePlaygroundEnabled } from './usePlaygroundEnabled';\n\nexport const usePlaygroundEditor = (id: any = '', scrollSelector?: string) => {\n const enabledPlugins = settingsStore.use.checkedPlugins();\n const overridePlugins = usePlaygroundEnabled(id);\n const autoformatOptions = getAutoformatOptions(id, enabledPlugins);\n\n const value = usePlaygroundValue(id);\n const key = settingsStore.use.version();\n const editorId = id || 'playground-' + key;\n\n return usePlateEditor(\n {\n id: editorId,\n override: {\n components: createPlateUI({\n draggable: isEnabled('dnd', id),\n placeholder: isEnabled('placeholder', id),\n }),\n plugins: overridePlugins,\n },\n plugins: [\n // AI\n ...(id === 'ai' || enabledPlugins[AIChatPlugin.key] ? aiPlugins : []),\n ...(id === 'copilot' || enabledPlugins[CopilotPlugin.key]\n ? copilotPlugins\n : []),\n // Nodes\n HeadingPlugin,\n TocPlugin.configure({\n options: {\n scrollContainerSelector: `#${scrollSelector}`,\n topOffset: 80,\n },\n }),\n BlockquotePlugin,\n CodeBlockPlugin.configure({\n options: {\n prism: Prism,\n },\n }),\n HorizontalRulePlugin,\n LinkPlugin.extend({\n render: { afterEditable: () => },\n }),\n ...(id === 'list' ? [ListPlugin] : []),\n ImagePlugin.extend({\n options: {\n disableUploadInsert: true,\n },\n render: { afterEditable: ImagePreview },\n }),\n MediaEmbedPlugin,\n CaptionPlugin.configure({\n options: {\n plugins: [ImagePlugin, MediaEmbedPlugin],\n },\n }),\n DatePlugin,\n MentionPlugin.configure({\n options: {\n triggerPreviousCharPattern: /^$|^[\\s\"']$/,\n },\n }),\n SlashPlugin,\n TablePlugin.configure({\n options: {\n enableMerging: id === 'tableMerge',\n },\n }),\n ColumnPlugin,\n SelectionOverlayPlugin,\n\n TodoListPlugin,\n TogglePlugin,\n ExcalidrawPlugin,\n // Marks\n BoldPlugin,\n ItalicPlugin,\n UnderlinePlugin,\n StrikethroughPlugin,\n CodePlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n FontColorPlugin,\n FontBackgroundColorPlugin,\n FontSizePlugin,\n HighlightPlugin,\n KbdPlugin,\n\n // Block Style\n AlignPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n MediaEmbedPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n ImagePlugin.key,\n HEADING_KEYS.h6,\n ],\n },\n }),\n IndentPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n }),\n IndentListPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n options: {\n listStyleTypes: {\n fire: {\n liComponent: FireLiComponent,\n markerComponent: FireMarker,\n type: 'fire',\n },\n todo: {\n liComponent: TodoLi,\n markerComponent: TodoMarker,\n type: 'todo',\n },\n },\n },\n }),\n LineHeightPlugin.extend({\n inject: {\n nodeProps: {\n defaultNodeValue: 1.5,\n validNodeValues: [1, 1.2, 1.5, 2, 3],\n },\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n ],\n },\n }),\n\n // Functionality\n AutoformatPlugin.configure({\n options: autoformatOptions,\n }),\n BlockSelectionPlugin.configure({\n options: {\n areaOptions: {\n behaviour: {\n scrolling: {\n speedDivider: 1.5,\n },\n startThreshold: 10,\n },\n boundaries: `#${scrollSelector}`,\n container: `#${scrollSelector}`,\n selectables: [`#${scrollSelector} .slate-selectable`],\n selectionAreaClass: 'slate-selection-area',\n },\n enableContextMenu: true,\n },\n }),\n BlockMenuPlugin.configure({\n render: { aboveEditable: BlockContextMenu },\n }),\n DndPlugin.configure({\n options: {\n enableScroller: true,\n onDropFiles: ({ dragItem, editor, target }) => {\n editor\n .getTransforms(ImagePlugin)\n .insertImageFromFiles(dragItem.files, {\n at: target,\n nextBlock: false,\n });\n },\n },\n }),\n EmojiPlugin,\n exitBreakPlugin,\n NodeIdPlugin,\n NormalizeTypesPlugin.configure({\n options: {\n rules: [{ path: [0], strictType: HEADING_KEYS.h1 }],\n },\n }),\n resetBlockTypePlugin,\n SelectOnBackspacePlugin.configure({\n options: {\n query: {\n allow: [ImagePlugin.key, HorizontalRulePlugin.key],\n },\n },\n }),\n DeletePlugin,\n SingleLinePlugin,\n softBreakPlugin,\n tabbablePlugin,\n TrailingBlockPlugin.configure({\n options: { type: ParagraphPlugin.key },\n }),\n DragOverCursorPlugin,\n\n // Collaboration\n CommentsPlugin.configure({\n options: {\n comments: commentsData,\n myUserId: '1',\n users: usersData,\n },\n }),\n\n // Deserialization\n DocxPlugin,\n MarkdownPlugin.configure({ options: { indentList: true } }),\n JuicePlugin,\n\n // Testing\n PlaywrightPlugin.configure({\n enabled: process.env.NODE_ENV !== 'production',\n }),\n ],\n value: value,\n },\n []\n );\n};\n\nexport default function PlaygroundDemo({\n id,\n className,\n scrollSelector,\n}: {\n id?: ValueId;\n className?: string;\n scrollSelector?: string;\n}) {\n const containerRef = useRef(null);\n const enabled = settingsStore.use.checkedComponents();\n\n const editor = usePlaygroundEditor(\n id,\n scrollSelector ?? `blockSelection-${id}`\n );\n\n return (\n \n \n \n \n \n \n \n \n \n\n
\n \n \n\n \n \n \n \n \n \n \n\n \n \n \n \n\n \n \n \n
\n
\n
\n );\n}\n\nconst DemoIdContext = React.createContext(undefined);\n\nexport function DemoId({\n id,\n children,\n}: {\n children: React.ReactNode;\n id?: string;\n}) {\n return {children};\n}\n\nexport function useDemoId() {\n return React.useContext(DemoIdContext);\n}\n", + "content": "'use client';\n\nimport React, { useRef } from 'react';\n\nimport type { ValueId } from '@/config/customizer-plugins';\n\nimport { cn } from '@udecode/cn';\nimport { AIChatPlugin, CopilotPlugin } from '@udecode/plate-ai/react';\nimport { AlignPlugin } from '@udecode/plate-alignment/react';\nimport { AutoformatPlugin } from '@udecode/plate-autoformat/react';\nimport {\n BoldPlugin,\n CodePlugin,\n ItalicPlugin,\n StrikethroughPlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n UnderlinePlugin,\n} from '@udecode/plate-basic-marks/react';\nimport { BlockquotePlugin } from '@udecode/plate-block-quote/react';\nimport { SingleLinePlugin } from '@udecode/plate-break/react';\nimport { CaptionPlugin } from '@udecode/plate-caption/react';\nimport { CodeBlockPlugin } from '@udecode/plate-code-block/react';\nimport { CommentsPlugin } from '@udecode/plate-comments/react';\nimport {\n ParagraphPlugin,\n Plate,\n usePlateEditor,\n} from '@udecode/plate-common/react';\nimport { DatePlugin } from '@udecode/plate-date/react';\nimport { DndPlugin } from '@udecode/plate-dnd';\nimport { DocxPlugin } from '@udecode/plate-docx';\nimport { EmojiPlugin } from '@udecode/plate-emoji/react';\nimport { ExcalidrawPlugin } from '@udecode/plate-excalidraw/react';\nimport {\n FontBackgroundColorPlugin,\n FontColorPlugin,\n FontSizePlugin,\n} from '@udecode/plate-font/react';\nimport { HEADING_KEYS } from '@udecode/plate-heading';\nimport { HeadingPlugin, TocPlugin } from '@udecode/plate-heading/react';\nimport { HighlightPlugin } from '@udecode/plate-highlight/react';\nimport { HorizontalRulePlugin } from '@udecode/plate-horizontal-rule/react';\nimport { IndentPlugin } from '@udecode/plate-indent/react';\nimport { IndentListPlugin } from '@udecode/plate-indent-list/react';\nimport { JuicePlugin } from '@udecode/plate-juice';\nimport { KbdPlugin } from '@udecode/plate-kbd/react';\nimport { ColumnPlugin } from '@udecode/plate-layout/react';\nimport { LineHeightPlugin } from '@udecode/plate-line-height/react';\nimport { LinkPlugin } from '@udecode/plate-link/react';\nimport { ListPlugin, TodoListPlugin } from '@udecode/plate-list/react';\nimport { MarkdownPlugin } from '@udecode/plate-markdown';\nimport { BaseImagePlugin } from '@udecode/plate-media';\nimport { ImagePlugin, MediaEmbedPlugin } from '@udecode/plate-media/react';\nimport { MentionPlugin } from '@udecode/plate-mention/react';\nimport { NodeIdPlugin } from '@udecode/plate-node-id';\nimport { NormalizeTypesPlugin } from '@udecode/plate-normalizers';\nimport { PlaywrightPlugin } from '@udecode/plate-playwright';\nimport { DeletePlugin, SelectOnBackspacePlugin } from '@udecode/plate-select';\nimport {\n BlockMenuPlugin,\n BlockSelectionPlugin,\n} from '@udecode/plate-selection/react';\nimport { SlashPlugin } from '@udecode/plate-slash-command/react';\nimport { TablePlugin } from '@udecode/plate-table/react';\nimport { TogglePlugin } from '@udecode/plate-toggle/react';\nimport { TrailingBlockPlugin } from '@udecode/plate-trailing-block';\nimport Prism from 'prismjs';\n\nimport { CheckPlugin } from '@/components/context/check-plugin';\nimport { settingsStore } from '@/components/context/settings-store';\nimport { aiPlugins } from '@/lib/plate/demo/plugins/ai-plugins';\nimport { getAutoformatOptions } from '@/lib/plate/demo/plugins/autoformatOptions';\nimport { copilotPlugins } from '@/lib/plate/demo/plugins/copilot-plugins';\nimport { createPlateUI } from '@/plate/create-plate-ui';\nimport { editableProps } from '@/plate/demo/editableProps';\nimport { isEnabled } from '@/plate/demo/is-enabled';\nimport { DragOverCursorPlugin } from '@/plate/demo/plugins/DragOverCursorPlugin';\nimport { exitBreakPlugin } from '@/plate/demo/plugins/exitBreakPlugin';\nimport { resetBlockTypePlugin } from '@/plate/demo/plugins/resetBlockTypePlugin';\nimport { softBreakPlugin } from '@/plate/demo/plugins/softBreakPlugin';\nimport { tabbablePlugin } from '@/plate/demo/plugins/tabbablePlugin';\nimport { commentsData, usersData } from '@/plate/demo/values/commentsValue';\nimport { usePlaygroundValue } from '@/plate/demo/values/usePlaygroundValue';\nimport { BlockContextMenu } from '@/components/plate-ui/block-context-menu';\nimport { CommentsPopover } from '@/components/plate-ui/comments-popover';\nimport {\n CursorOverlay,\n SelectionOverlayPlugin,\n} from '@/components/plate-ui/cursor-overlay';\nimport { Editor, EditorContainer } from '@/components/plate-ui/editor';\nimport { FixedToolbar } from '@/components/plate-ui/fixed-toolbar';\nimport { FixedToolbarButtons } from '@/components/plate-ui/fixed-toolbar-buttons';\nimport { FloatingToolbar } from '@/components/plate-ui/floating-toolbar';\nimport { FloatingToolbarButtons } from '@/components/plate-ui/floating-toolbar-buttons';\nimport { ImagePreview } from '@/components/plate-ui/image-preview';\nimport {\n FireLiComponent,\n FireMarker,\n} from '@/components/plate-ui/indent-fire-marker';\nimport {\n TodoLi,\n TodoMarker,\n} from '@/components/plate-ui/indent-todo-marker';\nimport { LinkFloatingToolbar } from '@/components/plate-ui/link-floating-toolbar';\n\nimport { usePlaygroundEnabled } from './usePlaygroundEnabled';\n\nexport const usePlaygroundEditor = (id: any = '', scrollSelector?: string) => {\n const enabledPlugins = settingsStore.use.checkedPlugins();\n const overridePlugins = usePlaygroundEnabled(id);\n const autoformatOptions = getAutoformatOptions(id, enabledPlugins);\n\n const value = usePlaygroundValue(id);\n const key = settingsStore.use.version();\n const editorId = id || 'playground-' + key;\n\n return usePlateEditor(\n {\n id: editorId,\n override: {\n components: createPlateUI({\n draggable: isEnabled('dnd', id),\n placeholder: isEnabled('placeholder', id),\n }),\n plugins: overridePlugins,\n },\n plugins: [\n // AI\n ...(id === 'ai' || enabledPlugins[AIChatPlugin.key] ? aiPlugins : []),\n ...(id === 'copilot' || enabledPlugins[CopilotPlugin.key]\n ? copilotPlugins\n : []),\n // Nodes\n HeadingPlugin,\n TocPlugin.configure({\n options: {\n scrollContainerSelector: `#${scrollSelector}`,\n topOffset: 80,\n },\n }),\n BlockquotePlugin,\n CodeBlockPlugin.configure({\n options: {\n prism: Prism,\n },\n }),\n HorizontalRulePlugin,\n LinkPlugin.extend({\n render: { afterEditable: () => },\n }),\n ...(id === 'list' ? [ListPlugin] : []),\n ImagePlugin.extend({\n options: {\n disableUploadInsert: true,\n },\n render: { afterEditable: ImagePreview },\n }),\n MediaEmbedPlugin,\n CaptionPlugin.configure({\n options: {\n plugins: [ImagePlugin, MediaEmbedPlugin],\n },\n }),\n DatePlugin,\n MentionPlugin.configure({\n options: {\n triggerPreviousCharPattern: /^$|^[\\s\"']$/,\n },\n }),\n SlashPlugin,\n TablePlugin.configure({\n options: {\n enableMerging: id === 'tableMerge',\n },\n }),\n ColumnPlugin,\n SelectionOverlayPlugin,\n\n TodoListPlugin,\n TogglePlugin,\n ExcalidrawPlugin,\n // Marks\n BoldPlugin,\n ItalicPlugin,\n UnderlinePlugin,\n StrikethroughPlugin,\n CodePlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n FontColorPlugin,\n FontBackgroundColorPlugin,\n FontSizePlugin,\n HighlightPlugin,\n KbdPlugin,\n\n // Block Style\n AlignPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n MediaEmbedPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n ImagePlugin.key,\n HEADING_KEYS.h6,\n ],\n },\n }),\n IndentPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n }),\n IndentListPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n options: {\n listStyleTypes: {\n fire: {\n liComponent: FireLiComponent,\n markerComponent: FireMarker,\n type: 'fire',\n },\n todo: {\n liComponent: TodoLi,\n markerComponent: TodoMarker,\n type: 'todo',\n },\n },\n },\n }),\n LineHeightPlugin.extend({\n inject: {\n nodeProps: {\n defaultNodeValue: 1.5,\n validNodeValues: [1, 1.2, 1.5, 2, 3],\n },\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n ],\n },\n }),\n\n // Functionality\n AutoformatPlugin.configure({\n options: autoformatOptions,\n }),\n BlockSelectionPlugin.configure({\n options: {\n areaOptions: {\n behaviour: {\n scrolling: {\n speedDivider: 1.5,\n },\n startThreshold: 10,\n },\n boundaries: `#${scrollSelector}`,\n container: `#${scrollSelector}`,\n selectables: [`#${scrollSelector} .slate-selectable`],\n selectionAreaClass: 'slate-selection-area',\n },\n enableContextMenu: true,\n },\n }),\n BlockMenuPlugin.configure({\n render: { aboveEditable: BlockContextMenu },\n }),\n DndPlugin.configure({\n options: {\n enableScroller: true,\n onDropFiles: ({ dragItem, editor, target }) => {\n editor\n .getTransforms(BaseImagePlugin)\n .insert.imageFromFiles(dragItem.files, {\n at: target,\n nextBlock: false,\n });\n },\n },\n }),\n EmojiPlugin,\n exitBreakPlugin,\n NodeIdPlugin,\n NormalizeTypesPlugin.configure({\n options: {\n rules: [{ path: [0], strictType: HEADING_KEYS.h1 }],\n },\n }),\n resetBlockTypePlugin,\n SelectOnBackspacePlugin.configure({\n options: {\n query: {\n allow: [ImagePlugin.key, HorizontalRulePlugin.key],\n },\n },\n }),\n DeletePlugin,\n SingleLinePlugin,\n softBreakPlugin,\n tabbablePlugin,\n TrailingBlockPlugin.configure({\n options: { type: ParagraphPlugin.key },\n }),\n DragOverCursorPlugin,\n\n // Collaboration\n CommentsPlugin.configure({\n options: {\n comments: commentsData,\n myUserId: '1',\n users: usersData,\n },\n }),\n\n // Deserialization\n DocxPlugin,\n MarkdownPlugin.configure({ options: { indentList: true } }),\n JuicePlugin,\n\n // Testing\n PlaywrightPlugin.configure({\n enabled: process.env.NODE_ENV !== 'production',\n }),\n ],\n value: value,\n },\n []\n );\n};\n\nexport default function PlaygroundDemo({\n id,\n className,\n scrollSelector,\n}: {\n id?: ValueId;\n className?: string;\n scrollSelector?: string;\n}) {\n const containerRef = useRef(null);\n const enabled = settingsStore.use.checkedComponents();\n\n const editor = usePlaygroundEditor(\n id,\n scrollSelector ?? `blockSelection-${id}`\n );\n\n return (\n \n \n \n \n \n \n \n \n \n\n
\n \n \n\n \n \n \n \n \n \n \n\n \n \n \n \n\n \n \n \n
\n
\n
\n );\n}\n\nconst DemoIdContext = React.createContext(undefined);\n\nexport function DemoId({\n id,\n children,\n}: {\n children: React.ReactNode;\n id?: string;\n}) {\n return {children};\n}\n\nexport function useDemoId() {\n return React.useContext(DemoIdContext);\n}\n", "path": "example/playground-demo.tsx", "target": "components/playground-demo.tsx", "type": "registry:example" diff --git a/apps/www/public/r/styles/default/resizable-demo.json b/apps/www/public/r/styles/default/resizable-demo.json index 02c877e5ee..47692a0963 100644 --- a/apps/www/public/r/styles/default/resizable-demo.json +++ b/apps/www/public/r/styles/default/resizable-demo.json @@ -4,7 +4,7 @@ }, "files": [ { - "content": "'use client';\n\nimport React, { useRef } from 'react';\n\nimport type { ValueId } from '@/config/customizer-plugins';\n\nimport { cn } from '@udecode/cn';\nimport { AIChatPlugin, CopilotPlugin } from '@udecode/plate-ai/react';\nimport { AlignPlugin } from '@udecode/plate-alignment/react';\nimport { AutoformatPlugin } from '@udecode/plate-autoformat/react';\nimport {\n BoldPlugin,\n CodePlugin,\n ItalicPlugin,\n StrikethroughPlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n UnderlinePlugin,\n} from '@udecode/plate-basic-marks/react';\nimport { BlockquotePlugin } from '@udecode/plate-block-quote/react';\nimport { SingleLinePlugin } from '@udecode/plate-break/react';\nimport { CaptionPlugin } from '@udecode/plate-caption/react';\nimport { CodeBlockPlugin } from '@udecode/plate-code-block/react';\nimport { CommentsPlugin } from '@udecode/plate-comments/react';\nimport {\n ParagraphPlugin,\n Plate,\n usePlateEditor,\n} from '@udecode/plate-common/react';\nimport { DatePlugin } from '@udecode/plate-date/react';\nimport { DndPlugin } from '@udecode/plate-dnd';\nimport { DocxPlugin } from '@udecode/plate-docx';\nimport { EmojiPlugin } from '@udecode/plate-emoji/react';\nimport { ExcalidrawPlugin } from '@udecode/plate-excalidraw/react';\nimport {\n FontBackgroundColorPlugin,\n FontColorPlugin,\n FontSizePlugin,\n} from '@udecode/plate-font/react';\nimport { HEADING_KEYS } from '@udecode/plate-heading';\nimport { HeadingPlugin, TocPlugin } from '@udecode/plate-heading/react';\nimport { HighlightPlugin } from '@udecode/plate-highlight/react';\nimport { HorizontalRulePlugin } from '@udecode/plate-horizontal-rule/react';\nimport { IndentPlugin } from '@udecode/plate-indent/react';\nimport { IndentListPlugin } from '@udecode/plate-indent-list/react';\nimport { JuicePlugin } from '@udecode/plate-juice';\nimport { KbdPlugin } from '@udecode/plate-kbd/react';\nimport { ColumnPlugin } from '@udecode/plate-layout/react';\nimport { LineHeightPlugin } from '@udecode/plate-line-height/react';\nimport { LinkPlugin } from '@udecode/plate-link/react';\nimport { ListPlugin, TodoListPlugin } from '@udecode/plate-list/react';\nimport { MarkdownPlugin } from '@udecode/plate-markdown';\nimport { ImagePlugin, MediaEmbedPlugin } from '@udecode/plate-media/react';\nimport { MentionPlugin } from '@udecode/plate-mention/react';\nimport { NodeIdPlugin } from '@udecode/plate-node-id';\nimport { NormalizeTypesPlugin } from '@udecode/plate-normalizers';\nimport { PlaywrightPlugin } from '@udecode/plate-playwright';\nimport { DeletePlugin, SelectOnBackspacePlugin } from '@udecode/plate-select';\nimport {\n BlockMenuPlugin,\n BlockSelectionPlugin,\n} from '@udecode/plate-selection/react';\nimport { SlashPlugin } from '@udecode/plate-slash-command/react';\nimport { TablePlugin } from '@udecode/plate-table/react';\nimport { TogglePlugin } from '@udecode/plate-toggle/react';\nimport { TrailingBlockPlugin } from '@udecode/plate-trailing-block';\nimport Prism from 'prismjs';\n\nimport { CheckPlugin } from '@/components/context/check-plugin';\nimport { settingsStore } from '@/components/context/settings-store';\nimport { aiPlugins } from '@/lib/plate/demo/plugins/ai-plugins';\nimport { getAutoformatOptions } from '@/lib/plate/demo/plugins/autoformatOptions';\nimport { copilotPlugins } from '@/lib/plate/demo/plugins/copilot-plugins';\nimport { createPlateUI } from '@/plate/create-plate-ui';\nimport { editableProps } from '@/plate/demo/editableProps';\nimport { isEnabled } from '@/plate/demo/is-enabled';\nimport { DragOverCursorPlugin } from '@/plate/demo/plugins/DragOverCursorPlugin';\nimport { exitBreakPlugin } from '@/plate/demo/plugins/exitBreakPlugin';\nimport { resetBlockTypePlugin } from '@/plate/demo/plugins/resetBlockTypePlugin';\nimport { softBreakPlugin } from '@/plate/demo/plugins/softBreakPlugin';\nimport { tabbablePlugin } from '@/plate/demo/plugins/tabbablePlugin';\nimport { commentsData, usersData } from '@/plate/demo/values/commentsValue';\nimport { usePlaygroundValue } from '@/plate/demo/values/usePlaygroundValue';\nimport { BlockContextMenu } from '@/components/plate-ui/block-context-menu';\nimport { CommentsPopover } from '@/components/plate-ui/comments-popover';\nimport {\n CursorOverlay,\n SelectionOverlayPlugin,\n} from '@/components/plate-ui/cursor-overlay';\nimport { Editor, EditorContainer } from '@/components/plate-ui/editor';\nimport { FixedToolbar } from '@/components/plate-ui/fixed-toolbar';\nimport { FixedToolbarButtons } from '@/components/plate-ui/fixed-toolbar-buttons';\nimport { FloatingToolbar } from '@/components/plate-ui/floating-toolbar';\nimport { FloatingToolbarButtons } from '@/components/plate-ui/floating-toolbar-buttons';\nimport { ImagePreview } from '@/components/plate-ui/image-preview';\nimport {\n FireLiComponent,\n FireMarker,\n} from '@/components/plate-ui/indent-fire-marker';\nimport {\n TodoLi,\n TodoMarker,\n} from '@/components/plate-ui/indent-todo-marker';\nimport { LinkFloatingToolbar } from '@/components/plate-ui/link-floating-toolbar';\n\nimport { usePlaygroundEnabled } from './usePlaygroundEnabled';\n\nexport const usePlaygroundEditor = (id: any = '', scrollSelector?: string) => {\n const enabledPlugins = settingsStore.use.checkedPlugins();\n const overridePlugins = usePlaygroundEnabled(id);\n const autoformatOptions = getAutoformatOptions(id, enabledPlugins);\n\n const value = usePlaygroundValue(id);\n const key = settingsStore.use.version();\n const editorId = id || 'playground-' + key;\n\n return usePlateEditor(\n {\n id: editorId,\n override: {\n components: createPlateUI({\n draggable: isEnabled('dnd', id),\n placeholder: isEnabled('placeholder', id),\n }),\n plugins: overridePlugins,\n },\n plugins: [\n // AI\n ...(id === 'ai' || enabledPlugins[AIChatPlugin.key] ? aiPlugins : []),\n ...(id === 'copilot' || enabledPlugins[CopilotPlugin.key]\n ? copilotPlugins\n : []),\n // Nodes\n HeadingPlugin,\n TocPlugin.configure({\n options: {\n scrollContainerSelector: `#${scrollSelector}`,\n topOffset: 80,\n },\n }),\n BlockquotePlugin,\n CodeBlockPlugin.configure({\n options: {\n prism: Prism,\n },\n }),\n HorizontalRulePlugin,\n LinkPlugin.extend({\n render: { afterEditable: () => },\n }),\n ...(id === 'list' ? [ListPlugin] : []),\n ImagePlugin.extend({\n options: {\n disableUploadInsert: true,\n },\n render: { afterEditable: ImagePreview },\n }),\n MediaEmbedPlugin,\n CaptionPlugin.configure({\n options: {\n plugins: [ImagePlugin, MediaEmbedPlugin],\n },\n }),\n DatePlugin,\n MentionPlugin.configure({\n options: {\n triggerPreviousCharPattern: /^$|^[\\s\"']$/,\n },\n }),\n SlashPlugin,\n TablePlugin.configure({\n options: {\n enableMerging: id === 'tableMerge',\n },\n }),\n ColumnPlugin,\n SelectionOverlayPlugin,\n\n TodoListPlugin,\n TogglePlugin,\n ExcalidrawPlugin,\n // Marks\n BoldPlugin,\n ItalicPlugin,\n UnderlinePlugin,\n StrikethroughPlugin,\n CodePlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n FontColorPlugin,\n FontBackgroundColorPlugin,\n FontSizePlugin,\n HighlightPlugin,\n KbdPlugin,\n\n // Block Style\n AlignPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n MediaEmbedPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n ImagePlugin.key,\n HEADING_KEYS.h6,\n ],\n },\n }),\n IndentPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n }),\n IndentListPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n options: {\n listStyleTypes: {\n fire: {\n liComponent: FireLiComponent,\n markerComponent: FireMarker,\n type: 'fire',\n },\n todo: {\n liComponent: TodoLi,\n markerComponent: TodoMarker,\n type: 'todo',\n },\n },\n },\n }),\n LineHeightPlugin.extend({\n inject: {\n nodeProps: {\n defaultNodeValue: 1.5,\n validNodeValues: [1, 1.2, 1.5, 2, 3],\n },\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n ],\n },\n }),\n\n // Functionality\n AutoformatPlugin.configure({\n options: autoformatOptions,\n }),\n BlockSelectionPlugin.configure({\n options: {\n areaOptions: {\n behaviour: {\n scrolling: {\n speedDivider: 1.5,\n },\n startThreshold: 10,\n },\n boundaries: `#${scrollSelector}`,\n container: `#${scrollSelector}`,\n selectables: [`#${scrollSelector} .slate-selectable`],\n selectionAreaClass: 'slate-selection-area',\n },\n enableContextMenu: true,\n },\n }),\n BlockMenuPlugin.configure({\n render: { aboveEditable: BlockContextMenu },\n }),\n DndPlugin.configure({\n options: {\n enableScroller: true,\n onDropFiles: ({ dragItem, editor, target }) => {\n editor\n .getTransforms(ImagePlugin)\n .insertImageFromFiles(dragItem.files, {\n at: target,\n nextBlock: false,\n });\n },\n },\n }),\n EmojiPlugin,\n exitBreakPlugin,\n NodeIdPlugin,\n NormalizeTypesPlugin.configure({\n options: {\n rules: [{ path: [0], strictType: HEADING_KEYS.h1 }],\n },\n }),\n resetBlockTypePlugin,\n SelectOnBackspacePlugin.configure({\n options: {\n query: {\n allow: [ImagePlugin.key, HorizontalRulePlugin.key],\n },\n },\n }),\n DeletePlugin,\n SingleLinePlugin,\n softBreakPlugin,\n tabbablePlugin,\n TrailingBlockPlugin.configure({\n options: { type: ParagraphPlugin.key },\n }),\n DragOverCursorPlugin,\n\n // Collaboration\n CommentsPlugin.configure({\n options: {\n comments: commentsData,\n myUserId: '1',\n users: usersData,\n },\n }),\n\n // Deserialization\n DocxPlugin,\n MarkdownPlugin.configure({ options: { indentList: true } }),\n JuicePlugin,\n\n // Testing\n PlaywrightPlugin.configure({\n enabled: process.env.NODE_ENV !== 'production',\n }),\n ],\n value: value,\n },\n []\n );\n};\n\nexport default function PlaygroundDemo({\n id,\n className,\n scrollSelector,\n}: {\n id?: ValueId;\n className?: string;\n scrollSelector?: string;\n}) {\n const containerRef = useRef(null);\n const enabled = settingsStore.use.checkedComponents();\n\n const editor = usePlaygroundEditor(\n id,\n scrollSelector ?? `blockSelection-${id}`\n );\n\n return (\n \n \n \n \n \n \n \n \n \n\n
\n \n \n\n \n \n \n \n \n \n \n\n \n \n \n \n\n \n \n \n
\n
\n
\n );\n}\n\nconst DemoIdContext = React.createContext(undefined);\n\nexport function DemoId({\n id,\n children,\n}: {\n children: React.ReactNode;\n id?: string;\n}) {\n return {children};\n}\n\nexport function useDemoId() {\n return React.useContext(DemoIdContext);\n}\n", + "content": "'use client';\n\nimport React, { useRef } from 'react';\n\nimport type { ValueId } from '@/config/customizer-plugins';\n\nimport { cn } from '@udecode/cn';\nimport { AIChatPlugin, CopilotPlugin } from '@udecode/plate-ai/react';\nimport { AlignPlugin } from '@udecode/plate-alignment/react';\nimport { AutoformatPlugin } from '@udecode/plate-autoformat/react';\nimport {\n BoldPlugin,\n CodePlugin,\n ItalicPlugin,\n StrikethroughPlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n UnderlinePlugin,\n} from '@udecode/plate-basic-marks/react';\nimport { BlockquotePlugin } from '@udecode/plate-block-quote/react';\nimport { SingleLinePlugin } from '@udecode/plate-break/react';\nimport { CaptionPlugin } from '@udecode/plate-caption/react';\nimport { CodeBlockPlugin } from '@udecode/plate-code-block/react';\nimport { CommentsPlugin } from '@udecode/plate-comments/react';\nimport {\n ParagraphPlugin,\n Plate,\n usePlateEditor,\n} from '@udecode/plate-common/react';\nimport { DatePlugin } from '@udecode/plate-date/react';\nimport { DndPlugin } from '@udecode/plate-dnd';\nimport { DocxPlugin } from '@udecode/plate-docx';\nimport { EmojiPlugin } from '@udecode/plate-emoji/react';\nimport { ExcalidrawPlugin } from '@udecode/plate-excalidraw/react';\nimport {\n FontBackgroundColorPlugin,\n FontColorPlugin,\n FontSizePlugin,\n} from '@udecode/plate-font/react';\nimport { HEADING_KEYS } from '@udecode/plate-heading';\nimport { HeadingPlugin, TocPlugin } from '@udecode/plate-heading/react';\nimport { HighlightPlugin } from '@udecode/plate-highlight/react';\nimport { HorizontalRulePlugin } from '@udecode/plate-horizontal-rule/react';\nimport { IndentPlugin } from '@udecode/plate-indent/react';\nimport { IndentListPlugin } from '@udecode/plate-indent-list/react';\nimport { JuicePlugin } from '@udecode/plate-juice';\nimport { KbdPlugin } from '@udecode/plate-kbd/react';\nimport { ColumnPlugin } from '@udecode/plate-layout/react';\nimport { LineHeightPlugin } from '@udecode/plate-line-height/react';\nimport { LinkPlugin } from '@udecode/plate-link/react';\nimport { ListPlugin, TodoListPlugin } from '@udecode/plate-list/react';\nimport { MarkdownPlugin } from '@udecode/plate-markdown';\nimport { BaseImagePlugin } from '@udecode/plate-media';\nimport { ImagePlugin, MediaEmbedPlugin } from '@udecode/plate-media/react';\nimport { MentionPlugin } from '@udecode/plate-mention/react';\nimport { NodeIdPlugin } from '@udecode/plate-node-id';\nimport { NormalizeTypesPlugin } from '@udecode/plate-normalizers';\nimport { PlaywrightPlugin } from '@udecode/plate-playwright';\nimport { DeletePlugin, SelectOnBackspacePlugin } from '@udecode/plate-select';\nimport {\n BlockMenuPlugin,\n BlockSelectionPlugin,\n} from '@udecode/plate-selection/react';\nimport { SlashPlugin } from '@udecode/plate-slash-command/react';\nimport { TablePlugin } from '@udecode/plate-table/react';\nimport { TogglePlugin } from '@udecode/plate-toggle/react';\nimport { TrailingBlockPlugin } from '@udecode/plate-trailing-block';\nimport Prism from 'prismjs';\n\nimport { CheckPlugin } from '@/components/context/check-plugin';\nimport { settingsStore } from '@/components/context/settings-store';\nimport { aiPlugins } from '@/lib/plate/demo/plugins/ai-plugins';\nimport { getAutoformatOptions } from '@/lib/plate/demo/plugins/autoformatOptions';\nimport { copilotPlugins } from '@/lib/plate/demo/plugins/copilot-plugins';\nimport { createPlateUI } from '@/plate/create-plate-ui';\nimport { editableProps } from '@/plate/demo/editableProps';\nimport { isEnabled } from '@/plate/demo/is-enabled';\nimport { DragOverCursorPlugin } from '@/plate/demo/plugins/DragOverCursorPlugin';\nimport { exitBreakPlugin } from '@/plate/demo/plugins/exitBreakPlugin';\nimport { resetBlockTypePlugin } from '@/plate/demo/plugins/resetBlockTypePlugin';\nimport { softBreakPlugin } from '@/plate/demo/plugins/softBreakPlugin';\nimport { tabbablePlugin } from '@/plate/demo/plugins/tabbablePlugin';\nimport { commentsData, usersData } from '@/plate/demo/values/commentsValue';\nimport { usePlaygroundValue } from '@/plate/demo/values/usePlaygroundValue';\nimport { BlockContextMenu } from '@/components/plate-ui/block-context-menu';\nimport { CommentsPopover } from '@/components/plate-ui/comments-popover';\nimport {\n CursorOverlay,\n SelectionOverlayPlugin,\n} from '@/components/plate-ui/cursor-overlay';\nimport { Editor, EditorContainer } from '@/components/plate-ui/editor';\nimport { FixedToolbar } from '@/components/plate-ui/fixed-toolbar';\nimport { FixedToolbarButtons } from '@/components/plate-ui/fixed-toolbar-buttons';\nimport { FloatingToolbar } from '@/components/plate-ui/floating-toolbar';\nimport { FloatingToolbarButtons } from '@/components/plate-ui/floating-toolbar-buttons';\nimport { ImagePreview } from '@/components/plate-ui/image-preview';\nimport {\n FireLiComponent,\n FireMarker,\n} from '@/components/plate-ui/indent-fire-marker';\nimport {\n TodoLi,\n TodoMarker,\n} from '@/components/plate-ui/indent-todo-marker';\nimport { LinkFloatingToolbar } from '@/components/plate-ui/link-floating-toolbar';\n\nimport { usePlaygroundEnabled } from './usePlaygroundEnabled';\n\nexport const usePlaygroundEditor = (id: any = '', scrollSelector?: string) => {\n const enabledPlugins = settingsStore.use.checkedPlugins();\n const overridePlugins = usePlaygroundEnabled(id);\n const autoformatOptions = getAutoformatOptions(id, enabledPlugins);\n\n const value = usePlaygroundValue(id);\n const key = settingsStore.use.version();\n const editorId = id || 'playground-' + key;\n\n return usePlateEditor(\n {\n id: editorId,\n override: {\n components: createPlateUI({\n draggable: isEnabled('dnd', id),\n placeholder: isEnabled('placeholder', id),\n }),\n plugins: overridePlugins,\n },\n plugins: [\n // AI\n ...(id === 'ai' || enabledPlugins[AIChatPlugin.key] ? aiPlugins : []),\n ...(id === 'copilot' || enabledPlugins[CopilotPlugin.key]\n ? copilotPlugins\n : []),\n // Nodes\n HeadingPlugin,\n TocPlugin.configure({\n options: {\n scrollContainerSelector: `#${scrollSelector}`,\n topOffset: 80,\n },\n }),\n BlockquotePlugin,\n CodeBlockPlugin.configure({\n options: {\n prism: Prism,\n },\n }),\n HorizontalRulePlugin,\n LinkPlugin.extend({\n render: { afterEditable: () => },\n }),\n ...(id === 'list' ? [ListPlugin] : []),\n ImagePlugin.extend({\n options: {\n disableUploadInsert: true,\n },\n render: { afterEditable: ImagePreview },\n }),\n MediaEmbedPlugin,\n CaptionPlugin.configure({\n options: {\n plugins: [ImagePlugin, MediaEmbedPlugin],\n },\n }),\n DatePlugin,\n MentionPlugin.configure({\n options: {\n triggerPreviousCharPattern: /^$|^[\\s\"']$/,\n },\n }),\n SlashPlugin,\n TablePlugin.configure({\n options: {\n enableMerging: id === 'tableMerge',\n },\n }),\n ColumnPlugin,\n SelectionOverlayPlugin,\n\n TodoListPlugin,\n TogglePlugin,\n ExcalidrawPlugin,\n // Marks\n BoldPlugin,\n ItalicPlugin,\n UnderlinePlugin,\n StrikethroughPlugin,\n CodePlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n FontColorPlugin,\n FontBackgroundColorPlugin,\n FontSizePlugin,\n HighlightPlugin,\n KbdPlugin,\n\n // Block Style\n AlignPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n MediaEmbedPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n ImagePlugin.key,\n HEADING_KEYS.h6,\n ],\n },\n }),\n IndentPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n }),\n IndentListPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n options: {\n listStyleTypes: {\n fire: {\n liComponent: FireLiComponent,\n markerComponent: FireMarker,\n type: 'fire',\n },\n todo: {\n liComponent: TodoLi,\n markerComponent: TodoMarker,\n type: 'todo',\n },\n },\n },\n }),\n LineHeightPlugin.extend({\n inject: {\n nodeProps: {\n defaultNodeValue: 1.5,\n validNodeValues: [1, 1.2, 1.5, 2, 3],\n },\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n ],\n },\n }),\n\n // Functionality\n AutoformatPlugin.configure({\n options: autoformatOptions,\n }),\n BlockSelectionPlugin.configure({\n options: {\n areaOptions: {\n behaviour: {\n scrolling: {\n speedDivider: 1.5,\n },\n startThreshold: 10,\n },\n boundaries: `#${scrollSelector}`,\n container: `#${scrollSelector}`,\n selectables: [`#${scrollSelector} .slate-selectable`],\n selectionAreaClass: 'slate-selection-area',\n },\n enableContextMenu: true,\n },\n }),\n BlockMenuPlugin.configure({\n render: { aboveEditable: BlockContextMenu },\n }),\n DndPlugin.configure({\n options: {\n enableScroller: true,\n onDropFiles: ({ dragItem, editor, target }) => {\n editor\n .getTransforms(BaseImagePlugin)\n .insert.imageFromFiles(dragItem.files, {\n at: target,\n nextBlock: false,\n });\n },\n },\n }),\n EmojiPlugin,\n exitBreakPlugin,\n NodeIdPlugin,\n NormalizeTypesPlugin.configure({\n options: {\n rules: [{ path: [0], strictType: HEADING_KEYS.h1 }],\n },\n }),\n resetBlockTypePlugin,\n SelectOnBackspacePlugin.configure({\n options: {\n query: {\n allow: [ImagePlugin.key, HorizontalRulePlugin.key],\n },\n },\n }),\n DeletePlugin,\n SingleLinePlugin,\n softBreakPlugin,\n tabbablePlugin,\n TrailingBlockPlugin.configure({\n options: { type: ParagraphPlugin.key },\n }),\n DragOverCursorPlugin,\n\n // Collaboration\n CommentsPlugin.configure({\n options: {\n comments: commentsData,\n myUserId: '1',\n users: usersData,\n },\n }),\n\n // Deserialization\n DocxPlugin,\n MarkdownPlugin.configure({ options: { indentList: true } }),\n JuicePlugin,\n\n // Testing\n PlaywrightPlugin.configure({\n enabled: process.env.NODE_ENV !== 'production',\n }),\n ],\n value: value,\n },\n []\n );\n};\n\nexport default function PlaygroundDemo({\n id,\n className,\n scrollSelector,\n}: {\n id?: ValueId;\n className?: string;\n scrollSelector?: string;\n}) {\n const containerRef = useRef(null);\n const enabled = settingsStore.use.checkedComponents();\n\n const editor = usePlaygroundEditor(\n id,\n scrollSelector ?? `blockSelection-${id}`\n );\n\n return (\n \n \n \n \n \n \n \n \n \n\n
\n \n \n\n \n \n \n \n \n \n \n\n \n \n \n \n\n \n \n \n
\n
\n
\n );\n}\n\nconst DemoIdContext = React.createContext(undefined);\n\nexport function DemoId({\n id,\n children,\n}: {\n children: React.ReactNode;\n id?: string;\n}) {\n return {children};\n}\n\nexport function useDemoId() {\n return React.useContext(DemoIdContext);\n}\n", "path": "example/playground-demo.tsx", "target": "components/playground-demo.tsx", "type": "registry:example" diff --git a/apps/www/public/r/styles/default/slash-command-demo.json b/apps/www/public/r/styles/default/slash-command-demo.json index 09306aa04c..18fab7b935 100644 --- a/apps/www/public/r/styles/default/slash-command-demo.json +++ b/apps/www/public/r/styles/default/slash-command-demo.json @@ -4,7 +4,7 @@ }, "files": [ { - "content": "'use client';\n\nimport React, { useRef } from 'react';\n\nimport type { ValueId } from '@/config/customizer-plugins';\n\nimport { cn } from '@udecode/cn';\nimport { AIChatPlugin, CopilotPlugin } from '@udecode/plate-ai/react';\nimport { AlignPlugin } from '@udecode/plate-alignment/react';\nimport { AutoformatPlugin } from '@udecode/plate-autoformat/react';\nimport {\n BoldPlugin,\n CodePlugin,\n ItalicPlugin,\n StrikethroughPlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n UnderlinePlugin,\n} from '@udecode/plate-basic-marks/react';\nimport { BlockquotePlugin } from '@udecode/plate-block-quote/react';\nimport { SingleLinePlugin } from '@udecode/plate-break/react';\nimport { CaptionPlugin } from '@udecode/plate-caption/react';\nimport { CodeBlockPlugin } from '@udecode/plate-code-block/react';\nimport { CommentsPlugin } from '@udecode/plate-comments/react';\nimport {\n ParagraphPlugin,\n Plate,\n usePlateEditor,\n} from '@udecode/plate-common/react';\nimport { DatePlugin } from '@udecode/plate-date/react';\nimport { DndPlugin } from '@udecode/plate-dnd';\nimport { DocxPlugin } from '@udecode/plate-docx';\nimport { EmojiPlugin } from '@udecode/plate-emoji/react';\nimport { ExcalidrawPlugin } from '@udecode/plate-excalidraw/react';\nimport {\n FontBackgroundColorPlugin,\n FontColorPlugin,\n FontSizePlugin,\n} from '@udecode/plate-font/react';\nimport { HEADING_KEYS } from '@udecode/plate-heading';\nimport { HeadingPlugin, TocPlugin } from '@udecode/plate-heading/react';\nimport { HighlightPlugin } from '@udecode/plate-highlight/react';\nimport { HorizontalRulePlugin } from '@udecode/plate-horizontal-rule/react';\nimport { IndentPlugin } from '@udecode/plate-indent/react';\nimport { IndentListPlugin } from '@udecode/plate-indent-list/react';\nimport { JuicePlugin } from '@udecode/plate-juice';\nimport { KbdPlugin } from '@udecode/plate-kbd/react';\nimport { ColumnPlugin } from '@udecode/plate-layout/react';\nimport { LineHeightPlugin } from '@udecode/plate-line-height/react';\nimport { LinkPlugin } from '@udecode/plate-link/react';\nimport { ListPlugin, TodoListPlugin } from '@udecode/plate-list/react';\nimport { MarkdownPlugin } from '@udecode/plate-markdown';\nimport { ImagePlugin, MediaEmbedPlugin } from '@udecode/plate-media/react';\nimport { MentionPlugin } from '@udecode/plate-mention/react';\nimport { NodeIdPlugin } from '@udecode/plate-node-id';\nimport { NormalizeTypesPlugin } from '@udecode/plate-normalizers';\nimport { PlaywrightPlugin } from '@udecode/plate-playwright';\nimport { DeletePlugin, SelectOnBackspacePlugin } from '@udecode/plate-select';\nimport {\n BlockMenuPlugin,\n BlockSelectionPlugin,\n} from '@udecode/plate-selection/react';\nimport { SlashPlugin } from '@udecode/plate-slash-command/react';\nimport { TablePlugin } from '@udecode/plate-table/react';\nimport { TogglePlugin } from '@udecode/plate-toggle/react';\nimport { TrailingBlockPlugin } from '@udecode/plate-trailing-block';\nimport Prism from 'prismjs';\n\nimport { CheckPlugin } from '@/components/context/check-plugin';\nimport { settingsStore } from '@/components/context/settings-store';\nimport { aiPlugins } from '@/lib/plate/demo/plugins/ai-plugins';\nimport { getAutoformatOptions } from '@/lib/plate/demo/plugins/autoformatOptions';\nimport { copilotPlugins } from '@/lib/plate/demo/plugins/copilot-plugins';\nimport { createPlateUI } from '@/plate/create-plate-ui';\nimport { editableProps } from '@/plate/demo/editableProps';\nimport { isEnabled } from '@/plate/demo/is-enabled';\nimport { DragOverCursorPlugin } from '@/plate/demo/plugins/DragOverCursorPlugin';\nimport { exitBreakPlugin } from '@/plate/demo/plugins/exitBreakPlugin';\nimport { resetBlockTypePlugin } from '@/plate/demo/plugins/resetBlockTypePlugin';\nimport { softBreakPlugin } from '@/plate/demo/plugins/softBreakPlugin';\nimport { tabbablePlugin } from '@/plate/demo/plugins/tabbablePlugin';\nimport { commentsData, usersData } from '@/plate/demo/values/commentsValue';\nimport { usePlaygroundValue } from '@/plate/demo/values/usePlaygroundValue';\nimport { BlockContextMenu } from '@/components/plate-ui/block-context-menu';\nimport { CommentsPopover } from '@/components/plate-ui/comments-popover';\nimport {\n CursorOverlay,\n SelectionOverlayPlugin,\n} from '@/components/plate-ui/cursor-overlay';\nimport { Editor, EditorContainer } from '@/components/plate-ui/editor';\nimport { FixedToolbar } from '@/components/plate-ui/fixed-toolbar';\nimport { FixedToolbarButtons } from '@/components/plate-ui/fixed-toolbar-buttons';\nimport { FloatingToolbar } from '@/components/plate-ui/floating-toolbar';\nimport { FloatingToolbarButtons } from '@/components/plate-ui/floating-toolbar-buttons';\nimport { ImagePreview } from '@/components/plate-ui/image-preview';\nimport {\n FireLiComponent,\n FireMarker,\n} from '@/components/plate-ui/indent-fire-marker';\nimport {\n TodoLi,\n TodoMarker,\n} from '@/components/plate-ui/indent-todo-marker';\nimport { LinkFloatingToolbar } from '@/components/plate-ui/link-floating-toolbar';\n\nimport { usePlaygroundEnabled } from './usePlaygroundEnabled';\n\nexport const usePlaygroundEditor = (id: any = '', scrollSelector?: string) => {\n const enabledPlugins = settingsStore.use.checkedPlugins();\n const overridePlugins = usePlaygroundEnabled(id);\n const autoformatOptions = getAutoformatOptions(id, enabledPlugins);\n\n const value = usePlaygroundValue(id);\n const key = settingsStore.use.version();\n const editorId = id || 'playground-' + key;\n\n return usePlateEditor(\n {\n id: editorId,\n override: {\n components: createPlateUI({\n draggable: isEnabled('dnd', id),\n placeholder: isEnabled('placeholder', id),\n }),\n plugins: overridePlugins,\n },\n plugins: [\n // AI\n ...(id === 'ai' || enabledPlugins[AIChatPlugin.key] ? aiPlugins : []),\n ...(id === 'copilot' || enabledPlugins[CopilotPlugin.key]\n ? copilotPlugins\n : []),\n // Nodes\n HeadingPlugin,\n TocPlugin.configure({\n options: {\n scrollContainerSelector: `#${scrollSelector}`,\n topOffset: 80,\n },\n }),\n BlockquotePlugin,\n CodeBlockPlugin.configure({\n options: {\n prism: Prism,\n },\n }),\n HorizontalRulePlugin,\n LinkPlugin.extend({\n render: { afterEditable: () => },\n }),\n ...(id === 'list' ? [ListPlugin] : []),\n ImagePlugin.extend({\n options: {\n disableUploadInsert: true,\n },\n render: { afterEditable: ImagePreview },\n }),\n MediaEmbedPlugin,\n CaptionPlugin.configure({\n options: {\n plugins: [ImagePlugin, MediaEmbedPlugin],\n },\n }),\n DatePlugin,\n MentionPlugin.configure({\n options: {\n triggerPreviousCharPattern: /^$|^[\\s\"']$/,\n },\n }),\n SlashPlugin,\n TablePlugin.configure({\n options: {\n enableMerging: id === 'tableMerge',\n },\n }),\n ColumnPlugin,\n SelectionOverlayPlugin,\n\n TodoListPlugin,\n TogglePlugin,\n ExcalidrawPlugin,\n // Marks\n BoldPlugin,\n ItalicPlugin,\n UnderlinePlugin,\n StrikethroughPlugin,\n CodePlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n FontColorPlugin,\n FontBackgroundColorPlugin,\n FontSizePlugin,\n HighlightPlugin,\n KbdPlugin,\n\n // Block Style\n AlignPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n MediaEmbedPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n ImagePlugin.key,\n HEADING_KEYS.h6,\n ],\n },\n }),\n IndentPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n }),\n IndentListPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n options: {\n listStyleTypes: {\n fire: {\n liComponent: FireLiComponent,\n markerComponent: FireMarker,\n type: 'fire',\n },\n todo: {\n liComponent: TodoLi,\n markerComponent: TodoMarker,\n type: 'todo',\n },\n },\n },\n }),\n LineHeightPlugin.extend({\n inject: {\n nodeProps: {\n defaultNodeValue: 1.5,\n validNodeValues: [1, 1.2, 1.5, 2, 3],\n },\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n ],\n },\n }),\n\n // Functionality\n AutoformatPlugin.configure({\n options: autoformatOptions,\n }),\n BlockSelectionPlugin.configure({\n options: {\n areaOptions: {\n behaviour: {\n scrolling: {\n speedDivider: 1.5,\n },\n startThreshold: 10,\n },\n boundaries: `#${scrollSelector}`,\n container: `#${scrollSelector}`,\n selectables: [`#${scrollSelector} .slate-selectable`],\n selectionAreaClass: 'slate-selection-area',\n },\n enableContextMenu: true,\n },\n }),\n BlockMenuPlugin.configure({\n render: { aboveEditable: BlockContextMenu },\n }),\n DndPlugin.configure({\n options: {\n enableScroller: true,\n onDropFiles: ({ dragItem, editor, target }) => {\n editor\n .getTransforms(ImagePlugin)\n .insertImageFromFiles(dragItem.files, {\n at: target,\n nextBlock: false,\n });\n },\n },\n }),\n EmojiPlugin,\n exitBreakPlugin,\n NodeIdPlugin,\n NormalizeTypesPlugin.configure({\n options: {\n rules: [{ path: [0], strictType: HEADING_KEYS.h1 }],\n },\n }),\n resetBlockTypePlugin,\n SelectOnBackspacePlugin.configure({\n options: {\n query: {\n allow: [ImagePlugin.key, HorizontalRulePlugin.key],\n },\n },\n }),\n DeletePlugin,\n SingleLinePlugin,\n softBreakPlugin,\n tabbablePlugin,\n TrailingBlockPlugin.configure({\n options: { type: ParagraphPlugin.key },\n }),\n DragOverCursorPlugin,\n\n // Collaboration\n CommentsPlugin.configure({\n options: {\n comments: commentsData,\n myUserId: '1',\n users: usersData,\n },\n }),\n\n // Deserialization\n DocxPlugin,\n MarkdownPlugin.configure({ options: { indentList: true } }),\n JuicePlugin,\n\n // Testing\n PlaywrightPlugin.configure({\n enabled: process.env.NODE_ENV !== 'production',\n }),\n ],\n value: value,\n },\n []\n );\n};\n\nexport default function PlaygroundDemo({\n id,\n className,\n scrollSelector,\n}: {\n id?: ValueId;\n className?: string;\n scrollSelector?: string;\n}) {\n const containerRef = useRef(null);\n const enabled = settingsStore.use.checkedComponents();\n\n const editor = usePlaygroundEditor(\n id,\n scrollSelector ?? `blockSelection-${id}`\n );\n\n return (\n \n \n \n \n \n \n \n \n \n\n
\n \n \n\n \n \n \n \n \n \n \n\n \n \n \n \n\n \n \n \n
\n
\n
\n );\n}\n\nconst DemoIdContext = React.createContext(undefined);\n\nexport function DemoId({\n id,\n children,\n}: {\n children: React.ReactNode;\n id?: string;\n}) {\n return {children};\n}\n\nexport function useDemoId() {\n return React.useContext(DemoIdContext);\n}\n", + "content": "'use client';\n\nimport React, { useRef } from 'react';\n\nimport type { ValueId } from '@/config/customizer-plugins';\n\nimport { cn } from '@udecode/cn';\nimport { AIChatPlugin, CopilotPlugin } from '@udecode/plate-ai/react';\nimport { AlignPlugin } from '@udecode/plate-alignment/react';\nimport { AutoformatPlugin } from '@udecode/plate-autoformat/react';\nimport {\n BoldPlugin,\n CodePlugin,\n ItalicPlugin,\n StrikethroughPlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n UnderlinePlugin,\n} from '@udecode/plate-basic-marks/react';\nimport { BlockquotePlugin } from '@udecode/plate-block-quote/react';\nimport { SingleLinePlugin } from '@udecode/plate-break/react';\nimport { CaptionPlugin } from '@udecode/plate-caption/react';\nimport { CodeBlockPlugin } from '@udecode/plate-code-block/react';\nimport { CommentsPlugin } from '@udecode/plate-comments/react';\nimport {\n ParagraphPlugin,\n Plate,\n usePlateEditor,\n} from '@udecode/plate-common/react';\nimport { DatePlugin } from '@udecode/plate-date/react';\nimport { DndPlugin } from '@udecode/plate-dnd';\nimport { DocxPlugin } from '@udecode/plate-docx';\nimport { EmojiPlugin } from '@udecode/plate-emoji/react';\nimport { ExcalidrawPlugin } from '@udecode/plate-excalidraw/react';\nimport {\n FontBackgroundColorPlugin,\n FontColorPlugin,\n FontSizePlugin,\n} from '@udecode/plate-font/react';\nimport { HEADING_KEYS } from '@udecode/plate-heading';\nimport { HeadingPlugin, TocPlugin } from '@udecode/plate-heading/react';\nimport { HighlightPlugin } from '@udecode/plate-highlight/react';\nimport { HorizontalRulePlugin } from '@udecode/plate-horizontal-rule/react';\nimport { IndentPlugin } from '@udecode/plate-indent/react';\nimport { IndentListPlugin } from '@udecode/plate-indent-list/react';\nimport { JuicePlugin } from '@udecode/plate-juice';\nimport { KbdPlugin } from '@udecode/plate-kbd/react';\nimport { ColumnPlugin } from '@udecode/plate-layout/react';\nimport { LineHeightPlugin } from '@udecode/plate-line-height/react';\nimport { LinkPlugin } from '@udecode/plate-link/react';\nimport { ListPlugin, TodoListPlugin } from '@udecode/plate-list/react';\nimport { MarkdownPlugin } from '@udecode/plate-markdown';\nimport { BaseImagePlugin } from '@udecode/plate-media';\nimport { ImagePlugin, MediaEmbedPlugin } from '@udecode/plate-media/react';\nimport { MentionPlugin } from '@udecode/plate-mention/react';\nimport { NodeIdPlugin } from '@udecode/plate-node-id';\nimport { NormalizeTypesPlugin } from '@udecode/plate-normalizers';\nimport { PlaywrightPlugin } from '@udecode/plate-playwright';\nimport { DeletePlugin, SelectOnBackspacePlugin } from '@udecode/plate-select';\nimport {\n BlockMenuPlugin,\n BlockSelectionPlugin,\n} from '@udecode/plate-selection/react';\nimport { SlashPlugin } from '@udecode/plate-slash-command/react';\nimport { TablePlugin } from '@udecode/plate-table/react';\nimport { TogglePlugin } from '@udecode/plate-toggle/react';\nimport { TrailingBlockPlugin } from '@udecode/plate-trailing-block';\nimport Prism from 'prismjs';\n\nimport { CheckPlugin } from '@/components/context/check-plugin';\nimport { settingsStore } from '@/components/context/settings-store';\nimport { aiPlugins } from '@/lib/plate/demo/plugins/ai-plugins';\nimport { getAutoformatOptions } from '@/lib/plate/demo/plugins/autoformatOptions';\nimport { copilotPlugins } from '@/lib/plate/demo/plugins/copilot-plugins';\nimport { createPlateUI } from '@/plate/create-plate-ui';\nimport { editableProps } from '@/plate/demo/editableProps';\nimport { isEnabled } from '@/plate/demo/is-enabled';\nimport { DragOverCursorPlugin } from '@/plate/demo/plugins/DragOverCursorPlugin';\nimport { exitBreakPlugin } from '@/plate/demo/plugins/exitBreakPlugin';\nimport { resetBlockTypePlugin } from '@/plate/demo/plugins/resetBlockTypePlugin';\nimport { softBreakPlugin } from '@/plate/demo/plugins/softBreakPlugin';\nimport { tabbablePlugin } from '@/plate/demo/plugins/tabbablePlugin';\nimport { commentsData, usersData } from '@/plate/demo/values/commentsValue';\nimport { usePlaygroundValue } from '@/plate/demo/values/usePlaygroundValue';\nimport { BlockContextMenu } from '@/components/plate-ui/block-context-menu';\nimport { CommentsPopover } from '@/components/plate-ui/comments-popover';\nimport {\n CursorOverlay,\n SelectionOverlayPlugin,\n} from '@/components/plate-ui/cursor-overlay';\nimport { Editor, EditorContainer } from '@/components/plate-ui/editor';\nimport { FixedToolbar } from '@/components/plate-ui/fixed-toolbar';\nimport { FixedToolbarButtons } from '@/components/plate-ui/fixed-toolbar-buttons';\nimport { FloatingToolbar } from '@/components/plate-ui/floating-toolbar';\nimport { FloatingToolbarButtons } from '@/components/plate-ui/floating-toolbar-buttons';\nimport { ImagePreview } from '@/components/plate-ui/image-preview';\nimport {\n FireLiComponent,\n FireMarker,\n} from '@/components/plate-ui/indent-fire-marker';\nimport {\n TodoLi,\n TodoMarker,\n} from '@/components/plate-ui/indent-todo-marker';\nimport { LinkFloatingToolbar } from '@/components/plate-ui/link-floating-toolbar';\n\nimport { usePlaygroundEnabled } from './usePlaygroundEnabled';\n\nexport const usePlaygroundEditor = (id: any = '', scrollSelector?: string) => {\n const enabledPlugins = settingsStore.use.checkedPlugins();\n const overridePlugins = usePlaygroundEnabled(id);\n const autoformatOptions = getAutoformatOptions(id, enabledPlugins);\n\n const value = usePlaygroundValue(id);\n const key = settingsStore.use.version();\n const editorId = id || 'playground-' + key;\n\n return usePlateEditor(\n {\n id: editorId,\n override: {\n components: createPlateUI({\n draggable: isEnabled('dnd', id),\n placeholder: isEnabled('placeholder', id),\n }),\n plugins: overridePlugins,\n },\n plugins: [\n // AI\n ...(id === 'ai' || enabledPlugins[AIChatPlugin.key] ? aiPlugins : []),\n ...(id === 'copilot' || enabledPlugins[CopilotPlugin.key]\n ? copilotPlugins\n : []),\n // Nodes\n HeadingPlugin,\n TocPlugin.configure({\n options: {\n scrollContainerSelector: `#${scrollSelector}`,\n topOffset: 80,\n },\n }),\n BlockquotePlugin,\n CodeBlockPlugin.configure({\n options: {\n prism: Prism,\n },\n }),\n HorizontalRulePlugin,\n LinkPlugin.extend({\n render: { afterEditable: () => },\n }),\n ...(id === 'list' ? [ListPlugin] : []),\n ImagePlugin.extend({\n options: {\n disableUploadInsert: true,\n },\n render: { afterEditable: ImagePreview },\n }),\n MediaEmbedPlugin,\n CaptionPlugin.configure({\n options: {\n plugins: [ImagePlugin, MediaEmbedPlugin],\n },\n }),\n DatePlugin,\n MentionPlugin.configure({\n options: {\n triggerPreviousCharPattern: /^$|^[\\s\"']$/,\n },\n }),\n SlashPlugin,\n TablePlugin.configure({\n options: {\n enableMerging: id === 'tableMerge',\n },\n }),\n ColumnPlugin,\n SelectionOverlayPlugin,\n\n TodoListPlugin,\n TogglePlugin,\n ExcalidrawPlugin,\n // Marks\n BoldPlugin,\n ItalicPlugin,\n UnderlinePlugin,\n StrikethroughPlugin,\n CodePlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n FontColorPlugin,\n FontBackgroundColorPlugin,\n FontSizePlugin,\n HighlightPlugin,\n KbdPlugin,\n\n // Block Style\n AlignPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n MediaEmbedPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n ImagePlugin.key,\n HEADING_KEYS.h6,\n ],\n },\n }),\n IndentPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n }),\n IndentListPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n options: {\n listStyleTypes: {\n fire: {\n liComponent: FireLiComponent,\n markerComponent: FireMarker,\n type: 'fire',\n },\n todo: {\n liComponent: TodoLi,\n markerComponent: TodoMarker,\n type: 'todo',\n },\n },\n },\n }),\n LineHeightPlugin.extend({\n inject: {\n nodeProps: {\n defaultNodeValue: 1.5,\n validNodeValues: [1, 1.2, 1.5, 2, 3],\n },\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n ],\n },\n }),\n\n // Functionality\n AutoformatPlugin.configure({\n options: autoformatOptions,\n }),\n BlockSelectionPlugin.configure({\n options: {\n areaOptions: {\n behaviour: {\n scrolling: {\n speedDivider: 1.5,\n },\n startThreshold: 10,\n },\n boundaries: `#${scrollSelector}`,\n container: `#${scrollSelector}`,\n selectables: [`#${scrollSelector} .slate-selectable`],\n selectionAreaClass: 'slate-selection-area',\n },\n enableContextMenu: true,\n },\n }),\n BlockMenuPlugin.configure({\n render: { aboveEditable: BlockContextMenu },\n }),\n DndPlugin.configure({\n options: {\n enableScroller: true,\n onDropFiles: ({ dragItem, editor, target }) => {\n editor\n .getTransforms(BaseImagePlugin)\n .insert.imageFromFiles(dragItem.files, {\n at: target,\n nextBlock: false,\n });\n },\n },\n }),\n EmojiPlugin,\n exitBreakPlugin,\n NodeIdPlugin,\n NormalizeTypesPlugin.configure({\n options: {\n rules: [{ path: [0], strictType: HEADING_KEYS.h1 }],\n },\n }),\n resetBlockTypePlugin,\n SelectOnBackspacePlugin.configure({\n options: {\n query: {\n allow: [ImagePlugin.key, HorizontalRulePlugin.key],\n },\n },\n }),\n DeletePlugin,\n SingleLinePlugin,\n softBreakPlugin,\n tabbablePlugin,\n TrailingBlockPlugin.configure({\n options: { type: ParagraphPlugin.key },\n }),\n DragOverCursorPlugin,\n\n // Collaboration\n CommentsPlugin.configure({\n options: {\n comments: commentsData,\n myUserId: '1',\n users: usersData,\n },\n }),\n\n // Deserialization\n DocxPlugin,\n MarkdownPlugin.configure({ options: { indentList: true } }),\n JuicePlugin,\n\n // Testing\n PlaywrightPlugin.configure({\n enabled: process.env.NODE_ENV !== 'production',\n }),\n ],\n value: value,\n },\n []\n );\n};\n\nexport default function PlaygroundDemo({\n id,\n className,\n scrollSelector,\n}: {\n id?: ValueId;\n className?: string;\n scrollSelector?: string;\n}) {\n const containerRef = useRef(null);\n const enabled = settingsStore.use.checkedComponents();\n\n const editor = usePlaygroundEditor(\n id,\n scrollSelector ?? `blockSelection-${id}`\n );\n\n return (\n \n \n \n \n \n \n \n \n \n\n
\n \n \n\n \n \n \n \n \n \n \n\n \n \n \n \n\n \n \n \n
\n
\n
\n );\n}\n\nconst DemoIdContext = React.createContext(undefined);\n\nexport function DemoId({\n id,\n children,\n}: {\n children: React.ReactNode;\n id?: string;\n}) {\n return {children};\n}\n\nexport function useDemoId() {\n return React.useContext(DemoIdContext);\n}\n", "path": "example/playground-demo.tsx", "target": "components/playground-demo.tsx", "type": "registry:example" diff --git a/apps/www/public/r/styles/default/table-demo.json b/apps/www/public/r/styles/default/table-demo.json index d761e26bf4..c1eea129fd 100644 --- a/apps/www/public/r/styles/default/table-demo.json +++ b/apps/www/public/r/styles/default/table-demo.json @@ -4,7 +4,7 @@ }, "files": [ { - "content": "'use client';\n\nimport React, { useRef } from 'react';\n\nimport type { ValueId } from '@/config/customizer-plugins';\n\nimport { cn } from '@udecode/cn';\nimport { AIChatPlugin, CopilotPlugin } from '@udecode/plate-ai/react';\nimport { AlignPlugin } from '@udecode/plate-alignment/react';\nimport { AutoformatPlugin } from '@udecode/plate-autoformat/react';\nimport {\n BoldPlugin,\n CodePlugin,\n ItalicPlugin,\n StrikethroughPlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n UnderlinePlugin,\n} from '@udecode/plate-basic-marks/react';\nimport { BlockquotePlugin } from '@udecode/plate-block-quote/react';\nimport { SingleLinePlugin } from '@udecode/plate-break/react';\nimport { CaptionPlugin } from '@udecode/plate-caption/react';\nimport { CodeBlockPlugin } from '@udecode/plate-code-block/react';\nimport { CommentsPlugin } from '@udecode/plate-comments/react';\nimport {\n ParagraphPlugin,\n Plate,\n usePlateEditor,\n} from '@udecode/plate-common/react';\nimport { DatePlugin } from '@udecode/plate-date/react';\nimport { DndPlugin } from '@udecode/plate-dnd';\nimport { DocxPlugin } from '@udecode/plate-docx';\nimport { EmojiPlugin } from '@udecode/plate-emoji/react';\nimport { ExcalidrawPlugin } from '@udecode/plate-excalidraw/react';\nimport {\n FontBackgroundColorPlugin,\n FontColorPlugin,\n FontSizePlugin,\n} from '@udecode/plate-font/react';\nimport { HEADING_KEYS } from '@udecode/plate-heading';\nimport { HeadingPlugin, TocPlugin } from '@udecode/plate-heading/react';\nimport { HighlightPlugin } from '@udecode/plate-highlight/react';\nimport { HorizontalRulePlugin } from '@udecode/plate-horizontal-rule/react';\nimport { IndentPlugin } from '@udecode/plate-indent/react';\nimport { IndentListPlugin } from '@udecode/plate-indent-list/react';\nimport { JuicePlugin } from '@udecode/plate-juice';\nimport { KbdPlugin } from '@udecode/plate-kbd/react';\nimport { ColumnPlugin } from '@udecode/plate-layout/react';\nimport { LineHeightPlugin } from '@udecode/plate-line-height/react';\nimport { LinkPlugin } from '@udecode/plate-link/react';\nimport { ListPlugin, TodoListPlugin } from '@udecode/plate-list/react';\nimport { MarkdownPlugin } from '@udecode/plate-markdown';\nimport { ImagePlugin, MediaEmbedPlugin } from '@udecode/plate-media/react';\nimport { MentionPlugin } from '@udecode/plate-mention/react';\nimport { NodeIdPlugin } from '@udecode/plate-node-id';\nimport { NormalizeTypesPlugin } from '@udecode/plate-normalizers';\nimport { PlaywrightPlugin } from '@udecode/plate-playwright';\nimport { DeletePlugin, SelectOnBackspacePlugin } from '@udecode/plate-select';\nimport {\n BlockMenuPlugin,\n BlockSelectionPlugin,\n} from '@udecode/plate-selection/react';\nimport { SlashPlugin } from '@udecode/plate-slash-command/react';\nimport { TablePlugin } from '@udecode/plate-table/react';\nimport { TogglePlugin } from '@udecode/plate-toggle/react';\nimport { TrailingBlockPlugin } from '@udecode/plate-trailing-block';\nimport Prism from 'prismjs';\n\nimport { CheckPlugin } from '@/components/context/check-plugin';\nimport { settingsStore } from '@/components/context/settings-store';\nimport { aiPlugins } from '@/lib/plate/demo/plugins/ai-plugins';\nimport { getAutoformatOptions } from '@/lib/plate/demo/plugins/autoformatOptions';\nimport { copilotPlugins } from '@/lib/plate/demo/plugins/copilot-plugins';\nimport { createPlateUI } from '@/plate/create-plate-ui';\nimport { editableProps } from '@/plate/demo/editableProps';\nimport { isEnabled } from '@/plate/demo/is-enabled';\nimport { DragOverCursorPlugin } from '@/plate/demo/plugins/DragOverCursorPlugin';\nimport { exitBreakPlugin } from '@/plate/demo/plugins/exitBreakPlugin';\nimport { resetBlockTypePlugin } from '@/plate/demo/plugins/resetBlockTypePlugin';\nimport { softBreakPlugin } from '@/plate/demo/plugins/softBreakPlugin';\nimport { tabbablePlugin } from '@/plate/demo/plugins/tabbablePlugin';\nimport { commentsData, usersData } from '@/plate/demo/values/commentsValue';\nimport { usePlaygroundValue } from '@/plate/demo/values/usePlaygroundValue';\nimport { BlockContextMenu } from '@/components/plate-ui/block-context-menu';\nimport { CommentsPopover } from '@/components/plate-ui/comments-popover';\nimport {\n CursorOverlay,\n SelectionOverlayPlugin,\n} from '@/components/plate-ui/cursor-overlay';\nimport { Editor, EditorContainer } from '@/components/plate-ui/editor';\nimport { FixedToolbar } from '@/components/plate-ui/fixed-toolbar';\nimport { FixedToolbarButtons } from '@/components/plate-ui/fixed-toolbar-buttons';\nimport { FloatingToolbar } from '@/components/plate-ui/floating-toolbar';\nimport { FloatingToolbarButtons } from '@/components/plate-ui/floating-toolbar-buttons';\nimport { ImagePreview } from '@/components/plate-ui/image-preview';\nimport {\n FireLiComponent,\n FireMarker,\n} from '@/components/plate-ui/indent-fire-marker';\nimport {\n TodoLi,\n TodoMarker,\n} from '@/components/plate-ui/indent-todo-marker';\nimport { LinkFloatingToolbar } from '@/components/plate-ui/link-floating-toolbar';\n\nimport { usePlaygroundEnabled } from './usePlaygroundEnabled';\n\nexport const usePlaygroundEditor = (id: any = '', scrollSelector?: string) => {\n const enabledPlugins = settingsStore.use.checkedPlugins();\n const overridePlugins = usePlaygroundEnabled(id);\n const autoformatOptions = getAutoformatOptions(id, enabledPlugins);\n\n const value = usePlaygroundValue(id);\n const key = settingsStore.use.version();\n const editorId = id || 'playground-' + key;\n\n return usePlateEditor(\n {\n id: editorId,\n override: {\n components: createPlateUI({\n draggable: isEnabled('dnd', id),\n placeholder: isEnabled('placeholder', id),\n }),\n plugins: overridePlugins,\n },\n plugins: [\n // AI\n ...(id === 'ai' || enabledPlugins[AIChatPlugin.key] ? aiPlugins : []),\n ...(id === 'copilot' || enabledPlugins[CopilotPlugin.key]\n ? copilotPlugins\n : []),\n // Nodes\n HeadingPlugin,\n TocPlugin.configure({\n options: {\n scrollContainerSelector: `#${scrollSelector}`,\n topOffset: 80,\n },\n }),\n BlockquotePlugin,\n CodeBlockPlugin.configure({\n options: {\n prism: Prism,\n },\n }),\n HorizontalRulePlugin,\n LinkPlugin.extend({\n render: { afterEditable: () => },\n }),\n ...(id === 'list' ? [ListPlugin] : []),\n ImagePlugin.extend({\n options: {\n disableUploadInsert: true,\n },\n render: { afterEditable: ImagePreview },\n }),\n MediaEmbedPlugin,\n CaptionPlugin.configure({\n options: {\n plugins: [ImagePlugin, MediaEmbedPlugin],\n },\n }),\n DatePlugin,\n MentionPlugin.configure({\n options: {\n triggerPreviousCharPattern: /^$|^[\\s\"']$/,\n },\n }),\n SlashPlugin,\n TablePlugin.configure({\n options: {\n enableMerging: id === 'tableMerge',\n },\n }),\n ColumnPlugin,\n SelectionOverlayPlugin,\n\n TodoListPlugin,\n TogglePlugin,\n ExcalidrawPlugin,\n // Marks\n BoldPlugin,\n ItalicPlugin,\n UnderlinePlugin,\n StrikethroughPlugin,\n CodePlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n FontColorPlugin,\n FontBackgroundColorPlugin,\n FontSizePlugin,\n HighlightPlugin,\n KbdPlugin,\n\n // Block Style\n AlignPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n MediaEmbedPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n ImagePlugin.key,\n HEADING_KEYS.h6,\n ],\n },\n }),\n IndentPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n }),\n IndentListPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n options: {\n listStyleTypes: {\n fire: {\n liComponent: FireLiComponent,\n markerComponent: FireMarker,\n type: 'fire',\n },\n todo: {\n liComponent: TodoLi,\n markerComponent: TodoMarker,\n type: 'todo',\n },\n },\n },\n }),\n LineHeightPlugin.extend({\n inject: {\n nodeProps: {\n defaultNodeValue: 1.5,\n validNodeValues: [1, 1.2, 1.5, 2, 3],\n },\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n ],\n },\n }),\n\n // Functionality\n AutoformatPlugin.configure({\n options: autoformatOptions,\n }),\n BlockSelectionPlugin.configure({\n options: {\n areaOptions: {\n behaviour: {\n scrolling: {\n speedDivider: 1.5,\n },\n startThreshold: 10,\n },\n boundaries: `#${scrollSelector}`,\n container: `#${scrollSelector}`,\n selectables: [`#${scrollSelector} .slate-selectable`],\n selectionAreaClass: 'slate-selection-area',\n },\n enableContextMenu: true,\n },\n }),\n BlockMenuPlugin.configure({\n render: { aboveEditable: BlockContextMenu },\n }),\n DndPlugin.configure({\n options: {\n enableScroller: true,\n onDropFiles: ({ dragItem, editor, target }) => {\n editor\n .getTransforms(ImagePlugin)\n .insertImageFromFiles(dragItem.files, {\n at: target,\n nextBlock: false,\n });\n },\n },\n }),\n EmojiPlugin,\n exitBreakPlugin,\n NodeIdPlugin,\n NormalizeTypesPlugin.configure({\n options: {\n rules: [{ path: [0], strictType: HEADING_KEYS.h1 }],\n },\n }),\n resetBlockTypePlugin,\n SelectOnBackspacePlugin.configure({\n options: {\n query: {\n allow: [ImagePlugin.key, HorizontalRulePlugin.key],\n },\n },\n }),\n DeletePlugin,\n SingleLinePlugin,\n softBreakPlugin,\n tabbablePlugin,\n TrailingBlockPlugin.configure({\n options: { type: ParagraphPlugin.key },\n }),\n DragOverCursorPlugin,\n\n // Collaboration\n CommentsPlugin.configure({\n options: {\n comments: commentsData,\n myUserId: '1',\n users: usersData,\n },\n }),\n\n // Deserialization\n DocxPlugin,\n MarkdownPlugin.configure({ options: { indentList: true } }),\n JuicePlugin,\n\n // Testing\n PlaywrightPlugin.configure({\n enabled: process.env.NODE_ENV !== 'production',\n }),\n ],\n value: value,\n },\n []\n );\n};\n\nexport default function PlaygroundDemo({\n id,\n className,\n scrollSelector,\n}: {\n id?: ValueId;\n className?: string;\n scrollSelector?: string;\n}) {\n const containerRef = useRef(null);\n const enabled = settingsStore.use.checkedComponents();\n\n const editor = usePlaygroundEditor(\n id,\n scrollSelector ?? `blockSelection-${id}`\n );\n\n return (\n \n \n \n \n \n \n \n \n \n\n
\n \n \n\n \n \n \n \n \n \n \n\n \n \n \n \n\n \n \n \n
\n
\n
\n );\n}\n\nconst DemoIdContext = React.createContext(undefined);\n\nexport function DemoId({\n id,\n children,\n}: {\n children: React.ReactNode;\n id?: string;\n}) {\n return {children};\n}\n\nexport function useDemoId() {\n return React.useContext(DemoIdContext);\n}\n", + "content": "'use client';\n\nimport React, { useRef } from 'react';\n\nimport type { ValueId } from '@/config/customizer-plugins';\n\nimport { cn } from '@udecode/cn';\nimport { AIChatPlugin, CopilotPlugin } from '@udecode/plate-ai/react';\nimport { AlignPlugin } from '@udecode/plate-alignment/react';\nimport { AutoformatPlugin } from '@udecode/plate-autoformat/react';\nimport {\n BoldPlugin,\n CodePlugin,\n ItalicPlugin,\n StrikethroughPlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n UnderlinePlugin,\n} from '@udecode/plate-basic-marks/react';\nimport { BlockquotePlugin } from '@udecode/plate-block-quote/react';\nimport { SingleLinePlugin } from '@udecode/plate-break/react';\nimport { CaptionPlugin } from '@udecode/plate-caption/react';\nimport { CodeBlockPlugin } from '@udecode/plate-code-block/react';\nimport { CommentsPlugin } from '@udecode/plate-comments/react';\nimport {\n ParagraphPlugin,\n Plate,\n usePlateEditor,\n} from '@udecode/plate-common/react';\nimport { DatePlugin } from '@udecode/plate-date/react';\nimport { DndPlugin } from '@udecode/plate-dnd';\nimport { DocxPlugin } from '@udecode/plate-docx';\nimport { EmojiPlugin } from '@udecode/plate-emoji/react';\nimport { ExcalidrawPlugin } from '@udecode/plate-excalidraw/react';\nimport {\n FontBackgroundColorPlugin,\n FontColorPlugin,\n FontSizePlugin,\n} from '@udecode/plate-font/react';\nimport { HEADING_KEYS } from '@udecode/plate-heading';\nimport { HeadingPlugin, TocPlugin } from '@udecode/plate-heading/react';\nimport { HighlightPlugin } from '@udecode/plate-highlight/react';\nimport { HorizontalRulePlugin } from '@udecode/plate-horizontal-rule/react';\nimport { IndentPlugin } from '@udecode/plate-indent/react';\nimport { IndentListPlugin } from '@udecode/plate-indent-list/react';\nimport { JuicePlugin } from '@udecode/plate-juice';\nimport { KbdPlugin } from '@udecode/plate-kbd/react';\nimport { ColumnPlugin } from '@udecode/plate-layout/react';\nimport { LineHeightPlugin } from '@udecode/plate-line-height/react';\nimport { LinkPlugin } from '@udecode/plate-link/react';\nimport { ListPlugin, TodoListPlugin } from '@udecode/plate-list/react';\nimport { MarkdownPlugin } from '@udecode/plate-markdown';\nimport { BaseImagePlugin } from '@udecode/plate-media';\nimport { ImagePlugin, MediaEmbedPlugin } from '@udecode/plate-media/react';\nimport { MentionPlugin } from '@udecode/plate-mention/react';\nimport { NodeIdPlugin } from '@udecode/plate-node-id';\nimport { NormalizeTypesPlugin } from '@udecode/plate-normalizers';\nimport { PlaywrightPlugin } from '@udecode/plate-playwright';\nimport { DeletePlugin, SelectOnBackspacePlugin } from '@udecode/plate-select';\nimport {\n BlockMenuPlugin,\n BlockSelectionPlugin,\n} from '@udecode/plate-selection/react';\nimport { SlashPlugin } from '@udecode/plate-slash-command/react';\nimport { TablePlugin } from '@udecode/plate-table/react';\nimport { TogglePlugin } from '@udecode/plate-toggle/react';\nimport { TrailingBlockPlugin } from '@udecode/plate-trailing-block';\nimport Prism from 'prismjs';\n\nimport { CheckPlugin } from '@/components/context/check-plugin';\nimport { settingsStore } from '@/components/context/settings-store';\nimport { aiPlugins } from '@/lib/plate/demo/plugins/ai-plugins';\nimport { getAutoformatOptions } from '@/lib/plate/demo/plugins/autoformatOptions';\nimport { copilotPlugins } from '@/lib/plate/demo/plugins/copilot-plugins';\nimport { createPlateUI } from '@/plate/create-plate-ui';\nimport { editableProps } from '@/plate/demo/editableProps';\nimport { isEnabled } from '@/plate/demo/is-enabled';\nimport { DragOverCursorPlugin } from '@/plate/demo/plugins/DragOverCursorPlugin';\nimport { exitBreakPlugin } from '@/plate/demo/plugins/exitBreakPlugin';\nimport { resetBlockTypePlugin } from '@/plate/demo/plugins/resetBlockTypePlugin';\nimport { softBreakPlugin } from '@/plate/demo/plugins/softBreakPlugin';\nimport { tabbablePlugin } from '@/plate/demo/plugins/tabbablePlugin';\nimport { commentsData, usersData } from '@/plate/demo/values/commentsValue';\nimport { usePlaygroundValue } from '@/plate/demo/values/usePlaygroundValue';\nimport { BlockContextMenu } from '@/components/plate-ui/block-context-menu';\nimport { CommentsPopover } from '@/components/plate-ui/comments-popover';\nimport {\n CursorOverlay,\n SelectionOverlayPlugin,\n} from '@/components/plate-ui/cursor-overlay';\nimport { Editor, EditorContainer } from '@/components/plate-ui/editor';\nimport { FixedToolbar } from '@/components/plate-ui/fixed-toolbar';\nimport { FixedToolbarButtons } from '@/components/plate-ui/fixed-toolbar-buttons';\nimport { FloatingToolbar } from '@/components/plate-ui/floating-toolbar';\nimport { FloatingToolbarButtons } from '@/components/plate-ui/floating-toolbar-buttons';\nimport { ImagePreview } from '@/components/plate-ui/image-preview';\nimport {\n FireLiComponent,\n FireMarker,\n} from '@/components/plate-ui/indent-fire-marker';\nimport {\n TodoLi,\n TodoMarker,\n} from '@/components/plate-ui/indent-todo-marker';\nimport { LinkFloatingToolbar } from '@/components/plate-ui/link-floating-toolbar';\n\nimport { usePlaygroundEnabled } from './usePlaygroundEnabled';\n\nexport const usePlaygroundEditor = (id: any = '', scrollSelector?: string) => {\n const enabledPlugins = settingsStore.use.checkedPlugins();\n const overridePlugins = usePlaygroundEnabled(id);\n const autoformatOptions = getAutoformatOptions(id, enabledPlugins);\n\n const value = usePlaygroundValue(id);\n const key = settingsStore.use.version();\n const editorId = id || 'playground-' + key;\n\n return usePlateEditor(\n {\n id: editorId,\n override: {\n components: createPlateUI({\n draggable: isEnabled('dnd', id),\n placeholder: isEnabled('placeholder', id),\n }),\n plugins: overridePlugins,\n },\n plugins: [\n // AI\n ...(id === 'ai' || enabledPlugins[AIChatPlugin.key] ? aiPlugins : []),\n ...(id === 'copilot' || enabledPlugins[CopilotPlugin.key]\n ? copilotPlugins\n : []),\n // Nodes\n HeadingPlugin,\n TocPlugin.configure({\n options: {\n scrollContainerSelector: `#${scrollSelector}`,\n topOffset: 80,\n },\n }),\n BlockquotePlugin,\n CodeBlockPlugin.configure({\n options: {\n prism: Prism,\n },\n }),\n HorizontalRulePlugin,\n LinkPlugin.extend({\n render: { afterEditable: () => },\n }),\n ...(id === 'list' ? [ListPlugin] : []),\n ImagePlugin.extend({\n options: {\n disableUploadInsert: true,\n },\n render: { afterEditable: ImagePreview },\n }),\n MediaEmbedPlugin,\n CaptionPlugin.configure({\n options: {\n plugins: [ImagePlugin, MediaEmbedPlugin],\n },\n }),\n DatePlugin,\n MentionPlugin.configure({\n options: {\n triggerPreviousCharPattern: /^$|^[\\s\"']$/,\n },\n }),\n SlashPlugin,\n TablePlugin.configure({\n options: {\n enableMerging: id === 'tableMerge',\n },\n }),\n ColumnPlugin,\n SelectionOverlayPlugin,\n\n TodoListPlugin,\n TogglePlugin,\n ExcalidrawPlugin,\n // Marks\n BoldPlugin,\n ItalicPlugin,\n UnderlinePlugin,\n StrikethroughPlugin,\n CodePlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n FontColorPlugin,\n FontBackgroundColorPlugin,\n FontSizePlugin,\n HighlightPlugin,\n KbdPlugin,\n\n // Block Style\n AlignPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n MediaEmbedPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n ImagePlugin.key,\n HEADING_KEYS.h6,\n ],\n },\n }),\n IndentPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n }),\n IndentListPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n options: {\n listStyleTypes: {\n fire: {\n liComponent: FireLiComponent,\n markerComponent: FireMarker,\n type: 'fire',\n },\n todo: {\n liComponent: TodoLi,\n markerComponent: TodoMarker,\n type: 'todo',\n },\n },\n },\n }),\n LineHeightPlugin.extend({\n inject: {\n nodeProps: {\n defaultNodeValue: 1.5,\n validNodeValues: [1, 1.2, 1.5, 2, 3],\n },\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n ],\n },\n }),\n\n // Functionality\n AutoformatPlugin.configure({\n options: autoformatOptions,\n }),\n BlockSelectionPlugin.configure({\n options: {\n areaOptions: {\n behaviour: {\n scrolling: {\n speedDivider: 1.5,\n },\n startThreshold: 10,\n },\n boundaries: `#${scrollSelector}`,\n container: `#${scrollSelector}`,\n selectables: [`#${scrollSelector} .slate-selectable`],\n selectionAreaClass: 'slate-selection-area',\n },\n enableContextMenu: true,\n },\n }),\n BlockMenuPlugin.configure({\n render: { aboveEditable: BlockContextMenu },\n }),\n DndPlugin.configure({\n options: {\n enableScroller: true,\n onDropFiles: ({ dragItem, editor, target }) => {\n editor\n .getTransforms(BaseImagePlugin)\n .insert.imageFromFiles(dragItem.files, {\n at: target,\n nextBlock: false,\n });\n },\n },\n }),\n EmojiPlugin,\n exitBreakPlugin,\n NodeIdPlugin,\n NormalizeTypesPlugin.configure({\n options: {\n rules: [{ path: [0], strictType: HEADING_KEYS.h1 }],\n },\n }),\n resetBlockTypePlugin,\n SelectOnBackspacePlugin.configure({\n options: {\n query: {\n allow: [ImagePlugin.key, HorizontalRulePlugin.key],\n },\n },\n }),\n DeletePlugin,\n SingleLinePlugin,\n softBreakPlugin,\n tabbablePlugin,\n TrailingBlockPlugin.configure({\n options: { type: ParagraphPlugin.key },\n }),\n DragOverCursorPlugin,\n\n // Collaboration\n CommentsPlugin.configure({\n options: {\n comments: commentsData,\n myUserId: '1',\n users: usersData,\n },\n }),\n\n // Deserialization\n DocxPlugin,\n MarkdownPlugin.configure({ options: { indentList: true } }),\n JuicePlugin,\n\n // Testing\n PlaywrightPlugin.configure({\n enabled: process.env.NODE_ENV !== 'production',\n }),\n ],\n value: value,\n },\n []\n );\n};\n\nexport default function PlaygroundDemo({\n id,\n className,\n scrollSelector,\n}: {\n id?: ValueId;\n className?: string;\n scrollSelector?: string;\n}) {\n const containerRef = useRef(null);\n const enabled = settingsStore.use.checkedComponents();\n\n const editor = usePlaygroundEditor(\n id,\n scrollSelector ?? `blockSelection-${id}`\n );\n\n return (\n \n \n \n \n \n \n \n \n \n\n
\n \n \n\n \n \n \n \n \n \n \n\n \n \n \n \n\n \n \n \n
\n
\n
\n );\n}\n\nconst DemoIdContext = React.createContext(undefined);\n\nexport function DemoId({\n id,\n children,\n}: {\n children: React.ReactNode;\n id?: string;\n}) {\n return {children};\n}\n\nexport function useDemoId() {\n return React.useContext(DemoIdContext);\n}\n", "path": "example/playground-demo.tsx", "target": "components/playground-demo.tsx", "type": "registry:example" diff --git a/apps/www/public/r/styles/default/toc-demo.json b/apps/www/public/r/styles/default/toc-demo.json index 1a6bc925ed..3284578ea0 100644 --- a/apps/www/public/r/styles/default/toc-demo.json +++ b/apps/www/public/r/styles/default/toc-demo.json @@ -4,7 +4,7 @@ }, "files": [ { - "content": "'use client';\n\nimport React, { useRef } from 'react';\n\nimport type { ValueId } from '@/config/customizer-plugins';\n\nimport { cn } from '@udecode/cn';\nimport { AIChatPlugin, CopilotPlugin } from '@udecode/plate-ai/react';\nimport { AlignPlugin } from '@udecode/plate-alignment/react';\nimport { AutoformatPlugin } from '@udecode/plate-autoformat/react';\nimport {\n BoldPlugin,\n CodePlugin,\n ItalicPlugin,\n StrikethroughPlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n UnderlinePlugin,\n} from '@udecode/plate-basic-marks/react';\nimport { BlockquotePlugin } from '@udecode/plate-block-quote/react';\nimport { SingleLinePlugin } from '@udecode/plate-break/react';\nimport { CaptionPlugin } from '@udecode/plate-caption/react';\nimport { CodeBlockPlugin } from '@udecode/plate-code-block/react';\nimport { CommentsPlugin } from '@udecode/plate-comments/react';\nimport {\n ParagraphPlugin,\n Plate,\n usePlateEditor,\n} from '@udecode/plate-common/react';\nimport { DatePlugin } from '@udecode/plate-date/react';\nimport { DndPlugin } from '@udecode/plate-dnd';\nimport { DocxPlugin } from '@udecode/plate-docx';\nimport { EmojiPlugin } from '@udecode/plate-emoji/react';\nimport { ExcalidrawPlugin } from '@udecode/plate-excalidraw/react';\nimport {\n FontBackgroundColorPlugin,\n FontColorPlugin,\n FontSizePlugin,\n} from '@udecode/plate-font/react';\nimport { HEADING_KEYS } from '@udecode/plate-heading';\nimport { HeadingPlugin, TocPlugin } from '@udecode/plate-heading/react';\nimport { HighlightPlugin } from '@udecode/plate-highlight/react';\nimport { HorizontalRulePlugin } from '@udecode/plate-horizontal-rule/react';\nimport { IndentPlugin } from '@udecode/plate-indent/react';\nimport { IndentListPlugin } from '@udecode/plate-indent-list/react';\nimport { JuicePlugin } from '@udecode/plate-juice';\nimport { KbdPlugin } from '@udecode/plate-kbd/react';\nimport { ColumnPlugin } from '@udecode/plate-layout/react';\nimport { LineHeightPlugin } from '@udecode/plate-line-height/react';\nimport { LinkPlugin } from '@udecode/plate-link/react';\nimport { ListPlugin, TodoListPlugin } from '@udecode/plate-list/react';\nimport { MarkdownPlugin } from '@udecode/plate-markdown';\nimport { ImagePlugin, MediaEmbedPlugin } from '@udecode/plate-media/react';\nimport { MentionPlugin } from '@udecode/plate-mention/react';\nimport { NodeIdPlugin } from '@udecode/plate-node-id';\nimport { NormalizeTypesPlugin } from '@udecode/plate-normalizers';\nimport { PlaywrightPlugin } from '@udecode/plate-playwright';\nimport { DeletePlugin, SelectOnBackspacePlugin } from '@udecode/plate-select';\nimport {\n BlockMenuPlugin,\n BlockSelectionPlugin,\n} from '@udecode/plate-selection/react';\nimport { SlashPlugin } from '@udecode/plate-slash-command/react';\nimport { TablePlugin } from '@udecode/plate-table/react';\nimport { TogglePlugin } from '@udecode/plate-toggle/react';\nimport { TrailingBlockPlugin } from '@udecode/plate-trailing-block';\nimport Prism from 'prismjs';\n\nimport { CheckPlugin } from '@/components/context/check-plugin';\nimport { settingsStore } from '@/components/context/settings-store';\nimport { aiPlugins } from '@/lib/plate/demo/plugins/ai-plugins';\nimport { getAutoformatOptions } from '@/lib/plate/demo/plugins/autoformatOptions';\nimport { copilotPlugins } from '@/lib/plate/demo/plugins/copilot-plugins';\nimport { createPlateUI } from '@/plate/create-plate-ui';\nimport { editableProps } from '@/plate/demo/editableProps';\nimport { isEnabled } from '@/plate/demo/is-enabled';\nimport { DragOverCursorPlugin } from '@/plate/demo/plugins/DragOverCursorPlugin';\nimport { exitBreakPlugin } from '@/plate/demo/plugins/exitBreakPlugin';\nimport { resetBlockTypePlugin } from '@/plate/demo/plugins/resetBlockTypePlugin';\nimport { softBreakPlugin } from '@/plate/demo/plugins/softBreakPlugin';\nimport { tabbablePlugin } from '@/plate/demo/plugins/tabbablePlugin';\nimport { commentsData, usersData } from '@/plate/demo/values/commentsValue';\nimport { usePlaygroundValue } from '@/plate/demo/values/usePlaygroundValue';\nimport { BlockContextMenu } from '@/components/plate-ui/block-context-menu';\nimport { CommentsPopover } from '@/components/plate-ui/comments-popover';\nimport {\n CursorOverlay,\n SelectionOverlayPlugin,\n} from '@/components/plate-ui/cursor-overlay';\nimport { Editor, EditorContainer } from '@/components/plate-ui/editor';\nimport { FixedToolbar } from '@/components/plate-ui/fixed-toolbar';\nimport { FixedToolbarButtons } from '@/components/plate-ui/fixed-toolbar-buttons';\nimport { FloatingToolbar } from '@/components/plate-ui/floating-toolbar';\nimport { FloatingToolbarButtons } from '@/components/plate-ui/floating-toolbar-buttons';\nimport { ImagePreview } from '@/components/plate-ui/image-preview';\nimport {\n FireLiComponent,\n FireMarker,\n} from '@/components/plate-ui/indent-fire-marker';\nimport {\n TodoLi,\n TodoMarker,\n} from '@/components/plate-ui/indent-todo-marker';\nimport { LinkFloatingToolbar } from '@/components/plate-ui/link-floating-toolbar';\n\nimport { usePlaygroundEnabled } from './usePlaygroundEnabled';\n\nexport const usePlaygroundEditor = (id: any = '', scrollSelector?: string) => {\n const enabledPlugins = settingsStore.use.checkedPlugins();\n const overridePlugins = usePlaygroundEnabled(id);\n const autoformatOptions = getAutoformatOptions(id, enabledPlugins);\n\n const value = usePlaygroundValue(id);\n const key = settingsStore.use.version();\n const editorId = id || 'playground-' + key;\n\n return usePlateEditor(\n {\n id: editorId,\n override: {\n components: createPlateUI({\n draggable: isEnabled('dnd', id),\n placeholder: isEnabled('placeholder', id),\n }),\n plugins: overridePlugins,\n },\n plugins: [\n // AI\n ...(id === 'ai' || enabledPlugins[AIChatPlugin.key] ? aiPlugins : []),\n ...(id === 'copilot' || enabledPlugins[CopilotPlugin.key]\n ? copilotPlugins\n : []),\n // Nodes\n HeadingPlugin,\n TocPlugin.configure({\n options: {\n scrollContainerSelector: `#${scrollSelector}`,\n topOffset: 80,\n },\n }),\n BlockquotePlugin,\n CodeBlockPlugin.configure({\n options: {\n prism: Prism,\n },\n }),\n HorizontalRulePlugin,\n LinkPlugin.extend({\n render: { afterEditable: () => },\n }),\n ...(id === 'list' ? [ListPlugin] : []),\n ImagePlugin.extend({\n options: {\n disableUploadInsert: true,\n },\n render: { afterEditable: ImagePreview },\n }),\n MediaEmbedPlugin,\n CaptionPlugin.configure({\n options: {\n plugins: [ImagePlugin, MediaEmbedPlugin],\n },\n }),\n DatePlugin,\n MentionPlugin.configure({\n options: {\n triggerPreviousCharPattern: /^$|^[\\s\"']$/,\n },\n }),\n SlashPlugin,\n TablePlugin.configure({\n options: {\n enableMerging: id === 'tableMerge',\n },\n }),\n ColumnPlugin,\n SelectionOverlayPlugin,\n\n TodoListPlugin,\n TogglePlugin,\n ExcalidrawPlugin,\n // Marks\n BoldPlugin,\n ItalicPlugin,\n UnderlinePlugin,\n StrikethroughPlugin,\n CodePlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n FontColorPlugin,\n FontBackgroundColorPlugin,\n FontSizePlugin,\n HighlightPlugin,\n KbdPlugin,\n\n // Block Style\n AlignPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n MediaEmbedPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n ImagePlugin.key,\n HEADING_KEYS.h6,\n ],\n },\n }),\n IndentPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n }),\n IndentListPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n options: {\n listStyleTypes: {\n fire: {\n liComponent: FireLiComponent,\n markerComponent: FireMarker,\n type: 'fire',\n },\n todo: {\n liComponent: TodoLi,\n markerComponent: TodoMarker,\n type: 'todo',\n },\n },\n },\n }),\n LineHeightPlugin.extend({\n inject: {\n nodeProps: {\n defaultNodeValue: 1.5,\n validNodeValues: [1, 1.2, 1.5, 2, 3],\n },\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n ],\n },\n }),\n\n // Functionality\n AutoformatPlugin.configure({\n options: autoformatOptions,\n }),\n BlockSelectionPlugin.configure({\n options: {\n areaOptions: {\n behaviour: {\n scrolling: {\n speedDivider: 1.5,\n },\n startThreshold: 10,\n },\n boundaries: `#${scrollSelector}`,\n container: `#${scrollSelector}`,\n selectables: [`#${scrollSelector} .slate-selectable`],\n selectionAreaClass: 'slate-selection-area',\n },\n enableContextMenu: true,\n },\n }),\n BlockMenuPlugin.configure({\n render: { aboveEditable: BlockContextMenu },\n }),\n DndPlugin.configure({\n options: {\n enableScroller: true,\n onDropFiles: ({ dragItem, editor, target }) => {\n editor\n .getTransforms(ImagePlugin)\n .insertImageFromFiles(dragItem.files, {\n at: target,\n nextBlock: false,\n });\n },\n },\n }),\n EmojiPlugin,\n exitBreakPlugin,\n NodeIdPlugin,\n NormalizeTypesPlugin.configure({\n options: {\n rules: [{ path: [0], strictType: HEADING_KEYS.h1 }],\n },\n }),\n resetBlockTypePlugin,\n SelectOnBackspacePlugin.configure({\n options: {\n query: {\n allow: [ImagePlugin.key, HorizontalRulePlugin.key],\n },\n },\n }),\n DeletePlugin,\n SingleLinePlugin,\n softBreakPlugin,\n tabbablePlugin,\n TrailingBlockPlugin.configure({\n options: { type: ParagraphPlugin.key },\n }),\n DragOverCursorPlugin,\n\n // Collaboration\n CommentsPlugin.configure({\n options: {\n comments: commentsData,\n myUserId: '1',\n users: usersData,\n },\n }),\n\n // Deserialization\n DocxPlugin,\n MarkdownPlugin.configure({ options: { indentList: true } }),\n JuicePlugin,\n\n // Testing\n PlaywrightPlugin.configure({\n enabled: process.env.NODE_ENV !== 'production',\n }),\n ],\n value: value,\n },\n []\n );\n};\n\nexport default function PlaygroundDemo({\n id,\n className,\n scrollSelector,\n}: {\n id?: ValueId;\n className?: string;\n scrollSelector?: string;\n}) {\n const containerRef = useRef(null);\n const enabled = settingsStore.use.checkedComponents();\n\n const editor = usePlaygroundEditor(\n id,\n scrollSelector ?? `blockSelection-${id}`\n );\n\n return (\n \n \n \n \n \n \n \n \n \n\n
\n \n \n\n \n \n \n \n \n \n \n\n \n \n \n \n\n \n \n \n
\n
\n
\n );\n}\n\nconst DemoIdContext = React.createContext(undefined);\n\nexport function DemoId({\n id,\n children,\n}: {\n children: React.ReactNode;\n id?: string;\n}) {\n return {children};\n}\n\nexport function useDemoId() {\n return React.useContext(DemoIdContext);\n}\n", + "content": "'use client';\n\nimport React, { useRef } from 'react';\n\nimport type { ValueId } from '@/config/customizer-plugins';\n\nimport { cn } from '@udecode/cn';\nimport { AIChatPlugin, CopilotPlugin } from '@udecode/plate-ai/react';\nimport { AlignPlugin } from '@udecode/plate-alignment/react';\nimport { AutoformatPlugin } from '@udecode/plate-autoformat/react';\nimport {\n BoldPlugin,\n CodePlugin,\n ItalicPlugin,\n StrikethroughPlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n UnderlinePlugin,\n} from '@udecode/plate-basic-marks/react';\nimport { BlockquotePlugin } from '@udecode/plate-block-quote/react';\nimport { SingleLinePlugin } from '@udecode/plate-break/react';\nimport { CaptionPlugin } from '@udecode/plate-caption/react';\nimport { CodeBlockPlugin } from '@udecode/plate-code-block/react';\nimport { CommentsPlugin } from '@udecode/plate-comments/react';\nimport {\n ParagraphPlugin,\n Plate,\n usePlateEditor,\n} from '@udecode/plate-common/react';\nimport { DatePlugin } from '@udecode/plate-date/react';\nimport { DndPlugin } from '@udecode/plate-dnd';\nimport { DocxPlugin } from '@udecode/plate-docx';\nimport { EmojiPlugin } from '@udecode/plate-emoji/react';\nimport { ExcalidrawPlugin } from '@udecode/plate-excalidraw/react';\nimport {\n FontBackgroundColorPlugin,\n FontColorPlugin,\n FontSizePlugin,\n} from '@udecode/plate-font/react';\nimport { HEADING_KEYS } from '@udecode/plate-heading';\nimport { HeadingPlugin, TocPlugin } from '@udecode/plate-heading/react';\nimport { HighlightPlugin } from '@udecode/plate-highlight/react';\nimport { HorizontalRulePlugin } from '@udecode/plate-horizontal-rule/react';\nimport { IndentPlugin } from '@udecode/plate-indent/react';\nimport { IndentListPlugin } from '@udecode/plate-indent-list/react';\nimport { JuicePlugin } from '@udecode/plate-juice';\nimport { KbdPlugin } from '@udecode/plate-kbd/react';\nimport { ColumnPlugin } from '@udecode/plate-layout/react';\nimport { LineHeightPlugin } from '@udecode/plate-line-height/react';\nimport { LinkPlugin } from '@udecode/plate-link/react';\nimport { ListPlugin, TodoListPlugin } from '@udecode/plate-list/react';\nimport { MarkdownPlugin } from '@udecode/plate-markdown';\nimport { BaseImagePlugin } from '@udecode/plate-media';\nimport { ImagePlugin, MediaEmbedPlugin } from '@udecode/plate-media/react';\nimport { MentionPlugin } from '@udecode/plate-mention/react';\nimport { NodeIdPlugin } from '@udecode/plate-node-id';\nimport { NormalizeTypesPlugin } from '@udecode/plate-normalizers';\nimport { PlaywrightPlugin } from '@udecode/plate-playwright';\nimport { DeletePlugin, SelectOnBackspacePlugin } from '@udecode/plate-select';\nimport {\n BlockMenuPlugin,\n BlockSelectionPlugin,\n} from '@udecode/plate-selection/react';\nimport { SlashPlugin } from '@udecode/plate-slash-command/react';\nimport { TablePlugin } from '@udecode/plate-table/react';\nimport { TogglePlugin } from '@udecode/plate-toggle/react';\nimport { TrailingBlockPlugin } from '@udecode/plate-trailing-block';\nimport Prism from 'prismjs';\n\nimport { CheckPlugin } from '@/components/context/check-plugin';\nimport { settingsStore } from '@/components/context/settings-store';\nimport { aiPlugins } from '@/lib/plate/demo/plugins/ai-plugins';\nimport { getAutoformatOptions } from '@/lib/plate/demo/plugins/autoformatOptions';\nimport { copilotPlugins } from '@/lib/plate/demo/plugins/copilot-plugins';\nimport { createPlateUI } from '@/plate/create-plate-ui';\nimport { editableProps } from '@/plate/demo/editableProps';\nimport { isEnabled } from '@/plate/demo/is-enabled';\nimport { DragOverCursorPlugin } from '@/plate/demo/plugins/DragOverCursorPlugin';\nimport { exitBreakPlugin } from '@/plate/demo/plugins/exitBreakPlugin';\nimport { resetBlockTypePlugin } from '@/plate/demo/plugins/resetBlockTypePlugin';\nimport { softBreakPlugin } from '@/plate/demo/plugins/softBreakPlugin';\nimport { tabbablePlugin } from '@/plate/demo/plugins/tabbablePlugin';\nimport { commentsData, usersData } from '@/plate/demo/values/commentsValue';\nimport { usePlaygroundValue } from '@/plate/demo/values/usePlaygroundValue';\nimport { BlockContextMenu } from '@/components/plate-ui/block-context-menu';\nimport { CommentsPopover } from '@/components/plate-ui/comments-popover';\nimport {\n CursorOverlay,\n SelectionOverlayPlugin,\n} from '@/components/plate-ui/cursor-overlay';\nimport { Editor, EditorContainer } from '@/components/plate-ui/editor';\nimport { FixedToolbar } from '@/components/plate-ui/fixed-toolbar';\nimport { FixedToolbarButtons } from '@/components/plate-ui/fixed-toolbar-buttons';\nimport { FloatingToolbar } from '@/components/plate-ui/floating-toolbar';\nimport { FloatingToolbarButtons } from '@/components/plate-ui/floating-toolbar-buttons';\nimport { ImagePreview } from '@/components/plate-ui/image-preview';\nimport {\n FireLiComponent,\n FireMarker,\n} from '@/components/plate-ui/indent-fire-marker';\nimport {\n TodoLi,\n TodoMarker,\n} from '@/components/plate-ui/indent-todo-marker';\nimport { LinkFloatingToolbar } from '@/components/plate-ui/link-floating-toolbar';\n\nimport { usePlaygroundEnabled } from './usePlaygroundEnabled';\n\nexport const usePlaygroundEditor = (id: any = '', scrollSelector?: string) => {\n const enabledPlugins = settingsStore.use.checkedPlugins();\n const overridePlugins = usePlaygroundEnabled(id);\n const autoformatOptions = getAutoformatOptions(id, enabledPlugins);\n\n const value = usePlaygroundValue(id);\n const key = settingsStore.use.version();\n const editorId = id || 'playground-' + key;\n\n return usePlateEditor(\n {\n id: editorId,\n override: {\n components: createPlateUI({\n draggable: isEnabled('dnd', id),\n placeholder: isEnabled('placeholder', id),\n }),\n plugins: overridePlugins,\n },\n plugins: [\n // AI\n ...(id === 'ai' || enabledPlugins[AIChatPlugin.key] ? aiPlugins : []),\n ...(id === 'copilot' || enabledPlugins[CopilotPlugin.key]\n ? copilotPlugins\n : []),\n // Nodes\n HeadingPlugin,\n TocPlugin.configure({\n options: {\n scrollContainerSelector: `#${scrollSelector}`,\n topOffset: 80,\n },\n }),\n BlockquotePlugin,\n CodeBlockPlugin.configure({\n options: {\n prism: Prism,\n },\n }),\n HorizontalRulePlugin,\n LinkPlugin.extend({\n render: { afterEditable: () => },\n }),\n ...(id === 'list' ? [ListPlugin] : []),\n ImagePlugin.extend({\n options: {\n disableUploadInsert: true,\n },\n render: { afterEditable: ImagePreview },\n }),\n MediaEmbedPlugin,\n CaptionPlugin.configure({\n options: {\n plugins: [ImagePlugin, MediaEmbedPlugin],\n },\n }),\n DatePlugin,\n MentionPlugin.configure({\n options: {\n triggerPreviousCharPattern: /^$|^[\\s\"']$/,\n },\n }),\n SlashPlugin,\n TablePlugin.configure({\n options: {\n enableMerging: id === 'tableMerge',\n },\n }),\n ColumnPlugin,\n SelectionOverlayPlugin,\n\n TodoListPlugin,\n TogglePlugin,\n ExcalidrawPlugin,\n // Marks\n BoldPlugin,\n ItalicPlugin,\n UnderlinePlugin,\n StrikethroughPlugin,\n CodePlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n FontColorPlugin,\n FontBackgroundColorPlugin,\n FontSizePlugin,\n HighlightPlugin,\n KbdPlugin,\n\n // Block Style\n AlignPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n MediaEmbedPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n ImagePlugin.key,\n HEADING_KEYS.h6,\n ],\n },\n }),\n IndentPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n }),\n IndentListPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n options: {\n listStyleTypes: {\n fire: {\n liComponent: FireLiComponent,\n markerComponent: FireMarker,\n type: 'fire',\n },\n todo: {\n liComponent: TodoLi,\n markerComponent: TodoMarker,\n type: 'todo',\n },\n },\n },\n }),\n LineHeightPlugin.extend({\n inject: {\n nodeProps: {\n defaultNodeValue: 1.5,\n validNodeValues: [1, 1.2, 1.5, 2, 3],\n },\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n ],\n },\n }),\n\n // Functionality\n AutoformatPlugin.configure({\n options: autoformatOptions,\n }),\n BlockSelectionPlugin.configure({\n options: {\n areaOptions: {\n behaviour: {\n scrolling: {\n speedDivider: 1.5,\n },\n startThreshold: 10,\n },\n boundaries: `#${scrollSelector}`,\n container: `#${scrollSelector}`,\n selectables: [`#${scrollSelector} .slate-selectable`],\n selectionAreaClass: 'slate-selection-area',\n },\n enableContextMenu: true,\n },\n }),\n BlockMenuPlugin.configure({\n render: { aboveEditable: BlockContextMenu },\n }),\n DndPlugin.configure({\n options: {\n enableScroller: true,\n onDropFiles: ({ dragItem, editor, target }) => {\n editor\n .getTransforms(BaseImagePlugin)\n .insert.imageFromFiles(dragItem.files, {\n at: target,\n nextBlock: false,\n });\n },\n },\n }),\n EmojiPlugin,\n exitBreakPlugin,\n NodeIdPlugin,\n NormalizeTypesPlugin.configure({\n options: {\n rules: [{ path: [0], strictType: HEADING_KEYS.h1 }],\n },\n }),\n resetBlockTypePlugin,\n SelectOnBackspacePlugin.configure({\n options: {\n query: {\n allow: [ImagePlugin.key, HorizontalRulePlugin.key],\n },\n },\n }),\n DeletePlugin,\n SingleLinePlugin,\n softBreakPlugin,\n tabbablePlugin,\n TrailingBlockPlugin.configure({\n options: { type: ParagraphPlugin.key },\n }),\n DragOverCursorPlugin,\n\n // Collaboration\n CommentsPlugin.configure({\n options: {\n comments: commentsData,\n myUserId: '1',\n users: usersData,\n },\n }),\n\n // Deserialization\n DocxPlugin,\n MarkdownPlugin.configure({ options: { indentList: true } }),\n JuicePlugin,\n\n // Testing\n PlaywrightPlugin.configure({\n enabled: process.env.NODE_ENV !== 'production',\n }),\n ],\n value: value,\n },\n []\n );\n};\n\nexport default function PlaygroundDemo({\n id,\n className,\n scrollSelector,\n}: {\n id?: ValueId;\n className?: string;\n scrollSelector?: string;\n}) {\n const containerRef = useRef(null);\n const enabled = settingsStore.use.checkedComponents();\n\n const editor = usePlaygroundEditor(\n id,\n scrollSelector ?? `blockSelection-${id}`\n );\n\n return (\n \n \n \n \n \n \n \n \n \n\n
\n \n \n\n \n \n \n \n \n \n \n\n \n \n \n \n\n \n \n \n
\n
\n
\n );\n}\n\nconst DemoIdContext = React.createContext(undefined);\n\nexport function DemoId({\n id,\n children,\n}: {\n children: React.ReactNode;\n id?: string;\n}) {\n return {children};\n}\n\nexport function useDemoId() {\n return React.useContext(DemoIdContext);\n}\n", "path": "example/playground-demo.tsx", "target": "components/playground-demo.tsx", "type": "registry:example" diff --git a/apps/www/public/r/styles/default/toggle-demo.json b/apps/www/public/r/styles/default/toggle-demo.json index 30c8528c65..8e804bef8e 100644 --- a/apps/www/public/r/styles/default/toggle-demo.json +++ b/apps/www/public/r/styles/default/toggle-demo.json @@ -4,7 +4,7 @@ }, "files": [ { - "content": "'use client';\n\nimport React, { useRef } from 'react';\n\nimport type { ValueId } from '@/config/customizer-plugins';\n\nimport { cn } from '@udecode/cn';\nimport { AIChatPlugin, CopilotPlugin } from '@udecode/plate-ai/react';\nimport { AlignPlugin } from '@udecode/plate-alignment/react';\nimport { AutoformatPlugin } from '@udecode/plate-autoformat/react';\nimport {\n BoldPlugin,\n CodePlugin,\n ItalicPlugin,\n StrikethroughPlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n UnderlinePlugin,\n} from '@udecode/plate-basic-marks/react';\nimport { BlockquotePlugin } from '@udecode/plate-block-quote/react';\nimport { SingleLinePlugin } from '@udecode/plate-break/react';\nimport { CaptionPlugin } from '@udecode/plate-caption/react';\nimport { CodeBlockPlugin } from '@udecode/plate-code-block/react';\nimport { CommentsPlugin } from '@udecode/plate-comments/react';\nimport {\n ParagraphPlugin,\n Plate,\n usePlateEditor,\n} from '@udecode/plate-common/react';\nimport { DatePlugin } from '@udecode/plate-date/react';\nimport { DndPlugin } from '@udecode/plate-dnd';\nimport { DocxPlugin } from '@udecode/plate-docx';\nimport { EmojiPlugin } from '@udecode/plate-emoji/react';\nimport { ExcalidrawPlugin } from '@udecode/plate-excalidraw/react';\nimport {\n FontBackgroundColorPlugin,\n FontColorPlugin,\n FontSizePlugin,\n} from '@udecode/plate-font/react';\nimport { HEADING_KEYS } from '@udecode/plate-heading';\nimport { HeadingPlugin, TocPlugin } from '@udecode/plate-heading/react';\nimport { HighlightPlugin } from '@udecode/plate-highlight/react';\nimport { HorizontalRulePlugin } from '@udecode/plate-horizontal-rule/react';\nimport { IndentPlugin } from '@udecode/plate-indent/react';\nimport { IndentListPlugin } from '@udecode/plate-indent-list/react';\nimport { JuicePlugin } from '@udecode/plate-juice';\nimport { KbdPlugin } from '@udecode/plate-kbd/react';\nimport { ColumnPlugin } from '@udecode/plate-layout/react';\nimport { LineHeightPlugin } from '@udecode/plate-line-height/react';\nimport { LinkPlugin } from '@udecode/plate-link/react';\nimport { ListPlugin, TodoListPlugin } from '@udecode/plate-list/react';\nimport { MarkdownPlugin } from '@udecode/plate-markdown';\nimport { ImagePlugin, MediaEmbedPlugin } from '@udecode/plate-media/react';\nimport { MentionPlugin } from '@udecode/plate-mention/react';\nimport { NodeIdPlugin } from '@udecode/plate-node-id';\nimport { NormalizeTypesPlugin } from '@udecode/plate-normalizers';\nimport { PlaywrightPlugin } from '@udecode/plate-playwright';\nimport { DeletePlugin, SelectOnBackspacePlugin } from '@udecode/plate-select';\nimport {\n BlockMenuPlugin,\n BlockSelectionPlugin,\n} from '@udecode/plate-selection/react';\nimport { SlashPlugin } from '@udecode/plate-slash-command/react';\nimport { TablePlugin } from '@udecode/plate-table/react';\nimport { TogglePlugin } from '@udecode/plate-toggle/react';\nimport { TrailingBlockPlugin } from '@udecode/plate-trailing-block';\nimport Prism from 'prismjs';\n\nimport { CheckPlugin } from '@/components/context/check-plugin';\nimport { settingsStore } from '@/components/context/settings-store';\nimport { aiPlugins } from '@/lib/plate/demo/plugins/ai-plugins';\nimport { getAutoformatOptions } from '@/lib/plate/demo/plugins/autoformatOptions';\nimport { copilotPlugins } from '@/lib/plate/demo/plugins/copilot-plugins';\nimport { createPlateUI } from '@/plate/create-plate-ui';\nimport { editableProps } from '@/plate/demo/editableProps';\nimport { isEnabled } from '@/plate/demo/is-enabled';\nimport { DragOverCursorPlugin } from '@/plate/demo/plugins/DragOverCursorPlugin';\nimport { exitBreakPlugin } from '@/plate/demo/plugins/exitBreakPlugin';\nimport { resetBlockTypePlugin } from '@/plate/demo/plugins/resetBlockTypePlugin';\nimport { softBreakPlugin } from '@/plate/demo/plugins/softBreakPlugin';\nimport { tabbablePlugin } from '@/plate/demo/plugins/tabbablePlugin';\nimport { commentsData, usersData } from '@/plate/demo/values/commentsValue';\nimport { usePlaygroundValue } from '@/plate/demo/values/usePlaygroundValue';\nimport { BlockContextMenu } from '@/components/plate-ui/block-context-menu';\nimport { CommentsPopover } from '@/components/plate-ui/comments-popover';\nimport {\n CursorOverlay,\n SelectionOverlayPlugin,\n} from '@/components/plate-ui/cursor-overlay';\nimport { Editor, EditorContainer } from '@/components/plate-ui/editor';\nimport { FixedToolbar } from '@/components/plate-ui/fixed-toolbar';\nimport { FixedToolbarButtons } from '@/components/plate-ui/fixed-toolbar-buttons';\nimport { FloatingToolbar } from '@/components/plate-ui/floating-toolbar';\nimport { FloatingToolbarButtons } from '@/components/plate-ui/floating-toolbar-buttons';\nimport { ImagePreview } from '@/components/plate-ui/image-preview';\nimport {\n FireLiComponent,\n FireMarker,\n} from '@/components/plate-ui/indent-fire-marker';\nimport {\n TodoLi,\n TodoMarker,\n} from '@/components/plate-ui/indent-todo-marker';\nimport { LinkFloatingToolbar } from '@/components/plate-ui/link-floating-toolbar';\n\nimport { usePlaygroundEnabled } from './usePlaygroundEnabled';\n\nexport const usePlaygroundEditor = (id: any = '', scrollSelector?: string) => {\n const enabledPlugins = settingsStore.use.checkedPlugins();\n const overridePlugins = usePlaygroundEnabled(id);\n const autoformatOptions = getAutoformatOptions(id, enabledPlugins);\n\n const value = usePlaygroundValue(id);\n const key = settingsStore.use.version();\n const editorId = id || 'playground-' + key;\n\n return usePlateEditor(\n {\n id: editorId,\n override: {\n components: createPlateUI({\n draggable: isEnabled('dnd', id),\n placeholder: isEnabled('placeholder', id),\n }),\n plugins: overridePlugins,\n },\n plugins: [\n // AI\n ...(id === 'ai' || enabledPlugins[AIChatPlugin.key] ? aiPlugins : []),\n ...(id === 'copilot' || enabledPlugins[CopilotPlugin.key]\n ? copilotPlugins\n : []),\n // Nodes\n HeadingPlugin,\n TocPlugin.configure({\n options: {\n scrollContainerSelector: `#${scrollSelector}`,\n topOffset: 80,\n },\n }),\n BlockquotePlugin,\n CodeBlockPlugin.configure({\n options: {\n prism: Prism,\n },\n }),\n HorizontalRulePlugin,\n LinkPlugin.extend({\n render: { afterEditable: () => },\n }),\n ...(id === 'list' ? [ListPlugin] : []),\n ImagePlugin.extend({\n options: {\n disableUploadInsert: true,\n },\n render: { afterEditable: ImagePreview },\n }),\n MediaEmbedPlugin,\n CaptionPlugin.configure({\n options: {\n plugins: [ImagePlugin, MediaEmbedPlugin],\n },\n }),\n DatePlugin,\n MentionPlugin.configure({\n options: {\n triggerPreviousCharPattern: /^$|^[\\s\"']$/,\n },\n }),\n SlashPlugin,\n TablePlugin.configure({\n options: {\n enableMerging: id === 'tableMerge',\n },\n }),\n ColumnPlugin,\n SelectionOverlayPlugin,\n\n TodoListPlugin,\n TogglePlugin,\n ExcalidrawPlugin,\n // Marks\n BoldPlugin,\n ItalicPlugin,\n UnderlinePlugin,\n StrikethroughPlugin,\n CodePlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n FontColorPlugin,\n FontBackgroundColorPlugin,\n FontSizePlugin,\n HighlightPlugin,\n KbdPlugin,\n\n // Block Style\n AlignPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n MediaEmbedPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n ImagePlugin.key,\n HEADING_KEYS.h6,\n ],\n },\n }),\n IndentPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n }),\n IndentListPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n options: {\n listStyleTypes: {\n fire: {\n liComponent: FireLiComponent,\n markerComponent: FireMarker,\n type: 'fire',\n },\n todo: {\n liComponent: TodoLi,\n markerComponent: TodoMarker,\n type: 'todo',\n },\n },\n },\n }),\n LineHeightPlugin.extend({\n inject: {\n nodeProps: {\n defaultNodeValue: 1.5,\n validNodeValues: [1, 1.2, 1.5, 2, 3],\n },\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n ],\n },\n }),\n\n // Functionality\n AutoformatPlugin.configure({\n options: autoformatOptions,\n }),\n BlockSelectionPlugin.configure({\n options: {\n areaOptions: {\n behaviour: {\n scrolling: {\n speedDivider: 1.5,\n },\n startThreshold: 10,\n },\n boundaries: `#${scrollSelector}`,\n container: `#${scrollSelector}`,\n selectables: [`#${scrollSelector} .slate-selectable`],\n selectionAreaClass: 'slate-selection-area',\n },\n enableContextMenu: true,\n },\n }),\n BlockMenuPlugin.configure({\n render: { aboveEditable: BlockContextMenu },\n }),\n DndPlugin.configure({\n options: {\n enableScroller: true,\n onDropFiles: ({ dragItem, editor, target }) => {\n editor\n .getTransforms(ImagePlugin)\n .insertImageFromFiles(dragItem.files, {\n at: target,\n nextBlock: false,\n });\n },\n },\n }),\n EmojiPlugin,\n exitBreakPlugin,\n NodeIdPlugin,\n NormalizeTypesPlugin.configure({\n options: {\n rules: [{ path: [0], strictType: HEADING_KEYS.h1 }],\n },\n }),\n resetBlockTypePlugin,\n SelectOnBackspacePlugin.configure({\n options: {\n query: {\n allow: [ImagePlugin.key, HorizontalRulePlugin.key],\n },\n },\n }),\n DeletePlugin,\n SingleLinePlugin,\n softBreakPlugin,\n tabbablePlugin,\n TrailingBlockPlugin.configure({\n options: { type: ParagraphPlugin.key },\n }),\n DragOverCursorPlugin,\n\n // Collaboration\n CommentsPlugin.configure({\n options: {\n comments: commentsData,\n myUserId: '1',\n users: usersData,\n },\n }),\n\n // Deserialization\n DocxPlugin,\n MarkdownPlugin.configure({ options: { indentList: true } }),\n JuicePlugin,\n\n // Testing\n PlaywrightPlugin.configure({\n enabled: process.env.NODE_ENV !== 'production',\n }),\n ],\n value: value,\n },\n []\n );\n};\n\nexport default function PlaygroundDemo({\n id,\n className,\n scrollSelector,\n}: {\n id?: ValueId;\n className?: string;\n scrollSelector?: string;\n}) {\n const containerRef = useRef(null);\n const enabled = settingsStore.use.checkedComponents();\n\n const editor = usePlaygroundEditor(\n id,\n scrollSelector ?? `blockSelection-${id}`\n );\n\n return (\n \n \n \n \n \n \n \n \n \n\n
\n \n \n\n \n \n \n \n \n \n \n\n \n \n \n \n\n \n \n \n
\n
\n
\n );\n}\n\nconst DemoIdContext = React.createContext(undefined);\n\nexport function DemoId({\n id,\n children,\n}: {\n children: React.ReactNode;\n id?: string;\n}) {\n return {children};\n}\n\nexport function useDemoId() {\n return React.useContext(DemoIdContext);\n}\n", + "content": "'use client';\n\nimport React, { useRef } from 'react';\n\nimport type { ValueId } from '@/config/customizer-plugins';\n\nimport { cn } from '@udecode/cn';\nimport { AIChatPlugin, CopilotPlugin } from '@udecode/plate-ai/react';\nimport { AlignPlugin } from '@udecode/plate-alignment/react';\nimport { AutoformatPlugin } from '@udecode/plate-autoformat/react';\nimport {\n BoldPlugin,\n CodePlugin,\n ItalicPlugin,\n StrikethroughPlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n UnderlinePlugin,\n} from '@udecode/plate-basic-marks/react';\nimport { BlockquotePlugin } from '@udecode/plate-block-quote/react';\nimport { SingleLinePlugin } from '@udecode/plate-break/react';\nimport { CaptionPlugin } from '@udecode/plate-caption/react';\nimport { CodeBlockPlugin } from '@udecode/plate-code-block/react';\nimport { CommentsPlugin } from '@udecode/plate-comments/react';\nimport {\n ParagraphPlugin,\n Plate,\n usePlateEditor,\n} from '@udecode/plate-common/react';\nimport { DatePlugin } from '@udecode/plate-date/react';\nimport { DndPlugin } from '@udecode/plate-dnd';\nimport { DocxPlugin } from '@udecode/plate-docx';\nimport { EmojiPlugin } from '@udecode/plate-emoji/react';\nimport { ExcalidrawPlugin } from '@udecode/plate-excalidraw/react';\nimport {\n FontBackgroundColorPlugin,\n FontColorPlugin,\n FontSizePlugin,\n} from '@udecode/plate-font/react';\nimport { HEADING_KEYS } from '@udecode/plate-heading';\nimport { HeadingPlugin, TocPlugin } from '@udecode/plate-heading/react';\nimport { HighlightPlugin } from '@udecode/plate-highlight/react';\nimport { HorizontalRulePlugin } from '@udecode/plate-horizontal-rule/react';\nimport { IndentPlugin } from '@udecode/plate-indent/react';\nimport { IndentListPlugin } from '@udecode/plate-indent-list/react';\nimport { JuicePlugin } from '@udecode/plate-juice';\nimport { KbdPlugin } from '@udecode/plate-kbd/react';\nimport { ColumnPlugin } from '@udecode/plate-layout/react';\nimport { LineHeightPlugin } from '@udecode/plate-line-height/react';\nimport { LinkPlugin } from '@udecode/plate-link/react';\nimport { ListPlugin, TodoListPlugin } from '@udecode/plate-list/react';\nimport { MarkdownPlugin } from '@udecode/plate-markdown';\nimport { BaseImagePlugin } from '@udecode/plate-media';\nimport { ImagePlugin, MediaEmbedPlugin } from '@udecode/plate-media/react';\nimport { MentionPlugin } from '@udecode/plate-mention/react';\nimport { NodeIdPlugin } from '@udecode/plate-node-id';\nimport { NormalizeTypesPlugin } from '@udecode/plate-normalizers';\nimport { PlaywrightPlugin } from '@udecode/plate-playwright';\nimport { DeletePlugin, SelectOnBackspacePlugin } from '@udecode/plate-select';\nimport {\n BlockMenuPlugin,\n BlockSelectionPlugin,\n} from '@udecode/plate-selection/react';\nimport { SlashPlugin } from '@udecode/plate-slash-command/react';\nimport { TablePlugin } from '@udecode/plate-table/react';\nimport { TogglePlugin } from '@udecode/plate-toggle/react';\nimport { TrailingBlockPlugin } from '@udecode/plate-trailing-block';\nimport Prism from 'prismjs';\n\nimport { CheckPlugin } from '@/components/context/check-plugin';\nimport { settingsStore } from '@/components/context/settings-store';\nimport { aiPlugins } from '@/lib/plate/demo/plugins/ai-plugins';\nimport { getAutoformatOptions } from '@/lib/plate/demo/plugins/autoformatOptions';\nimport { copilotPlugins } from '@/lib/plate/demo/plugins/copilot-plugins';\nimport { createPlateUI } from '@/plate/create-plate-ui';\nimport { editableProps } from '@/plate/demo/editableProps';\nimport { isEnabled } from '@/plate/demo/is-enabled';\nimport { DragOverCursorPlugin } from '@/plate/demo/plugins/DragOverCursorPlugin';\nimport { exitBreakPlugin } from '@/plate/demo/plugins/exitBreakPlugin';\nimport { resetBlockTypePlugin } from '@/plate/demo/plugins/resetBlockTypePlugin';\nimport { softBreakPlugin } from '@/plate/demo/plugins/softBreakPlugin';\nimport { tabbablePlugin } from '@/plate/demo/plugins/tabbablePlugin';\nimport { commentsData, usersData } from '@/plate/demo/values/commentsValue';\nimport { usePlaygroundValue } from '@/plate/demo/values/usePlaygroundValue';\nimport { BlockContextMenu } from '@/components/plate-ui/block-context-menu';\nimport { CommentsPopover } from '@/components/plate-ui/comments-popover';\nimport {\n CursorOverlay,\n SelectionOverlayPlugin,\n} from '@/components/plate-ui/cursor-overlay';\nimport { Editor, EditorContainer } from '@/components/plate-ui/editor';\nimport { FixedToolbar } from '@/components/plate-ui/fixed-toolbar';\nimport { FixedToolbarButtons } from '@/components/plate-ui/fixed-toolbar-buttons';\nimport { FloatingToolbar } from '@/components/plate-ui/floating-toolbar';\nimport { FloatingToolbarButtons } from '@/components/plate-ui/floating-toolbar-buttons';\nimport { ImagePreview } from '@/components/plate-ui/image-preview';\nimport {\n FireLiComponent,\n FireMarker,\n} from '@/components/plate-ui/indent-fire-marker';\nimport {\n TodoLi,\n TodoMarker,\n} from '@/components/plate-ui/indent-todo-marker';\nimport { LinkFloatingToolbar } from '@/components/plate-ui/link-floating-toolbar';\n\nimport { usePlaygroundEnabled } from './usePlaygroundEnabled';\n\nexport const usePlaygroundEditor = (id: any = '', scrollSelector?: string) => {\n const enabledPlugins = settingsStore.use.checkedPlugins();\n const overridePlugins = usePlaygroundEnabled(id);\n const autoformatOptions = getAutoformatOptions(id, enabledPlugins);\n\n const value = usePlaygroundValue(id);\n const key = settingsStore.use.version();\n const editorId = id || 'playground-' + key;\n\n return usePlateEditor(\n {\n id: editorId,\n override: {\n components: createPlateUI({\n draggable: isEnabled('dnd', id),\n placeholder: isEnabled('placeholder', id),\n }),\n plugins: overridePlugins,\n },\n plugins: [\n // AI\n ...(id === 'ai' || enabledPlugins[AIChatPlugin.key] ? aiPlugins : []),\n ...(id === 'copilot' || enabledPlugins[CopilotPlugin.key]\n ? copilotPlugins\n : []),\n // Nodes\n HeadingPlugin,\n TocPlugin.configure({\n options: {\n scrollContainerSelector: `#${scrollSelector}`,\n topOffset: 80,\n },\n }),\n BlockquotePlugin,\n CodeBlockPlugin.configure({\n options: {\n prism: Prism,\n },\n }),\n HorizontalRulePlugin,\n LinkPlugin.extend({\n render: { afterEditable: () => },\n }),\n ...(id === 'list' ? [ListPlugin] : []),\n ImagePlugin.extend({\n options: {\n disableUploadInsert: true,\n },\n render: { afterEditable: ImagePreview },\n }),\n MediaEmbedPlugin,\n CaptionPlugin.configure({\n options: {\n plugins: [ImagePlugin, MediaEmbedPlugin],\n },\n }),\n DatePlugin,\n MentionPlugin.configure({\n options: {\n triggerPreviousCharPattern: /^$|^[\\s\"']$/,\n },\n }),\n SlashPlugin,\n TablePlugin.configure({\n options: {\n enableMerging: id === 'tableMerge',\n },\n }),\n ColumnPlugin,\n SelectionOverlayPlugin,\n\n TodoListPlugin,\n TogglePlugin,\n ExcalidrawPlugin,\n // Marks\n BoldPlugin,\n ItalicPlugin,\n UnderlinePlugin,\n StrikethroughPlugin,\n CodePlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n FontColorPlugin,\n FontBackgroundColorPlugin,\n FontSizePlugin,\n HighlightPlugin,\n KbdPlugin,\n\n // Block Style\n AlignPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n MediaEmbedPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n ImagePlugin.key,\n HEADING_KEYS.h6,\n ],\n },\n }),\n IndentPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n }),\n IndentListPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n options: {\n listStyleTypes: {\n fire: {\n liComponent: FireLiComponent,\n markerComponent: FireMarker,\n type: 'fire',\n },\n todo: {\n liComponent: TodoLi,\n markerComponent: TodoMarker,\n type: 'todo',\n },\n },\n },\n }),\n LineHeightPlugin.extend({\n inject: {\n nodeProps: {\n defaultNodeValue: 1.5,\n validNodeValues: [1, 1.2, 1.5, 2, 3],\n },\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n ],\n },\n }),\n\n // Functionality\n AutoformatPlugin.configure({\n options: autoformatOptions,\n }),\n BlockSelectionPlugin.configure({\n options: {\n areaOptions: {\n behaviour: {\n scrolling: {\n speedDivider: 1.5,\n },\n startThreshold: 10,\n },\n boundaries: `#${scrollSelector}`,\n container: `#${scrollSelector}`,\n selectables: [`#${scrollSelector} .slate-selectable`],\n selectionAreaClass: 'slate-selection-area',\n },\n enableContextMenu: true,\n },\n }),\n BlockMenuPlugin.configure({\n render: { aboveEditable: BlockContextMenu },\n }),\n DndPlugin.configure({\n options: {\n enableScroller: true,\n onDropFiles: ({ dragItem, editor, target }) => {\n editor\n .getTransforms(BaseImagePlugin)\n .insert.imageFromFiles(dragItem.files, {\n at: target,\n nextBlock: false,\n });\n },\n },\n }),\n EmojiPlugin,\n exitBreakPlugin,\n NodeIdPlugin,\n NormalizeTypesPlugin.configure({\n options: {\n rules: [{ path: [0], strictType: HEADING_KEYS.h1 }],\n },\n }),\n resetBlockTypePlugin,\n SelectOnBackspacePlugin.configure({\n options: {\n query: {\n allow: [ImagePlugin.key, HorizontalRulePlugin.key],\n },\n },\n }),\n DeletePlugin,\n SingleLinePlugin,\n softBreakPlugin,\n tabbablePlugin,\n TrailingBlockPlugin.configure({\n options: { type: ParagraphPlugin.key },\n }),\n DragOverCursorPlugin,\n\n // Collaboration\n CommentsPlugin.configure({\n options: {\n comments: commentsData,\n myUserId: '1',\n users: usersData,\n },\n }),\n\n // Deserialization\n DocxPlugin,\n MarkdownPlugin.configure({ options: { indentList: true } }),\n JuicePlugin,\n\n // Testing\n PlaywrightPlugin.configure({\n enabled: process.env.NODE_ENV !== 'production',\n }),\n ],\n value: value,\n },\n []\n );\n};\n\nexport default function PlaygroundDemo({\n id,\n className,\n scrollSelector,\n}: {\n id?: ValueId;\n className?: string;\n scrollSelector?: string;\n}) {\n const containerRef = useRef(null);\n const enabled = settingsStore.use.checkedComponents();\n\n const editor = usePlaygroundEditor(\n id,\n scrollSelector ?? `blockSelection-${id}`\n );\n\n return (\n \n \n \n \n \n \n \n \n \n\n
\n \n \n\n \n \n \n \n \n \n \n\n \n \n \n \n\n \n \n \n
\n
\n
\n );\n}\n\nconst DemoIdContext = React.createContext(undefined);\n\nexport function DemoId({\n id,\n children,\n}: {\n children: React.ReactNode;\n id?: string;\n}) {\n return {children};\n}\n\nexport function useDemoId() {\n return React.useContext(DemoIdContext);\n}\n", "path": "example/playground-demo.tsx", "target": "components/playground-demo.tsx", "type": "registry:example" diff --git a/apps/www/public/r/styles/default/toolbar-demo.json b/apps/www/public/r/styles/default/toolbar-demo.json index c67da04bd8..a1806716b9 100644 --- a/apps/www/public/r/styles/default/toolbar-demo.json +++ b/apps/www/public/r/styles/default/toolbar-demo.json @@ -4,7 +4,7 @@ }, "files": [ { - "content": "'use client';\n\nimport React, { useRef } from 'react';\n\nimport type { ValueId } from '@/config/customizer-plugins';\n\nimport { cn } from '@udecode/cn';\nimport { AIChatPlugin, CopilotPlugin } from '@udecode/plate-ai/react';\nimport { AlignPlugin } from '@udecode/plate-alignment/react';\nimport { AutoformatPlugin } from '@udecode/plate-autoformat/react';\nimport {\n BoldPlugin,\n CodePlugin,\n ItalicPlugin,\n StrikethroughPlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n UnderlinePlugin,\n} from '@udecode/plate-basic-marks/react';\nimport { BlockquotePlugin } from '@udecode/plate-block-quote/react';\nimport { SingleLinePlugin } from '@udecode/plate-break/react';\nimport { CaptionPlugin } from '@udecode/plate-caption/react';\nimport { CodeBlockPlugin } from '@udecode/plate-code-block/react';\nimport { CommentsPlugin } from '@udecode/plate-comments/react';\nimport {\n ParagraphPlugin,\n Plate,\n usePlateEditor,\n} from '@udecode/plate-common/react';\nimport { DatePlugin } from '@udecode/plate-date/react';\nimport { DndPlugin } from '@udecode/plate-dnd';\nimport { DocxPlugin } from '@udecode/plate-docx';\nimport { EmojiPlugin } from '@udecode/plate-emoji/react';\nimport { ExcalidrawPlugin } from '@udecode/plate-excalidraw/react';\nimport {\n FontBackgroundColorPlugin,\n FontColorPlugin,\n FontSizePlugin,\n} from '@udecode/plate-font/react';\nimport { HEADING_KEYS } from '@udecode/plate-heading';\nimport { HeadingPlugin, TocPlugin } from '@udecode/plate-heading/react';\nimport { HighlightPlugin } from '@udecode/plate-highlight/react';\nimport { HorizontalRulePlugin } from '@udecode/plate-horizontal-rule/react';\nimport { IndentPlugin } from '@udecode/plate-indent/react';\nimport { IndentListPlugin } from '@udecode/plate-indent-list/react';\nimport { JuicePlugin } from '@udecode/plate-juice';\nimport { KbdPlugin } from '@udecode/plate-kbd/react';\nimport { ColumnPlugin } from '@udecode/plate-layout/react';\nimport { LineHeightPlugin } from '@udecode/plate-line-height/react';\nimport { LinkPlugin } from '@udecode/plate-link/react';\nimport { ListPlugin, TodoListPlugin } from '@udecode/plate-list/react';\nimport { MarkdownPlugin } from '@udecode/plate-markdown';\nimport { ImagePlugin, MediaEmbedPlugin } from '@udecode/plate-media/react';\nimport { MentionPlugin } from '@udecode/plate-mention/react';\nimport { NodeIdPlugin } from '@udecode/plate-node-id';\nimport { NormalizeTypesPlugin } from '@udecode/plate-normalizers';\nimport { PlaywrightPlugin } from '@udecode/plate-playwright';\nimport { DeletePlugin, SelectOnBackspacePlugin } from '@udecode/plate-select';\nimport {\n BlockMenuPlugin,\n BlockSelectionPlugin,\n} from '@udecode/plate-selection/react';\nimport { SlashPlugin } from '@udecode/plate-slash-command/react';\nimport { TablePlugin } from '@udecode/plate-table/react';\nimport { TogglePlugin } from '@udecode/plate-toggle/react';\nimport { TrailingBlockPlugin } from '@udecode/plate-trailing-block';\nimport Prism from 'prismjs';\n\nimport { CheckPlugin } from '@/components/context/check-plugin';\nimport { settingsStore } from '@/components/context/settings-store';\nimport { aiPlugins } from '@/lib/plate/demo/plugins/ai-plugins';\nimport { getAutoformatOptions } from '@/lib/plate/demo/plugins/autoformatOptions';\nimport { copilotPlugins } from '@/lib/plate/demo/plugins/copilot-plugins';\nimport { createPlateUI } from '@/plate/create-plate-ui';\nimport { editableProps } from '@/plate/demo/editableProps';\nimport { isEnabled } from '@/plate/demo/is-enabled';\nimport { DragOverCursorPlugin } from '@/plate/demo/plugins/DragOverCursorPlugin';\nimport { exitBreakPlugin } from '@/plate/demo/plugins/exitBreakPlugin';\nimport { resetBlockTypePlugin } from '@/plate/demo/plugins/resetBlockTypePlugin';\nimport { softBreakPlugin } from '@/plate/demo/plugins/softBreakPlugin';\nimport { tabbablePlugin } from '@/plate/demo/plugins/tabbablePlugin';\nimport { commentsData, usersData } from '@/plate/demo/values/commentsValue';\nimport { usePlaygroundValue } from '@/plate/demo/values/usePlaygroundValue';\nimport { BlockContextMenu } from '@/components/plate-ui/block-context-menu';\nimport { CommentsPopover } from '@/components/plate-ui/comments-popover';\nimport {\n CursorOverlay,\n SelectionOverlayPlugin,\n} from '@/components/plate-ui/cursor-overlay';\nimport { Editor, EditorContainer } from '@/components/plate-ui/editor';\nimport { FixedToolbar } from '@/components/plate-ui/fixed-toolbar';\nimport { FixedToolbarButtons } from '@/components/plate-ui/fixed-toolbar-buttons';\nimport { FloatingToolbar } from '@/components/plate-ui/floating-toolbar';\nimport { FloatingToolbarButtons } from '@/components/plate-ui/floating-toolbar-buttons';\nimport { ImagePreview } from '@/components/plate-ui/image-preview';\nimport {\n FireLiComponent,\n FireMarker,\n} from '@/components/plate-ui/indent-fire-marker';\nimport {\n TodoLi,\n TodoMarker,\n} from '@/components/plate-ui/indent-todo-marker';\nimport { LinkFloatingToolbar } from '@/components/plate-ui/link-floating-toolbar';\n\nimport { usePlaygroundEnabled } from './usePlaygroundEnabled';\n\nexport const usePlaygroundEditor = (id: any = '', scrollSelector?: string) => {\n const enabledPlugins = settingsStore.use.checkedPlugins();\n const overridePlugins = usePlaygroundEnabled(id);\n const autoformatOptions = getAutoformatOptions(id, enabledPlugins);\n\n const value = usePlaygroundValue(id);\n const key = settingsStore.use.version();\n const editorId = id || 'playground-' + key;\n\n return usePlateEditor(\n {\n id: editorId,\n override: {\n components: createPlateUI({\n draggable: isEnabled('dnd', id),\n placeholder: isEnabled('placeholder', id),\n }),\n plugins: overridePlugins,\n },\n plugins: [\n // AI\n ...(id === 'ai' || enabledPlugins[AIChatPlugin.key] ? aiPlugins : []),\n ...(id === 'copilot' || enabledPlugins[CopilotPlugin.key]\n ? copilotPlugins\n : []),\n // Nodes\n HeadingPlugin,\n TocPlugin.configure({\n options: {\n scrollContainerSelector: `#${scrollSelector}`,\n topOffset: 80,\n },\n }),\n BlockquotePlugin,\n CodeBlockPlugin.configure({\n options: {\n prism: Prism,\n },\n }),\n HorizontalRulePlugin,\n LinkPlugin.extend({\n render: { afterEditable: () => },\n }),\n ...(id === 'list' ? [ListPlugin] : []),\n ImagePlugin.extend({\n options: {\n disableUploadInsert: true,\n },\n render: { afterEditable: ImagePreview },\n }),\n MediaEmbedPlugin,\n CaptionPlugin.configure({\n options: {\n plugins: [ImagePlugin, MediaEmbedPlugin],\n },\n }),\n DatePlugin,\n MentionPlugin.configure({\n options: {\n triggerPreviousCharPattern: /^$|^[\\s\"']$/,\n },\n }),\n SlashPlugin,\n TablePlugin.configure({\n options: {\n enableMerging: id === 'tableMerge',\n },\n }),\n ColumnPlugin,\n SelectionOverlayPlugin,\n\n TodoListPlugin,\n TogglePlugin,\n ExcalidrawPlugin,\n // Marks\n BoldPlugin,\n ItalicPlugin,\n UnderlinePlugin,\n StrikethroughPlugin,\n CodePlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n FontColorPlugin,\n FontBackgroundColorPlugin,\n FontSizePlugin,\n HighlightPlugin,\n KbdPlugin,\n\n // Block Style\n AlignPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n MediaEmbedPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n ImagePlugin.key,\n HEADING_KEYS.h6,\n ],\n },\n }),\n IndentPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n }),\n IndentListPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n options: {\n listStyleTypes: {\n fire: {\n liComponent: FireLiComponent,\n markerComponent: FireMarker,\n type: 'fire',\n },\n todo: {\n liComponent: TodoLi,\n markerComponent: TodoMarker,\n type: 'todo',\n },\n },\n },\n }),\n LineHeightPlugin.extend({\n inject: {\n nodeProps: {\n defaultNodeValue: 1.5,\n validNodeValues: [1, 1.2, 1.5, 2, 3],\n },\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n ],\n },\n }),\n\n // Functionality\n AutoformatPlugin.configure({\n options: autoformatOptions,\n }),\n BlockSelectionPlugin.configure({\n options: {\n areaOptions: {\n behaviour: {\n scrolling: {\n speedDivider: 1.5,\n },\n startThreshold: 10,\n },\n boundaries: `#${scrollSelector}`,\n container: `#${scrollSelector}`,\n selectables: [`#${scrollSelector} .slate-selectable`],\n selectionAreaClass: 'slate-selection-area',\n },\n enableContextMenu: true,\n },\n }),\n BlockMenuPlugin.configure({\n render: { aboveEditable: BlockContextMenu },\n }),\n DndPlugin.configure({\n options: {\n enableScroller: true,\n onDropFiles: ({ dragItem, editor, target }) => {\n editor\n .getTransforms(ImagePlugin)\n .insertImageFromFiles(dragItem.files, {\n at: target,\n nextBlock: false,\n });\n },\n },\n }),\n EmojiPlugin,\n exitBreakPlugin,\n NodeIdPlugin,\n NormalizeTypesPlugin.configure({\n options: {\n rules: [{ path: [0], strictType: HEADING_KEYS.h1 }],\n },\n }),\n resetBlockTypePlugin,\n SelectOnBackspacePlugin.configure({\n options: {\n query: {\n allow: [ImagePlugin.key, HorizontalRulePlugin.key],\n },\n },\n }),\n DeletePlugin,\n SingleLinePlugin,\n softBreakPlugin,\n tabbablePlugin,\n TrailingBlockPlugin.configure({\n options: { type: ParagraphPlugin.key },\n }),\n DragOverCursorPlugin,\n\n // Collaboration\n CommentsPlugin.configure({\n options: {\n comments: commentsData,\n myUserId: '1',\n users: usersData,\n },\n }),\n\n // Deserialization\n DocxPlugin,\n MarkdownPlugin.configure({ options: { indentList: true } }),\n JuicePlugin,\n\n // Testing\n PlaywrightPlugin.configure({\n enabled: process.env.NODE_ENV !== 'production',\n }),\n ],\n value: value,\n },\n []\n );\n};\n\nexport default function PlaygroundDemo({\n id,\n className,\n scrollSelector,\n}: {\n id?: ValueId;\n className?: string;\n scrollSelector?: string;\n}) {\n const containerRef = useRef(null);\n const enabled = settingsStore.use.checkedComponents();\n\n const editor = usePlaygroundEditor(\n id,\n scrollSelector ?? `blockSelection-${id}`\n );\n\n return (\n \n \n \n \n \n \n \n \n \n\n
\n \n \n\n \n \n \n \n \n \n \n\n \n \n \n \n\n \n \n \n
\n
\n
\n );\n}\n\nconst DemoIdContext = React.createContext(undefined);\n\nexport function DemoId({\n id,\n children,\n}: {\n children: React.ReactNode;\n id?: string;\n}) {\n return {children};\n}\n\nexport function useDemoId() {\n return React.useContext(DemoIdContext);\n}\n", + "content": "'use client';\n\nimport React, { useRef } from 'react';\n\nimport type { ValueId } from '@/config/customizer-plugins';\n\nimport { cn } from '@udecode/cn';\nimport { AIChatPlugin, CopilotPlugin } from '@udecode/plate-ai/react';\nimport { AlignPlugin } from '@udecode/plate-alignment/react';\nimport { AutoformatPlugin } from '@udecode/plate-autoformat/react';\nimport {\n BoldPlugin,\n CodePlugin,\n ItalicPlugin,\n StrikethroughPlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n UnderlinePlugin,\n} from '@udecode/plate-basic-marks/react';\nimport { BlockquotePlugin } from '@udecode/plate-block-quote/react';\nimport { SingleLinePlugin } from '@udecode/plate-break/react';\nimport { CaptionPlugin } from '@udecode/plate-caption/react';\nimport { CodeBlockPlugin } from '@udecode/plate-code-block/react';\nimport { CommentsPlugin } from '@udecode/plate-comments/react';\nimport {\n ParagraphPlugin,\n Plate,\n usePlateEditor,\n} from '@udecode/plate-common/react';\nimport { DatePlugin } from '@udecode/plate-date/react';\nimport { DndPlugin } from '@udecode/plate-dnd';\nimport { DocxPlugin } from '@udecode/plate-docx';\nimport { EmojiPlugin } from '@udecode/plate-emoji/react';\nimport { ExcalidrawPlugin } from '@udecode/plate-excalidraw/react';\nimport {\n FontBackgroundColorPlugin,\n FontColorPlugin,\n FontSizePlugin,\n} from '@udecode/plate-font/react';\nimport { HEADING_KEYS } from '@udecode/plate-heading';\nimport { HeadingPlugin, TocPlugin } from '@udecode/plate-heading/react';\nimport { HighlightPlugin } from '@udecode/plate-highlight/react';\nimport { HorizontalRulePlugin } from '@udecode/plate-horizontal-rule/react';\nimport { IndentPlugin } from '@udecode/plate-indent/react';\nimport { IndentListPlugin } from '@udecode/plate-indent-list/react';\nimport { JuicePlugin } from '@udecode/plate-juice';\nimport { KbdPlugin } from '@udecode/plate-kbd/react';\nimport { ColumnPlugin } from '@udecode/plate-layout/react';\nimport { LineHeightPlugin } from '@udecode/plate-line-height/react';\nimport { LinkPlugin } from '@udecode/plate-link/react';\nimport { ListPlugin, TodoListPlugin } from '@udecode/plate-list/react';\nimport { MarkdownPlugin } from '@udecode/plate-markdown';\nimport { BaseImagePlugin } from '@udecode/plate-media';\nimport { ImagePlugin, MediaEmbedPlugin } from '@udecode/plate-media/react';\nimport { MentionPlugin } from '@udecode/plate-mention/react';\nimport { NodeIdPlugin } from '@udecode/plate-node-id';\nimport { NormalizeTypesPlugin } from '@udecode/plate-normalizers';\nimport { PlaywrightPlugin } from '@udecode/plate-playwright';\nimport { DeletePlugin, SelectOnBackspacePlugin } from '@udecode/plate-select';\nimport {\n BlockMenuPlugin,\n BlockSelectionPlugin,\n} from '@udecode/plate-selection/react';\nimport { SlashPlugin } from '@udecode/plate-slash-command/react';\nimport { TablePlugin } from '@udecode/plate-table/react';\nimport { TogglePlugin } from '@udecode/plate-toggle/react';\nimport { TrailingBlockPlugin } from '@udecode/plate-trailing-block';\nimport Prism from 'prismjs';\n\nimport { CheckPlugin } from '@/components/context/check-plugin';\nimport { settingsStore } from '@/components/context/settings-store';\nimport { aiPlugins } from '@/lib/plate/demo/plugins/ai-plugins';\nimport { getAutoformatOptions } from '@/lib/plate/demo/plugins/autoformatOptions';\nimport { copilotPlugins } from '@/lib/plate/demo/plugins/copilot-plugins';\nimport { createPlateUI } from '@/plate/create-plate-ui';\nimport { editableProps } from '@/plate/demo/editableProps';\nimport { isEnabled } from '@/plate/demo/is-enabled';\nimport { DragOverCursorPlugin } from '@/plate/demo/plugins/DragOverCursorPlugin';\nimport { exitBreakPlugin } from '@/plate/demo/plugins/exitBreakPlugin';\nimport { resetBlockTypePlugin } from '@/plate/demo/plugins/resetBlockTypePlugin';\nimport { softBreakPlugin } from '@/plate/demo/plugins/softBreakPlugin';\nimport { tabbablePlugin } from '@/plate/demo/plugins/tabbablePlugin';\nimport { commentsData, usersData } from '@/plate/demo/values/commentsValue';\nimport { usePlaygroundValue } from '@/plate/demo/values/usePlaygroundValue';\nimport { BlockContextMenu } from '@/components/plate-ui/block-context-menu';\nimport { CommentsPopover } from '@/components/plate-ui/comments-popover';\nimport {\n CursorOverlay,\n SelectionOverlayPlugin,\n} from '@/components/plate-ui/cursor-overlay';\nimport { Editor, EditorContainer } from '@/components/plate-ui/editor';\nimport { FixedToolbar } from '@/components/plate-ui/fixed-toolbar';\nimport { FixedToolbarButtons } from '@/components/plate-ui/fixed-toolbar-buttons';\nimport { FloatingToolbar } from '@/components/plate-ui/floating-toolbar';\nimport { FloatingToolbarButtons } from '@/components/plate-ui/floating-toolbar-buttons';\nimport { ImagePreview } from '@/components/plate-ui/image-preview';\nimport {\n FireLiComponent,\n FireMarker,\n} from '@/components/plate-ui/indent-fire-marker';\nimport {\n TodoLi,\n TodoMarker,\n} from '@/components/plate-ui/indent-todo-marker';\nimport { LinkFloatingToolbar } from '@/components/plate-ui/link-floating-toolbar';\n\nimport { usePlaygroundEnabled } from './usePlaygroundEnabled';\n\nexport const usePlaygroundEditor = (id: any = '', scrollSelector?: string) => {\n const enabledPlugins = settingsStore.use.checkedPlugins();\n const overridePlugins = usePlaygroundEnabled(id);\n const autoformatOptions = getAutoformatOptions(id, enabledPlugins);\n\n const value = usePlaygroundValue(id);\n const key = settingsStore.use.version();\n const editorId = id || 'playground-' + key;\n\n return usePlateEditor(\n {\n id: editorId,\n override: {\n components: createPlateUI({\n draggable: isEnabled('dnd', id),\n placeholder: isEnabled('placeholder', id),\n }),\n plugins: overridePlugins,\n },\n plugins: [\n // AI\n ...(id === 'ai' || enabledPlugins[AIChatPlugin.key] ? aiPlugins : []),\n ...(id === 'copilot' || enabledPlugins[CopilotPlugin.key]\n ? copilotPlugins\n : []),\n // Nodes\n HeadingPlugin,\n TocPlugin.configure({\n options: {\n scrollContainerSelector: `#${scrollSelector}`,\n topOffset: 80,\n },\n }),\n BlockquotePlugin,\n CodeBlockPlugin.configure({\n options: {\n prism: Prism,\n },\n }),\n HorizontalRulePlugin,\n LinkPlugin.extend({\n render: { afterEditable: () => },\n }),\n ...(id === 'list' ? [ListPlugin] : []),\n ImagePlugin.extend({\n options: {\n disableUploadInsert: true,\n },\n render: { afterEditable: ImagePreview },\n }),\n MediaEmbedPlugin,\n CaptionPlugin.configure({\n options: {\n plugins: [ImagePlugin, MediaEmbedPlugin],\n },\n }),\n DatePlugin,\n MentionPlugin.configure({\n options: {\n triggerPreviousCharPattern: /^$|^[\\s\"']$/,\n },\n }),\n SlashPlugin,\n TablePlugin.configure({\n options: {\n enableMerging: id === 'tableMerge',\n },\n }),\n ColumnPlugin,\n SelectionOverlayPlugin,\n\n TodoListPlugin,\n TogglePlugin,\n ExcalidrawPlugin,\n // Marks\n BoldPlugin,\n ItalicPlugin,\n UnderlinePlugin,\n StrikethroughPlugin,\n CodePlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n FontColorPlugin,\n FontBackgroundColorPlugin,\n FontSizePlugin,\n HighlightPlugin,\n KbdPlugin,\n\n // Block Style\n AlignPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n MediaEmbedPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n ImagePlugin.key,\n HEADING_KEYS.h6,\n ],\n },\n }),\n IndentPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n }),\n IndentListPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n options: {\n listStyleTypes: {\n fire: {\n liComponent: FireLiComponent,\n markerComponent: FireMarker,\n type: 'fire',\n },\n todo: {\n liComponent: TodoLi,\n markerComponent: TodoMarker,\n type: 'todo',\n },\n },\n },\n }),\n LineHeightPlugin.extend({\n inject: {\n nodeProps: {\n defaultNodeValue: 1.5,\n validNodeValues: [1, 1.2, 1.5, 2, 3],\n },\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n ],\n },\n }),\n\n // Functionality\n AutoformatPlugin.configure({\n options: autoformatOptions,\n }),\n BlockSelectionPlugin.configure({\n options: {\n areaOptions: {\n behaviour: {\n scrolling: {\n speedDivider: 1.5,\n },\n startThreshold: 10,\n },\n boundaries: `#${scrollSelector}`,\n container: `#${scrollSelector}`,\n selectables: [`#${scrollSelector} .slate-selectable`],\n selectionAreaClass: 'slate-selection-area',\n },\n enableContextMenu: true,\n },\n }),\n BlockMenuPlugin.configure({\n render: { aboveEditable: BlockContextMenu },\n }),\n DndPlugin.configure({\n options: {\n enableScroller: true,\n onDropFiles: ({ dragItem, editor, target }) => {\n editor\n .getTransforms(BaseImagePlugin)\n .insert.imageFromFiles(dragItem.files, {\n at: target,\n nextBlock: false,\n });\n },\n },\n }),\n EmojiPlugin,\n exitBreakPlugin,\n NodeIdPlugin,\n NormalizeTypesPlugin.configure({\n options: {\n rules: [{ path: [0], strictType: HEADING_KEYS.h1 }],\n },\n }),\n resetBlockTypePlugin,\n SelectOnBackspacePlugin.configure({\n options: {\n query: {\n allow: [ImagePlugin.key, HorizontalRulePlugin.key],\n },\n },\n }),\n DeletePlugin,\n SingleLinePlugin,\n softBreakPlugin,\n tabbablePlugin,\n TrailingBlockPlugin.configure({\n options: { type: ParagraphPlugin.key },\n }),\n DragOverCursorPlugin,\n\n // Collaboration\n CommentsPlugin.configure({\n options: {\n comments: commentsData,\n myUserId: '1',\n users: usersData,\n },\n }),\n\n // Deserialization\n DocxPlugin,\n MarkdownPlugin.configure({ options: { indentList: true } }),\n JuicePlugin,\n\n // Testing\n PlaywrightPlugin.configure({\n enabled: process.env.NODE_ENV !== 'production',\n }),\n ],\n value: value,\n },\n []\n );\n};\n\nexport default function PlaygroundDemo({\n id,\n className,\n scrollSelector,\n}: {\n id?: ValueId;\n className?: string;\n scrollSelector?: string;\n}) {\n const containerRef = useRef(null);\n const enabled = settingsStore.use.checkedComponents();\n\n const editor = usePlaygroundEditor(\n id,\n scrollSelector ?? `blockSelection-${id}`\n );\n\n return (\n \n \n \n \n \n \n \n \n \n\n
\n \n \n\n \n \n \n \n \n \n \n\n \n \n \n \n\n \n \n \n
\n
\n
\n );\n}\n\nconst DemoIdContext = React.createContext(undefined);\n\nexport function DemoId({\n id,\n children,\n}: {\n children: React.ReactNode;\n id?: string;\n}) {\n return {children};\n}\n\nexport function useDemoId() {\n return React.useContext(DemoIdContext);\n}\n", "path": "example/playground-demo.tsx", "target": "components/playground-demo.tsx", "type": "registry:example" diff --git a/apps/www/public/r/styles/default/upload-demo.json b/apps/www/public/r/styles/default/upload-demo.json index 8f8ba398f0..23344de3ce 100644 --- a/apps/www/public/r/styles/default/upload-demo.json +++ b/apps/www/public/r/styles/default/upload-demo.json @@ -4,7 +4,7 @@ }, "files": [ { - "content": "'use client';\n\nimport React, { useRef } from 'react';\n\nimport type { ValueId } from '@/config/customizer-plugins';\n\nimport { cn } from '@udecode/cn';\nimport { AIChatPlugin, CopilotPlugin } from '@udecode/plate-ai/react';\nimport { AlignPlugin } from '@udecode/plate-alignment/react';\nimport { AutoformatPlugin } from '@udecode/plate-autoformat/react';\nimport {\n BoldPlugin,\n CodePlugin,\n ItalicPlugin,\n StrikethroughPlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n UnderlinePlugin,\n} from '@udecode/plate-basic-marks/react';\nimport { BlockquotePlugin } from '@udecode/plate-block-quote/react';\nimport { SingleLinePlugin } from '@udecode/plate-break/react';\nimport { CaptionPlugin } from '@udecode/plate-caption/react';\nimport { CodeBlockPlugin } from '@udecode/plate-code-block/react';\nimport { CommentsPlugin } from '@udecode/plate-comments/react';\nimport {\n ParagraphPlugin,\n Plate,\n usePlateEditor,\n} from '@udecode/plate-common/react';\nimport { DatePlugin } from '@udecode/plate-date/react';\nimport { DndPlugin } from '@udecode/plate-dnd';\nimport { DocxPlugin } from '@udecode/plate-docx';\nimport { EmojiPlugin } from '@udecode/plate-emoji/react';\nimport { ExcalidrawPlugin } from '@udecode/plate-excalidraw/react';\nimport {\n FontBackgroundColorPlugin,\n FontColorPlugin,\n FontSizePlugin,\n} from '@udecode/plate-font/react';\nimport { HEADING_KEYS } from '@udecode/plate-heading';\nimport { HeadingPlugin, TocPlugin } from '@udecode/plate-heading/react';\nimport { HighlightPlugin } from '@udecode/plate-highlight/react';\nimport { HorizontalRulePlugin } from '@udecode/plate-horizontal-rule/react';\nimport { IndentPlugin } from '@udecode/plate-indent/react';\nimport { IndentListPlugin } from '@udecode/plate-indent-list/react';\nimport { JuicePlugin } from '@udecode/plate-juice';\nimport { KbdPlugin } from '@udecode/plate-kbd/react';\nimport { ColumnPlugin } from '@udecode/plate-layout/react';\nimport { LineHeightPlugin } from '@udecode/plate-line-height/react';\nimport { LinkPlugin } from '@udecode/plate-link/react';\nimport { ListPlugin, TodoListPlugin } from '@udecode/plate-list/react';\nimport { MarkdownPlugin } from '@udecode/plate-markdown';\nimport { ImagePlugin, MediaEmbedPlugin } from '@udecode/plate-media/react';\nimport { MentionPlugin } from '@udecode/plate-mention/react';\nimport { NodeIdPlugin } from '@udecode/plate-node-id';\nimport { NormalizeTypesPlugin } from '@udecode/plate-normalizers';\nimport { PlaywrightPlugin } from '@udecode/plate-playwright';\nimport { DeletePlugin, SelectOnBackspacePlugin } from '@udecode/plate-select';\nimport {\n BlockMenuPlugin,\n BlockSelectionPlugin,\n} from '@udecode/plate-selection/react';\nimport { SlashPlugin } from '@udecode/plate-slash-command/react';\nimport { TablePlugin } from '@udecode/plate-table/react';\nimport { TogglePlugin } from '@udecode/plate-toggle/react';\nimport { TrailingBlockPlugin } from '@udecode/plate-trailing-block';\nimport Prism from 'prismjs';\n\nimport { CheckPlugin } from '@/components/context/check-plugin';\nimport { settingsStore } from '@/components/context/settings-store';\nimport { aiPlugins } from '@/lib/plate/demo/plugins/ai-plugins';\nimport { getAutoformatOptions } from '@/lib/plate/demo/plugins/autoformatOptions';\nimport { copilotPlugins } from '@/lib/plate/demo/plugins/copilot-plugins';\nimport { createPlateUI } from '@/plate/create-plate-ui';\nimport { editableProps } from '@/plate/demo/editableProps';\nimport { isEnabled } from '@/plate/demo/is-enabled';\nimport { DragOverCursorPlugin } from '@/plate/demo/plugins/DragOverCursorPlugin';\nimport { exitBreakPlugin } from '@/plate/demo/plugins/exitBreakPlugin';\nimport { resetBlockTypePlugin } from '@/plate/demo/plugins/resetBlockTypePlugin';\nimport { softBreakPlugin } from '@/plate/demo/plugins/softBreakPlugin';\nimport { tabbablePlugin } from '@/plate/demo/plugins/tabbablePlugin';\nimport { commentsData, usersData } from '@/plate/demo/values/commentsValue';\nimport { usePlaygroundValue } from '@/plate/demo/values/usePlaygroundValue';\nimport { BlockContextMenu } from '@/components/plate-ui/block-context-menu';\nimport { CommentsPopover } from '@/components/plate-ui/comments-popover';\nimport {\n CursorOverlay,\n SelectionOverlayPlugin,\n} from '@/components/plate-ui/cursor-overlay';\nimport { Editor, EditorContainer } from '@/components/plate-ui/editor';\nimport { FixedToolbar } from '@/components/plate-ui/fixed-toolbar';\nimport { FixedToolbarButtons } from '@/components/plate-ui/fixed-toolbar-buttons';\nimport { FloatingToolbar } from '@/components/plate-ui/floating-toolbar';\nimport { FloatingToolbarButtons } from '@/components/plate-ui/floating-toolbar-buttons';\nimport { ImagePreview } from '@/components/plate-ui/image-preview';\nimport {\n FireLiComponent,\n FireMarker,\n} from '@/components/plate-ui/indent-fire-marker';\nimport {\n TodoLi,\n TodoMarker,\n} from '@/components/plate-ui/indent-todo-marker';\nimport { LinkFloatingToolbar } from '@/components/plate-ui/link-floating-toolbar';\n\nimport { usePlaygroundEnabled } from './usePlaygroundEnabled';\n\nexport const usePlaygroundEditor = (id: any = '', scrollSelector?: string) => {\n const enabledPlugins = settingsStore.use.checkedPlugins();\n const overridePlugins = usePlaygroundEnabled(id);\n const autoformatOptions = getAutoformatOptions(id, enabledPlugins);\n\n const value = usePlaygroundValue(id);\n const key = settingsStore.use.version();\n const editorId = id || 'playground-' + key;\n\n return usePlateEditor(\n {\n id: editorId,\n override: {\n components: createPlateUI({\n draggable: isEnabled('dnd', id),\n placeholder: isEnabled('placeholder', id),\n }),\n plugins: overridePlugins,\n },\n plugins: [\n // AI\n ...(id === 'ai' || enabledPlugins[AIChatPlugin.key] ? aiPlugins : []),\n ...(id === 'copilot' || enabledPlugins[CopilotPlugin.key]\n ? copilotPlugins\n : []),\n // Nodes\n HeadingPlugin,\n TocPlugin.configure({\n options: {\n scrollContainerSelector: `#${scrollSelector}`,\n topOffset: 80,\n },\n }),\n BlockquotePlugin,\n CodeBlockPlugin.configure({\n options: {\n prism: Prism,\n },\n }),\n HorizontalRulePlugin,\n LinkPlugin.extend({\n render: { afterEditable: () => },\n }),\n ...(id === 'list' ? [ListPlugin] : []),\n ImagePlugin.extend({\n options: {\n disableUploadInsert: true,\n },\n render: { afterEditable: ImagePreview },\n }),\n MediaEmbedPlugin,\n CaptionPlugin.configure({\n options: {\n plugins: [ImagePlugin, MediaEmbedPlugin],\n },\n }),\n DatePlugin,\n MentionPlugin.configure({\n options: {\n triggerPreviousCharPattern: /^$|^[\\s\"']$/,\n },\n }),\n SlashPlugin,\n TablePlugin.configure({\n options: {\n enableMerging: id === 'tableMerge',\n },\n }),\n ColumnPlugin,\n SelectionOverlayPlugin,\n\n TodoListPlugin,\n TogglePlugin,\n ExcalidrawPlugin,\n // Marks\n BoldPlugin,\n ItalicPlugin,\n UnderlinePlugin,\n StrikethroughPlugin,\n CodePlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n FontColorPlugin,\n FontBackgroundColorPlugin,\n FontSizePlugin,\n HighlightPlugin,\n KbdPlugin,\n\n // Block Style\n AlignPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n MediaEmbedPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n ImagePlugin.key,\n HEADING_KEYS.h6,\n ],\n },\n }),\n IndentPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n }),\n IndentListPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n options: {\n listStyleTypes: {\n fire: {\n liComponent: FireLiComponent,\n markerComponent: FireMarker,\n type: 'fire',\n },\n todo: {\n liComponent: TodoLi,\n markerComponent: TodoMarker,\n type: 'todo',\n },\n },\n },\n }),\n LineHeightPlugin.extend({\n inject: {\n nodeProps: {\n defaultNodeValue: 1.5,\n validNodeValues: [1, 1.2, 1.5, 2, 3],\n },\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n ],\n },\n }),\n\n // Functionality\n AutoformatPlugin.configure({\n options: autoformatOptions,\n }),\n BlockSelectionPlugin.configure({\n options: {\n areaOptions: {\n behaviour: {\n scrolling: {\n speedDivider: 1.5,\n },\n startThreshold: 10,\n },\n boundaries: `#${scrollSelector}`,\n container: `#${scrollSelector}`,\n selectables: [`#${scrollSelector} .slate-selectable`],\n selectionAreaClass: 'slate-selection-area',\n },\n enableContextMenu: true,\n },\n }),\n BlockMenuPlugin.configure({\n render: { aboveEditable: BlockContextMenu },\n }),\n DndPlugin.configure({\n options: {\n enableScroller: true,\n onDropFiles: ({ dragItem, editor, target }) => {\n editor\n .getTransforms(ImagePlugin)\n .insertImageFromFiles(dragItem.files, {\n at: target,\n nextBlock: false,\n });\n },\n },\n }),\n EmojiPlugin,\n exitBreakPlugin,\n NodeIdPlugin,\n NormalizeTypesPlugin.configure({\n options: {\n rules: [{ path: [0], strictType: HEADING_KEYS.h1 }],\n },\n }),\n resetBlockTypePlugin,\n SelectOnBackspacePlugin.configure({\n options: {\n query: {\n allow: [ImagePlugin.key, HorizontalRulePlugin.key],\n },\n },\n }),\n DeletePlugin,\n SingleLinePlugin,\n softBreakPlugin,\n tabbablePlugin,\n TrailingBlockPlugin.configure({\n options: { type: ParagraphPlugin.key },\n }),\n DragOverCursorPlugin,\n\n // Collaboration\n CommentsPlugin.configure({\n options: {\n comments: commentsData,\n myUserId: '1',\n users: usersData,\n },\n }),\n\n // Deserialization\n DocxPlugin,\n MarkdownPlugin.configure({ options: { indentList: true } }),\n JuicePlugin,\n\n // Testing\n PlaywrightPlugin.configure({\n enabled: process.env.NODE_ENV !== 'production',\n }),\n ],\n value: value,\n },\n []\n );\n};\n\nexport default function PlaygroundDemo({\n id,\n className,\n scrollSelector,\n}: {\n id?: ValueId;\n className?: string;\n scrollSelector?: string;\n}) {\n const containerRef = useRef(null);\n const enabled = settingsStore.use.checkedComponents();\n\n const editor = usePlaygroundEditor(\n id,\n scrollSelector ?? `blockSelection-${id}`\n );\n\n return (\n \n \n \n \n \n \n \n \n \n\n
\n \n \n\n \n \n \n \n \n \n \n\n \n \n \n \n\n \n \n \n
\n
\n
\n );\n}\n\nconst DemoIdContext = React.createContext(undefined);\n\nexport function DemoId({\n id,\n children,\n}: {\n children: React.ReactNode;\n id?: string;\n}) {\n return {children};\n}\n\nexport function useDemoId() {\n return React.useContext(DemoIdContext);\n}\n", + "content": "'use client';\n\nimport React, { useRef } from 'react';\n\nimport type { ValueId } from '@/config/customizer-plugins';\n\nimport { cn } from '@udecode/cn';\nimport { AIChatPlugin, CopilotPlugin } from '@udecode/plate-ai/react';\nimport { AlignPlugin } from '@udecode/plate-alignment/react';\nimport { AutoformatPlugin } from '@udecode/plate-autoformat/react';\nimport {\n BoldPlugin,\n CodePlugin,\n ItalicPlugin,\n StrikethroughPlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n UnderlinePlugin,\n} from '@udecode/plate-basic-marks/react';\nimport { BlockquotePlugin } from '@udecode/plate-block-quote/react';\nimport { SingleLinePlugin } from '@udecode/plate-break/react';\nimport { CaptionPlugin } from '@udecode/plate-caption/react';\nimport { CodeBlockPlugin } from '@udecode/plate-code-block/react';\nimport { CommentsPlugin } from '@udecode/plate-comments/react';\nimport {\n ParagraphPlugin,\n Plate,\n usePlateEditor,\n} from '@udecode/plate-common/react';\nimport { DatePlugin } from '@udecode/plate-date/react';\nimport { DndPlugin } from '@udecode/plate-dnd';\nimport { DocxPlugin } from '@udecode/plate-docx';\nimport { EmojiPlugin } from '@udecode/plate-emoji/react';\nimport { ExcalidrawPlugin } from '@udecode/plate-excalidraw/react';\nimport {\n FontBackgroundColorPlugin,\n FontColorPlugin,\n FontSizePlugin,\n} from '@udecode/plate-font/react';\nimport { HEADING_KEYS } from '@udecode/plate-heading';\nimport { HeadingPlugin, TocPlugin } from '@udecode/plate-heading/react';\nimport { HighlightPlugin } from '@udecode/plate-highlight/react';\nimport { HorizontalRulePlugin } from '@udecode/plate-horizontal-rule/react';\nimport { IndentPlugin } from '@udecode/plate-indent/react';\nimport { IndentListPlugin } from '@udecode/plate-indent-list/react';\nimport { JuicePlugin } from '@udecode/plate-juice';\nimport { KbdPlugin } from '@udecode/plate-kbd/react';\nimport { ColumnPlugin } from '@udecode/plate-layout/react';\nimport { LineHeightPlugin } from '@udecode/plate-line-height/react';\nimport { LinkPlugin } from '@udecode/plate-link/react';\nimport { ListPlugin, TodoListPlugin } from '@udecode/plate-list/react';\nimport { MarkdownPlugin } from '@udecode/plate-markdown';\nimport { BaseImagePlugin } from '@udecode/plate-media';\nimport { ImagePlugin, MediaEmbedPlugin } from '@udecode/plate-media/react';\nimport { MentionPlugin } from '@udecode/plate-mention/react';\nimport { NodeIdPlugin } from '@udecode/plate-node-id';\nimport { NormalizeTypesPlugin } from '@udecode/plate-normalizers';\nimport { PlaywrightPlugin } from '@udecode/plate-playwright';\nimport { DeletePlugin, SelectOnBackspacePlugin } from '@udecode/plate-select';\nimport {\n BlockMenuPlugin,\n BlockSelectionPlugin,\n} from '@udecode/plate-selection/react';\nimport { SlashPlugin } from '@udecode/plate-slash-command/react';\nimport { TablePlugin } from '@udecode/plate-table/react';\nimport { TogglePlugin } from '@udecode/plate-toggle/react';\nimport { TrailingBlockPlugin } from '@udecode/plate-trailing-block';\nimport Prism from 'prismjs';\n\nimport { CheckPlugin } from '@/components/context/check-plugin';\nimport { settingsStore } from '@/components/context/settings-store';\nimport { aiPlugins } from '@/lib/plate/demo/plugins/ai-plugins';\nimport { getAutoformatOptions } from '@/lib/plate/demo/plugins/autoformatOptions';\nimport { copilotPlugins } from '@/lib/plate/demo/plugins/copilot-plugins';\nimport { createPlateUI } from '@/plate/create-plate-ui';\nimport { editableProps } from '@/plate/demo/editableProps';\nimport { isEnabled } from '@/plate/demo/is-enabled';\nimport { DragOverCursorPlugin } from '@/plate/demo/plugins/DragOverCursorPlugin';\nimport { exitBreakPlugin } from '@/plate/demo/plugins/exitBreakPlugin';\nimport { resetBlockTypePlugin } from '@/plate/demo/plugins/resetBlockTypePlugin';\nimport { softBreakPlugin } from '@/plate/demo/plugins/softBreakPlugin';\nimport { tabbablePlugin } from '@/plate/demo/plugins/tabbablePlugin';\nimport { commentsData, usersData } from '@/plate/demo/values/commentsValue';\nimport { usePlaygroundValue } from '@/plate/demo/values/usePlaygroundValue';\nimport { BlockContextMenu } from '@/components/plate-ui/block-context-menu';\nimport { CommentsPopover } from '@/components/plate-ui/comments-popover';\nimport {\n CursorOverlay,\n SelectionOverlayPlugin,\n} from '@/components/plate-ui/cursor-overlay';\nimport { Editor, EditorContainer } from '@/components/plate-ui/editor';\nimport { FixedToolbar } from '@/components/plate-ui/fixed-toolbar';\nimport { FixedToolbarButtons } from '@/components/plate-ui/fixed-toolbar-buttons';\nimport { FloatingToolbar } from '@/components/plate-ui/floating-toolbar';\nimport { FloatingToolbarButtons } from '@/components/plate-ui/floating-toolbar-buttons';\nimport { ImagePreview } from '@/components/plate-ui/image-preview';\nimport {\n FireLiComponent,\n FireMarker,\n} from '@/components/plate-ui/indent-fire-marker';\nimport {\n TodoLi,\n TodoMarker,\n} from '@/components/plate-ui/indent-todo-marker';\nimport { LinkFloatingToolbar } from '@/components/plate-ui/link-floating-toolbar';\n\nimport { usePlaygroundEnabled } from './usePlaygroundEnabled';\n\nexport const usePlaygroundEditor = (id: any = '', scrollSelector?: string) => {\n const enabledPlugins = settingsStore.use.checkedPlugins();\n const overridePlugins = usePlaygroundEnabled(id);\n const autoformatOptions = getAutoformatOptions(id, enabledPlugins);\n\n const value = usePlaygroundValue(id);\n const key = settingsStore.use.version();\n const editorId = id || 'playground-' + key;\n\n return usePlateEditor(\n {\n id: editorId,\n override: {\n components: createPlateUI({\n draggable: isEnabled('dnd', id),\n placeholder: isEnabled('placeholder', id),\n }),\n plugins: overridePlugins,\n },\n plugins: [\n // AI\n ...(id === 'ai' || enabledPlugins[AIChatPlugin.key] ? aiPlugins : []),\n ...(id === 'copilot' || enabledPlugins[CopilotPlugin.key]\n ? copilotPlugins\n : []),\n // Nodes\n HeadingPlugin,\n TocPlugin.configure({\n options: {\n scrollContainerSelector: `#${scrollSelector}`,\n topOffset: 80,\n },\n }),\n BlockquotePlugin,\n CodeBlockPlugin.configure({\n options: {\n prism: Prism,\n },\n }),\n HorizontalRulePlugin,\n LinkPlugin.extend({\n render: { afterEditable: () => },\n }),\n ...(id === 'list' ? [ListPlugin] : []),\n ImagePlugin.extend({\n options: {\n disableUploadInsert: true,\n },\n render: { afterEditable: ImagePreview },\n }),\n MediaEmbedPlugin,\n CaptionPlugin.configure({\n options: {\n plugins: [ImagePlugin, MediaEmbedPlugin],\n },\n }),\n DatePlugin,\n MentionPlugin.configure({\n options: {\n triggerPreviousCharPattern: /^$|^[\\s\"']$/,\n },\n }),\n SlashPlugin,\n TablePlugin.configure({\n options: {\n enableMerging: id === 'tableMerge',\n },\n }),\n ColumnPlugin,\n SelectionOverlayPlugin,\n\n TodoListPlugin,\n TogglePlugin,\n ExcalidrawPlugin,\n // Marks\n BoldPlugin,\n ItalicPlugin,\n UnderlinePlugin,\n StrikethroughPlugin,\n CodePlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n FontColorPlugin,\n FontBackgroundColorPlugin,\n FontSizePlugin,\n HighlightPlugin,\n KbdPlugin,\n\n // Block Style\n AlignPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n MediaEmbedPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n ImagePlugin.key,\n HEADING_KEYS.h6,\n ],\n },\n }),\n IndentPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n }),\n IndentListPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n options: {\n listStyleTypes: {\n fire: {\n liComponent: FireLiComponent,\n markerComponent: FireMarker,\n type: 'fire',\n },\n todo: {\n liComponent: TodoLi,\n markerComponent: TodoMarker,\n type: 'todo',\n },\n },\n },\n }),\n LineHeightPlugin.extend({\n inject: {\n nodeProps: {\n defaultNodeValue: 1.5,\n validNodeValues: [1, 1.2, 1.5, 2, 3],\n },\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n ],\n },\n }),\n\n // Functionality\n AutoformatPlugin.configure({\n options: autoformatOptions,\n }),\n BlockSelectionPlugin.configure({\n options: {\n areaOptions: {\n behaviour: {\n scrolling: {\n speedDivider: 1.5,\n },\n startThreshold: 10,\n },\n boundaries: `#${scrollSelector}`,\n container: `#${scrollSelector}`,\n selectables: [`#${scrollSelector} .slate-selectable`],\n selectionAreaClass: 'slate-selection-area',\n },\n enableContextMenu: true,\n },\n }),\n BlockMenuPlugin.configure({\n render: { aboveEditable: BlockContextMenu },\n }),\n DndPlugin.configure({\n options: {\n enableScroller: true,\n onDropFiles: ({ dragItem, editor, target }) => {\n editor\n .getTransforms(BaseImagePlugin)\n .insert.imageFromFiles(dragItem.files, {\n at: target,\n nextBlock: false,\n });\n },\n },\n }),\n EmojiPlugin,\n exitBreakPlugin,\n NodeIdPlugin,\n NormalizeTypesPlugin.configure({\n options: {\n rules: [{ path: [0], strictType: HEADING_KEYS.h1 }],\n },\n }),\n resetBlockTypePlugin,\n SelectOnBackspacePlugin.configure({\n options: {\n query: {\n allow: [ImagePlugin.key, HorizontalRulePlugin.key],\n },\n },\n }),\n DeletePlugin,\n SingleLinePlugin,\n softBreakPlugin,\n tabbablePlugin,\n TrailingBlockPlugin.configure({\n options: { type: ParagraphPlugin.key },\n }),\n DragOverCursorPlugin,\n\n // Collaboration\n CommentsPlugin.configure({\n options: {\n comments: commentsData,\n myUserId: '1',\n users: usersData,\n },\n }),\n\n // Deserialization\n DocxPlugin,\n MarkdownPlugin.configure({ options: { indentList: true } }),\n JuicePlugin,\n\n // Testing\n PlaywrightPlugin.configure({\n enabled: process.env.NODE_ENV !== 'production',\n }),\n ],\n value: value,\n },\n []\n );\n};\n\nexport default function PlaygroundDemo({\n id,\n className,\n scrollSelector,\n}: {\n id?: ValueId;\n className?: string;\n scrollSelector?: string;\n}) {\n const containerRef = useRef(null);\n const enabled = settingsStore.use.checkedComponents();\n\n const editor = usePlaygroundEditor(\n id,\n scrollSelector ?? `blockSelection-${id}`\n );\n\n return (\n \n \n \n \n \n \n \n \n \n\n
\n \n \n\n \n \n \n \n \n \n \n\n \n \n \n \n\n \n \n \n
\n
\n
\n );\n}\n\nconst DemoIdContext = React.createContext(undefined);\n\nexport function DemoId({\n id,\n children,\n}: {\n children: React.ReactNode;\n id?: string;\n}) {\n return {children};\n}\n\nexport function useDemoId() {\n return React.useContext(DemoIdContext);\n}\n", "path": "example/playground-demo.tsx", "target": "components/playground-demo.tsx", "type": "registry:example" diff --git a/apps/www/src/registry/default/example/playground-demo.tsx b/apps/www/src/registry/default/example/playground-demo.tsx index 8a5ca7badb..6c39f56195 100644 --- a/apps/www/src/registry/default/example/playground-demo.tsx +++ b/apps/www/src/registry/default/example/playground-demo.tsx @@ -50,6 +50,7 @@ import { LineHeightPlugin } from '@udecode/plate-line-height/react'; import { LinkPlugin } from '@udecode/plate-link/react'; import { ListPlugin, TodoListPlugin } from '@udecode/plate-list/react'; import { MarkdownPlugin } from '@udecode/plate-markdown'; +import { BaseImagePlugin } from '@udecode/plate-media'; import { ImagePlugin, MediaEmbedPlugin } from '@udecode/plate-media/react'; import { MentionPlugin } from '@udecode/plate-mention/react'; import { NodeIdPlugin } from '@udecode/plate-node-id'; @@ -302,7 +303,7 @@ export const usePlaygroundEditor = (id: any = '', scrollSelector?: string) => { enableScroller: true, onDropFiles: ({ dragItem, editor, target }) => { editor - .getTransforms(ImagePlugin) + .getTransforms(BaseImagePlugin) .insert.imageFromFiles(dragItem.files, { at: target, nextBlock: false, diff --git a/packages/media/src/lib/image/BaseImagePlugin.ts b/packages/media/src/lib/image/BaseImagePlugin.ts index 0ff9d9a4c1..1ab7d8a19a 100644 --- a/packages/media/src/lib/image/BaseImagePlugin.ts +++ b/packages/media/src/lib/image/BaseImagePlugin.ts @@ -46,7 +46,7 @@ export const BaseImagePlugin = createTSlatePlugin({ }) .extendEditorTransforms(({ editor }) => ({ insert: { - imageFromFiles: bindFirst(insertImageFromFiles, editor as any), + imageFromFiles: bindFirst(insertImageFromFiles, editor), }, })) .extend(({ plugin }) => ({ diff --git a/packages/media/src/lib/image/transforms/index.ts b/packages/media/src/lib/image/transforms/index.ts index c334d0ebc8..cfa5d0c32b 100644 --- a/packages/media/src/lib/image/transforms/index.ts +++ b/packages/media/src/lib/image/transforms/index.ts @@ -3,3 +3,4 @@ */ export * from './insertImage'; +export * from './insertImageFromFiles'; \ No newline at end of file diff --git a/packages/media/src/lib/image/transforms/insertImageFromFiles.ts b/packages/media/src/lib/image/transforms/insertImageFromFiles.ts index 3f2b1dec84..45c2160b86 100644 --- a/packages/media/src/lib/image/transforms/insertImageFromFiles.ts +++ b/packages/media/src/lib/image/transforms/insertImageFromFiles.ts @@ -1,6 +1,6 @@ import type { InsertNodesOptions, SlateEditor } from '@udecode/plate-common'; -import { ImagePlugin } from '../../../react'; +import { BaseImagePlugin } from '../BaseImagePlugin'; import { insertImage } from './insertImage'; export const insertImageFromFiles = ( @@ -18,7 +18,7 @@ export const insertImageFromFiles = ( return; } - const uploadImage = editor.getOptions(ImagePlugin).uploadImage; + const uploadImage = editor.getOptions(BaseImagePlugin).uploadImage; const uploadedUrl = uploadImage ? await uploadImage(reader.result) diff --git a/packages/media/src/lib/image/withImageEmbed.spec.tsx b/packages/media/src/lib/image/withImageEmbed.spec.tsx index 11f7bda11d..31316e543a 100644 --- a/packages/media/src/lib/image/withImageEmbed.spec.tsx +++ b/packages/media/src/lib/image/withImageEmbed.spec.tsx @@ -4,7 +4,7 @@ import { getEditorPlugin } from '@udecode/plate-common'; import { createSlateEditor } from '@udecode/plate-common'; import { jsx } from '@udecode/plate-test-utils'; -import { ImagePlugin } from '../../react'; +import { BaseImagePlugin } from './BaseImagePlugin'; import { withImageEmbed } from './withImageEmbed'; jsx; @@ -27,7 +27,10 @@ describe('withImageEmbed', () => { it('should insert image from the text', () => { const editor = withImageEmbed( - getEditorPlugin(createSlateEditor({ editor: input }), ImagePlugin as any) + getEditorPlugin( + createSlateEditor({ editor: input }), + BaseImagePlugin as any + ) ); const data = { diff --git a/packages/media/src/lib/image/withImageUpload.spec.tsx b/packages/media/src/lib/image/withImageUpload.spec.tsx index 7576bc0d33..0d2eb8135e 100644 --- a/packages/media/src/lib/image/withImageUpload.spec.tsx +++ b/packages/media/src/lib/image/withImageUpload.spec.tsx @@ -2,8 +2,8 @@ import { createPlateEditor } from '@udecode/plate-common/react'; import { jsx } from '@udecode/plate-test-utils'; -import { ImagePlugin } from '../../react'; +import { BaseImagePlugin } from './BaseImagePlugin'; jsx; @@ -24,7 +24,7 @@ describe('withImageUpload', () => { it('should insert image from the file(s)', () => { const editor = createPlateEditor({ editor: input, - plugins: [ImagePlugin], + plugins: [BaseImagePlugin], }); const data = { @@ -59,7 +59,7 @@ describe('withImageUpload', () => { const editor = createPlateEditor({ editor: input, - plugins: [ImagePlugin], + plugins: [BaseImagePlugin], }); const data = { @@ -87,7 +87,7 @@ describe('withImageUpload', () => { it('should insert image from the file(s)', () => { const editor = createPlateEditor({ editor: input, - plugins: [ImagePlugin], + plugins: [BaseImagePlugin], }); const data = { diff --git a/packages/media/src/lib/image/withImageUpload.ts b/packages/media/src/lib/image/withImageUpload.ts index 61c46bc645..58d6c38d62 100644 --- a/packages/media/src/lib/image/withImageUpload.ts +++ b/packages/media/src/lib/image/withImageUpload.ts @@ -6,7 +6,7 @@ import { import type { ImageConfig } from './BaseImagePlugin'; -import { ImagePlugin } from '../../react'; +import { insertImageFromFiles } from './transforms'; /** * Allows for pasting images from clipboard. Not yet: dragging and dropping @@ -39,7 +39,7 @@ export const withImageUpload: ExtendEditor = ({ return insertData(dataTransfer); } - editor.getTransforms(ImagePlugin).insert.imageFromFiles(files); + insertImageFromFiles(editor, files); } else { return insertData(dataTransfer); } From 1a6eecdeec1789c47235912f217447728fd05990 Mon Sep 17 00:00:00 2001 From: Felix Feng Date: Mon, 4 Nov 2024 20:14:18 +0800 Subject: [PATCH 19/25] test --- .../media/src/lib/image/transforms/index.ts | 2 +- packages/media/src/lib/media/index.ts | 2 +- .../react/placeholder/PlaceholderPlugin.tsx | 84 +- packages/media/src/react/placeholder/index.ts | 1 + .../react/placeholder/internal/application.ts | 2654 +++++++++++++++++ .../src/react/placeholder/internal/audio.ts | 154 + .../src/react/placeholder/internal/image.ts | 342 +++ .../src/react/placeholder/internal/mimes.ts | 32 + .../src/react/placeholder/internal/misc.ts | 199 ++ .../src/react/placeholder/internal/text.ts | 204 ++ .../src/react/placeholder/internal/utils.ts | 90 + .../src/react/placeholder/internal/video.ts | 166 ++ .../placeholder/transforms/insertMedia.ts | 33 +- packages/media/src/react/placeholder/type.ts | 34 + .../placeholder/utils/createUploadError.ts | 22 + .../placeholder/utils/fileSizeToBytes.spec.ts | 66 + .../placeholder/utils/fileSizeToBytes.ts | 38 + .../placeholder/utils/getFileExtension.ts | 19 - .../react/placeholder/utils/getMediaType.ts | 14 + .../utils/getMediaTypeByFileName.ts | 65 - .../utils/groupFilesByType.spec.ts | 90 + .../placeholder/utils/groupFilesByType.ts | 26 + .../src/react/placeholder/utils/index.ts | 8 +- .../placeholder/utils/matchFileType.spec.ts | 51 + .../react/placeholder/utils/matchFileType.ts | 48 + .../react/placeholder/utils/parseFileSize.ts | 17 - .../utils/validateFileItem.spec.ts | 70 + .../placeholder/utils/validateFileItem.ts | 30 + .../react/placeholder/utils/validateFiles.ts | 108 +- 29 files changed, 4414 insertions(+), 255 deletions(-) create mode 100644 packages/media/src/react/placeholder/internal/application.ts create mode 100644 packages/media/src/react/placeholder/internal/audio.ts create mode 100644 packages/media/src/react/placeholder/internal/image.ts create mode 100644 packages/media/src/react/placeholder/internal/mimes.ts create mode 100644 packages/media/src/react/placeholder/internal/misc.ts create mode 100644 packages/media/src/react/placeholder/internal/text.ts create mode 100644 packages/media/src/react/placeholder/internal/utils.ts create mode 100644 packages/media/src/react/placeholder/internal/video.ts create mode 100644 packages/media/src/react/placeholder/type.ts create mode 100644 packages/media/src/react/placeholder/utils/createUploadError.ts create mode 100644 packages/media/src/react/placeholder/utils/fileSizeToBytes.spec.ts create mode 100644 packages/media/src/react/placeholder/utils/fileSizeToBytes.ts delete mode 100644 packages/media/src/react/placeholder/utils/getFileExtension.ts create mode 100644 packages/media/src/react/placeholder/utils/getMediaType.ts delete mode 100644 packages/media/src/react/placeholder/utils/getMediaTypeByFileName.ts create mode 100644 packages/media/src/react/placeholder/utils/groupFilesByType.spec.ts create mode 100644 packages/media/src/react/placeholder/utils/groupFilesByType.ts create mode 100644 packages/media/src/react/placeholder/utils/matchFileType.spec.ts create mode 100644 packages/media/src/react/placeholder/utils/matchFileType.ts delete mode 100644 packages/media/src/react/placeholder/utils/parseFileSize.ts create mode 100644 packages/media/src/react/placeholder/utils/validateFileItem.spec.ts create mode 100644 packages/media/src/react/placeholder/utils/validateFileItem.ts diff --git a/packages/media/src/lib/image/transforms/index.ts b/packages/media/src/lib/image/transforms/index.ts index cfa5d0c32b..c50b0acd9d 100644 --- a/packages/media/src/lib/image/transforms/index.ts +++ b/packages/media/src/lib/image/transforms/index.ts @@ -3,4 +3,4 @@ */ export * from './insertImage'; -export * from './insertImageFromFiles'; \ No newline at end of file +export * from './insertImageFromFiles'; diff --git a/packages/media/src/lib/media/index.ts b/packages/media/src/lib/media/index.ts index 7f9a061e57..4a95d1b952 100644 --- a/packages/media/src/lib/media/index.ts +++ b/packages/media/src/lib/media/index.ts @@ -4,4 +4,4 @@ export * from './insertMedia'; export * from './parseMediaUrl'; -export type * from './types'; +export * from './types'; diff --git a/packages/media/src/react/placeholder/PlaceholderPlugin.tsx b/packages/media/src/react/placeholder/PlaceholderPlugin.tsx index c1b092ddca..a78529a4b0 100644 --- a/packages/media/src/react/placeholder/PlaceholderPlugin.tsx +++ b/packages/media/src/react/placeholder/PlaceholderPlugin.tsx @@ -1,31 +1,13 @@ import { type ExtendConfig, bindFirst } from '@udecode/plate-common'; import { findEventRange, toTPlatePlugin } from '@udecode/plate-common/react'; +import type { AllowedFileType } from './internal/mimes'; +import type { MediaItemConfig, UploadErrorCode } from './type'; + import { type PlaceholderConfig, BasePlaceholderPlugin } from '../../lib'; import { AudioPlugin, FilePlugin, ImagePlugin, VideoPlugin } from '../plugins'; import { insertMedia } from './transforms/insertMedia'; -export type MediaType = 'audio' | 'file' | 'image' | 'video'; - -export type MediaKeys = - | typeof AudioPlugin.key - | typeof FilePlugin.key - | typeof ImagePlugin.key - | typeof VideoPlugin.key; - -export type MediaItemConfig = { - // The type of media that this config is for. - mediaType: MediaKeys; - // extensions that are accepted for this media type - accept?: string[]; - // The maximum number of files of this type that can be uploaded. - maxFileCount?: number; - // The maximum file size for a file of this type. FileSize is a string that can be parsed as a number followed by a unit of measurement (B, KB, MB, or GB) - maxFileSize?: string; - // The minimum number of files of this type that must be uploaded. - minFileCount?: number; -}; - export type PlaceholderApi = { addUploadingFile: (id: string, file: File) => void; getUploadingFile: (id: string) => File | undefined; @@ -36,55 +18,69 @@ export type PlaceholderTransforms = { insertMedia: (files: FileList) => void; }; -export type MediaConfig = Partial>; +export type UploadError = { + code: UploadErrorCode; + data: { invalidateFiles: File[] }; +}; + +export type uploadConfig = Partial>; export const PlaceholderPlugin = toTPlatePlugin< ExtendConfig< PlaceholderConfig, { - mediaConfig: MediaConfig; + uploadConfig: uploadConfig; uploadingFiles: Record; // Whether multiple files of the same type can be uploaded. multiple?: boolean; - uploadErrorMessage?: string | null; + uploadCode?: string | null; + uploadError?: UploadError; uploadMaxFileCount?: number; }, { placeholder: PlaceholderApi } > >(BasePlaceholderPlugin, { options: { - mediaConfig: { + multiple: true, + uploadCode: null, + uploadConfig: { audio: { - accept: ['.mp3'], maxFileCount: 1, maxFileSize: '8MB', mediaType: AudioPlugin.key, minFileCount: 1, }, - file: { - accept: ['.pdf', '.txt'], + blob: { maxFileCount: 1, - maxFileSize: '8MB', + maxFileSize: '256MB', mediaType: FilePlugin.key, minFileCount: 1, }, image: { - accept: ['.png', '.jpg', '.jpeg'], maxFileCount: 1, maxFileSize: '2MB', mediaType: ImagePlugin.key, minFileCount: 1, }, + pdf: { + maxFileCount: 1, + maxFileSize: '8MB', + mediaType: FilePlugin.key, + minFileCount: 1, + }, + text: { + maxFileCount: 1, + maxFileSize: '256MB', + mediaType: FilePlugin.key, + minFileCount: 1, + }, video: { - accept: ['.mp4'], maxFileCount: 1, maxFileSize: '256MB', mediaType: VideoPlugin.key, minFileCount: 1, }, }, - multiple: true, - uploadErrorMessage: null, uploadMaxFileCount: 5, uploadingFiles: {}, }, @@ -103,21 +99,21 @@ export const PlaceholderPlugin = toTPlatePlugin< [id]: file, }); }, - getMediaConfig: (mediaType: MediaKeys) => { - const config = getOption('mediaConfig'); + // getMediaConfig: (mediaType: MediaKeys) => { + // const config = getOption('mediaConfig'); - const keys = Object.keys(config); + // const keys = Object.keys(config); - for (const key of keys) { - const item = config[key as MediaType]; + // for (const key of keys) { + // const item = config[key as AllowedFileType]; - if (item?.mediaType === mediaType) { - return item; - } - } + // if (item?.mediaType === mediaType) { + // return item; + // } + // } - return null; - }, + // return null; + // }, getUploadingFile: (id: string) => { const uploadingFiles = getOption('uploadingFiles'); diff --git a/packages/media/src/react/placeholder/index.ts b/packages/media/src/react/placeholder/index.ts index 8a48475757..9370b312cb 100644 --- a/packages/media/src/react/placeholder/index.ts +++ b/packages/media/src/react/placeholder/index.ts @@ -4,6 +4,7 @@ export * from './PlaceholderPlugin'; export * from './placeholderStore'; +export * from './type'; export * from './usePlaceholderElement'; export * from './usePlaceholderPopover'; export * from './transforms/index'; diff --git a/packages/media/src/react/placeholder/internal/application.ts b/packages/media/src/react/placeholder/internal/application.ts new file mode 100644 index 0000000000..b10a7469c6 --- /dev/null +++ b/packages/media/src/react/placeholder/internal/application.ts @@ -0,0 +1,2654 @@ +/* eslint-disable unicorn/text-encoding-identifier-case */ +export const application = { + 'application/andrew-inset': { + extensions: ['ez'], + source: 'iana', + }, + 'application/applixware': { + extensions: ['aw'], + source: 'apache', + }, + 'application/atom+xml': { + extensions: ['atom'], + source: 'iana', + }, + 'application/atomcat+xml': { + extensions: ['atomcat'], + source: 'iana', + }, + 'application/atomdeleted+xml': { + extensions: ['atomdeleted'], + source: 'iana', + }, + 'application/atomsvc+xml': { + extensions: ['atomsvc'], + source: 'iana', + }, + 'application/atsc-dwd+xml': { + extensions: ['dwd'], + source: 'iana', + }, + 'application/atsc-held+xml': { + extensions: ['held'], + source: 'iana', + }, + 'application/atsc-rsat+xml': { + extensions: ['rsat'], + source: 'iana', + }, + 'application/calendar+xml': { + extensions: ['xcs'], + source: 'iana', + }, + 'application/ccxml+xml': { + extensions: ['ccxml'], + source: 'iana', + }, + 'application/cdfx+xml': { + extensions: ['cdfx'], + source: 'iana', + }, + 'application/cdmi-capability': { + extensions: ['cdmia'], + source: 'iana', + }, + 'application/cdmi-container': { + extensions: ['cdmic'], + source: 'iana', + }, + 'application/cdmi-domain': { + extensions: ['cdmid'], + source: 'iana', + }, + 'application/cdmi-object': { + extensions: ['cdmio'], + source: 'iana', + }, + 'application/cdmi-queue': { + extensions: ['cdmiq'], + source: 'iana', + }, + 'application/cpl+xml': { + extensions: ['cpl'], + source: 'iana', + }, + 'application/cu-seeme': { + extensions: ['cu'], + source: 'apache', + }, + 'application/dash+xml': { + extensions: ['mpd'], + source: 'iana', + }, + 'application/dash-patch+xml': { + extensions: ['mpp'], + source: 'iana', + }, + 'application/davmount+xml': { + extensions: ['davmount'], + source: 'iana', + }, + 'application/dicom': { + extensions: ['dcm'], + source: 'iana', + }, + 'application/docbook+xml': { + extensions: ['dbk'], + source: 'apache', + }, + 'application/dssc+der': { + extensions: ['dssc'], + source: 'iana', + }, + 'application/dssc+xml': { + extensions: ['xdssc'], + source: 'iana', + }, + 'application/ecmascript': { + extensions: ['es', 'ecma'], + source: 'iana', + }, + 'application/emma+xml': { + extensions: ['emma'], + source: 'iana', + }, + 'application/emotionml+xml': { + extensions: ['emotionml'], + source: 'iana', + }, + 'application/epub+zip': { + extensions: ['epub'], + source: 'iana', + }, + 'application/exi': { + extensions: ['exi'], + source: 'iana', + }, + 'application/express': { + extensions: ['exp'], + source: 'iana', + }, + 'application/fdt+xml': { + extensions: ['fdt'], + source: 'iana', + }, + 'application/font-tdpfr': { + extensions: ['pfr'], + source: 'iana', + }, + 'application/geo+json': { + extensions: ['geojson'], + source: 'iana', + }, + 'application/gml+xml': { + extensions: ['gml'], + source: 'iana', + }, + 'application/gpx+xml': { + extensions: ['gpx'], + source: 'apache', + }, + 'application/gxf': { + extensions: ['gxf'], + source: 'apache', + }, + 'application/gzip': { + extensions: ['gz'], + source: 'iana', + }, + 'application/hyperstudio': { + extensions: ['stk'], + source: 'iana', + }, + 'application/inkml+xml': { + extensions: ['ink', 'inkml'], + source: 'iana', + }, + 'application/ipfix': { + extensions: ['ipfix'], + source: 'iana', + }, + 'application/its+xml': { + extensions: ['its'], + source: 'iana', + }, + 'application/java-archive': { + extensions: ['jar', 'war', 'ear'], + source: 'apache', + }, + 'application/java-serialized-object': { + extensions: ['ser'], + source: 'apache', + }, + 'application/java-vm': { + extensions: ['class'], + source: 'apache', + }, + 'application/javascript': { + charset: 'UTF-8', + extensions: ['js', 'mjs'], + source: 'iana', + }, + 'application/json': { + charset: 'UTF-8', + extensions: ['json', 'map'], + source: 'iana', + }, + 'application/jsonml+json': { + extensions: ['jsonml'], + source: 'apache', + }, + 'application/ld+json': { + extensions: ['jsonld'], + source: 'iana', + }, + 'application/lgr+xml': { + extensions: ['lgr'], + source: 'iana', + }, + 'application/lost+xml': { + extensions: ['lostxml'], + source: 'iana', + }, + 'application/mac-binhex40': { + extensions: ['hqx'], + source: 'iana', + }, + 'application/mac-compactpro': { + extensions: ['cpt'], + source: 'apache', + }, + 'application/mads+xml': { + extensions: ['mads'], + source: 'iana', + }, + 'application/manifest+json': { + charset: 'UTF-8', + extensions: ['webmanifest'], + source: 'iana', + }, + 'application/marc': { + extensions: ['mrc'], + source: 'iana', + }, + 'application/marcxml+xml': { + extensions: ['mrcx'], + source: 'iana', + }, + 'application/mathematica': { + extensions: ['ma', 'nb', 'mb'], + source: 'iana', + }, + 'application/mathml+xml': { + extensions: ['mathml'], + source: 'iana', + }, + 'application/mbox': { + extensions: ['mbox'], + source: 'iana', + }, + 'application/media-policy-dataset+xml': { + extensions: ['mpf'], + source: 'iana', + }, + 'application/mediaservercontrol+xml': { + extensions: ['mscml'], + source: 'iana', + }, + 'application/metalink+xml': { + extensions: ['metalink'], + source: 'apache', + }, + 'application/metalink4+xml': { + extensions: ['meta4'], + source: 'iana', + }, + 'application/mets+xml': { + extensions: ['mets'], + source: 'iana', + }, + 'application/mmt-aei+xml': { + extensions: ['maei'], + source: 'iana', + }, + 'application/mmt-usd+xml': { + extensions: ['musd'], + source: 'iana', + }, + 'application/mods+xml': { + extensions: ['mods'], + source: 'iana', + }, + 'application/mp4': { + extensions: ['mp4s', 'm4p'], + source: 'iana', + }, + 'application/mp21': { + extensions: ['m21', 'mp21'], + source: 'iana', + }, + 'application/msword': { + extensions: ['doc', 'dot'], + source: 'iana', + }, + 'application/mxf': { + extensions: ['mxf'], + source: 'iana', + }, + 'application/n-quads': { + extensions: ['nq'], + source: 'iana', + }, + 'application/n-triples': { + extensions: ['nt'], + source: 'iana', + }, + 'application/node': { + extensions: ['cjs'], + source: 'iana', + }, + 'application/octet-stream': { + extensions: [ + 'bin', + 'dms', + 'lrf', + 'mar', + 'so', + 'dist', + 'distz', + 'pkg', + 'bpk', + 'dump', + 'elc', + 'deploy', + 'exe', + 'dll', + 'deb', + 'dmg', + 'iso', + 'img', + 'msi', + 'msp', + 'msm', + 'buffer', + ], + source: 'iana', + }, + 'application/oda': { + extensions: ['oda'], + source: 'iana', + }, + 'application/oebps-package+xml': { + extensions: ['opf'], + source: 'iana', + }, + 'application/ogg': { + extensions: ['ogx'], + source: 'iana', + }, + 'application/omdoc+xml': { + extensions: ['omdoc'], + source: 'apache', + }, + 'application/onenote': { + extensions: ['onetoc', 'onetoc2', 'onetmp', 'onepkg'], + source: 'apache', + }, + 'application/oxps': { + extensions: ['oxps'], + source: 'iana', + }, + 'application/p2p-overlay+xml': { + extensions: ['relo'], + source: 'iana', + }, + 'application/patch-ops-error+xml': { + extensions: ['xer'], + source: 'iana', + }, + 'application/pdf': { + extensions: ['pdf'], + source: 'iana', + }, + 'application/pgp-encrypted': { + extensions: ['pgp'], + source: 'iana', + }, + 'application/pgp-keys': { + extensions: ['asc'], + source: 'iana', + }, + 'application/pgp-signature': { + extensions: ['asc', 'sig'], + source: 'iana', + }, + 'application/pics-rules': { + extensions: ['prf'], + source: 'apache', + }, + 'application/pkcs7-mime': { + extensions: ['p7m', 'p7c'], + source: 'iana', + }, + 'application/pkcs7-signature': { + extensions: ['p7s'], + source: 'iana', + }, + 'application/pkcs8': { + extensions: ['p8'], + source: 'iana', + }, + 'application/pkcs10': { + extensions: ['p10'], + source: 'iana', + }, + 'application/pkix-attr-cert': { + extensions: ['ac'], + source: 'iana', + }, + 'application/pkix-cert': { + extensions: ['cer'], + source: 'iana', + }, + 'application/pkix-crl': { + extensions: ['crl'], + source: 'iana', + }, + 'application/pkix-pkipath': { + extensions: ['pkipath'], + source: 'iana', + }, + 'application/pkixcmp': { + extensions: ['pki'], + source: 'iana', + }, + 'application/pls+xml': { + extensions: ['pls'], + source: 'iana', + }, + 'application/postscript': { + extensions: ['ai', 'eps', 'ps'], + source: 'iana', + }, + 'application/provenance+xml': { + extensions: ['provx'], + source: 'iana', + }, + 'application/prs.cww': { + extensions: ['cww'], + source: 'iana', + }, + 'application/pskc+xml': { + extensions: ['pskcxml'], + source: 'iana', + }, + 'application/rdf+xml': { + extensions: ['rdf', 'owl'], + source: 'iana', + }, + 'application/reginfo+xml': { + extensions: ['rif'], + source: 'iana', + }, + 'application/relax-ng-compact-syntax': { + extensions: ['rnc'], + source: 'iana', + }, + 'application/resource-lists+xml': { + extensions: ['rl'], + source: 'iana', + }, + 'application/resource-lists-diff+xml': { + extensions: ['rld'], + source: 'iana', + }, + 'application/rls-services+xml': { + extensions: ['rs'], + source: 'iana', + }, + 'application/route-apd+xml': { + extensions: ['rapd'], + source: 'iana', + }, + 'application/route-s-tsid+xml': { + extensions: ['sls'], + source: 'iana', + }, + 'application/route-usd+xml': { + extensions: ['rusd'], + source: 'iana', + }, + 'application/rpki-ghostbusters': { + extensions: ['gbr'], + source: 'iana', + }, + 'application/rpki-manifest': { + extensions: ['mft'], + source: 'iana', + }, + 'application/rpki-roa': { + extensions: ['roa'], + source: 'iana', + }, + 'application/rsd+xml': { + extensions: ['rsd'], + source: 'apache', + }, + 'application/rss+xml': { + extensions: ['rss'], + source: 'apache', + }, + 'application/rtf': { + extensions: ['rtf'], + source: 'iana', + }, + 'application/sbml+xml': { + extensions: ['sbml'], + source: 'iana', + }, + 'application/scvp-cv-request': { + extensions: ['scq'], + source: 'iana', + }, + 'application/scvp-cv-response': { + extensions: ['scs'], + source: 'iana', + }, + 'application/scvp-vp-request': { + extensions: ['spq'], + source: 'iana', + }, + 'application/scvp-vp-response': { + extensions: ['spp'], + source: 'iana', + }, + 'application/sdp': { + extensions: ['sdp'], + source: 'iana', + }, + 'application/senml+xml': { + extensions: ['senmlx'], + source: 'iana', + }, + 'application/sensml+xml': { + extensions: ['sensmlx'], + source: 'iana', + }, + 'application/set-payment-initiation': { + extensions: ['setpay'], + source: 'iana', + }, + 'application/set-registration-initiation': { + extensions: ['setreg'], + source: 'iana', + }, + 'application/shf+xml': { + extensions: ['shf'], + source: 'iana', + }, + 'application/sieve': { + extensions: ['siv', 'sieve'], + source: 'iana', + }, + 'application/smil+xml': { + extensions: ['smi', 'smil'], + source: 'iana', + }, + 'application/sparql-query': { + extensions: ['rq'], + source: 'iana', + }, + 'application/sparql-results+xml': { + extensions: ['srx'], + source: 'iana', + }, + 'application/srgs': { + extensions: ['gram'], + source: 'iana', + }, + 'application/srgs+xml': { + extensions: ['grxml'], + source: 'iana', + }, + 'application/sru+xml': { + extensions: ['sru'], + source: 'iana', + }, + 'application/ssdl+xml': { + extensions: ['ssdl'], + source: 'apache', + }, + 'application/ssml+xml': { + extensions: ['ssml'], + source: 'iana', + }, + 'application/swid+xml': { + extensions: ['swidtag'], + source: 'iana', + }, + 'application/tei+xml': { + extensions: ['tei', 'teicorpus'], + source: 'iana', + }, + 'application/thraud+xml': { + extensions: ['tfi'], + source: 'iana', + }, + 'application/timestamped-data': { + extensions: ['tsd'], + source: 'iana', + }, + 'application/trig': { + extensions: ['trig'], + source: 'iana', + }, + 'application/ttml+xml': { + extensions: ['ttml'], + source: 'iana', + }, + 'application/urc-ressheet+xml': { + extensions: ['rsheet'], + source: 'iana', + }, + 'application/urc-targetdesc+xml': { + extensions: ['td'], + source: 'iana', + }, + 'application/vnd.3gpp.pic-bw-large': { + extensions: ['plb'], + source: 'iana', + }, + 'application/vnd.3gpp.pic-bw-small': { + extensions: ['psb'], + source: 'iana', + }, + 'application/vnd.3gpp.pic-bw-var': { + extensions: ['pvb'], + source: 'iana', + }, + 'application/vnd.3gpp2.tcap': { + extensions: ['tcap'], + source: 'iana', + }, + 'application/vnd.3m.post-it-notes': { + extensions: ['pwn'], + source: 'iana', + }, + 'application/vnd.1000minds.decision-model+xml': { + extensions: ['1km'], + source: 'iana', + }, + 'application/vnd.accpac.simply.aso': { + extensions: ['aso'], + source: 'iana', + }, + 'application/vnd.accpac.simply.imp': { + extensions: ['imp'], + source: 'iana', + }, + 'application/vnd.acucobol': { + extensions: ['acu'], + source: 'iana', + }, + 'application/vnd.acucorp': { + extensions: ['atc', 'acutc'], + source: 'iana', + }, + 'application/vnd.adobe.air-application-installer-package+zip': { + extensions: ['air'], + source: 'apache', + }, + 'application/vnd.adobe.formscentral.fcdt': { + extensions: ['fcdt'], + source: 'iana', + }, + 'application/vnd.adobe.fxp': { + extensions: ['fxp', 'fxpl'], + source: 'iana', + }, + 'application/vnd.adobe.xdp+xml': { + extensions: ['xdp'], + source: 'iana', + }, + 'application/vnd.adobe.xfdf': { + extensions: ['xfdf'], + source: 'iana', + }, + 'application/vnd.age': { + extensions: ['age'], + source: 'iana', + }, + 'application/vnd.ahead.space': { + extensions: ['ahead'], + source: 'iana', + }, + 'application/vnd.airzip.filesecure.azf': { + extensions: ['azf'], + source: 'iana', + }, + 'application/vnd.airzip.filesecure.azs': { + extensions: ['azs'], + source: 'iana', + }, + 'application/vnd.amazon.ebook': { + extensions: ['azw'], + source: 'apache', + }, + 'application/vnd.americandynamics.acc': { + extensions: ['acc'], + source: 'iana', + }, + 'application/vnd.amiga.ami': { + extensions: ['ami'], + source: 'iana', + }, + 'application/vnd.android.package-archive': { + extensions: ['apk'], + source: 'apache', + }, + 'application/vnd.anser-web-certificate-issue-initiation': { + extensions: ['cii'], + source: 'iana', + }, + 'application/vnd.anser-web-funds-transfer-initiation': { + extensions: ['fti'], + source: 'apache', + }, + 'application/vnd.antix.game-component': { + extensions: ['atx'], + source: 'iana', + }, + 'application/vnd.apple.installer+xml': { + extensions: ['mpkg'], + source: 'iana', + }, + 'application/vnd.apple.keynote': { + extensions: ['key'], + source: 'iana', + }, + 'application/vnd.apple.mpegurl': { + extensions: ['m3u8'], + source: 'iana', + }, + 'application/vnd.apple.numbers': { + extensions: ['numbers'], + source: 'iana', + }, + 'application/vnd.apple.pages': { + extensions: ['pages'], + source: 'iana', + }, + 'application/vnd.aristanetworks.swi': { + extensions: ['swi'], + source: 'iana', + }, + 'application/vnd.astraea-software.iota': { + extensions: ['iota'], + source: 'iana', + }, + 'application/vnd.audiograph': { + extensions: ['aep'], + source: 'iana', + }, + 'application/vnd.balsamiq.bmml+xml': { + extensions: ['bmml'], + source: 'iana', + }, + 'application/vnd.blueice.multipass': { + extensions: ['mpm'], + source: 'iana', + }, + 'application/vnd.bmi': { + extensions: ['bmi'], + source: 'iana', + }, + 'application/vnd.businessobjects': { + extensions: ['rep'], + source: 'iana', + }, + 'application/vnd.chemdraw+xml': { + extensions: ['cdxml'], + source: 'iana', + }, + 'application/vnd.chipnuts.karaoke-mmd': { + extensions: ['mmd'], + source: 'iana', + }, + 'application/vnd.cinderella': { + extensions: ['cdy'], + source: 'iana', + }, + 'application/vnd.citationstyles.style+xml': { + extensions: ['csl'], + source: 'iana', + }, + 'application/vnd.claymore': { + extensions: ['cla'], + source: 'iana', + }, + 'application/vnd.cloanto.rp9': { + extensions: ['rp9'], + source: 'iana', + }, + 'application/vnd.clonk.c4group': { + extensions: ['c4g', 'c4d', 'c4f', 'c4p', 'c4u'], + source: 'iana', + }, + 'application/vnd.cluetrust.cartomobile-config': { + extensions: ['c11amc'], + source: 'iana', + }, + 'application/vnd.cluetrust.cartomobile-config-pkg': { + extensions: ['c11amz'], + source: 'iana', + }, + 'application/vnd.commonspace': { + extensions: ['csp'], + source: 'iana', + }, + 'application/vnd.contact.cmsg': { + extensions: ['cdbcmsg'], + source: 'iana', + }, + 'application/vnd.cosmocaller': { + extensions: ['cmc'], + source: 'iana', + }, + 'application/vnd.crick.clicker': { + extensions: ['clkx'], + source: 'iana', + }, + 'application/vnd.crick.clicker.keyboard': { + extensions: ['clkk'], + source: 'iana', + }, + 'application/vnd.crick.clicker.palette': { + extensions: ['clkp'], + source: 'iana', + }, + 'application/vnd.crick.clicker.template': { + extensions: ['clkt'], + source: 'iana', + }, + 'application/vnd.crick.clicker.wordbank': { + extensions: ['clkw'], + source: 'iana', + }, + 'application/vnd.criticaltools.wbs+xml': { + extensions: ['wbs'], + source: 'iana', + }, + 'application/vnd.ctc-posml': { + extensions: ['pml'], + source: 'iana', + }, + 'application/vnd.cups-ppd': { + extensions: ['ppd'], + source: 'iana', + }, + 'application/vnd.curl.car': { + extensions: ['car'], + source: 'apache', + }, + 'application/vnd.curl.pcurl': { + extensions: ['pcurl'], + source: 'apache', + }, + 'application/vnd.dart': { + extensions: ['dart'], + source: 'iana', + }, + 'application/vnd.data-vision.rdz': { + extensions: ['rdz'], + source: 'iana', + }, + 'application/vnd.dbf': { + extensions: ['dbf'], + source: 'iana', + }, + 'application/vnd.dece.data': { + extensions: ['uvf', 'uvvf', 'uvd', 'uvvd'], + source: 'iana', + }, + 'application/vnd.dece.ttml+xml': { + extensions: ['uvt', 'uvvt'], + source: 'iana', + }, + 'application/vnd.dece.unspecified': { + extensions: ['uvx', 'uvvx'], + source: 'iana', + }, + 'application/vnd.dece.zip': { + extensions: ['uvz', 'uvvz'], + source: 'iana', + }, + 'application/vnd.denovo.fcselayout-link': { + extensions: ['fe_launch'], + source: 'iana', + }, + 'application/vnd.dna': { + extensions: ['dna'], + source: 'iana', + }, + 'application/vnd.dolby.mlp': { + extensions: ['mlp'], + source: 'apache', + }, + 'application/vnd.dpgraph': { + extensions: ['dpg'], + source: 'iana', + }, + 'application/vnd.dreamfactory': { + extensions: ['dfac'], + source: 'iana', + }, + 'application/vnd.ds-keypoint': { + extensions: ['kpxx'], + source: 'apache', + }, + 'application/vnd.dvb.ait': { + extensions: ['ait'], + source: 'iana', + }, + 'application/vnd.dvb.service': { + extensions: ['svc'], + source: 'iana', + }, + 'application/vnd.dynageo': { + extensions: ['geo'], + source: 'iana', + }, + 'application/vnd.ecowin.chart': { + extensions: ['mag'], + source: 'iana', + }, + 'application/vnd.enliven': { + extensions: ['nml'], + source: 'iana', + }, + 'application/vnd.epson.esf': { + extensions: ['esf'], + source: 'iana', + }, + 'application/vnd.epson.msf': { + extensions: ['msf'], + source: 'iana', + }, + 'application/vnd.epson.quickanime': { + extensions: ['qam'], + source: 'iana', + }, + 'application/vnd.epson.salt': { + extensions: ['slt'], + source: 'iana', + }, + 'application/vnd.epson.ssf': { + extensions: ['ssf'], + source: 'iana', + }, + 'application/vnd.eszigno3+xml': { + extensions: ['es3', 'et3'], + source: 'iana', + }, + 'application/vnd.ezpix-album': { + extensions: ['ez2'], + source: 'iana', + }, + 'application/vnd.ezpix-package': { + extensions: ['ez3'], + source: 'iana', + }, + 'application/vnd.fdf': { + extensions: ['fdf'], + source: 'iana', + }, + 'application/vnd.fdsn.mseed': { + extensions: ['mseed'], + source: 'iana', + }, + 'application/vnd.fdsn.seed': { + extensions: ['seed', 'dataless'], + source: 'iana', + }, + 'application/vnd.flographit': { + extensions: ['gph'], + source: 'iana', + }, + 'application/vnd.fluxtime.clip': { + extensions: ['ftc'], + source: 'iana', + }, + 'application/vnd.framemaker': { + extensions: ['fm', 'frame', 'maker', 'book'], + source: 'iana', + }, + 'application/vnd.frogans.fnc': { + extensions: ['fnc'], + source: 'iana', + }, + 'application/vnd.frogans.ltf': { + extensions: ['ltf'], + source: 'iana', + }, + 'application/vnd.fsc.weblaunch': { + extensions: ['fsc'], + source: 'iana', + }, + 'application/vnd.fujitsu.oasys': { + extensions: ['oas'], + source: 'iana', + }, + 'application/vnd.fujitsu.oasys2': { + extensions: ['oa2'], + source: 'iana', + }, + 'application/vnd.fujitsu.oasys3': { + extensions: ['oa3'], + source: 'iana', + }, + 'application/vnd.fujitsu.oasysgp': { + extensions: ['fg5'], + source: 'iana', + }, + 'application/vnd.fujitsu.oasysprs': { + extensions: ['bh2'], + source: 'iana', + }, + 'application/vnd.fujixerox.ddd': { + extensions: ['ddd'], + source: 'iana', + }, + 'application/vnd.fujixerox.docuworks': { + extensions: ['xdw'], + source: 'iana', + }, + 'application/vnd.fujixerox.docuworks.binder': { + extensions: ['xbd'], + source: 'iana', + }, + 'application/vnd.fuzzysheet': { + extensions: ['fzs'], + source: 'iana', + }, + 'application/vnd.genomatix.tuxedo': { + extensions: ['txd'], + source: 'iana', + }, + 'application/vnd.geogebra.file': { + extensions: ['ggb'], + source: 'iana', + }, + 'application/vnd.geogebra.tool': { + extensions: ['ggt'], + source: 'iana', + }, + 'application/vnd.geometry-explorer': { + extensions: ['gex', 'gre'], + source: 'iana', + }, + 'application/vnd.geonext': { + extensions: ['gxt'], + source: 'iana', + }, + 'application/vnd.geoplan': { + extensions: ['g2w'], + source: 'iana', + }, + 'application/vnd.geospace': { + extensions: ['g3w'], + source: 'iana', + }, + 'application/vnd.gmx': { + extensions: ['gmx'], + source: 'iana', + }, + 'application/vnd.google-earth.kml+xml': { + extensions: ['kml'], + source: 'iana', + }, + 'application/vnd.google-earth.kmz': { + extensions: ['kmz'], + source: 'iana', + }, + 'application/vnd.grafeq': { + extensions: ['gqf', 'gqs'], + source: 'iana', + }, + 'application/vnd.groove-account': { + extensions: ['gac'], + source: 'iana', + }, + 'application/vnd.groove-help': { + extensions: ['ghf'], + source: 'iana', + }, + 'application/vnd.groove-identity-message': { + extensions: ['gim'], + source: 'iana', + }, + 'application/vnd.groove-injector': { + extensions: ['grv'], + source: 'iana', + }, + 'application/vnd.groove-tool-message': { + extensions: ['gtm'], + source: 'iana', + }, + 'application/vnd.groove-tool-template': { + extensions: ['tpl'], + source: 'iana', + }, + 'application/vnd.groove-vcard': { + extensions: ['vcg'], + source: 'iana', + }, + 'application/vnd.hal+xml': { + extensions: ['hal'], + source: 'iana', + }, + 'application/vnd.handheld-entertainment+xml': { + extensions: ['zmm'], + source: 'iana', + }, + 'application/vnd.hbci': { + extensions: ['hbci'], + source: 'iana', + }, + 'application/vnd.hhe.lesson-player': { + extensions: ['les'], + source: 'iana', + }, + 'application/vnd.hp-hpgl': { + extensions: ['hpgl'], + source: 'iana', + }, + 'application/vnd.hp-hpid': { + extensions: ['hpid'], + source: 'iana', + }, + 'application/vnd.hp-hps': { + extensions: ['hps'], + source: 'iana', + }, + 'application/vnd.hp-jlyt': { + extensions: ['jlt'], + source: 'iana', + }, + 'application/vnd.hp-pcl': { + extensions: ['pcl'], + source: 'iana', + }, + 'application/vnd.hp-pclxl': { + extensions: ['pclxl'], + source: 'iana', + }, + 'application/vnd.hydrostatix.sof-data': { + extensions: ['sfd-hdstx'], + source: 'iana', + }, + 'application/vnd.ibm.minipay': { + extensions: ['mpy'], + source: 'iana', + }, + 'application/vnd.ibm.modcap': { + extensions: ['afp', 'listafp', 'list3820'], + source: 'iana', + }, + 'application/vnd.ibm.rights-management': { + extensions: ['irm'], + source: 'iana', + }, + 'application/vnd.ibm.secure-container': { + extensions: ['sc'], + source: 'iana', + }, + 'application/vnd.iccprofile': { + extensions: ['icc', 'icm'], + source: 'iana', + }, + 'application/vnd.igloader': { + extensions: ['igl'], + source: 'iana', + }, + 'application/vnd.immervision-ivp': { + extensions: ['ivp'], + source: 'iana', + }, + 'application/vnd.immervision-ivu': { + extensions: ['ivu'], + source: 'iana', + }, + 'application/vnd.insors.igm': { + extensions: ['igm'], + source: 'iana', + }, + 'application/vnd.intercon.formnet': { + extensions: ['xpw', 'xpx'], + source: 'iana', + }, + 'application/vnd.intergeo': { + extensions: ['i2g'], + source: 'iana', + }, + 'application/vnd.intu.qbo': { + extensions: ['qbo'], + source: 'iana', + }, + 'application/vnd.intu.qfx': { + extensions: ['qfx'], + source: 'iana', + }, + 'application/vnd.ipunplugged.rcprofile': { + extensions: ['rcprofile'], + source: 'iana', + }, + 'application/vnd.irepository.package+xml': { + extensions: ['irp'], + source: 'iana', + }, + 'application/vnd.is-xpr': { + extensions: ['xpr'], + source: 'iana', + }, + 'application/vnd.isac.fcs': { + extensions: ['fcs'], + source: 'iana', + }, + 'application/vnd.jam': { + extensions: ['jam'], + source: 'iana', + }, + 'application/vnd.jcp.javame.midlet-rms': { + extensions: ['rms'], + source: 'iana', + }, + 'application/vnd.jisp': { + extensions: ['jisp'], + source: 'iana', + }, + 'application/vnd.joost.joda-archive': { + extensions: ['joda'], + source: 'iana', + }, + 'application/vnd.kahootz': { + extensions: ['ktz', 'ktr'], + source: 'iana', + }, + 'application/vnd.kde.karbon': { + extensions: ['karbon'], + source: 'iana', + }, + 'application/vnd.kde.kchart': { + extensions: ['chrt'], + source: 'iana', + }, + 'application/vnd.kde.kformula': { + extensions: ['kfo'], + source: 'iana', + }, + 'application/vnd.kde.kivio': { + extensions: ['flw'], + source: 'iana', + }, + 'application/vnd.kde.kontour': { + extensions: ['kon'], + source: 'iana', + }, + 'application/vnd.kde.kpresenter': { + extensions: ['kpr', 'kpt'], + source: 'iana', + }, + 'application/vnd.kde.kspread': { + extensions: ['ksp'], + source: 'iana', + }, + 'application/vnd.kde.kword': { + extensions: ['kwd', 'kwt'], + source: 'iana', + }, + 'application/vnd.kenameaapp': { + extensions: ['htke'], + source: 'iana', + }, + 'application/vnd.kidspiration': { + extensions: ['kia'], + source: 'iana', + }, + 'application/vnd.kinar': { + extensions: ['kne', 'knp'], + source: 'iana', + }, + 'application/vnd.koan': { + extensions: ['skp', 'skd', 'skt', 'skm'], + source: 'iana', + }, + 'application/vnd.kodak-descriptor': { + extensions: ['sse'], + source: 'iana', + }, + 'application/vnd.las.las+xml': { + extensions: ['lasxml'], + source: 'iana', + }, + 'application/vnd.llamagraphics.life-balance.desktop': { + extensions: ['lbd'], + source: 'iana', + }, + 'application/vnd.llamagraphics.life-balance.exchange+xml': { + extensions: ['lbe'], + source: 'iana', + }, + 'application/vnd.lotus-1-2-3': { + extensions: ['123'], + source: 'iana', + }, + 'application/vnd.lotus-approach': { + extensions: ['apr'], + source: 'iana', + }, + 'application/vnd.lotus-freelance': { + extensions: ['pre'], + source: 'iana', + }, + 'application/vnd.lotus-notes': { + extensions: ['nsf'], + source: 'iana', + }, + 'application/vnd.lotus-organizer': { + extensions: ['org'], + source: 'iana', + }, + 'application/vnd.lotus-screencam': { + extensions: ['scm'], + source: 'iana', + }, + 'application/vnd.lotus-wordpro': { + extensions: ['lwp'], + source: 'iana', + }, + 'application/vnd.macports.portpkg': { + extensions: ['portpkg'], + source: 'iana', + }, + 'application/vnd.mapbox-vector-tile': { + extensions: ['mvt'], + source: 'iana', + }, + 'application/vnd.mcd': { + extensions: ['mcd'], + source: 'iana', + }, + 'application/vnd.medcalcdata': { + extensions: ['mc1'], + source: 'iana', + }, + 'application/vnd.mediastation.cdkey': { + extensions: ['cdkey'], + source: 'iana', + }, + 'application/vnd.mfer': { + extensions: ['mwf'], + source: 'iana', + }, + 'application/vnd.mfmp': { + extensions: ['mfm'], + source: 'iana', + }, + 'application/vnd.micrografx.flo': { + extensions: ['flo'], + source: 'iana', + }, + 'application/vnd.micrografx.igx': { + extensions: ['igx'], + source: 'iana', + }, + 'application/vnd.mif': { + extensions: ['mif'], + source: 'iana', + }, + 'application/vnd.mobius.daf': { + extensions: ['daf'], + source: 'iana', + }, + 'application/vnd.mobius.dis': { + extensions: ['dis'], + source: 'iana', + }, + 'application/vnd.mobius.mbk': { + extensions: ['mbk'], + source: 'iana', + }, + 'application/vnd.mobius.mqy': { + extensions: ['mqy'], + source: 'iana', + }, + 'application/vnd.mobius.msl': { + extensions: ['msl'], + source: 'iana', + }, + 'application/vnd.mobius.plc': { + extensions: ['plc'], + source: 'iana', + }, + 'application/vnd.mobius.txf': { + extensions: ['txf'], + source: 'iana', + }, + 'application/vnd.mophun.application': { + extensions: ['mpn'], + source: 'iana', + }, + 'application/vnd.mophun.certificate': { + extensions: ['mpc'], + source: 'iana', + }, + 'application/vnd.mozilla.xul+xml': { + extensions: ['xul'], + source: 'iana', + }, + 'application/vnd.ms-artgalry': { + extensions: ['cil'], + source: 'iana', + }, + 'application/vnd.ms-cab-compressed': { + extensions: ['cab'], + source: 'iana', + }, + 'application/vnd.ms-excel': { + extensions: ['xls', 'xlm', 'xla', 'xlc', 'xlt', 'xlw'], + source: 'iana', + }, + 'application/vnd.ms-excel.addin.macroenabled.12': { + extensions: ['xlam'], + source: 'iana', + }, + 'application/vnd.ms-excel.sheet.binary.macroenabled.12': { + extensions: ['xlsb'], + source: 'iana', + }, + 'application/vnd.ms-excel.sheet.macroenabled.12': { + extensions: ['xlsm'], + source: 'iana', + }, + 'application/vnd.ms-excel.template.macroenabled.12': { + extensions: ['xltm'], + source: 'iana', + }, + 'application/vnd.ms-fontobject': { + extensions: ['eot'], + source: 'iana', + }, + 'application/vnd.ms-htmlhelp': { + extensions: ['chm'], + source: 'iana', + }, + 'application/vnd.ms-ims': { + extensions: ['ims'], + source: 'iana', + }, + 'application/vnd.ms-lrm': { + extensions: ['lrm'], + source: 'iana', + }, + 'application/vnd.ms-officetheme': { + extensions: ['thmx'], + source: 'iana', + }, + 'application/vnd.ms-pki.seccat': { + extensions: ['cat'], + source: 'apache', + }, + 'application/vnd.ms-pki.stl': { + extensions: ['stl'], + source: 'apache', + }, + 'application/vnd.ms-powerpoint': { + extensions: ['ppt', 'pps', 'pot'], + source: 'iana', + }, + 'application/vnd.ms-powerpoint.addin.macroenabled.12': { + extensions: ['ppam'], + source: 'iana', + }, + 'application/vnd.ms-powerpoint.presentation.macroenabled.12': { + extensions: ['pptm'], + source: 'iana', + }, + 'application/vnd.ms-powerpoint.slide.macroenabled.12': { + extensions: ['sldm'], + source: 'iana', + }, + 'application/vnd.ms-powerpoint.slideshow.macroenabled.12': { + extensions: ['ppsm'], + source: 'iana', + }, + 'application/vnd.ms-powerpoint.template.macroenabled.12': { + extensions: ['potm'], + source: 'iana', + }, + 'application/vnd.ms-project': { + extensions: ['mpp', 'mpt'], + source: 'iana', + }, + 'application/vnd.ms-word.document.macroenabled.12': { + extensions: ['docm'], + source: 'iana', + }, + 'application/vnd.ms-word.template.macroenabled.12': { + extensions: ['dotm'], + source: 'iana', + }, + 'application/vnd.ms-works': { + extensions: ['wps', 'wks', 'wcm', 'wdb'], + source: 'iana', + }, + 'application/vnd.ms-wpl': { + extensions: ['wpl'], + source: 'iana', + }, + 'application/vnd.ms-xpsdocument': { + extensions: ['xps'], + source: 'iana', + }, + 'application/vnd.mseq': { + extensions: ['mseq'], + source: 'iana', + }, + 'application/vnd.musician': { + extensions: ['mus'], + source: 'iana', + }, + 'application/vnd.muvee.style': { + extensions: ['msty'], + source: 'iana', + }, + 'application/vnd.mynfc': { + extensions: ['taglet'], + source: 'iana', + }, + 'application/vnd.neurolanguage.nlu': { + extensions: ['nlu'], + source: 'iana', + }, + 'application/vnd.nitf': { + extensions: ['ntf', 'nitf'], + source: 'iana', + }, + 'application/vnd.noblenet-directory': { + extensions: ['nnd'], + source: 'iana', + }, + 'application/vnd.noblenet-sealer': { + extensions: ['nns'], + source: 'iana', + }, + 'application/vnd.noblenet-web': { + extensions: ['nnw'], + source: 'iana', + }, + 'application/vnd.nokia.n-gage.ac+xml': { + extensions: ['ac'], + source: 'iana', + }, + 'application/vnd.nokia.n-gage.data': { + extensions: ['ngdat'], + source: 'iana', + }, + 'application/vnd.nokia.n-gage.symbian.install': { + extensions: ['n-gage'], + source: 'iana', + }, + 'application/vnd.nokia.radio-preset': { + extensions: ['rpst'], + source: 'iana', + }, + 'application/vnd.nokia.radio-presets': { + extensions: ['rpss'], + source: 'iana', + }, + 'application/vnd.novadigm.edm': { + extensions: ['edm'], + source: 'iana', + }, + 'application/vnd.novadigm.edx': { + extensions: ['edx'], + source: 'iana', + }, + 'application/vnd.novadigm.ext': { + extensions: ['ext'], + source: 'iana', + }, + 'application/vnd.oasis.opendocument.chart': { + extensions: ['odc'], + source: 'iana', + }, + 'application/vnd.oasis.opendocument.chart-template': { + extensions: ['otc'], + source: 'iana', + }, + 'application/vnd.oasis.opendocument.database': { + extensions: ['odb'], + source: 'iana', + }, + 'application/vnd.oasis.opendocument.formula': { + extensions: ['odf'], + source: 'iana', + }, + 'application/vnd.oasis.opendocument.formula-template': { + extensions: ['odft'], + source: 'iana', + }, + 'application/vnd.oasis.opendocument.graphics': { + extensions: ['odg'], + source: 'iana', + }, + 'application/vnd.oasis.opendocument.graphics-template': { + extensions: ['otg'], + source: 'iana', + }, + 'application/vnd.oasis.opendocument.image': { + extensions: ['odi'], + source: 'iana', + }, + 'application/vnd.oasis.opendocument.image-template': { + extensions: ['oti'], + source: 'iana', + }, + 'application/vnd.oasis.opendocument.presentation': { + extensions: ['odp'], + source: 'iana', + }, + 'application/vnd.oasis.opendocument.presentation-template': { + extensions: ['otp'], + source: 'iana', + }, + 'application/vnd.oasis.opendocument.spreadsheet': { + extensions: ['ods'], + source: 'iana', + }, + 'application/vnd.oasis.opendocument.spreadsheet-template': { + extensions: ['ots'], + source: 'iana', + }, + 'application/vnd.oasis.opendocument.text': { + extensions: ['odt'], + source: 'iana', + }, + 'application/vnd.oasis.opendocument.text-master': { + extensions: ['odm'], + source: 'iana', + }, + 'application/vnd.oasis.opendocument.text-template': { + extensions: ['ott'], + source: 'iana', + }, + 'application/vnd.oasis.opendocument.text-web': { + extensions: ['oth'], + source: 'iana', + }, + 'application/vnd.olpc-sugar': { + extensions: ['xo'], + source: 'iana', + }, + 'application/vnd.oma.dd2+xml': { + extensions: ['dd2'], + source: 'iana', + }, + 'application/vnd.openblox.game+xml': { + extensions: ['obgx'], + source: 'iana', + }, + 'application/vnd.openofficeorg.extension': { + extensions: ['oxt'], + source: 'apache', + }, + 'application/vnd.openstreetmap.data+xml': { + extensions: ['osm'], + source: 'iana', + }, + 'application/vnd.openxmlformats-officedocument.presentationml.presentation': { + extensions: ['pptx'], + source: 'iana', + }, + 'application/vnd.openxmlformats-officedocument.presentationml.slide': { + extensions: ['sldx'], + source: 'iana', + }, + 'application/vnd.openxmlformats-officedocument.presentationml.slideshow': { + extensions: ['ppsx'], + source: 'iana', + }, + 'application/vnd.openxmlformats-officedocument.presentationml.template': { + extensions: ['potx'], + source: 'iana', + }, + 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet': { + extensions: ['xlsx'], + source: 'iana', + }, + 'application/vnd.openxmlformats-officedocument.spreadsheetml.template': { + extensions: ['xltx'], + source: 'iana', + }, + 'application/vnd.openxmlformats-officedocument.wordprocessingml.document': { + extensions: ['docx'], + source: 'iana', + }, + 'application/vnd.openxmlformats-officedocument.wordprocessingml.template': { + extensions: ['dotx'], + source: 'iana', + }, + 'application/vnd.osgeo.mapguide.package': { + extensions: ['mgp'], + source: 'iana', + }, + 'application/vnd.osgi.dp': { + extensions: ['dp'], + source: 'iana', + }, + 'application/vnd.osgi.subsystem': { + extensions: ['esa'], + source: 'iana', + }, + 'application/vnd.palm': { + extensions: ['pdb', 'pqa', 'oprc'], + source: 'iana', + }, + 'application/vnd.pawaafile': { + extensions: ['paw'], + source: 'iana', + }, + 'application/vnd.pg.format': { + extensions: ['str'], + source: 'iana', + }, + 'application/vnd.pg.osasli': { + extensions: ['ei6'], + source: 'iana', + }, + 'application/vnd.picsel': { + extensions: ['efif'], + source: 'iana', + }, + 'application/vnd.pmi.widget': { + extensions: ['wg'], + source: 'iana', + }, + 'application/vnd.pocketlearn': { + extensions: ['plf'], + source: 'iana', + }, + 'application/vnd.powerbuilder6': { + extensions: ['pbd'], + source: 'iana', + }, + 'application/vnd.previewsystems.box': { + extensions: ['box'], + source: 'iana', + }, + 'application/vnd.proteus.magazine': { + extensions: ['mgz'], + source: 'iana', + }, + 'application/vnd.publishare-delta-tree': { + extensions: ['qps'], + source: 'iana', + }, + 'application/vnd.pvi.ptid1': { + extensions: ['ptid'], + source: 'iana', + }, + 'application/vnd.quark.quarkxpress': { + extensions: ['qxd', 'qxt', 'qwd', 'qwt', 'qxl', 'qxb'], + source: 'iana', + }, + 'application/vnd.rar': { + extensions: ['rar'], + source: 'iana', + }, + 'application/vnd.realvnc.bed': { + extensions: ['bed'], + source: 'iana', + }, + 'application/vnd.recordare.musicxml': { + extensions: ['mxl'], + source: 'iana', + }, + 'application/vnd.recordare.musicxml+xml': { + extensions: ['musicxml'], + source: 'iana', + }, + 'application/vnd.rig.cryptonote': { + extensions: ['cryptonote'], + source: 'iana', + }, + 'application/vnd.rim.cod': { + extensions: ['cod'], + source: 'apache', + }, + 'application/vnd.rn-realmedia': { + extensions: ['rm'], + source: 'apache', + }, + 'application/vnd.rn-realmedia-vbr': { + extensions: ['rmvb'], + source: 'apache', + }, + 'application/vnd.route66.link66+xml': { + extensions: ['link66'], + source: 'iana', + }, + 'application/vnd.sailingtracker.track': { + extensions: ['st'], + source: 'iana', + }, + 'application/vnd.seemail': { + extensions: ['see'], + source: 'iana', + }, + 'application/vnd.sema': { + extensions: ['sema'], + source: 'iana', + }, + 'application/vnd.semd': { + extensions: ['semd'], + source: 'iana', + }, + 'application/vnd.semf': { + extensions: ['semf'], + source: 'iana', + }, + 'application/vnd.shana.informed.formdata': { + extensions: ['ifm'], + source: 'iana', + }, + 'application/vnd.shana.informed.formtemplate': { + extensions: ['itp'], + source: 'iana', + }, + 'application/vnd.shana.informed.interchange': { + extensions: ['iif'], + source: 'iana', + }, + 'application/vnd.shana.informed.package': { + extensions: ['ipk'], + source: 'iana', + }, + 'application/vnd.simtech-mindmapper': { + extensions: ['twd', 'twds'], + source: 'iana', + }, + 'application/vnd.smaf': { + extensions: ['mmf'], + source: 'iana', + }, + 'application/vnd.smart.teacher': { + extensions: ['teacher'], + source: 'iana', + }, + 'application/vnd.software602.filler.form+xml': { + extensions: ['fo'], + source: 'iana', + }, + 'application/vnd.solent.sdkm+xml': { + extensions: ['sdkm', 'sdkd'], + source: 'iana', + }, + 'application/vnd.spotfire.dxp': { + extensions: ['dxp'], + source: 'iana', + }, + 'application/vnd.spotfire.sfs': { + extensions: ['sfs'], + source: 'iana', + }, + 'application/vnd.stardivision.calc': { + extensions: ['sdc'], + source: 'apache', + }, + 'application/vnd.stardivision.draw': { + extensions: ['sda'], + source: 'apache', + }, + 'application/vnd.stardivision.impress': { + extensions: ['sdd'], + source: 'apache', + }, + 'application/vnd.stardivision.math': { + extensions: ['smf'], + source: 'apache', + }, + 'application/vnd.stardivision.writer': { + extensions: ['sdw', 'vor'], + source: 'apache', + }, + 'application/vnd.stardivision.writer-global': { + extensions: ['sgl'], + source: 'apache', + }, + 'application/vnd.stepmania.package': { + extensions: ['smzip'], + source: 'iana', + }, + 'application/vnd.stepmania.stepchart': { + extensions: ['sm'], + source: 'iana', + }, + 'application/vnd.sun.wadl+xml': { + extensions: ['wadl'], + source: 'iana', + }, + 'application/vnd.sun.xml.calc': { + extensions: ['sxc'], + source: 'apache', + }, + 'application/vnd.sun.xml.calc.template': { + extensions: ['stc'], + source: 'apache', + }, + 'application/vnd.sun.xml.draw': { + extensions: ['sxd'], + source: 'apache', + }, + 'application/vnd.sun.xml.draw.template': { + extensions: ['std'], + source: 'apache', + }, + 'application/vnd.sun.xml.impress': { + extensions: ['sxi'], + source: 'apache', + }, + 'application/vnd.sun.xml.impress.template': { + extensions: ['sti'], + source: 'apache', + }, + 'application/vnd.sun.xml.math': { + extensions: ['sxm'], + source: 'apache', + }, + 'application/vnd.sun.xml.writer': { + extensions: ['sxw'], + source: 'apache', + }, + 'application/vnd.sun.xml.writer.global': { + extensions: ['sxg'], + source: 'apache', + }, + 'application/vnd.sun.xml.writer.template': { + extensions: ['stw'], + source: 'apache', + }, + 'application/vnd.sus-calendar': { + extensions: ['sus', 'susp'], + source: 'iana', + }, + 'application/vnd.svd': { + extensions: ['svd'], + source: 'iana', + }, + 'application/vnd.symbian.install': { + extensions: ['sis', 'sisx'], + source: 'apache', + }, + 'application/vnd.syncml+xml': { + charset: 'UTF-8', + extensions: ['xsm'], + source: 'iana', + }, + 'application/vnd.syncml.dm+wbxml': { + charset: 'UTF-8', + extensions: ['bdm'], + source: 'iana', + }, + 'application/vnd.syncml.dm+xml': { + charset: 'UTF-8', + extensions: ['xdm'], + source: 'iana', + }, + 'application/vnd.syncml.dmddf+xml': { + charset: 'UTF-8', + extensions: ['ddf'], + source: 'iana', + }, + 'application/vnd.tao.intent-module-archive': { + extensions: ['tao'], + source: 'iana', + }, + 'application/vnd.tcpdump.pcap': { + extensions: ['pcap', 'cap', 'dmp'], + source: 'iana', + }, + 'application/vnd.tmobile-livetv': { + extensions: ['tmo'], + source: 'iana', + }, + 'application/vnd.trid.tpt': { + extensions: ['tpt'], + source: 'iana', + }, + 'application/vnd.triscape.mxs': { + extensions: ['mxs'], + source: 'iana', + }, + 'application/vnd.trueapp': { + extensions: ['tra'], + source: 'iana', + }, + 'application/vnd.ufdl': { + extensions: ['ufd', 'ufdl'], + source: 'iana', + }, + 'application/vnd.uiq.theme': { + extensions: ['utz'], + source: 'iana', + }, + 'application/vnd.umajin': { + extensions: ['umj'], + source: 'iana', + }, + 'application/vnd.unity': { + extensions: ['unityweb'], + source: 'iana', + }, + 'application/vnd.uoml+xml': { + extensions: ['uoml'], + source: 'iana', + }, + 'application/vnd.vcx': { + extensions: ['vcx'], + source: 'iana', + }, + 'application/vnd.visio': { + extensions: ['vsd', 'vst', 'vss', 'vsw'], + source: 'iana', + }, + 'application/vnd.visionary': { + extensions: ['vis'], + source: 'iana', + }, + 'application/vnd.vsf': { + extensions: ['vsf'], + source: 'iana', + }, + 'application/vnd.wap.wbxml': { + charset: 'UTF-8', + extensions: ['wbxml'], + source: 'iana', + }, + 'application/vnd.wap.wmlc': { + extensions: ['wmlc'], + source: 'iana', + }, + 'application/vnd.wap.wmlscriptc': { + extensions: ['wmlsc'], + source: 'iana', + }, + 'application/vnd.webturbo': { + extensions: ['wtb'], + source: 'iana', + }, + 'application/vnd.wolfram.player': { + extensions: ['nbp'], + source: 'iana', + }, + 'application/vnd.wordperfect': { + extensions: ['wpd'], + source: 'iana', + }, + 'application/vnd.wqd': { + extensions: ['wqd'], + source: 'iana', + }, + 'application/vnd.wt.stf': { + extensions: ['stf'], + source: 'iana', + }, + 'application/vnd.xara': { + extensions: ['xar'], + source: 'iana', + }, + 'application/vnd.xfdl': { + extensions: ['xfdl'], + source: 'iana', + }, + 'application/vnd.yamaha.hv-dic': { + extensions: ['hvd'], + source: 'iana', + }, + 'application/vnd.yamaha.hv-script': { + extensions: ['hvs'], + source: 'iana', + }, + 'application/vnd.yamaha.hv-voice': { + extensions: ['hvp'], + source: 'iana', + }, + 'application/vnd.yamaha.openscoreformat': { + extensions: ['osf'], + source: 'iana', + }, + 'application/vnd.yamaha.openscoreformat.osfpvg+xml': { + extensions: ['osfpvg'], + source: 'iana', + }, + 'application/vnd.yamaha.smaf-audio': { + extensions: ['saf'], + source: 'iana', + }, + 'application/vnd.yamaha.smaf-phrase': { + extensions: ['spf'], + source: 'iana', + }, + 'application/vnd.yellowriver-custom-menu': { + extensions: ['cmp'], + source: 'iana', + }, + 'application/vnd.zul': { + extensions: ['zir', 'zirz'], + source: 'iana', + }, + 'application/vnd.zzazz.deck+xml': { + extensions: ['zaz'], + source: 'iana', + }, + 'application/voicexml+xml': { + extensions: ['vxml'], + source: 'iana', + }, + 'application/wasm': { + extensions: ['wasm'], + source: 'iana', + }, + 'application/watcherinfo+xml': { + extensions: ['wif'], + source: 'iana', + }, + 'application/widget': { + extensions: ['wgt'], + source: 'iana', + }, + 'application/winhlp': { + extensions: ['hlp'], + source: 'apache', + }, + 'application/wsdl+xml': { + extensions: ['wsdl'], + source: 'iana', + }, + 'application/wspolicy+xml': { + extensions: ['wspolicy'], + source: 'iana', + }, + 'application/x-7z-compressed': { + extensions: ['7z'], + source: 'apache', + }, + 'application/x-abiword': { + extensions: ['abw'], + source: 'apache', + }, + 'application/x-ace-compressed': { + extensions: ['ace'], + source: 'apache', + }, + 'application/x-apple-diskimage': { + extensions: ['dmg'], + source: 'apache', + }, + 'application/x-authorware-bin': { + extensions: ['aab', 'x32', 'u32', 'vox'], + source: 'apache', + }, + 'application/x-authorware-map': { + extensions: ['aam'], + source: 'apache', + }, + 'application/x-authorware-seg': { + extensions: ['aas'], + source: 'apache', + }, + 'application/x-bcpio': { + extensions: ['bcpio'], + source: 'apache', + }, + 'application/x-bittorrent': { + extensions: ['torrent'], + source: 'apache', + }, + 'application/x-blorb': { + extensions: ['blb', 'blorb'], + source: 'apache', + }, + 'application/x-bzip': { + extensions: ['bz'], + source: 'apache', + }, + 'application/x-bzip2': { + extensions: ['bz2', 'boz'], + source: 'apache', + }, + 'application/x-cbr': { + extensions: ['cbr', 'cba', 'cbt', 'cbz', 'cb7'], + source: 'apache', + }, + 'application/x-cdlink': { + extensions: ['vcd'], + source: 'apache', + }, + 'application/x-cfs-compressed': { + extensions: ['cfs'], + source: 'apache', + }, + 'application/x-chat': { + extensions: ['chat'], + source: 'apache', + }, + 'application/x-chess-pgn': { + extensions: ['pgn'], + source: 'apache', + }, + 'application/x-cocoa': { + extensions: ['cco'], + source: 'nginx', + }, + 'application/x-conference': { + extensions: ['nsc'], + source: 'apache', + }, + 'application/x-cpio': { + extensions: ['cpio'], + source: 'apache', + }, + 'application/x-csh': { + extensions: ['csh'], + source: 'apache', + }, + 'application/x-debian-package': { + extensions: ['deb', 'udeb'], + source: 'apache', + }, + 'application/x-dgc-compressed': { + extensions: ['dgc'], + source: 'apache', + }, + 'application/x-director': { + extensions: ['dir', 'dcr', 'dxr', 'cst', 'cct', 'cxt', 'w3d', 'fgd', 'swa'], + source: 'apache', + }, + 'application/x-doom': { + extensions: ['wad'], + source: 'apache', + }, + 'application/x-dtbncx+xml': { + extensions: ['ncx'], + source: 'apache', + }, + 'application/x-dtbook+xml': { + extensions: ['dtb'], + source: 'apache', + }, + 'application/x-dtbresource+xml': { + extensions: ['res'], + source: 'apache', + }, + 'application/x-dvi': { + extensions: ['dvi'], + source: 'apache', + }, + 'application/x-envoy': { + extensions: ['evy'], + source: 'apache', + }, + 'application/x-eva': { + extensions: ['eva'], + source: 'apache', + }, + 'application/x-font-bdf': { + extensions: ['bdf'], + source: 'apache', + }, + 'application/x-font-ghostscript': { + extensions: ['gsf'], + source: 'apache', + }, + 'application/x-font-linux-psf': { + extensions: ['psf'], + source: 'apache', + }, + 'application/x-font-pcf': { + extensions: ['pcf'], + source: 'apache', + }, + 'application/x-font-snf': { + extensions: ['snf'], + source: 'apache', + }, + 'application/x-font-type1': { + extensions: ['pfa', 'pfb', 'pfm', 'afm'], + source: 'apache', + }, + 'application/x-freearc': { + extensions: ['arc'], + source: 'apache', + }, + 'application/x-futuresplash': { + extensions: ['spl'], + source: 'apache', + }, + 'application/x-gca-compressed': { + extensions: ['gca'], + source: 'apache', + }, + 'application/x-glulx': { + extensions: ['ulx'], + source: 'apache', + }, + 'application/x-gnumeric': { + extensions: ['gnumeric'], + source: 'apache', + }, + 'application/x-gramps-xml': { + extensions: ['gramps'], + source: 'apache', + }, + 'application/x-gtar': { + extensions: ['gtar'], + source: 'apache', + }, + 'application/x-hdf': { + extensions: ['hdf'], + source: 'apache', + }, + 'application/x-install-instructions': { + extensions: ['install'], + source: 'apache', + }, + 'application/x-iso9660-image': { + extensions: ['iso'], + source: 'apache', + }, + 'application/x-java-archive-diff': { + extensions: ['jardiff'], + source: 'nginx', + }, + 'application/x-java-jnlp-file': { + extensions: ['jnlp'], + source: 'apache', + }, + 'application/x-latex': { + extensions: ['latex'], + source: 'apache', + }, + 'application/x-lzh-compressed': { + extensions: ['lzh', 'lha'], + source: 'apache', + }, + 'application/x-makeself': { + extensions: ['run'], + source: 'nginx', + }, + 'application/x-mie': { + extensions: ['mie'], + source: 'apache', + }, + 'application/x-mobipocket-ebook': { + extensions: ['prc', 'mobi'], + source: 'apache', + }, + 'application/x-ms-application': { + extensions: ['application'], + source: 'apache', + }, + 'application/x-ms-shortcut': { + extensions: ['lnk'], + source: 'apache', + }, + 'application/x-ms-wmd': { + extensions: ['wmd'], + source: 'apache', + }, + 'application/x-ms-wmz': { + extensions: ['wmz'], + source: 'apache', + }, + 'application/x-ms-xbap': { + extensions: ['xbap'], + source: 'apache', + }, + 'application/x-msaccess': { + extensions: ['mdb'], + source: 'apache', + }, + 'application/x-msbinder': { + extensions: ['obd'], + source: 'apache', + }, + 'application/x-mscardfile': { + extensions: ['crd'], + source: 'apache', + }, + 'application/x-msclip': { + extensions: ['clp'], + source: 'apache', + }, + 'application/x-msdownload': { + extensions: ['exe', 'dll', 'com', 'bat', 'msi'], + source: 'apache', + }, + 'application/x-msmediaview': { + extensions: ['mvb', 'm13', 'm14'], + source: 'apache', + }, + 'application/x-msmetafile': { + extensions: ['wmf', 'wmz', 'emf', 'emz'], + source: 'apache', + }, + 'application/x-msmoney': { + extensions: ['mny'], + source: 'apache', + }, + 'application/x-mspublisher': { + extensions: ['pub'], + source: 'apache', + }, + 'application/x-msschedule': { + extensions: ['scd'], + source: 'apache', + }, + 'application/x-msterminal': { + extensions: ['trm'], + source: 'apache', + }, + 'application/x-mswrite': { + extensions: ['wri'], + source: 'apache', + }, + 'application/x-netcdf': { + extensions: ['nc', 'cdf'], + source: 'apache', + }, + 'application/x-nzb': { + extensions: ['nzb'], + source: 'apache', + }, + 'application/x-perl': { + extensions: ['pl', 'pm'], + source: 'nginx', + }, + 'application/x-pilot': { + extensions: ['prc', 'pdb'], + source: 'nginx', + }, + 'application/x-pkcs7-certificates': { + extensions: ['p7b', 'spc'], + source: 'apache', + }, + 'application/x-pkcs7-certreqresp': { + extensions: ['p7r'], + source: 'apache', + }, + 'application/x-pkcs12': { + extensions: ['p12', 'pfx'], + source: 'apache', + }, + 'application/x-rar-compressed': { + extensions: ['rar'], + source: 'apache', + }, + 'application/x-redhat-package-manager': { + extensions: ['rpm'], + source: 'nginx', + }, + 'application/x-research-info-systems': { + extensions: ['ris'], + source: 'apache', + }, + 'application/x-sea': { + extensions: ['sea'], + source: 'nginx', + }, + 'application/x-sh': { + extensions: ['sh'], + source: 'apache', + }, + 'application/x-shar': { + extensions: ['shar'], + source: 'apache', + }, + 'application/x-shockwave-flash': { + extensions: ['swf'], + source: 'apache', + }, + 'application/x-silverlight-app': { + extensions: ['xap'], + source: 'apache', + }, + 'application/x-sql': { + extensions: ['sql'], + source: 'apache', + }, + 'application/x-stuffit': { + extensions: ['sit'], + source: 'apache', + }, + 'application/x-stuffitx': { + extensions: ['sitx'], + source: 'apache', + }, + 'application/x-subrip': { + extensions: ['srt'], + source: 'apache', + }, + 'application/x-sv4cpio': { + extensions: ['sv4cpio'], + source: 'apache', + }, + 'application/x-sv4crc': { + extensions: ['sv4crc'], + source: 'apache', + }, + 'application/x-t3vm-image': { + extensions: ['t3'], + source: 'apache', + }, + 'application/x-tads': { + extensions: ['gam'], + source: 'apache', + }, + 'application/x-tar': { + extensions: ['tar'], + source: 'apache', + }, + 'application/x-tcl': { + extensions: ['tcl', 'tk'], + source: 'apache', + }, + 'application/x-tex': { + extensions: ['tex'], + source: 'apache', + }, + 'application/x-tex-tfm': { + extensions: ['tfm'], + source: 'apache', + }, + 'application/x-texinfo': { + extensions: ['texinfo', 'texi'], + source: 'apache', + }, + 'application/x-tgif': { + extensions: ['obj'], + source: 'apache', + }, + 'application/x-ustar': { + extensions: ['ustar'], + source: 'apache', + }, + 'application/x-wais-source': { + extensions: ['src'], + source: 'apache', + }, + 'application/x-x509-ca-cert': { + extensions: ['der', 'crt', 'pem'], + source: 'iana', + }, + 'application/x-xfig': { + extensions: ['fig'], + source: 'apache', + }, + 'application/x-xliff+xml': { + extensions: ['xlf'], + source: 'apache', + }, + 'application/x-xpinstall': { + extensions: ['xpi'], + source: 'apache', + }, + 'application/x-xz': { + extensions: ['xz'], + source: 'apache', + }, + 'application/x-zmachine': { + extensions: ['z1', 'z2', 'z3', 'z4', 'z5', 'z6', 'z7', 'z8'], + source: 'apache', + }, + 'application/xaml+xml': { + extensions: ['xaml'], + source: 'apache', + }, + 'application/xcap-att+xml': { + extensions: ['xav'], + source: 'iana', + }, + 'application/xcap-caps+xml': { + extensions: ['xca'], + source: 'iana', + }, + 'application/xcap-diff+xml': { + extensions: ['xdf'], + source: 'iana', + }, + 'application/xcap-el+xml': { + extensions: ['xel'], + source: 'iana', + }, + 'application/xcap-ns+xml': { + extensions: ['xns'], + source: 'iana', + }, + 'application/xenc+xml': { + extensions: ['xenc'], + source: 'iana', + }, + 'application/xhtml+xml': { + extensions: ['xhtml', 'xht'], + source: 'iana', + }, + 'application/xliff+xml': { + extensions: ['xlf'], + source: 'iana', + }, + 'application/xml': { + extensions: ['xml', 'xsl', 'xsd', 'rng'], + source: 'iana', + }, + 'application/xml-dtd': { + extensions: ['dtd'], + source: 'iana', + }, + 'application/xop+xml': { + extensions: ['xop'], + source: 'iana', + }, + 'application/xproc+xml': { + extensions: ['xpl'], + source: 'apache', + }, + 'application/xslt+xml': { + extensions: ['xsl', 'xslt'], + source: 'iana', + }, + 'application/xspf+xml': { + extensions: ['xspf'], + source: 'apache', + }, + 'application/xv+xml': { + extensions: ['mxml', 'xhvml', 'xvml', 'xvm'], + source: 'iana', + }, + 'application/yaml': { + extensions: ['yaml', 'yml'], + source: 'iana', + }, + 'application/yang': { + extensions: ['yang'], + source: 'iana', + }, + 'application/yin+xml': { + extensions: ['yin'], + source: 'iana', + }, + 'application/zip': { + extensions: ['zip'], + source: 'iana', + }, +} as const; diff --git a/packages/media/src/react/placeholder/internal/audio.ts b/packages/media/src/react/placeholder/internal/audio.ts new file mode 100644 index 0000000000..f017c26729 --- /dev/null +++ b/packages/media/src/react/placeholder/internal/audio.ts @@ -0,0 +1,154 @@ +export const audio = { + 'audio/3gpp': { + extensions: ['3gpp'], + source: 'iana', + }, + 'audio/adpcm': { + extensions: ['adp'], + source: 'apache', + }, + 'audio/amr': { + extensions: ['amr'], + source: 'iana', + }, + 'audio/basic': { + extensions: ['au', 'snd'], + source: 'iana', + }, + 'audio/midi': { + extensions: ['mid', 'midi', 'kar', 'rmi'], + source: 'apache', + }, + 'audio/mobile-xmf': { + extensions: ['mxmf'], + source: 'iana', + }, + 'audio/mp4': { + extensions: ['m4a', 'mp4a'], + source: 'iana', + }, + 'audio/mpeg': { + extensions: ['mpga', 'mp2', 'mp2a', 'mp3', 'm2a', 'm3a'], + source: 'iana', + }, + 'audio/ogg': { + extensions: ['oga', 'ogg', 'spx', 'opus'], + source: 'iana', + }, + 'audio/s3m': { + extensions: ['s3m'], + source: 'apache', + }, + 'audio/silk': { + extensions: ['sil'], + source: 'apache', + }, + 'audio/vnd.dece.audio': { + extensions: ['uva', 'uvva'], + source: 'iana', + }, + 'audio/vnd.digital-winds': { + extensions: ['eol'], + source: 'iana', + }, + 'audio/vnd.dra': { + extensions: ['dra'], + source: 'iana', + }, + 'audio/vnd.dts': { + extensions: ['dts'], + source: 'iana', + }, + 'audio/vnd.dts.hd': { + extensions: ['dtshd'], + source: 'iana', + }, + 'audio/vnd.lucent.voice': { + extensions: ['lvp'], + source: 'iana', + }, + 'audio/vnd.ms-playready.media.pya': { + extensions: ['pya'], + source: 'iana', + }, + 'audio/vnd.nuera.ecelp4800': { + extensions: ['ecelp4800'], + source: 'iana', + }, + 'audio/vnd.nuera.ecelp7470': { + extensions: ['ecelp7470'], + source: 'iana', + }, + 'audio/vnd.nuera.ecelp9600': { + extensions: ['ecelp9600'], + source: 'iana', + }, + 'audio/vnd.rip': { + extensions: ['rip'], + source: 'iana', + }, + 'audio/webm': { + extensions: ['weba'], + source: 'apache', + }, + 'audio/x-aac': { + extensions: ['aac'], + source: 'apache', + }, + 'audio/x-aiff': { + extensions: ['aif', 'aiff', 'aifc'], + source: 'apache', + }, + 'audio/x-caf': { + extensions: ['caf'], + source: 'apache', + }, + 'audio/x-flac': { + extensions: ['flac'], + source: 'apache', + }, + 'audio/x-gsm': { + extensions: ['gsm'], + source: 'apache', + }, + 'audio/x-m4a': { + extensions: ['m4a'], + source: 'nginx', + }, + 'audio/x-matroska': { + extensions: ['mka'], + source: 'apache', + }, + 'audio/x-mpegurl': { + extensions: ['m3u'], + source: 'apache', + }, + 'audio/x-ms-wax': { + extensions: ['wax'], + source: 'apache', + }, + 'audio/x-ms-wma': { + extensions: ['wma'], + source: 'apache', + }, + 'audio/x-pn-realaudio': { + extensions: ['ram', 'ra'], + source: 'apache', + }, + 'audio/x-pn-realaudio-plugin': { + extensions: ['rmp'], + source: 'apache', + }, + 'audio/x-realaudio': { + extensions: ['ra'], + source: 'nginx', + }, + 'audio/x-wav': { + extensions: ['wav'], + source: 'apache', + }, + 'audio/xm': { + extensions: ['xm'], + source: 'apache', + }, +} as const; diff --git a/packages/media/src/react/placeholder/internal/image.ts b/packages/media/src/react/placeholder/internal/image.ts new file mode 100644 index 0000000000..a2b3e69a49 --- /dev/null +++ b/packages/media/src/react/placeholder/internal/image.ts @@ -0,0 +1,342 @@ +export const image = { + 'image/aces': { + extensions: ['exr'], + source: 'iana', + }, + 'image/avci': { + extensions: ['avci'], + source: 'iana', + }, + 'image/avcs': { + extensions: ['avcs'], + source: 'iana', + }, + 'image/avif': { + extensions: ['avif'], + source: 'iana', + }, + 'image/bmp': { + extensions: ['bmp'], + source: 'iana', + }, + 'image/cgm': { + extensions: ['cgm'], + source: 'iana', + }, + 'image/dicom-rle': { + extensions: ['drle'], + source: 'iana', + }, + 'image/emf': { + extensions: ['emf'], + source: 'iana', + }, + 'image/fits': { + extensions: ['fits'], + source: 'iana', + }, + 'image/g3fax': { + extensions: ['g3'], + source: 'iana', + }, + 'image/gif': { + extensions: ['gif'], + source: 'iana', + }, + 'image/heic': { + extensions: ['heic'], + source: 'iana', + }, + 'image/heic-sequence': { + extensions: ['heics'], + source: 'iana', + }, + 'image/heif': { + extensions: ['heif'], + source: 'iana', + }, + 'image/heif-sequence': { + extensions: ['heifs'], + source: 'iana', + }, + 'image/hej2k': { + extensions: ['hej2'], + source: 'iana', + }, + 'image/hsj2': { + extensions: ['hsj2'], + source: 'iana', + }, + 'image/ief': { + extensions: ['ief'], + source: 'iana', + }, + 'image/jls': { + extensions: ['jls'], + source: 'iana', + }, + 'image/jp2': { + extensions: ['jp2', 'jpg2'], + source: 'iana', + }, + 'image/jpeg': { + extensions: ['jpeg', 'jpg', 'jpe', 'jfif', 'pjpeg', 'pjp'], + source: 'iana', + }, + 'image/jph': { + extensions: ['jph'], + source: 'iana', + }, + 'image/jphc': { + extensions: ['jhc'], + source: 'iana', + }, + 'image/jpm': { + extensions: ['jpm'], + source: 'iana', + }, + 'image/jpx': { + extensions: ['jpx', 'jpf'], + source: 'iana', + }, + 'image/jxr': { + extensions: ['jxr'], + source: 'iana', + }, + 'image/jxra': { + extensions: ['jxra'], + source: 'iana', + }, + 'image/jxrs': { + extensions: ['jxrs'], + source: 'iana', + }, + 'image/jxs': { + extensions: ['jxs'], + source: 'iana', + }, + 'image/jxsc': { + extensions: ['jxsc'], + source: 'iana', + }, + 'image/jxsi': { + extensions: ['jxsi'], + source: 'iana', + }, + 'image/jxss': { + extensions: ['jxss'], + source: 'iana', + }, + 'image/ktx': { + extensions: ['ktx'], + source: 'iana', + }, + 'image/ktx2': { + extensions: ['ktx2'], + source: 'iana', + }, + 'image/png': { + extensions: ['png'], + source: 'iana', + }, + 'image/prs.btif': { + extensions: ['btif'], + source: 'iana', + }, + 'image/prs.pti': { + extensions: ['pti'], + source: 'iana', + }, + 'image/sgi': { + extensions: ['sgi'], + source: 'apache', + }, + 'image/svg+xml': { + extensions: ['svg', 'svgz'], + source: 'iana', + }, + 'image/t38': { + extensions: ['t38'], + source: 'iana', + }, + 'image/tiff': { + extensions: ['tif', 'tiff'], + source: 'iana', + }, + 'image/tiff-fx': { + extensions: ['tfx'], + source: 'iana', + }, + 'image/vnd.adobe.photoshop': { + extensions: ['psd'], + source: 'iana', + }, + 'image/vnd.airzip.accelerator.azv': { + extensions: ['azv'], + source: 'iana', + }, + 'image/vnd.dece.graphic': { + extensions: ['uvi', 'uvvi', 'uvg', 'uvvg'], + source: 'iana', + }, + 'image/vnd.djvu': { + extensions: ['djvu', 'djv'], + source: 'iana', + }, + 'image/vnd.dvb.subtitle': { + extensions: ['sub'], + source: 'iana', + }, + 'image/vnd.dwg': { + extensions: ['dwg'], + source: 'iana', + }, + 'image/vnd.dxf': { + extensions: ['dxf'], + source: 'iana', + }, + 'image/vnd.fastbidsheet': { + extensions: ['fbs'], + source: 'iana', + }, + 'image/vnd.fpx': { + extensions: ['fpx'], + source: 'iana', + }, + 'image/vnd.fst': { + extensions: ['fst'], + source: 'iana', + }, + 'image/vnd.fujixerox.edmics-mmr': { + extensions: ['mmr'], + source: 'iana', + }, + 'image/vnd.fujixerox.edmics-rlc': { + extensions: ['rlc'], + source: 'iana', + }, + 'image/vnd.microsoft.icon': { + extensions: ['ico'], + source: 'iana', + }, + 'image/vnd.ms-modi': { + extensions: ['mdi'], + source: 'iana', + }, + 'image/vnd.ms-photo': { + extensions: ['wdp'], + source: 'apache', + }, + 'image/vnd.net-fpx': { + extensions: ['npx'], + source: 'iana', + }, + 'image/vnd.pco.b16': { + extensions: ['b16'], + source: 'iana', + }, + 'image/vnd.tencent.tap': { + extensions: ['tap'], + source: 'iana', + }, + 'image/vnd.valve.source.texture': { + extensions: ['vtf'], + source: 'iana', + }, + 'image/vnd.wap.wbmp': { + extensions: ['wbmp'], + source: 'iana', + }, + 'image/vnd.xiff': { + extensions: ['xif'], + source: 'iana', + }, + 'image/vnd.zbrush.pcx': { + extensions: ['pcx'], + source: 'iana', + }, + 'image/webp': { + extensions: ['webp'], + source: 'apache', + }, + 'image/wmf': { + extensions: ['wmf'], + source: 'iana', + }, + 'image/x-3ds': { + extensions: ['3ds'], + source: 'apache', + }, + 'image/x-cmu-raster': { + extensions: ['ras'], + source: 'apache', + }, + 'image/x-cmx': { + extensions: ['cmx'], + source: 'apache', + }, + 'image/x-freehand': { + extensions: ['fh', 'fhc', 'fh4', 'fh5', 'fh7'], + source: 'apache', + }, + 'image/x-icon': { + extensions: ['ico'], + source: 'apache', + }, + 'image/x-jng': { + extensions: ['jng'], + source: 'nginx', + }, + 'image/x-mrsid-image': { + extensions: ['sid'], + source: 'apache', + }, + 'image/x-ms-bmp': { + extensions: ['bmp'], + source: 'nginx', + }, + 'image/x-pcx': { + extensions: ['pcx'], + source: 'apache', + }, + 'image/x-pict': { + extensions: ['pic', 'pct'], + source: 'apache', + }, + 'image/x-portable-anymap': { + extensions: ['pnm'], + source: 'apache', + }, + 'image/x-portable-bitmap': { + extensions: ['pbm'], + source: 'apache', + }, + 'image/x-portable-graymap': { + extensions: ['pgm'], + source: 'apache', + }, + 'image/x-portable-pixmap': { + extensions: ['ppm'], + source: 'apache', + }, + 'image/x-rgb': { + extensions: ['rgb'], + source: 'apache', + }, + 'image/x-tga': { + extensions: ['tga'], + source: 'apache', + }, + 'image/x-xbitmap': { + extensions: ['xbm'], + source: 'apache', + }, + 'image/x-xpixmap': { + extensions: ['xpm'], + source: 'apache', + }, + 'image/x-xwindowdump': { + extensions: ['xwd'], + source: 'apache', + }, +} as const; diff --git a/packages/media/src/react/placeholder/internal/mimes.ts b/packages/media/src/react/placeholder/internal/mimes.ts new file mode 100644 index 0000000000..9f1c1695c9 --- /dev/null +++ b/packages/media/src/react/placeholder/internal/mimes.ts @@ -0,0 +1,32 @@ +import { application } from '../internal/application'; +import { audio } from '../internal/audio'; +import { image } from '../internal/image'; +import { misc } from '../internal/misc'; +import { video } from '../internal/video'; +import { text } from './text'; + +export const mimes = { + ...application, + ...audio, + ...image, + ...text, + ...video, + ...misc, +}; + +export type MimeType = keyof typeof mimes; + +export type FileExtension = (typeof mimes)[MimeType]['extensions'][number]; + +export const ALLOWED_FILE_TYPES = [ + 'image', + 'video', + 'audio', + 'pdf', + 'text', + 'blob', +] as const; + +export type AllowedFileType = (typeof ALLOWED_FILE_TYPES)[number]; + +export type FileRouterInputKey = AllowedFileType | MimeType; diff --git a/packages/media/src/react/placeholder/internal/misc.ts b/packages/media/src/react/placeholder/internal/misc.ts new file mode 100644 index 0000000000..2d8f15bbc5 --- /dev/null +++ b/packages/media/src/react/placeholder/internal/misc.ts @@ -0,0 +1,199 @@ +/** Random types not worthy of their own file */ +export const misc = { + 'chemical/x-cdx': { + extensions: ['cdx'], + source: 'apache', + }, + 'chemical/x-cif': { + extensions: ['cif'], + source: 'apache', + }, + 'chemical/x-cmdf': { + extensions: ['cmdf'], + source: 'apache', + }, + 'chemical/x-cml': { + extensions: ['cml'], + source: 'apache', + }, + 'chemical/x-csml': { + extensions: ['csml'], + source: 'apache', + }, + 'chemical/x-xyz': { + extensions: ['xyz'], + source: 'apache', + }, + 'font/collection': { + extensions: ['ttc'], + source: 'iana', + }, + 'font/otf': { + extensions: ['otf'], + source: 'iana', + }, + 'font/ttf': { + extensions: ['ttf'], + source: 'iana', + }, + 'font/woff': { + extensions: ['woff'], + source: 'iana', + }, + 'font/woff2': { + extensions: ['woff2'], + source: 'iana', + }, + 'message/disposition-notification': { + extensions: ['disposition-notification'], + source: 'iana', + }, + 'message/global': { + extensions: ['u8msg'], + source: 'iana', + }, + 'message/global-delivery-status': { + extensions: ['u8dsn'], + source: 'iana', + }, + 'message/global-disposition-notification': { + extensions: ['u8mdn'], + source: 'iana', + }, + 'message/global-headers': { + extensions: ['u8hdr'], + source: 'iana', + }, + 'message/rfc822': { + extensions: ['eml', 'mime'], + source: 'iana', + }, + 'message/vnd.wfa.wsc': { + extensions: ['wsc'], + source: 'iana', + }, + 'model/3mf': { + extensions: ['3mf'], + source: 'iana', + }, + 'model/gltf+json': { + extensions: ['gltf'], + source: 'iana', + }, + 'model/gltf-binary': { + extensions: ['glb'], + source: 'iana', + }, + 'model/iges': { + extensions: ['igs', 'iges'], + source: 'iana', + }, + 'model/mesh': { + extensions: ['msh', 'mesh', 'silo'], + source: 'iana', + }, + 'model/mtl': { + extensions: ['mtl'], + source: 'iana', + }, + 'model/obj': { + extensions: ['obj'], + source: 'iana', + }, + 'model/step': { + extensions: ['.p21', '.stp', '.step', '.stpnc', '.210'], + source: 'iana', + }, + 'model/step+xml': { + extensions: ['stpx'], + source: 'iana', + }, + 'model/step+zip': { + extensions: ['stpz'], + source: 'iana', + }, + 'model/step-xml+zip': { + extensions: ['stpxz'], + source: 'iana', + }, + 'model/stl': { + extensions: ['stl'], + source: 'iana', + }, + 'model/vnd.collada+xml': { + extensions: ['dae'], + source: 'iana', + }, + 'model/vnd.dwf': { + extensions: ['dwf'], + source: 'iana', + }, + 'model/vnd.gdl': { + extensions: ['gdl'], + source: 'iana', + }, + 'model/vnd.gtw': { + extensions: ['gtw'], + source: 'iana', + }, + 'model/vnd.mts': { + extensions: ['mts'], + source: 'iana', + }, + 'model/vnd.opengex': { + extensions: ['ogex'], + source: 'iana', + }, + 'model/vnd.parasolid.transmit.binary': { + extensions: ['x_b'], + source: 'iana', + }, + 'model/vnd.parasolid.transmit.text': { + extensions: ['x_t'], + source: 'iana', + }, + 'model/vnd.sap.vds': { + extensions: ['vds'], + source: 'iana', + }, + 'model/vnd.usdz+zip': { + extensions: ['usdz'], + source: 'iana', + }, + 'model/vnd.valve.source.compiled-map': { + extensions: ['bsp'], + source: 'iana', + }, + 'model/vnd.vtu': { + extensions: ['vtu'], + source: 'iana', + }, + 'model/vrml': { + extensions: ['wrl', 'vrml'], + source: 'iana', + }, + 'model/x3d+binary': { + extensions: ['x3db', 'x3dbz'], + source: 'apache', + }, + 'model/x3d+fastinfoset': { + extensions: ['x3db'], + source: 'iana', + }, + 'model/x3d+vrml': { + extensions: ['x3dv', 'x3dvz'], + source: 'apache', + }, + 'model/x3d+xml': { + extensions: ['x3d', 'x3dz'], + source: 'iana', + }, + 'model/x3d-vrml': { + extensions: ['x3dv'], + source: 'iana', + }, + 'x-conference/x-cooltalk': { + extensions: ['ice'], + source: 'apache', + }, +} as const; diff --git a/packages/media/src/react/placeholder/internal/text.ts b/packages/media/src/react/placeholder/internal/text.ts new file mode 100644 index 0000000000..bb1c17a185 --- /dev/null +++ b/packages/media/src/react/placeholder/internal/text.ts @@ -0,0 +1,204 @@ +/* eslint-disable unicorn/text-encoding-identifier-case */ +export const text = { + 'text/cache-manifest': { + extensions: ['appcache', 'manifest'], + source: 'iana', + }, + 'text/calendar': { + extensions: ['ics', 'ifb'], + source: 'iana', + }, + 'text/css': { + charset: 'UTF-8', + extensions: ['css'], + source: 'iana', + }, + 'text/csv': { + extensions: ['csv'], + source: 'iana', + }, + 'text/html': { + extensions: ['html', 'htm', 'shtml'], + source: 'iana', + }, + 'text/markdown': { + extensions: ['markdown', 'md'], + source: 'iana', + }, + 'text/mathml': { + extensions: ['mml'], + source: 'nginx', + }, + 'text/n3': { + charset: 'UTF-8', + extensions: ['n3'], + source: 'iana', + }, + 'text/plain': { + extensions: ['txt', 'text', 'conf', 'def', 'list', 'log', 'in', 'ini'], + source: 'iana', + }, + 'text/prs.lines.tag': { + extensions: ['dsc'], + source: 'iana', + }, + 'text/richtext': { + extensions: ['rtx'], + source: 'iana', + }, + 'text/rtf': { + extensions: ['rtf'], + source: 'iana', + }, + 'text/sgml': { + extensions: ['sgml', 'sgm'], + source: 'iana', + }, + 'text/shex': { + extensions: ['shex'], + source: 'iana', + }, + 'text/spdx': { + extensions: ['spdx'], + source: 'iana', + }, + 'text/tab-separated-values': { + extensions: ['tsv'], + source: 'iana', + }, + 'text/troff': { + extensions: ['t', 'tr', 'roff', 'man', 'me', 'ms'], + source: 'iana', + }, + 'text/turtle': { + charset: 'UTF-8', + extensions: ['ttl'], + source: 'iana', + }, + 'text/uri-list': { + extensions: ['uri', 'uris', 'urls'], + source: 'iana', + }, + 'text/vcard': { + extensions: ['vcard'], + source: 'iana', + }, + 'text/vnd.curl': { + extensions: ['curl'], + source: 'iana', + }, + 'text/vnd.curl.dcurl': { + extensions: ['dcurl'], + source: 'apache', + }, + 'text/vnd.curl.mcurl': { + extensions: ['mcurl'], + source: 'apache', + }, + 'text/vnd.curl.scurl': { + extensions: ['scurl'], + source: 'apache', + }, + 'text/vnd.dvb.subtitle': { + extensions: ['sub'], + source: 'iana', + }, + 'text/vnd.familysearch.gedcom': { + extensions: ['ged'], + source: 'iana', + }, + 'text/vnd.fly': { + extensions: ['fly'], + source: 'iana', + }, + 'text/vnd.fmi.flexstor': { + extensions: ['flx'], + source: 'iana', + }, + 'text/vnd.graphviz': { + extensions: ['gv'], + source: 'iana', + }, + 'text/vnd.in3d.3dml': { + extensions: ['3dml'], + source: 'iana', + }, + 'text/vnd.in3d.spot': { + extensions: ['spot'], + source: 'iana', + }, + 'text/vnd.sun.j2me.app-descriptor': { + charset: 'UTF-8', + extensions: ['jad'], + source: 'iana', + }, + 'text/vnd.wap.wml': { + extensions: ['wml'], + source: 'iana', + }, + 'text/vnd.wap.wmlscript': { + extensions: ['wmls'], + source: 'iana', + }, + 'text/vtt': { + charset: 'UTF-8', + extensions: ['vtt'], + source: 'iana', + }, + 'text/x-asm': { + extensions: ['s', 'asm'], + source: 'apache', + }, + 'text/x-c': { + extensions: ['c', 'cc', 'cxx', 'cpp', 'h', 'hh', 'dic'], + source: 'apache', + }, + 'text/x-component': { + extensions: ['htc'], + source: 'nginx', + }, + 'text/x-fortran': { + extensions: ['f', 'for', 'f77', 'f90'], + source: 'apache', + }, + 'text/x-java-source': { + extensions: ['java'], + source: 'apache', + }, + 'text/x-nfo': { + extensions: ['nfo'], + source: 'apache', + }, + 'text/x-opml': { + extensions: ['opml'], + source: 'apache', + }, + 'text/x-pascal': { + extensions: ['p', 'pas'], + source: 'apache', + }, + 'text/x-setext': { + extensions: ['etx'], + source: 'apache', + }, + 'text/x-sfv': { + extensions: ['sfv'], + source: 'apache', + }, + 'text/x-uuencode': { + extensions: ['uu'], + source: 'apache', + }, + 'text/x-vcalendar': { + extensions: ['vcs'], + source: 'apache', + }, + 'text/x-vcard': { + extensions: ['vcf'], + source: 'apache', + }, + 'text/xml': { + extensions: ['xml'], + source: 'iana', + }, +} as const; diff --git a/packages/media/src/react/placeholder/internal/utils.ts b/packages/media/src/react/placeholder/internal/utils.ts new file mode 100644 index 0000000000..d430f16156 --- /dev/null +++ b/packages/media/src/react/placeholder/internal/utils.ts @@ -0,0 +1,90 @@ +import { type FileExtension, type MimeType, mimes } from './mimes'; + +/** Lookup the MIME type for a file path/extension. */ +export function lookup(path: string): MimeType | false { + if (!path || typeof path !== 'string') { + return false; + } + + // get the extension ("ext" or ".ext" or full path) + const extension = extname('x.' + path) + .toLowerCase() + .slice(1) as FileExtension; + + if (!extension) { + return false; + } + + return getTypes()[extension] || false; +} + +const extensions = {} as Record; +const types = {} as Record; + +export function getTypes(): Record { + populateMaps(extensions, types); + + return types; +} + +export const mimeTypes = mimes as unknown as Record< + MimeType, + { extensions: FileExtension[]; source: string } +>; + +let inittedMaps = false; +/** + * Populate the extensions and types maps. + * + * @private + */ + +function populateMaps( + extensions: Record, + types: Record +) { + if (inittedMaps) return; + + inittedMaps = true; + // source preference (least -> most) + const preference = ['nginx', 'apache', undefined, 'iana']; + + (Object.keys(mimeTypes) as MimeType[]).forEach((type) => { + const mime = mimeTypes[type]; + const exts = mime.extensions; + + if (!exts?.length) { + return; + } + + // mime -> extensions + extensions[type] = exts; + + // extension -> mime + + for (const extension of exts) { + if (types[extension]) { + const from = preference.indexOf(mimeTypes[types[extension]].source); + const to = preference.indexOf(mime.source); + + if ( + types[extension] !== 'application/octet-stream' && + (from > to || + (from === to && types[extension].startsWith('application/'))) + ) { + // skip the remapping + continue; + } + } + + // set the extension -> mime + types[extension] = type; + } + }); +} + +function extname(path: string) { + const index = path.lastIndexOf('.'); + + return index < 0 ? '' : path.slice(Math.max(0, index)); +} diff --git a/packages/media/src/react/placeholder/internal/video.ts b/packages/media/src/react/placeholder/internal/video.ts new file mode 100644 index 0000000000..ab2f3145e6 --- /dev/null +++ b/packages/media/src/react/placeholder/internal/video.ts @@ -0,0 +1,166 @@ +export const video = { + 'video/3gpp': { + extensions: ['3gp', '3gpp'], + source: 'iana', + }, + 'video/3gpp2': { + extensions: ['3g2'], + source: 'iana', + }, + 'video/h261': { + extensions: ['h261'], + source: 'iana', + }, + 'video/h263': { + extensions: ['h263'], + source: 'iana', + }, + 'video/h264': { + extensions: ['h264'], + source: 'iana', + }, + 'video/iso.segment': { + extensions: ['m4s'], + source: 'iana', + }, + 'video/jpeg': { + extensions: ['jpgv'], + source: 'iana', + }, + 'video/jpm': { + extensions: ['jpm', 'jpgm'], + source: 'apache', + }, + 'video/mj2': { + extensions: ['mj2', 'mjp2'], + source: 'iana', + }, + 'video/mp2t': { + extensions: ['ts'], + source: 'iana', + }, + 'video/mp4': { + extensions: ['mp4', 'mp4v', 'mpg4'], + source: 'iana', + }, + 'video/mpeg': { + extensions: ['mpeg', 'mpg', 'mpe', 'm1v', 'm2v'], + source: 'iana', + }, + 'video/ogg': { + extensions: ['ogv'], + source: 'iana', + }, + 'video/quicktime': { + extensions: ['qt', 'mov'], + source: 'iana', + }, + 'video/vnd.dece.hd': { + extensions: ['uvh', 'uvvh'], + source: 'iana', + }, + 'video/vnd.dece.mobile': { + extensions: ['uvm', 'uvvm'], + source: 'iana', + }, + 'video/vnd.dece.pd': { + extensions: ['uvp', 'uvvp'], + source: 'iana', + }, + 'video/vnd.dece.sd': { + extensions: ['uvs', 'uvvs'], + source: 'iana', + }, + 'video/vnd.dece.video': { + extensions: ['uvv', 'uvvv'], + source: 'iana', + }, + 'video/vnd.dvb.file': { + extensions: ['dvb'], + source: 'iana', + }, + 'video/vnd.fvt': { + extensions: ['fvt'], + source: 'iana', + }, + 'video/vnd.mpegurl': { + extensions: ['mxu', 'm4u'], + source: 'iana', + }, + 'video/vnd.ms-playready.media.pyv': { + extensions: ['pyv'], + source: 'iana', + }, + 'video/vnd.uvvu.mp4': { + extensions: ['uvu', 'uvvu'], + source: 'iana', + }, + 'video/vnd.vivo': { + extensions: ['viv'], + source: 'iana', + }, + 'video/webm': { + extensions: ['webm'], + source: 'apache', + }, + 'video/x-f4v': { + extensions: ['f4v'], + source: 'apache', + }, + 'video/x-fli': { + extensions: ['fli'], + source: 'apache', + }, + 'video/x-flv': { + extensions: ['flv'], + source: 'apache', + }, + 'video/x-m4v': { + extensions: ['m4v'], + source: 'apache', + }, + 'video/x-matroska': { + extensions: ['mkv', 'mk3d', 'mks'], + source: 'apache', + }, + 'video/x-mng': { + extensions: ['mng'], + source: 'apache', + }, + 'video/x-ms-asf': { + extensions: ['asf', 'asx'], + source: 'apache', + }, + 'video/x-ms-vob': { + extensions: ['vob'], + source: 'apache', + }, + 'video/x-ms-wm': { + extensions: ['wm'], + source: 'apache', + }, + 'video/x-ms-wmv': { + extensions: ['wmv'], + source: 'apache', + }, + 'video/x-ms-wmx': { + extensions: ['wmx'], + source: 'apache', + }, + 'video/x-ms-wvx': { + extensions: ['wvx'], + source: 'apache', + }, + 'video/x-msvideo': { + extensions: ['avi'], + source: 'apache', + }, + 'video/x-sgi-movie': { + extensions: ['movie'], + source: 'apache', + }, + 'video/x-smv': { + extensions: ['smv'], + source: 'apache', + }, +} as const; diff --git a/packages/media/src/react/placeholder/transforms/insertMedia.ts b/packages/media/src/react/placeholder/transforms/insertMedia.ts index 8ff832809f..e0c3f462a7 100644 --- a/packages/media/src/react/placeholder/transforms/insertMedia.ts +++ b/packages/media/src/react/placeholder/transforms/insertMedia.ts @@ -4,28 +4,31 @@ import { insertNodes, nanoid, withoutNormalizing } from '@udecode/plate-common'; import { type TPlaceholderElement, BasePlaceholderPlugin } from '../../../lib'; import { PlaceholderPlugin } from '../PlaceholderPlugin'; -import { getMediaTypeByFileName } from '../utils/getMediaTypeByFileName'; +import { UploadErrorCode } from '../type'; +import { createUploadError, isUploadError } from '../utils/createUploadError'; +import { getMediaType } from '../utils/getMediaType'; import { validateFiles } from '../utils/validateFiles'; export const insertMedia = (editor: PlateEditor, files: FileList): any => { const api = editor.getApi(PlaceholderPlugin); - const mediaConfig = editor.getOption(PlaceholderPlugin, 'mediaConfig'); + const uploadConfig = editor.getOption(PlaceholderPlugin, 'uploadConfig'); const multiple = editor.getOption(PlaceholderPlugin, 'multiple'); - const validationResult = validateFiles(files, mediaConfig); + try { + validateFiles(files, uploadConfig); + } catch (error) { + if (!isUploadError(error)) throw error; - if (!validationResult.isValid && validationResult.errorMessage) { - return editor.setOption( - PlaceholderPlugin, - 'uploadErrorMessage', - validationResult.errorMessage - ); + return editor.setOption(PlaceholderPlugin, 'uploadError', error); } + if (!multiple && files.length > 1) { return editor.setOption( PlaceholderPlugin, - 'uploadErrorMessage', - 'Can not upload multiple files' + 'uploadError', + createUploadError(UploadErrorCode.MaxFileCountExceeded, { + invalidateFiles: Array.from(files), + }) ); } @@ -35,8 +38,10 @@ export const insertMedia = (editor: PlateEditor, files: FileList): any => { if (files.length > maxFileCount) { return editor.setOption( PlaceholderPlugin, - 'uploadErrorMessage', - `Can not upload more than ${maxFileCount} files` + 'uploadError', + createUploadError(UploadErrorCode.MaxFileCountExceeded, { + invalidateFiles: Array.from(files), + }) ); } @@ -47,7 +52,7 @@ export const insertMedia = (editor: PlateEditor, files: FileList): any => { insertNodes(editor, { id, children: [{ text: '' }], - mediaType: getMediaTypeByFileName(file.name, mediaConfig)!, + mediaType: getMediaType(file, uploadConfig)!, type: editor.getType(BasePlaceholderPlugin), }) ); diff --git a/packages/media/src/react/placeholder/type.ts b/packages/media/src/react/placeholder/type.ts new file mode 100644 index 0000000000..702a643f63 --- /dev/null +++ b/packages/media/src/react/placeholder/type.ts @@ -0,0 +1,34 @@ +import type { AudioPlugin, FilePlugin, ImagePlugin, VideoPlugin } from '..'; + +export enum UploadErrorCode { + Success = '200', + InvalidFileTypeError = '400', + InvalidConfigKey = '401', + MaxFileCountExceeded = '402', + InvalidFileSize = '403', + MaxFileSizeExceeded = '404', + MinFileCountNotMet = '405', +} + +export type MediaKeys = + | typeof AudioPlugin.key + | typeof FilePlugin.key + | typeof ImagePlugin.key + | typeof VideoPlugin.key; + +type PowOf2 = 1 | 2 | 4 | 8 | 16 | 32 | 64 | 128 | 256 | 512 | 1024; + +export type SizeUnit = 'B' | 'GB' | 'KB' | 'MB'; + +export type FileSize = `${PowOf2}${SizeUnit}`; + +export type MediaItemConfig = { + // The type of media that this config is for. + mediaType: MediaKeys; + // The maximum number of files of this type that can be uploaded. + maxFileCount?: number; + // The maximum file size for a file of this type. FileSize is a string that can be parsed as a number followed by a unit of measurement (B, KB, MB, or GB) + maxFileSize?: FileSize; + // The minimum number of files of this type that must be uploaded. + minFileCount?: number; +}; diff --git a/packages/media/src/react/placeholder/utils/createUploadError.ts b/packages/media/src/react/placeholder/utils/createUploadError.ts new file mode 100644 index 0000000000..b01b3389eb --- /dev/null +++ b/packages/media/src/react/placeholder/utils/createUploadError.ts @@ -0,0 +1,22 @@ +import type { UploadError } from '../PlaceholderPlugin'; +import type { UploadErrorCode } from '../type'; + +export const createUploadError = ( + code: UploadErrorCode, + data: { invalidateFiles: File[] } +): UploadError => { + return { code, data } as UploadError; +}; + +export const isUploadError = (error: unknown): error is UploadError => { + return ( + typeof error === 'object' && + error !== null && + 'code' in error && + 'data' in error && + typeof error.data === 'object' && + error.data !== null && + 'invalidateFiles' in error.data && + Array.isArray(error.data.invalidateFiles) + ); +}; diff --git a/packages/media/src/react/placeholder/utils/fileSizeToBytes.spec.ts b/packages/media/src/react/placeholder/utils/fileSizeToBytes.spec.ts new file mode 100644 index 0000000000..b5b66b14c1 --- /dev/null +++ b/packages/media/src/react/placeholder/utils/fileSizeToBytes.spec.ts @@ -0,0 +1,66 @@ +/* eslint-disable jest/valid-expect */ +/* eslint-disable jest/no-conditional-expect */ +import { UploadErrorCode } from '../type'; +import { bytesToFileSize, fileSizeToBytes } from './fileSizeToBytes'; + +describe('fileSizeToBytes', () => { + it('should convert bytes correctly', () => { + expect(fileSizeToBytes('1B', new File([], ''))).toBe(1); + expect(fileSizeToBytes('1024B', new File([], ''))).toBe(1024); + }); + + it('should convert kilobytes correctly', () => { + expect(fileSizeToBytes('1KB', new File([], ''))).toBe(1024); + }); + + it('should convert megabytes correctly', () => { + expect(fileSizeToBytes('1MB', new File([], ''))).toBe(1_048_576); + }); + + it('should convert gigabytes correctly', () => { + expect(fileSizeToBytes('1GB', new File([], ''))).toBe(1_073_741_824); + }); + + it('should be case insensitive', () => { + expect(fileSizeToBytes('1KB', new File([], ''))).toBe(1024); + }); + + it('should handle whitespace', () => {}); + + it('should throw InvalidFileSize for invalid formats', () => { + expect(() => { + try { + fileSizeToBytes('invalid' as any, new File([], '')); + } catch (error: any) { + expect(error.code).toBe(UploadErrorCode.InvalidFileSize); + } + }); + + expect(() => { + try { + fileSizeToBytes('-1KB' as any, new File([], '')); + } catch (error: any) { + expect(error.code).toBe(UploadErrorCode.InvalidFileSize); + } + }); + }); +}); + +describe('bytesToFileSize', () => { + it('should handle zero and negative one', () => { + expect(bytesToFileSize(0)).toBe('0B'); + expect(bytesToFileSize(-1)).toBe('0B'); + }); + + it('should convert bytes to human readable format', () => { + expect(bytesToFileSize(500)).toBe('500.00B'); + expect(bytesToFileSize(1024)).toBe('1.02KB'); + expect(bytesToFileSize(1_048_576)).toBe('1.05MB'); + expect(bytesToFileSize(1_073_741_824)).toBe('1.07GB'); + }); + + it('should round to 2 decimal places', () => { + expect(bytesToFileSize(1536)).toBe('1.54KB'); + expect(bytesToFileSize(2_621_440)).toBe('2.62MB'); + }); +}); diff --git a/packages/media/src/react/placeholder/utils/fileSizeToBytes.ts b/packages/media/src/react/placeholder/utils/fileSizeToBytes.ts new file mode 100644 index 0000000000..9f9c4bc7ee --- /dev/null +++ b/packages/media/src/react/placeholder/utils/fileSizeToBytes.ts @@ -0,0 +1,38 @@ +import { type FileSize, UploadErrorCode } from '../type'; +import { createUploadError } from './createUploadError'; + +export const FILESIZE_UNITS = ['B', 'KB', 'MB', 'GB'] as const; + +export type FileSizeUnit = (typeof FILESIZE_UNITS)[number]; + +export const fileSizeToBytes = (fileSize: FileSize, file: File): number => { + const regex = new RegExp( + `^(\\d+)(\\.\\d+)?\\s*(${FILESIZE_UNITS.join('|')})$`, + 'i' + ); + + // make sure the string is in the format of 123KB + const match = fileSize.match(regex); + + if (!match) { + throw createUploadError(UploadErrorCode.InvalidFileSize, { + invalidateFiles: [file], + }); + } + + const sizeValue = Number.parseFloat(match[1]); + const sizeUnit = match[3].toUpperCase() as FileSizeUnit; + const bytes = sizeValue * Math.pow(1024, FILESIZE_UNITS.indexOf(sizeUnit)); + + return Math.floor(bytes); +}; + +export const bytesToFileSize = (bytes: number) => { + if (bytes === 0 || bytes === -1) { + return '0B'; + } + + const i = Math.floor(Math.log(bytes) / Math.log(1000)); + + return `${(bytes / Math.pow(1000, i)).toFixed(2)}${FILESIZE_UNITS[i]}`; +}; diff --git a/packages/media/src/react/placeholder/utils/getFileExtension.ts b/packages/media/src/react/placeholder/utils/getFileExtension.ts deleted file mode 100644 index ef59f2ae56..0000000000 --- a/packages/media/src/react/placeholder/utils/getFileExtension.ts +++ /dev/null @@ -1,19 +0,0 @@ -export const getFileExtension = (filename: string) => { - if (!filename || typeof filename !== 'string') { - return ''; - } - - filename = filename.trim(); - - if (filename.endsWith('.')) { - return ''; - } - - const ext = filename.split('.').pop(); - - if (ext === filename || filename.startsWith('.')) { - return ''; - } - - return ext?.toLowerCase() ?? ''; -}; diff --git a/packages/media/src/react/placeholder/utils/getMediaType.ts b/packages/media/src/react/placeholder/utils/getMediaType.ts new file mode 100644 index 0000000000..8db91c01ae --- /dev/null +++ b/packages/media/src/react/placeholder/utils/getMediaType.ts @@ -0,0 +1,14 @@ +import type { uploadConfig } from '../PlaceholderPlugin'; +import type { AllowedFileType, FileRouterInputKey } from '../internal/mimes'; +import type { MediaItemConfig, MediaKeys } from '../type'; + +import { matchFileType } from './matchFileType'; + +export const getMediaType = (file: File, config: uploadConfig): MediaKeys => { + const type = matchFileType( + file, + Object.keys(config) as FileRouterInputKey[] + ) as AllowedFileType; + + return (config[type] as MediaItemConfig).mediaType; +}; diff --git a/packages/media/src/react/placeholder/utils/getMediaTypeByFileName.ts b/packages/media/src/react/placeholder/utils/getMediaTypeByFileName.ts deleted file mode 100644 index 91cefa60a1..0000000000 --- a/packages/media/src/react/placeholder/utils/getMediaTypeByFileName.ts +++ /dev/null @@ -1,65 +0,0 @@ -import type { MediaConfig } from '../PlaceholderPlugin'; - -import { getFileExtension } from './getFileExtension'; - -export const getMediaTypeByFileName = ( - fileName: string, - config: MediaConfig -): string | null => { - const extension = getFileExtension(fileName); - - for (const [key, value] of Object.entries(config)) { - const accept = value?.accept ?? []; - - // user can use both `.mp3` or `mp3` in options - if (accept.includes(extension) || accept.includes(`.${extension}`)) { - switch (key) { - case 'audio': { - return value.mediaType; - } - case 'file': { - return value.mediaType; - } - case 'image': { - return value.mediaType; - } - case 'video': { - return value.mediaType; - } - } - } - } - - return null; -}; - -export const getMediaConfigKeyByFileName = ( - fileName: string, - config: MediaConfig -): string | null => { - const extension = getFileExtension(fileName); - - for (const [key, value] of Object.entries(config)) { - const accept = value?.accept ?? []; - - // user can use both `.mp3` or `mp3` in options - if (accept.includes(extension) || accept.includes(`.${extension}`)) { - switch (key) { - case 'audio': { - return key; - } - case 'file': { - return key; - } - case 'image': { - return key; - } - case 'video': { - return key; - } - } - } - } - - return null; -}; diff --git a/packages/media/src/react/placeholder/utils/groupFilesByType.spec.ts b/packages/media/src/react/placeholder/utils/groupFilesByType.spec.ts new file mode 100644 index 0000000000..2c7a082e25 --- /dev/null +++ b/packages/media/src/react/placeholder/utils/groupFilesByType.spec.ts @@ -0,0 +1,90 @@ +/* eslint-disable jest/valid-expect */ +/* eslint-disable jest/no-conditional-expect */ +import type { uploadConfig } from '../PlaceholderPlugin'; + +import { UploadErrorCode } from '../type'; +import { groupFilesByType } from './groupFilesByType'; + +describe('groupFilesByType', () => { + const createFile = (name: string, type: string): File => { + return new File([], name, { type }); + }; + + it('should group files by their types', () => { + const files = [ + createFile('image.jpg', 'image/jpeg'), + createFile('video.mp4', 'video/mp4'), + createFile('doc.pdf', 'application/pdf'), + ]; + + const fileList = { + [Symbol.iterator]: function* () { + for (let i = 0; i < this.length; i++) { + yield this.item(i); + } + }, + item: (i: number) => files[i], + length: files.length, + } as FileList; + + const config: uploadConfig = { + image: { maxFileSize: '8B', mediaType: 'img' }, + pdf: { maxFileSize: '64B', mediaType: 'file' }, + video: { maxFileSize: '1024MB', mediaType: 'video' }, + }; + + const result = groupFilesByType(fileList, config); + + expect(result.image).toHaveLength(1); + expect(result.video).toHaveLength(1); + expect(result.pdf).toHaveLength(1); + expect(result.audio).toHaveLength(0); + expect(result.blob).toHaveLength(0); + expect(result.text).toHaveLength(0); + }); + + it('should throw InvalidFileTypeError for unsupported file types', () => { + const files = [createFile('text.txt', 'text/plain')]; + const fileList = { + [Symbol.iterator]: function* () { + for (let i = 0; i < this.length; i++) { + yield this.item(i); + } + }, + item: (i: number) => files[i], + length: files.length, + } as FileList; + + const config: uploadConfig = { + image: { maxFileSize: '8MB', mediaType: 'img' }, + }; + + expect(() => { + try { + groupFilesByType(fileList, config); + } catch (error: any) { + expect(error.code).toBe(UploadErrorCode.InvalidFileTypeError); + } + }); + }); + + it('should accept blob type as fallback', () => { + const files = [createFile('unknown.xyz', 'application/octet-stream')]; + const fileList = { + [Symbol.iterator]: function* () { + for (let i = 0; i < this.length; i++) { + yield this.item(i); + } + }, + item: (i: number) => files[i], + length: files.length, + } as FileList; + + const config: uploadConfig = { + blob: { maxFileSize: '1024MB', mediaType: 'file' }, + }; + + const result = groupFilesByType(fileList, config); + expect(result.blob).toHaveLength(1); + }); +}); diff --git a/packages/media/src/react/placeholder/utils/groupFilesByType.ts b/packages/media/src/react/placeholder/utils/groupFilesByType.ts new file mode 100644 index 0000000000..b1fc7c9249 --- /dev/null +++ b/packages/media/src/react/placeholder/utils/groupFilesByType.ts @@ -0,0 +1,26 @@ +import type { uploadConfig } from '../PlaceholderPlugin'; +import type { AllowedFileType } from '../internal/mimes'; + +import { matchFileType } from './matchFileType'; + +export const groupFilesByType = ( + fileList: FileList, + config: uploadConfig +): Record => { + const FileTypeMap: Record = { + audio: [], + blob: [], + image: [], + pdf: [], + text: [], + video: [], + }; + + for (const file of fileList) { + const type = matchFileType(file, Object.keys(config) as AllowedFileType[]); + + FileTypeMap[type as AllowedFileType].push(file); + } + + return FileTypeMap; +}; diff --git a/packages/media/src/react/placeholder/utils/index.ts b/packages/media/src/react/placeholder/utils/index.ts index c4cb3869b9..86f0e02b48 100644 --- a/packages/media/src/react/placeholder/utils/index.ts +++ b/packages/media/src/react/placeholder/utils/index.ts @@ -2,7 +2,9 @@ * @file Automatically generated by barrelsby. */ -export * from './getFileExtension'; -export * from './getMediaTypeByFileName'; -export * from './parseFileSize'; +export * from './fileSizeToBytes'; +export * from './getMediaType'; +export * from './groupFilesByType'; +export * from './matchFileType'; +export * from './validateFileItem'; export * from './validateFiles'; diff --git a/packages/media/src/react/placeholder/utils/matchFileType.spec.ts b/packages/media/src/react/placeholder/utils/matchFileType.spec.ts new file mode 100644 index 0000000000..572af02694 --- /dev/null +++ b/packages/media/src/react/placeholder/utils/matchFileType.spec.ts @@ -0,0 +1,51 @@ +/* eslint-disable jest/valid-expect */ +/* eslint-disable jest/no-conditional-expect */ +import { UploadErrorCode } from '../type'; +import { matchFileType } from './matchFileType'; + +describe('matchFileType', () => { + const createFile = (name: string, type: string): File => { + return new File([], name, { type }); + }; + + it('should return blob if no mime type and blob is allowed', () => { + const file = createFile('test.txt', ''); + expect(matchFileType(file, ['blob'])).toBe('blob'); + }); + + it('should match exact mime type if specified in allowed types', () => { + const file = createFile('test.jpg', 'image/jpeg'); + expect(matchFileType(file, ['image/jpeg'])).toBe('image/jpeg'); + }); + + it('should match general type for images', () => { + const file = createFile('test.jpg', 'image/jpeg'); + expect(matchFileType(file, ['image'])).toBe('image'); + }); + + it('should match general type for videos', () => { + const file = createFile('test.mp4', 'video/mp4'); + expect(matchFileType(file, ['video'])).toBe('video'); + }); + + it('should handle PDF files specially', () => { + const file = createFile('test.pdf', 'application/pdf'); + expect(matchFileType(file, ['pdf'])).toBe('pdf'); + }); + + it('should return blob for unsupported type if blob is allowed', () => { + const file = createFile('test.txt', 'text/plain'); + expect(matchFileType(file, ['image', 'blob'])).toBe('blob'); + }); + + it('should return InvalidFileTypeError for unsupported type if blob is not allowed', () => { + const file = createFile('test.txt', 'text/plain'); + expect(() => { + try { + matchFileType(file, ['image']); + } catch (error: any) { + expect(error.code).toBe(UploadErrorCode.InvalidFileTypeError); + } + }); + }); +}); diff --git a/packages/media/src/react/placeholder/utils/matchFileType.ts b/packages/media/src/react/placeholder/utils/matchFileType.ts new file mode 100644 index 0000000000..529f3a38f5 --- /dev/null +++ b/packages/media/src/react/placeholder/utils/matchFileType.ts @@ -0,0 +1,48 @@ +import type { AllowedFileType, FileRouterInputKey } from '../internal/mimes'; + +import { lookup } from '../internal/utils'; +import { UploadErrorCode } from '../type'; +import { createUploadError } from './createUploadError'; + +export const matchFileType = ( + file: File, + allowedTypes: FileRouterInputKey[] +): FileRouterInputKey => { + // Type might be "" if the browser doesn't recognize the mime type + const mimeType = file.type || lookup(file.name); + + if (!mimeType) { + if (allowedTypes.includes('blob')) return 'blob'; + + throw createUploadError(UploadErrorCode.InvalidFileTypeError, { + invalidateFiles: [file], + }); + } + // If the user has specified a specific mime type, use that + if ( + allowedTypes.some((type) => type.includes('/')) && + allowedTypes.includes(mimeType as FileRouterInputKey) + ) { + return mimeType as FileRouterInputKey; + } + + // Otherwise, we have a "magic" type eg. "image" or "video" + const type = ( + mimeType.toLowerCase() === 'application/pdf' + ? 'pdf' + : mimeType.split('/')[0] + ) as AllowedFileType; + + if (!allowedTypes.includes(type)) { + // Blob is a catch-all for any file type not explicitly supported + if (allowedTypes.includes('blob')) { + return 'blob'; + } else { + throw createUploadError(UploadErrorCode.InvalidFileTypeError, { + invalidateFiles: [file], + }); + } + } + + return type; +}; diff --git a/packages/media/src/react/placeholder/utils/parseFileSize.ts b/packages/media/src/react/placeholder/utils/parseFileSize.ts deleted file mode 100644 index 97e3ca90b6..0000000000 --- a/packages/media/src/react/placeholder/utils/parseFileSize.ts +++ /dev/null @@ -1,17 +0,0 @@ -/** Convert string like 1B to 1024 number */ -export const parseFileSize = (size: string): number => { - const match = /^(\d+(?:\.\d+)?)\s*(b|kb|mb|gb)$/i.exec(size); - - if (!match) { - throw new Error('Invalid file size format'); - } - - const [, value, unit] = match; - const sizes = { B: 0, GB: 3, KB: 1, MB: 2 }; - const k = 1024; - - return Math.floor( - Number.parseFloat(value) * - Math.pow(k, sizes[unit.toUpperCase() as keyof typeof sizes]) - ); -}; diff --git a/packages/media/src/react/placeholder/utils/validateFileItem.spec.ts b/packages/media/src/react/placeholder/utils/validateFileItem.spec.ts new file mode 100644 index 0000000000..e2640d9198 --- /dev/null +++ b/packages/media/src/react/placeholder/utils/validateFileItem.spec.ts @@ -0,0 +1,70 @@ +/* eslint-disable jest/valid-expect */ +/* eslint-disable jest/no-conditional-expect */ +import { type MediaItemConfig, UploadErrorCode } from '../type'; +import { validateFileItem } from './validateFileItem'; + +describe('validateFileItem', () => { + const createFile = (name: string, size = 0): File => { + const file = new File([''], name, { type: '' }); + Object.defineProperty(file, 'size', { value: size }); + + return file; + }; + + it('should validate files within constraints', () => { + const files = [createFile('test.jpg', 500)]; + const config: MediaItemConfig = { + maxFileSize: '1KB', + mediaType: 'img', + }; + + expect(validateFileItem(files, config)).toBe(true); + }); + + it('should throw MaxFileCountExceeded when files exceed maximum', () => { + const files = [ + createFile('test1.jpg', 500), + createFile('test2.jpg', 500), + createFile('test3.jpg', 500), + ]; + const config: MediaItemConfig = { + maxFileCount: 2, + maxFileSize: '1KB', + mediaType: 'img', + }; + + expect(() => { + try { + validateFileItem(files, config); + } catch (error: any) { + expect(error.code).toBe(UploadErrorCode.MaxFileCountExceeded); + } + }); + }); + + it('should throw MaxFileSizeExceeded when any file exceeds size limit', () => { + const files = [createFile('test.jpg', 2048)]; + const config: MediaItemConfig = { + maxFileSize: '1KB', + mediaType: 'img', + }; + + expect(() => { + try { + validateFileItem(files, config); + } catch (error: any) { + expect(error.code).toBe(UploadErrorCode.MaxFileSizeExceeded); + } + }); + }); + + it('should use default values for min and max file count', () => { + const files = [createFile('test.jpg', 500)]; + const config: MediaItemConfig = { + maxFileSize: '1KB', + mediaType: 'img', + }; + + expect(validateFileItem(files, config)).toBe(true); + }); +}); diff --git a/packages/media/src/react/placeholder/utils/validateFileItem.ts b/packages/media/src/react/placeholder/utils/validateFileItem.ts new file mode 100644 index 0000000000..4078376072 --- /dev/null +++ b/packages/media/src/react/placeholder/utils/validateFileItem.ts @@ -0,0 +1,30 @@ +import { type FileSize, type MediaItemConfig, UploadErrorCode } from '../type'; +import { createUploadError } from './createUploadError'; +import { fileSizeToBytes } from './fileSizeToBytes'; + +export const validateFileItem = ( + files: File[], + config: MediaItemConfig +): UploadErrorCode | true => { + const { maxFileCount = Infinity, maxFileSize, minFileCount = 1 } = config; + + if (files.length < minFileCount) + throw createUploadError(UploadErrorCode.MinFileCountNotMet, { + invalidateFiles: files, + }); + if (files.length > maxFileCount) + throw createUploadError(UploadErrorCode.MaxFileCountExceeded, { + invalidateFiles: files, + }); + + for (const f of files) { + const bytes = fileSizeToBytes(maxFileSize as FileSize, f); + + if (f.size > bytes) + throw createUploadError(UploadErrorCode.MaxFileSizeExceeded, { + invalidateFiles: [f], + }); + } + + return true; +}; diff --git a/packages/media/src/react/placeholder/utils/validateFiles.ts b/packages/media/src/react/placeholder/utils/validateFiles.ts index bf1ecb8358..caf9eb458e 100644 --- a/packages/media/src/react/placeholder/utils/validateFiles.ts +++ b/packages/media/src/react/placeholder/utils/validateFiles.ts @@ -1,102 +1,28 @@ -import type { - MediaConfig, - MediaItemConfig, - MediaType, -} from '../PlaceholderPlugin'; +import type { uploadConfig } from '../PlaceholderPlugin'; +import type { AllowedFileType } from '../internal/mimes'; -import { getMediaConfigKeyByFileName } from './getMediaTypeByFileName'; -import { parseFileSize } from './parseFileSize'; +import { UploadErrorCode } from '../type'; +import { createUploadError } from './createUploadError'; +import { groupFilesByType } from './groupFilesByType'; +import { validateFileItem } from './validateFileItem'; -interface ValidationResult { - errorMessage: string | null; - isValid: boolean; -} +export const validateFiles = (fileList: FileList, config: uploadConfig) => { + const fileTypeMap = groupFilesByType(fileList, config); -export const validateFiles = ( - fileList: FileList, - config: MediaConfig -): ValidationResult => { - const unknown: File[] = []; - - const map: Record = { - audio: [], - file: [], - image: [], - video: [], - }; - - Array.from(fileList).forEach((file) => { - // group files by acceptExtension - const mediaType = getMediaConfigKeyByFileName(file.name, config); - - if (mediaType && mediaType in map) { - map[mediaType as MediaType].push(file); - } else { - unknown.push(file); - } - }); - - if (unknown.length > 0) { - return { - errorMessage: `The files: ${unknown.map((file) => file.name).join(',')} is not support`, - isValid: false, - }; - } - - const keys = Object.keys(map) as (keyof typeof map)[]; + const keys = Object.keys(fileTypeMap) as AllowedFileType[]; for (const key of keys) { - const itemFiles = map[key]; - - const result = validateFileItem(itemFiles, config[key]!, { - debugName: key, - }); + const itemConfig = config[key]; - if (!result.isValid) { - return result; - } - } - - return { errorMessage: null, isValid: true }; -}; + if (!itemConfig) + throw createUploadError(UploadErrorCode.InvalidConfigKey, { + invalidateFiles: Array.from(fileList), + }); -const validateFileItem = ( - fileList: File[], - config: MediaItemConfig, - options: { debugName: string } -): ValidationResult => { - if (fileList.length === 0) return { errorMessage: null, isValid: true }; + const itemFiles = fileTypeMap[key]; - const { debugName } = options; - // validate file count - const minFileCount = config.minFileCount ?? 1; - const maxFileCount = config.maxFileCount ?? 3; - console.log('🚀 ~ maxFileCount:', maxFileCount); + if (itemFiles.length === 0) continue; - if (fileList.length < minFileCount) { - return { - errorMessage: `Minimum ${debugName} file count is ${minFileCount}`, - isValid: false, - }; - } - if (fileList.length > maxFileCount) { - return { - errorMessage: `Maximum ${debugName} file count is ${maxFileCount}`, - isValid: false, - }; + validateFileItem(itemFiles, itemConfig); } - - // validate file size - const maxFileSize = config.maxFileSize ?? '10MB'; - - fileList.forEach((file) => { - if (file.size > parseFileSize(maxFileSize)) { - return { - errors: `Maximum ${debugName} file size is ${maxFileSize}`, - isValid: false, - }; - } - }); - - return { errorMessage: null, isValid: true }; }; From fa9613c75e45e2c6a34e5541840fc4efd8754ff4 Mon Sep 17 00:00:00 2001 From: Felix Feng Date: Mon, 4 Nov 2024 20:24:44 +0800 Subject: [PATCH 20/25] default config --- .../src/react/placeholder/PlaceholderPlugin.tsx | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/packages/media/src/react/placeholder/PlaceholderPlugin.tsx b/packages/media/src/react/placeholder/PlaceholderPlugin.tsx index a78529a4b0..12c2dfef77 100644 --- a/packages/media/src/react/placeholder/PlaceholderPlugin.tsx +++ b/packages/media/src/react/placeholder/PlaceholderPlugin.tsx @@ -33,8 +33,7 @@ export const PlaceholderPlugin = toTPlatePlugin< uploadingFiles: Record; // Whether multiple files of the same type can be uploaded. multiple?: boolean; - uploadCode?: string | null; - uploadError?: UploadError; + uploadError?: UploadError | null; uploadMaxFileCount?: number; }, { placeholder: PlaceholderApi } @@ -42,7 +41,6 @@ export const PlaceholderPlugin = toTPlatePlugin< >(BasePlaceholderPlugin, { options: { multiple: true, - uploadCode: null, uploadConfig: { audio: { maxFileCount: 1, @@ -52,35 +50,36 @@ export const PlaceholderPlugin = toTPlatePlugin< }, blob: { maxFileCount: 1, - maxFileSize: '256MB', + maxFileSize: '8MB', mediaType: FilePlugin.key, minFileCount: 1, }, image: { - maxFileCount: 1, - maxFileSize: '2MB', + maxFileCount: 3, + maxFileSize: '4MB', mediaType: ImagePlugin.key, minFileCount: 1, }, pdf: { maxFileCount: 1, - maxFileSize: '8MB', + maxFileSize: '4MB', mediaType: FilePlugin.key, minFileCount: 1, }, text: { maxFileCount: 1, - maxFileSize: '256MB', + maxFileSize: '64KB', mediaType: FilePlugin.key, minFileCount: 1, }, video: { maxFileCount: 1, - maxFileSize: '256MB', + maxFileSize: '16MB', mediaType: VideoPlugin.key, minFileCount: 1, }, }, + uploadError: null, uploadMaxFileCount: 5, uploadingFiles: {}, }, From 4b0ff3610c5e8fd6cd175de7351c0e43b55bb15e Mon Sep 17 00:00:00 2001 From: Felix Feng Date: Mon, 4 Nov 2024 20:28:01 +0800 Subject: [PATCH 21/25] lint --- packages/media/src/react/placeholder/utils/fileSizeToBytes.ts | 1 + packages/media/src/react/placeholder/utils/matchFileType.ts | 1 + packages/media/src/react/placeholder/utils/validateFileItem.ts | 1 + packages/media/src/react/placeholder/utils/validateFiles.ts | 1 + 4 files changed, 4 insertions(+) diff --git a/packages/media/src/react/placeholder/utils/fileSizeToBytes.ts b/packages/media/src/react/placeholder/utils/fileSizeToBytes.ts index 9f9c4bc7ee..dda7eacc04 100644 --- a/packages/media/src/react/placeholder/utils/fileSizeToBytes.ts +++ b/packages/media/src/react/placeholder/utils/fileSizeToBytes.ts @@ -15,6 +15,7 @@ export const fileSizeToBytes = (fileSize: FileSize, file: File): number => { const match = fileSize.match(regex); if (!match) { + // eslint-disable-next-line @typescript-eslint/only-throw-error throw createUploadError(UploadErrorCode.InvalidFileSize, { invalidateFiles: [file], }); diff --git a/packages/media/src/react/placeholder/utils/matchFileType.ts b/packages/media/src/react/placeholder/utils/matchFileType.ts index 529f3a38f5..324e535843 100644 --- a/packages/media/src/react/placeholder/utils/matchFileType.ts +++ b/packages/media/src/react/placeholder/utils/matchFileType.ts @@ -1,3 +1,4 @@ +/* eslint-disable @typescript-eslint/only-throw-error */ import type { AllowedFileType, FileRouterInputKey } from '../internal/mimes'; import { lookup } from '../internal/utils'; diff --git a/packages/media/src/react/placeholder/utils/validateFileItem.ts b/packages/media/src/react/placeholder/utils/validateFileItem.ts index 4078376072..90be6ed7ae 100644 --- a/packages/media/src/react/placeholder/utils/validateFileItem.ts +++ b/packages/media/src/react/placeholder/utils/validateFileItem.ts @@ -1,3 +1,4 @@ +/* eslint-disable @typescript-eslint/only-throw-error */ import { type FileSize, type MediaItemConfig, UploadErrorCode } from '../type'; import { createUploadError } from './createUploadError'; import { fileSizeToBytes } from './fileSizeToBytes'; diff --git a/packages/media/src/react/placeholder/utils/validateFiles.ts b/packages/media/src/react/placeholder/utils/validateFiles.ts index caf9eb458e..f8b67ea7c6 100644 --- a/packages/media/src/react/placeholder/utils/validateFiles.ts +++ b/packages/media/src/react/placeholder/utils/validateFiles.ts @@ -1,3 +1,4 @@ +/* eslint-disable @typescript-eslint/only-throw-error */ import type { uploadConfig } from '../PlaceholderPlugin'; import type { AllowedFileType } from '../internal/mimes'; From 02b7c3d83a03f12da4fd7c241057ee59abd9a63a Mon Sep 17 00:00:00 2001 From: Felix Feng Date: Tue, 5 Nov 2024 10:19:17 +0800 Subject: [PATCH 22/25] code --- .../react/placeholder/PlaceholderPlugin.tsx | 41 +++++---------- .../placeholder/transforms/insertMedia.ts | 19 ++++--- packages/media/src/react/placeholder/type.ts | 50 ++++++++++++++++--- .../placeholder/utils/createUploadError.ts | 18 ++++--- .../placeholder/utils/fileSizeToBytes.spec.ts | 6 +-- .../placeholder/utils/fileSizeToBytes.ts | 6 +-- .../react/placeholder/utils/getMediaType.ts | 4 +- .../utils/groupFilesByType.spec.ts | 12 ++--- .../placeholder/utils/groupFilesByType.ts | 4 +- .../placeholder/utils/matchFileType.spec.ts | 4 +- .../react/placeholder/utils/matchFileType.ts | 12 +++-- .../utils/validateFileItem.spec.ts | 6 +-- .../placeholder/utils/validateFileItem.ts | 21 ++++---- .../react/placeholder/utils/validateFiles.ts | 13 ++--- 14 files changed, 117 insertions(+), 99 deletions(-) diff --git a/packages/media/src/react/placeholder/PlaceholderPlugin.tsx b/packages/media/src/react/placeholder/PlaceholderPlugin.tsx index 12c2dfef77..3c7f64efec 100644 --- a/packages/media/src/react/placeholder/PlaceholderPlugin.tsx +++ b/packages/media/src/react/placeholder/PlaceholderPlugin.tsx @@ -2,7 +2,7 @@ import { type ExtendConfig, bindFirst } from '@udecode/plate-common'; import { findEventRange, toTPlatePlugin } from '@udecode/plate-common/react'; import type { AllowedFileType } from './internal/mimes'; -import type { MediaItemConfig, UploadErrorCode } from './type'; +import type { Error, MediaItemConfig } from './type'; import { type PlaceholderConfig, BasePlaceholderPlugin } from '../../lib'; import { AudioPlugin, FilePlugin, ImagePlugin, VideoPlugin } from '../plugins'; @@ -18,28 +18,27 @@ export type PlaceholderTransforms = { insertMedia: (files: FileList) => void; }; -export type UploadError = { - code: UploadErrorCode; - data: { invalidateFiles: File[] }; -}; - -export type uploadConfig = Partial>; +export type UploadConfig = Partial>; export const PlaceholderPlugin = toTPlatePlugin< ExtendConfig< PlaceholderConfig, { - uploadConfig: uploadConfig; + disabledDndPlugin: boolean; + uploadConfig: UploadConfig; uploadingFiles: Record; + error?: Error | null; + maxFileCount?: number; // Whether multiple files of the same type can be uploaded. multiple?: boolean; - uploadError?: UploadError | null; - uploadMaxFileCount?: number; }, { placeholder: PlaceholderApi } > >(BasePlaceholderPlugin, { options: { + disabledDndPlugin: false, + error: null, + maxFileCount: 5, multiple: true, uploadConfig: { audio: { @@ -79,8 +78,6 @@ export const PlaceholderPlugin = toTPlatePlugin< minFileCount: 1, }, }, - uploadError: null, - uploadMaxFileCount: 5, uploadingFiles: {}, }, }) @@ -98,21 +95,6 @@ export const PlaceholderPlugin = toTPlatePlugin< [id]: file, }); }, - // getMediaConfig: (mediaType: MediaKeys) => { - // const config = getOption('mediaConfig'); - - // const keys = Object.keys(config); - - // for (const key of keys) { - // const item = config[key as AllowedFileType]; - - // if (item?.mediaType === mediaType) { - // return item; - // } - // } - - // return null; - // }, getUploadingFile: (id: string) => { const uploadingFiles = getOption('uploadingFiles'); @@ -126,9 +108,12 @@ export const PlaceholderPlugin = toTPlatePlugin< setOption('uploadingFiles', uploadingFiles); }, })) - .extend(() => ({ + .extend(({ getOption }) => ({ handlers: { onDrop: ({ editor, event, tf }) => { + // using DnD plugin by default + if (!getOption('disabledDndPlugin')) return; + const { files } = event.dataTransfer; if (files.length === 0) return false; diff --git a/packages/media/src/react/placeholder/transforms/insertMedia.ts b/packages/media/src/react/placeholder/transforms/insertMedia.ts index e0c3f462a7..ea511f1f0a 100644 --- a/packages/media/src/react/placeholder/transforms/insertMedia.ts +++ b/packages/media/src/react/placeholder/transforms/insertMedia.ts @@ -4,7 +4,7 @@ import { insertNodes, nanoid, withoutNormalizing } from '@udecode/plate-common'; import { type TPlaceholderElement, BasePlaceholderPlugin } from '../../../lib'; import { PlaceholderPlugin } from '../PlaceholderPlugin'; -import { UploadErrorCode } from '../type'; +import { ErrorCode } from '../type'; import { createUploadError, isUploadError } from '../utils/createUploadError'; import { getMediaType } from '../utils/getMediaType'; import { validateFiles } from '../utils/validateFiles'; @@ -19,28 +19,27 @@ export const insertMedia = (editor: PlateEditor, files: FileList): any => { } catch (error) { if (!isUploadError(error)) throw error; - return editor.setOption(PlaceholderPlugin, 'uploadError', error); + return editor.setOption(PlaceholderPlugin, 'error', error); } if (!multiple && files.length > 1) { return editor.setOption( PlaceholderPlugin, - 'uploadError', - createUploadError(UploadErrorCode.MaxFileCountExceeded, { - invalidateFiles: Array.from(files), + 'error', + createUploadError(ErrorCode.TOO_MANY_FILES, { + files: Array.from(files), }) ); } - const maxFileCount = - editor.getOption(PlaceholderPlugin, 'uploadMaxFileCount') ?? 3; + const maxFileCount = editor.getOption(PlaceholderPlugin, 'maxFileCount') ?? 3; if (files.length > maxFileCount) { return editor.setOption( PlaceholderPlugin, - 'uploadError', - createUploadError(UploadErrorCode.MaxFileCountExceeded, { - invalidateFiles: Array.from(files), + 'error', + createUploadError(ErrorCode.TOO_MANY_FILES, { + files: Array.from(files), }) ); } diff --git a/packages/media/src/react/placeholder/type.ts b/packages/media/src/react/placeholder/type.ts index 702a643f63..a3afe5b82f 100644 --- a/packages/media/src/react/placeholder/type.ts +++ b/packages/media/src/react/placeholder/type.ts @@ -1,15 +1,49 @@ import type { AudioPlugin, FilePlugin, ImagePlugin, VideoPlugin } from '..'; -export enum UploadErrorCode { - Success = '200', - InvalidFileTypeError = '400', - InvalidConfigKey = '401', - MaxFileCountExceeded = '402', - InvalidFileSize = '403', - MaxFileSizeExceeded = '404', - MinFileCountNotMet = '405', +export enum ErrorCode { + INVALID_FILE_TYPE = 400, + TOO_MANY_FILES = 402, + INVALID_FILE_SIZE = 403, + TOO_LESS_FILES = 405, + TOO_LARGE = 413, } +export type Error = + | { + data: { + allowedTypes: string[]; + files: File[]; + }; + code: ErrorCode.INVALID_FILE_TYPE; + } + | { + data: { + files: File[]; + }; + code: ErrorCode.INVALID_FILE_SIZE; + } + | { + data: { + files: File[]; + maxFileCount: number; + }; + code: ErrorCode.TOO_MANY_FILES; + } + | { + data: { + files: File[]; + maxFileSize: string; + }; + code: ErrorCode.TOO_LARGE; + } + | { + data: { + files: File[]; + minFileCount: number; + }; + code: ErrorCode.TOO_LESS_FILES; + }; + export type MediaKeys = | typeof AudioPlugin.key | typeof FilePlugin.key diff --git a/packages/media/src/react/placeholder/utils/createUploadError.ts b/packages/media/src/react/placeholder/utils/createUploadError.ts index b01b3389eb..480bd989b7 100644 --- a/packages/media/src/react/placeholder/utils/createUploadError.ts +++ b/packages/media/src/react/placeholder/utils/createUploadError.ts @@ -1,14 +1,16 @@ -import type { UploadError } from '../PlaceholderPlugin'; -import type { UploadErrorCode } from '../type'; +import type { Error, ErrorCode } from '../type'; +// 首先定义一个类型,用于获取指定错误码对应的data类型 +type ErrorDataType = Extract['data']; -export const createUploadError = ( - code: UploadErrorCode, - data: { invalidateFiles: File[] } -): UploadError => { - return { code, data } as UploadError; +// 改写createUploadError函数 +export const createUploadError = ( + code: T, + data: ErrorDataType +): Error => { + return { code, data } as Error; }; -export const isUploadError = (error: unknown): error is UploadError => { +export const isUploadError = (error: unknown): error is Error => { return ( typeof error === 'object' && error !== null && diff --git a/packages/media/src/react/placeholder/utils/fileSizeToBytes.spec.ts b/packages/media/src/react/placeholder/utils/fileSizeToBytes.spec.ts index b5b66b14c1..4b0ed2aae1 100644 --- a/packages/media/src/react/placeholder/utils/fileSizeToBytes.spec.ts +++ b/packages/media/src/react/placeholder/utils/fileSizeToBytes.spec.ts @@ -1,6 +1,6 @@ /* eslint-disable jest/valid-expect */ /* eslint-disable jest/no-conditional-expect */ -import { UploadErrorCode } from '../type'; +import { ErrorCode } from '../type'; import { bytesToFileSize, fileSizeToBytes } from './fileSizeToBytes'; describe('fileSizeToBytes', () => { @@ -32,7 +32,7 @@ describe('fileSizeToBytes', () => { try { fileSizeToBytes('invalid' as any, new File([], '')); } catch (error: any) { - expect(error.code).toBe(UploadErrorCode.InvalidFileSize); + expect(error.code).toBe(ErrorCode.INVALID_FILE_SIZE); } }); @@ -40,7 +40,7 @@ describe('fileSizeToBytes', () => { try { fileSizeToBytes('-1KB' as any, new File([], '')); } catch (error: any) { - expect(error.code).toBe(UploadErrorCode.InvalidFileSize); + expect(error.code).toBe(ErrorCode.INVALID_FILE_SIZE); } }); }); diff --git a/packages/media/src/react/placeholder/utils/fileSizeToBytes.ts b/packages/media/src/react/placeholder/utils/fileSizeToBytes.ts index dda7eacc04..c41ba56b09 100644 --- a/packages/media/src/react/placeholder/utils/fileSizeToBytes.ts +++ b/packages/media/src/react/placeholder/utils/fileSizeToBytes.ts @@ -1,4 +1,4 @@ -import { type FileSize, UploadErrorCode } from '../type'; +import { type FileSize, ErrorCode } from '../type'; import { createUploadError } from './createUploadError'; export const FILESIZE_UNITS = ['B', 'KB', 'MB', 'GB'] as const; @@ -16,8 +16,8 @@ export const fileSizeToBytes = (fileSize: FileSize, file: File): number => { if (!match) { // eslint-disable-next-line @typescript-eslint/only-throw-error - throw createUploadError(UploadErrorCode.InvalidFileSize, { - invalidateFiles: [file], + throw createUploadError(ErrorCode.INVALID_FILE_SIZE, { + files: [file], }); } diff --git a/packages/media/src/react/placeholder/utils/getMediaType.ts b/packages/media/src/react/placeholder/utils/getMediaType.ts index 8db91c01ae..caa374d0fb 100644 --- a/packages/media/src/react/placeholder/utils/getMediaType.ts +++ b/packages/media/src/react/placeholder/utils/getMediaType.ts @@ -1,10 +1,10 @@ -import type { uploadConfig } from '../PlaceholderPlugin'; +import type { UploadConfig } from '../PlaceholderPlugin'; import type { AllowedFileType, FileRouterInputKey } from '../internal/mimes'; import type { MediaItemConfig, MediaKeys } from '../type'; import { matchFileType } from './matchFileType'; -export const getMediaType = (file: File, config: uploadConfig): MediaKeys => { +export const getMediaType = (file: File, config: UploadConfig): MediaKeys => { const type = matchFileType( file, Object.keys(config) as FileRouterInputKey[] diff --git a/packages/media/src/react/placeholder/utils/groupFilesByType.spec.ts b/packages/media/src/react/placeholder/utils/groupFilesByType.spec.ts index 2c7a082e25..b571be16bd 100644 --- a/packages/media/src/react/placeholder/utils/groupFilesByType.spec.ts +++ b/packages/media/src/react/placeholder/utils/groupFilesByType.spec.ts @@ -1,8 +1,8 @@ /* eslint-disable jest/valid-expect */ /* eslint-disable jest/no-conditional-expect */ -import type { uploadConfig } from '../PlaceholderPlugin'; +import type { UploadConfig } from '../PlaceholderPlugin'; -import { UploadErrorCode } from '../type'; +import { ErrorCode } from '../type'; import { groupFilesByType } from './groupFilesByType'; describe('groupFilesByType', () => { @@ -27,7 +27,7 @@ describe('groupFilesByType', () => { length: files.length, } as FileList; - const config: uploadConfig = { + const config: UploadConfig = { image: { maxFileSize: '8B', mediaType: 'img' }, pdf: { maxFileSize: '64B', mediaType: 'file' }, video: { maxFileSize: '1024MB', mediaType: 'video' }, @@ -55,7 +55,7 @@ describe('groupFilesByType', () => { length: files.length, } as FileList; - const config: uploadConfig = { + const config: UploadConfig = { image: { maxFileSize: '8MB', mediaType: 'img' }, }; @@ -63,7 +63,7 @@ describe('groupFilesByType', () => { try { groupFilesByType(fileList, config); } catch (error: any) { - expect(error.code).toBe(UploadErrorCode.InvalidFileTypeError); + expect(error.code).toBe(ErrorCode.INVALID_FILE_TYPE); } }); }); @@ -80,7 +80,7 @@ describe('groupFilesByType', () => { length: files.length, } as FileList; - const config: uploadConfig = { + const config: UploadConfig = { blob: { maxFileSize: '1024MB', mediaType: 'file' }, }; diff --git a/packages/media/src/react/placeholder/utils/groupFilesByType.ts b/packages/media/src/react/placeholder/utils/groupFilesByType.ts index b1fc7c9249..255edec079 100644 --- a/packages/media/src/react/placeholder/utils/groupFilesByType.ts +++ b/packages/media/src/react/placeholder/utils/groupFilesByType.ts @@ -1,11 +1,11 @@ -import type { uploadConfig } from '../PlaceholderPlugin'; +import type { UploadConfig } from '../PlaceholderPlugin'; import type { AllowedFileType } from '../internal/mimes'; import { matchFileType } from './matchFileType'; export const groupFilesByType = ( fileList: FileList, - config: uploadConfig + config: UploadConfig ): Record => { const FileTypeMap: Record = { audio: [], diff --git a/packages/media/src/react/placeholder/utils/matchFileType.spec.ts b/packages/media/src/react/placeholder/utils/matchFileType.spec.ts index 572af02694..0bb2dc51be 100644 --- a/packages/media/src/react/placeholder/utils/matchFileType.spec.ts +++ b/packages/media/src/react/placeholder/utils/matchFileType.spec.ts @@ -1,6 +1,6 @@ /* eslint-disable jest/valid-expect */ /* eslint-disable jest/no-conditional-expect */ -import { UploadErrorCode } from '../type'; +import { ErrorCode } from '../type'; import { matchFileType } from './matchFileType'; describe('matchFileType', () => { @@ -44,7 +44,7 @@ describe('matchFileType', () => { try { matchFileType(file, ['image']); } catch (error: any) { - expect(error.code).toBe(UploadErrorCode.InvalidFileTypeError); + expect(error.code).toBe(ErrorCode.INVALID_FILE_TYPE); } }); }); diff --git a/packages/media/src/react/placeholder/utils/matchFileType.ts b/packages/media/src/react/placeholder/utils/matchFileType.ts index 324e535843..c90f153580 100644 --- a/packages/media/src/react/placeholder/utils/matchFileType.ts +++ b/packages/media/src/react/placeholder/utils/matchFileType.ts @@ -2,7 +2,7 @@ import type { AllowedFileType, FileRouterInputKey } from '../internal/mimes'; import { lookup } from '../internal/utils'; -import { UploadErrorCode } from '../type'; +import { ErrorCode } from '../type'; import { createUploadError } from './createUploadError'; export const matchFileType = ( @@ -15,8 +15,9 @@ export const matchFileType = ( if (!mimeType) { if (allowedTypes.includes('blob')) return 'blob'; - throw createUploadError(UploadErrorCode.InvalidFileTypeError, { - invalidateFiles: [file], + throw createUploadError(ErrorCode.INVALID_FILE_TYPE, { + allowedTypes: allowedTypes, + files: [file], }); } // If the user has specified a specific mime type, use that @@ -39,8 +40,9 @@ export const matchFileType = ( if (allowedTypes.includes('blob')) { return 'blob'; } else { - throw createUploadError(UploadErrorCode.InvalidFileTypeError, { - invalidateFiles: [file], + throw createUploadError(ErrorCode.INVALID_FILE_TYPE, { + allowedTypes: allowedTypes, + files: [file], }); } } diff --git a/packages/media/src/react/placeholder/utils/validateFileItem.spec.ts b/packages/media/src/react/placeholder/utils/validateFileItem.spec.ts index e2640d9198..d066b52a37 100644 --- a/packages/media/src/react/placeholder/utils/validateFileItem.spec.ts +++ b/packages/media/src/react/placeholder/utils/validateFileItem.spec.ts @@ -1,6 +1,6 @@ /* eslint-disable jest/valid-expect */ /* eslint-disable jest/no-conditional-expect */ -import { type MediaItemConfig, UploadErrorCode } from '../type'; +import { type MediaItemConfig, ErrorCode } from '../type'; import { validateFileItem } from './validateFileItem'; describe('validateFileItem', () => { @@ -37,7 +37,7 @@ describe('validateFileItem', () => { try { validateFileItem(files, config); } catch (error: any) { - expect(error.code).toBe(UploadErrorCode.MaxFileCountExceeded); + expect(error.code).toBe(ErrorCode.TOO_MANY_FILES); } }); }); @@ -53,7 +53,7 @@ describe('validateFileItem', () => { try { validateFileItem(files, config); } catch (error: any) { - expect(error.code).toBe(UploadErrorCode.MaxFileSizeExceeded); + expect(error.code).toBe(ErrorCode.TOO_LARGE); } }); }); diff --git a/packages/media/src/react/placeholder/utils/validateFileItem.ts b/packages/media/src/react/placeholder/utils/validateFileItem.ts index 90be6ed7ae..0c30e89e3f 100644 --- a/packages/media/src/react/placeholder/utils/validateFileItem.ts +++ b/packages/media/src/react/placeholder/utils/validateFileItem.ts @@ -1,29 +1,32 @@ /* eslint-disable @typescript-eslint/only-throw-error */ -import { type FileSize, type MediaItemConfig, UploadErrorCode } from '../type'; +import { type FileSize, type MediaItemConfig, ErrorCode } from '../type'; import { createUploadError } from './createUploadError'; -import { fileSizeToBytes } from './fileSizeToBytes'; +import { bytesToFileSize, fileSizeToBytes } from './fileSizeToBytes'; export const validateFileItem = ( files: File[], config: MediaItemConfig -): UploadErrorCode | true => { +): ErrorCode | true => { const { maxFileCount = Infinity, maxFileSize, minFileCount = 1 } = config; if (files.length < minFileCount) - throw createUploadError(UploadErrorCode.MinFileCountNotMet, { - invalidateFiles: files, + throw createUploadError(ErrorCode.TOO_LESS_FILES, { + files: files, + minFileCount: minFileCount, }); if (files.length > maxFileCount) - throw createUploadError(UploadErrorCode.MaxFileCountExceeded, { - invalidateFiles: files, + throw createUploadError(ErrorCode.TOO_MANY_FILES, { + files: files, + maxFileCount: maxFileCount, }); for (const f of files) { const bytes = fileSizeToBytes(maxFileSize as FileSize, f); if (f.size > bytes) - throw createUploadError(UploadErrorCode.MaxFileSizeExceeded, { - invalidateFiles: [f], + throw createUploadError(ErrorCode.TOO_LARGE, { + files: [f], + maxFileSize: bytesToFileSize(bytes), }); } diff --git a/packages/media/src/react/placeholder/utils/validateFiles.ts b/packages/media/src/react/placeholder/utils/validateFiles.ts index f8b67ea7c6..c4cfd68eb4 100644 --- a/packages/media/src/react/placeholder/utils/validateFiles.ts +++ b/packages/media/src/react/placeholder/utils/validateFiles.ts @@ -1,13 +1,11 @@ /* eslint-disable @typescript-eslint/only-throw-error */ -import type { uploadConfig } from '../PlaceholderPlugin'; +import type { UploadConfig } from '../PlaceholderPlugin'; import type { AllowedFileType } from '../internal/mimes'; -import { UploadErrorCode } from '../type'; -import { createUploadError } from './createUploadError'; import { groupFilesByType } from './groupFilesByType'; import { validateFileItem } from './validateFileItem'; -export const validateFiles = (fileList: FileList, config: uploadConfig) => { +export const validateFiles = (fileList: FileList, config: UploadConfig) => { const fileTypeMap = groupFilesByType(fileList, config); const keys = Object.keys(fileTypeMap) as AllowedFileType[]; @@ -15,15 +13,10 @@ export const validateFiles = (fileList: FileList, config: uploadConfig) => { for (const key of keys) { const itemConfig = config[key]; - if (!itemConfig) - throw createUploadError(UploadErrorCode.InvalidConfigKey, { - invalidateFiles: Array.from(fileList), - }); - const itemFiles = fileTypeMap[key]; if (itemFiles.length === 0) continue; - validateFileItem(itemFiles, itemConfig); + validateFileItem(itemFiles, itemConfig!); } }; From 8a91ef38fcf272af25279c3243d7aff359a34fe5 Mon Sep 17 00:00:00 2001 From: Felix Feng Date: Tue, 5 Nov 2024 10:20:39 +0800 Subject: [PATCH 23/25] brl --- packages/media/src/react/placeholder/hooks/index.ts | 6 ++++++ .../react/placeholder/{ => hooks}/usePlaceholderElement.ts | 0 .../react/placeholder/{ => hooks}/usePlaceholderPopover.ts | 0 packages/media/src/react/placeholder/index.ts | 3 +-- packages/media/src/react/placeholder/utils/index.ts | 1 + 5 files changed, 8 insertions(+), 2 deletions(-) create mode 100644 packages/media/src/react/placeholder/hooks/index.ts rename packages/media/src/react/placeholder/{ => hooks}/usePlaceholderElement.ts (100%) rename packages/media/src/react/placeholder/{ => hooks}/usePlaceholderPopover.ts (100%) diff --git a/packages/media/src/react/placeholder/hooks/index.ts b/packages/media/src/react/placeholder/hooks/index.ts new file mode 100644 index 0000000000..cfb6baabf5 --- /dev/null +++ b/packages/media/src/react/placeholder/hooks/index.ts @@ -0,0 +1,6 @@ +/** + * @file Automatically generated by barrelsby. + */ + +export * from './usePlaceholderElement'; +export * from './usePlaceholderPopover'; diff --git a/packages/media/src/react/placeholder/usePlaceholderElement.ts b/packages/media/src/react/placeholder/hooks/usePlaceholderElement.ts similarity index 100% rename from packages/media/src/react/placeholder/usePlaceholderElement.ts rename to packages/media/src/react/placeholder/hooks/usePlaceholderElement.ts diff --git a/packages/media/src/react/placeholder/usePlaceholderPopover.ts b/packages/media/src/react/placeholder/hooks/usePlaceholderPopover.ts similarity index 100% rename from packages/media/src/react/placeholder/usePlaceholderPopover.ts rename to packages/media/src/react/placeholder/hooks/usePlaceholderPopover.ts diff --git a/packages/media/src/react/placeholder/index.ts b/packages/media/src/react/placeholder/index.ts index 9370b312cb..f960f0d3ab 100644 --- a/packages/media/src/react/placeholder/index.ts +++ b/packages/media/src/react/placeholder/index.ts @@ -5,7 +5,6 @@ export * from './PlaceholderPlugin'; export * from './placeholderStore'; export * from './type'; -export * from './usePlaceholderElement'; -export * from './usePlaceholderPopover'; +export * from './hooks/index'; export * from './transforms/index'; export * from './utils/index'; diff --git a/packages/media/src/react/placeholder/utils/index.ts b/packages/media/src/react/placeholder/utils/index.ts index 86f0e02b48..1229070e05 100644 --- a/packages/media/src/react/placeholder/utils/index.ts +++ b/packages/media/src/react/placeholder/utils/index.ts @@ -2,6 +2,7 @@ * @file Automatically generated by barrelsby. */ +export * from './createUploadError'; export * from './fileSizeToBytes'; export * from './getMediaType'; export * from './groupFilesByType'; From 43f5b0ec14a18b134d2164a724e63396c4919381 Mon Sep 17 00:00:00 2001 From: Felix Feng Date: Tue, 5 Nov 2024 11:00:34 +0800 Subject: [PATCH 24/25] ci --- packages/media/src/lib/media/index.ts | 2 +- .../react/placeholder/PlaceholderPlugin.tsx | 4 +-- .../hooks/usePlaceholderElement.ts | 7 ++--- .../hooks/usePlaceholderPopover.ts | 7 ++--- .../placeholder/transforms/insertMedia.ts | 10 ++++-- packages/media/src/react/placeholder/type.ts | 31 ++++++++++++------- .../placeholder/utils/createUploadError.ts | 19 +++++++----- .../placeholder/utils/fileSizeToBytes.spec.ts | 6 ++-- .../placeholder/utils/fileSizeToBytes.ts | 6 ++-- .../utils/groupFilesByType.spec.ts | 4 +-- .../placeholder/utils/matchFileType.spec.ts | 4 +-- .../react/placeholder/utils/matchFileType.ts | 6 ++-- .../utils/validateFileItem.spec.ts | 14 ++++----- .../placeholder/utils/validateFileItem.ts | 18 +++++++---- .../react/placeholder/utils/validateFiles.ts | 2 +- 15 files changed, 78 insertions(+), 62 deletions(-) diff --git a/packages/media/src/lib/media/index.ts b/packages/media/src/lib/media/index.ts index 4a95d1b952..7f9a061e57 100644 --- a/packages/media/src/lib/media/index.ts +++ b/packages/media/src/lib/media/index.ts @@ -4,4 +4,4 @@ export * from './insertMedia'; export * from './parseMediaUrl'; -export * from './types'; +export type * from './types'; diff --git a/packages/media/src/react/placeholder/PlaceholderPlugin.tsx b/packages/media/src/react/placeholder/PlaceholderPlugin.tsx index 3c7f64efec..ea58a9a15a 100644 --- a/packages/media/src/react/placeholder/PlaceholderPlugin.tsx +++ b/packages/media/src/react/placeholder/PlaceholderPlugin.tsx @@ -2,7 +2,7 @@ import { type ExtendConfig, bindFirst } from '@udecode/plate-common'; import { findEventRange, toTPlatePlugin } from '@udecode/plate-common/react'; import type { AllowedFileType } from './internal/mimes'; -import type { Error, MediaItemConfig } from './type'; +import type { MediaItemConfig, UploadError } from './type'; import { type PlaceholderConfig, BasePlaceholderPlugin } from '../../lib'; import { AudioPlugin, FilePlugin, ImagePlugin, VideoPlugin } from '../plugins'; @@ -27,7 +27,7 @@ export const PlaceholderPlugin = toTPlatePlugin< disabledDndPlugin: boolean; uploadConfig: UploadConfig; uploadingFiles: Record; - error?: Error | null; + error?: UploadError | null; maxFileCount?: number; // Whether multiple files of the same type can be uploaded. multiple?: boolean; diff --git a/packages/media/src/react/placeholder/hooks/usePlaceholderElement.ts b/packages/media/src/react/placeholder/hooks/usePlaceholderElement.ts index 729d2ca6be..659769a74d 100644 --- a/packages/media/src/react/placeholder/hooks/usePlaceholderElement.ts +++ b/packages/media/src/react/placeholder/hooks/usePlaceholderElement.ts @@ -1,11 +1,8 @@ import { useEditorRef, useElement } from '@udecode/plate-common/react'; import { useFocused, useReadOnly, useSelected } from 'slate-react'; -import { - type TPlaceholderElement, - BasePlaceholderPlugin, -} from '../../lib/placeholder/BasePlaceholderPlugin'; -import { usePlaceholderStore } from './placeholderStore'; +import { type TPlaceholderElement, BasePlaceholderPlugin } from '../../../lib'; +import { usePlaceholderStore } from '../placeholderStore'; export const usePlaceholderElementState = () => { const element = useElement(); diff --git a/packages/media/src/react/placeholder/hooks/usePlaceholderPopover.ts b/packages/media/src/react/placeholder/hooks/usePlaceholderPopover.ts index c122c2fc5f..3721fd772b 100644 --- a/packages/media/src/react/placeholder/hooks/usePlaceholderPopover.ts +++ b/packages/media/src/react/placeholder/hooks/usePlaceholderPopover.ts @@ -6,11 +6,8 @@ import { } from '@udecode/plate-common/react'; import { useFocused, useReadOnly, useSelected } from 'slate-react'; -import { - type TPlaceholderElement, - BasePlaceholderPlugin, -} from '../../lib/placeholder/BasePlaceholderPlugin'; -import { usePlaceholderStore } from './placeholderStore'; +import { type TPlaceholderElement, BasePlaceholderPlugin } from '../../../lib'; +import { usePlaceholderStore } from '../placeholderStore'; export const usePlaceholderPopoverState = () => { const editor = useEditorRef(); diff --git a/packages/media/src/react/placeholder/transforms/insertMedia.ts b/packages/media/src/react/placeholder/transforms/insertMedia.ts index ea511f1f0a..9c88405b7f 100644 --- a/packages/media/src/react/placeholder/transforms/insertMedia.ts +++ b/packages/media/src/react/placeholder/transforms/insertMedia.ts @@ -4,7 +4,7 @@ import { insertNodes, nanoid, withoutNormalizing } from '@udecode/plate-common'; import { type TPlaceholderElement, BasePlaceholderPlugin } from '../../../lib'; import { PlaceholderPlugin } from '../PlaceholderPlugin'; -import { ErrorCode } from '../type'; +import { UploadErrorCode } from '../type'; import { createUploadError, isUploadError } from '../utils/createUploadError'; import { getMediaType } from '../utils/getMediaType'; import { validateFiles } from '../utils/validateFiles'; @@ -26,8 +26,10 @@ export const insertMedia = (editor: PlateEditor, files: FileList): any => { return editor.setOption( PlaceholderPlugin, 'error', - createUploadError(ErrorCode.TOO_MANY_FILES, { + createUploadError(UploadErrorCode.TOO_MANY_FILES, { + fileType: null, files: Array.from(files), + maxFileCount: 1, }) ); } @@ -38,8 +40,10 @@ export const insertMedia = (editor: PlateEditor, files: FileList): any => { return editor.setOption( PlaceholderPlugin, 'error', - createUploadError(ErrorCode.TOO_MANY_FILES, { + createUploadError(UploadErrorCode.TOO_MANY_FILES, { + fileType: null, files: Array.from(files), + maxFileCount, }) ); } diff --git a/packages/media/src/react/placeholder/type.ts b/packages/media/src/react/placeholder/type.ts index a3afe5b82f..b3ede8acd4 100644 --- a/packages/media/src/react/placeholder/type.ts +++ b/packages/media/src/react/placeholder/type.ts @@ -1,6 +1,12 @@ -import type { AudioPlugin, FilePlugin, ImagePlugin, VideoPlugin } from '..'; +import type { + AudioPlugin, + FilePlugin, + ImagePlugin, + VideoPlugin, +} from '../plugins'; +import type { AllowedFileType } from './internal/mimes'; -export enum ErrorCode { +export enum UploadErrorCode { INVALID_FILE_TYPE = 400, TOO_MANY_FILES = 402, INVALID_FILE_SIZE = 403, @@ -8,40 +14,43 @@ export enum ErrorCode { TOO_LARGE = 413, } -export type Error = +export type UploadError = | { data: { allowedTypes: string[]; files: File[]; }; - code: ErrorCode.INVALID_FILE_TYPE; + code: UploadErrorCode.INVALID_FILE_TYPE; } | { data: { + fileType: AllowedFileType; files: File[]; + maxFileSize: string; }; - code: ErrorCode.INVALID_FILE_SIZE; + code: UploadErrorCode.TOO_LARGE; } | { data: { + fileType: AllowedFileType; files: File[]; - maxFileCount: number; + minFileCount: number; }; - code: ErrorCode.TOO_MANY_FILES; + code: UploadErrorCode.TOO_LESS_FILES; } | { data: { + fileType: AllowedFileType | null; files: File[]; - maxFileSize: string; + maxFileCount: number; }; - code: ErrorCode.TOO_LARGE; + code: UploadErrorCode.TOO_MANY_FILES; } | { data: { files: File[]; - minFileCount: number; }; - code: ErrorCode.TOO_LESS_FILES; + code: UploadErrorCode.INVALID_FILE_SIZE; }; export type MediaKeys = diff --git a/packages/media/src/react/placeholder/utils/createUploadError.ts b/packages/media/src/react/placeholder/utils/createUploadError.ts index 480bd989b7..a0c1c66285 100644 --- a/packages/media/src/react/placeholder/utils/createUploadError.ts +++ b/packages/media/src/react/placeholder/utils/createUploadError.ts @@ -1,16 +1,19 @@ -import type { Error, ErrorCode } from '../type'; +import type { UploadError, UploadErrorCode } from '../type'; // 首先定义一个类型,用于获取指定错误码对应的data类型 -type ErrorDataType = Extract['data']; +type ErrorDataType = Extract< + UploadError, + { code: T } +>['data']; // 改写createUploadError函数 -export const createUploadError = ( +export const createUploadError = ( code: T, data: ErrorDataType -): Error => { - return { code, data } as Error; +): UploadError => { + return { code, data } as UploadError; }; -export const isUploadError = (error: unknown): error is Error => { +export const isUploadError = (error: unknown): error is UploadError => { return ( typeof error === 'object' && error !== null && @@ -18,7 +21,7 @@ export const isUploadError = (error: unknown): error is Error => { 'data' in error && typeof error.data === 'object' && error.data !== null && - 'invalidateFiles' in error.data && - Array.isArray(error.data.invalidateFiles) + 'files' in error.data && + Array.isArray(error.data.files) ); }; diff --git a/packages/media/src/react/placeholder/utils/fileSizeToBytes.spec.ts b/packages/media/src/react/placeholder/utils/fileSizeToBytes.spec.ts index 4b0ed2aae1..998a3100be 100644 --- a/packages/media/src/react/placeholder/utils/fileSizeToBytes.spec.ts +++ b/packages/media/src/react/placeholder/utils/fileSizeToBytes.spec.ts @@ -1,6 +1,6 @@ /* eslint-disable jest/valid-expect */ /* eslint-disable jest/no-conditional-expect */ -import { ErrorCode } from '../type'; +import { UploadErrorCode } from '../type'; import { bytesToFileSize, fileSizeToBytes } from './fileSizeToBytes'; describe('fileSizeToBytes', () => { @@ -32,7 +32,7 @@ describe('fileSizeToBytes', () => { try { fileSizeToBytes('invalid' as any, new File([], '')); } catch (error: any) { - expect(error.code).toBe(ErrorCode.INVALID_FILE_SIZE); + expect(error.code).toBe(UploadErrorCode.INVALID_FILE_SIZE); } }); @@ -40,7 +40,7 @@ describe('fileSizeToBytes', () => { try { fileSizeToBytes('-1KB' as any, new File([], '')); } catch (error: any) { - expect(error.code).toBe(ErrorCode.INVALID_FILE_SIZE); + expect(error.code).toBe(UploadErrorCode.INVALID_FILE_SIZE); } }); }); diff --git a/packages/media/src/react/placeholder/utils/fileSizeToBytes.ts b/packages/media/src/react/placeholder/utils/fileSizeToBytes.ts index c41ba56b09..48bdbe3eb6 100644 --- a/packages/media/src/react/placeholder/utils/fileSizeToBytes.ts +++ b/packages/media/src/react/placeholder/utils/fileSizeToBytes.ts @@ -1,4 +1,5 @@ -import { type FileSize, ErrorCode } from '../type'; +/* eslint-disable @typescript-eslint/only-throw-error */ +import { type FileSize, UploadErrorCode } from '../type'; import { createUploadError } from './createUploadError'; export const FILESIZE_UNITS = ['B', 'KB', 'MB', 'GB'] as const; @@ -15,8 +16,7 @@ export const fileSizeToBytes = (fileSize: FileSize, file: File): number => { const match = fileSize.match(regex); if (!match) { - // eslint-disable-next-line @typescript-eslint/only-throw-error - throw createUploadError(ErrorCode.INVALID_FILE_SIZE, { + throw createUploadError(UploadErrorCode.INVALID_FILE_SIZE, { files: [file], }); } diff --git a/packages/media/src/react/placeholder/utils/groupFilesByType.spec.ts b/packages/media/src/react/placeholder/utils/groupFilesByType.spec.ts index b571be16bd..35290ae8ee 100644 --- a/packages/media/src/react/placeholder/utils/groupFilesByType.spec.ts +++ b/packages/media/src/react/placeholder/utils/groupFilesByType.spec.ts @@ -2,7 +2,7 @@ /* eslint-disable jest/no-conditional-expect */ import type { UploadConfig } from '../PlaceholderPlugin'; -import { ErrorCode } from '../type'; +import { UploadErrorCode } from '../type'; import { groupFilesByType } from './groupFilesByType'; describe('groupFilesByType', () => { @@ -63,7 +63,7 @@ describe('groupFilesByType', () => { try { groupFilesByType(fileList, config); } catch (error: any) { - expect(error.code).toBe(ErrorCode.INVALID_FILE_TYPE); + expect(error.code).toBe(UploadErrorCode.INVALID_FILE_TYPE); } }); }); diff --git a/packages/media/src/react/placeholder/utils/matchFileType.spec.ts b/packages/media/src/react/placeholder/utils/matchFileType.spec.ts index 0bb2dc51be..3d2230f73d 100644 --- a/packages/media/src/react/placeholder/utils/matchFileType.spec.ts +++ b/packages/media/src/react/placeholder/utils/matchFileType.spec.ts @@ -1,6 +1,6 @@ /* eslint-disable jest/valid-expect */ /* eslint-disable jest/no-conditional-expect */ -import { ErrorCode } from '../type'; +import { UploadErrorCode } from '../type'; import { matchFileType } from './matchFileType'; describe('matchFileType', () => { @@ -44,7 +44,7 @@ describe('matchFileType', () => { try { matchFileType(file, ['image']); } catch (error: any) { - expect(error.code).toBe(ErrorCode.INVALID_FILE_TYPE); + expect(error.code).toBe(UploadErrorCode.INVALID_FILE_TYPE); } }); }); diff --git a/packages/media/src/react/placeholder/utils/matchFileType.ts b/packages/media/src/react/placeholder/utils/matchFileType.ts index c90f153580..69addee6e8 100644 --- a/packages/media/src/react/placeholder/utils/matchFileType.ts +++ b/packages/media/src/react/placeholder/utils/matchFileType.ts @@ -2,7 +2,7 @@ import type { AllowedFileType, FileRouterInputKey } from '../internal/mimes'; import { lookup } from '../internal/utils'; -import { ErrorCode } from '../type'; +import { UploadErrorCode } from '../type'; import { createUploadError } from './createUploadError'; export const matchFileType = ( @@ -15,7 +15,7 @@ export const matchFileType = ( if (!mimeType) { if (allowedTypes.includes('blob')) return 'blob'; - throw createUploadError(ErrorCode.INVALID_FILE_TYPE, { + throw createUploadError(UploadErrorCode.INVALID_FILE_TYPE, { allowedTypes: allowedTypes, files: [file], }); @@ -40,7 +40,7 @@ export const matchFileType = ( if (allowedTypes.includes('blob')) { return 'blob'; } else { - throw createUploadError(ErrorCode.INVALID_FILE_TYPE, { + throw createUploadError(UploadErrorCode.INVALID_FILE_TYPE, { allowedTypes: allowedTypes, files: [file], }); diff --git a/packages/media/src/react/placeholder/utils/validateFileItem.spec.ts b/packages/media/src/react/placeholder/utils/validateFileItem.spec.ts index d066b52a37..d500fdd053 100644 --- a/packages/media/src/react/placeholder/utils/validateFileItem.spec.ts +++ b/packages/media/src/react/placeholder/utils/validateFileItem.spec.ts @@ -1,6 +1,6 @@ /* eslint-disable jest/valid-expect */ /* eslint-disable jest/no-conditional-expect */ -import { type MediaItemConfig, ErrorCode } from '../type'; +import { type MediaItemConfig, UploadErrorCode } from '../type'; import { validateFileItem } from './validateFileItem'; describe('validateFileItem', () => { @@ -18,7 +18,7 @@ describe('validateFileItem', () => { mediaType: 'img', }; - expect(validateFileItem(files, config)).toBe(true); + expect(validateFileItem(files, config, 'image')).toBe(true); }); it('should throw MaxFileCountExceeded when files exceed maximum', () => { @@ -35,9 +35,9 @@ describe('validateFileItem', () => { expect(() => { try { - validateFileItem(files, config); + validateFileItem(files, config, 'image'); } catch (error: any) { - expect(error.code).toBe(ErrorCode.TOO_MANY_FILES); + expect(error.code).toBe(UploadErrorCode.TOO_MANY_FILES); } }); }); @@ -51,9 +51,9 @@ describe('validateFileItem', () => { expect(() => { try { - validateFileItem(files, config); + validateFileItem(files, config, 'image'); } catch (error: any) { - expect(error.code).toBe(ErrorCode.TOO_LARGE); + expect(error.code).toBe(UploadErrorCode.TOO_LARGE); } }); }); @@ -65,6 +65,6 @@ describe('validateFileItem', () => { mediaType: 'img', }; - expect(validateFileItem(files, config)).toBe(true); + expect(validateFileItem(files, config, 'image')).toBe(true); }); }); diff --git a/packages/media/src/react/placeholder/utils/validateFileItem.ts b/packages/media/src/react/placeholder/utils/validateFileItem.ts index 0c30e89e3f..42b94a97dc 100644 --- a/packages/media/src/react/placeholder/utils/validateFileItem.ts +++ b/packages/media/src/react/placeholder/utils/validateFileItem.ts @@ -1,21 +1,26 @@ /* eslint-disable @typescript-eslint/only-throw-error */ -import { type FileSize, type MediaItemConfig, ErrorCode } from '../type'; +import type { AllowedFileType } from '../internal/mimes'; + +import { type FileSize, type MediaItemConfig, UploadErrorCode } from '../type'; import { createUploadError } from './createUploadError'; import { bytesToFileSize, fileSizeToBytes } from './fileSizeToBytes'; export const validateFileItem = ( files: File[], - config: MediaItemConfig -): ErrorCode | true => { + config: MediaItemConfig, + key: AllowedFileType +): UploadErrorCode | true => { const { maxFileCount = Infinity, maxFileSize, minFileCount = 1 } = config; if (files.length < minFileCount) - throw createUploadError(ErrorCode.TOO_LESS_FILES, { + throw createUploadError(UploadErrorCode.TOO_LESS_FILES, { + fileType: key, files: files, minFileCount: minFileCount, }); if (files.length > maxFileCount) - throw createUploadError(ErrorCode.TOO_MANY_FILES, { + throw createUploadError(UploadErrorCode.TOO_MANY_FILES, { + fileType: key, files: files, maxFileCount: maxFileCount, }); @@ -24,7 +29,8 @@ export const validateFileItem = ( const bytes = fileSizeToBytes(maxFileSize as FileSize, f); if (f.size > bytes) - throw createUploadError(ErrorCode.TOO_LARGE, { + throw createUploadError(UploadErrorCode.TOO_LARGE, { + fileType: key, files: [f], maxFileSize: bytesToFileSize(bytes), }); diff --git a/packages/media/src/react/placeholder/utils/validateFiles.ts b/packages/media/src/react/placeholder/utils/validateFiles.ts index c4cfd68eb4..7baf85c8f1 100644 --- a/packages/media/src/react/placeholder/utils/validateFiles.ts +++ b/packages/media/src/react/placeholder/utils/validateFiles.ts @@ -17,6 +17,6 @@ export const validateFiles = (fileList: FileList, config: UploadConfig) => { if (itemFiles.length === 0) continue; - validateFileItem(itemFiles, itemConfig!); + validateFileItem(itemFiles, itemConfig!, key); } }; From 702ad161cfa3d6d7c546efdee67ae1e102cfec67 Mon Sep 17 00:00:00 2001 From: Felix Feng Date: Tue, 5 Nov 2024 11:12:26 +0800 Subject: [PATCH 25/25] docs --- .changeset/sour-bananas-arrive.md | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/.changeset/sour-bananas-arrive.md b/.changeset/sour-bananas-arrive.md index 3d405ccd81..e7e7f60126 100644 --- a/.changeset/sour-bananas-arrive.md +++ b/.changeset/sour-bananas-arrive.md @@ -1,10 +1,15 @@ --- '@udecode/plate-media': minor --- +ImagePlugin: +- New `initialHeight` and `initialWidth` in `TImageElement` This will display a loading placeholder while the image is still loading, which helps maintain a consistent height. +- New Api: editor.insert.imageFromFiles -New `initialHeight` and `initialWidth` in `TImageElement` This will display a loading placeholder while the image is still loading, which helps maintain a consistent height. -Mew `placeholderId` Used to track what was converted from that placeholder plugin. -New `insertMedia` Used for inserting the placeholder at once. -New `validateFiles` utils for validate the files meet the `mediaConfig`. -If validation fails,stop insert placeholder and save the error message in uploadErrorMessage. -NEw `option.multiple` `uploadMaxFileCount` Used to limit the number of placeholders inserted. \ No newline at end of file +PlaceholderPlugin: +- Mew `placeholderId` Used to track what was converted from that placeholder plugin. +- New `insertMedia` Used for inserting the placeholder at once. +- New `validateFiles` utils for validate the files meet the `mediaConfig`. + - If validation fails,stop insert placeholder and save the error message in uploadErrorMessage. +- New `option.multiple` `maxFileCount` Used to limit the number of placeholders inserted. +- New `option.disable` `disabledDndPlugin` Used to using the browser drop. +- New `error` use `editor.useOption` to watch and display a toast message.