Toolbar rewrite: (mostly) fixed content, separate config, rich tooltips, and roadmapped tools (#3119)
* Basic implementation of rich tooltips * Break out config to its own file, add a bunch of items * Better lower right control tooltip sizing * Add a bunch of sketch tools to the config * Fix hotkey collisions and UX polish * Get tests working again * A snapshot a day keeps the bugs away! 📷🐛 (OS: ubuntu) * Re-run CI * A snapshot a day keeps the bugs away! 📷🐛 (OS: ubuntu) * We updated how the sidebar buttons' test IDs are generated, fix it post-merge * fmt * A snapshot a day keeps the bugs away! 📷🐛 (OS: ubuntu) * Re-run CI * A snapshot a day keeps the bugs away! 📷🐛 (OS: ubuntu) * Re-run CI * A snapshot a day keeps the bugs away! 📷🐛 (OS: ubuntu) * Re-run CI --------- Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
This commit is contained in:
@ -1,56 +1,93 @@
|
||||
import { Popover } from '@headlessui/react'
|
||||
import { ActionButton, ActionButtonProps } from './ActionButton'
|
||||
import { ActionButtonProps } from './ActionButton'
|
||||
import { CustomIcon } from './CustomIcon'
|
||||
|
||||
type ActionButtonSplitProps = Omit<ActionButtonProps, 'iconEnd'> & {
|
||||
type ActionButtonSplitProps = ActionButtonProps & { Element: 'button' } & {
|
||||
name?: string
|
||||
splitMenuItems: {
|
||||
id: string
|
||||
label: string
|
||||
shortcut?: string
|
||||
onClick: () => void
|
||||
disabled?: boolean
|
||||
status?: 'available' | 'unavailable' | 'kcl-only'
|
||||
}[]
|
||||
}
|
||||
|
||||
export function ActionButtonDropdown({
|
||||
splitMenuItems,
|
||||
className,
|
||||
children,
|
||||
...props
|
||||
}: ActionButtonSplitProps) {
|
||||
const baseClassNames = `action-button p-0 m-0 group mono text-xs leading-none flex items-center gap-2 rounded-sm border-solid border border-chalkboard-30 hover:border-chalkboard-40 enabled:dark:border-chalkboard-70 dark:hover:border-chalkboard-60 dark:bg-chalkboard-90/50 text-chalkboard-100 dark:text-chalkboard-10`
|
||||
return (
|
||||
<Popover className="relative">
|
||||
<Popover.Button
|
||||
as={ActionButton}
|
||||
className={className}
|
||||
{...props}
|
||||
Element="button"
|
||||
iconEnd={{
|
||||
icon: 'caretDown',
|
||||
className: 'ui-open:rotate-180',
|
||||
bgClassName:
|
||||
'bg-chalkboard-20 dark:bg-chalkboard-80 ui-open:bg-primary ui-open:text-chalkboard-10',
|
||||
}}
|
||||
/>
|
||||
<Popover.Panel
|
||||
as="ul"
|
||||
className="absolute z-20 left-1/2 -translate-x-1/2 top-full mt-1 w-fit max-h-[80vh] overflow-y-auto py-2 flex flex-col gap-1 align-stretch text-inherit dark:text-chalkboard-10 bg-chalkboard-10 dark:bg-chalkboard-100 rounded shadow-lg border border-solid border-chalkboard-30 dark:border-chalkboard-80 text-sm m-0 p-0"
|
||||
>
|
||||
{splitMenuItems.map((item) => (
|
||||
<li className="contents" key={item.label}>
|
||||
<button
|
||||
onClick={item.onClick}
|
||||
className="block px-3 py-1 hover:bg-primary/10 dark:hover:bg-chalkboard-80 border-0 m-0 text-sm w-full rounded-none text-left disabled:!bg-transparent dark:disabled:text-chalkboard-60"
|
||||
disabled={item.disabled}
|
||||
data-testid={item.label}
|
||||
>
|
||||
<span className="capitalize">{item.label}</span>
|
||||
{item.shortcut && (
|
||||
<kbd className="bg-primary/10 dark:bg-chalkboard-80 dark:group-hover:bg-primary font-mono rounded-sm dark:text-inherit inline-block px-1 border-primary dark:border-chalkboard-90">
|
||||
{item.shortcut}
|
||||
</kbd>
|
||||
)}
|
||||
</button>
|
||||
</li>
|
||||
))}
|
||||
</Popover.Panel>
|
||||
<Popover className={`${baseClassNames} ${className}`}>
|
||||
{({ close }) => (
|
||||
<>
|
||||
{children}
|
||||
<Popover.Button className="border-transparent dark:border-transparent p-0 m-0 rounded-none !outline-none ui-open:border-primary ui-open:bg-primary">
|
||||
<CustomIcon
|
||||
name="caretDown"
|
||||
className={
|
||||
'w-3.5 h-5 text-chalkboard-70 dark:text-chalkboard-40 rounded-none ' +
|
||||
'ui-open:rotate-180 ui-open:!text-chalkboard-10'
|
||||
}
|
||||
/>
|
||||
<span className="sr-only">
|
||||
{props.name ? props.name + ': ' : ''}open menu
|
||||
</span>
|
||||
</Popover.Button>
|
||||
<Popover.Panel
|
||||
as="ul"
|
||||
className="!pointer-events-auto absolute z-20 left-1/2 -translate-x-1/2 top-full mt-4 w-fit max-w-[280px] max-h-[80vh] overflow-y-auto py-2 flex flex-col align-stretch text-inherit dark:text-chalkboard-10 bg-chalkboard-10 dark:bg-chalkboard-100 rounded shadow-lg border border-solid border-chalkboard-30 dark:border-chalkboard-80 text-sm m-0 p-0"
|
||||
>
|
||||
{splitMenuItems.map((item) => (
|
||||
<li className="contents" key={item.label}>
|
||||
<button
|
||||
onClick={() => {
|
||||
item.onClick()
|
||||
// Close the popover
|
||||
close()
|
||||
}}
|
||||
className="group/button flex items-center gap-6 px-3 py-1 font-sans text-xs hover:bg-primary/10 dark:hover:bg-chalkboard-80 border-0 m-0 w-full rounded-none text-left disabled:!bg-transparent dark:disabled:text-chalkboard-60"
|
||||
disabled={item.disabled}
|
||||
data-testid={'dropdown-' + item.id}
|
||||
>
|
||||
<span className="capitalize flex-grow text-left">
|
||||
{item.label}
|
||||
</span>
|
||||
{item.status === 'unavailable' ? (
|
||||
<div className="flex flex-none items-center gap-1">
|
||||
<span className="text-chalkboard-70 dark:text-chalkboard-40">
|
||||
In development
|
||||
</span>
|
||||
<CustomIcon
|
||||
name="lockClosed"
|
||||
className="w-4 h-4 text-chalkboard-70 dark:text-chalkboard-40"
|
||||
/>
|
||||
</div>
|
||||
) : item.status === 'kcl-only' ? (
|
||||
<div className="flex flex-none items-center gap-1">
|
||||
<span className="text-chalkboard-70 dark:text-chalkboard-40">
|
||||
KCL code only
|
||||
</span>
|
||||
<CustomIcon
|
||||
name="code"
|
||||
className="w-4 h-4 text-chalkboard-70 dark:text-chalkboard-40"
|
||||
/>
|
||||
</div>
|
||||
) : item.shortcut ? (
|
||||
<kbd className="hotkey flex-none group-disabled/button:text-chalkboard-50 dark:group-disabled/button:text-chalkboard-70 group-disabled/button:border-chalkboard-20 dark:group-disabled/button:border-chalkboard-80">
|
||||
{item.shortcut}
|
||||
</kbd>
|
||||
) : null}
|
||||
</button>
|
||||
</li>
|
||||
))}
|
||||
</Popover.Panel>
|
||||
</>
|
||||
)}
|
||||
</Popover>
|
||||
)
|
||||
}
|
||||
|
Reference in New Issue
Block a user