macOS Magnify Dock
A floating icon dock whose items swell under the pointer, the neighbours lifting less than the one you are on.
6 个框架高级
A launcher button that opens a grid popover of app links, closable with Escape.
<!--
A launcher button that opens a grid of app links. The trigger owns
aria-haspopup, aria-expanded and aria-controls; the grid is role="menu" with
role="menuitem" links. Shown here OPEN - the React/TypeScript variants wire
the toggle and close on Escape. The popover is max-w-[calc(100vw-2rem)] so it
never runs off a 320px screen.
-->
<div class="fixed bottom-6 left-1/2 -translate-x-1/2">
<div id="app-grid" role="menu" aria-label="Applications" class="absolute bottom-[calc(100%+0.5rem)] left-1/2 w-60 max-w-[calc(100vw-2rem)] -translate-x-1/2 rounded-2xl border border-black/10 bg-white/90 p-2 shadow-[0_16px_40px_-12px_rgba(0,0,0,0.45)] backdrop-blur-md dark:border-white/10 dark:bg-gray-900/90">
<ul class="grid grid-cols-3 gap-1">
<li>
<a href="/mail" role="menuitem" class="flex min-h-[4rem] flex-col items-center justify-center gap-1 rounded-xl p-2 text-gray-700 hover:bg-black/5 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-blue-600 dark:text-gray-200 dark:hover:bg-white/10 dark:focus-visible:ring-blue-400">
<svg class="h-6 w-6" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><path d="M3 7l9 6 9-6M5 5h14a2 2 0 0 1 2 2v10a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V7a2 2 0 0 1 2-2Z" /></svg>
<span class="text-[0.6875rem] font-medium leading-none">Mail</span>
</a>
</li>
<li>
<a href="/calendar" role="menuitem" class="flex min-h-[4rem] flex-col items-center justify-center gap-1 rounded-xl p-2 text-gray-700 hover:bg-black/5 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-blue-600 dark:text-gray-200 dark:hover:bg-white/10 dark:focus-visible:ring-blue-400">
<svg class="h-6 w-6" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><path d="M5 5h14a2 2 0 0 1 2 2v12a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V7a2 2 0 0 1 2-2ZM3 10h18M8 3v4M16 3v4" /></svg>
<span class="text-[0.6875rem] font-medium leading-none">Calendar</span>
</a>
</li>
<li>
<a href="/photos" role="menuitem" class="flex min-h-[4rem] flex-col items-center justify-center gap-1 rounded-xl p-2 text-gray-700 hover:bg-black/5 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-blue-600 dark:text-gray-200 dark:hover:bg-white/10 dark:focus-visible:ring-blue-400">
<svg class="h-6 w-6" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><path d="M5 4h14a2 2 0 0 1 2 2v12a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2Zm-1 13 5-5 4 4 3-2 4 4" /></svg>
<span class="text-[0.6875rem] font-medium leading-none">Photos</span>
</a>
</li>
</ul>
</div>
<div class="rounded-2xl border border-black/10 bg-white/85 p-2 shadow-[0_12px_32px_-12px_rgba(0,0,0,0.4)] backdrop-blur-md dark:border-white/10 dark:bg-gray-900/85">
<button type="button" aria-label="Applications" aria-haspopup="menu" aria-expanded="true" aria-controls="app-grid" class="flex h-11 w-11 items-center justify-center rounded-xl text-gray-700 hover:bg-black/5 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-blue-600 aria-expanded:bg-blue-100 aria-expanded:text-blue-700 dark:text-gray-200 dark:hover:bg-white/10 dark:focus-visible:ring-blue-400 dark:aria-expanded:bg-blue-900 dark:aria-expanded:text-blue-200">
<svg class="h-6 w-6" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><path d="M4 5h5v5H4zM15 5h5v5h-5zM4 15h5v5H4zM15 15h5v5h-5z" /></svg>
</button>
</div>
</div>| Prop | 类型 | 默认值 | 说明 |
|---|---|---|---|
apps | readonly LauncherApp[] | DEFAULT_APPS | 要渲染的项目数组。 |
onSelect | (id: string) => void | - | 用户选择菜单项时触发,参数为所选项。 |
ariaLabel | string | 'Applications' | 按钮的无障碍名称。仅有图标的按钮必须设置。 |
className | string | - | 合并到根元素上的额外类名。 |
The trigger owns `aria-haspopup`, `aria-expanded` and `aria-controls`; the grid is a `menu` of `menuitem` links. Escape closes it and returns focus to the trigger, so the popover is never a keyboard trap. The grid is `max-w-[calc(100vw-2rem)]` so it never runs off a 320px screen.