import FocusTrap from 'focus-trap-react'; import { Badge, Box, config, Icon, IconButton, Icons, IconSrc, Line, Menu, PopOut, Scroll, Text, Tooltip, TooltipProvider, toRem, } from 'folds'; import React, { ReactNode, useState } from 'react'; import { ReactEditor, useSlate } from 'slate-react'; import { isAnyMarkActive, isBlockActive, isMarkActive, removeAllMark, toggleBlock, toggleMark, } from './common'; import * as css from './Editor.css'; import { BlockType, MarkType } from './Elements'; import { HeadingLevel } from './slate'; import { isMacOS } from '../../utils/user-agent'; import { KeySymbol } from '../../utils/key-symbol'; function BtnTooltip({ text, shortCode }: { text: string; shortCode?: string }) { return ( {text} {shortCode && ( {shortCode} )} ); } type MarkButtonProps = { format: MarkType; icon: IconSrc; tooltip: ReactNode }; export function MarkButton({ format, icon, tooltip }: MarkButtonProps) { const editor = useSlate(); const disableInline = isBlockActive(editor, BlockType.CodeBlock); if (disableInline) { removeAllMark(editor); } const handleClick = () => { toggleMark(editor, format); ReactEditor.focus(editor); }; return ( {(triggerRef) => ( )} ); } type BlockButtonProps = { format: BlockType; icon: IconSrc; tooltip: ReactNode; }; export function BlockButton({ format, icon, tooltip }: BlockButtonProps) { const editor = useSlate(); const handleClick = () => { toggleBlock(editor, format, { level: 1 }); ReactEditor.focus(editor); }; return ( {(triggerRef) => ( )} ); } export function HeadingBlockButton() { const editor = useSlate(); const [level, setLevel] = useState(1); const [open, setOpen] = useState(false); const isActive = isBlockActive(editor, BlockType.Heading); const handleMenuSelect = (selectedLevel: HeadingLevel) => { setOpen(false); setLevel(selectedLevel); toggleBlock(editor, BlockType.Heading, { level: selectedLevel }); ReactEditor.focus(editor); }; return ( setOpen(false), clickOutsideDeactivates: true, isKeyForward: (evt: KeyboardEvent) => evt.key === 'ArrowDown' || evt.key === 'ArrowRight', isKeyBackward: (evt: KeyboardEvent) => evt.key === 'ArrowUp' || evt.key === 'ArrowLeft', }} > handleMenuSelect(1)} size="400" radii="300"> handleMenuSelect(2)} size="400" radii="300"> handleMenuSelect(3)} size="400" radii="300"> } > {(ref) => ( (isActive ? toggleBlock(editor, BlockType.Heading) : setOpen(!open))} aria-pressed={isActive} size="400" radii="300" > )} ); } type ExitFormattingProps = { tooltip: ReactNode }; export function ExitFormatting({ tooltip }: ExitFormattingProps) { const editor = useSlate(); const handleClick = () => { if (isAnyMarkActive(editor)) { removeAllMark(editor); } else if (!isBlockActive(editor, BlockType.Paragraph)) { toggleBlock(editor, BlockType.Paragraph); } ReactEditor.focus(editor); }; return ( {(triggerRef) => ( {`Exit ${KeySymbol.Hyper}`} )} ); } export function Toolbar() { const editor = useSlate(); const modKey = isMacOS() ? KeySymbol.Command : 'Ctrl'; const canEscape = isAnyMarkActive(editor) || !isBlockActive(editor, BlockType.Paragraph); return ( <> } /> } /> } /> } /> } /> } /> } /> } /> } /> } /> {canEscape && ( <> } /> )} ); }