Shut it, then open it again
Gooey Plus Menu
A square plus whose actions bud out of it one after another, joined by a gooey neck until they part.
Usage
import { GooeyMenu } from '@wdzyi/ui';
<GooeyMenu
label='Add'
direction='right'
items={[
{ label: 'Photo', icon: <PhotoIcon />, onSelect: addPhoto },
{ label: 'File', icon: <FileIcon />, onSelect: addFile },
{ label: 'Link', icon: <LinkIcon />, onSelect: addLink },
]}
/>Part of @wdzyi/ui. See setup to install it, or copy the code above.
Props
- itemsGooeyMenuItem[]
- Each has a label, a 16px icon and an onSelect.
- labelstring = 'Add'
- Names the button and its menu for screen readers.
- direction'up' | 'down' | 'left' | 'right' = 'up'
- Which way the actions go from the button.
- side'start' | 'end' = 'end'
- Which side of the line of actions the words sit on: after it, which is to the right or below, or before it.
- onSelect(item: GooeyMenuItem) => void
- Called with the action that was picked, after its own onSelect.
- open, onOpenChangeboolean, (open: boolean) => void
- To open and shut it yourself. Opened this way, it leaves focus where it is.
- classNamestring
- Added to its root.
Notes
- The squares underneath are blurred by 6px, then kept only where they’re dense enough to be ink, so two that are close run together. The squares themselves go back on top, so at rest they’re square, 12px apart, and the goo only shows as they part. The icons and words are never filtered.
- Each action nests in the one before it, so opening, the first buds out of the button and each of the rest out of the far side of the last, 60ms apart, growing from half size over 520ms on a spring. Each icon comes 160ms after its square sets off, and each word 260ms after. Shutting draws them back in over 300ms, the furthest first, 30ms apart, and the plus turns an eighth to a cross and back.
- The arrows along the line of actions move between them, Home and End go to either end, Enter picks one, and Escape shuts it and hands focus back to the button. A press elsewhere shuts it, though a touch that turns into a scroll doesn’t.
- It sits in the page rather than floating over it: the actions reach 52px a piece past the button, so leave that much room on their side.
- With reduced motion, the actions fade in and out in their places, with no goo and no travel.