mirror of https://github.com/fantasticit/think.git
feat: add sub/sup script support
This commit is contained in:
parent
fd4c2de11d
commit
f0e7950c5f
|
@ -39,6 +39,8 @@
|
|||
"@tiptap/extension-paragraph": "^2.0.0-beta.23",
|
||||
"@tiptap/extension-placeholder": "^2.0.0-beta.47",
|
||||
"@tiptap/extension-strike": "^2.0.0-beta.27",
|
||||
"@tiptap/extension-subscript": "^2.0.0-beta.10",
|
||||
"@tiptap/extension-superscript": "^2.0.0-beta.10",
|
||||
"@tiptap/extension-table": "^2.0.0-beta.48",
|
||||
"@tiptap/extension-table-cell": "^2.0.0-beta.20",
|
||||
"@tiptap/extension-table-header": "^2.0.0-beta.22",
|
||||
|
|
|
@ -0,0 +1,22 @@
|
|||
import { Icon } from '@douyinfe/semi-ui';
|
||||
|
||||
export const IconSub: React.FC<{ style?: React.CSSProperties }> = ({ style = {} }) => {
|
||||
return (
|
||||
<Icon
|
||||
style={style}
|
||||
svg={
|
||||
<svg width="16" height="16" viewBox="0 0 256 256" role="presentation">
|
||||
<g stroke="currentColor" fill="none" fill-rule="evenodd">
|
||||
<path stroke-width="20" stroke-linecap="round" d="m40 50 114 168M154 50 40 218"></path>
|
||||
<path
|
||||
d="M231.92 225.48c2.72 0 4.08-1.48 4.08-4.44 0-2.88-1.36-4.32-4.08-4.32H198.8c6.48-5.52 12.28-11.24 17.4-17.16 2.16-2.48 4.28-5.16 6.36-8.04 2.08-2.88 3.94-5.82 5.58-8.82 1.64-3 2.96-6.04 3.96-9.12 1-3.08 1.5-6.14 1.5-9.18 0-3.36-.48-6.42-1.44-9.18s-2.38-5.12-4.26-7.08-4.2-3.48-6.96-4.56c-2.76-1.08-5.9-1.62-9.42-1.62-7.92 0-13.8 2.26-17.64 6.78-3.84 4.52-5.76 10.66-5.76 18.42 0 2.24.32 3.74.96 4.5.64.76 1.96 1.14 3.96 1.14 1.76 0 2.98-.44 3.66-1.32.68-.88 1.02-2.32 1.02-4.32 0-4.8 1.04-8.74 3.12-11.82s5.4-4.62 9.96-4.62c4 0 7.16 1.32 9.48 3.96 2.32 2.64 3.48 6.12 3.48 10.44 0 3.2-.64 6.42-1.92 9.66-1.28 3.24-2.94 6.4-4.98 9.48a84.099 84.099 0 0 1-6.84 8.94c-2.52 2.88-5.04 5.6-7.56 8.16-2.52 2.56-4.92 4.94-7.2 7.14-2.28 2.2-4.18 4.1-5.7 5.7-.64 1.04-.96 2.04-.96 3-.56 1.04-.86 2.06-.9 3.06-.04 1 .1 1.88.42 2.64.32.76.8 1.38 1.44 1.86.64.48 1.36.72 2.16.72h40.2Z"
|
||||
strokeWidth="5"
|
||||
fill="currentColor"
|
||||
fillRule="nonzero"
|
||||
></path>
|
||||
</g>
|
||||
</svg>
|
||||
}
|
||||
/>
|
||||
);
|
||||
};
|
|
@ -0,0 +1,22 @@
|
|||
import { Icon } from '@douyinfe/semi-ui';
|
||||
|
||||
export const IconSup: React.FC<{ style?: React.CSSProperties }> = ({ style = {} }) => {
|
||||
return (
|
||||
<Icon
|
||||
style={style}
|
||||
svg={
|
||||
<svg width="16" height="16" viewBox="0 0 256 256" role="presentation">
|
||||
<g stroke="currentColor" fill="none" fill-rule="evenodd">
|
||||
<path stroke-width="20" stroke-linecap="round" d="m40 50 114 168M154 50 40 218"></path>
|
||||
<path
|
||||
d="M231.92 103.48c2.72 0 4.08-1.48 4.08-4.44 0-2.88-1.36-4.32-4.08-4.32H198.8c6.48-5.52 12.28-11.24 17.4-17.16 2.16-2.48 4.28-5.16 6.36-8.04 2.08-2.88 3.94-5.82 5.58-8.82 1.64-3 2.96-6.04 3.96-9.12 1-3.08 1.5-6.14 1.5-9.18 0-3.36-.48-6.42-1.44-9.18s-2.38-5.12-4.26-7.08-4.2-3.48-6.96-4.56c-2.76-1.08-5.9-1.62-9.42-1.62-7.92 0-13.8 2.26-17.64 6.78-3.84 4.52-5.76 10.66-5.76 18.42 0 2.24.32 3.74.96 4.5.64.76 1.96 1.14 3.96 1.14 1.76 0 2.98-.44 3.66-1.32.68-.88 1.02-2.32 1.02-4.32 0-4.8 1.04-8.74 3.12-11.82s5.4-4.62 9.96-4.62c4 0 7.16 1.32 9.48 3.96 2.32 2.64 3.48 6.12 3.48 10.44 0 3.2-.64 6.42-1.92 9.66-1.28 3.24-2.94 6.4-4.98 9.48a84.099 84.099 0 0 1-6.84 8.94c-2.52 2.88-5.04 5.6-7.56 8.16-2.52 2.56-4.92 4.94-7.2 7.14-2.28 2.2-4.18 4.1-5.7 5.7-.64 1.04-.96 2.04-.96 3-.56 1.04-.86 2.06-.9 3.06-.04 1 .1 1.88.42 2.64.32.76.8 1.38 1.44 1.86.64.48 1.36.72 2.16.72h40.2Z"
|
||||
strokeWidth="5"
|
||||
fill="currentColor"
|
||||
fillRule="nonzero"
|
||||
></path>
|
||||
</g>
|
||||
</svg>
|
||||
}
|
||||
/>
|
||||
);
|
||||
};
|
|
@ -45,3 +45,5 @@ export * from './IconHeading3';
|
|||
export * from './IconTableHeaderRow';
|
||||
export * from './IconTableHeaderColumn';
|
||||
export * from './IconTableHeaderCell';
|
||||
export * from './IconSub';
|
||||
export * from './IconSup';
|
||||
|
|
|
@ -36,6 +36,8 @@ import { SearchNReplace } from './extensions/search';
|
|||
import { SelectionExtension } from './extensions/selection';
|
||||
import { Status } from './extensions/status';
|
||||
import { Strike } from './extensions/strike';
|
||||
import { Subscript } from './extensions/subscript';
|
||||
import { Superscript } from './extensions/superscript';
|
||||
import { Table } from './extensions/table';
|
||||
import { TableCell } from './extensions/tableCell';
|
||||
import { TableHeader } from './extensions/tableHeader';
|
||||
|
@ -89,6 +91,8 @@ export const BaseKit = [
|
|||
SelectionExtension,
|
||||
Status,
|
||||
Strike,
|
||||
Subscript,
|
||||
Superscript,
|
||||
Table,
|
||||
TableCell,
|
||||
TableHeader,
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
import Subscript from '@tiptap/extension-subscript';
|
||||
|
||||
export { Subscript };
|
|
@ -0,0 +1,3 @@
|
|||
import Superscript from '@tiptap/extension-superscript';
|
||||
|
||||
export { Superscript };
|
|
@ -1,6 +1,7 @@
|
|||
import React from 'react';
|
||||
import { Button } from '@douyinfe/semi-ui';
|
||||
import { IconBold, IconItalic, IconStrikeThrough, IconUnderline, IconCode } from '@douyinfe/semi-icons';
|
||||
import { IconSup, IconSub } from 'components/icons';
|
||||
import { Tooltip } from 'components/tooltip';
|
||||
import { isTitleActive } from '../services/isActive';
|
||||
import { ColorMenu } from './color';
|
||||
|
@ -62,6 +63,26 @@ export const BaseMenu: React.FC<{ editor: any }> = ({ editor }) => {
|
|||
/>
|
||||
</Tooltip>
|
||||
|
||||
<Tooltip content="上标">
|
||||
<Button
|
||||
theme={editor.isActive('superscript') ? 'light' : 'borderless'}
|
||||
type="tertiary"
|
||||
icon={<IconSup />}
|
||||
onClick={() => editor.chain().focus().toggleSuperscript().run()}
|
||||
disabled={isTitleActive(editor)}
|
||||
/>
|
||||
</Tooltip>
|
||||
|
||||
<Tooltip content="下标">
|
||||
<Button
|
||||
theme={editor.isActive('subscript') ? 'light' : 'borderless'}
|
||||
type="tertiary"
|
||||
icon={<IconSub />}
|
||||
onClick={() => editor.chain().focus().toggleSubscript().run()}
|
||||
disabled={isTitleActive(editor)}
|
||||
/>
|
||||
</Tooltip>
|
||||
|
||||
<ColorMenu editor={editor} />
|
||||
</>
|
||||
);
|
||||
|
|
|
@ -0,0 +1,13 @@
|
|||
import { Mark } from './mark';
|
||||
|
||||
export class Subscript extends Mark {
|
||||
matching() {
|
||||
return this.DOMNode.nodeName === 'SUB';
|
||||
}
|
||||
|
||||
data() {
|
||||
return {
|
||||
type: 'subscript',
|
||||
};
|
||||
}
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
import { Mark } from './mark';
|
||||
|
||||
export class Superscript extends Mark {
|
||||
matching() {
|
||||
return this.DOMNode.nodeName === 'SUP';
|
||||
}
|
||||
|
||||
data() {
|
||||
return {
|
||||
type: 'superscript',
|
||||
};
|
||||
}
|
||||
}
|
|
@ -36,6 +36,8 @@ import { Bold } from './marks/bold';
|
|||
import { Code } from './marks/code';
|
||||
import { Italic } from './marks/italic';
|
||||
import { Link } from './marks/link';
|
||||
import { Subscript } from './marks/subscript';
|
||||
import { Superscript } from './marks/superscript';
|
||||
import { Underline } from './marks/underline';
|
||||
|
||||
export class Renderer {
|
||||
|
@ -84,7 +86,7 @@ export class Renderer {
|
|||
BulletList,
|
||||
];
|
||||
|
||||
this.marks = [Bold, Code, Italic, Link, Underline];
|
||||
this.marks = [Bold, Code, Italic, Link, Subscript, Superscript, Underline];
|
||||
}
|
||||
|
||||
setDocument(document) {
|
||||
|
|
|
@ -22,6 +22,8 @@ import { OrderedList } from '../../../extensions/orderedList';
|
|||
import { Paragraph } from '../../../extensions/paragraph';
|
||||
import { Status } from '../../../extensions/status';
|
||||
import { Strike } from '../../../extensions/strike';
|
||||
import { Subscript } from '../../../extensions/subscript';
|
||||
import { Superscript } from '../../../extensions/superscript';
|
||||
import { Table } from '../../../extensions/table';
|
||||
import { TableCell } from '../../../extensions/tableCell';
|
||||
import { TableHeader } from '../../../extensions/tableHeader';
|
||||
|
@ -67,6 +69,8 @@ const SerializerConfig = {
|
|||
mixable: true,
|
||||
expelEnclosingWhitespace: true,
|
||||
},
|
||||
[Subscript.name]: { open: '<sub>', close: '</sub>', mixable: true },
|
||||
[Superscript.name]: { open: '<sup>', close: '</sup>', mixable: true },
|
||||
// FIXME: 如何导出 style?
|
||||
[TextStyle.name]: { open: '', close: '', mixable: true, expelEnclosingWhitespace: true },
|
||||
...marks.reduce(
|
||||
|
|
|
@ -73,6 +73,8 @@ importers:
|
|||
'@tiptap/extension-paragraph': ^2.0.0-beta.23
|
||||
'@tiptap/extension-placeholder': ^2.0.0-beta.47
|
||||
'@tiptap/extension-strike': ^2.0.0-beta.27
|
||||
'@tiptap/extension-subscript': ^2.0.0-beta.10
|
||||
'@tiptap/extension-superscript': ^2.0.0-beta.10
|
||||
'@tiptap/extension-table': ^2.0.0-beta.48
|
||||
'@tiptap/extension-table-cell': ^2.0.0-beta.20
|
||||
'@tiptap/extension-table-header': ^2.0.0-beta.22
|
||||
|
@ -150,6 +152,8 @@ importers:
|
|||
'@tiptap/extension-paragraph': 2.0.0-beta.23_@tiptap+core@2.0.0-beta.171
|
||||
'@tiptap/extension-placeholder': 2.0.0-beta.47_@tiptap+core@2.0.0-beta.171
|
||||
'@tiptap/extension-strike': 2.0.0-beta.27_@tiptap+core@2.0.0-beta.171
|
||||
'@tiptap/extension-subscript': 2.0.0-beta.10_@tiptap+core@2.0.0-beta.171
|
||||
'@tiptap/extension-superscript': 2.0.0-beta.10_@tiptap+core@2.0.0-beta.171
|
||||
'@tiptap/extension-table': 2.0.0-beta.48_@tiptap+core@2.0.0-beta.171
|
||||
'@tiptap/extension-table-cell': 2.0.0-beta.20_@tiptap+core@2.0.0-beta.171
|
||||
'@tiptap/extension-table-header': 2.0.0-beta.22_@tiptap+core@2.0.0-beta.171
|
||||
|
@ -1807,6 +1811,22 @@ packages:
|
|||
'@tiptap/core': 2.0.0-beta.171
|
||||
dev: false
|
||||
|
||||
/@tiptap/extension-subscript/2.0.0-beta.10_@tiptap+core@2.0.0-beta.171:
|
||||
resolution: {integrity: sha512-er8/1lp0Rb+SKwEioW0w4oVf3EkdQZ0WS/5kPBG4W0DncfUMT+bw5de76S3kRL9PLZ9UShAL7wuXtuiSi5QsMw==}
|
||||
peerDependencies:
|
||||
'@tiptap/core': ^2.0.0-beta.1
|
||||
dependencies:
|
||||
'@tiptap/core': 2.0.0-beta.171
|
||||
dev: false
|
||||
|
||||
/@tiptap/extension-superscript/2.0.0-beta.10_@tiptap+core@2.0.0-beta.171:
|
||||
resolution: {integrity: sha512-TUUBS8XsD2MorGORYVlhGDH7wcc9diSbHscD4Dnz8pKWVR0JPUd/od4h5qSffDzAOKxtphTiX9LOFWk6zVooKg==}
|
||||
peerDependencies:
|
||||
'@tiptap/core': ^2.0.0-beta.1
|
||||
dependencies:
|
||||
'@tiptap/core': 2.0.0-beta.171
|
||||
dev: false
|
||||
|
||||
/@tiptap/extension-table-cell/2.0.0-beta.20_@tiptap+core@2.0.0-beta.171:
|
||||
resolution: {integrity: sha512-IllQyxLQvgm1FAewz3U+DkgNHRthmuVrtUQnG6la45qdUOLCOrpFbRRaQ1LJ/BpbvZ2Xs1o2yAa97BqZOPwovQ==}
|
||||
peerDependencies:
|
||||
|
|
Loading…
Reference in New Issue