Use editorjs instead of draftail
This commit is contained in:
parent
f3b399830c
commit
dab8064e26
6 changed files with 245 additions and 361 deletions
44
package-lock.json
generated
44
package-lock.json
generated
|
@ -1949,6 +1949,35 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"@editorjs/editorjs": {
|
||||||
|
"version": "2.19.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@editorjs/editorjs/-/editorjs-2.19.0.tgz",
|
||||||
|
"integrity": "sha512-8PUVaBZx69IrG8dNrE+FZbHSiRTR8ql8L/cmEi1mOdEdTqnOLq5Wv9dgemK00mBWEgNoavMAjtGQpItGknAa8A==",
|
||||||
|
"requires": {
|
||||||
|
"codex-notifier": "^1.1.2",
|
||||||
|
"codex-tooltip": "^1.0.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"@editorjs/header": {
|
||||||
|
"version": "2.6.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@editorjs/header/-/header-2.6.0.tgz",
|
||||||
|
"integrity": "sha512-1psNX/irDjJ8Bp1l7DjkYWz7IBtjVIRANk7kPkNoY2CfAeeCFYbJmMlXdqTF2WeAjYv2WMy5ey/aR5fTccgFaw=="
|
||||||
|
},
|
||||||
|
"@editorjs/image": {
|
||||||
|
"version": "2.6.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@editorjs/image/-/image-2.6.0.tgz",
|
||||||
|
"integrity": "sha512-lX4Pz9cW3gGFzlmYLRAsBXTiqUG/MRG7NK4QVU+n/VnUWPU1e791eiIpgRLHfpPj6Maaw5a+GRut90D5EdXtqg=="
|
||||||
|
},
|
||||||
|
"@editorjs/list": {
|
||||||
|
"version": "1.6.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@editorjs/list/-/list-1.6.0.tgz",
|
||||||
|
"integrity": "sha512-2oJ3Nj3lDcIKS6GcrHYHzUUabIjg7zlXTYXQWdEWXevbnM0/fq+4psyI/AYtqbaa3jN+bycPBIW4OG3zD+3d5A=="
|
||||||
|
},
|
||||||
|
"@editorjs/quote": {
|
||||||
|
"version": "2.4.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@editorjs/quote/-/quote-2.4.0.tgz",
|
||||||
|
"integrity": "sha512-IWOBWjL2ngPP63GcIAltyD9kc7OVZFma4kS+T5JRHvKKDspYsnmrxsbRmCPc+coZQzqPxXHkiOZuNMdmGX/Y3w=="
|
||||||
|
},
|
||||||
"@emotion/cache": {
|
"@emotion/cache": {
|
||||||
"version": "10.0.19",
|
"version": "10.0.19",
|
||||||
"resolved": "https://registry.npmjs.org/@emotion/cache/-/cache-10.0.19.tgz",
|
"resolved": "https://registry.npmjs.org/@emotion/cache/-/cache-10.0.19.tgz",
|
||||||
|
@ -8778,6 +8807,16 @@
|
||||||
"urlgrey": "0.4.4"
|
"urlgrey": "0.4.4"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"codex-notifier": {
|
||||||
|
"version": "1.1.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/codex-notifier/-/codex-notifier-1.1.2.tgz",
|
||||||
|
"integrity": "sha512-DCp6xe/LGueJ1N5sXEwcBc3r3PyVkEEDNWCVigfvywAkeXcZMk9K41a31tkEFBW0Ptlwji6/JlAb49E3Yrxbtg=="
|
||||||
|
},
|
||||||
|
"codex-tooltip": {
|
||||||
|
"version": "1.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/codex-tooltip/-/codex-tooltip-1.0.1.tgz",
|
||||||
|
"integrity": "sha512-1xLb1NZbxguNtf02xBRhDphq/EXvMMeEbY0ievjQTHqf8UjXsD41evGk9rqcbjpl+JOjNgtwnp1OaU/X/h6fhQ=="
|
||||||
|
},
|
||||||
"coffeescript": {
|
"coffeescript": {
|
||||||
"version": "2.5.1",
|
"version": "2.5.1",
|
||||||
"resolved": "https://registry.npmjs.org/coffeescript/-/coffeescript-2.5.1.tgz",
|
"resolved": "https://registry.npmjs.org/coffeescript/-/coffeescript-2.5.1.tgz",
|
||||||
|
@ -10306,6 +10345,11 @@
|
||||||
"safer-buffer": "^2.1.0"
|
"safer-buffer": "^2.1.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"editorjs-inline-tool": {
|
||||||
|
"version": "0.4.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/editorjs-inline-tool/-/editorjs-inline-tool-0.4.0.tgz",
|
||||||
|
"integrity": "sha512-Ppb4e8IFPjWuNcoNM4tg9bDSo7FgMYAlqP4UhuV5W2JoJBubV5pUcpLrFrSyGTt1HJVEpbrib134zf4wxO+7VA=="
|
||||||
|
},
|
||||||
"ee-first": {
|
"ee-first": {
|
||||||
"version": "1.1.1",
|
"version": "1.1.1",
|
||||||
"resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
|
||||||
|
|
|
@ -17,6 +17,11 @@
|
||||||
"npm": ">=6.11.0"
|
"npm": ">=6.11.0"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"@editorjs/editorjs": "^2.19.0",
|
||||||
|
"@editorjs/header": "^2.6.0",
|
||||||
|
"@editorjs/image": "^2.6.0",
|
||||||
|
"@editorjs/list": "^1.6.0",
|
||||||
|
"@editorjs/quote": "^2.4.0",
|
||||||
"@material-ui/core": "^4.5.1",
|
"@material-ui/core": "^4.5.1",
|
||||||
"@material-ui/icons": "^4.5.1",
|
"@material-ui/icons": "^4.5.1",
|
||||||
"@material-ui/styles": "^4.5.2",
|
"@material-ui/styles": "^4.5.2",
|
||||||
|
@ -36,6 +41,7 @@
|
||||||
"draft-js": "^0.10.5",
|
"draft-js": "^0.10.5",
|
||||||
"draftail": "^1.2.1",
|
"draftail": "^1.2.1",
|
||||||
"draftjs-to-html": "^0.9.1",
|
"draftjs-to-html": "^0.9.1",
|
||||||
|
"editorjs-inline-tool": "^0.4.0",
|
||||||
"fast-array-diff": "^0.2.0",
|
"fast-array-diff": "^0.2.0",
|
||||||
"fuzzaldrin": "^2.1.0",
|
"fuzzaldrin": "^2.1.0",
|
||||||
"graphql": "^14.4.2",
|
"graphql": "^14.4.2",
|
||||||
|
|
|
@ -1,298 +1,163 @@
|
||||||
|
import EditorJS, { OutputData } from "@editorjs/editorjs";
|
||||||
|
import Header from "@editorjs/header";
|
||||||
|
import List from "@editorjs/list";
|
||||||
|
import Quote from "@editorjs/quote";
|
||||||
import { makeStyles } from "@material-ui/core/styles";
|
import { makeStyles } from "@material-ui/core/styles";
|
||||||
import { fade } from "@material-ui/core/styles/colorManipulator";
|
import { fade } from "@material-ui/core/styles/colorManipulator";
|
||||||
import Typography from "@material-ui/core/Typography";
|
import Typography from "@material-ui/core/Typography";
|
||||||
import { CreateCSSProperties } from "@material-ui/styles/withStyles";
|
import { CreateCSSProperties } from "@material-ui/styles/withStyles";
|
||||||
import { ChangeEvent } from "@saleor/hooks/useForm";
|
import { FormChange } from "@saleor/hooks/useForm";
|
||||||
|
import strikethroughIcon from "@saleor/icons/StrikethroughIcon";
|
||||||
import classNames from "classnames";
|
import classNames from "classnames";
|
||||||
import { RawDraftContentState } from "draft-js";
|
import createGenericInlineTool, {
|
||||||
import {
|
ItalicInlineTool,
|
||||||
BLOCK_TYPE,
|
UnderlineInlineTool
|
||||||
DraftailEditor,
|
} from "editorjs-inline-tool";
|
||||||
ENTITY_TYPE,
|
|
||||||
INLINE_STYLE
|
|
||||||
} from "draftail";
|
|
||||||
import isEqual from "lodash-es/isEqual";
|
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import ErrorBoundary from "react-error-boundary";
|
|
||||||
import { FormattedMessage } from "react-intl";
|
|
||||||
|
|
||||||
import BoldIcon from "../../icons/BoldIcon";
|
|
||||||
import HeaderOne from "../../icons/HeaderOne";
|
|
||||||
import HeaderThree from "../../icons/HeaderThree";
|
|
||||||
import HeaderTwo from "../../icons/HeaderTwo";
|
|
||||||
import ItalicIcon from "../../icons/ItalicIcon";
|
|
||||||
import LinkIcon from "../../icons/LinkIcon";
|
|
||||||
import OrderedListIcon from "../../icons/OrderedListIcon";
|
|
||||||
import QuotationIcon from "../../icons/QuotationIcon";
|
|
||||||
import StrikethroughIcon from "../../icons/StrikethroughIcon";
|
|
||||||
import UnorderedListIcon from "../../icons/UnorderedListIcon";
|
|
||||||
import LinkEntity from "./LinkEntity";
|
|
||||||
import LinkSource from "./LinkSource";
|
|
||||||
|
|
||||||
export interface RichTextEditorProps {
|
export interface RichTextEditorProps {
|
||||||
disabled: boolean;
|
disabled: boolean;
|
||||||
error: boolean;
|
error: boolean;
|
||||||
helperText: string;
|
helperText: string;
|
||||||
initial?: RawDraftContentState;
|
initial: OutputData;
|
||||||
label: string;
|
label: string;
|
||||||
name: string;
|
name: string;
|
||||||
scroll?: boolean;
|
onChange: FormChange;
|
||||||
onChange: (event: React.ChangeEvent<any>) => void;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const useStyles = makeStyles(
|
const useStyles = makeStyles(
|
||||||
theme => {
|
theme => {
|
||||||
const editorContainer: CreateCSSProperties = {
|
const hover = {
|
||||||
border: `1px ${theme.palette.divider} solid`,
|
"&:hover": {
|
||||||
borderRadius: 4,
|
background: fade(theme.palette.primary.main, 0.1)
|
||||||
padding: "27px 12px 10px",
|
}
|
||||||
position: "relative",
|
|
||||||
transition: theme.transitions.duration.shortest + "ms"
|
|
||||||
};
|
};
|
||||||
|
|
||||||
return {
|
return {
|
||||||
editorContainer,
|
|
||||||
error: {
|
error: {
|
||||||
color: theme.palette.error.main
|
color: theme.palette.error.main
|
||||||
},
|
},
|
||||||
helperText: {
|
helperText: {
|
||||||
marginTop: theme.spacing(0.75)
|
marginTop: theme.spacing(0.75)
|
||||||
},
|
},
|
||||||
input: {
|
|
||||||
position: "relative"
|
|
||||||
},
|
|
||||||
label: {
|
label: {
|
||||||
fontSize: theme.typography.caption.fontSize,
|
color: theme.palette.text.secondary,
|
||||||
left: 12,
|
|
||||||
position: "absolute",
|
position: "absolute",
|
||||||
top: 9
|
top: theme.spacing(4),
|
||||||
|
transition: theme.transitions.duration.short + "ms"
|
||||||
},
|
},
|
||||||
linkIcon: {
|
labelActive: {
|
||||||
marginTop: 2
|
color: theme.palette.primary.main
|
||||||
},
|
},
|
||||||
root: {
|
root: {
|
||||||
"& .DraftEditor": {
|
"& .cdx-quote__text": {
|
||||||
"&-editorContainer": {
|
minHeight: 24
|
||||||
"& .public-DraftEditor-content": {
|
|
||||||
lineHeight: 1.62
|
|
||||||
},
|
|
||||||
"& a": {
|
|
||||||
color: theme.palette.primary.light
|
|
||||||
},
|
|
||||||
"&:after": {
|
|
||||||
background: theme.palette.getContrastText(
|
|
||||||
theme.palette.background.default
|
|
||||||
),
|
|
||||||
bottom: -11,
|
|
||||||
content: "''",
|
|
||||||
display: "block",
|
|
||||||
height: 2,
|
|
||||||
left: -12,
|
|
||||||
position: "absolute",
|
|
||||||
transform: "scaleX(0) scaleY(0)",
|
|
||||||
width: "calc(100% + 24px)"
|
|
||||||
},
|
|
||||||
position: "relative"
|
|
||||||
},
|
|
||||||
"&-root": {
|
|
||||||
...theme.typography.body1
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
"& .Draftail": {
|
"& .ce-conversion-tool": {
|
||||||
"&-Editor": {
|
...hover
|
||||||
"&--focus": {
|
|
||||||
boxShadow: `inset 0px 0px 0px 2px ${theme.palette.primary.main}`
|
|
||||||
},
|
|
||||||
"&:hover": {
|
|
||||||
borderColor: theme.palette.primary.main
|
|
||||||
},
|
|
||||||
...editorContainer
|
|
||||||
},
|
|
||||||
"&-Toolbar": {
|
|
||||||
"&Button": {
|
|
||||||
"& svg": {
|
|
||||||
padding: 2
|
|
||||||
},
|
|
||||||
"&--active": {
|
|
||||||
"&:hover": {
|
|
||||||
background: theme.palette.primary.main
|
|
||||||
},
|
|
||||||
"&:not(:hover)": {
|
|
||||||
borderRightColor: theme.palette.primary.main
|
|
||||||
},
|
|
||||||
background: theme.palette.primary.main
|
|
||||||
},
|
|
||||||
"&:focus": {
|
|
||||||
"&:active": {
|
|
||||||
"&:after": {
|
|
||||||
background: fade(theme.palette.primary.main, 0.3),
|
|
||||||
borderRadius: "100%",
|
|
||||||
content: "''",
|
|
||||||
display: "block",
|
|
||||||
height: "100%",
|
|
||||||
width: "100%"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"&:hover": {
|
|
||||||
background: fade(theme.palette.primary.main, 0.3)
|
|
||||||
},
|
|
||||||
background: "none",
|
|
||||||
border: "none",
|
|
||||||
borderRight: `1px ${theme.palette.divider} solid`,
|
|
||||||
color: theme.typography.body1.color,
|
|
||||||
cursor: "pointer",
|
|
||||||
display: "inline-flex",
|
|
||||||
height: 36,
|
|
||||||
justifyContent: "center",
|
|
||||||
padding: theme.spacing(1) + 2,
|
|
||||||
transition: theme.transitions.duration.short + "ms",
|
|
||||||
width: 36
|
|
||||||
},
|
|
||||||
"&Group": {
|
|
||||||
"&:last-of-type": {
|
|
||||||
"& .Draftail-ToolbarButton": {
|
|
||||||
"&:last-of-type": {
|
|
||||||
border: "none"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
display: "flex"
|
|
||||||
},
|
|
||||||
background: theme.palette.background.default,
|
|
||||||
border: `1px ${theme.palette.divider} solid`,
|
|
||||||
display: "inline-flex",
|
|
||||||
flexWrap: "wrap",
|
|
||||||
marginBottom: theme.spacing(),
|
|
||||||
marginTop: 10,
|
|
||||||
[theme.breakpoints.down(460)]: {
|
|
||||||
width: "min-content"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"&-block": {
|
|
||||||
"&--blockquote": {
|
|
||||||
borderLeft: `2px solid ${theme.palette.divider}`,
|
|
||||||
margin: 0,
|
|
||||||
padding: theme.spacing(1, 2)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
"&$error": {
|
"& .ce-conversion-tool--focused": {
|
||||||
"& .Draftail": {
|
background: `${fade(theme.palette.primary.main, 0.1)} !important`
|
||||||
"&-Editor": {
|
},
|
||||||
borderColor: theme.palette.error.main
|
"& .ce-inline-tool": {
|
||||||
}
|
...hover,
|
||||||
}
|
height: 32,
|
||||||
}
|
transition: theme.transitions.duration.short + "ms",
|
||||||
|
width: 32
|
||||||
|
},
|
||||||
|
"& .ce-inline-toolbar__dropdown": {
|
||||||
|
...hover,
|
||||||
|
height: 32,
|
||||||
|
marginRight: 0
|
||||||
|
},
|
||||||
|
"& .ce-inline-toolbar__toggler-and-button-wrapper": {
|
||||||
|
paddingRight: 0
|
||||||
|
},
|
||||||
|
"& .codex-editor__redactor": {
|
||||||
|
marginRight: `${theme.spacing(4)}px !important`,
|
||||||
|
paddingBottom: "0 !important"
|
||||||
|
},
|
||||||
|
"& a": {
|
||||||
|
color: theme.palette.primary.light
|
||||||
|
},
|
||||||
|
"&:hover": {
|
||||||
|
borderColor: theme.palette.primary.main
|
||||||
|
},
|
||||||
|
border: `1px solid ${theme.palette.divider}`,
|
||||||
|
borderRadius: 8,
|
||||||
|
boxShadow: `inset 0 0 0 0 ${theme.palette.primary.main}`,
|
||||||
|
padding: theme.spacing(3, 2),
|
||||||
|
transition: theme.transitions.duration.short + "ms"
|
||||||
},
|
},
|
||||||
scroll: {
|
rootActive: {
|
||||||
"& .DraftEditor": {
|
boxShadow: `inset 0px 0px 0 2px ${theme.palette.primary.main}`
|
||||||
"&-editorContainer": {
|
|
||||||
"& .public-DraftEditor-content": {
|
|
||||||
lineHeight: 1.62
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
smallIcon: {
|
|
||||||
marginLeft: 10
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
{ name: "RichTextEditor" }
|
{ name: "RichTextEditor" }
|
||||||
);
|
);
|
||||||
|
|
||||||
function handleSave(
|
class NewEditor extends EditorJS {}
|
||||||
value: any,
|
|
||||||
initial: any,
|
const RichTextEditor: React.FC<RichTextEditorProps> = ({
|
||||||
name: string,
|
error,
|
||||||
onChange: (event: ChangeEvent) => void
|
helperText,
|
||||||
) {
|
initial,
|
||||||
if (value && !isEqual(value, initial)) {
|
label,
|
||||||
onChange({
|
name,
|
||||||
target: {
|
onChange
|
||||||
name,
|
}) => {
|
||||||
value
|
const classes = useStyles({});
|
||||||
|
|
||||||
|
const [isFocused, setFocus] = React.useState(false);
|
||||||
|
const editor = React.useRef<EditorJS>();
|
||||||
|
const editorContainer = React.useRef<HTMLDivElement>();
|
||||||
|
React.useEffect(() => {
|
||||||
|
editor.current = new NewEditor({
|
||||||
|
data: initial,
|
||||||
|
holder: editorContainer.current,
|
||||||
|
tools: {
|
||||||
|
header: {
|
||||||
|
class: Header,
|
||||||
|
config: {
|
||||||
|
defaultLevel: 1,
|
||||||
|
levels: [1, 2, 3]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
list: List,
|
||||||
|
quote: Quote,
|
||||||
|
strikethrough: createGenericInlineTool({
|
||||||
|
sanitize: {
|
||||||
|
s: true
|
||||||
|
},
|
||||||
|
shortcut: "CMD+S",
|
||||||
|
tagName: "s",
|
||||||
|
toolboxIcon: strikethroughIcon
|
||||||
|
})
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}, []);
|
||||||
}
|
React.useEffect(() => () => editor.current.destroy(), []);
|
||||||
|
|
||||||
const RichTextEditor: React.FC<RichTextEditorProps> = props => {
|
|
||||||
const { error, helperText, initial, label, name, scroll, onChange } = props;
|
|
||||||
|
|
||||||
const classes = useStyles(props);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div>
|
||||||
className={classNames({
|
<div
|
||||||
[classes.error]: error,
|
className={classNames(classes.root, {
|
||||||
[classes.root]: true,
|
[classes.rootActive]: isFocused
|
||||||
[classes.scroll]: scroll
|
})}
|
||||||
})}
|
ref={editorContainer}
|
||||||
>
|
data-test="richTextEditor"
|
||||||
<div className={classes.input}>
|
onFocus={() => setFocus(true)}
|
||||||
<Typography className={classes.label} variant="caption" color="primary">
|
onBlur={() => setFocus(false)}
|
||||||
|
>
|
||||||
|
<Typography
|
||||||
|
className={classNames(classes.label, {
|
||||||
|
[classes.labelActive]: isFocused
|
||||||
|
})}
|
||||||
|
variant="caption"
|
||||||
|
>
|
||||||
{label}
|
{label}
|
||||||
</Typography>
|
</Typography>
|
||||||
<ErrorBoundary
|
|
||||||
FallbackComponent={() => (
|
|
||||||
<div className={classes.editorContainer}>
|
|
||||||
<Typography color="error">
|
|
||||||
<FormattedMessage
|
|
||||||
defaultMessage="Invalid content"
|
|
||||||
description="rich text error"
|
|
||||||
/>
|
|
||||||
</Typography>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
>
|
|
||||||
<DraftailEditor
|
|
||||||
key={JSON.stringify(initial)}
|
|
||||||
rawContentState={
|
|
||||||
initial && Object.keys(initial).length > 0 ? initial : null
|
|
||||||
}
|
|
||||||
onSave={value => handleSave(value, initial, name, onChange)}
|
|
||||||
blockTypes={[
|
|
||||||
{
|
|
||||||
icon: <HeaderOne />,
|
|
||||||
type: BLOCK_TYPE.HEADER_ONE
|
|
||||||
},
|
|
||||||
{ icon: <HeaderTwo />, type: BLOCK_TYPE.HEADER_TWO },
|
|
||||||
{ icon: <HeaderThree />, type: BLOCK_TYPE.HEADER_THREE },
|
|
||||||
{ icon: <QuotationIcon />, type: BLOCK_TYPE.BLOCKQUOTE },
|
|
||||||
{
|
|
||||||
icon: <UnorderedListIcon />,
|
|
||||||
type: BLOCK_TYPE.UNORDERED_LIST_ITEM
|
|
||||||
},
|
|
||||||
{ icon: <OrderedListIcon />, type: BLOCK_TYPE.ORDERED_LIST_ITEM }
|
|
||||||
]}
|
|
||||||
inlineStyles={[
|
|
||||||
{
|
|
||||||
icon: <BoldIcon className={classes.smallIcon} />,
|
|
||||||
type: INLINE_STYLE.BOLD
|
|
||||||
},
|
|
||||||
{
|
|
||||||
icon: <ItalicIcon className={classes.smallIcon} />,
|
|
||||||
type: INLINE_STYLE.ITALIC
|
|
||||||
},
|
|
||||||
{
|
|
||||||
icon: <StrikethroughIcon />,
|
|
||||||
type: INLINE_STYLE.STRIKETHROUGH
|
|
||||||
}
|
|
||||||
]}
|
|
||||||
enableLineBreak
|
|
||||||
entityTypes={[
|
|
||||||
{
|
|
||||||
attributes: ["url"],
|
|
||||||
decorator: LinkEntity,
|
|
||||||
icon: <LinkIcon className={classes.linkIcon} />,
|
|
||||||
source: LinkSource,
|
|
||||||
type: ENTITY_TYPE.LINK
|
|
||||||
}
|
|
||||||
]}
|
|
||||||
/>
|
|
||||||
</ErrorBoundary>
|
|
||||||
</div>
|
</div>
|
||||||
{helperText && (
|
{helperText && (
|
||||||
<Typography
|
<Typography
|
||||||
|
@ -310,7 +175,4 @@ const RichTextEditor: React.FC<RichTextEditorProps> = props => {
|
||||||
};
|
};
|
||||||
|
|
||||||
RichTextEditor.displayName = "RichTextEditor";
|
RichTextEditor.displayName = "RichTextEditor";
|
||||||
RichTextEditor.defaultProps = {
|
|
||||||
scroll: true
|
|
||||||
};
|
|
||||||
export default RichTextEditor;
|
export default RichTextEditor;
|
||||||
|
|
|
@ -1,11 +1,3 @@
|
||||||
import createSvgIcon from "@material-ui/icons/utils/createSvgIcon";
|
const Strikethrough = `<svg height="32" width="32" viewBox="-4 -1 24 16"><path d="M6.53333 14H10.2667V11.2H6.53333V14ZM1.86667 0V2.8H6.53333V5.6H10.2667V2.8H14.9333V0H1.86667ZM0 9.33333H16.8V7.46667H0V9.33333Z"></path></svg>`;
|
||||||
import React from "react";
|
|
||||||
|
|
||||||
const HeaderOne = createSvgIcon(
|
export default Strikethrough;
|
||||||
<>
|
|
||||||
<path d="M6.53333 14H10.2667V11.2H6.53333V14ZM1.86667 0V2.8H6.53333V5.6H10.2667V2.8H14.9333V0H1.86667ZM0 9.33333H16.8V7.46667H0V9.33333Z" />
|
|
||||||
</>,
|
|
||||||
"HeaderOne"
|
|
||||||
);
|
|
||||||
|
|
||||||
export default HeaderOne;
|
|
||||||
|
|
|
@ -1,108 +1,14 @@
|
||||||
|
import { OutputData } from "@editorjs/editorjs";
|
||||||
import RichTextEditor from "@saleor/components/RichTextEditor";
|
import RichTextEditor from "@saleor/components/RichTextEditor";
|
||||||
import { storiesOf } from "@storybook/react";
|
import { storiesOf } from "@storybook/react";
|
||||||
import { RawDraftContentState } from "draft-js";
|
|
||||||
import React from "react";
|
import React from "react";
|
||||||
|
|
||||||
import CardDecorator from "../../CardDecorator";
|
import CardDecorator from "../../CardDecorator";
|
||||||
import Decorator from "../../Decorator";
|
import Decorator from "../../Decorator";
|
||||||
|
import * as fixtures from "./fixtures.json";
|
||||||
|
|
||||||
|
export const content: OutputData = fixtures.richTextEditor;
|
||||||
|
|
||||||
export const content: RawDraftContentState = {
|
|
||||||
blocks: [
|
|
||||||
{
|
|
||||||
data: {},
|
|
||||||
depth: 0,
|
|
||||||
entityRanges: [],
|
|
||||||
inlineStyleRanges: [{ length: 4, offset: 0, style: "BOLD" }],
|
|
||||||
key: "rosn",
|
|
||||||
text: "bold",
|
|
||||||
type: "unstyled"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
data: {},
|
|
||||||
depth: 0,
|
|
||||||
entityRanges: [],
|
|
||||||
inlineStyleRanges: [{ length: 6, offset: 0, style: "ITALIC" }],
|
|
||||||
key: "6tbch",
|
|
||||||
text: "italic",
|
|
||||||
type: "unstyled"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
data: {},
|
|
||||||
depth: 0,
|
|
||||||
entityRanges: [],
|
|
||||||
inlineStyleRanges: [{ length: 13, offset: 0, style: "STRIKETHROUGH" }],
|
|
||||||
key: "1p044",
|
|
||||||
text: "strikethrough",
|
|
||||||
type: "unstyled"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
data: {},
|
|
||||||
depth: 0,
|
|
||||||
entityRanges: [],
|
|
||||||
inlineStyleRanges: [],
|
|
||||||
key: "aven6",
|
|
||||||
text: "h1",
|
|
||||||
type: "header-one"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
data: {},
|
|
||||||
depth: 0,
|
|
||||||
entityRanges: [],
|
|
||||||
inlineStyleRanges: [],
|
|
||||||
key: "9rabl",
|
|
||||||
text: "h2",
|
|
||||||
type: "header-two"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
data: {},
|
|
||||||
depth: 0,
|
|
||||||
entityRanges: [],
|
|
||||||
inlineStyleRanges: [],
|
|
||||||
key: "bv0ac",
|
|
||||||
text: "h3",
|
|
||||||
type: "header-three"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
data: {},
|
|
||||||
depth: 0,
|
|
||||||
entityRanges: [],
|
|
||||||
inlineStyleRanges: [],
|
|
||||||
key: "2ip7q",
|
|
||||||
text: "blockquote",
|
|
||||||
type: "blockquote"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
data: {},
|
|
||||||
depth: 0,
|
|
||||||
entityRanges: [],
|
|
||||||
inlineStyleRanges: [],
|
|
||||||
key: "8r8ss",
|
|
||||||
text: "ul",
|
|
||||||
type: "unordered-list-item"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
data: {},
|
|
||||||
depth: 0,
|
|
||||||
entityRanges: [],
|
|
||||||
inlineStyleRanges: [],
|
|
||||||
key: "911hc",
|
|
||||||
text: "ol",
|
|
||||||
type: "ordered-list-item"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
data: {},
|
|
||||||
depth: 0,
|
|
||||||
entityRanges: [{ key: 0, length: 4, offset: 0 }],
|
|
||||||
inlineStyleRanges: [],
|
|
||||||
key: "5aejo",
|
|
||||||
text: "link",
|
|
||||||
type: "unstyled"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
entityMap: {
|
|
||||||
"0": { data: { url: "#" }, mutability: "MUTABLE", type: "LINK" }
|
|
||||||
}
|
|
||||||
};
|
|
||||||
storiesOf("Generics / Rich text editor", module)
|
storiesOf("Generics / Rich text editor", module)
|
||||||
.addDecorator(CardDecorator)
|
.addDecorator(CardDecorator)
|
||||||
.addDecorator(Decorator)
|
.addDecorator(Decorator)
|
||||||
|
@ -110,7 +16,7 @@ storiesOf("Generics / Rich text editor", module)
|
||||||
<RichTextEditor
|
<RichTextEditor
|
||||||
disabled={false}
|
disabled={false}
|
||||||
error={false}
|
error={false}
|
||||||
helperText={""}
|
helperText="Lorem ipsum dolor sit amet, consectetur adipiscing elit"
|
||||||
initial={content}
|
initial={content}
|
||||||
label="Content"
|
label="Content"
|
||||||
name="content"
|
name="content"
|
||||||
|
|
74
src/storybook/stories/components/fixtures.json
Normal file
74
src/storybook/stories/components/fixtures.json
Normal file
|
@ -0,0 +1,74 @@
|
||||||
|
{
|
||||||
|
"richTextEditor": {
|
||||||
|
"time": 1603898483525,
|
||||||
|
"blocks": [
|
||||||
|
{ "type": "header", "data": { "text": "Lorem ipsum ", "level": 1 } },
|
||||||
|
{
|
||||||
|
"type": "paragraph",
|
||||||
|
"data": {
|
||||||
|
"text": "Dolor sit amet, consectetur adipiscing elit. <b>Sed iaculis urna et justo accumsan</b>, eget porta est egestas. Nunc odio libero, pharetra in tristique eget, pellentesque in lectus. Sed sed laoreet orci. Suspendisse dui nibh, iaculis ac dui posuere, placerat elementum dolor. In sit amet aliquet nibh. Maecenas sed felis sed lectus gravida vulputate et a mi. Sed a tristique neque, ut euismod arcu. <i>Donec quis aliquet massa.</i> Curabitur arcu purus, facilisis quis posuere sit amet, pharetra at erat."
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "list",
|
||||||
|
"data": {
|
||||||
|
"style": "ordered",
|
||||||
|
"items": [
|
||||||
|
"Maecenas pretium aliquam odio, a iaculis diam dictum ut.",
|
||||||
|
"Vestibulum pulvinar, quam quis sollicitudin luctus, libero odio laoreet lectus, in tristique ligula dui et ex.<br>",
|
||||||
|
"Nam quis nibh sed elit fermentum interdum non eget quam."
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "paragraph",
|
||||||
|
"data": {
|
||||||
|
"text": "Nulla sit amet cursus augue, in maximus tellus. <a href=\"http://lipsum.com\">Donec sit amet mollis neque</a>, eget commodo odio."
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{ "type": "header", "data": { "text": "Morbi aliquam", "level": 2 } },
|
||||||
|
{
|
||||||
|
"type": "paragraph",
|
||||||
|
"data": {
|
||||||
|
"text": "Aliquam posuere nisi et ante malesuada egestas. Phasellus auctor risus a erat aliquam, tempus volutpat arcu rutrum. Duis bibendum id justo ut commodo. Suspendisse imperdiet tincidunt blandit."
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{ "type": "header", "data": { "text": "Nam ipsum purus", "level": 3 } },
|
||||||
|
{
|
||||||
|
"type": "paragraph",
|
||||||
|
"data": {
|
||||||
|
"text": "Nam ipsum purus, feugiat ut dapibus at, porttitor eget leo. Phasellus sodales urna quis mi viverra, non mollis magna tristique. <s>Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos.</s> Pellentesque viverra est sit amet nisi hendrerit, pharetra vehicula neque volutpat. Maecenas feugiat a nulla id blandit. Sed sagittis tempus libero non dignissim. In lectus felis, mattis vitae lacinia nec, volutpat eu elit. Proin ultricies lacus id felis placerat mollis. Integer ultricies eros nec mauris interdum, sit amet sodales ipsum elementum. Vivamus quis dapibus turpis, eu dignissim quam."
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "quote",
|
||||||
|
"data": {
|
||||||
|
"text": "Nam facilisis augue vel urna tristique rutrum id et tortor.",
|
||||||
|
"caption": "Morbi erat mi",
|
||||||
|
"alignment": "left"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "header",
|
||||||
|
"data": { "text": "Tempor ac posuere nec", "level": 3 }
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "paragraph",
|
||||||
|
"data": {
|
||||||
|
"text": "Rhoncus ac lectus. Etiam viverra nisl feugiat tempus eleifend. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia curae."
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "list",
|
||||||
|
"data": {
|
||||||
|
"style": "unordered",
|
||||||
|
"items": [
|
||||||
|
"Phasellus nec ipsum non metus vestibulum semper",
|
||||||
|
"In tincidunt, dui vitae suscipit sodales, lacus justo porttitor nulla<br>"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"version": "2.19.0"
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue