diff --git a/packages/richtext-lexical/src/features/toolbars/fixed/client/Toolbar/index.tsx b/packages/richtext-lexical/src/features/toolbars/fixed/client/Toolbar/index.tsx index 4300dbdb5..8806fcc0a 100644 --- a/packages/richtext-lexical/src/features/toolbars/fixed/client/Toolbar/index.tsx +++ b/packages/richtext-lexical/src/features/toolbars/fixed/client/Toolbar/index.tsx @@ -110,9 +110,8 @@ function ToolbarGroupComponent({ @@ -111,8 +110,7 @@ function ToolbarGroupComponent({ diff --git a/packages/richtext-lexical/src/features/toolbars/shared/ToolbarButton/index.scss b/packages/richtext-lexical/src/features/toolbars/shared/ToolbarButton/index.scss index 87f323a80..78f06a91a 100644 --- a/packages/richtext-lexical/src/features/toolbars/shared/ToolbarButton/index.scss +++ b/packages/richtext-lexical/src/features/toolbars/shared/ToolbarButton/index.scss @@ -18,7 +18,7 @@ margin-right: 2px; } - &:hover:not([disabled]) { + &:hover:not(.disabled) { background-color: var(--theme-elevation-100); } diff --git a/packages/richtext-lexical/src/features/toolbars/shared/ToolbarDropdown/index.scss b/packages/richtext-lexical/src/features/toolbars/shared/ToolbarDropdown/index.scss index 2cf44af3f..cd60bb842 100644 --- a/packages/richtext-lexical/src/features/toolbars/shared/ToolbarDropdown/index.scss +++ b/packages/richtext-lexical/src/features/toolbars/shared/ToolbarDropdown/index.scss @@ -23,10 +23,7 @@ &:disabled { cursor: not-allowed; - - .icon { - opacity: 0.2; - } + opacity: 0.2; } &:hover:not([disabled]) { diff --git a/packages/richtext-lexical/src/features/toolbars/shared/ToolbarDropdown/index.tsx b/packages/richtext-lexical/src/features/toolbars/shared/ToolbarDropdown/index.tsx index ebb45348e..2ad549f33 100644 --- a/packages/richtext-lexical/src/features/toolbars/shared/ToolbarDropdown/index.tsx +++ b/packages/richtext-lexical/src/features/toolbars/shared/ToolbarDropdown/index.tsx @@ -9,7 +9,7 @@ import { mergeRegister } from '@lexical/utils' import { useTranslation } from '@payloadcms/ui' import { $getSelection } from 'lexical' -import type { ToolbarGroupItem } from '../../types.js' +import type { ToolbarDropdownGroup, ToolbarGroupItem } from '../../types.js' import { useEditorConfigContext } from '../../../../lexical/config/client/EditorConfigProvider.js' import { DropDown, DropDownItem } from './DropDown.js' @@ -70,9 +70,8 @@ export const ToolbarDropdown = ({ anchorElem, classNames, editor, - groupKey, + group, Icon, - items, itemsContainerClassNames, label, maxActiveItems, @@ -81,9 +80,8 @@ export const ToolbarDropdown = ({ anchorElem: HTMLElement classNames?: string[] editor: LexicalEditor - groupKey: string + group: ToolbarDropdownGroup Icon?: React.FC - items: ToolbarGroupItem[] itemsContainerClassNames?: string[] label?: string /** @@ -95,7 +93,9 @@ export const ToolbarDropdown = ({ }) => { const [activeItemKeys, setActiveItemKeys] = React.useState([]) const [enabledItemKeys, setEnabledItemKeys] = React.useState([]) + const [enabledGroup, setEnabledGroup] = React.useState(true) const editorConfigContext = useEditorConfigContext() + const { items, key: groupKey } = group const updateStates = useCallback(() => { editor.getEditorState().read(() => { @@ -125,6 +125,9 @@ export const ToolbarDropdown = ({ _enabledItemKeys.push(item.key) } } + if (group.isEnabled) { + setEnabledGroup(group.isEnabled({ editor, editorConfigContext, selection })) + } setActiveItemKeys(_activeItemKeys) setEnabledItemKeys(_enabledItemKeys) @@ -132,7 +135,7 @@ export const ToolbarDropdown = ({ onActiveChange({ activeItems: _activeItems }) } }) - }, [editor, editorConfigContext, items, maxActiveItems, onActiveChange]) + }, [editor, editorConfigContext, group, items, maxActiveItems, onActiveChange]) useEffect(() => { updateStates() @@ -152,6 +155,7 @@ export const ToolbarDropdown = ({ buttonClassName={[baseClass, `${baseClass}-${groupKey}`, ...(classNames || [])] .filter(Boolean) .join(' ')} + disabled={!enabledGroup} Icon={Icon} itemsContainerClassNames={[`${baseClass}-items`, ...(itemsContainerClassNames || [])]} key={groupKey} diff --git a/packages/richtext-lexical/src/features/toolbars/types.ts b/packages/richtext-lexical/src/features/toolbars/types.ts index 3d48d3f9e..de48cd8c5 100644 --- a/packages/richtext-lexical/src/features/toolbars/types.ts +++ b/packages/richtext-lexical/src/features/toolbars/types.ts @@ -4,47 +4,61 @@ import type React from 'react' import type { EditorConfigContextType } from '../../lexical/config/client/EditorConfigProvider.js' -export type ToolbarGroup = - | { - /** - * All toolbar items part of this toolbar group need to be added here. - */ - items: Array - /** - * Each toolbar group needs to have a unique key. Groups with the same keys will have their items merged together. - */ - key: string - /** - * Determines where the toolbar group will be. - */ - order?: number - /** - * Controls the toolbar group type. Set to `buttons` to create a buttons toolbar group, which displays toolbar items horizontally using only their icons. - */ - type: 'buttons' - } - | { - /** - * The dropdown toolbar ChildComponent allows you to pass in a React Component which will be displayed within the dropdown button. - */ - ChildComponent?: React.FC - /** - * All toolbar items part of this toolbar group need to be added here. - */ - items: Array - /** - * Each toolbar group needs to have a unique key. Groups with the same keys will have their items merged together. - */ - key: string - /** - * Determines where the toolbar group will be. - */ - order?: number - /** - * Controls the toolbar group type. Set to `dropdown` to create a buttons toolbar group, which displays toolbar items vertically using their icons and labels, if the dropdown is open. - */ - type: 'dropdown' - } +export type ToolbarGroup = ToolbarButtonsGroup | ToolbarDropdownGroup + +export type ToolbarDropdownGroup = { + /** + * The dropdown toolbar ChildComponent allows you to pass in a React Component which will be displayed within the dropdown button. + */ + ChildComponent?: React.FC + /** + * This is optional and controls if the toolbar group is highlighted or not. + */ + isEnabled?: ({ + editor, + editorConfigContext, + selection, + }: { + editor: LexicalEditor + editorConfigContext: EditorConfigContextType + selection: BaseSelection + }) => boolean + /** + * All toolbar items part of this toolbar group need to be added here. + */ + items: Array + /** + * Each toolbar group needs to have a unique key. Groups with the same keys will have their items merged together. + */ + key: string + /** + * Determines where the toolbar group will be. + */ + order?: number + /** + * Controls the toolbar group type. Set to `dropdown` to create a buttons toolbar group, which displays toolbar items vertically using their icons and labels, if the dropdown is open. + */ + type: 'dropdown' +} + +export type ToolbarButtonsGroup = { + /** + * All toolbar items part of this toolbar group need to be added here. + */ + items: Array + /** + * Each toolbar group needs to have a unique key. Groups with the same keys will have their items merged together. + */ + key: string + /** + * Determines where the toolbar group will be. + */ + order?: number + /** + * Controls the toolbar group type. Set to `buttons` to create a buttons toolbar group, which displays toolbar items horizontally using only their icons. + */ + type: 'buttons' +} export type ToolbarGroupItem = { /** A React component which is rendered within your toolbar item's default button component. Usually, you want this to be an icon. */