ruler-components 0.1.0 → 0.1.2
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/index.d.mts +51 -0
- package/dist/index.d.ts +51 -0
- package/dist/index.js +534 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +498 -0
- package/dist/index.mjs.map +1 -0
- package/package.json +21 -2
- package/AGENTS.md +0 -9
- package/CLAUDE.md +0 -1
- package/app/docs/[slug]/page.tsx +0 -147
- package/app/docs/layout.tsx +0 -26
- package/app/docs/page.tsx +0 -148
- package/app/favicon.ico +0 -0
- package/app/globals.css +0 -168
- package/app/icon.png +0 -0
- package/app/layout.tsx +0 -90
- package/app/opengraph-image.tsx +0 -10
- package/app/page.tsx +0 -34
- package/app/twitter-image.tsx +0 -10
- package/components/docs/accordion-doc-page.tsx +0 -352
- package/components/docs/alert-doc-page.tsx +0 -293
- package/components/docs/allinput-doc-page.tsx +0 -183
- package/components/docs/avatar-doc-page.tsx +0 -424
- package/components/docs/badge-doc-page.tsx +0 -363
- package/components/docs/button-doc-page.tsx +0 -406
- package/components/docs/card-doc-page.tsx +0 -364
- package/components/docs/checkbox-doc-page.tsx +0 -277
- package/components/docs/colors-doc-page.tsx +0 -430
- package/components/docs/dialog-doc-page.tsx +0 -364
- package/components/docs/docs-footer.tsx +0 -11
- package/components/docs/docs-mobile-menu-bar.tsx +0 -22
- package/components/docs/docs-mobile-nav-context.tsx +0 -27
- package/components/docs/docs-page.tsx +0 -263
- package/components/docs/docs-search.tsx +0 -303
- package/components/docs/docs-sidebar.tsx +0 -165
- package/components/docs/docs-topbar.tsx +0 -32
- package/components/docs/dropdown-doc-page.tsx +0 -522
- package/components/docs/getting-started-doc-page.tsx +0 -205
- package/components/docs/label-doc-page.tsx +0 -173
- package/components/docs/loaders-doc-page.tsx +0 -244
- package/components/docs/menu-doc-page.tsx +0 -373
- package/components/docs/modal-doc-page.tsx +0 -436
- package/components/docs/next-steps.tsx +0 -53
- package/components/docs/pagination-doc-page.tsx +0 -316
- package/components/docs/progress-doc-page.tsx +0 -387
- package/components/docs/radio-doc-page.tsx +0 -270
- package/components/docs/skeleton-doc-page.tsx +0 -230
- package/components/docs/stepper-doc-page.tsx +0 -309
- package/components/docs/switch-doc-page.tsx +0 -264
- package/components/docs/table-doc-page.tsx +0 -689
- package/components/docs/tabs-doc-page.tsx +0 -359
- package/components/docs/theming-doc-page.tsx +0 -243
- package/components/docs/tooltip-doc-page.tsx +0 -357
- package/components/docs/usage-section.tsx +0 -21
- package/components/icons/discord.tsx +0 -9
- package/components/icons/github.tsx +0 -9
- package/components/icons/x.tsx +0 -9
- package/components/installation-section.tsx +0 -34
- package/components/landing/feature-highlights.tsx +0 -105
- package/components/landing/footer-strip.tsx +0 -45
- package/components/landing/hero-card.tsx +0 -14
- package/components/landing/hero-spotlight.tsx +0 -126
- package/components/landing/hero.tsx +0 -64
- package/components/landing/navbar.tsx +0 -44
- package/components/landing/quick-start-section.tsx +0 -59
- package/components/landing/site-footer.tsx +0 -55
- package/components/theme-provider.tsx +0 -60
- package/components/ui/accordion.tsx +0 -174
- package/components/ui/alert.tsx +0 -103
- package/components/ui/allinput.tsx +0 -210
- package/components/ui/avatar.tsx +0 -179
- package/components/ui/badge.tsx +0 -52
- package/components/ui/button.tsx +0 -75
- package/components/ui/card.tsx +0 -105
- package/components/ui/checkbox.tsx +0 -130
- package/components/ui/code-block.tsx +0 -60
- package/components/ui/data-table.tsx +0 -235
- package/components/ui/dialog.tsx +0 -173
- package/components/ui/dropdown.tsx +0 -78
- package/components/ui/feature-card.tsx +0 -38
- package/components/ui/input.tsx +0 -44
- package/components/ui/label.tsx +0 -110
- package/components/ui/loaders.tsx +0 -139
- package/components/ui/menu.tsx +0 -118
- package/components/ui/modal.tsx +0 -399
- package/components/ui/package-manager-tabs.tsx +0 -40
- package/components/ui/pagination.tsx +0 -200
- package/components/ui/progress.tsx +0 -134
- package/components/ui/radio.tsx +0 -262
- package/components/ui/skeleton.tsx +0 -102
- package/components/ui/steppers.tsx +0 -309
- package/components/ui/switch.tsx +0 -153
- package/components/ui/table.tsx +0 -58
- package/components/ui/tabs.tsx +0 -166
- package/components/ui/theme-toggle.tsx +0 -60
- package/components/ui/tooltip.tsx +0 -238
- package/data/color-palette.ts +0 -35
- package/data/docs-nav.ts +0 -84
- package/eslint.config.mjs +0 -18
- package/index.ts +0 -8
- package/lib/cn.ts +0 -4
- package/lib/color.ts +0 -85
- package/lib/og-image.tsx +0 -138
- package/lib/theme.ts +0 -33
- package/next.config.ts +0 -7
- package/postcss.config.mjs +0 -7
- package/public/dark.png +0 -0
- package/public/dark1.png +0 -0
- package/public/dark2.png +0 -0
- package/public/file.svg +0 -1
- package/public/globe.svg +0 -1
- package/public/light.png +0 -0
- package/public/light1.png +0 -0
- package/public/next.svg +0 -1
- package/public/vercel.svg +0 -1
- package/public/video/hero-demo.mp4 +0 -0
- package/public/window.svg +0 -1
- package/tsconfig.json +0 -34
|
@@ -1,373 +0,0 @@
|
|
|
1
|
-
"use client";
|
|
2
|
-
|
|
3
|
-
import { useState } from "react";
|
|
4
|
-
import {
|
|
5
|
-
Check,
|
|
6
|
-
Copy,
|
|
7
|
-
Download,
|
|
8
|
-
FileText,
|
|
9
|
-
Folder,
|
|
10
|
-
LayoutDashboard,
|
|
11
|
-
LogOut,
|
|
12
|
-
Menu as MenuIcon,
|
|
13
|
-
Pencil,
|
|
14
|
-
Plus,
|
|
15
|
-
Settings,
|
|
16
|
-
Share2,
|
|
17
|
-
Star,
|
|
18
|
-
Trash2,
|
|
19
|
-
User,
|
|
20
|
-
Users,
|
|
21
|
-
} from "lucide-react";
|
|
22
|
-
import { Menu, MenuItem, MenuLabel, MenuDivider, type MenuProps } from "@/components/ui/menu";
|
|
23
|
-
import { Card, CardHeader, CardTitle, CardDescription, CardContent } from "@/components/ui/card";
|
|
24
|
-
import { Badge } from "@/components/ui/badge";
|
|
25
|
-
import { Tooltip } from "@/components/ui/tooltip";
|
|
26
|
-
import {
|
|
27
|
-
DocsAccessibility,
|
|
28
|
-
DocsApiSection,
|
|
29
|
-
DocsApiTable,
|
|
30
|
-
DocsPage,
|
|
31
|
-
DocsPageHeader,
|
|
32
|
-
DocsSection,
|
|
33
|
-
DocsSectionGrid,
|
|
34
|
-
} from "@/components/docs/docs-page";
|
|
35
|
-
import { cn } from "@/lib/cn";
|
|
36
|
-
|
|
37
|
-
const MENU_API_ROWS = [
|
|
38
|
-
{ prop: "variant", type: '"default" | "ghost"', default: '"default"', description: "Bordered surface or a transparent list" },
|
|
39
|
-
{ prop: "children", type: "ReactNode", default: "—", description: "MenuItem, MenuLabel, and MenuDivider elements" },
|
|
40
|
-
{ prop: "className", type: "string", default: "—", description: "Additional CSS classes" },
|
|
41
|
-
];
|
|
42
|
-
|
|
43
|
-
const ITEM_API_ROWS = [
|
|
44
|
-
{ prop: "label", type: "string", default: "—", description: "Row text" },
|
|
45
|
-
{ prop: "icon", type: "LucideIcon", default: "—", description: "Optional leading icon" },
|
|
46
|
-
{ prop: "shortcut", type: "string", default: "—", description: "Trailing keyboard shortcut hint, e.g. \"⌘K\"" },
|
|
47
|
-
{ prop: "selected", type: "boolean", default: "false", description: "Shows a trailing check mark" },
|
|
48
|
-
{ prop: "disabled", type: "boolean", default: "false", description: "Disables the item" },
|
|
49
|
-
{ prop: "onClick", type: "() => void", default: "—", description: "Called when the item is chosen" },
|
|
50
|
-
{ prop: "variant", type: '"default" | "destructive"', default: '"default"', description: "Red styling for irreversible actions like delete" },
|
|
51
|
-
];
|
|
52
|
-
|
|
53
|
-
const ACCESSIBILITY_ITEMS = [
|
|
54
|
-
"Menu carries role=\"menu\" and each MenuItem is a real <button> with role=\"menuitem\" — reachable and activatable via keyboard by default.",
|
|
55
|
-
"MenuDivider carries role=\"separator\" — it's structural, not another option.",
|
|
56
|
-
"Disabled items use the native disabled attribute, so they're skipped by screen readers and keyboard focus.",
|
|
57
|
-
"Pair the destructive item variant with an explicit label, like \"Delete\" rather than a bare icon.",
|
|
58
|
-
"Unlike Dropdown, Menu has no built-in open/close behavior — wire up your own trigger (a click, a right-click, a route) and unmount the Menu when it should close.",
|
|
59
|
-
];
|
|
60
|
-
|
|
61
|
-
type Variant = NonNullable<MenuProps["variant"]>;
|
|
62
|
-
|
|
63
|
-
const VARIANTS: { value: Variant; label: string }[] = [
|
|
64
|
-
{ value: "default", label: "Default" },
|
|
65
|
-
{ value: "ghost", label: "Ghost" },
|
|
66
|
-
];
|
|
67
|
-
|
|
68
|
-
function codeFor(variant: Variant, withIcons: boolean, withShortcuts: boolean, withDestructive: boolean) {
|
|
69
|
-
const props = variant !== "default" ? ` variant="${variant}"` : "";
|
|
70
|
-
const icon = (name: string) => (withIcons ? ` icon={${name}}` : "");
|
|
71
|
-
const shortcut = (key: string) => (withShortcuts ? ` shortcut="${key}"` : "");
|
|
72
|
-
const items = [
|
|
73
|
-
`<MenuItem label="Rename"${icon("Pencil")}${shortcut("⌘R")} />`,
|
|
74
|
-
`<MenuItem label="Duplicate"${icon("Copy")}${shortcut("⌘D")} />`,
|
|
75
|
-
`<MenuItem label="Share"${icon("Share2")} />`,
|
|
76
|
-
];
|
|
77
|
-
if (withDestructive) {
|
|
78
|
-
items.push("<MenuDivider />");
|
|
79
|
-
items.push(`<MenuItem label="Delete"${icon("Trash2")} variant="destructive" />`);
|
|
80
|
-
}
|
|
81
|
-
const body = items.join("\n ");
|
|
82
|
-
return `<Menu${props}>\n ${body}\n</Menu>`;
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
export function MenuDocPage() {
|
|
86
|
-
const [variant, setVariant] = useState<Variant>("default");
|
|
87
|
-
const [withIcons, setWithIcons] = useState(true);
|
|
88
|
-
const [withShortcuts, setWithShortcuts] = useState(true);
|
|
89
|
-
const [withDestructive, setWithDestructive] = useState(true);
|
|
90
|
-
const [copied, setCopied] = useState(false);
|
|
91
|
-
|
|
92
|
-
const [view, setView] = useState<"grid" | "list">("grid");
|
|
93
|
-
const [favorited, setFavorited] = useState(true);
|
|
94
|
-
|
|
95
|
-
const snippet = codeFor(variant, withIcons, withShortcuts, withDestructive);
|
|
96
|
-
|
|
97
|
-
function copySnippet() {
|
|
98
|
-
navigator.clipboard.writeText(snippet).catch(() => {});
|
|
99
|
-
setCopied(true);
|
|
100
|
-
setTimeout(() => setCopied(false), 1200);
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
return (
|
|
104
|
-
<DocsPage>
|
|
105
|
-
<DocsPageHeader
|
|
106
|
-
icon={MenuIcon}
|
|
107
|
-
title="Menu"
|
|
108
|
-
description="A standalone list of actions — the visual surface behind a context menu, command palette, or sidebar, rendered inline rather than anchored to a trigger."
|
|
109
|
-
/>
|
|
110
|
-
|
|
111
|
-
<DocsSection
|
|
112
|
-
first
|
|
113
|
-
title="Playground"
|
|
114
|
-
description="Build a menu and copy the exact markup — icons, shortcuts, and a destructive action, live."
|
|
115
|
-
>
|
|
116
|
-
<div className="overflow-hidden rounded-2xl border border-zinc-200 shadow-[0_2px_8px_rgba(0,0,0,0.04)] dark:border-zinc-800 dark:shadow-[0_2px_8px_rgba(0,0,0,0.2)]">
|
|
117
|
-
<div className="relative flex min-h-[16rem] items-center justify-center overflow-hidden bg-zinc-50 p-6 dark:bg-zinc-900/40">
|
|
118
|
-
<div
|
|
119
|
-
aria-hidden
|
|
120
|
-
className="pointer-events-none absolute inset-0 opacity-[0.4] dark:opacity-[0.15]"
|
|
121
|
-
style={{
|
|
122
|
-
backgroundImage:
|
|
123
|
-
"linear-gradient(to right, rgb(161 161 170 / 0.35) 1px, transparent 1px), linear-gradient(to bottom, rgb(161 161 170 / 0.35) 1px, transparent 1px)",
|
|
124
|
-
backgroundSize: "24px 24px",
|
|
125
|
-
}}
|
|
126
|
-
/>
|
|
127
|
-
<div
|
|
128
|
-
key={`${variant}-${withIcons}-${withShortcuts}-${withDestructive}`}
|
|
129
|
-
className="relative animate-[pagination-pop_0.2s_ease-out]"
|
|
130
|
-
>
|
|
131
|
-
<Menu variant={variant}>
|
|
132
|
-
<MenuItem
|
|
133
|
-
label="Rename"
|
|
134
|
-
icon={withIcons ? Pencil : undefined}
|
|
135
|
-
shortcut={withShortcuts ? "⌘R" : undefined}
|
|
136
|
-
/>
|
|
137
|
-
<MenuItem
|
|
138
|
-
label="Duplicate"
|
|
139
|
-
icon={withIcons ? Copy : undefined}
|
|
140
|
-
shortcut={withShortcuts ? "⌘D" : undefined}
|
|
141
|
-
/>
|
|
142
|
-
<MenuItem label="Share" icon={withIcons ? Share2 : undefined} />
|
|
143
|
-
{withDestructive && (
|
|
144
|
-
<>
|
|
145
|
-
<MenuDivider />
|
|
146
|
-
<MenuItem
|
|
147
|
-
label="Delete"
|
|
148
|
-
icon={withIcons ? Trash2 : undefined}
|
|
149
|
-
variant="destructive"
|
|
150
|
-
/>
|
|
151
|
-
</>
|
|
152
|
-
)}
|
|
153
|
-
</Menu>
|
|
154
|
-
</div>
|
|
155
|
-
</div>
|
|
156
|
-
|
|
157
|
-
<div className="flex flex-col gap-5 border-t border-zinc-200 p-5 dark:border-zinc-800">
|
|
158
|
-
<div className="flex flex-wrap items-start justify-between gap-6">
|
|
159
|
-
<div>
|
|
160
|
-
<p className="mb-2 text-xs font-medium uppercase tracking-wide text-zinc-400 dark:text-zinc-500">
|
|
161
|
-
Variant
|
|
162
|
-
</p>
|
|
163
|
-
<div className="flex flex-wrap items-center gap-1 rounded-lg border border-zinc-200 bg-zinc-50 p-1 dark:border-zinc-800 dark:bg-zinc-900/60">
|
|
164
|
-
{VARIANTS.map((v) => (
|
|
165
|
-
<button
|
|
166
|
-
key={v.value}
|
|
167
|
-
type="button"
|
|
168
|
-
onClick={() => setVariant(v.value)}
|
|
169
|
-
className={cn(
|
|
170
|
-
"rounded-md px-3 py-1.5 text-xs font-medium uppercase tracking-wide transition-colors",
|
|
171
|
-
variant === v.value
|
|
172
|
-
? "bg-white text-zinc-900 shadow-sm dark:bg-zinc-800 dark:text-white"
|
|
173
|
-
: "text-zinc-500 hover:text-zinc-800 dark:text-zinc-400 dark:hover:text-zinc-200"
|
|
174
|
-
)}
|
|
175
|
-
>
|
|
176
|
-
{v.label}
|
|
177
|
-
</button>
|
|
178
|
-
))}
|
|
179
|
-
</div>
|
|
180
|
-
</div>
|
|
181
|
-
|
|
182
|
-
<div>
|
|
183
|
-
<p className="mb-2 text-xs font-medium uppercase tracking-wide text-zinc-400 dark:text-zinc-500">
|
|
184
|
-
Icons
|
|
185
|
-
</p>
|
|
186
|
-
<button
|
|
187
|
-
type="button"
|
|
188
|
-
onClick={() => setWithIcons((v) => !v)}
|
|
189
|
-
className={cn(
|
|
190
|
-
"flex h-[2.125rem] items-center gap-2 rounded-lg border px-3 text-xs font-medium transition-colors",
|
|
191
|
-
withIcons
|
|
192
|
-
? "border-zinc-900 bg-zinc-900 text-white dark:border-white dark:bg-white dark:text-zinc-900"
|
|
193
|
-
: "border-zinc-200 text-zinc-500 hover:border-zinc-300 dark:border-zinc-700 dark:text-zinc-400"
|
|
194
|
-
)}
|
|
195
|
-
>
|
|
196
|
-
{withIcons ? "On" : "Off"}
|
|
197
|
-
</button>
|
|
198
|
-
</div>
|
|
199
|
-
|
|
200
|
-
<div>
|
|
201
|
-
<p className="mb-2 text-xs font-medium uppercase tracking-wide text-zinc-400 dark:text-zinc-500">
|
|
202
|
-
Shortcuts
|
|
203
|
-
</p>
|
|
204
|
-
<button
|
|
205
|
-
type="button"
|
|
206
|
-
onClick={() => setWithShortcuts((v) => !v)}
|
|
207
|
-
className={cn(
|
|
208
|
-
"flex h-[2.125rem] items-center gap-2 rounded-lg border px-3 text-xs font-medium transition-colors",
|
|
209
|
-
withShortcuts
|
|
210
|
-
? "border-zinc-900 bg-zinc-900 text-white dark:border-white dark:bg-white dark:text-zinc-900"
|
|
211
|
-
: "border-zinc-200 text-zinc-500 hover:border-zinc-300 dark:border-zinc-700 dark:text-zinc-400"
|
|
212
|
-
)}
|
|
213
|
-
>
|
|
214
|
-
{withShortcuts ? "On" : "Off"}
|
|
215
|
-
</button>
|
|
216
|
-
</div>
|
|
217
|
-
|
|
218
|
-
<div>
|
|
219
|
-
<p className="mb-2 text-xs font-medium uppercase tracking-wide text-zinc-400 dark:text-zinc-500">
|
|
220
|
-
Destructive item
|
|
221
|
-
</p>
|
|
222
|
-
<button
|
|
223
|
-
type="button"
|
|
224
|
-
onClick={() => setWithDestructive((v) => !v)}
|
|
225
|
-
className={cn(
|
|
226
|
-
"flex h-[2.125rem] items-center gap-2 rounded-lg border px-3 text-xs font-medium transition-colors",
|
|
227
|
-
withDestructive
|
|
228
|
-
? "border-zinc-900 bg-zinc-900 text-white dark:border-white dark:bg-white dark:text-zinc-900"
|
|
229
|
-
: "border-zinc-200 text-zinc-500 hover:border-zinc-300 dark:border-zinc-700 dark:text-zinc-400"
|
|
230
|
-
)}
|
|
231
|
-
>
|
|
232
|
-
{withDestructive ? "On" : "Off"}
|
|
233
|
-
</button>
|
|
234
|
-
</div>
|
|
235
|
-
</div>
|
|
236
|
-
|
|
237
|
-
<div className="flex items-center justify-between gap-3 rounded-xl bg-zinc-900 px-4 py-3 dark:bg-black">
|
|
238
|
-
<pre className="overflow-x-auto font-mono text-[13px] leading-relaxed text-zinc-100">
|
|
239
|
-
<code>{snippet}</code>
|
|
240
|
-
</pre>
|
|
241
|
-
<Tooltip content={copied ? "Copied!" : "Copy code"}>
|
|
242
|
-
<button
|
|
243
|
-
type="button"
|
|
244
|
-
onClick={copySnippet}
|
|
245
|
-
className="flex h-8 w-8 shrink-0 items-center justify-center rounded-lg text-zinc-400 transition-colors hover:bg-white/10 hover:text-white"
|
|
246
|
-
>
|
|
247
|
-
{copied ? <Check className="h-4 w-4 text-emerald-400" /> : <Copy className="h-4 w-4" />}
|
|
248
|
-
</button>
|
|
249
|
-
</Tooltip>
|
|
250
|
-
</div>
|
|
251
|
-
</div>
|
|
252
|
-
</div>
|
|
253
|
-
</DocsSection>
|
|
254
|
-
|
|
255
|
-
<DocsSection
|
|
256
|
-
title="Menu vs. Dropdown"
|
|
257
|
-
description="Menu is the list itself — Dropdown wraps it with a trigger, positioning, and open/close behavior."
|
|
258
|
-
>
|
|
259
|
-
<div className="grid gap-3 sm:grid-cols-2">
|
|
260
|
-
<div className="rounded-xl border border-zinc-200 bg-white p-4 dark:border-zinc-800 dark:bg-zinc-950">
|
|
261
|
-
<p className="text-sm font-semibold text-zinc-900 dark:text-white">Use Menu when</p>
|
|
262
|
-
<p className="mt-1.5 text-xs leading-relaxed text-zinc-500 dark:text-zinc-400">
|
|
263
|
-
The list is always visible — a sidebar, a right-click context menu you position yourself, or the
|
|
264
|
-
options pane inside a command palette.
|
|
265
|
-
</p>
|
|
266
|
-
</div>
|
|
267
|
-
<div className="rounded-xl border border-zinc-200 bg-white p-4 dark:border-zinc-800 dark:bg-zinc-950">
|
|
268
|
-
<p className="text-sm font-semibold text-zinc-900 dark:text-white">Use Dropdown when</p>
|
|
269
|
-
<p className="mt-1.5 text-xs leading-relaxed text-zinc-500 dark:text-zinc-400">
|
|
270
|
-
You need a button that opens/closes a floating panel — an account menu, a select, a filter. Dropdown
|
|
271
|
-
is built on the same item styling as Menu.
|
|
272
|
-
</p>
|
|
273
|
-
</div>
|
|
274
|
-
</div>
|
|
275
|
-
</DocsSection>
|
|
276
|
-
|
|
277
|
-
<DocsSection title="In context" description="Menu rarely stands alone — here's how it reads inside real UI.">
|
|
278
|
-
<DocsSectionGrid className="lg:grid-cols-[1fr_1.1fr]">
|
|
279
|
-
<Card>
|
|
280
|
-
<CardHeader>
|
|
281
|
-
<div className="flex items-center justify-between gap-3">
|
|
282
|
-
<div>
|
|
283
|
-
<CardTitle>Right-click menu</CardTitle>
|
|
284
|
-
<CardDescription>Positioned by the caller at the click coordinates.</CardDescription>
|
|
285
|
-
</div>
|
|
286
|
-
<Badge variant="outline">Context menu</Badge>
|
|
287
|
-
</div>
|
|
288
|
-
</CardHeader>
|
|
289
|
-
<CardContent>
|
|
290
|
-
<div className="flex flex-col gap-3">
|
|
291
|
-
<div
|
|
292
|
-
className="flex h-24 items-center justify-center rounded-lg border border-dashed border-zinc-300 text-xs text-zinc-400 dark:border-zinc-700 dark:text-zinc-600"
|
|
293
|
-
onContextMenu={(e) => e.preventDefault()}
|
|
294
|
-
>
|
|
295
|
-
Right-click target (menu shown below for reference)
|
|
296
|
-
</div>
|
|
297
|
-
<Menu className="w-48">
|
|
298
|
-
<MenuItem label="Cut" shortcut="⌘X" />
|
|
299
|
-
<MenuItem label="Copy" shortcut="⌘C" />
|
|
300
|
-
<MenuItem label="Paste" shortcut="⌘V" />
|
|
301
|
-
<MenuDivider />
|
|
302
|
-
<MenuItem label="Inspect" icon={FileText} />
|
|
303
|
-
</Menu>
|
|
304
|
-
</div>
|
|
305
|
-
</CardContent>
|
|
306
|
-
</Card>
|
|
307
|
-
|
|
308
|
-
<Card>
|
|
309
|
-
<CardHeader>
|
|
310
|
-
<div className="flex items-center gap-3">
|
|
311
|
-
<div className="flex h-10 w-10 items-center justify-center rounded-xl bg-zinc-100 dark:bg-zinc-800">
|
|
312
|
-
<LayoutDashboard className="h-5 w-5 text-zinc-600 dark:text-zinc-300" />
|
|
313
|
-
</div>
|
|
314
|
-
<div>
|
|
315
|
-
<CardTitle>Sidebar navigation</CardTitle>
|
|
316
|
-
<CardDescription>Grouped, always-visible — no open/close state needed.</CardDescription>
|
|
317
|
-
</div>
|
|
318
|
-
</div>
|
|
319
|
-
</CardHeader>
|
|
320
|
-
<CardContent>
|
|
321
|
-
<Menu variant="ghost" className="w-full">
|
|
322
|
-
<MenuLabel>Workspace</MenuLabel>
|
|
323
|
-
<MenuItem label="Dashboard" icon={LayoutDashboard} selected />
|
|
324
|
-
<MenuItem label="Projects" icon={Folder} />
|
|
325
|
-
<MenuItem label="Team" icon={Users} />
|
|
326
|
-
<MenuDivider />
|
|
327
|
-
<MenuLabel>Account</MenuLabel>
|
|
328
|
-
<MenuItem label="Profile" icon={User} />
|
|
329
|
-
<MenuItem label="Settings" icon={Settings} />
|
|
330
|
-
<MenuItem label="Log out" icon={LogOut} variant="destructive" />
|
|
331
|
-
</Menu>
|
|
332
|
-
</CardContent>
|
|
333
|
-
</Card>
|
|
334
|
-
</DocsSectionGrid>
|
|
335
|
-
</DocsSection>
|
|
336
|
-
|
|
337
|
-
<DocsSection
|
|
338
|
-
title="Command palette"
|
|
339
|
-
description="Grouped, keyboard-first actions — the pattern behind ⌘K launchers."
|
|
340
|
-
>
|
|
341
|
-
<Card className="max-w-lg">
|
|
342
|
-
<CardContent className="pt-6">
|
|
343
|
-
<div className="mb-1 flex items-center gap-2 rounded-lg border border-zinc-200 bg-zinc-50 px-3 py-2 dark:border-zinc-800 dark:bg-zinc-900">
|
|
344
|
-
<span className="text-sm text-zinc-400">Type a command or search...</span>
|
|
345
|
-
</div>
|
|
346
|
-
<Menu variant="ghost" className="w-full">
|
|
347
|
-
<MenuLabel>Suggestions</MenuLabel>
|
|
348
|
-
<MenuItem label="New file" icon={Plus} shortcut="⌘N" />
|
|
349
|
-
<MenuItem label="Export as PDF" icon={Download} shortcut="⌘E" />
|
|
350
|
-
<MenuDivider />
|
|
351
|
-
<MenuLabel>Actions</MenuLabel>
|
|
352
|
-
<MenuItem
|
|
353
|
-
label={favorited ? "Remove from favorites" : "Add to favorites"}
|
|
354
|
-
icon={Star}
|
|
355
|
-
onClick={() => setFavorited((v) => !v)}
|
|
356
|
-
/>
|
|
357
|
-
<MenuItem
|
|
358
|
-
label={`View as ${view === "grid" ? "list" : "grid"}`}
|
|
359
|
-
onClick={() => setView((v) => (v === "grid" ? "list" : "grid"))}
|
|
360
|
-
/>
|
|
361
|
-
</Menu>
|
|
362
|
-
</CardContent>
|
|
363
|
-
</Card>
|
|
364
|
-
</DocsSection>
|
|
365
|
-
|
|
366
|
-
<DocsApiSection>
|
|
367
|
-
<DocsApiTable title="API Reference — Menu" rows={MENU_API_ROWS} />
|
|
368
|
-
<DocsApiTable title="API Reference — MenuItem" rows={ITEM_API_ROWS} />
|
|
369
|
-
<DocsAccessibility items={ACCESSIBILITY_ITEMS} />
|
|
370
|
-
</DocsApiSection>
|
|
371
|
-
</DocsPage>
|
|
372
|
-
);
|
|
373
|
-
}
|