UNPKG

@amaui/ui-react

Version:
742 lines 101 kB
"use strict"; var __rest = (this && this.__rest) || function (s, e) { var t = {}; for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) t[p] = s[p]; if (s != null && typeof Object.getOwnPropertySymbols === "function") for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) { if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i])) t[p[i]] = s[p[i]]; } return t; }; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); const jsx_runtime_1 = require("react/jsx-runtime"); const react_1 = __importDefault(require("react")); const utils_1 = require("@amaui/utils"); const style_react_1 = require("@amaui/style-react"); const IconMaterialFormatItalicW100_1 = __importDefault(require("@amaui/icons-material-rounded-react/IconMaterialFormatItalicW100")); const IconMaterialFormatUnderlinedW100_1 = __importDefault(require("@amaui/icons-material-rounded-react/IconMaterialFormatUnderlinedW100")); const IconMaterialFormatBoldW100_1 = __importDefault(require("@amaui/icons-material-rounded-react/IconMaterialFormatBoldW100")); const IconMaterialContentCopyW100_1 = __importDefault(require("@amaui/icons-material-rounded-react/IconMaterialContentCopyW100")); const IconMaterialContentCutW100_1 = __importDefault(require("@amaui/icons-material-rounded-react/IconMaterialContentCutW100")); const IconMaterialContentPasteW100_1 = __importDefault(require("@amaui/icons-material-rounded-react/IconMaterialContentPasteW100")); const IconMaterialFormatAlignLeftW100_1 = __importDefault(require("@amaui/icons-material-rounded-react/IconMaterialFormatAlignLeftW100")); const IconMaterialFormatAlignCenterW100_1 = __importDefault(require("@amaui/icons-material-rounded-react/IconMaterialFormatAlignCenterW100")); const IconMaterialFormatAlignRightW100_1 = __importDefault(require("@amaui/icons-material-rounded-react/IconMaterialFormatAlignRightW100")); const IconMaterialFormatAlignJustifyW100_1 = __importDefault(require("@amaui/icons-material-rounded-react/IconMaterialFormatAlignJustifyW100")); const IconMaterialStrikethroughSW100_1 = __importDefault(require("@amaui/icons-material-rounded-react/IconMaterialStrikethroughSW100")); const IconMaterialUndoW100_1 = __importDefault(require("@amaui/icons-material-rounded-react/IconMaterialUndoW100")); const IconMaterialRedoW100_1 = __importDefault(require("@amaui/icons-material-rounded-react/IconMaterialRedoW100")); const IconMaterialFormatClearW100_1 = __importDefault(require("@amaui/icons-material-rounded-react/IconMaterialFormatClearW100")); const IconMaterialSuperscriptW100_1 = __importDefault(require("@amaui/icons-material-rounded-react/IconMaterialSuperscriptW100")); const IconMaterialSubscriptW100_1 = __importDefault(require("@amaui/icons-material-rounded-react/IconMaterialSubscriptW100")); const IconMaterialFormatIndentIncreaseW100_1 = __importDefault(require("@amaui/icons-material-rounded-react/IconMaterialFormatIndentIncreaseW100")); const IconMaterialFormatIndentDecreaseW100_1 = __importDefault(require("@amaui/icons-material-rounded-react/IconMaterialFormatIndentDecreaseW100")); const IconMaterialFormatListNumberedW100_1 = __importDefault(require("@amaui/icons-material-rounded-react/IconMaterialFormatListNumberedW100")); const IconMaterialFormatListBulletedW100_1 = __importDefault(require("@amaui/icons-material-rounded-react/IconMaterialFormatListBulletedW100")); const IconMaterialHorizontalRuleW100_1 = __importDefault(require("@amaui/icons-material-rounded-react/IconMaterialHorizontalRuleW100")); const IconMaterialFormatColorTextW100_1 = __importDefault(require("@amaui/icons-material-rounded-react/IconMaterialFormatColorTextW100")); const IconMaterialFormatColorFillW100_1 = __importDefault(require("@amaui/icons-material-rounded-react/IconMaterialFormatColorFillW100")); const IconMaterialAddLinkW100_1 = __importDefault(require("@amaui/icons-material-rounded-react/IconMaterialAddLinkW100")); const IconMaterialLinkOffW100_1 = __importDefault(require("@amaui/icons-material-rounded-react/IconMaterialLinkOffW100")); const IconMaterialImageW100_1 = __importDefault(require("@amaui/icons-material-rounded-react/IconMaterialImageW100")); const IconMaterialFormatQuoteW100_1 = __importDefault(require("@amaui/icons-material-rounded-react/IconMaterialFormatQuoteW100")); const IconMaterialVideocamW100_1 = __importDefault(require("@amaui/icons-material-rounded-react/IconMaterialVideocamW100")); const IconMaterialPlayArrowW100_1 = __importDefault(require("@amaui/icons-material-rounded-react/IconMaterialPlayArrowW100")); const IconMaterialCodeW100_1 = __importDefault(require("@amaui/icons-material-rounded-react/IconMaterialCodeW100")); const IconMaterialDeleteSweepW100_1 = __importDefault(require("@amaui/icons-material-rounded-react/IconMaterialDeleteSweepW100")); const IconMaterialSelectAllW100_1 = __importDefault(require("@amaui/icons-material-rounded-react/IconMaterialSelectAllW100")); const IconMaterialPrintW100_1 = __importDefault(require("@amaui/icons-material-rounded-react/IconMaterialPrintW100")); const IconMaterialDownloadW100_1 = __importDefault(require("@amaui/icons-material-rounded-react/IconMaterialDownloadW100")); const IconMaterialTableW100_1 = __importDefault(require("@amaui/icons-material-rounded-react/IconMaterialTableW100")); const IconMaterialDrawW100_1 = __importDefault(require("@amaui/icons-material-rounded-react/IconMaterialDrawW100")); const Type_1 = __importDefault(require("../Type")); const Tooltip_1 = __importDefault(require("../Tooltip")); const Fade_1 = __importDefault(require("../Fade")); const Append_1 = __importDefault(require("../Append")); const Select_1 = __importDefault(require("../Select")); const Switch_1 = __importDefault(require("../Switch")); const Label_1 = __importDefault(require("../Label")); const NumericTextField_1 = __importDefault(require("../NumericTextField")); const ColorTextField_1 = __importDefault(require("../ColorTextField")); const ToggleButtons_1 = __importDefault(require("../ToggleButtons")); const ToggleButton_1 = __importDefault(require("../ToggleButton")); const Drawing_1 = __importDefault(require("../Drawing")); const Divider_1 = __importDefault(require("../Divider")); const ClickListener_1 = __importDefault(require("../ClickListener")); const TextField_1 = __importDefault(require("../TextField")); const Button_1 = __importDefault(require("../Button")); const Surface_1 = __importDefault(require("../Surface")); const ListItem_1 = __importDefault(require("../ListItem")); const Line_1 = __importDefault(require("../Line")); const utils_2 = require("../utils"); const useStyle = (0, style_react_1.style)(theme => ({ root: { width: '100%' }, value: { padding: theme.methods.space.value(2, 'px'), whiteSpace: 'break-spaces', '& p': Object.assign({}, theme.typography.values.b2), '& h1': Object.assign({}, theme.typography.values.h1), '& h2': Object.assign({}, theme.typography.values.h2), '& h3': Object.assign({}, theme.typography.values.h3), '& h4': Object.assign({}, theme.typography.values.t1), '& h5': Object.assign({}, theme.typography.values.t2), '& a': { color: theme.palette.color.primary.main, textDecoration: 'underline' }, '& blockquote': { margin: '16px 0', marginInlineStart: '16px', padding: `${theme.methods.space.value(2.5, 'px')} ${theme.methods.space.value(2, 'px')}`, borderInlineStart: `4px solid ${theme.methods.palette.color.colorToRgb(theme.palette.text.default.primary, theme.palette.light ? 0.04 : 0.2)}`, background: theme.methods.palette.color.colorToRgb(theme.palette.text.default.primary, theme.palette.light ? 0.02 : 0.14), '& > *': { margin: '0px' }, '& > $blockquote': { marginBlock: '16px' } }, '& iframe': { display: 'block', maxWidth: '100%', margin: '16px auto' }, '& video': { display: 'block', margin: '16px auto' }, '& code': { padding: `${theme.methods.space.value(0.25, 'px')} ${theme.methods.space.value(0.5, 'px')}`, borderRadius: theme.methods.shape.radius.value(0.5, 'px'), color: theme.palette.text.default.primary, background: theme.methods.palette.color.colorToRgb(theme.palette.text.default.primary, theme.palette.light ? 0.04 : 0.1) }, '& pre': { margin: '16px 0', padding: theme.methods.space.value(2, 'px'), borderRadius: theme.methods.shape.radius.value(1, 'px'), color: theme.palette.text.default.primary, background: theme.methods.palette.color.colorToRgb(theme.palette.text.default.primary, theme.palette.light ? 0.04 : 0.1), '& code': { padding: '0px', background: 'transparent' } }, '& table': { margin: '16px auto', borderCollapse: 'collapse', border: `1px solid ${theme.palette.light ? theme.palette.color.neutral[80] : theme.palette.color.neutral[30]}`, '& th, & td': Object.assign(Object.assign({}, theme.typography.values.b2), { height: '45px', padding: `${theme.methods.space.value(1.5, 'px')} ${theme.methods.space.value(2, 'px')}`, borderBottom: `1px solid ${theme.palette.light ? theme.palette.color.neutral[80] : theme.palette.color.neutral[30]}`, borderRight: `1px solid ${theme.palette.light ? theme.palette.color.neutral[80] : theme.palette.color.neutral[30]}` }), '& th': { fontWeight: 500, borderBottom: `1px solid ${theme.palette.light ? theme.palette.color.neutral[50] : theme.palette.color.neutral[50]}` } }, '& .amaui-Drawing-svg': { display: 'block', margin: '16px auto', background: theme.palette.color.neutral[100] } }, toolbars: { width: '100%' }, toolbar: { width: '100%', overflowX: 'auto', padding: theme.methods.space.value(1, 'px') }, divider: { '&.amaui-Divider-root': { margin: 0 } }, divider_middle: { '&.amaui-Divider-root': { opacity: theme.palette.light ? 0.07 : 0.24 } }, divider_end: { '&.amaui-Divider-root': { opacity: theme.palette.light ? 0.14 : 0.4 } }, select: { '& .amaui-TextField-input-wrapper': { height: '40px', paddingBlock: theme.methods.space.value(1.25, 'px') }, '& .amaui-Select-input': { '& > *': Object.assign(Object.assign({}, theme.typography.values.b2), { fontWeight: 400 }) } }, miniMenu: { padding: theme.methods.space.value(1.5, 'px'), borderRadius: theme.methods.shape.radius.value(140, 'px'), boxShadow: theme.shadows.values.default[2] }, palette: { padding: theme.methods.space.value(1.5, 'px'), borderRadius: theme.methods.shape.radius.value(1, 'px'), boxShadow: theme.shadows.values.default[2] }, paletteItem: { position: 'relative', width: '17px', height: '17px', cursor: 'pointer', borderRadius: theme.methods.shape.radius.value(40, 'px'), boxShadow: theme.shadows.values.default[1], transition: theme.methods.transitions.make('box-shadow'), '&:hover': { boxShadow: theme.shadows.values.default[2], } }, textFieldColor: { flex: '1 1 auto' }, inputColor: { border: 'none', borderRadius: theme.methods.shape.radius.value(40, 'px'), overflow: 'hidden', width: '17px', height: '17px', cursor: 'pointer', boxShadow: theme.shadows.values.default[1], '&::-webkit-color-swatch-wrapper': { padding: '0px' }, '&::-webkit-color-swatch': { border: 'none' } } }), { name: 'amaui-RichTextEditor' }); const RichTextEditor = react_1.default.forwardRef((props__, ref) => { var _a; const theme = (0, style_react_1.useAmauiTheme)(); const props = react_1.default.useMemo(() => { var _a, _b, _c, _d, _e, _f, _g, _h; return (Object.assign(Object.assign(Object.assign({}, (_d = (_c = (_b = (_a = theme === null || theme === void 0 ? void 0 : theme.ui) === null || _a === void 0 ? void 0 : _a.elements) === null || _b === void 0 ? void 0 : _b.all) === null || _c === void 0 ? void 0 : _c.props) === null || _d === void 0 ? void 0 : _d.default), (_h = (_g = (_f = (_e = theme === null || theme === void 0 ? void 0 : theme.ui) === null || _e === void 0 ? void 0 : _e.elements) === null || _f === void 0 ? void 0 : _f.amauiRichTextEditor) === null || _g === void 0 ? void 0 : _g.props) === null || _h === void 0 ? void 0 : _h.default), props__)); }, [props__]); const Line = react_1.default.useMemo(() => { var _a; return ((_a = theme === null || theme === void 0 ? void 0 : theme.elements) === null || _a === void 0 ? void 0 : _a.Line) || Line_1.default; }, [theme]); const Type = react_1.default.useMemo(() => { var _a; return ((_a = theme === null || theme === void 0 ? void 0 : theme.elements) === null || _a === void 0 ? void 0 : _a.Type) || Type_1.default; }, [theme]); const Tooltip = react_1.default.useMemo(() => { var _a; return ((_a = theme === null || theme === void 0 ? void 0 : theme.elements) === null || _a === void 0 ? void 0 : _a.Tooltip) || Tooltip_1.default; }, [theme]); const Fade = react_1.default.useMemo(() => { var _a; return ((_a = theme === null || theme === void 0 ? void 0 : theme.elements) === null || _a === void 0 ? void 0 : _a.Fade) || Fade_1.default; }, [theme]); const Append = react_1.default.useMemo(() => { var _a; return ((_a = theme === null || theme === void 0 ? void 0 : theme.elements) === null || _a === void 0 ? void 0 : _a.Append) || Append_1.default; }, [theme]); const Select = react_1.default.useMemo(() => { var _a; return ((_a = theme === null || theme === void 0 ? void 0 : theme.elements) === null || _a === void 0 ? void 0 : _a.Select) || Select_1.default; }, [theme]); const Switch = react_1.default.useMemo(() => { var _a; return ((_a = theme === null || theme === void 0 ? void 0 : theme.elements) === null || _a === void 0 ? void 0 : _a.Switch) || Switch_1.default; }, [theme]); const Label = react_1.default.useMemo(() => { var _a; return ((_a = theme === null || theme === void 0 ? void 0 : theme.elements) === null || _a === void 0 ? void 0 : _a.Label) || Label_1.default; }, [theme]); const NumericTextField = react_1.default.useMemo(() => { var _a; return ((_a = theme === null || theme === void 0 ? void 0 : theme.elements) === null || _a === void 0 ? void 0 : _a.NumericTextField) || NumericTextField_1.default; }, [theme]); const ColorTextField = react_1.default.useMemo(() => { var _a; return ((_a = theme === null || theme === void 0 ? void 0 : theme.elements) === null || _a === void 0 ? void 0 : _a.ColorTextField) || ColorTextField_1.default; }, [theme]); const ToggleButton = react_1.default.useMemo(() => { var _a; return ((_a = theme === null || theme === void 0 ? void 0 : theme.elements) === null || _a === void 0 ? void 0 : _a.ToggleButton) || ToggleButton_1.default; }, [theme]); const ToggleButtons = react_1.default.useMemo(() => { var _a; return ((_a = theme === null || theme === void 0 ? void 0 : theme.elements) === null || _a === void 0 ? void 0 : _a.ToggleButtons) || ToggleButtons_1.default; }, [theme]); const Drawing = react_1.default.useMemo(() => { var _a; return ((_a = theme === null || theme === void 0 ? void 0 : theme.elements) === null || _a === void 0 ? void 0 : _a.Drawing) || Drawing_1.default; }, [theme]); const Divider = react_1.default.useMemo(() => { var _a; return ((_a = theme === null || theme === void 0 ? void 0 : theme.elements) === null || _a === void 0 ? void 0 : _a.Divider) || Divider_1.default; }, [theme]); const ClickListener = react_1.default.useMemo(() => { var _a; return ((_a = theme === null || theme === void 0 ? void 0 : theme.elements) === null || _a === void 0 ? void 0 : _a.ClickListener) || ClickListener_1.default; }, [theme]); const TextField = react_1.default.useMemo(() => { var _a; return ((_a = theme === null || theme === void 0 ? void 0 : theme.elements) === null || _a === void 0 ? void 0 : _a.TextField) || TextField_1.default; }, [theme]); const Surface = react_1.default.useMemo(() => { var _a; return ((_a = theme === null || theme === void 0 ? void 0 : theme.elements) === null || _a === void 0 ? void 0 : _a.Surface) || Surface_1.default; }, [theme]); const Button = react_1.default.useMemo(() => { var _a; return ((_a = theme === null || theme === void 0 ? void 0 : theme.elements) === null || _a === void 0 ? void 0 : _a.Button) || Button_1.default; }, [theme]); const ListItem = react_1.default.useMemo(() => { var _a; return ((_a = theme === null || theme === void 0 ? void 0 : theme.elements) === null || _a === void 0 ? void 0 : _a.ListItem) || ListItem_1.default; }, [theme]); const { tonal = true, color = 'default', version = 'filled', value, onChange, render, miniMenu = true, miniMenuInclude = [ 'italic', 'underline', 'bold', 'strike-line', 'font-color', 'font-background', 'align-left', 'align-center', 'align-right', 'align-justify', 'link-add', 'link-remove', 'clear' ], exclude, updates = true, actions = true, fontFamilies = [ { label: 'Arial', value: `Arial, sans-serif` }, { label: 'Verdana', value: `Verdana, sans-serif` }, { label: 'Helvetica', value: `Helvetica, sans-serif` }, { label: 'Georgia', value: `Georgia, sans-serif` }, { label: 'Roboto', value: `Roboto, sans-serif` }, { label: 'DM Sans', value: `DM Sans, sans-serif` } ], addFontFamilies = [], // Update IconItalic = IconMaterialFormatItalicW100_1.default, IconUnderline = IconMaterialFormatUnderlinedW100_1.default, IconBold = IconMaterialFormatBoldW100_1.default, IconStrikeLine = IconMaterialStrikethroughSW100_1.default, IconColor = IconMaterialFormatColorTextW100_1.default, IconBackground = IconMaterialFormatColorFillW100_1.default, IconAlignLeft = IconMaterialFormatAlignLeftW100_1.default, IconAlignCenter = IconMaterialFormatAlignCenterW100_1.default, IconAlignRight = IconMaterialFormatAlignRightW100_1.default, IconAlignJustify = IconMaterialFormatAlignJustifyW100_1.default, IconIndent = IconMaterialFormatIndentIncreaseW100_1.default, IconOutdent = IconMaterialFormatIndentDecreaseW100_1.default, IconSuperscript = IconMaterialSuperscriptW100_1.default, IconSubscript = IconMaterialSubscriptW100_1.default, IconListOrdered = IconMaterialFormatListNumberedW100_1.default, IconListUnordered = IconMaterialFormatListBulletedW100_1.default, IconHorizontalRule = IconMaterialHorizontalRuleW100_1.default, IconLinkAdd = IconMaterialAddLinkW100_1.default, IconLinkRemove = IconMaterialLinkOffW100_1.default, IconQuote = IconMaterialFormatQuoteW100_1.default, IconImage = IconMaterialImageW100_1.default, IconVideo = IconMaterialVideocamW100_1.default, IconVideoYoutube = IconMaterialPlayArrowW100_1.default, IconTable = IconMaterialTableW100_1.default, IconCode = IconMaterialCodeW100_1.default, IconDrawing = IconMaterialDrawW100_1.default, // Action IconCopy = IconMaterialContentCopyW100_1.default, IconCut = IconMaterialContentCutW100_1.default, IconPaste = IconMaterialContentPasteW100_1.default, IconDelete = IconMaterialDeleteSweepW100_1.default, IconClear = IconMaterialFormatClearW100_1.default, IconSelectAll = IconMaterialSelectAllW100_1.default, IconSave = IconMaterialDownloadW100_1.default, IconPrint = IconMaterialPrintW100_1.default, IconUndo = IconMaterialUndoW100_1.default, IconRedo = IconMaterialRedoW100_1.default, AppendProps: AppendProps_, ToolbarProps, ToolbarUpdatesProps, ToolbarActionsProps, ToggleButtonProps: ToggleButtonProps_, ToggleButtonsProps: ToggleButtonsProps_, DividerProps: DividerProps_, SelectProps: SelectProps_, ListItemProps: ListItemProps_, TooltipProps: TooltipProps_, MiniMenuProps: MiniMenuProps_, DrawingProps, IconProps: IconProps_, ColorTextFieldProps, Component = 'div', className, children } = props, other = __rest(props, ["tonal", "color", "version", "value", "onChange", "render", "miniMenu", "miniMenuInclude", "exclude", "updates", "actions", "fontFamilies", "addFontFamilies", "IconItalic", "IconUnderline", "IconBold", "IconStrikeLine", "IconColor", "IconBackground", "IconAlignLeft", "IconAlignCenter", "IconAlignRight", "IconAlignJustify", "IconIndent", "IconOutdent", "IconSuperscript", "IconSubscript", "IconListOrdered", "IconListUnordered", "IconHorizontalRule", "IconLinkAdd", "IconLinkRemove", "IconQuote", "IconImage", "IconVideo", "IconVideoYoutube", "IconTable", "IconCode", "IconDrawing", "IconCopy", "IconCut", "IconPaste", "IconDelete", "IconClear", "IconSelectAll", "IconSave", "IconPrint", "IconUndo", "IconRedo", "AppendProps", "ToolbarProps", "ToolbarUpdatesProps", "ToolbarActionsProps", "ToggleButtonProps", "ToggleButtonsProps", "DividerProps", "SelectProps", "ListItemProps", "TooltipProps", "MiniMenuProps", "DrawingProps", "IconProps", "ColorTextFieldProps", "Component", "className", "children"]); const { classes } = useStyle(); const [inputValues, setInputValues] = react_1.default.useState({}); const [open, setOpen] = react_1.default.useState({}); const [selected, setSelected] = react_1.default.useState([]); const [selection, setSelection] = react_1.default.useState(); const refs = { root: react_1.default.useRef(undefined), value: react_1.default.useRef(undefined), range: react_1.default.useRef(undefined), inputValues: react_1.default.useRef(undefined), open: react_1.default.useRef(undefined), props: react_1.default.useRef(undefined), selected: react_1.default.useRef(undefined), miniMenu: react_1.default.useRef(undefined), miniMenuInclude: react_1.default.useRef(undefined), miniMenuElements: { color: react_1.default.useRef(undefined), colorPalette: react_1.default.useRef(undefined), background: react_1.default.useRef(undefined), backgroundPalette: react_1.default.useRef(undefined), linkAdd: react_1.default.useRef(undefined), linkAddInput: react_1.default.useRef(undefined), linkRemove: react_1.default.useRef(undefined), }, elements: { color: react_1.default.useRef(undefined), background: react_1.default.useRef(undefined), linkAdd: react_1.default.useRef(undefined), linkRemove: react_1.default.useRef(undefined), quote: react_1.default.useRef(undefined), image: react_1.default.useRef(undefined), video: react_1.default.useRef(undefined), videoYoutube: react_1.default.useRef(undefined), table: react_1.default.useRef(undefined), drawing: react_1.default.useRef(undefined), drawingSvg: react_1.default.useRef(undefined), drawingSize: react_1.default.useRef(undefined), drawingSelect: react_1.default.useRef(undefined), drawingPalette: react_1.default.useRef(undefined), code: react_1.default.useRef(undefined) }, rootDocument: react_1.default.useRef(), rootWindow: react_1.default.useRef() }; refs.inputValues.current = inputValues; refs.open.current = open; refs.props.current = props; refs.selected.current = selected; refs.miniMenuInclude.current = miniMenuInclude; const rootDocument = (0, utils_1.isEnvironment)('browser') && (((_a = refs.root.current) === null || _a === void 0 ? void 0 : _a.ownerDocument) || window.document); const rootWindow = rootDocument && (rootDocument.defaultView || window); refs.rootDocument.current = rootDocument; refs.rootWindow.current = rootWindow; react_1.default.useEffect(() => { // Add value as innerHTML refs.value.current.innerHTML = value; }, [value]); react_1.default.useEffect(() => { var _a, _b; const selection_ = refs.rootWindow.current.getSelection(); if (selection_.anchorNode && !((_b = (_a = selection_.anchorNode) === null || _a === void 0 ? void 0 : _a.className) === null || _b === void 0 ? void 0 : _b.includes('TextField'))) refs.range.current = selection_.getRangeAt(0); }, [open]); react_1.default.useEffect(() => { if (!selection) { updateOpen('colorMiniMenu', false); updateOpen('backgroundMiniMenu', false); updateOpen('linkMiniMenu', false); } }, [selection]); const query = (command) => { return (0, utils_1.parse)(refs.rootDocument.current.queryCommandValue(command)); }; const includesMinMenu = (...args) => args.some(item => refs.miniMenuInclude.current.includes(item)); const clear = (element = refs.value.current) => { const children_ = Array.from(element.children); const toRemove = []; const other_ = []; children_.forEach((item, index) => { ((item.tagName === 'SPAN' && !item.innerHTML) || (item.tagName === 'BR' && index > 0 && (children_[index - 1].tagName === 'SPAN' && !children_[index - 1].innerHTML))) ? toRemove.push(item) : other_.push(item); }); toRemove.forEach((item) => item.remove()); other_.forEach(item => clear(item)); }; const onUpdate = (event) => { // Clear from empty element values clear(); if ((0, utils_1.is)('function', onChange)) onChange(event); }; const updateInputValues = (property, itemValue) => { setInputValues(values => (Object.assign(Object.assign({}, values), { [property]: itemValue }))); }; const updateOpen = (property, itemValue) => { setOpen(values => (Object.assign(Object.assign({}, values), { [property]: itemValue }))); }; const paste = async () => { const value_ = await navigator.clipboard.read(); if (value_) { let values = ''; for (const item of Array.from(value_)) { const valueItem = await item.getType('text/html'); values += await valueItem.text(); } refs.rootDocument.current.execCommand('insertHTML', undefined, values); } }; const method = react_1.default.useCallback((command) => (argument) => { switch (command) { // updates case 'italic': refs.rootDocument.current.execCommand('italic'); if (query('italic')) setSelected(values => [...values, 'italic']); else setSelected(values => values.filter(item => item !== 'italic')); break; case 'underline': refs.rootDocument.current.execCommand('underline'); if (query('underline')) setSelected(values => [...values, 'underline']); else setSelected(values => values.filter(item => item !== 'underline')); break; case 'bold': refs.rootDocument.current.execCommand('bold'); if (query('bold')) setSelected(values => [...values, 'bold']); else setSelected(values => values.filter(item => item !== 'bold')); break; case 'strike-line': refs.rootDocument.current.execCommand('strikeThrough'); if (query('strikeThrough')) setSelected(values => [...values, 'strike-line']); else setSelected(values => values.filter(item => item !== 'strike-line')); break; case 'align-left': refs.rootDocument.current.execCommand('justifyLeft'); if (query('justifyLeft')) setSelected(values => [...values.filter(item => !item.includes('align')), 'align-left']); else setSelected(values => values.filter(item => item !== 'align-left')); break; case 'align-center': refs.rootDocument.current.execCommand('justifyCenter'); if (query('justifyCenter')) setSelected(values => [...values.filter(item => !item.includes('align')), 'align-center']); else setSelected(values => values.filter(item => item !== 'align-center')); break; case 'align-right': refs.rootDocument.current.execCommand('justifyRight'); if (query('justifyRight')) setSelected(values => [...values.filter(item => !item.includes('align')), 'align-right']); else setSelected(values => values.filter(item => item !== 'align-right')); break; case 'align-justify': refs.rootDocument.current.execCommand('justifyFull'); if (query('justifyFull')) setSelected(values => [...values.filter(item => !item.includes('align')), 'align-justify']); else setSelected(values => values.filter(item => item !== 'align-justify')); break; case 'superscript': refs.rootDocument.current.execCommand('superscript'); if (query('superscript')) setSelected(values => [...values, 'superscript']); else setSelected(values => values.filter(item => item !== 'superscript')); break; case 'subscript': refs.rootDocument.current.execCommand('subscript'); if (query('subscript')) setSelected(values => [...values, 'subscript']); else setSelected(values => values.filter(item => item !== 'subscript')); break; case 'indent': refs.rootDocument.current.execCommand('indent'); break; case 'outdent': refs.rootDocument.current.execCommand('outdent'); break; case 'font-version': refs.rootDocument.current.execCommand('formatBlock', undefined, argument); break; case 'font-family': refs.rootDocument.current.execCommand('styleWithCSS', true); refs.rootDocument.current.execCommand('fontName', undefined, argument); refs.rootDocument.current.execCommand('styleWithCSS', false); break; case 'font-size': refs.rootDocument.current.execCommand('styleWithCSS', true); refs.rootDocument.current.execCommand('fontSize', undefined, argument); refs.rootDocument.current.execCommand('styleWithCSS', false); break; case 'font-color': refs.rootDocument.current.execCommand('styleWithCSS', true); refs.rootDocument.current.execCommand('foreColor', undefined, argument); refs.rootDocument.current.execCommand('styleWithCSS', false); break; case 'font-background': refs.rootDocument.current.execCommand('styleWithCSS', true); refs.rootDocument.current.execCommand('backColor', undefined, argument); refs.rootDocument.current.execCommand('styleWithCSS', false); break; case 'list-ordered': refs.rootDocument.current.execCommand('insertOrderedList'); if (query('insertOrderedList')) setSelected(values => [...values.filter(item => !item.includes('list')), 'list-ordered']); else setSelected(values => values.filter(item => item !== 'list-ordered')); break; case 'list-unordered': refs.rootDocument.current.execCommand('insertUnorderedList'); if (query('insertUnorderedList')) setSelected(values => [...values.filter(item => !item.includes('list')), 'list-unordered']); else setSelected(values => values.filter(item => item !== 'list-unordered')); break; case 'horizontal-rule': refs.rootDocument.current.execCommand('insertHorizontalRule'); break; case 'link-add': refs.rootDocument.current.execCommand('createLink', undefined, argument); break; case 'link-remove': refs.rootDocument.current.execCommand('unlink'); break; case 'image': refs.rootDocument.current.execCommand('insertImage', undefined, argument); break; case 'html': refs.rootDocument.current.execCommand('insertHTML', undefined, argument); break; // actions case 'copy': refs.rootDocument.current.execCommand('copy'); break; case 'cut': refs.rootDocument.current.execCommand('cut'); break; case 'paste': if (refs.rootDocument.current.queryCommandSupported('paste')) refs.rootDocument.current.execCommand('paste'); else paste(); break; case 'delete': refs.rootDocument.current.execCommand('delete'); break; case 'clear': refs.rootDocument.current.execCommand('removeFormat'); break; case 'select-all': refs.rootDocument.current.execCommand('selectAll'); break; case 'undo': refs.rootDocument.current.execCommand('undo'); break; case 'redo': refs.rootDocument.current.execCommand('redo'); break; default: break; } }, []); const includes = (...args) => !(0, utils_1.is)('array', exclude) || args.some(item => !exclude.includes(item)); // italic, underline, bold // updates toolbar const updateOptions = ['font-family', 'font-version', 'font-size', 'font-color', 'font-background', 'italic', 'underline', 'bold', 'strike-line', 'align-left', 'align-center', 'align-right', 'align-justify', 'superscript', 'subscript', 'indent', 'outdent', 'list-ordered', 'list-unordered', 'horizontal-rule', 'link-add', 'link-remove', 'quote', 'image', 'video', 'video-youtube', 'table', 'drawing', 'code']; const updates_ = updates && (!(0, utils_1.is)('array', exclude) || includes(...updateOptions)); // copy, paste, cut // action toolbar const actions_ = actions && (!(0, utils_1.is)('array', exclude) || includes('copy', 'paste', 'cut', 'clear', 'undo', 'redo', 'delete', 'select-all', 'save', 'print')); const AppendProps = Object.assign({ padding: [14, 14] }, AppendProps_); const DividerProps = Object.assign({ color: 'inherit' }, DividerProps_); const TooltipProps = Object.assign({ position: 'bottom', interactive: false }, TooltipProps_); const ToggleButtonsProps = Object.assign({ tonal, color, version: 'text', border: false }, ToggleButtonsProps_); const ToggleButtonProps = Object.assign({ size: 'small' }, ToggleButtonProps_); const MiniMenuProps = Object.assign({ tonal, color: refs.props.current.color !== undefined ? refs.props.current.color : 'themed' }, MiniMenuProps_); const SelectProps = Object.assign({ tonal, color: refs.props.current.color !== undefined ? refs.props.current.color : 'themed', version: 'outlined', size: 'small', ListProps: { tonal, color: refs.props.current.color !== undefined ? refs.props.current.color : 'themed' }, MenuProps: { portal: true } }, SelectProps_); const ListItemProps = Object.assign({ size: 'small', PrimaryProps: { style: { fontFamily: 'inherit' } } }, ListItemProps_); const IconProps = Object.assign({ size: 'small' }, IconProps_); const WrapperToggleButton = react_1.default.useCallback(react_1.default.forwardRef((props_, ref_) => { const { open: open_, label, children: children_ } = props_, other_ = __rest(props_, ["open", "label", "children"]); return ((0, jsx_runtime_1.jsx)(Tooltip, Object.assign({ open: open_ !== undefined ? open_ : undefined, label: label }, TooltipProps, { children: react_1.default.cloneElement(children_, Object.assign(Object.assign({}, other_), children_.props)) }))); }), []); const WrapperAppend = react_1.default.useCallback((props_) => { const { open: open_, element, anchorElement, onClose, children: children_ } = props_, other_ = __rest(props_, ["open", "element", "anchorElement", "onClose", "children"]); return ((0, jsx_runtime_1.jsx)(Append, Object.assign({ open: open_, element: ((0, jsx_runtime_1.jsx)("div", { children: (0, jsx_runtime_1.jsx)(Fade, Object.assign({ in: open_, add: true }, { children: react_1.default.cloneElement(element) })) })), anchorElement: anchorElement, portal: true, alignment: 'center', position: 'bottom' }, AppendProps, { children: react_1.default.cloneElement(children_, Object.assign(Object.assign({}, other_), children_.props)) }))); }, []); const onMouseDown = react_1.default.useCallback(() => { var _a, _b; const selection_ = refs.rootWindow.current.getSelection(); if (selection_.anchorNode && !((_b = (_a = selection_.anchorNode) === null || _a === void 0 ? void 0 : _a.className) === null || _b === void 0 ? void 0 : _b.includes('TextField'))) refs.range.current = selection_.getRangeAt(0); }, []); const onMouseUp = react_1.default.useCallback(() => { if (refs.range.current) { const selection_ = refs.rootWindow.current.getSelection(); selection_.removeAllRanges(); selection_.addRange(refs.range.current); } }, []); const PaletteItem = react_1.default.useCallback((props_) => { const { color: color_ } = props_, other_ = __rest(props_, ["color"]); return ((0, jsx_runtime_1.jsx)("span", Object.assign({ className: (0, style_react_1.classNames)([ (0, utils_2.staticClassName)('RichTextEditor', theme) && [ 'amaui-RichTextEditor-palette-item' ], classes.paletteItem ]), style: { background: color_ } }, other_))); }, []); const Palette = react_1.default.useCallback(react_1.default.forwardRef((props_, ref_) => { const { version: version_, onUpdate: onUpdate_, onClose } = props_, other_ = __rest(props_, ["version", "onUpdate", "onClose"]); return ((0, jsx_runtime_1.jsxs)(Line, Object.assign({ ref: ref_, gap: 1, direction: 'column', tonal: tonal, color: refs.props.current.color !== undefined ? refs.props.current.color : 'themed', Component: Surface, className: (0, style_react_1.classNames)([ (0, utils_2.staticClassName)('RichTextEditor', theme) && [ 'amaui-RichTextEditor-palette' ], classes.palette ]) }, other_, { children: [(0, jsx_runtime_1.jsxs)(Line, Object.assign({ gap: 0.5, onMouseUp: onMouseUp, onMouseDown: onMouseDown }, { children: [(0, jsx_runtime_1.jsxs)(Line, Object.assign({ gap: 0.5, direction: 'row', style: { width: '100%' } }, { children: [(0, jsx_runtime_1.jsx)(PaletteItem, { color: '#000000', onClick: () => { onUpdate_('#000000'); onClose(); } }), (0, jsx_runtime_1.jsx)(PaletteItem, { color: '#ffffff', onClick: () => { onUpdate_('#ffffff'); onClose(); } })] })), Object.keys(style_react_1.colors).filter(item => !['black', 'white'].includes(item)).map((item, index) => ((0, jsx_runtime_1.jsx)(Line, Object.assign({ gap: 0.5, direction: 'row', style: { width: '100%' } }, { children: Object.keys(style_react_1.colors[item]).map((item_, index_) => ((0, jsx_runtime_1.jsx)(PaletteItem, { color: style_react_1.colors[item][item_], onClick: () => { if (refs.range.current) { const selection_ = refs.rootWindow.current.getSelection(); selection_.removeAllRanges(); selection_.addRange(refs.range.current); } onUpdate_(style_react_1.colors[item][item_]); onClose(); } }, index_))) }), index)))] })), (0, jsx_runtime_1.jsx)(Divider, {}), (0, jsx_runtime_1.jsxs)(Line, Object.assign({ gap: 0.5, direction: 'row', align: 'center', style: { width: '100%' } }, { children: [(0, jsx_runtime_1.jsx)(ColorTextField, Object.assign({ tonal: tonal, color: color, label: 'Custom color', version: 'outlined', size: 'small', value: refs.inputValues.current[version_], onChange: valueNew => updateInputValues(version_, valueNew) }, ColorTextFieldProps, { className: (0, style_react_1.classNames)([ (0, utils_2.staticClassName)('RichTextEditor', theme) && [ 'amaui-RichTextEditor-text-field-color' ], ColorTextFieldProps === null || ColorTextFieldProps === void 0 ? void 0 : ColorTextFieldProps.className, classes.textFieldColor ]) })), (0, jsx_runtime_1.jsx)(Button, Object.assign({ tonal: tonal, color: 'inherit', version: 'text', size: 'small', onClick: () => { if (refs.range.current) { const selection_ = refs.rootWindow.current.getSelection(); selection_.removeAllRanges(); selection_.addRange(refs.range.current); } onUpdate_(refs.inputValues.current[version_]); onClose(); } }, { children: "Apply" }))] }))] }))); }), []); const Input = react_1.default.useCallback(react_1.default.forwardRef((props_, ref_) => { const { label, labelButton, value: value__, onChange: onChange__, onClick, InputComponent = TextField, InputProps } = props_, other_ = __rest(props_, ["label", "labelButton", "value", "onChange", "onClick", "InputComponent", "InputProps"]); return ((0, jsx_runtime_1.jsx)(Line, Object.assign({ ref: ref_, gap: 1, direction: 'column', tonal: tonal, color: refs.props.current.color !== undefined ? refs.props.current.color : 'themed', Component: Surface, className: (0, style_react_1.classNames)([ (0, utils_2.staticClassName)('RichTextEditor', theme) && [ 'amaui-RichTextEditor-palette' ], classes.palette ]) }, other_, { children: (0, jsx_runtime_1.jsxs)(Line, Object.assign({ gap: 0.5, direction: 'row', align: 'center', style: { width: '100%' } }, { children: [(0, jsx_runtime_1.jsx)(InputComponent, Object.assign({ tonal: tonal, color: color, label: label, version: 'outlined', size: 'small', value: value__, onChange: onChange__, className: (0, style_react_1.classNames)([ (0, utils_2.staticClassName)('RichTextEditor', theme) && [ 'amaui-RichTextEditor-text-field-color' ], classes.textFieldColor ]) }, InputProps)), (0, jsx_runtime_1.jsx)(Button, Object.assign({ tonal: tonal, color: 'inherit', version: 'text', size: 'small', onClick: onClick }, { children: labelButton }))] })) }))); }), []); const font_families = [ ...fontFamilies, ...addFontFamilies ]; const font_sizes = [ { label: '11', value: 1 }, { label: '14', value: 2 }, { label: '16', value: 3 }, { label: '18', value: 4 }, { label: '24', value: 5 }, { label: '32', value: 6 }, { label: '48', value: 7 } ]; const font_versions = [ { label: (0, jsx_runtime_1.jsx)(Type, Object.assign({ version: 'b2' }, { children: "Normal text" })), value: 'p' }, { label: (0, jsx_runtime_1.jsx)(Type, Object.assign({ version: 'h1' }, { children: "Heading 1" })), value: 'h1' }, { label: (0, jsx_runtime_1.jsx)(Type, Object.assign({ version: 'h2' }, { children: "Heading 2" })), value: 'h2' }, { label: (0, jsx_runtime_1.jsx)(Type, Object.assign({ version: 'h3' }, { children: "Heading 3" })), value: 'h3' }, { label: (0, jsx_runtime_1.jsx)(Type, Object.assign({ version: 't1' }, { children: "Heading 4" })), value: 'h4' }, { label: (0, jsx_runtime_1.jsx)(Type, Object.assign({ version: 't2' }, { children: "Heading 5" })), value: 'h5' } ]; const queryValueUpdate = () => { const selected_ = []; const inputValues_ = Object.assign({}, inputValues); const updateOptionValues = [ { name: 'italic', command: 'italic' }, { name: 'underline', command: 'underline' }, { name: 'bold', command: 'bold' }, { name: 'strike-line', command: 'strikeThrough' }, { name: 'align-left', command: 'justifyLeft' }, { name: 'align-center', command: 'justifyCenter' }, { name: 'align-right', command: 'justifyRight' }, { name: 'align-justify', command: 'justifyFull' }, { name: 'superscript', command: 'superscript' }, { name: 'subscript', command: 'subscript' }, { name: 'list-ordered', command: 'insertOrderedList' }, { name: 'list-unordered', command: 'insertUnorderedList' } ]; updateOptionValues.forEach(item => { if (query(item.command)) selected_.push(item.name); }); // Font version const fontVersion = query('formatBlock'); const fontVersionValue = font_versions.find(item_ => item_.value === fontVersion) || font_versions[0]; inputValues_['font-version'] = fontVersionValue === null || fontVersionValue === void 0 ? void 0 : fontVersionValue.value; // Font family const fontFamily = query('fontName'); const fontFamilyValue = font_families.find(item_ => fontFamily === null || fontFamily === void 0 ? void 0 : fontFamily.includes(item_.label)) || font_families.find(item_ => item_.label === 'DM Sans'); inputValues_['font-family'] = fontFamilyValue === null || fontFamilyValue === void 0 ? void 0 : fontFamilyValue.value; // Font version const fontSize = query('fontSize'); const fontSizeValue = font_sizes.find(item_ => item_.value === fontSize) || font_sizes.find(item_ => item_.label === '14'); inputValues_['font-size'] = fontSizeValue === null || fontSizeValue === void 0 ? void 0 : fontSizeValue.value; setInputValues(inputValues_); setSelected(selected_); }; const onMouseUpValue = react_1.default.useCallback(() => { queryValueUpdate(); setTimeout(() => { const selection_ = refs.rootWindow.current.getSelection(); if (!selection_.anchorNode || !refs.value.current.contains(selection_.anchorNode)) return setSelection(''); const rect = selection_.getRangeAt(0).getBoundingClientRect(); setSelection(Math.round(rect.width) ? rect : ''); }); }, []); const onMouseDownValue = react_1.default.useCallback(() => { queryValueUpdate(); }, []); const updateElements = { 'font-version': ((0, jsx_runtime_1.jsx)(Select, Object.assign({ label: 'Font Version', valueDefault: font_versions.find(item => item.value.includes('p')).value, value: inputValues['font-version'], onChange: (valueNew) => { updateInputValues('font-version', valueNew); method('font-version')(valueNew); }, onMouseUp: onMouseUp, onMouseDown: onMouseDown }, SelectProps, { className: (0, style_react_1.classNames)([ (0, utils_2.staticClassName)('RichTextEditor', theme) && [ 'amaui-RichTextEditor-select' ], SelectProps === null || SelectProps === void 0 ? void 0 : SelectProps.className, classes.select ]), styl