@adea-ai/ui 0.97.0 → 0.97.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/composites/account-menu/account-menu.d.ts +8 -1
- package/dist/components/composites/account-menu/account-menu.d.ts.map +1 -1
- package/dist/components/composites/account-menu/account-menu.js +12 -1
- package/dist/components/composites/account-menu/account-menu.js.map +1 -1
- package/dist/r/src/components/composites/account-menu/account-menu.tsx +12 -1
- package/package.json +1 -1
- package/src/components/composites/account-menu/account-menu.tsx +12 -1
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import type { JSX } from 'solid-js';
|
|
1
|
+
import type { ComponentProps, JSX } from 'solid-js';
|
|
2
2
|
import { type ButtonProps } from '../../ui/button/button';
|
|
3
|
+
import { DropdownMenu } from '../../ui/dropdown-menu/dropdown-menu';
|
|
3
4
|
/**
|
|
4
5
|
* AccountMenu.
|
|
5
6
|
*
|
|
@@ -32,6 +33,12 @@ export type AccountMenuItem = {
|
|
|
32
33
|
};
|
|
33
34
|
export type AccountMenuProps = {
|
|
34
35
|
class?: string;
|
|
36
|
+
/** Anchor a rail menu beside its trigger, or keep the default upward placement. */
|
|
37
|
+
placement?: ComponentProps<typeof DropdownMenu>['placement'];
|
|
38
|
+
/** Space between the trigger and menu, in pixels. */
|
|
39
|
+
gutter?: ComponentProps<typeof DropdownMenu>['gutter'];
|
|
40
|
+
/** Hide the menu pointer when aligning it beside a compact rail. */
|
|
41
|
+
hideArrow?: boolean;
|
|
35
42
|
/** The trigger size. Icon-only menus default to the standard icon size. */
|
|
36
43
|
size?: ButtonProps['size'];
|
|
37
44
|
/** The entries above the separator. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"account-menu.d.ts","sourceRoot":"","sources":["../../../../src/components/composites/account-menu/account-menu.tsx"],"names":[],"mappings":"AAWA,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"account-menu.d.ts","sourceRoot":"","sources":["../../../../src/components/composites/account-menu/account-menu.tsx"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAAE,cAAc,EAAE,GAAG,EAAE,MAAM,UAAU,CAAA;AAGnD,OAAO,EAAU,KAAK,WAAW,EAAE,MAAM,wBAAwB,CAAA;AACjE,OAAO,EACL,YAAY,EAMb,MAAM,sCAAsC,CAAA;AAG7C;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,MAAM,eAAe,GAAG;IAC5B,EAAE,EAAE,MAAM,CAAA;IACV,KAAK,EAAE,MAAM,CAAA;IACb,IAAI,CAAC,EAAE,GAAG,CAAC,OAAO,CAAA;IAClB,qDAAqD;IACrD,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,2DAA2D;IAC3D,QAAQ,CAAC,EAAE,SAAS,GAAG,KAAK,CAAA;IAC5B,QAAQ,CAAC,EAAE,MAAM,IAAI,CAAA;IACrB,mFAAmF;IACnF,kBAAkB,CAAC,EAAE,CAAC,OAAO,EAAE,iBAAiB,GAAG,SAAS,KAAK,IAAI,CAAA;CACtE,CAAA;AAED,MAAM,MAAM,gBAAgB,GAAG;IAC7B,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,mFAAmF;IACnF,SAAS,CAAC,EAAE,cAAc,CAAC,OAAO,YAAY,CAAC,CAAC,WAAW,CAAC,CAAA;IAC5D,qDAAqD;IACrD,MAAM,CAAC,EAAE,cAAc,CAAC,OAAO,YAAY,CAAC,CAAC,QAAQ,CAAC,CAAA;IACtD,oEAAoE;IACpE,SAAS,CAAC,EAAE,OAAO,CAAA;IACnB,2EAA2E;IAC3E,IAAI,CAAC,EAAE,WAAW,CAAC,MAAM,CAAC,CAAA;IAC1B,uCAAuC;IACvC,KAAK,EAAE,SAAS,eAAe,EAAE,CAAA;IACjC,sEAAsE;IACtE,QAAQ,CAAC,EAAE,SAAS,GAAG,KAAK,CAAA;IAC5B,kEAAkE;IAClE,aAAa,EAAE,OAAO,CAAA;IACtB,uEAAuE;IACvE,WAAW,CAAC,EAAE,OAAO,CAAA;IACrB,wEAAwE;IACxE,IAAI,CAAC,EAAE,OAAO,CAAA;IACd,wDAAwD;IACxD,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,QAAQ,CAAC,EAAE,MAAM,IAAI,CAAA;IACrB,SAAS,CAAC,EAAE,MAAM,IAAI,CAAA;IACtB,qEAAqE;IACrE,QAAQ,CAAC,EAAE,MAAM,IAAI,CAAA;CACtB,CAAA;AAWD,wBAAgB,WAAW,CAAC,KAAK,EAAE,gBAAgB,eAmHlD;AAED,oFAAoF;AACpF,wBAAgB,kBAAkB,CAAC,OAAO,EAAE;IAC1C,WAAW,CAAC,EAAE,eAAe,CAAA;IAC7B,gBAAgB,CAAC,EAAE,MAAM,CAAA;IACzB,OAAO,CAAC,EAAE,eAAe,CAAC,oBAAoB,CAAC,CAAA;IAC/C,MAAM,CAAC,EAAE,eAAe,CAAC,oBAAoB,CAAC,CAAA;IAC9C,UAAU,CAAC,EAAE,eAAe,CAAC,oBAAoB,CAAC,CAAA;IAClD,SAAS,CAAC,EAAE,eAAe,CAAC,oBAAoB,CAAC,CAAA;IACjD,UAAU,CAAC,EAAE,eAAe,CAAC,oBAAoB,CAAC,CAAA;CACnD,GAAG,eAAe,EAAE,CAoCpB"}
|
|
@@ -18,6 +18,9 @@ var FALLBACK_ICONS = {
|
|
|
18
18
|
function AccountMenu(props) {
|
|
19
19
|
const [local, rest] = splitProps(props, [
|
|
20
20
|
"class",
|
|
21
|
+
"placement",
|
|
22
|
+
"gutter",
|
|
23
|
+
"hideArrow",
|
|
21
24
|
"size",
|
|
22
25
|
"items",
|
|
23
26
|
"platform",
|
|
@@ -47,6 +50,12 @@ function AccountMenu(props) {
|
|
|
47
50
|
get children() {
|
|
48
51
|
return createComponent(DropdownMenu, {
|
|
49
52
|
modal: false,
|
|
53
|
+
get placement() {
|
|
54
|
+
return local.placement ?? "top-start";
|
|
55
|
+
},
|
|
56
|
+
get gutter() {
|
|
57
|
+
return local.gutter;
|
|
58
|
+
},
|
|
50
59
|
onOpenChange: (open) => {
|
|
51
60
|
setMenuOpen(open);
|
|
52
61
|
if (open) setTooltipOpen(false);
|
|
@@ -78,7 +87,9 @@ function AccountMenu(props) {
|
|
|
78
87
|
}
|
|
79
88
|
}),
|
|
80
89
|
createComponent(DropdownMenuContent, {
|
|
81
|
-
|
|
90
|
+
get hideArrow() {
|
|
91
|
+
return local.hideArrow;
|
|
92
|
+
},
|
|
82
93
|
"class": "min-w-56 max-h-(--kb-popper-available-height) overflow-x-hidden overflow-y-auto",
|
|
83
94
|
onCloseAutoFocus: (event) => {
|
|
84
95
|
const selection = pendingAfterClose;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"account-menu.js","names":["CircleHelp","Info","LogIn","LogOut","Megaphone","RefreshCw","Settings2","Smartphone","UserRound","ComponentProps","JSX","For","Show","createSignal","onCleanup","splitProps","cn","Button","ButtonProps","DropdownMenu","DropdownMenuContent","DropdownMenuGroup","DropdownMenuItem","DropdownMenuSeparator","DropdownMenuTrigger","Tooltip","TooltipContent","TooltipTrigger","AccountMenuItem","id","label","icon","Element","shortcut","disabled","platform","onSelect","onSelectAfterClose","trigger","HTMLButtonElement","AccountMenuProps","class","size","items","authenticated","showSession","busy","onSignIn","onSignOut","onIntent","FALLBACK_ICONS","Record","mobile","settings","about","help","feedback","updates","AccountMenu","props","local","rest","pendingAfterClose","callback","NonNullable","scheduledAfterClose","menuOpen","setMenuOpen","tooltipOpen","setTooltipOpen","undefined","visible","filter","item","_$createComponent","open","onOpenChange","children","modal","_$mergeProps","as","AccountMenuButton","ref","element","variant","aria-label","onFocus","onPointerEnter","placement","onCloseAutoFocus","event","selection","preventDefault","queueMicrotask","each","_$memo","renderFallbackIcon","_el$2","_tmpl$","_$insert","when","fallback","_el$","createAppMenuItems","options","primaryItem","settingsShortcut","onAbout","onHelp","onFeedback","onUpdates","onSettings","Icon","_$createComponent","_$mergeProps","_$memo"],"sources":["../../../../src/components/composites/account-menu/account-menu.tsx"],"sourcesContent":["import {\n CircleHelp,\n Info,\n LogIn,\n LogOut,\n Megaphone,\n RefreshCw,\n Settings2,\n Smartphone,\n UserRound,\n} from 'lucide-solid'\nimport type { ComponentProps, JSX } from 'solid-js'\nimport { For, Show, createSignal, onCleanup, splitProps } from 'solid-js'\nimport { cn } from '#lib/utils'\nimport { Button, type ButtonProps } from '../../ui/button/button'\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuGroup,\n DropdownMenuItem,\n DropdownMenuSeparator,\n DropdownMenuTrigger,\n} from '../../ui/dropdown-menu/dropdown-menu'\nimport { Tooltip, TooltipContent, TooltipTrigger } from '../../ui/tooltip/tooltip'\n\n/**\n * AccountMenu.\n *\n * The trailing control in a rail or a top bar: the account, the way into settings,\n * and the way out. Every desktop application has one and they are all the same menu,\n * which is why it belongs here rather than being redrawn per app.\n *\n * ## The items are the caller's\n *\n * The menu takes a list rather than hard-coding one. An application adds and removes\n * entries — a mobile hand-off that only makes sense on desktop, a feedback link that\n * only exists once there is somewhere to send it — and a component that decided the\n * list could not be used by two products.\n *\n * `disabled` on an item is deliberately visible rather than hidden: a greyed \"Help\n * Center\" says the destination is coming, while an absent one says it does not exist.\n */\nexport type AccountMenuItem = {\n id: string\n label: string\n icon?: JSX.Element\n /** A chord drawn at the trailing edge, e.g. `⌘,`. */\n shortcut?: string\n disabled?: boolean\n /** Render only on this platform. Omit to always render. */\n platform?: 'desktop' | 'web'\n onSelect?: () => void\n /** Run after the menu's close-focus cycle, with its trigger as a stable opener. */\n onSelectAfterClose?: (trigger: HTMLButtonElement | undefined) => void\n}\n\nexport type AccountMenuProps = {\n class?: string\n /** The trigger size. Icon-only menus default to the standard icon size. */\n size?: ButtonProps['size']\n /** The entries above the separator. */\n items: readonly AccountMenuItem[]\n /** Which platform this is rendered on, for items that declare one. */\n platform?: 'desktop' | 'web'\n /** Whether a session exists. Decides the sign-in/sign-out row. */\n authenticated: boolean\n /** Local-only applications can omit the session actions altogether. */\n showSession?: boolean\n /** Disable the session row while a sign-in or sign-out is in flight. */\n busy?: boolean\n /** The name shown on the trigger's accessible label. */\n label?: string\n onSignIn?: () => void\n onSignOut?: () => void\n /** Fires on hover or focus of the trigger — a chance to prefetch. */\n onIntent?: () => void\n}\n\nconst FALLBACK_ICONS: Record<string, typeof Settings2> = {\n mobile: Smartphone,\n settings: Settings2,\n about: Info,\n help: CircleHelp,\n feedback: Megaphone,\n updates: RefreshCw,\n}\n\nexport function AccountMenu(props: AccountMenuProps) {\n const [local, rest] = splitProps(props, [\n 'class',\n 'size',\n 'items',\n 'platform',\n 'authenticated',\n 'showSession',\n 'busy',\n 'label',\n 'onSignIn',\n 'onSignOut',\n 'onIntent',\n ])\n\n let trigger: HTMLButtonElement | undefined\n let pendingAfterClose:\n | { callback: NonNullable<AccountMenuItem['onSelectAfterClose']> }\n | undefined\n let scheduledAfterClose:\n | { callback: NonNullable<AccountMenuItem['onSelectAfterClose']> }\n | undefined\n const [menuOpen, setMenuOpen] = createSignal(false)\n const [tooltipOpen, setTooltipOpen] = createSignal(false)\n\n onCleanup(() => {\n pendingAfterClose = undefined\n scheduledAfterClose = undefined\n })\n\n const visible = () =>\n local.items.filter((item) => !item.platform || item.platform === (local.platform ?? 'desktop'))\n\n return (\n <Tooltip open={tooltipOpen()} onOpenChange={(open) => setTooltipOpen(open && !menuOpen())}>\n <DropdownMenu\n modal={false}\n onOpenChange={(open) => {\n setMenuOpen(open)\n if (open) setTooltipOpen(false)\n }}\n >\n <TooltipTrigger\n as={AccountMenuButton}\n ref={(element: HTMLButtonElement) => (trigger = element)}\n variant=\"ghost\"\n size={local.size ?? 'icon-md'}\n class={cn('text-muted-foreground', local.class)}\n aria-label={local.label ?? 'Account and settings'}\n onFocus={() => local.onIntent?.()}\n onPointerEnter={() => local.onIntent?.()}\n {...rest}\n >\n <UserRound aria-hidden=\"true\" />\n </TooltipTrigger>\n <TooltipContent placement=\"top\">{local.label ?? 'Account and settings'}</TooltipContent>\n <DropdownMenuContent\n placement=\"top-start\"\n class=\"min-w-56 max-h-(--kb-popper-available-height) overflow-x-hidden overflow-y-auto\"\n onCloseAutoFocus={(event) => {\n const selection = pendingAfterClose\n pendingAfterClose = undefined\n if (!selection) return\n\n event.preventDefault()\n scheduledAfterClose = selection\n queueMicrotask(() => {\n if (scheduledAfterClose !== selection) return\n scheduledAfterClose = undefined\n selection.callback(trigger)\n })\n }}\n >\n <DropdownMenuGroup>\n <For each={visible()}>\n {(item) => (\n <DropdownMenuItem\n disabled={item.disabled}\n onSelect={() => {\n pendingAfterClose = item.onSelectAfterClose\n ? { callback: item.onSelectAfterClose }\n : undefined\n item.onSelect?.()\n }}\n shortcut={item.shortcut}\n >\n {item.icon ?? renderFallbackIcon(item.id)}\n <span>{item.label}</span>\n </DropdownMenuItem>\n )}\n </For>\n </DropdownMenuGroup>\n <Show when={local.showSession !== false}>\n <DropdownMenuSeparator />\n <DropdownMenuGroup>\n <DropdownMenuItem\n disabled={local.busy}\n onSelect={() => (local.authenticated ? local.onSignOut?.() : local.onSignIn?.())}\n >\n <Show when={local.authenticated} fallback={<LogIn aria-hidden=\"true\" />}>\n <LogOut aria-hidden=\"true\" />\n </Show>\n <span>{local.authenticated ? 'Sign out' : 'Sign in'}</span>\n </DropdownMenuItem>\n </DropdownMenuGroup>\n </Show>\n </DropdownMenuContent>\n </DropdownMenu>\n </Tooltip>\n )\n}\n\n/** The common support menu, with one app-specific entry before the shared items. */\nexport function createAppMenuItems(options: {\n primaryItem?: AccountMenuItem\n settingsShortcut?: string\n onAbout?: AccountMenuItem['onSelectAfterClose']\n onHelp?: AccountMenuItem['onSelectAfterClose']\n onFeedback?: AccountMenuItem['onSelectAfterClose']\n onUpdates?: AccountMenuItem['onSelectAfterClose']\n onSettings?: AccountMenuItem['onSelectAfterClose']\n}): AccountMenuItem[] {\n return [\n ...(options.primaryItem ? [options.primaryItem] : []),\n {\n id: 'about',\n label: 'About',\n disabled: !options.onAbout,\n onSelectAfterClose: options.onAbout,\n },\n {\n id: 'help',\n label: 'Help Center',\n disabled: !options.onHelp,\n onSelectAfterClose: options.onHelp,\n },\n {\n id: 'feedback',\n label: 'Send Feedback',\n disabled: !options.onFeedback,\n onSelectAfterClose: options.onFeedback,\n },\n {\n id: 'updates',\n label: 'Updates',\n platform: 'desktop',\n disabled: !options.onUpdates,\n onSelectAfterClose: options.onUpdates,\n },\n {\n id: 'settings',\n label: 'Settings',\n shortcut: options.settingsShortcut,\n disabled: !options.onSettings,\n onSelectAfterClose: options.onSettings,\n },\n ]\n}\n\nfunction AccountMenuButton(props: ComponentProps<typeof Button>) {\n return <DropdownMenuTrigger as={Button} {...props} />\n}\n\n/**\n * A known item id gets its conventional glyph, so a caller that only wants the\n * standard menu does not have to import six icons to get it.\n */\nfunction renderFallbackIcon(id: string): JSX.Element {\n const Icon = FALLBACK_ICONS[id]\n return Icon ? <Icon aria-hidden=\"true\" /> : null\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"account-menu.js","names":["CircleHelp","Info","LogIn","LogOut","Megaphone","RefreshCw","Settings2","Smartphone","UserRound","ComponentProps","JSX","For","Show","createSignal","onCleanup","splitProps","cn","Button","ButtonProps","DropdownMenu","DropdownMenuContent","DropdownMenuGroup","DropdownMenuItem","DropdownMenuSeparator","DropdownMenuTrigger","Tooltip","TooltipContent","TooltipTrigger","AccountMenuItem","id","label","icon","Element","shortcut","disabled","platform","onSelect","onSelectAfterClose","trigger","HTMLButtonElement","AccountMenuProps","class","placement","gutter","hideArrow","size","items","authenticated","showSession","busy","onSignIn","onSignOut","onIntent","FALLBACK_ICONS","Record","mobile","settings","about","help","feedback","updates","AccountMenu","props","local","rest","pendingAfterClose","callback","NonNullable","scheduledAfterClose","menuOpen","setMenuOpen","tooltipOpen","setTooltipOpen","undefined","visible","filter","item","_$createComponent","open","onOpenChange","children","modal","_$mergeProps","as","AccountMenuButton","ref","element","variant","aria-label","onFocus","onPointerEnter","onCloseAutoFocus","event","selection","preventDefault","queueMicrotask","each","_$memo","renderFallbackIcon","_el$2","_tmpl$","_$insert","when","fallback","_el$","createAppMenuItems","options","primaryItem","settingsShortcut","onAbout","onHelp","onFeedback","onUpdates","onSettings","Icon","_$createComponent","_$mergeProps","_$memo"],"sources":["../../../../src/components/composites/account-menu/account-menu.tsx"],"sourcesContent":["import {\n CircleHelp,\n Info,\n LogIn,\n LogOut,\n Megaphone,\n RefreshCw,\n Settings2,\n Smartphone,\n UserRound,\n} from 'lucide-solid'\nimport type { ComponentProps, JSX } from 'solid-js'\nimport { For, Show, createSignal, onCleanup, splitProps } from 'solid-js'\nimport { cn } from '#lib/utils'\nimport { Button, type ButtonProps } from '../../ui/button/button'\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuGroup,\n DropdownMenuItem,\n DropdownMenuSeparator,\n DropdownMenuTrigger,\n} from '../../ui/dropdown-menu/dropdown-menu'\nimport { Tooltip, TooltipContent, TooltipTrigger } from '../../ui/tooltip/tooltip'\n\n/**\n * AccountMenu.\n *\n * The trailing control in a rail or a top bar: the account, the way into settings,\n * and the way out. Every desktop application has one and they are all the same menu,\n * which is why it belongs here rather than being redrawn per app.\n *\n * ## The items are the caller's\n *\n * The menu takes a list rather than hard-coding one. An application adds and removes\n * entries — a mobile hand-off that only makes sense on desktop, a feedback link that\n * only exists once there is somewhere to send it — and a component that decided the\n * list could not be used by two products.\n *\n * `disabled` on an item is deliberately visible rather than hidden: a greyed \"Help\n * Center\" says the destination is coming, while an absent one says it does not exist.\n */\nexport type AccountMenuItem = {\n id: string\n label: string\n icon?: JSX.Element\n /** A chord drawn at the trailing edge, e.g. `⌘,`. */\n shortcut?: string\n disabled?: boolean\n /** Render only on this platform. Omit to always render. */\n platform?: 'desktop' | 'web'\n onSelect?: () => void\n /** Run after the menu's close-focus cycle, with its trigger as a stable opener. */\n onSelectAfterClose?: (trigger: HTMLButtonElement | undefined) => void\n}\n\nexport type AccountMenuProps = {\n class?: string\n /** Anchor a rail menu beside its trigger, or keep the default upward placement. */\n placement?: ComponentProps<typeof DropdownMenu>['placement']\n /** Space between the trigger and menu, in pixels. */\n gutter?: ComponentProps<typeof DropdownMenu>['gutter']\n /** Hide the menu pointer when aligning it beside a compact rail. */\n hideArrow?: boolean\n /** The trigger size. Icon-only menus default to the standard icon size. */\n size?: ButtonProps['size']\n /** The entries above the separator. */\n items: readonly AccountMenuItem[]\n /** Which platform this is rendered on, for items that declare one. */\n platform?: 'desktop' | 'web'\n /** Whether a session exists. Decides the sign-in/sign-out row. */\n authenticated: boolean\n /** Local-only applications can omit the session actions altogether. */\n showSession?: boolean\n /** Disable the session row while a sign-in or sign-out is in flight. */\n busy?: boolean\n /** The name shown on the trigger's accessible label. */\n label?: string\n onSignIn?: () => void\n onSignOut?: () => void\n /** Fires on hover or focus of the trigger — a chance to prefetch. */\n onIntent?: () => void\n}\n\nconst FALLBACK_ICONS: Record<string, typeof Settings2> = {\n mobile: Smartphone,\n settings: Settings2,\n about: Info,\n help: CircleHelp,\n feedback: Megaphone,\n updates: RefreshCw,\n}\n\nexport function AccountMenu(props: AccountMenuProps) {\n const [local, rest] = splitProps(props, [\n 'class',\n 'placement',\n 'gutter',\n 'hideArrow',\n 'size',\n 'items',\n 'platform',\n 'authenticated',\n 'showSession',\n 'busy',\n 'label',\n 'onSignIn',\n 'onSignOut',\n 'onIntent',\n ])\n\n let trigger: HTMLButtonElement | undefined\n let pendingAfterClose:\n | { callback: NonNullable<AccountMenuItem['onSelectAfterClose']> }\n | undefined\n let scheduledAfterClose:\n | { callback: NonNullable<AccountMenuItem['onSelectAfterClose']> }\n | undefined\n const [menuOpen, setMenuOpen] = createSignal(false)\n const [tooltipOpen, setTooltipOpen] = createSignal(false)\n\n onCleanup(() => {\n pendingAfterClose = undefined\n scheduledAfterClose = undefined\n })\n\n const visible = () =>\n local.items.filter((item) => !item.platform || item.platform === (local.platform ?? 'desktop'))\n\n return (\n <Tooltip open={tooltipOpen()} onOpenChange={(open) => setTooltipOpen(open && !menuOpen())}>\n <DropdownMenu\n modal={false}\n placement={local.placement ?? 'top-start'}\n gutter={local.gutter}\n onOpenChange={(open) => {\n setMenuOpen(open)\n if (open) setTooltipOpen(false)\n }}\n >\n <TooltipTrigger\n as={AccountMenuButton}\n ref={(element: HTMLButtonElement) => (trigger = element)}\n variant=\"ghost\"\n size={local.size ?? 'icon-md'}\n class={cn('text-muted-foreground', local.class)}\n aria-label={local.label ?? 'Account and settings'}\n onFocus={() => local.onIntent?.()}\n onPointerEnter={() => local.onIntent?.()}\n {...rest}\n >\n <UserRound aria-hidden=\"true\" />\n </TooltipTrigger>\n <TooltipContent placement=\"top\">{local.label ?? 'Account and settings'}</TooltipContent>\n <DropdownMenuContent\n hideArrow={local.hideArrow}\n class=\"min-w-56 max-h-(--kb-popper-available-height) overflow-x-hidden overflow-y-auto\"\n onCloseAutoFocus={(event) => {\n const selection = pendingAfterClose\n pendingAfterClose = undefined\n if (!selection) return\n\n event.preventDefault()\n scheduledAfterClose = selection\n queueMicrotask(() => {\n if (scheduledAfterClose !== selection) return\n scheduledAfterClose = undefined\n selection.callback(trigger)\n })\n }}\n >\n <DropdownMenuGroup>\n <For each={visible()}>\n {(item) => (\n <DropdownMenuItem\n disabled={item.disabled}\n onSelect={() => {\n pendingAfterClose = item.onSelectAfterClose\n ? { callback: item.onSelectAfterClose }\n : undefined\n item.onSelect?.()\n }}\n shortcut={item.shortcut}\n >\n {item.icon ?? renderFallbackIcon(item.id)}\n <span>{item.label}</span>\n </DropdownMenuItem>\n )}\n </For>\n </DropdownMenuGroup>\n <Show when={local.showSession !== false}>\n <DropdownMenuSeparator />\n <DropdownMenuGroup>\n <DropdownMenuItem\n disabled={local.busy}\n onSelect={() => (local.authenticated ? local.onSignOut?.() : local.onSignIn?.())}\n >\n <Show when={local.authenticated} fallback={<LogIn aria-hidden=\"true\" />}>\n <LogOut aria-hidden=\"true\" />\n </Show>\n <span>{local.authenticated ? 'Sign out' : 'Sign in'}</span>\n </DropdownMenuItem>\n </DropdownMenuGroup>\n </Show>\n </DropdownMenuContent>\n </DropdownMenu>\n </Tooltip>\n )\n}\n\n/** The common support menu, with one app-specific entry before the shared items. */\nexport function createAppMenuItems(options: {\n primaryItem?: AccountMenuItem\n settingsShortcut?: string\n onAbout?: AccountMenuItem['onSelectAfterClose']\n onHelp?: AccountMenuItem['onSelectAfterClose']\n onFeedback?: AccountMenuItem['onSelectAfterClose']\n onUpdates?: AccountMenuItem['onSelectAfterClose']\n onSettings?: AccountMenuItem['onSelectAfterClose']\n}): AccountMenuItem[] {\n return [\n ...(options.primaryItem ? [options.primaryItem] : []),\n {\n id: 'about',\n label: 'About',\n disabled: !options.onAbout,\n onSelectAfterClose: options.onAbout,\n },\n {\n id: 'help',\n label: 'Help Center',\n disabled: !options.onHelp,\n onSelectAfterClose: options.onHelp,\n },\n {\n id: 'feedback',\n label: 'Send Feedback',\n disabled: !options.onFeedback,\n onSelectAfterClose: options.onFeedback,\n },\n {\n id: 'updates',\n label: 'Updates',\n platform: 'desktop',\n disabled: !options.onUpdates,\n onSelectAfterClose: options.onUpdates,\n },\n {\n id: 'settings',\n label: 'Settings',\n shortcut: options.settingsShortcut,\n disabled: !options.onSettings,\n onSelectAfterClose: options.onSettings,\n },\n ]\n}\n\nfunction AccountMenuButton(props: ComponentProps<typeof Button>) {\n return <DropdownMenuTrigger as={Button} {...props} />\n}\n\n/**\n * A known item id gets its conventional glyph, so a caller that only wants the\n * standard menu does not have to import six icons to get it.\n */\nfunction renderFallbackIcon(id: string): JSX.Element {\n const Icon = FALLBACK_ICONS[id]\n return Icon ? <Icon aria-hidden=\"true\" /> : null\n}\n"],"mappings":"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"}
|
|
@@ -56,6 +56,12 @@ export type AccountMenuItem = {
|
|
|
56
56
|
|
|
57
57
|
export type AccountMenuProps = {
|
|
58
58
|
class?: string
|
|
59
|
+
/** Anchor a rail menu beside its trigger, or keep the default upward placement. */
|
|
60
|
+
placement?: ComponentProps<typeof DropdownMenu>['placement']
|
|
61
|
+
/** Space between the trigger and menu, in pixels. */
|
|
62
|
+
gutter?: ComponentProps<typeof DropdownMenu>['gutter']
|
|
63
|
+
/** Hide the menu pointer when aligning it beside a compact rail. */
|
|
64
|
+
hideArrow?: boolean
|
|
59
65
|
/** The trigger size. Icon-only menus default to the standard icon size. */
|
|
60
66
|
size?: ButtonProps['size']
|
|
61
67
|
/** The entries above the separator. */
|
|
@@ -88,6 +94,9 @@ const FALLBACK_ICONS: Record<string, typeof Settings2> = {
|
|
|
88
94
|
export function AccountMenu(props: AccountMenuProps) {
|
|
89
95
|
const [local, rest] = splitProps(props, [
|
|
90
96
|
'class',
|
|
97
|
+
'placement',
|
|
98
|
+
'gutter',
|
|
99
|
+
'hideArrow',
|
|
91
100
|
'size',
|
|
92
101
|
'items',
|
|
93
102
|
'platform',
|
|
@@ -122,6 +131,8 @@ export function AccountMenu(props: AccountMenuProps) {
|
|
|
122
131
|
<Tooltip open={tooltipOpen()} onOpenChange={(open) => setTooltipOpen(open && !menuOpen())}>
|
|
123
132
|
<DropdownMenu
|
|
124
133
|
modal={false}
|
|
134
|
+
placement={local.placement ?? 'top-start'}
|
|
135
|
+
gutter={local.gutter}
|
|
125
136
|
onOpenChange={(open) => {
|
|
126
137
|
setMenuOpen(open)
|
|
127
138
|
if (open) setTooltipOpen(false)
|
|
@@ -142,7 +153,7 @@ export function AccountMenu(props: AccountMenuProps) {
|
|
|
142
153
|
</TooltipTrigger>
|
|
143
154
|
<TooltipContent placement="top">{local.label ?? 'Account and settings'}</TooltipContent>
|
|
144
155
|
<DropdownMenuContent
|
|
145
|
-
|
|
156
|
+
hideArrow={local.hideArrow}
|
|
146
157
|
class="min-w-56 max-h-(--kb-popper-available-height) overflow-x-hidden overflow-y-auto"
|
|
147
158
|
onCloseAutoFocus={(event) => {
|
|
148
159
|
const selection = pendingAfterClose
|
package/package.json
CHANGED
|
@@ -56,6 +56,12 @@ export type AccountMenuItem = {
|
|
|
56
56
|
|
|
57
57
|
export type AccountMenuProps = {
|
|
58
58
|
class?: string
|
|
59
|
+
/** Anchor a rail menu beside its trigger, or keep the default upward placement. */
|
|
60
|
+
placement?: ComponentProps<typeof DropdownMenu>['placement']
|
|
61
|
+
/** Space between the trigger and menu, in pixels. */
|
|
62
|
+
gutter?: ComponentProps<typeof DropdownMenu>['gutter']
|
|
63
|
+
/** Hide the menu pointer when aligning it beside a compact rail. */
|
|
64
|
+
hideArrow?: boolean
|
|
59
65
|
/** The trigger size. Icon-only menus default to the standard icon size. */
|
|
60
66
|
size?: ButtonProps['size']
|
|
61
67
|
/** The entries above the separator. */
|
|
@@ -88,6 +94,9 @@ const FALLBACK_ICONS: Record<string, typeof Settings2> = {
|
|
|
88
94
|
export function AccountMenu(props: AccountMenuProps) {
|
|
89
95
|
const [local, rest] = splitProps(props, [
|
|
90
96
|
'class',
|
|
97
|
+
'placement',
|
|
98
|
+
'gutter',
|
|
99
|
+
'hideArrow',
|
|
91
100
|
'size',
|
|
92
101
|
'items',
|
|
93
102
|
'platform',
|
|
@@ -122,6 +131,8 @@ export function AccountMenu(props: AccountMenuProps) {
|
|
|
122
131
|
<Tooltip open={tooltipOpen()} onOpenChange={(open) => setTooltipOpen(open && !menuOpen())}>
|
|
123
132
|
<DropdownMenu
|
|
124
133
|
modal={false}
|
|
134
|
+
placement={local.placement ?? 'top-start'}
|
|
135
|
+
gutter={local.gutter}
|
|
125
136
|
onOpenChange={(open) => {
|
|
126
137
|
setMenuOpen(open)
|
|
127
138
|
if (open) setTooltipOpen(false)
|
|
@@ -142,7 +153,7 @@ export function AccountMenu(props: AccountMenuProps) {
|
|
|
142
153
|
</TooltipTrigger>
|
|
143
154
|
<TooltipContent placement="top">{local.label ?? 'Account and settings'}</TooltipContent>
|
|
144
155
|
<DropdownMenuContent
|
|
145
|
-
|
|
156
|
+
hideArrow={local.hideArrow}
|
|
146
157
|
class="min-w-56 max-h-(--kb-popper-available-height) overflow-x-hidden overflow-y-auto"
|
|
147
158
|
onCloseAutoFocus={(event) => {
|
|
148
159
|
const selection = pendingAfterClose
|