import * as React from 'react'; import { Box, Card, ToggleButton, ToggleButtonGroup, ToggleButtonProps, useTheme, } from '@mui/material'; import FormatColorTextIcon from '@mui/icons-material/FormatColorText'; import FontDownloadIcon from '@mui/icons-material/FontDownload'; import { useTranslate } from 'ra-core'; import { useTiptapEditor } from '../useTiptapEditor'; import { grey, red, orange, yellow, green, blue, purple, } from '@mui/material/colors'; const FONT = 'font'; const BACKGROUND = 'background'; type ColorType = typeof FONT | typeof BACKGROUND; export const ColorButtons = (props: Omit) => { const translate = useTranslate(); const editor = useTiptapEditor(); const [showColorChoiceDialog, setShowColorChoiceDialog] = React.useState(false); const [colorType, setColorType] = React.useState(FONT); const colorLabel = translate('ra.tiptap.color', { _: 'Color' }); const highlightLabel = translate('ra.tiptap.highlight', { _: 'Highlight' }); const displayColorChoiceDialog = (colorType: ColorType) => { setShowColorChoiceDialog(true); setColorType(colorType); }; return ( setShowColorChoiceDialog(false)}> displayColorChoiceDialog(FONT)} > displayColorChoiceDialog(BACKGROUND)} > {showColorChoiceDialog && ( setShowColorChoiceDialog(false)} colorType={colorType} /> )} ); }; interface ColorChoiceDialogProps { editor: any; close: () => void; colorType: ColorType; } const ColorChoiceDialog = ({ editor, close, colorType, }: ColorChoiceDialogProps) => { const theme = useTheme(); const colors = [grey, red, orange, yellow, green, blue, purple]; const shades = [900, 700, 500, 300, 100]; const selectColor = (color: string) => { if (colorType === FONT) { editor.chain().focus().setColor(color).run(); } else { editor.chain().focus().toggleHighlight({ color }).run(); } close(); }; return ( {shades.map((shade, line) => ( {colors.map((color, row) => ( selectColor(color[shade])} > ))} ))} ); }; type OutsideListenerProps = { className?: string; onClick: () => void; children: React.ReactNode; }; /** * Component that listens if you click outside of it */ const OutsideListener = ({ className, onClick, children, }: OutsideListenerProps) => { const wrapperRef = React.useRef(null); useOutsideListener(wrapperRef, onClick); return (
{children}
); }; /** * Hook that listens clicks outside of the passed ref */ const useOutsideListener = ( ref: React.MutableRefObject, onClick: () => void ) => { React.useEffect(() => { const handleClickOutside = (event: MouseEvent) => { if (ref.current && !ref.current.contains(event.target)) { onClick(); } }; // Bind the event listener document.addEventListener('mousedown', handleClickOutside); return () => { // Unbind the event listener on clean up document.removeEventListener('mousedown', handleClickOutside); }; }, [ref, onClick]); };