feat(richtext-lexical): add tooltips to toolbar dropdown items (#9218)
Previously, if the dropdown item text is cut off due to length, there was no way to view the full text. Now, you can hover: 
This commit is contained in:
@@ -40,7 +40,7 @@ function ButtonGroupItem({
|
||||
|
||||
return (
|
||||
<ToolbarButton editor={editor} item={item} key={item.key}>
|
||||
{<item.ChildComponent />}
|
||||
<item.ChildComponent />
|
||||
</ToolbarButton>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
'use client'
|
||||
import type { LexicalEditor } from 'lexical'
|
||||
|
||||
import { Button } from '@payloadcms/ui'
|
||||
import React, { type ReactNode, useCallback, useEffect, useMemo, useRef, useState } from 'react'
|
||||
import { createPortal } from 'react-dom'
|
||||
|
||||
@@ -19,15 +20,17 @@ export function DropDownItem({
|
||||
children,
|
||||
editor,
|
||||
enabled,
|
||||
Icon,
|
||||
item,
|
||||
title,
|
||||
tooltip,
|
||||
}: {
|
||||
active?: boolean
|
||||
children: React.ReactNode
|
||||
editor: LexicalEditor
|
||||
enabled?: boolean
|
||||
Icon: React.ReactNode
|
||||
item: ToolbarGroupItem
|
||||
title?: string
|
||||
tooltip?: string
|
||||
}): React.ReactNode {
|
||||
const [className, setClassName] = useState<string>(baseClass)
|
||||
|
||||
@@ -61,8 +64,14 @@ export function DropDownItem({
|
||||
}, [ref, registerItem])
|
||||
|
||||
return (
|
||||
<button
|
||||
<Button
|
||||
aria-label={tooltip}
|
||||
buttonStyle="none"
|
||||
className={className}
|
||||
disabled={enabled === false}
|
||||
icon={Icon}
|
||||
iconPosition="left"
|
||||
iconStyle="none"
|
||||
onClick={() => {
|
||||
if (enabled !== false) {
|
||||
editor._updateTags = new Set(['toolbar', ...editor._updateTags]) // without setting the tags, our onSelect will not be able to trigger our onChange as focus onChanges are ignored.
|
||||
@@ -82,11 +91,11 @@ export function DropDownItem({
|
||||
e.preventDefault()
|
||||
}}
|
||||
ref={ref}
|
||||
title={title}
|
||||
tooltip={tooltip}
|
||||
type="button"
|
||||
>
|
||||
{children}
|
||||
</button>
|
||||
</Button>
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -75,6 +75,7 @@
|
||||
cursor: pointer;
|
||||
color: var(--theme-elevation-900);
|
||||
transition: background-color 0.15s cubic-bezier(0, 0.2, 0.2, 1);
|
||||
position: relative;
|
||||
|
||||
.text {
|
||||
overflow: hidden;
|
||||
@@ -91,6 +92,13 @@
|
||||
opacity: 0.2;
|
||||
}
|
||||
|
||||
.btn__icon {
|
||||
// Override default button icon styles that
|
||||
// set a background color when focused
|
||||
background: none !important;
|
||||
background-color: none !important;
|
||||
}
|
||||
|
||||
padding-left: 6.25px;
|
||||
padding-right: 6.25px;
|
||||
width: 100%;
|
||||
|
||||
@@ -49,6 +49,7 @@ const ToolbarItem = ({
|
||||
}
|
||||
|
||||
let title = item.key
|
||||
let croppedTitle = item.key
|
||||
if (item.label) {
|
||||
title =
|
||||
typeof item.label === 'function'
|
||||
@@ -57,13 +58,22 @@ const ToolbarItem = ({
|
||||
}
|
||||
// Crop title to max. 25 characters
|
||||
if (title.length > 25) {
|
||||
title = title.substring(0, 25) + '...'
|
||||
croppedTitle = title.substring(0, 25) + '...'
|
||||
} else {
|
||||
croppedTitle = title
|
||||
}
|
||||
|
||||
return (
|
||||
<DropDownItem active={active} editor={editor} enabled={enabled} item={item} key={item.key}>
|
||||
{item?.ChildComponent && <item.ChildComponent />}
|
||||
<span className="text">{title}</span>
|
||||
<DropDownItem
|
||||
active={active}
|
||||
editor={editor}
|
||||
enabled={enabled}
|
||||
Icon={item?.ChildComponent ? <item.ChildComponent /> : undefined}
|
||||
item={item}
|
||||
key={item.key}
|
||||
tooltip={title}
|
||||
>
|
||||
<span className="text">{croppedTitle}</span>
|
||||
</DropDownItem>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -63,6 +63,7 @@ export const Button = forwardRef<HTMLAnchorElement | HTMLButtonElement, Props>((
|
||||
Link,
|
||||
newTab,
|
||||
onClick,
|
||||
onMouseDown,
|
||||
round,
|
||||
size = 'medium',
|
||||
SubMenuPopupContent,
|
||||
@@ -114,6 +115,7 @@ export const Button = forwardRef<HTMLAnchorElement | HTMLButtonElement, Props>((
|
||||
className: !SubMenuPopupContent ? [classes, styleClasses].join(' ') : classes,
|
||||
disabled,
|
||||
onClick: !disabled ? handleClick : undefined,
|
||||
onMouseDown: !disabled ? onMouseDown : undefined,
|
||||
onPointerEnter: tooltip ? () => setShowTooltip(true) : undefined,
|
||||
onPointerLeave: tooltip ? () => setShowTooltip(false) : undefined,
|
||||
rel: newTab ? 'noopener noreferrer' : undefined,
|
||||
|
||||
@@ -20,6 +20,7 @@ export type Props = {
|
||||
Link?: React.ElementType
|
||||
newTab?: boolean
|
||||
onClick?: (event: MouseEvent) => void
|
||||
onMouseDown?: (event: MouseEvent) => void
|
||||
round?: boolean
|
||||
secondaryActions?: secondaryAction | secondaryAction[]
|
||||
size?: 'large' | 'medium' | 'small'
|
||||
|
||||
Reference in New Issue
Block a user