import type { PopoverProps } from '@os-design/core'; import { EditorState, RichUtils } from 'draft-js'; import React, { useCallback, useMemo } from 'react'; import Toolbar from './Toolbar.js'; import ToolbarButton from './ToolbarButton.js'; import type { StyleToolbarItem } from './utils/defaultStyleToolbarItems.js'; import setLink from './utils/setLink.js'; import unsetLink from './utils/unsetLink.js'; interface StyleToolbarProps extends Omit { items: StyleToolbarItem[]; value: EditorState; onChange: (value: EditorState) => void; } const StyleToolbar: React.FC = ({ items, value, onChange = () => {}, ...rest }) => { const currentBlockType = useMemo( () => RichUtils.getCurrentBlockType(value), [value] ); const currentBlockContainsLink = useMemo( () => RichUtils.currentBlockContainsLink(value), [value] ); const toggleLink = useCallback(() => { if (currentBlockContainsLink) { onChange(unsetLink(value)); return; } const url = prompt('Paste or type a link'); if (!url) return; onChange(setLink(value, url)); }, [currentBlockContainsLink, value, onChange]); const clickHandler = useCallback<(item: StyleToolbarItem) => void>( (item) => { if (item.type === 'inline') { onChange(RichUtils.toggleInlineStyle(value, item.name)); } else if (item.type === 'block') { onChange(RichUtils.toggleBlockType(value, item.name)); } }, [value, onChange] ); if (items.length === 0) return null; return ( {items.map((item) => { const isLink = item.name === 'LINK' && item.type === 'inline'; const active = isLink ? currentBlockContainsLink : value.getCurrentInlineStyle().has(item.name) || currentBlockType === item.name; const onClick = isLink ? toggleLink : () => clickHandler(item); return ( {item.icon} ); })} ); }; StyleToolbar.displayName = 'StyleToolbar'; export default StyleToolbar;