feat(sw): footer command labels end in an ellipsis with a full-name tooltip
Same 68 x 47 slot and 14px label; without a title the full label is the native tooltip only while it is cut. Accessible name unchanged, no new props.
This commit is contained in:
1 parent
87598ab35e
commit
83c8815445
2 files changed
+16
-5
No files matched your search
@@ -105,15 +105,24 @@ export interface SWFooterToolButtonProps extends Omit<ButtonHTMLAttributes<HTMLB
|
||||
pressed?: boolean
|
||||
}
|
||||
|
||||
/** 68 × 47 command slot (Figma line / Pline / Arc …). Consecutive slots draw the 1px gold divider between them. */
|
||||
/**
|
||||
* 68 × 47 command slot (Figma line / Pline / Arc …). Consecutive slots draw the 1px gold divider between them.
|
||||
* A label longer than the slot ends in … (CSS); without a `title` its full text becomes the native tooltip on hover /
|
||||
* focus, only while it is cut. The accessible name stays the full label (or `aria-label`).
|
||||
*/
|
||||
export const SWFooterToolButton = forwardRef<HTMLButtonElement, SWFooterToolButtonProps>(function SWFooterToolButton(
|
||||
{ label, icon, activeIcon, pressed, className, type = "button", ...rest }, ref,
|
||||
{ label, icon, activeIcon, pressed, className, type = "button", title, onPointerEnter, onFocus, ...rest }, ref,
|
||||
) {
|
||||
const labelRef = useRef<HTMLSpanElement>(null)
|
||||
const [cut, setCut] = useState(false)
|
||||
// Measured when the tooltip could show (not on every render): the label can only be cut by its own text and font.
|
||||
const measure = () => { const node = labelRef.current; setCut(!!node && node.scrollWidth > node.clientWidth) }
|
||||
return (
|
||||
<div className="hm-sw-footer-slot">
|
||||
<button ref={ref} type={type} className={cx("hm-sw-footer-tool", className)} aria-pressed={pressed ?? false}
|
||||
data-active-icon={activeIcon !== undefined ? "" : undefined} {...rest}>
|
||||
<span className="hm-sw-footer-tool__label">{label}</span>
|
||||
data-active-icon={activeIcon !== undefined ? "" : undefined} title={title ?? (cut ? label : undefined)}
|
||||
onPointerEnter={event => { measure(); onPointerEnter?.(event) }} onFocus={event => { measure(); onFocus?.(event) }} {...rest}>
|
||||
<span ref={labelRef} className="hm-sw-footer-tool__label">{label}</span>
|
||||
{icon !== undefined && <span className="hm-sw-footer-tool__icon hm-sw-footer-tool__icon--default" aria-hidden="true">{icon}</span>}
|
||||
{activeIcon !== undefined && <span className="hm-sw-footer-tool__icon hm-sw-footer-tool__icon--active" aria-hidden="true">{activeIcon}</span>}
|
||||
</button>
|
||||
|
||||
@@ -278,7 +278,9 @@
|
||||
overflow: hidden;
|
||||
line-height: 16px;
|
||||
text-align: center;
|
||||
text-overflow: clip;
|
||||
/* A command longer than the slot (POLYGON, WIPEOUT …) ends in … inside the same 64px; the full name stays the
|
||||
accessible name and shows as the tooltip (SWFooterToolButton). Slot, font and centering are unchanged. */
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
text-shadow: var(--hm-sw-header-text-outline);
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user