From f6bfe9e8689b4765cb293ce72c3326f52ce23051 Mon Sep 17 00:00:00 2001 From: Aman Harwara Date: Wed, 25 Oct 2023 11:14:34 +0530 Subject: [PATCH] chore: consolidate super toolbar items and remove need for scroll [skip e2e] --- packages/icons/src/Icons/ic-list-check.svg | 3 + packages/icons/src/Icons/index.ts | 2 + .../Components/Icon/IconNameToSvgMapping.tsx | 1 + .../src/javascripts/Components/Menu/Menu.tsx | 11 +- .../javascripts/Components/Menu/MenuItem.tsx | 4 +- .../SuperEditor/Plugins/Blocks/List.tsx | 2 +- .../Plugins/CodeOptionsPlugin/CodeOptions.tsx | 2 +- .../Plugins/SearchPlugin/SearchDialog.tsx | 2 +- .../Plugins/ToolbarPlugin/ToolbarPlugin.tsx | 468 ++++++++++++------ 9 files changed, 329 insertions(+), 166 deletions(-) create mode 100644 packages/icons/src/Icons/ic-list-check.svg diff --git a/packages/icons/src/Icons/ic-list-check.svg b/packages/icons/src/Icons/ic-list-check.svg new file mode 100644 index 000000000..019e1d35b --- /dev/null +++ b/packages/icons/src/Icons/ic-list-check.svg @@ -0,0 +1,3 @@ + + + diff --git a/packages/icons/src/Icons/index.ts b/packages/icons/src/Icons/index.ts index f8c78a9d5..2820c656a 100644 --- a/packages/icons/src/Icons/index.ts +++ b/packages/icons/src/Icons/index.ts @@ -35,6 +35,7 @@ import CheckBoldIcon from './ic-check-bold.svg' import CheckCircleFilledIcon from './ic-check-circle-filled.svg' import CheckCircleIcon from './ic-check-circle.svg' import CheckIcon from './ic-check.svg' +import CheckListIcon from './ic-list-check.svg' import ChevronDownIcon from './ic-chevron-down.svg' import ChevronLeftIcon from './ic-chevron-left.svg' import ChevronRightIcon from './ic-chevron-right.svg' @@ -254,6 +255,7 @@ export { CheckCircleFilledIcon, CheckCircleIcon, CheckIcon, + CheckListIcon, ChevronDownIcon, ChevronLeftIcon, ChevronRightIcon, diff --git a/packages/web/src/javascripts/Components/Icon/IconNameToSvgMapping.tsx b/packages/web/src/javascripts/Components/Icon/IconNameToSvgMapping.tsx index 48d602d27..b055e4aae 100644 --- a/packages/web/src/javascripts/Components/Icon/IconNameToSvgMapping.tsx +++ b/packages/web/src/javascripts/Components/Icon/IconNameToSvgMapping.tsx @@ -49,6 +49,7 @@ export const IconNameToSvgMapping = { 'link-off': icons.LinkOffIcon, 'list-bulleted': icons.ListBulleted, 'list-numbered': icons.ListNumbered, + 'list-check': icons.CheckListIcon, 'lock-filled': icons.LockFilledIcon, 'menu-arrow-down-alt': icons.MenuArrowDownAlt, 'menu-arrow-down': icons.MenuArrowDownIcon, diff --git a/packages/web/src/javascripts/Components/Menu/Menu.tsx b/packages/web/src/javascripts/Components/Menu/Menu.tsx index 86a1e2c0d..4fe1f1777 100644 --- a/packages/web/src/javascripts/Components/Menu/Menu.tsx +++ b/packages/web/src/javascripts/Components/Menu/Menu.tsx @@ -1,8 +1,7 @@ import { - CSSProperties, + ComponentPropsWithoutRef, forwardRef, KeyboardEventHandler, - ReactNode, useCallback, useImperativeHandle, useRef, @@ -12,15 +11,11 @@ import { useListKeyboardNavigation } from '@/Hooks/useListKeyboardNavigation' import { mergeRefs } from '@/Hooks/mergeRefs' import { MutuallyExclusiveMediaQueryBreakpoints, useMediaQuery } from '@/Hooks/useMediaQuery' -type MenuProps = { - className?: string - style?: CSSProperties | undefined +interface MenuProps extends ComponentPropsWithoutRef<'menu'> { a11yLabel: string - children: ReactNode closeMenu?: () => void isOpen: boolean initialFocus?: number - onKeyDown?: KeyboardEventHandler shouldAutoFocus?: boolean } @@ -35,6 +30,7 @@ const Menu = forwardRef( initialFocus, onKeyDown, shouldAutoFocus = true, + ...props }: MenuProps, forwardedRef, ) => { @@ -73,6 +69,7 @@ const Menu = forwardRef( ref={mergeRefs([menuElementRef, forwardedRef])} style={style} aria-label={a11yLabel} + {...props} > {children} diff --git a/packages/web/src/javascripts/Components/Menu/MenuItem.tsx b/packages/web/src/javascripts/Components/Menu/MenuItem.tsx index a38fe471d..dd1056934 100644 --- a/packages/web/src/javascripts/Components/Menu/MenuItem.tsx +++ b/packages/web/src/javascripts/Components/Menu/MenuItem.tsx @@ -7,7 +7,7 @@ import { PlatformedKeyboardShortcut } from '@standardnotes/ui-services' import { KeyboardShortcutIndicator } from '../KeyboardShortcutIndicator/KeyboardShortcutIndicator' import MenuListItem from './MenuListItem' -type MenuItemProps = { +export interface MenuItemProps extends ComponentPropsWithoutRef<'button'> { children: ReactNode onClick?: MouseEventHandler onBlur?: (event: { relatedTarget: EventTarget | null }) => void @@ -17,7 +17,7 @@ type MenuItemProps = { tabIndex?: number disabled?: boolean shortcut?: PlatformedKeyboardShortcut -} & ComponentPropsWithoutRef<'button'> +} const MenuItem = forwardRef( ( diff --git a/packages/web/src/javascripts/Components/SuperEditor/Plugins/Blocks/List.tsx b/packages/web/src/javascripts/Components/SuperEditor/Plugins/Blocks/List.tsx index 86f6c347e..391d08c1a 100644 --- a/packages/web/src/javascripts/Components/SuperEditor/Plugins/Blocks/List.tsx +++ b/packages/web/src/javascripts/Components/SuperEditor/Plugins/Blocks/List.tsx @@ -12,7 +12,7 @@ export const BulletedListBlock = { export const ChecklistBlock = { name: 'Check List', - iconName: 'check' as LexicalIconName, + iconName: 'list-check' as LexicalIconName, keywords: ['check list', 'todo list'], onSelect: (editor: LexicalEditor) => editor.dispatchCommand(INSERT_CHECK_LIST_COMMAND, undefined), } diff --git a/packages/web/src/javascripts/Components/SuperEditor/Plugins/CodeOptionsPlugin/CodeOptions.tsx b/packages/web/src/javascripts/Components/SuperEditor/Plugins/CodeOptionsPlugin/CodeOptions.tsx index b2c79eb77..d36b19bab 100644 --- a/packages/web/src/javascripts/Components/SuperEditor/Plugins/CodeOptionsPlugin/CodeOptions.tsx +++ b/packages/web/src/javascripts/Components/SuperEditor/Plugins/CodeOptionsPlugin/CodeOptions.tsx @@ -93,7 +93,7 @@ const CodeOptionsPlugin = () => { return ( <> -
+
({ diff --git a/packages/web/src/javascripts/Components/SuperEditor/Plugins/SearchPlugin/SearchDialog.tsx b/packages/web/src/javascripts/Components/SuperEditor/Plugins/SearchPlugin/SearchDialog.tsx index 43ad24084..d1bc86c1b 100644 --- a/packages/web/src/javascripts/Components/SuperEditor/Plugins/SearchPlugin/SearchDialog.tsx +++ b/packages/web/src/javascripts/Components/SuperEditor/Plugins/SearchPlugin/SearchDialog.tsx @@ -53,7 +53,7 @@ export const SearchDialog = ({ open, closeDialog }: { open: boolean; closeDialog return (
@@ -117,6 +147,24 @@ const ToolbarButton = forwardRef( }, ) +interface ToolbarMenuItemProps extends Omit { + name: string + iconName: string + active?: boolean +} + +const ToolbarMenuItem = ({ name, iconName, active, ...props }: ToolbarMenuItemProps) => { + return ( + + + {name} + + ) +} + const ToolbarPlugin = () => { const application = useApplication() const isMobile = useMediaQuery(MutuallyExclusiveMediaQueryBreakpoints.sm) @@ -149,6 +197,18 @@ const ToolbarPlugin = () => { const [isTOCOpen, setIsTOCOpen] = useState(false) const tocAnchorRef = useRef(null) + const [isTextFormatMenuOpen, setIsTextFormatMenuOpen] = useState(false) + const textFormatAnchorRef = useRef(null) + + const [isTextStyleMenuOpen, setIsTextStyleMenuOpen] = useState(false) + const textStyleAnchorRef = useRef(null) + + const [isAlignmentMenuOpen, setIsAlignmentMenuOpen] = useState(false) + const alignmentAnchorRef = useRef(null) + + const [isInsertMenuOpen, setIsInsertMenuOpen] = useState(false) + const insertAnchorRef = useRef(null) + const [canUndo, setCanUndo] = useState(false) const [canRedo, setCanRedo] = useState(false) @@ -400,7 +460,7 @@ const ToolbarPlugin = () => {
{ )}
@@ -431,6 +491,11 @@ const ToolbarPlugin = () => { onSelect={() => setIsTOCOpen(!isTOCOpen)} ref={tocAnchorRef} /> + application.keyboardService.triggerCommand(SUPER_TOGGLE_SEARCH)} + /> { active={isUnderline} onSelect={() => editor.dispatchCommand(FORMAT_TEXT_COMMAND, 'underline')} /> - editor.dispatchCommand(FORMAT_TEXT_COMMAND, 'highlight')} - /> { editor.dispatchCommand(TOGGLE_LINK_AND_EDIT_COMMAND, '') }} /> - editor.dispatchCommand(FORMAT_TEXT_COMMAND, 'strikethrough')} - /> - editor.dispatchCommand(FORMAT_TEXT_COMMAND, 'subscript')} - /> - editor.dispatchCommand(FORMAT_TEXT_COMMAND, 'superscript')} - /> { onSelect={() => editor.dispatchCommand(FORMAT_TEXT_COMMAND, 'code')} /> application.keyboardService.triggerCommand(SUPER_TOGGLE_SEARCH)} - /> + name="Formatting options" + onSelect={() => { + setIsTextFormatMenuOpen(!isTextFormatMenuOpen) + }} + ref={textFormatAnchorRef} + > + + + ParagraphBlock.onSelect(editor)} - /> + name="Text style" + onSelect={() => { + setIsTextStyleMenuOpen(!isTextStyleMenuOpen) + }} + ref={textStyleAnchorRef} + > + + + H1Block.onSelect(editor)} - /> + name="Alignment" + onSelect={() => { + setIsAlignmentMenuOpen(!isAlignmentMenuOpen) + }} + ref={alignmentAnchorRef} + > + + + H2Block.onSelect(editor)} - /> - H3Block.onSelect(editor)} - /> - IndentBlock.onSelect(editor)} - /> - OutdentBlock.onSelect(editor)} - /> - LeftAlignBlock.onSelect(editor)} - /> - CenterAlignBlock.onSelect(editor)} - /> - RightAlignBlock.onSelect(editor)} - /> - JustifyAlignBlock.onSelect(editor)} - /> - BulletedListBlock.onSelect(editor)} - /> - NumberedListBlock.onSelect(editor)} - /> - ChecklistBlock.onSelect(editor)} - /> - - showModal('Insert Table', (onClose) => ) - } - /> - - showModal('Insert image from URL', (onClose) => ) - } - /> - CodeBlock.onSelect(editor)} - /> - QuoteBlock.onSelect(editor)} - /> - DividerBlock.onSelect(editor)} - /> - CollapsibleBlock.onSelect(editor)} - /> - PasswordBlock.onSelect(editor)} - /> + name="Insert" + onSelect={() => { + setIsInsertMenuOpen(!isInsertMenuOpen) + }} + ref={insertAnchorRef} + > + + + {isMobile && (