Add tooltips to basic view buttons
This commit is contained in:
parent
9cd5a0f74f
commit
f3cd1c2f8c
@ -220,7 +220,7 @@ export default function AdminAppMenu({
|
||||
</div>}
|
||||
align="start"
|
||||
sideOffset={12}
|
||||
alignOffset={-85}
|
||||
alignOffset={-93}
|
||||
onOpen={refreshAdminData}
|
||||
className={clsx(
|
||||
'border-medium',
|
||||
|
||||
@ -22,22 +22,22 @@ export default function ThemeSwitcher () {
|
||||
return (
|
||||
<Switcher>
|
||||
<SwitcherItem
|
||||
title="System"
|
||||
icon={<BiDesktop size={16} />}
|
||||
onClick={() => setTheme('system')}
|
||||
active={theme === 'system'}
|
||||
tooltip={{ content: 'System' }}
|
||||
/>
|
||||
<SwitcherItem
|
||||
title="Light"
|
||||
icon={<BiSun size={18} />}
|
||||
onClick={() => setTheme('light')}
|
||||
active={theme === 'light'}
|
||||
tooltip={{ content: 'Light Mode' }}
|
||||
/>
|
||||
<SwitcherItem
|
||||
title="Dark"
|
||||
icon={<BiMoon size={16} />}
|
||||
onClick={() => setTheme('dark')}
|
||||
active={theme === 'dark'}
|
||||
tooltip={{ content: 'Dark Mode' }}
|
||||
/>
|
||||
</Switcher>
|
||||
);
|
||||
|
||||
@ -30,17 +30,25 @@ export default function ViewSwitcher({
|
||||
|
||||
const renderItemFeed =
|
||||
<SwitcherItem
|
||||
icon={<IconFeed />}
|
||||
icon={<IconFeed includeTitle={false} />}
|
||||
href={PATH_FEED_INFERRED}
|
||||
active={currentSelection === 'feed'}
|
||||
tooltip={{
|
||||
content: 'Feed',
|
||||
keyCommand: 'F',
|
||||
}}
|
||||
noPadding
|
||||
/>;
|
||||
|
||||
const renderItemGrid =
|
||||
<SwitcherItem
|
||||
icon={<IconGrid />}
|
||||
icon={<IconGrid includeTitle={false} />}
|
||||
href={PATH_GRID_INFERRED}
|
||||
active={currentSelection === 'grid'}
|
||||
tooltip={{
|
||||
content: 'Grid',
|
||||
keyCommand: 'G',
|
||||
}}
|
||||
noPadding
|
||||
/>;
|
||||
|
||||
@ -58,18 +66,25 @@ export default function ViewSwitcher({
|
||||
icon={<Spinner />}
|
||||
isInteractive={false}
|
||||
noPadding
|
||||
tooltip={{ content: 'Admin Menu' }}
|
||||
/>}
|
||||
{isUserSignedIn &&
|
||||
<SwitcherItem
|
||||
className="p-0!"
|
||||
icon={<AdminAppMenu />}
|
||||
noPadding
|
||||
tooltip={{ content: 'Admin Menu' }}
|
||||
/>}
|
||||
</Switcher>
|
||||
<Switcher type="borderless">
|
||||
<SwitcherItem
|
||||
icon={<IconSearch />}
|
||||
title="Search"
|
||||
icon={<IconSearch includeTitle={false} />}
|
||||
onClick={() => setIsCommandKOpen?.(true)}
|
||||
tooltip={{
|
||||
content: 'Search',
|
||||
keyCommand: 'K',
|
||||
keyCommandModifier: '⌘',
|
||||
}}
|
||||
/>
|
||||
</Switcher>
|
||||
</div>
|
||||
|
||||
@ -1,8 +1,9 @@
|
||||
import { clsx } from 'clsx/lite';
|
||||
import { SHOULD_PREFETCH_ALL_LINKS } from '@/app/config';
|
||||
import { ReactNode } from 'react';
|
||||
import { ComponentProps, ReactNode } from 'react';
|
||||
import Spinner from './Spinner';
|
||||
import LinkWithIconLoader from './LinkWithIconLoader';
|
||||
import Tooltip from './Tooltip';
|
||||
|
||||
export default function SwitcherItem({
|
||||
icon,
|
||||
@ -14,6 +15,7 @@ export default function SwitcherItem({
|
||||
isInteractive = true,
|
||||
noPadding,
|
||||
prefetch = SHOULD_PREFETCH_ALL_LINKS,
|
||||
tooltip,
|
||||
}: {
|
||||
icon: ReactNode
|
||||
title?: string
|
||||
@ -24,6 +26,7 @@ export default function SwitcherItem({
|
||||
isInteractive?: boolean
|
||||
noPadding?: boolean
|
||||
prefetch?: boolean
|
||||
tooltip?: ComponentProps<typeof Tooltip>
|
||||
}) {
|
||||
const className = clsx(
|
||||
'flex items-center justify-center',
|
||||
@ -50,18 +53,24 @@ export default function SwitcherItem({
|
||||
{icon}
|
||||
</div>;
|
||||
|
||||
const content = href
|
||||
? <LinkWithIconLoader {...{
|
||||
href,
|
||||
title,
|
||||
className,
|
||||
prefetch,
|
||||
icon: renderIcon(),
|
||||
loader: <Spinner />,
|
||||
}} />
|
||||
: <div {...{ title, onClick, className }}>
|
||||
{renderIcon()}
|
||||
</div>;
|
||||
|
||||
return (
|
||||
href
|
||||
? <LinkWithIconLoader {...{
|
||||
title,
|
||||
href,
|
||||
className,
|
||||
prefetch,
|
||||
icon: renderIcon(),
|
||||
loader: <Spinner />,
|
||||
}} />
|
||||
: <div {...{ title, onClick, className }}>
|
||||
{renderIcon()}
|
||||
</div>
|
||||
tooltip
|
||||
? <Tooltip {...tooltip}>
|
||||
{content}
|
||||
</Tooltip>
|
||||
: content
|
||||
);
|
||||
};
|
||||
|
||||
29
src/components/primitives/KeyCommand.tsx
Normal file
29
src/components/primitives/KeyCommand.tsx
Normal file
@ -0,0 +1,29 @@
|
||||
import clsx from 'clsx/lite';
|
||||
import { useMemo } from 'react';
|
||||
|
||||
export default function KeyCommand({
|
||||
children,
|
||||
modifier,
|
||||
className,
|
||||
}: {
|
||||
children: string
|
||||
modifier?: '⌘' | '⌥' | '⇧' | '⌃' | '⏎'
|
||||
className?: string
|
||||
}) {
|
||||
const keys = useMemo(() =>
|
||||
modifier ? [modifier, ...children] : [...children],
|
||||
[modifier, children]);
|
||||
|
||||
return (
|
||||
<span className={clsx('inline-flex items-center gap-0.5', className)}>
|
||||
{keys.map((key) => (
|
||||
<span
|
||||
key={key}
|
||||
className="text-gray-600 bg-gray-200/75 px-1 rounded-sm"
|
||||
>
|
||||
{key}
|
||||
</span>
|
||||
))}
|
||||
</span>
|
||||
);
|
||||
}
|
||||
@ -6,22 +6,30 @@ import MenuSurface from './MenuSurface';
|
||||
import useSupportsHover from '@/utility/useSupportsHover';
|
||||
import clsx from 'clsx/lite';
|
||||
import useClickInsideOutside from '@/utility/useClickInsideOutside';
|
||||
|
||||
import KeyCommand from './KeyCommand';
|
||||
export default function TooltipPrimitive({
|
||||
content,
|
||||
content: contentProp,
|
||||
className,
|
||||
classNameTrigger: classNameTriggerProp,
|
||||
sideOffset = 10,
|
||||
delayDuration = 100,
|
||||
skipDelayDuration = 300,
|
||||
supportMobile,
|
||||
color,
|
||||
keyCommand,
|
||||
keyCommandModifier,
|
||||
children,
|
||||
}: {
|
||||
content?: ReactNode
|
||||
className?: string
|
||||
classNameTrigger?: string
|
||||
sideOffset?: number
|
||||
delayDuration?: number
|
||||
skipDelayDuration?: number
|
||||
supportMobile?: boolean
|
||||
color?: ComponentProps<typeof MenuSurface>['color']
|
||||
keyCommand?: string
|
||||
keyCommandModifier?: ComponentProps<typeof KeyCommand>['modifier']
|
||||
children: ReactNode
|
||||
}) {
|
||||
const refTrigger = useRef<HTMLButtonElement>(null);
|
||||
@ -45,8 +53,18 @@ export default function TooltipPrimitive({
|
||||
classNameTriggerProp,
|
||||
);
|
||||
|
||||
const content = keyCommand
|
||||
? <div className="-mr-0.5">
|
||||
{contentProp}
|
||||
{' '}
|
||||
<KeyCommand {...{ modifier: keyCommandModifier }}>
|
||||
{keyCommand}
|
||||
</KeyCommand>
|
||||
</div>
|
||||
: contentProp;
|
||||
|
||||
return (
|
||||
<Tooltip.Provider delayDuration={100}>
|
||||
<Tooltip.Provider {...{ delayDuration, skipDelayDuration }}>
|
||||
<Tooltip.Root open={includeButton ? isOpen : undefined}>
|
||||
<Tooltip.Trigger asChild>
|
||||
{includeButton
|
||||
|
||||
Loading…
Reference in New Issue
Block a user