burdy
Version:
Open Source Headless Platform
282 lines (281 loc) • 15.5 kB
JavaScript
"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;