UNPKG

burdy

Version:

Open Source Headless Platform

282 lines (281 loc) 15.5 kB
"use strict"; var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } }); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); __setModuleDefault(result, mod); return result; }; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); const react_1 = __importStar(require("react")); const react_2 = require("@fluentui/react"); const dynamic_richtext_context_1 = require("../../dynamic-richtext.context"); const dynamic_form_1 = require("../../dynamic-form"); const draft_js_1 = require("draft-js"); const assets_select_panel_1 = __importDefault(require("../../../features/assets/components/assets-select-panel")); const insert_link_dialog_1 = __importDefault(require("../../../components/insert-link-dialog")); const draft_ace_dialog_1 = __importDefault(require("./draft-ace-dialog")); const content_types_components_select_panel_1 = __importDefault(require("../../../features/content-types/components/content-types-components-select-panel")); const snackbar_1 = require("../../../context/snackbar"); const utility_1 = require("../../../helpers/utility"); const useToolbarStyles = (0, react_2.makeStyles)((theme) => ({ button: { minWidth: 34, padding: '0 4px', borderRadius: 0, '&:not(:first-of-type)': { borderLeft: 'none' }, border: `1px solid ${theme.palette.neutralLight}` }, group: { flexDirection: 'row', flexWrap: 'wrap', marginRight: 10 } })); const BlockHeadingTypes = [ { label: 'H1', style: 'header-one' }, { label: 'H2', style: 'header-two' }, { label: 'H3', style: 'header-three' }, { label: 'H4', style: 'header-four' }, { label: 'H5', style: 'header-five' }, { label: 'H6', style: 'header-six' } ]; const BlockSecondTypes = [ { label: 'Code Block', icon: 'Code', style: 'code-block' }, { label: 'Blockquote', icon: 'RightDoubleQuote', style: 'blockquote' } ]; const BlockListTypes = [ { label: 'UL', icon: 'BulletedList', style: 'unordered-list-item' }, { label: 'OL', icon: 'NumberedList', style: 'ordered-list-item' } ]; const InlineStyles = [ { label: 'Bold', icon: 'Bold', style: 'BOLD' }, { label: 'Italic', icon: 'Italic', style: 'ITALIC' }, { label: 'Underline', icon: 'Underline', style: 'UNDERLINE' }, { label: 'Strikethrough', icon: 'Strikethrough', style: 'STRIKETHROUGH' }, { label: 'Code', icon: 'CodeEdit', style: 'CODE' }, ]; const BlockButtons = () => { const { editorState, toggleBlockType } = (0, dynamic_richtext_context_1.useRichtext)(); const selection = editorState.getSelection(); const blockType = editorState .getCurrentContent() .getBlockForKey(selection.getStartKey()) .getType(); const classes = useToolbarStyles(); return (react_1.default.createElement(react_1.default.Fragment, null, react_1.default.createElement("div", { className: classes.group }, BlockHeadingTypes.map(({ style, label }) => (react_1.default.createElement(StyleButton, { key: label, style: style, isActive: style === blockType, onToggle: toggleBlockType }, label)))), react_1.default.createElement("div", { className: classes.group }, BlockSecondTypes.map(({ style, label, icon }) => (react_1.default.createElement(StyleButton, { key: label, icon: icon, style: style, isActive: style === blockType, onToggle: toggleBlockType }, label)))), react_1.default.createElement("div", { className: classes.group }, BlockListTypes.map(({ style, label, icon }) => (react_1.default.createElement(StyleButton, { key: label, style: style, isActive: style === blockType, onToggle: toggleBlockType, icon: icon }, label)))))); }; const InlineButtons = () => { const { editorState, toggleInlineStyle } = (0, dynamic_richtext_context_1.useRichtext)(); const currentStyle = editorState.getCurrentInlineStyle(); const classes = useToolbarStyles(); return (react_1.default.createElement("div", { className: classes.group }, InlineStyles.map(({ style, label, icon }) => (react_1.default.createElement(StyleButton, { icon: icon, key: label, onToggle: toggleInlineStyle, isActive: currentStyle.has(style), style: style }, label))))); }; const StyleButton = ({ icon, isActive, children, onToggle, style }) => { const { disabled } = (0, dynamic_form_1.useExtendedFormContext)(); const classes = useToolbarStyles(); const Button = (0, react_1.useMemo)(() => (isActive ? react_2.PrimaryButton : react_2.DefaultButton), [isActive]); return (react_1.default.createElement(Button, { iconProps: { iconName: icon }, className: classes.button, disabled: disabled, onMouseDown: (e) => { onToggle(style); e.preventDefault(); return false; } }, !icon && children)); }; const ActionButtons = () => { const classes = useToolbarStyles(); const { disabled } = (0, dynamic_form_1.useExtendedFormContext)(); const { editorState, setEditorState, editorProps, setEditorProps } = (0, dynamic_richtext_context_1.useRichtext)(); const { openSnackbar } = (0, snackbar_1.useSnackbar)(); const [assetOpen, setAssetOpen] = (0, react_1.useState)(false); const [linkOpen, setLinkOpen] = (0, react_1.useState)(false); const [aceOpen, setAceOpen] = (0, react_1.useState)(false); const [componentsOpen, setComponentsOpen] = (0, react_1.useState)(false); const [selection, setSelection] = (0, react_1.useState)(null); const styles = useToolbarStyles(); const setReadOnly = (readOnly) => { setEditorProps(Object.assign(Object.assign({}, editorProps), { readOnly })); }; const forceSelection = () => { setEditorState(draft_js_1.EditorState.forceSelection(editorState, selection)); setSelection(null); }; const createImage = (image) => { const contentState = editorState.getCurrentContent(); const contentStateWithEntity = contentState.createEntity('IMAGE', 'IMMUTABLE', { npath: image.npath, name: image.name, mimeType: image.mimeType, meta: image.meta, caption: '', align: 'center' }); const entityKey = contentStateWithEntity.getLastCreatedEntityKey(); setEditorState(draft_js_1.AtomicBlockUtils.insertAtomicBlock(editorState, entityKey, ' ')); draft_js_1.EditorState.forceSelection(editorState, editorState.getCurrentContent().getSelectionAfter()); }; const createAce = (mode) => { const contentState = editorState.getCurrentContent(); const contentStateWithEntity = contentState.createEntity('TEXT_EDITOR', 'IMMUTABLE', { mode }); const entityKey = contentStateWithEntity.getLastCreatedEntityKey(); setEditorState(draft_js_1.AtomicBlockUtils.insertAtomicBlock(editorState, entityKey, ' ')); draft_js_1.EditorState.forceSelection(editorState, editorState.getCurrentContent().getSelectionAfter()); }; const createComponent = (name) => { const contentState = editorState.getCurrentContent(); const contentStateWithEntity = contentState.createEntity('COMPONENT', 'IMMUTABLE', { name }); const entityKey = contentStateWithEntity.getLastCreatedEntityKey(); setEditorState(draft_js_1.AtomicBlockUtils.insertAtomicBlock(editorState, entityKey, ' ')); draft_js_1.EditorState.forceSelection(editorState, editorState.getCurrentContent().getSelectionAfter()); }; const createDivider = () => { const contentState = editorState.getCurrentContent(); const contentStateWithEntity = contentState.createEntity('DIVIDER', 'IMMUTABLE'); const entityKey = contentStateWithEntity.getLastCreatedEntityKey(); setEditorState(draft_js_1.AtomicBlockUtils.insertAtomicBlock(editorState, entityKey, ' ')); draft_js_1.EditorState.forceSelection(editorState, editorState.getCurrentContent().getSelectionAfter()); }; const createLink = (link) => { var _a; const selection = editorState.getSelection(); if (!(((_a = link === null || link === void 0 ? void 0 : link.url) === null || _a === void 0 ? void 0 : _a.length) > 0)) { setEditorState(draft_js_1.RichUtils.toggleLink(editorState, selection, null)); return; } const content = editorState.getCurrentContent(); const contentWithEntity = content.createEntity('LINK', 'MUTABLE', link); const newEditorState = draft_js_1.EditorState.push(editorState, contentWithEntity, 'apply-entity'); const entityKey = contentWithEntity.getLastCreatedEntityKey(); setEditorState(draft_js_1.RichUtils.toggleLink(newEditorState, selection, entityKey)); draft_js_1.EditorState.forceSelection(newEditorState, newEditorState.getCurrentContent().getSelectionAfter()); }; return (react_1.default.createElement(react_1.default.Fragment, null, react_1.default.createElement("div", { className: styles.group }, react_1.default.createElement(react_2.DefaultButton, { iconProps: { iconName: 'CalculatorSubtract' }, label: 'Divider', ariaLabel: 'Divider', className: classes.button, disabled: disabled, onMouseDown: () => { createDivider(); setSelection(editorState.getSelection()); return false; } }), react_1.default.createElement(react_2.DefaultButton, { iconProps: { iconName: 'MediaAdd' }, className: classes.button, disabled: disabled, onMouseDown: (e) => { setAssetOpen(true); e.preventDefault(); setSelection(editorState.getSelection()); return false; } }), react_1.default.createElement(react_2.DefaultButton, { iconProps: { iconName: 'Link' }, className: classes.button, disabled: disabled, onMouseDown: (e) => { setLinkOpen(true); e.preventDefault(); setReadOnly(true); return false; } }), react_1.default.createElement(react_2.DefaultButton, { iconProps: { iconName: 'FileCode' }, className: classes.button, disabled: disabled, onMouseDown: (e) => { setAceOpen(true); e.preventDefault(); setSelection(editorState.getSelection()); return false; } }), react_1.default.createElement(react_2.DefaultButton, { iconProps: { iconName: 'WebComponents' }, className: classes.button, disabled: disabled, onMouseDown: (e) => { setComponentsOpen(true); e.preventDefault(); setSelection(editorState.getSelection()); return false; } }), react_1.default.createElement(react_2.DefaultButton, { iconProps: { iconName: 'Copy' }, className: classes.button, disabled: disabled, onMouseDown: () => { try { (0, utility_1.copyToClipboard)(JSON.stringify((0, draft_js_1.convertToRaw)(editorState.getCurrentContent()))); openSnackbar({ message: 'Content copied', messageBarType: react_2.MessageBarType.success }); } catch (_a) { // } return false; } })), react_1.default.createElement(assets_select_panel_1.default, { isOpen: assetOpen, mimeTypes: ['image/jpeg', 'image/webp', 'image/png', 'image/gif', 'image/svg+xml'], selectionMode: react_2.SelectionMode.single, onDismiss: () => { setAssetOpen(false); forceSelection(); }, onSubmit: (asset) => { if (asset[0]) { createImage(asset[0]); } setAssetOpen(false); } }), react_1.default.createElement(insert_link_dialog_1.default, { isOpen: linkOpen, onDismiss: () => { setLinkOpen(false); setReadOnly(false); }, onInsert: (data) => { createLink(data); setLinkOpen(false); setReadOnly(false); } }), react_1.default.createElement(draft_ace_dialog_1.default, { isOpen: aceOpen, onDismiss: () => { setAceOpen(false); forceSelection(); }, onInsert: (data) => { if (data) { createAce(data === null || data === void 0 ? void 0 : data.mode); } setAceOpen(false); } }), react_1.default.createElement(content_types_components_select_panel_1.default, { isOpen: componentsOpen, filter: { type: 'component' }, onDismiss: () => setComponentsOpen(false), onSubmit: (e) => { createComponent(e === null || e === void 0 ? void 0 : e[0].name); setComponentsOpen(false); } }))); }; const UtilityButtons = () => { const classes = useToolbarStyles(); const { disabled } = (0, dynamic_form_1.useExtendedFormContext)(); const { editorState } = (0, dynamic_richtext_context_1.useRichtext)(); const { openSnackbar } = (0, snackbar_1.useSnackbar)(); const styles = useToolbarStyles(); return (react_1.default.createElement(react_1.default.Fragment, null, react_1.default.createElement("div", { className: styles.group }, react_1.default.createElement(react_2.DefaultButton, { iconProps: { iconName: 'Copy' }, label: 'Copy', className: classes.button, disabled: disabled, onMouseDown: () => { try { (0, utility_1.copyToClipboard)(JSON.stringify((0, draft_js_1.convertToRaw)(editorState.getCurrentContent()))); openSnackbar({ message: 'Raw content copied', messageBarType: react_2.MessageBarType.success }); } catch (_a) { // } return false; } })))); }; const RichtextToolbar = () => { return (react_1.default.createElement(react_1.default.Fragment, null, react_1.default.createElement(BlockButtons, null), react_1.default.createElement(InlineButtons, null), react_1.default.createElement(ActionButtons, null), react_1.default.createElement(UtilityButtons, null))); }; exports.default = RichtextToolbar;