import './style.css'; import classnames from 'classnames'; import React, { useState } from 'react'; import { IconButton, Icons, ITooltipProps, ListItem, Tooltip } from '../../../../component'; import { ToolDisplay } from '../../utils'; import { IProp } from '../index'; const noop = () => {}; const getConfigVal = (val: Array) => { let res; val.some(t => { if (t) { res = t; return true; } else if (t === false) { res = false; return true; } return false; }); return res; }; interface IToolbarVerticalButtonExtraProps { buttonProps?: Partial, HTMLButtonElement>>; } interface IToolbarHorizonButtonExtraProps { buttonProps?: Partial, HTMLLIElement>>; } interface IButtonForToolbarProps extends IProp { getRef?: (node: HTMLElement | null) => any; className?: string; tooltipProps?: Partial; buttonProps?: any; } interface IButtonProps extends IButtonForToolbarProps { disable: boolean; icon: any; tooltipVisible: boolean; } // Vertical buttons are usually displayed directly on the toolbar const renderVertical = ({ name, disable, active, tooltip: propTooltip, handler, editor, icon, tipDirection, tipDistance, tooltipVisible, className = '', buttonProps = {}, tooltipProps = {}, toolbarType, getRef, }: IButtonProps & IToolbarVerticalButtonExtraProps) => { let tooltip = propTooltip; const renderContent = () => { const content = ( { if (disable) return; handler(editor, name, !active); }} {...buttonProps} > {icon} ); if (tooltipVisible && tooltip) { if (typeof tooltip === 'function') { const tipNode = tooltip(content); if (typeof tipNode === 'string' && tipNode) { tooltip = tipNode; } else { return tipNode; } } return ( {content} ); } return content; }; return (
{renderContent()}
); }; // Horizon buttons are usually displayed in the dropdown menu of the toolbar const renderHorizon = ({ name, disable, active, tooltip: propTooltip, handler, editor, icon, tipDirection, tipDistance, tooltipVisible, showName, className = '', toolbarType = 'static', buttonProps, getRef, }: IButtonProps & IToolbarHorizonButtonExtraProps) => { let tooltip = propTooltip; if (toolbarType === 'static' && typeof tooltip !== 'function' && showName === tooltip) { tooltip = ''; } const renderContent = () => { const content = ( <> {icon} {showName !== false && {showName || tooltip}} ); if (tooltipVisible && tooltip) { if (typeof tooltip === 'function') { const tipNode = tooltip(content); if (typeof tipNode === 'string' && tipNode) { if (tipNode === showName) return content; tooltip = tipNode; } else { return tipNode; } } return ( {content} ); } return content; }; return ( { if (disable) return; handler(editor, name, !active); }} key={name} listRef={getRef} {...buttonProps} > {renderContent()} ); }; const ButtonForToolbar = (props: IButtonForToolbarProps) => { const { name, attrs, toolbar, active, showName: configShowName, tooltip: configTooltip, editor, display, toolbarType = 'static', } = props; const { disable = noop, active: activeHandler = noop, tooltip: defaultTooltip, showName: defaultShowName, buttonProps = {}, tooltipProps = {}, getRef = noop, } = toolbar; const [tooltipVisible, setTooltipVisible] = useState(true); const locale = editor.configurator.getLocaleValue(name); const tooltip = getConfigVal([configTooltip, locale.tooltip, defaultTooltip, name]); const showName = getConfigVal([configShowName, locale.showName, defaultShowName, tooltip]); const isDisable = disable(editor); const isActive = activeHandler(editor) || active; let icon = toolbar.icon || Icons[name as keyof typeof Icons]; if (typeof icon === 'function') { // TODO: animation is difficult to achieve while using function icon = icon(editor, attrs, { setTooltipVisible, display, tooltip, toolbarType, }); } const generalProps = { buttonProps, tooltipProps, getRef, ...props, disable: isDisable, active: isActive, tooltip, icon, showName, toolbarType, tooltipVisible, }; return props.display === ToolDisplay.VERTICAL ? renderVertical(generalProps) : renderHorizon(generalProps); }; export { ButtonForToolbar, getConfigVal };