@blocklet/editor 2.4.15 → 2.4.16
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/ext/CodeCopyPlugin/CodeCopyPlugin.d.ts +2 -0
- package/lib/ext/CodeCopyPlugin/CodeCopyPlugin.js +90 -0
- package/lib/ext/CodeCopyPlugin/copy.svg +1 -0
- package/lib/ext/CodeCopyPlugin/index.d.ts +1 -0
- package/lib/ext/CodeCopyPlugin/index.js +1 -0
- package/lib/ext/CodeCopyPlugin/style.css +12 -0
- package/lib/main/editor.js +3 -3
- package/lib/main/themes/code-highlight/index.d.ts +62 -0
- package/lib/main/themes/code-highlight/index.js +113 -0
- package/lib/main/themes/customTheme.js +5 -4
- package/package.json +3 -2
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import { jsx as _jsx, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
+
import { CodeNode } from '@lexical/code';
|
|
3
|
+
import { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext';
|
|
4
|
+
import { Box, IconButton } from '@mui/material';
|
|
5
|
+
import { $getNodeByKey } from 'lexical';
|
|
6
|
+
import { useEffect, useMemo, useState } from 'react';
|
|
7
|
+
import { Icon } from '@iconify/react';
|
|
8
|
+
import { usePopper } from 'react-popper';
|
|
9
|
+
import './style.css';
|
|
10
|
+
function isPointInsideElement(point, element) {
|
|
11
|
+
if (!element) {
|
|
12
|
+
return false;
|
|
13
|
+
}
|
|
14
|
+
const rect = element.getBoundingClientRect();
|
|
15
|
+
return point.x > rect.left && point.x < rect.right && point.y > rect.top && point.y < rect.bottom;
|
|
16
|
+
}
|
|
17
|
+
export function CodeCopyPlugin() {
|
|
18
|
+
const [editor] = useLexicalComposerContext();
|
|
19
|
+
const [codeNodes, setCodeNodes] = useState([]);
|
|
20
|
+
useEffect(() => {
|
|
21
|
+
return editor.registerMutationListener(CodeNode, (mutatedNodes) => {
|
|
22
|
+
const nodes = Array.from(mutatedNodes.keys())
|
|
23
|
+
.map((key) => $getNodeByKey(key, editor.getEditorState()))
|
|
24
|
+
.filter(Boolean);
|
|
25
|
+
setCodeNodes(nodes);
|
|
26
|
+
}, { skipInitialization: false });
|
|
27
|
+
}, [editor]);
|
|
28
|
+
return (_jsx(_Fragment, { children: codeNodes.map((codeNode) => (_jsx(CodeCopyButton, { editor: editor, codeNode: codeNode }, codeNode.getKey()))) }));
|
|
29
|
+
}
|
|
30
|
+
function CodeCopyButton({ editor, codeNode }) {
|
|
31
|
+
const [isCopied, setIsCopied] = useState(false);
|
|
32
|
+
const [buttonElement, setButtonElement] = useState(null);
|
|
33
|
+
const codeElement = useMemo(() => editor.getElementByKey(codeNode.getKey()), [editor, codeNode]);
|
|
34
|
+
const [isActivated, setIsActivated] = useState(false);
|
|
35
|
+
const popper = usePopper(codeElement, buttonElement, {
|
|
36
|
+
placement: 'right-start',
|
|
37
|
+
modifiers: [
|
|
38
|
+
{ name: 'flip', enabled: false },
|
|
39
|
+
{
|
|
40
|
+
name: 'offset',
|
|
41
|
+
options: {
|
|
42
|
+
offset: [8, -36],
|
|
43
|
+
},
|
|
44
|
+
},
|
|
45
|
+
],
|
|
46
|
+
});
|
|
47
|
+
useEffect(() => {
|
|
48
|
+
const handleMouseEnter = () => setIsActivated(true);
|
|
49
|
+
const handleMouseLeave = (e) => {
|
|
50
|
+
if (!isPointInsideElement(e, codeElement)) {
|
|
51
|
+
setIsActivated(false);
|
|
52
|
+
}
|
|
53
|
+
};
|
|
54
|
+
if (codeElement) {
|
|
55
|
+
codeElement.addEventListener('mouseenter', handleMouseEnter);
|
|
56
|
+
codeElement.addEventListener('mouseleave', handleMouseLeave);
|
|
57
|
+
return () => {
|
|
58
|
+
codeElement.removeEventListener('mouseenter', handleMouseEnter);
|
|
59
|
+
codeElement.removeEventListener('mouseleave', handleMouseLeave);
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
}, [codeElement]);
|
|
63
|
+
if (!isActivated && !isCopied) {
|
|
64
|
+
return null;
|
|
65
|
+
}
|
|
66
|
+
return (_jsx(IconButton, { ref: setButtonElement, style: popper.styles.popper, ...popper.attributes.popper, sx: {
|
|
67
|
+
color: 'text.secondary',
|
|
68
|
+
fontSize: 18,
|
|
69
|
+
bgcolor: 'background.paper',
|
|
70
|
+
'&:hover': {
|
|
71
|
+
color: 'text.primary',
|
|
72
|
+
bgcolor: 'background.paper',
|
|
73
|
+
},
|
|
74
|
+
}, onClick: async () => {
|
|
75
|
+
let content = '';
|
|
76
|
+
editor.update(() => {
|
|
77
|
+
content = codeNode.getTextContent();
|
|
78
|
+
});
|
|
79
|
+
try {
|
|
80
|
+
await navigator.clipboard.writeText(content);
|
|
81
|
+
setIsCopied(true);
|
|
82
|
+
setTimeout(() => {
|
|
83
|
+
setIsCopied(false);
|
|
84
|
+
}, 1500);
|
|
85
|
+
}
|
|
86
|
+
catch (err) {
|
|
87
|
+
console.error('Failed to copy: ', err);
|
|
88
|
+
}
|
|
89
|
+
}, children: isCopied ? (_jsx(Box, { component: Icon, icon: "tabler:check", sx: { color: 'success.main' } })) : (_jsx(Icon, { icon: "tabler:copy" })) }));
|
|
90
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24"><!-- Icon from Tabler Icons by Paweł Kuna - https://github.com/tabler/tabler-icons/blob/master/LICENSE --><g fill="none" stroke="#888888" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"><path d="M7 9.667A2.667 2.667 0 0 1 9.667 7h8.666A2.667 2.667 0 0 1 21 9.667v8.666A2.667 2.667 0 0 1 18.333 21H9.667A2.667 2.667 0 0 1 7 18.333z"/><path d="M4.012 16.737A2 2 0 0 1 3 15V5c0-1.1.9-2 2-2h10c.75 0 1.158.385 1.5 1"/></g></svg>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './CodeCopyPlugin';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './CodeCopyPlugin';
|
package/lib/main/editor.js
CHANGED
|
@@ -28,7 +28,6 @@ import useHasNodes from './hooks/useHasNodes';
|
|
|
28
28
|
import AutoEmbedPlugin from './plugins/AutoEmbedPlugin';
|
|
29
29
|
import AutoLinkPlugin from './plugins/AutoLinkPlugin';
|
|
30
30
|
import ClickableLinkPlugin from './plugins/ClickableLinkPlugin';
|
|
31
|
-
import CodeActionMenuPlugin from './plugins/CodeActionMenuPlugin';
|
|
32
31
|
import CodeHighlightPlugin from './plugins/CodeHighlightPlugin';
|
|
33
32
|
import CollapsiblePlugin from './plugins/CollapsiblePlugin';
|
|
34
33
|
import ComponentPickerPlugin from './plugins/ComponentPickerPlugin';
|
|
@@ -77,6 +76,7 @@ import { useTranslationListener } from './hooks/useTranslationListener';
|
|
|
77
76
|
import { PagesKitComponentPlugin } from '../ext/PagesKitComponent/PagesKitComponentPlugin';
|
|
78
77
|
import { EditorHolderPlugin } from '../ext/EditorHolderPlugin';
|
|
79
78
|
import { StyledEditorContent } from './styled-editor-content';
|
|
79
|
+
import { CodeCopyPlugin } from '../ext/CodeCopyPlugin';
|
|
80
80
|
export default function Editor({ children, prepend, placeholder, onChange, autoFocus = true, showToolbar = true, editorRef, onReady, enableHeadingsIdPlugin, }) {
|
|
81
81
|
const [editor] = useLexicalComposerContext();
|
|
82
82
|
const [editable, setEditable] = useState(false);
|
|
@@ -106,7 +106,7 @@ export default function Editor({ children, prepend, placeholder, onChange, autoF
|
|
|
106
106
|
}
|
|
107
107
|
}, [hasNodes('image'), hasUploader]);
|
|
108
108
|
if (minimalMode) {
|
|
109
|
-
return (_jsxs(_Fragment, { children: [prepend, isRichText && editable && showToolbar && _jsx(ToolbarPlugin, {}), hasNodes('image') && hasUploader && _jsx(DragDropPaste, {}), autoFocus && _jsx(AutoFocusPlugin, { defaultSelection: "rootEnd" }), _jsx(ClearEditorPlugin, {}), !!editable && _jsx(ComponentPickerPlugin, {}), !!editable && _jsx(MentionsPlugin, {}), hasNodes('link') && _jsx(AutoEmbedPlugin, {}), _jsx(PasteSlackImagePlugin, {}), _jsx(StyledEditorContent, { ref: onRef, className: cx('be-content', editable && 'editable'), children: _jsx(RichTextPlugin, { contentEditable: _jsx(ContentEditable, { className: cx('be-editable', 'notranslate') }), placeholder: _jsx(Placeholder, { className: "be-placeholder", children: placeholder }), ErrorBoundary: LexicalErrorBoundary }) }), hasNodes('code', 'code-highlight') && _jsx(CodeHighlightPlugin, {}), hasNodes('image') && hasUploader && _jsx(ImagesPlugin, {}), hasNodes('video') && _jsx(VideoPlugin, {}), hasNodes('link') && _jsx(LinkPlugin, {}), hasNodes('tweet') && _jsx(TwitterPlugin, {}), hasNodes('youtube') && _jsx(YouTubePlugin, {}), hasNodes('figma') && _jsx(FigmaPlugin, {}), _jsx(PostLinkEmbedPlugin, {}), _jsx(BookmarkPlugin, {}), editable && _jsx(CustomOnChangePlugin, { placeholder: placeholder }), editable && _jsx(TemplatePlugin, {}), !editable && _jsx(BlurTextPlugin, {}), hasNodes('pdf') && _jsx(PdfPlugin, {}), hasNodes('file') && _jsx(FilePlugin, {}), hasNodes('horizontalrule') && _jsx(HorizontalRulePlugin, {}), hasNodes('excalidraw') && _jsx(ExcalidrawPlugin, {}), hasNodes('alert') && _jsx(AlertPlugin, {}), hasNodes('pages-kit-component') && _jsx(PagesKitComponentPlugin, {}), _jsx(TabFocusPlugin, {}), onChange && _jsx(OnChangePlugin, { onChange: onChange }), floatingAnchorElem && editable &&
|
|
109
|
+
return (_jsxs(_Fragment, { children: [prepend, isRichText && editable && showToolbar && _jsx(ToolbarPlugin, {}), hasNodes('image') && hasUploader && _jsx(DragDropPaste, {}), autoFocus && _jsx(AutoFocusPlugin, { defaultSelection: "rootEnd" }), _jsx(ClearEditorPlugin, {}), !!editable && _jsx(ComponentPickerPlugin, {}), !!editable && _jsx(MentionsPlugin, {}), hasNodes('link') && _jsx(AutoEmbedPlugin, {}), _jsx(PasteSlackImagePlugin, {}), _jsx(StyledEditorContent, { ref: onRef, className: cx('be-content', editable && 'editable'), children: _jsx(RichTextPlugin, { contentEditable: _jsx(ContentEditable, { className: cx('be-editable', 'notranslate') }), placeholder: _jsx(Placeholder, { className: "be-placeholder", children: placeholder }), ErrorBoundary: LexicalErrorBoundary }) }), hasNodes('code', 'code-highlight') && _jsx(CodeHighlightPlugin, {}), hasNodes('code') && _jsx(CodeCopyPlugin, {}), hasNodes('image') && hasUploader && _jsx(ImagesPlugin, {}), hasNodes('video') && _jsx(VideoPlugin, {}), hasNodes('link') && _jsx(LinkPlugin, {}), hasNodes('tweet') && _jsx(TwitterPlugin, {}), hasNodes('youtube') && _jsx(YouTubePlugin, {}), hasNodes('figma') && _jsx(FigmaPlugin, {}), _jsx(PostLinkEmbedPlugin, {}), _jsx(BookmarkPlugin, {}), editable && _jsx(CustomOnChangePlugin, { placeholder: placeholder }), editable && _jsx(TemplatePlugin, {}), !editable && _jsx(BlurTextPlugin, {}), hasNodes('pdf') && _jsx(PdfPlugin, {}), hasNodes('file') && _jsx(FilePlugin, {}), hasNodes('horizontalrule') && _jsx(HorizontalRulePlugin, {}), hasNodes('excalidraw') && _jsx(ExcalidrawPlugin, {}), hasNodes('alert') && _jsx(AlertPlugin, {}), hasNodes('pages-kit-component') && _jsx(PagesKitComponentPlugin, {}), _jsx(TabFocusPlugin, {}), onChange && _jsx(OnChangePlugin, { onChange: onChange }), floatingAnchorElem && editable && hasNodes('link') && (_jsx(FloatingLinkEditorPlugin, { anchorElem: floatingAnchorElem })), !!characterLimitConfig?.maxLength && (_jsx(CharacterLimitPlugin, { maxLength: characterLimitConfig.maxLength, charLimitIndicatorStyle: characterLimitConfig.indicatorStyle, alignLeft: characterLimitConfig.alignLeft })), editorRef && _jsx(EditorRefPlugin, { editorRef: editorRef }), children] }));
|
|
110
110
|
}
|
|
111
|
-
return (_jsxs(_Fragment, { children: [prepend, isRichText && editable && showToolbar && _jsx(ToolbarPlugin, {}), !!characterLimitConfig?.maxLength && (_jsx(CharacterLimitPlugin, { maxLength: characterLimitConfig.maxLength, charLimitIndicatorStyle: characterLimitConfig.indicatorStyle, alignLeft: characterLimitConfig.alignLeft })), hasNodes('image') && hasUploader && _jsx(DragDropPaste, {}), autoFocus && _jsx(AutoFocusPlugin, { defaultSelection: "rootEnd" }), _jsx(ClearEditorPlugin, {}), !!editable && _jsx(ComponentPickerPlugin, {}), !!editable && _jsx(EmojiPickerPlugin, {}), hasNodes('link') && _jsx(AutoEmbedPlugin, {}), !!editable && _jsx(MentionsPlugin, {}), hasNodes('hashtag') && _jsx(HashtagPlugin, {}), hasNodes('autolink') && !!editable && _jsx(AutoLinkPlugin, {}), isRichText ? (_jsxs(_Fragment, { children: [_jsx(PasteSlackImagePlugin, {}), _jsx(HistoryPlugin, { externalHistoryState: historyState }), _jsx(StyledEditorContent, { ref: onRef, className: cx('be-content', editable && 'editable'), children: _jsx(RichTextPlugin, { contentEditable: _jsx(ContentEditable, { className: cx('be-editable', 'notranslate') }), placeholder: _jsx(Placeholder, { className: "be-placeholder", children: placeholder }), ErrorBoundary: LexicalErrorBoundary }) }), _jsx(MarkdownShortcutPlugin, {}), _jsx(TabIndentationPlugin, {}), hasNodes('code', 'code-highlight') && _jsx(CodeHighlightPlugin, {}), hasNodes('list', 'listitem') && _jsx(ListPlugin, {}), hasNodes('list', 'listitem') && _jsx(CheckListPlugin, {}), hasNodes('list', 'listitem') && _jsx(ListMaxIndentLevelPlugin, { maxDepth: 7 }), hasNodes('table', 'tablerow', 'tablecell') && editable && (_jsx(TablePlugin, { hasCellMerge: true, hasCellBackgroundColor: true, hasHorizontalScroll: true })), hasNodes('table', 'tablerow', 'tablecell') && _jsx(TableCellResizer, {}), hasNodes('image') && hasUploader && _jsx(ImagesPlugin, {}), hasNodes('video') && _jsx(VideoPlugin, {}), hasNodes('link') && _jsx(LinkPlugin, {}), hasNodes('tweet') && _jsx(TwitterPlugin, {}), hasNodes('youtube') && _jsx(YouTubePlugin, {}), hasNodes('figma') && _jsx(FigmaPlugin, {}), _jsx(BilibiliPlugin, {}), _jsx(BlockletEmbedPlugin, {}), _jsx(PostLinkEmbedPlugin, {}), _jsx(BookmarkPlugin, {}), _jsx(AidePlugin, {}), editable && _jsx(CustomOnChangePlugin, { placeholder: placeholder }), editable && _jsx(TemplatePlugin, {}), !editable && _jsx(BlurTextPlugin, {}), hasNodes('pdf') && _jsx(PdfPlugin, {}), hasNodes('file') && _jsx(FilePlugin, {}), hasNodes('link') && _jsx(ClickableLinkPlugin, {}), hasNodes('horizontalrule') && _jsx(HorizontalRulePlugin, {}), hasNodes('excalidraw') && _jsx(ExcalidrawPlugin, {}), hasNodes('alert') && _jsx(AlertPlugin, {}), hasNodes('pages-kit-component') && _jsx(PagesKitComponentPlugin, {}), _jsx(TabFocusPlugin, {}), hasNodes('collapsible-container', 'collapsible-content', 'collapsible-title') && _jsx(CollapsiblePlugin, {}), onChange && _jsx(OnChangePlugin, { onChange: onChange }), floatingAnchorElem && editable && (_jsxs(_Fragment, { children: [_jsx(DraggableBlockPlugin, { anchorElem: floatingAnchorElem }), hasNodes('
|
|
111
|
+
return (_jsxs(_Fragment, { children: [prepend, isRichText && editable && showToolbar && _jsx(ToolbarPlugin, {}), !!characterLimitConfig?.maxLength && (_jsx(CharacterLimitPlugin, { maxLength: characterLimitConfig.maxLength, charLimitIndicatorStyle: characterLimitConfig.indicatorStyle, alignLeft: characterLimitConfig.alignLeft })), hasNodes('image') && hasUploader && _jsx(DragDropPaste, {}), autoFocus && _jsx(AutoFocusPlugin, { defaultSelection: "rootEnd" }), _jsx(ClearEditorPlugin, {}), !!editable && _jsx(ComponentPickerPlugin, {}), !!editable && _jsx(EmojiPickerPlugin, {}), hasNodes('link') && _jsx(AutoEmbedPlugin, {}), !!editable && _jsx(MentionsPlugin, {}), hasNodes('hashtag') && _jsx(HashtagPlugin, {}), hasNodes('autolink') && !!editable && _jsx(AutoLinkPlugin, {}), isRichText ? (_jsxs(_Fragment, { children: [_jsx(PasteSlackImagePlugin, {}), _jsx(HistoryPlugin, { externalHistoryState: historyState }), _jsx(StyledEditorContent, { ref: onRef, className: cx('be-content', editable && 'editable'), children: _jsx(RichTextPlugin, { contentEditable: _jsx(ContentEditable, { className: cx('be-editable', 'notranslate') }), placeholder: _jsx(Placeholder, { className: "be-placeholder", children: placeholder }), ErrorBoundary: LexicalErrorBoundary }) }), _jsx(MarkdownShortcutPlugin, {}), _jsx(TabIndentationPlugin, {}), hasNodes('code', 'code-highlight') && _jsx(CodeHighlightPlugin, {}), hasNodes('code') && _jsx(CodeCopyPlugin, {}), hasNodes('list', 'listitem') && _jsx(ListPlugin, {}), hasNodes('list', 'listitem') && _jsx(CheckListPlugin, {}), hasNodes('list', 'listitem') && _jsx(ListMaxIndentLevelPlugin, { maxDepth: 7 }), hasNodes('table', 'tablerow', 'tablecell') && editable && (_jsx(TablePlugin, { hasCellMerge: true, hasCellBackgroundColor: true, hasHorizontalScroll: true })), hasNodes('table', 'tablerow', 'tablecell') && _jsx(TableCellResizer, {}), hasNodes('image') && hasUploader && _jsx(ImagesPlugin, {}), hasNodes('video') && _jsx(VideoPlugin, {}), hasNodes('link') && _jsx(LinkPlugin, {}), hasNodes('tweet') && _jsx(TwitterPlugin, {}), hasNodes('youtube') && _jsx(YouTubePlugin, {}), hasNodes('figma') && _jsx(FigmaPlugin, {}), _jsx(BilibiliPlugin, {}), _jsx(BlockletEmbedPlugin, {}), _jsx(PostLinkEmbedPlugin, {}), _jsx(BookmarkPlugin, {}), _jsx(AidePlugin, {}), editable && _jsx(CustomOnChangePlugin, { placeholder: placeholder }), editable && _jsx(TemplatePlugin, {}), !editable && _jsx(BlurTextPlugin, {}), hasNodes('pdf') && _jsx(PdfPlugin, {}), hasNodes('file') && _jsx(FilePlugin, {}), hasNodes('link') && _jsx(ClickableLinkPlugin, {}), hasNodes('horizontalrule') && _jsx(HorizontalRulePlugin, {}), hasNodes('excalidraw') && _jsx(ExcalidrawPlugin, {}), hasNodes('alert') && _jsx(AlertPlugin, {}), hasNodes('pages-kit-component') && _jsx(PagesKitComponentPlugin, {}), _jsx(TabFocusPlugin, {}), hasNodes('collapsible-container', 'collapsible-content', 'collapsible-title') && _jsx(CollapsiblePlugin, {}), onChange && _jsx(OnChangePlugin, { onChange: onChange }), floatingAnchorElem && editable && (_jsxs(_Fragment, { children: [_jsx(DraggableBlockPlugin, { anchorElem: floatingAnchorElem }), hasNodes('link') && _jsx(FloatingLinkEditorPlugin, { anchorElem: floatingAnchorElem }), hasNodes('table') && _jsx(TableCellActionMenuPlugin, { anchorElem: floatingAnchorElem, cellMerge: true }), _jsx(FloatingTextFormatToolbarPlugin, { anchorElem: floatingAnchorElem })] })), enableHeadingsIdPlugin && _jsx(HeadingsIdPlugin, {})] })) : (_jsxs(_Fragment, { children: [_jsx(PlainTextPlugin, { contentEditable: _jsx(ContentEditable, {}), placeholder: _jsx(Placeholder, { children: "placeholder" }), ErrorBoundary: LexicalErrorBoundary }), _jsx(HistoryPlugin, { externalHistoryState: historyState })] })), _jsx("div", { children: showTableOfContents && _jsx(TableOfContentsPlugin, {}) }), _jsx(MarkdownHeadTextPlugin, {}), _jsx(EditorHolderPlugin, {}), editorRef && _jsx(EditorRefPlugin, { editorRef: editorRef }), onReady && _jsx(EditorReadyPlugin, { onReady: onReady }), children] }));
|
|
112
112
|
}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
export declare const codeHighlightDark: {
|
|
2
|
+
atrule: string;
|
|
3
|
+
attr: string;
|
|
4
|
+
boolean: string;
|
|
5
|
+
builtin: string;
|
|
6
|
+
cdata: string;
|
|
7
|
+
char: string;
|
|
8
|
+
class: string;
|
|
9
|
+
comment: string;
|
|
10
|
+
constant: string;
|
|
11
|
+
deleted: string;
|
|
12
|
+
doctype: string;
|
|
13
|
+
entity: string;
|
|
14
|
+
function: string;
|
|
15
|
+
important: string;
|
|
16
|
+
inserted: string;
|
|
17
|
+
keyword: string;
|
|
18
|
+
namespace: string;
|
|
19
|
+
number: string;
|
|
20
|
+
operator: string;
|
|
21
|
+
prolog: string;
|
|
22
|
+
property: string;
|
|
23
|
+
punctuation: string;
|
|
24
|
+
regex: string;
|
|
25
|
+
selector: string;
|
|
26
|
+
string: string;
|
|
27
|
+
symbol: string;
|
|
28
|
+
tag: string;
|
|
29
|
+
url: string;
|
|
30
|
+
variable: string;
|
|
31
|
+
};
|
|
32
|
+
export declare const codeHighlightLight: {
|
|
33
|
+
atrule: string;
|
|
34
|
+
attr: string;
|
|
35
|
+
boolean: string;
|
|
36
|
+
builtin: string;
|
|
37
|
+
cdata: string;
|
|
38
|
+
char: string;
|
|
39
|
+
class: string;
|
|
40
|
+
comment: string;
|
|
41
|
+
constant: string;
|
|
42
|
+
deleted: string;
|
|
43
|
+
doctype: string;
|
|
44
|
+
entity: string;
|
|
45
|
+
function: string;
|
|
46
|
+
important: string;
|
|
47
|
+
inserted: string;
|
|
48
|
+
keyword: string;
|
|
49
|
+
namespace: string;
|
|
50
|
+
number: string;
|
|
51
|
+
operator: string;
|
|
52
|
+
prolog: string;
|
|
53
|
+
property: string;
|
|
54
|
+
punctuation: string;
|
|
55
|
+
regex: string;
|
|
56
|
+
selector: string;
|
|
57
|
+
string: string;
|
|
58
|
+
symbol: string;
|
|
59
|
+
tag: string;
|
|
60
|
+
url: string;
|
|
61
|
+
variable: string;
|
|
62
|
+
};
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
import { css } from '@emotion/css';
|
|
2
|
+
// Dark theme tokens
|
|
3
|
+
const tokenComment = css `
|
|
4
|
+
color: #6a9955;
|
|
5
|
+
`;
|
|
6
|
+
const tokenPunctuation = css `
|
|
7
|
+
color: #d4d4d4;
|
|
8
|
+
`;
|
|
9
|
+
const tokenProperty = css `
|
|
10
|
+
color: #9cdcfe;
|
|
11
|
+
`;
|
|
12
|
+
const tokenSelector = css `
|
|
13
|
+
color: #d7ba7d;
|
|
14
|
+
`;
|
|
15
|
+
const tokenOperator = css `
|
|
16
|
+
color: #d4d4d4;
|
|
17
|
+
`;
|
|
18
|
+
const tokenAttr = css `
|
|
19
|
+
color: #9cdcfe;
|
|
20
|
+
`;
|
|
21
|
+
const tokenVariable = css `
|
|
22
|
+
color: #9cdcfe;
|
|
23
|
+
`;
|
|
24
|
+
const tokenFunction = css `
|
|
25
|
+
color: #dcdcaa;
|
|
26
|
+
`;
|
|
27
|
+
// Light theme tokens - 更有活力和年轻化的配色,优化对比度
|
|
28
|
+
const tokenCommentLight = css `
|
|
29
|
+
color: #1e8449;
|
|
30
|
+
`;
|
|
31
|
+
const tokenPunctuationLight = css `
|
|
32
|
+
color: #2c3e50;
|
|
33
|
+
`;
|
|
34
|
+
const tokenPropertyLight = css `
|
|
35
|
+
color: #e67e22;
|
|
36
|
+
`;
|
|
37
|
+
const tokenSelectorLight = css `
|
|
38
|
+
color: #c0392b;
|
|
39
|
+
`;
|
|
40
|
+
const tokenOperatorLight = css `
|
|
41
|
+
color: #8e44ad;
|
|
42
|
+
`;
|
|
43
|
+
const tokenAttrLight = css `
|
|
44
|
+
color: #2980b9;
|
|
45
|
+
`;
|
|
46
|
+
const tokenVariableLight = css `
|
|
47
|
+
color: #27ae60;
|
|
48
|
+
`;
|
|
49
|
+
const tokenFunctionLight = css `
|
|
50
|
+
color: #f39c12;
|
|
51
|
+
`;
|
|
52
|
+
export const codeHighlightDark = {
|
|
53
|
+
atrule: tokenAttr,
|
|
54
|
+
attr: tokenAttr,
|
|
55
|
+
boolean: tokenProperty,
|
|
56
|
+
builtin: tokenSelector,
|
|
57
|
+
cdata: tokenComment,
|
|
58
|
+
char: tokenSelector,
|
|
59
|
+
class: tokenFunction,
|
|
60
|
+
comment: tokenComment,
|
|
61
|
+
constant: tokenProperty,
|
|
62
|
+
deleted: tokenProperty,
|
|
63
|
+
doctype: tokenComment,
|
|
64
|
+
entity: tokenOperator,
|
|
65
|
+
function: tokenFunction,
|
|
66
|
+
important: tokenVariable,
|
|
67
|
+
inserted: tokenSelector,
|
|
68
|
+
keyword: tokenAttr,
|
|
69
|
+
namespace: tokenVariable,
|
|
70
|
+
number: tokenProperty,
|
|
71
|
+
operator: tokenOperator,
|
|
72
|
+
prolog: tokenComment,
|
|
73
|
+
property: tokenProperty,
|
|
74
|
+
punctuation: tokenPunctuation,
|
|
75
|
+
regex: tokenVariable,
|
|
76
|
+
selector: tokenSelector,
|
|
77
|
+
string: tokenSelector,
|
|
78
|
+
symbol: tokenProperty,
|
|
79
|
+
tag: tokenProperty,
|
|
80
|
+
url: tokenOperator,
|
|
81
|
+
variable: tokenVariable,
|
|
82
|
+
};
|
|
83
|
+
export const codeHighlightLight = {
|
|
84
|
+
atrule: tokenAttrLight,
|
|
85
|
+
attr: tokenAttrLight,
|
|
86
|
+
boolean: tokenPropertyLight,
|
|
87
|
+
builtin: tokenSelectorLight,
|
|
88
|
+
cdata: tokenCommentLight,
|
|
89
|
+
char: tokenSelectorLight,
|
|
90
|
+
class: tokenFunctionLight,
|
|
91
|
+
comment: tokenCommentLight,
|
|
92
|
+
constant: tokenPropertyLight,
|
|
93
|
+
deleted: tokenPropertyLight,
|
|
94
|
+
doctype: tokenCommentLight,
|
|
95
|
+
entity: tokenOperatorLight,
|
|
96
|
+
function: tokenFunctionLight,
|
|
97
|
+
important: tokenVariableLight,
|
|
98
|
+
inserted: tokenSelectorLight,
|
|
99
|
+
keyword: tokenAttrLight,
|
|
100
|
+
namespace: tokenVariableLight,
|
|
101
|
+
number: tokenPropertyLight,
|
|
102
|
+
operator: tokenOperatorLight,
|
|
103
|
+
prolog: tokenCommentLight,
|
|
104
|
+
property: tokenPropertyLight,
|
|
105
|
+
punctuation: tokenPunctuationLight,
|
|
106
|
+
regex: tokenVariableLight,
|
|
107
|
+
selector: tokenSelectorLight,
|
|
108
|
+
string: tokenSelectorLight,
|
|
109
|
+
symbol: tokenPropertyLight,
|
|
110
|
+
tag: tokenPropertyLight,
|
|
111
|
+
url: tokenOperatorLight,
|
|
112
|
+
variable: tokenVariableLight,
|
|
113
|
+
};
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { css } from '@emotion/css';
|
|
2
2
|
import { useTheme } from '@mui/material';
|
|
3
3
|
import defaultTheme from './defaultTheme';
|
|
4
|
+
import { codeHighlightLight, codeHighlightDark } from './code-highlight';
|
|
4
5
|
const createCustomTheme = (theme) => {
|
|
5
6
|
const { palette } = theme;
|
|
6
7
|
const noMarginTopStyle = css(`
|
|
@@ -235,8 +236,8 @@ const createCustomTheme = (theme) => {
|
|
|
235
236
|
}
|
|
236
237
|
`;
|
|
237
238
|
const code = css `
|
|
238
|
-
background-color:
|
|
239
|
-
color:
|
|
239
|
+
background-color: ${palette.background.paper};
|
|
240
|
+
color: ${palette.text.primary};
|
|
240
241
|
font-family: Menlo, Consolas, Monaco, monospace;
|
|
241
242
|
display: block;
|
|
242
243
|
// padding: 16px;
|
|
@@ -251,12 +252,11 @@ const createCustomTheme = (theme) => {
|
|
|
251
252
|
overflow-x: auto;
|
|
252
253
|
position: relative;
|
|
253
254
|
border-radius: 8px;
|
|
254
|
-
border: 1px solid
|
|
255
|
+
border: 1px solid ${palette.divider};
|
|
255
256
|
|
|
256
257
|
&:before {
|
|
257
258
|
content: attr(data-gutter);
|
|
258
259
|
position: absolute;
|
|
259
|
-
background-color: #18181b;
|
|
260
260
|
left: 0;
|
|
261
261
|
top: 0;
|
|
262
262
|
// border-right: 1px solid #ccc;
|
|
@@ -296,6 +296,7 @@ const createCustomTheme = (theme) => {
|
|
|
296
296
|
olDepth: [ol1, ol2, ol3, ol4, ol5],
|
|
297
297
|
ul,
|
|
298
298
|
},
|
|
299
|
+
codeHighlight: palette.mode === 'dark' ? codeHighlightDark : codeHighlightLight,
|
|
299
300
|
embedBlock: {
|
|
300
301
|
base: embedBlock,
|
|
301
302
|
focus: embedBlockFocus,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@blocklet/editor",
|
|
3
|
-
"version": "2.4.
|
|
3
|
+
"version": "2.4.16",
|
|
4
4
|
"main": "lib/index.js",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public"
|
|
@@ -32,6 +32,7 @@
|
|
|
32
32
|
"@excalidraw/excalidraw": "^0.18.0",
|
|
33
33
|
"@iconify/iconify": "^3.1.1",
|
|
34
34
|
"@iconify/icons-tabler": "^1.2.95",
|
|
35
|
+
"@iconify/react": "^4.1.1",
|
|
35
36
|
"@lexical/clipboard": "^0.30.0",
|
|
36
37
|
"@lexical/code": "^0.30.0",
|
|
37
38
|
"@lexical/file": "^0.30.0",
|
|
@@ -68,7 +69,7 @@
|
|
|
68
69
|
"ufo": "^1.5.4",
|
|
69
70
|
"url-join": "^4.0.1",
|
|
70
71
|
"zustand": "^4.5.5",
|
|
71
|
-
"@blocklet/pdf": "^2.4.
|
|
72
|
+
"@blocklet/pdf": "^2.4.16"
|
|
72
73
|
},
|
|
73
74
|
"devDependencies": {
|
|
74
75
|
"@babel/core": "^7.25.2",
|