@neynar/ui 0.1.1 → 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/components/ui/accordion.d.ts +1 -25
- package/dist/components/ui/accordion.d.ts.map +1 -1
- package/dist/components/ui/alert-dialog.d.ts +240 -46
- package/dist/components/ui/alert-dialog.d.ts.map +1 -1
- package/dist/components/ui/alert.d.ts +73 -11
- package/dist/components/ui/alert.d.ts.map +1 -1
- package/dist/components/ui/aspect-ratio.d.ts +44 -10
- package/dist/components/ui/aspect-ratio.d.ts.map +1 -1
- package/dist/components/ui/avatar.d.ts +117 -33
- package/dist/components/ui/avatar.d.ts.map +1 -1
- package/dist/components/ui/badge.d.ts +50 -71
- package/dist/components/ui/badge.d.ts.map +1 -1
- package/dist/components/ui/breadcrumb.d.ts +231 -49
- package/dist/components/ui/breadcrumb.d.ts.map +1 -1
- package/dist/components/ui/button.d.ts +189 -71
- package/dist/components/ui/button.d.ts.map +1 -1
- package/dist/components/ui/calendar.d.ts +197 -40
- package/dist/components/ui/calendar.d.ts.map +1 -1
- package/dist/components/ui/card.d.ts +7 -22
- package/dist/components/ui/card.d.ts.map +1 -1
- package/dist/components/ui/carousel.d.ts +369 -99
- package/dist/components/ui/carousel.d.ts.map +1 -1
- package/dist/components/ui/chart.d.ts.map +1 -1
- package/dist/components/ui/checkbox.d.ts +110 -38
- package/dist/components/ui/checkbox.d.ts.map +1 -1
- package/dist/components/ui/collapsible.d.ts +246 -61
- package/dist/components/ui/collapsible.d.ts.map +1 -1
- package/dist/components/ui/combobox.d.ts +207 -159
- package/dist/components/ui/combobox.d.ts.map +1 -1
- package/dist/components/ui/command.d.ts +336 -67
- package/dist/components/ui/command.d.ts.map +1 -1
- package/dist/components/ui/container.d.ts +159 -64
- package/dist/components/ui/container.d.ts.map +1 -1
- package/dist/components/ui/context-menu.d.ts +321 -39
- package/dist/components/ui/context-menu.d.ts.map +1 -1
- package/dist/components/ui/date-picker.d.ts +113 -86
- package/dist/components/ui/date-picker.d.ts.map +1 -1
- package/dist/components/ui/dialog.d.ts +106 -25
- package/dist/components/ui/dialog.d.ts.map +1 -1
- package/dist/components/ui/drawer.d.ts +388 -59
- package/dist/components/ui/drawer.d.ts.map +1 -1
- package/dist/components/ui/dropdown-menu.d.ts +521 -74
- package/dist/components/ui/dropdown-menu.d.ts.map +1 -1
- package/dist/components/ui/empty-state.d.ts +148 -76
- package/dist/components/ui/empty-state.d.ts.map +1 -1
- package/dist/components/ui/hover-card.d.ts +253 -34
- package/dist/components/ui/hover-card.d.ts.map +1 -1
- package/dist/components/ui/input.d.ts +143 -44
- package/dist/components/ui/input.d.ts.map +1 -1
- package/dist/components/ui/label.d.ts +0 -8
- package/dist/components/ui/label.d.ts.map +1 -1
- package/dist/components/ui/menubar.d.ts +288 -46
- package/dist/components/ui/menubar.d.ts.map +1 -1
- package/dist/components/ui/navigation-menu.d.ts +444 -127
- package/dist/components/ui/navigation-menu.d.ts.map +1 -1
- package/dist/components/ui/pagination.d.ts +342 -66
- package/dist/components/ui/pagination.d.ts.map +1 -1
- package/dist/components/ui/popover.d.ts +0 -8
- package/dist/components/ui/popover.d.ts.map +1 -1
- package/dist/components/ui/progress.d.ts +88 -30
- package/dist/components/ui/progress.d.ts.map +1 -1
- package/dist/components/ui/radio-group.d.ts +189 -45
- package/dist/components/ui/radio-group.d.ts.map +1 -1
- package/dist/components/ui/resizable.d.ts +178 -62
- package/dist/components/ui/resizable.d.ts.map +1 -1
- package/dist/components/ui/scroll-area.d.ts +180 -21
- package/dist/components/ui/scroll-area.d.ts.map +1 -1
- package/dist/components/ui/select.d.ts +382 -60
- package/dist/components/ui/select.d.ts.map +1 -1
- package/dist/components/ui/separator.d.ts +52 -39
- package/dist/components/ui/separator.d.ts.map +1 -1
- package/dist/components/ui/sheet.d.ts +144 -27
- package/dist/components/ui/sheet.d.ts.map +1 -1
- package/dist/components/ui/sidebar.d.ts +81 -31
- package/dist/components/ui/sidebar.d.ts.map +1 -1
- package/dist/components/ui/skeleton.d.ts +94 -32
- package/dist/components/ui/skeleton.d.ts.map +1 -1
- package/dist/components/ui/slider.d.ts +37 -31
- package/dist/components/ui/slider.d.ts.map +1 -1
- package/dist/components/ui/sonner.d.ts +280 -46
- package/dist/components/ui/sonner.d.ts.map +1 -1
- package/dist/components/ui/stack.d.ts +289 -148
- package/dist/components/ui/stack.d.ts.map +1 -1
- package/dist/components/ui/stories/aspect-ratio.stories.d.ts +1 -2
- package/dist/components/ui/stories/aspect-ratio.stories.d.ts.map +1 -1
- package/dist/components/ui/stories/container.stories.d.ts +2 -3
- package/dist/components/ui/stories/container.stories.d.ts.map +1 -1
- package/dist/components/ui/stories/empty-state.stories.d.ts +2 -2
- package/dist/components/ui/stories/scroll-area.stories.d.ts +1 -2
- package/dist/components/ui/stories/scroll-area.stories.d.ts.map +1 -1
- package/dist/components/ui/stories/stack.stories.d.ts +1 -1
- package/dist/components/ui/stories/text-field.stories.d.ts +7 -1
- package/dist/components/ui/stories/text-field.stories.d.ts.map +1 -1
- package/dist/components/ui/switch.d.ts +44 -38
- package/dist/components/ui/switch.d.ts.map +1 -1
- package/dist/components/ui/table.d.ts +33 -0
- package/dist/components/ui/table.d.ts.map +1 -1
- package/dist/components/ui/tabs.d.ts +4 -22
- package/dist/components/ui/tabs.d.ts.map +1 -1
- package/dist/components/ui/text-field.d.ts +170 -84
- package/dist/components/ui/text-field.d.ts.map +1 -1
- package/dist/components/ui/textarea.d.ts +106 -29
- package/dist/components/ui/textarea.d.ts.map +1 -1
- package/dist/components/ui/theme-toggle.d.ts +190 -65
- package/dist/components/ui/theme-toggle.d.ts.map +1 -1
- package/dist/components/ui/theme.d.ts +107 -23
- package/dist/components/ui/theme.d.ts.map +1 -1
- package/dist/components/ui/toggle-group.d.ts +143 -67
- package/dist/components/ui/toggle-group.d.ts.map +1 -1
- package/dist/components/ui/toggle.d.ts +118 -30
- package/dist/components/ui/toggle.d.ts.map +1 -1
- package/dist/components/ui/tooltip.d.ts +152 -28
- package/dist/components/ui/tooltip.d.ts.map +1 -1
- package/dist/components/ui/typography.d.ts +452 -134
- package/dist/components/ui/typography.d.ts.map +1 -1
- package/dist/index.js +9388 -8281
- package/dist/index.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/llms.txt +173 -3
- package/package.json +5 -2
- package/src/components/ui/accordion.tsx +112 -27
- package/src/components/ui/alert-dialog.tsx +401 -46
- package/src/components/ui/alert.tsx +114 -11
- package/src/components/ui/aspect-ratio.tsx +69 -14
- package/src/components/ui/avatar.tsx +179 -33
- package/src/components/ui/badge.tsx +74 -75
- package/src/components/ui/breadcrumb.tsx +335 -50
- package/src/components/ui/button.tsx +198 -90
- package/src/components/ui/calendar.tsx +867 -43
- package/src/components/ui/card.tsx +140 -33
- package/src/components/ui/carousel.tsx +529 -98
- package/src/components/ui/chart.tsx +222 -1
- package/src/components/ui/checkbox.tsx +176 -38
- package/src/components/ui/collapsible.tsx +321 -67
- package/src/components/ui/combobox.tsx +284 -83
- package/src/components/ui/command.tsx +527 -67
- package/src/components/ui/container.tsx +217 -65
- package/src/components/ui/context-menu.tsx +716 -51
- package/src/components/ui/date-picker.tsx +228 -38
- package/src/components/ui/dialog.tsx +270 -33
- package/src/components/ui/drawer.tsx +546 -67
- package/src/components/ui/dropdown-menu.tsx +657 -74
- package/src/components/ui/empty-state.tsx +241 -82
- package/src/components/ui/hover-card.tsx +328 -39
- package/src/components/ui/input.tsx +207 -44
- package/src/components/ui/label.tsx +98 -8
- package/src/components/ui/menubar.tsx +587 -54
- package/src/components/ui/navigation-menu.tsx +557 -128
- package/src/components/ui/pagination.tsx +561 -79
- package/src/components/ui/popover.tsx +119 -8
- package/src/components/ui/progress.tsx +131 -29
- package/src/components/ui/radio-group.tsx +260 -51
- package/src/components/ui/resizable.tsx +289 -63
- package/src/components/ui/scroll-area.tsx +377 -66
- package/src/components/ui/select.tsx +545 -60
- package/src/components/ui/separator.tsx +146 -40
- package/src/components/ui/sheet.tsx +348 -31
- package/src/components/ui/sidebar.tsx +471 -29
- package/src/components/ui/skeleton.tsx +114 -32
- package/src/components/ui/slider.tsx +77 -31
- package/src/components/ui/sonner.tsx +574 -46
- package/src/components/ui/stack.tsx +423 -101
- package/src/components/ui/switch.tsx +78 -39
- package/src/components/ui/table.tsx +170 -4
- package/src/components/ui/tabs.tsx +108 -22
- package/src/components/ui/text-field.tsx +226 -81
- package/src/components/ui/textarea.tsx +180 -29
- package/src/components/ui/theme-toggle.tsx +313 -65
- package/src/components/ui/theme.tsx +117 -23
- package/src/components/ui/toggle-group.tsx +280 -69
- package/src/components/ui/toggle.tsx +124 -35
- package/src/components/ui/tooltip.tsx +239 -29
- package/src/components/ui/typography.tsx +1115 -165
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as React from "react";
|
|
2
|
-
import { Command as CommandPrimitive } from "cmdk";
|
|
2
|
+
import { Command as CommandPrimitive, useCommandState } from "cmdk";
|
|
3
3
|
import { SearchIcon } from "lucide-react";
|
|
4
4
|
|
|
5
5
|
import { cn } from "@/lib/utils";
|
|
@@ -11,6 +11,186 @@ import {
|
|
|
11
11
|
DialogTitle,
|
|
12
12
|
} from "@/components/ui/dialog";
|
|
13
13
|
|
|
14
|
+
// ============================================================================
|
|
15
|
+
// CMDK HOOK EXPORTS
|
|
16
|
+
// ============================================================================
|
|
17
|
+
|
|
18
|
+
// useCommandState is now imported directly from 'cmdk' and available for use
|
|
19
|
+
|
|
20
|
+
// ============================================================================
|
|
21
|
+
// DOCUMENTATION-ONLY PROP TYPES (Internal - not exported)
|
|
22
|
+
// ============================================================================
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Props for Command component (Documentation only - NOT used in component implementation)
|
|
26
|
+
* These types are for documentation generation and should not replace CMDK inferred types
|
|
27
|
+
*/
|
|
28
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
29
|
+
type CommandDocsProps = {
|
|
30
|
+
/** Accessibility label for the command menu - helps identify the menu purpose for screen readers */
|
|
31
|
+
label?: string;
|
|
32
|
+
/** Whether to filter and sort items automatically based on search input @default true */
|
|
33
|
+
shouldFilter?: boolean;
|
|
34
|
+
/** Custom filter function for ranking items based on search relevance - return 0 to hide, 1+ to show and rank */
|
|
35
|
+
filter?: (value: string, search: string, keywords?: string[]) => number;
|
|
36
|
+
/** Current selected item value for controlled usage - useful for managing selection state externally */
|
|
37
|
+
value?: string;
|
|
38
|
+
/** Callback fired when the selected item changes - receives the new selected value */
|
|
39
|
+
onValueChange?: (value: string) => void;
|
|
40
|
+
/** Whether to enable circular navigation with arrow keys through all items @default false */
|
|
41
|
+
loop?: boolean;
|
|
42
|
+
/** Whether to disable mouse/pointer selection and only allow keyboard navigation @default true */
|
|
43
|
+
disablePointerSelection?: boolean;
|
|
44
|
+
/** Whether to enable Vim-style keybindings for navigation (j/k for up/down) @default false */
|
|
45
|
+
vimBindings?: boolean;
|
|
46
|
+
/** Additional CSS classes for styling customization */
|
|
47
|
+
className?: string;
|
|
48
|
+
/** Child components - typically CommandInput, CommandList with CommandItems */
|
|
49
|
+
children?: React.ReactNode;
|
|
50
|
+
} & React.HTMLAttributes<HTMLDivElement>;
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Props for CommandDialog component (Documentation only - NOT used in component implementation)
|
|
54
|
+
* These types are for documentation generation and should not replace Dialog + Command inferred types
|
|
55
|
+
*/
|
|
56
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
57
|
+
type CommandDialogDocsProps = {
|
|
58
|
+
/** Whether the dialog is open - controls visibility state */
|
|
59
|
+
open?: boolean;
|
|
60
|
+
/** Callback when dialog open state changes - useful for managing dialog state */
|
|
61
|
+
onOpenChange?: (open: boolean) => void;
|
|
62
|
+
/** The title announced to screen readers for accessibility @default "Command Palette" */
|
|
63
|
+
title?: string;
|
|
64
|
+
/** The description announced to screen readers explaining dialog purpose @default "Search for a command to run..." */
|
|
65
|
+
description?: string;
|
|
66
|
+
/** Whether to show the X close button in the dialog header @default true */
|
|
67
|
+
showCloseButton?: boolean;
|
|
68
|
+
/** Portal container element for rendering the dialog - allows custom positioning */
|
|
69
|
+
container?: HTMLElement | null;
|
|
70
|
+
/** Additional CSS classes for dialog content styling */
|
|
71
|
+
className?: string;
|
|
72
|
+
/** Child components - typically Command with CommandInput and CommandList */
|
|
73
|
+
children?: React.ReactNode;
|
|
74
|
+
};
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* Props for CommandInput component (Documentation only - NOT used in component implementation)
|
|
78
|
+
* These types are for documentation generation and should not replace CMDK inferred types
|
|
79
|
+
*/
|
|
80
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
81
|
+
type CommandInputDocsProps = {
|
|
82
|
+
/** Current search input value for controlled input behavior */
|
|
83
|
+
value?: string;
|
|
84
|
+
/** Callback fired when input value changes during typing - receives the new search string */
|
|
85
|
+
onValueChange?: (search: string) => void;
|
|
86
|
+
/** Placeholder text displayed when input is empty - helps users understand purpose */
|
|
87
|
+
placeholder?: string;
|
|
88
|
+
/** Whether the input is disabled and cannot receive focus @default false */
|
|
89
|
+
disabled?: boolean;
|
|
90
|
+
/** Whether to automatically focus the input when rendered @default false */
|
|
91
|
+
autoFocus?: boolean;
|
|
92
|
+
/** Additional CSS classes for input styling */
|
|
93
|
+
className?: string;
|
|
94
|
+
} & Omit<React.InputHTMLAttributes<HTMLInputElement>, "value" | "onChange">;
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* Props for CommandList component (Documentation only - NOT used in component implementation)
|
|
98
|
+
* These types are for documentation generation and should not replace CMDK inferred types
|
|
99
|
+
*/
|
|
100
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
101
|
+
type CommandListDocsProps = {
|
|
102
|
+
/** Additional CSS classes for list container styling - useful for height and scroll behavior */
|
|
103
|
+
className?: string;
|
|
104
|
+
/** Child components - typically CommandEmpty, CommandGroup, and CommandItem components */
|
|
105
|
+
children?: React.ReactNode;
|
|
106
|
+
} & Omit<React.HTMLAttributes<HTMLDivElement>, "role">;
|
|
107
|
+
|
|
108
|
+
/**
|
|
109
|
+
* Props for CommandEmpty component (Documentation only - NOT used in component implementation)
|
|
110
|
+
* These types are for documentation generation and should not replace CMDK inferred types
|
|
111
|
+
*/
|
|
112
|
+
type CommandEmptyDocsProps = {
|
|
113
|
+
/** Additional CSS classes for empty state styling */
|
|
114
|
+
className?: string;
|
|
115
|
+
/** Content to display when no items match the search - can be text or custom components */
|
|
116
|
+
children?: React.ReactNode;
|
|
117
|
+
} & React.HTMLAttributes<HTMLDivElement>;
|
|
118
|
+
|
|
119
|
+
/**
|
|
120
|
+
* Props for CommandGroup component (Documentation only - NOT used in component implementation)
|
|
121
|
+
* These types are for documentation generation and should not replace CMDK inferred types
|
|
122
|
+
*/
|
|
123
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
124
|
+
type CommandGroupDocsProps = {
|
|
125
|
+
/** The group heading displayed above items - can be text or a React component */
|
|
126
|
+
heading?: React.ReactNode;
|
|
127
|
+
/** Group value identifier for programmatic control and filtering */
|
|
128
|
+
value?: string;
|
|
129
|
+
/** Whether to always render the group even when all items are filtered out @default false */
|
|
130
|
+
forceMount?: boolean;
|
|
131
|
+
/** Additional CSS classes for group styling */
|
|
132
|
+
className?: string;
|
|
133
|
+
/** Child components - typically CommandItem components */
|
|
134
|
+
children?: React.ReactNode;
|
|
135
|
+
} & Omit<React.HTMLAttributes<HTMLDivElement>, "role">;
|
|
136
|
+
|
|
137
|
+
/**
|
|
138
|
+
* Props for CommandSeparator component (Documentation only - NOT used in component implementation)
|
|
139
|
+
* These types are for documentation generation and should not replace CMDK inferred types
|
|
140
|
+
*/
|
|
141
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
142
|
+
type CommandSeparatorDocsProps = {
|
|
143
|
+
/** Whether to always render the separator regardless of surrounding content visibility @default false */
|
|
144
|
+
alwaysRender?: boolean;
|
|
145
|
+
/** Additional CSS classes for separator styling */
|
|
146
|
+
className?: string;
|
|
147
|
+
} & React.HTMLAttributes<HTMLDivElement>;
|
|
148
|
+
|
|
149
|
+
/**
|
|
150
|
+
* Props for CommandItem component (Documentation only - NOT used in component implementation)
|
|
151
|
+
* These types are for documentation generation and should not replace CMDK inferred types
|
|
152
|
+
*/
|
|
153
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
154
|
+
type CommandItemDocsProps = {
|
|
155
|
+
/** Unique item value used for filtering and selection - defaults to text content if not provided */
|
|
156
|
+
value?: string;
|
|
157
|
+
/** Additional keywords for improved search matching without affecting display */
|
|
158
|
+
keywords?: string[];
|
|
159
|
+
/** Whether the item is disabled and cannot be selected @default false */
|
|
160
|
+
disabled?: boolean;
|
|
161
|
+
/** Callback fired when item is selected via Enter key or mouse click - receives the item value */
|
|
162
|
+
onSelect?: (value: string) => void;
|
|
163
|
+
/** Whether to always render the item even when it doesn't match the search filter @default false */
|
|
164
|
+
forceMount?: boolean;
|
|
165
|
+
/** Additional CSS classes for item styling */
|
|
166
|
+
className?: string;
|
|
167
|
+
/** Child content - typically text, icons, and CommandShortcut components */
|
|
168
|
+
children?: React.ReactNode;
|
|
169
|
+
} & Omit<React.HTMLAttributes<HTMLDivElement>, "onSelect">;
|
|
170
|
+
|
|
171
|
+
/**
|
|
172
|
+
* Props for CommandShortcut component (Documentation only - NOT used in component implementation)
|
|
173
|
+
* These types are for documentation generation and should not replace standard span props
|
|
174
|
+
*/
|
|
175
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
176
|
+
type CommandShortcutDocsProps = {
|
|
177
|
+
/** Additional CSS classes for shortcut styling */
|
|
178
|
+
className?: string;
|
|
179
|
+
/** Keyboard shortcut text content - typically key combinations like "⌘K" or "Ctrl+N" */
|
|
180
|
+
children?: React.ReactNode;
|
|
181
|
+
} & React.HTMLAttributes<HTMLSpanElement>;
|
|
182
|
+
|
|
183
|
+
/**
|
|
184
|
+
* Props for CommandLoading component (Documentation only - NOT used in component implementation)
|
|
185
|
+
* These types are for documentation generation and extend CommandEmpty props
|
|
186
|
+
*/
|
|
187
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
188
|
+
type CommandLoadingDocsProps = CommandEmptyDocsProps;
|
|
189
|
+
|
|
190
|
+
// ============================================================================
|
|
191
|
+
// COMPONENTS
|
|
192
|
+
// ============================================================================
|
|
193
|
+
|
|
14
194
|
/**
|
|
15
195
|
* Command - A fast, composable command menu for search and navigation
|
|
16
196
|
*
|
|
@@ -18,11 +198,23 @@ import {
|
|
|
18
198
|
* interface with search, filtering, and keyboard navigation. Perfect for creating
|
|
19
199
|
* search interfaces, command palettes, and action menus with full accessibility support.
|
|
20
200
|
*
|
|
21
|
-
*
|
|
201
|
+
* Features advanced filtering with fuzzy search, keyboard shortcuts, nested navigation,
|
|
202
|
+
* asynchronous loading states, and comprehensive accessibility patterns.
|
|
203
|
+
*
|
|
204
|
+
* @param label - Accessibility label for screen readers and assistive technology
|
|
205
|
+
* @param shouldFilter - Controls automatic filtering and sorting @default true
|
|
206
|
+
* @param filter - Custom filter function for ranking items based on search
|
|
207
|
+
* @param value - Currently selected item value for controlled usage
|
|
208
|
+
* @param onValueChange - Callback fired when selected item changes
|
|
209
|
+
* @param loop - Enables circular navigation through items @default false
|
|
210
|
+
* @param disablePointerSelection - Prevents mouse selection behavior @default true
|
|
211
|
+
* @param vimBindings - Enables Vim-style navigation keybindings @default false
|
|
212
|
+
* @param className - Additional CSS classes
|
|
213
|
+
*
|
|
22
214
|
* @example
|
|
23
215
|
* ```tsx
|
|
24
216
|
* // Basic command menu
|
|
25
|
-
* <Command>
|
|
217
|
+
* <Command label="Main Menu">
|
|
26
218
|
* <CommandInput placeholder="Type a command or search..." />
|
|
27
219
|
* <CommandList>
|
|
28
220
|
* <CommandEmpty>No results found.</CommandEmpty>
|
|
@@ -37,6 +229,34 @@ import {
|
|
|
37
229
|
*
|
|
38
230
|
* @example
|
|
39
231
|
* ```tsx
|
|
232
|
+
* // Controlled command menu with custom filtering
|
|
233
|
+
* const [value, setValue] = useState('');
|
|
234
|
+
* const [search, setSearch] = useState('');
|
|
235
|
+
*
|
|
236
|
+
* <Command
|
|
237
|
+
* value={value}
|
|
238
|
+
* onValueChange={setValue}
|
|
239
|
+
* filter={(value, search, keywords) => {
|
|
240
|
+
* const extended = value + ' ' + (keywords?.join(' ') || '');
|
|
241
|
+
* return extended.toLowerCase().includes(search.toLowerCase()) ? 1 : 0;
|
|
242
|
+
* }}
|
|
243
|
+
* loop
|
|
244
|
+
* >
|
|
245
|
+
* <CommandInput
|
|
246
|
+
* value={search}
|
|
247
|
+
* onValueChange={setSearch}
|
|
248
|
+
* placeholder="Search..."
|
|
249
|
+
* />
|
|
250
|
+
* <CommandList>
|
|
251
|
+
* <CommandItem value="apple" keywords={['fruit', 'red']}>
|
|
252
|
+
* Apple
|
|
253
|
+
* </CommandItem>
|
|
254
|
+
* </CommandList>
|
|
255
|
+
* </Command>
|
|
256
|
+
* ```
|
|
257
|
+
*
|
|
258
|
+
* @example
|
|
259
|
+
* ```tsx
|
|
40
260
|
* // Command dialog with keyboard shortcut
|
|
41
261
|
* const [open, setOpen] = useState(false);
|
|
42
262
|
*
|
|
@@ -65,17 +285,20 @@ import {
|
|
|
65
285
|
* ```
|
|
66
286
|
*
|
|
67
287
|
* @accessibility
|
|
68
|
-
* - Full keyboard navigation with
|
|
69
|
-
* - Type-ahead search
|
|
288
|
+
* - Full keyboard navigation with Arrow keys, Home/End, Page Up/Down
|
|
289
|
+
* - Type-ahead search with live region announcements
|
|
70
290
|
* - Enter key to select items, Escape to close dialogs
|
|
71
|
-
* - Screen reader announcements for filtered results
|
|
72
|
-
* - ARIA roles following command palette
|
|
73
|
-
* - Focus management
|
|
291
|
+
* - Screen reader announcements for filtered results and state changes
|
|
292
|
+
* - ARIA roles following WAI-ARIA command palette patterns
|
|
293
|
+
* - Focus management with proper tab trapping in dialog mode
|
|
294
|
+
* - Support for disabled items and groups
|
|
74
295
|
*
|
|
296
|
+
* @see {@link https://cmdk.paco.me} Official CMDK documentation
|
|
75
297
|
* @see {@link https://ui.shadcn.com/docs/components/command} for design patterns
|
|
76
298
|
* @see {@link CommandDialog} - For modal command palette
|
|
77
299
|
* @see {@link CommandInput} - Search input component
|
|
78
300
|
* @see {@link CommandList} - Scrollable results container
|
|
301
|
+
* @see {@link useCommandState} - Hook for accessing command state
|
|
79
302
|
* @since 1.0.0
|
|
80
303
|
*/
|
|
81
304
|
function Command({
|
|
@@ -98,10 +321,20 @@ function Command({
|
|
|
98
321
|
* CommandDialog - Modal dialog wrapper for command menu
|
|
99
322
|
*
|
|
100
323
|
* Presents the command menu in a modal dialog overlay, perfect for application-wide
|
|
101
|
-
* command palettes triggered by keyboard shortcuts like Cmd+K.
|
|
102
|
-
* focus management and accessibility
|
|
324
|
+
* command palettes triggered by keyboard shortcuts like Cmd+K or Ctrl+K. Built on
|
|
325
|
+
* Radix UI Dialog with proper focus management, portal rendering, and accessibility.
|
|
326
|
+
*
|
|
327
|
+
* The dialog automatically handles focus trapping, scroll locking, and provides
|
|
328
|
+
* screen reader announcements. Use `container` prop to specify custom portal target.
|
|
329
|
+
*
|
|
330
|
+
* @param open - Controls dialog visibility state
|
|
331
|
+
* @param onOpenChange - Callback when dialog open state changes
|
|
332
|
+
* @param title - Screen reader accessible title @default "Command Palette"
|
|
333
|
+
* @param description - Screen reader description @default "Search for a command to run..."
|
|
334
|
+
* @param showCloseButton - Whether to show the X close button @default true
|
|
335
|
+
* @param container - Custom portal container element for rendering
|
|
336
|
+
* @param className - Additional CSS classes for dialog content
|
|
103
337
|
*
|
|
104
|
-
* @component
|
|
105
338
|
* @example
|
|
106
339
|
* ```tsx
|
|
107
340
|
* // Command palette dialog with keyboard shortcut
|
|
@@ -129,16 +362,38 @@ function Command({
|
|
|
129
362
|
* </CommandDialog>
|
|
130
363
|
* ```
|
|
131
364
|
*
|
|
132
|
-
* @
|
|
133
|
-
*
|
|
134
|
-
*
|
|
365
|
+
* @example
|
|
366
|
+
* ```tsx
|
|
367
|
+
* // Custom portal container
|
|
368
|
+
* const containerRef = useRef<HTMLDivElement>(null);
|
|
369
|
+
*
|
|
370
|
+
* <>
|
|
371
|
+
* <CommandDialog
|
|
372
|
+
* open={open}
|
|
373
|
+
* onOpenChange={setOpen}
|
|
374
|
+
* container={containerRef.current}
|
|
375
|
+
* title="Quick Actions"
|
|
376
|
+
* description="Find and run commands quickly"
|
|
377
|
+
* >
|
|
378
|
+
* <CommandInput />
|
|
379
|
+
* <CommandList>
|
|
380
|
+
* <CommandItem>Action 1</CommandItem>
|
|
381
|
+
* </CommandList>
|
|
382
|
+
* </CommandDialog>
|
|
383
|
+
* <div ref={containerRef} />
|
|
384
|
+
* </>
|
|
385
|
+
* ```
|
|
135
386
|
*
|
|
136
387
|
* @accessibility
|
|
137
|
-
* - Focus trapped within dialog when open
|
|
388
|
+
* - Focus trapped within dialog when open with proper restoration
|
|
138
389
|
* - Escape key closes the dialog
|
|
390
|
+
* - Click outside or close button dismisses dialog
|
|
139
391
|
* - Screen reader announcements with title and description
|
|
140
392
|
* - Preserves all command menu keyboard navigation
|
|
393
|
+
* - Modal backdrop prevents interaction with background content
|
|
141
394
|
*
|
|
395
|
+
* @see {@link Dialog} - Base dialog component
|
|
396
|
+
* @see {@link Command} - Command menu component
|
|
142
397
|
* @since 1.0.0
|
|
143
398
|
*/
|
|
144
399
|
function CommandDialog({
|
|
@@ -148,27 +403,13 @@ function CommandDialog({
|
|
|
148
403
|
className,
|
|
149
404
|
showCloseButton = true,
|
|
150
405
|
...props
|
|
151
|
-
}:
|
|
152
|
-
/**
|
|
153
|
-
* The title for screen readers
|
|
154
|
-
* @default "Command Palette"
|
|
155
|
-
*/
|
|
406
|
+
}: {
|
|
156
407
|
title?: string;
|
|
157
|
-
/**
|
|
158
|
-
* The description for screen readers
|
|
159
|
-
* @default "Search for a command to run..."
|
|
160
|
-
*/
|
|
161
408
|
description?: string;
|
|
162
|
-
|
|
163
|
-
* Additional CSS classes
|
|
164
|
-
*/
|
|
409
|
+
children?: React.ReactNode;
|
|
165
410
|
className?: string;
|
|
166
|
-
/**
|
|
167
|
-
* Whether to show the close button
|
|
168
|
-
* @default true
|
|
169
|
-
*/
|
|
170
411
|
showCloseButton?: boolean;
|
|
171
|
-
}) {
|
|
412
|
+
} & React.ComponentProps<typeof Dialog>) {
|
|
172
413
|
return (
|
|
173
414
|
<Dialog {...props}>
|
|
174
415
|
<DialogHeader className="sr-only">
|
|
@@ -179,7 +420,7 @@ function CommandDialog({
|
|
|
179
420
|
className={cn("overflow-hidden p-0", className)}
|
|
180
421
|
showCloseButton={showCloseButton}
|
|
181
422
|
>
|
|
182
|
-
<Command className="[&_[cmdk-group-heading]]:text-muted-foreground
|
|
423
|
+
<Command className="[&_[cmdk-group-heading]]:text-muted-foreground [&_[data-slot=command-input-wrapper]]:h-12 [&_[cmdk-group-heading]]:px-2 [&_[cmdk-group-heading]]:font-medium [&_[cmdk-group]]:px-2 [&_[cmdk-group]:not([hidden])_~[cmdk-group]]:pt-0 [&_[cmdk-input-wrapper]_svg]:h-5 [&_[cmdk-input-wrapper]_svg]:w-5 [&_[cmdk-input]]:h-12 [&_[cmdk-item]]:px-2 [&_[cmdk-item]]:py-3 [&_[cmdk-item]_svg]:h-5 [&_[cmdk-item]_svg]:w-5">
|
|
183
424
|
{children}
|
|
184
425
|
</Command>
|
|
185
426
|
</DialogContent>
|
|
@@ -191,11 +432,23 @@ function CommandDialog({
|
|
|
191
432
|
* CommandInput - Search input for command menu filtering
|
|
192
433
|
*
|
|
193
434
|
* Provides a search input with search icon for filtering command menu items.
|
|
194
|
-
* Automatically filters items as the user types and
|
|
435
|
+
* Automatically filters items as the user types and triggers live region announcements
|
|
436
|
+
* for screen readers. Supports both controlled and uncontrolled usage patterns.
|
|
437
|
+
*
|
|
438
|
+
* The input integrates with the Command context to provide real-time filtering,
|
|
439
|
+
* search highlighting, and result announcements. Includes built-in search icon
|
|
440
|
+
* and proper focus management.
|
|
441
|
+
*
|
|
442
|
+
* @param value - Controlled input value for managing search state externally
|
|
443
|
+
* @param onValueChange - Callback fired when input value changes
|
|
444
|
+
* @param placeholder - Placeholder text displayed when input is empty
|
|
445
|
+
* @param disabled - Disables the input and prevents interaction @default false
|
|
446
|
+
* @param autoFocus - Auto-focus the input when rendered @default false
|
|
447
|
+
* @param className - Additional CSS classes
|
|
195
448
|
*
|
|
196
|
-
* @component
|
|
197
449
|
* @example
|
|
198
450
|
* ```tsx
|
|
451
|
+
* // Basic uncontrolled input
|
|
199
452
|
* <Command>
|
|
200
453
|
* <CommandInput placeholder="Search commands..." />
|
|
201
454
|
* <CommandList>...</CommandList>
|
|
@@ -204,18 +457,32 @@ function CommandDialog({
|
|
|
204
457
|
*
|
|
205
458
|
* @example
|
|
206
459
|
* ```tsx
|
|
207
|
-
* // Controlled input with state
|
|
460
|
+
* // Controlled input with external state
|
|
461
|
+
* const [search, setSearch] = useState('');
|
|
462
|
+
*
|
|
208
463
|
* <CommandInput
|
|
464
|
+
* value={search}
|
|
465
|
+
* onValueChange={setSearch}
|
|
209
466
|
* placeholder="Type a command or search..."
|
|
210
|
-
*
|
|
211
|
-
*
|
|
467
|
+
* autoFocus
|
|
468
|
+
* />
|
|
469
|
+
* ```
|
|
470
|
+
*
|
|
471
|
+
* @example
|
|
472
|
+
* ```tsx
|
|
473
|
+
* // With disabled state
|
|
474
|
+
* <CommandInput
|
|
475
|
+
* placeholder="Loading..."
|
|
476
|
+
* disabled={isLoading}
|
|
212
477
|
* />
|
|
213
478
|
* ```
|
|
214
479
|
*
|
|
215
480
|
* @accessibility
|
|
216
|
-
* - Auto-focuses when command menu opens
|
|
217
|
-
* - Live region announces result count to screen readers
|
|
481
|
+
* - Auto-focuses when command menu opens (if autoFocus is true)
|
|
482
|
+
* - Live region announces result count changes to screen readers
|
|
218
483
|
* - Supports all standard input accessibility features
|
|
484
|
+
* - Proper labeling and description associations
|
|
485
|
+
* - Keyboard navigation integration with command list
|
|
219
486
|
*
|
|
220
487
|
* @since 1.0.0
|
|
221
488
|
*/
|
|
@@ -244,10 +511,15 @@ function CommandInput({
|
|
|
244
511
|
/**
|
|
245
512
|
* CommandList - Scrollable container for command items
|
|
246
513
|
*
|
|
247
|
-
* Contains and manages the list of command items with automatic scrolling
|
|
248
|
-
*
|
|
514
|
+
* Contains and manages the list of command items with automatic scrolling,
|
|
515
|
+
* overflow handling, and dynamic height calculation. Provides the scrollable
|
|
516
|
+
* viewport for command items and groups with proper keyboard navigation.
|
|
517
|
+
*
|
|
518
|
+
* Uses CSS custom property `--cmdk-list-height` for smooth height transitions
|
|
519
|
+
* when items are filtered. Supports scroll padding for better item visibility.
|
|
520
|
+
*
|
|
521
|
+
* @param className - Additional CSS classes
|
|
249
522
|
*
|
|
250
|
-
* @component
|
|
251
523
|
* @example
|
|
252
524
|
* ```tsx
|
|
253
525
|
* <CommandList>
|
|
@@ -259,10 +531,25 @@ function CommandInput({
|
|
|
259
531
|
* </CommandList>
|
|
260
532
|
* ```
|
|
261
533
|
*
|
|
534
|
+
* @example
|
|
535
|
+
* ```tsx
|
|
536
|
+
* // With custom height and scroll behavior
|
|
537
|
+
* <CommandList className="max-h-[400px] scroll-py-2">
|
|
538
|
+
* {items.map((item) => (
|
|
539
|
+
* <CommandItem key={item.id} value={item.id}>
|
|
540
|
+
* {item.name}
|
|
541
|
+
* </CommandItem>
|
|
542
|
+
* ))}
|
|
543
|
+
* </CommandList>
|
|
544
|
+
* ```
|
|
545
|
+
*
|
|
262
546
|
* @accessibility
|
|
263
547
|
* - Scrollable with keyboard arrow navigation
|
|
264
548
|
* - Maintains focus within list boundaries
|
|
265
|
-
* - Supports Home/End key navigation
|
|
549
|
+
* - Supports Home/End key navigation to first/last items
|
|
550
|
+
* - Page Up/Page Down for faster scrolling
|
|
551
|
+
* - Proper ARIA role as listbox
|
|
552
|
+
* - Screen reader announcements for list changes
|
|
266
553
|
*
|
|
267
554
|
* @since 1.0.0
|
|
268
555
|
*/
|
|
@@ -286,9 +573,14 @@ function CommandList({
|
|
|
286
573
|
* CommandEmpty - Empty state message for command menu
|
|
287
574
|
*
|
|
288
575
|
* Displays when no command items match the current search query.
|
|
289
|
-
* Can contain custom content beyond simple text messages.
|
|
576
|
+
* Can contain custom content beyond simple text messages. Automatically
|
|
577
|
+
* shows/hides based on filtered results and announces changes to screen readers.
|
|
578
|
+
*
|
|
579
|
+
* Supports dynamic content using the `useCommandState` hook to access current
|
|
580
|
+
* search term and create contextual empty messages.
|
|
581
|
+
*
|
|
582
|
+
* @param className - Additional CSS classes
|
|
290
583
|
*
|
|
291
|
-
* @component
|
|
292
584
|
* @example
|
|
293
585
|
* ```tsx
|
|
294
586
|
* <CommandList>
|
|
@@ -310,10 +602,26 @@ function CommandList({
|
|
|
310
602
|
* </CommandEmpty>
|
|
311
603
|
* ```
|
|
312
604
|
*
|
|
605
|
+
* @example
|
|
606
|
+
* ```tsx
|
|
607
|
+
* // Dynamic empty message with search term
|
|
608
|
+
* function DynamicEmpty() {
|
|
609
|
+
* const search = useCommandState((state) => state.search);
|
|
610
|
+
* return (
|
|
611
|
+
* <CommandEmpty>
|
|
612
|
+
* {search ? `No results found for "${search}".` : 'Start typing to search...'}
|
|
613
|
+
* </CommandEmpty>
|
|
614
|
+
* );
|
|
615
|
+
* }
|
|
616
|
+
* ```
|
|
617
|
+
*
|
|
313
618
|
* @accessibility
|
|
314
619
|
* - Announced to screen readers when no results are found
|
|
315
|
-
* - Content is properly focusable if interactive
|
|
620
|
+
* - Content is properly focusable if interactive elements are included
|
|
621
|
+
* - Live region updates when search state changes
|
|
622
|
+
* - Proper semantic markup for empty state content
|
|
316
623
|
*
|
|
624
|
+
* @see {@link useCommandState} - Hook for accessing search state
|
|
317
625
|
* @since 1.0.0
|
|
318
626
|
*/
|
|
319
627
|
function CommandEmpty({
|
|
@@ -331,10 +639,18 @@ function CommandEmpty({
|
|
|
331
639
|
/**
|
|
332
640
|
* CommandGroup - Groups related command items under a heading
|
|
333
641
|
*
|
|
334
|
-
* Organizes command items into labeled sections for better
|
|
335
|
-
* and navigation. Groups provide semantic structure for screen readers
|
|
642
|
+
* Organizes command items into labeled sections with optional headings for better
|
|
643
|
+
* organization and navigation. Groups provide semantic structure for screen readers
|
|
644
|
+
* and can be hidden/shown based on whether they contain matching items.
|
|
645
|
+
*
|
|
646
|
+
* Groups automatically manage their visibility - if all contained items are filtered
|
|
647
|
+
* out, the entire group is hidden. Use `forceMount` to override this behavior.
|
|
648
|
+
*
|
|
649
|
+
* @param heading - The group heading text or component displayed above items
|
|
650
|
+
* @param value - Group identifier for programmatic control
|
|
651
|
+
* @param forceMount - Whether to always render the group even when hidden @default false
|
|
652
|
+
* @param className - Additional CSS classes
|
|
336
653
|
*
|
|
337
|
-
* @component
|
|
338
654
|
* @example
|
|
339
655
|
* ```tsx
|
|
340
656
|
* <CommandGroup heading="Recent Files">
|
|
@@ -347,12 +663,35 @@ function CommandEmpty({
|
|
|
347
663
|
* </CommandGroup>
|
|
348
664
|
* ```
|
|
349
665
|
*
|
|
350
|
-
* @
|
|
666
|
+
* @example
|
|
667
|
+
* ```tsx
|
|
668
|
+
* // Group with custom heading component
|
|
669
|
+
* <CommandGroup
|
|
670
|
+
* heading={
|
|
671
|
+
* <div className="flex items-center gap-2">
|
|
672
|
+
* <FolderIcon className="h-4 w-4" />
|
|
673
|
+
* <span>Projects</span>
|
|
674
|
+
* </div>
|
|
675
|
+
* }
|
|
676
|
+
* >
|
|
677
|
+
* <CommandItem>Project A</CommandItem>
|
|
678
|
+
* <CommandItem>Project B</CommandItem>
|
|
679
|
+
* </CommandGroup>
|
|
680
|
+
* ```
|
|
681
|
+
*
|
|
682
|
+
* @example
|
|
683
|
+
* ```tsx
|
|
684
|
+
* // Group that always shows even when filtered
|
|
685
|
+
* <CommandGroup heading="Important" forceMount>
|
|
686
|
+
* <CommandItem>Critical Action</CommandItem>
|
|
687
|
+
* </CommandGroup>
|
|
688
|
+
* ```
|
|
351
689
|
*
|
|
352
690
|
* @accessibility
|
|
353
691
|
* - Group headings are announced to screen readers
|
|
354
|
-
* - Provides semantic grouping
|
|
692
|
+
* - Provides semantic grouping with proper ARIA roles
|
|
355
693
|
* - Maintains keyboard navigation flow between groups
|
|
694
|
+
* - Groups are properly labeled for assistive technology
|
|
356
695
|
*
|
|
357
696
|
* @since 1.0.0
|
|
358
697
|
*/
|
|
@@ -376,9 +715,15 @@ function CommandGroup({
|
|
|
376
715
|
* CommandSeparator - Visual separator between command groups
|
|
377
716
|
*
|
|
378
717
|
* Provides visual separation between different sections of commands.
|
|
379
|
-
* Purely decorative element that improves visual organization.
|
|
718
|
+
* Purely decorative element that improves visual organization and hierarchy.
|
|
719
|
+
* Automatically hides when adjacent groups are filtered out.
|
|
720
|
+
*
|
|
721
|
+
* The separator will only render when it has visible content before and after it,
|
|
722
|
+
* unless `alwaysRender` is true.
|
|
723
|
+
*
|
|
724
|
+
* @param alwaysRender - Whether to always show separator regardless of context @default false
|
|
725
|
+
* @param className - Additional CSS classes
|
|
380
726
|
*
|
|
381
|
-
* @component
|
|
382
727
|
* @example
|
|
383
728
|
* ```tsx
|
|
384
729
|
* <CommandGroup heading="Recent">...</CommandGroup>
|
|
@@ -386,9 +731,18 @@ function CommandGroup({
|
|
|
386
731
|
* <CommandGroup heading="Actions">...</CommandGroup>
|
|
387
732
|
* ```
|
|
388
733
|
*
|
|
734
|
+
* @example
|
|
735
|
+
* ```tsx
|
|
736
|
+
* // Separator that always renders
|
|
737
|
+
* <CommandGroup heading="Primary">...</CommandGroup>
|
|
738
|
+
* <CommandSeparator alwaysRender />
|
|
739
|
+
* <CommandGroup heading="Secondary">...</CommandGroup>
|
|
740
|
+
* ```
|
|
741
|
+
*
|
|
389
742
|
* @accessibility
|
|
390
|
-
* - Decorative element, properly hidden from screen readers
|
|
743
|
+
* - Decorative element, properly hidden from screen readers with aria-hidden
|
|
391
744
|
* - Does not interfere with keyboard navigation
|
|
745
|
+
* - No focusable content or semantic meaning
|
|
392
746
|
*
|
|
393
747
|
* @since 1.0.0
|
|
394
748
|
*/
|
|
@@ -408,10 +762,20 @@ function CommandSeparator({
|
|
|
408
762
|
/**
|
|
409
763
|
* CommandItem - Individual selectable command item
|
|
410
764
|
*
|
|
411
|
-
* Represents a single command or action that can be selected via
|
|
412
|
-
*
|
|
765
|
+
* Represents a single command or action that can be selected via keyboard or mouse
|
|
766
|
+
* interaction. Supports icons, text, shortcuts, and advanced filtering with keywords.
|
|
767
|
+
* Items can be disabled, have custom values for filtering, and trigger callbacks on selection.
|
|
768
|
+
*
|
|
769
|
+
* The item's value is used for filtering - if not provided, it defaults to the text content.
|
|
770
|
+
* Keywords can be added to improve search matching without affecting the display.
|
|
771
|
+
*
|
|
772
|
+
* @param value - Unique identifier for filtering and selection (defaults to text content)
|
|
773
|
+
* @param keywords - Additional search terms for improved filtering
|
|
774
|
+
* @param disabled - Disables interaction and selection @default false
|
|
775
|
+
* @param onSelect - Callback fired when item is selected with Enter or click
|
|
776
|
+
* @param forceMount - Always render even when filtered out @default false
|
|
777
|
+
* @param className - Additional CSS classes
|
|
413
778
|
*
|
|
414
|
-
* @component
|
|
415
779
|
* @example
|
|
416
780
|
* ```tsx
|
|
417
781
|
* // Basic command item
|
|
@@ -430,15 +794,33 @@ function CommandSeparator({
|
|
|
430
794
|
* </CommandItem>
|
|
431
795
|
* ```
|
|
432
796
|
*
|
|
433
|
-
* @
|
|
434
|
-
*
|
|
435
|
-
*
|
|
797
|
+
* @example
|
|
798
|
+
* ```tsx
|
|
799
|
+
* // Item with keywords for better search
|
|
800
|
+
* <CommandItem
|
|
801
|
+
* value="apple"
|
|
802
|
+
* keywords={['fruit', 'red', 'healthy']}
|
|
803
|
+
* onSelect={() => selectFruit('apple')}
|
|
804
|
+
* >
|
|
805
|
+
* 🍎 Apple
|
|
806
|
+
* </CommandItem>
|
|
807
|
+
* ```
|
|
808
|
+
*
|
|
809
|
+
* @example
|
|
810
|
+
* ```tsx
|
|
811
|
+
* // Disabled item that shows but cannot be selected
|
|
812
|
+
* <CommandItem disabled>
|
|
813
|
+
* <LockIcon className="mr-2 h-4 w-4" />
|
|
814
|
+
* Premium Feature
|
|
815
|
+
* </CommandItem>
|
|
816
|
+
* ```
|
|
436
817
|
*
|
|
437
818
|
* @accessibility
|
|
438
819
|
* - Keyboard selectable with Enter key and arrow navigation
|
|
439
|
-
* - Visual highlight on focus and hover states
|
|
820
|
+
* - Visual highlight on focus and hover states with proper contrast
|
|
440
821
|
* - Supports disabled state with proper ARIA attributes
|
|
441
|
-
* - Screen reader announces item content and
|
|
822
|
+
* - Screen reader announces item content, state, and shortcuts
|
|
823
|
+
* - Maintains focus within list boundaries
|
|
442
824
|
*
|
|
443
825
|
* @since 1.0.0
|
|
444
826
|
*/
|
|
@@ -461,10 +843,15 @@ function CommandItem({
|
|
|
461
843
|
/**
|
|
462
844
|
* CommandShortcut - Displays keyboard shortcut for command items
|
|
463
845
|
*
|
|
464
|
-
* Shows the keyboard shortcut associated with a command item,
|
|
465
|
-
*
|
|
846
|
+
* Shows the keyboard shortcut associated with a command item, typically displayed
|
|
847
|
+
* on the right side with proper spacing. Supports platform-specific shortcuts and
|
|
848
|
+
* complex key combinations with consistent formatting.
|
|
849
|
+
*
|
|
850
|
+
* The component uses monospace-style formatting with appropriate opacity and spacing
|
|
851
|
+
* to clearly indicate keyboard shortcuts without overwhelming the item content.
|
|
852
|
+
*
|
|
853
|
+
* @param className - Additional CSS classes
|
|
466
854
|
*
|
|
467
|
-
* @component
|
|
468
855
|
* @example
|
|
469
856
|
* ```tsx
|
|
470
857
|
* <CommandItem>
|
|
@@ -482,10 +869,29 @@ function CommandItem({
|
|
|
482
869
|
* </CommandItem>
|
|
483
870
|
* ```
|
|
484
871
|
*
|
|
872
|
+
* @example
|
|
873
|
+
* ```tsx
|
|
874
|
+
* // Platform-specific shortcuts
|
|
875
|
+
* <CommandItem>
|
|
876
|
+
* Copy
|
|
877
|
+
* <CommandShortcut>{isMac ? '⌘C' : 'Ctrl+C'}</CommandShortcut>
|
|
878
|
+
* </CommandItem>
|
|
879
|
+
* ```
|
|
880
|
+
*
|
|
881
|
+
* @example
|
|
882
|
+
* ```tsx
|
|
883
|
+
* // Complex shortcuts with modifiers
|
|
884
|
+
* <CommandItem>
|
|
885
|
+
* Open Command Palette
|
|
886
|
+
* <CommandShortcut>⌘⇧P</CommandShortcut>
|
|
887
|
+
* </CommandItem>
|
|
888
|
+
* ```
|
|
889
|
+
*
|
|
485
890
|
* @accessibility
|
|
486
891
|
* - Semantically associated with its command item
|
|
487
892
|
* - Announced to screen readers as part of item description
|
|
488
|
-
* - Uses proper keyboard shortcut formatting
|
|
893
|
+
* - Uses proper keyboard shortcut formatting and labeling
|
|
894
|
+
* - Maintains readability with appropriate contrast
|
|
489
895
|
*
|
|
490
896
|
* @since 1.0.0
|
|
491
897
|
*/
|
|
@@ -505,6 +911,58 @@ function CommandShortcut({
|
|
|
505
911
|
);
|
|
506
912
|
}
|
|
507
913
|
|
|
914
|
+
/**
|
|
915
|
+
* CommandLoading - Loading state indicator for command menu
|
|
916
|
+
*
|
|
917
|
+
* Displays a loading message while command items are being fetched asynchronously.
|
|
918
|
+
* Should be conditionally rendered based on loading state. Shares the same styling
|
|
919
|
+
* and behavior as CommandEmpty but indicates active loading rather than empty state.
|
|
920
|
+
*
|
|
921
|
+
* @param className - Additional CSS classes
|
|
922
|
+
*
|
|
923
|
+
* @example
|
|
924
|
+
* ```tsx
|
|
925
|
+
* const [loading, setLoading] = useState(false);
|
|
926
|
+
* const [items, setItems] = useState([]);
|
|
927
|
+
*
|
|
928
|
+
* <CommandList>
|
|
929
|
+
* {loading && <CommandLoading>Fetching commands...</CommandLoading>}
|
|
930
|
+
* {items.map(item => (
|
|
931
|
+
* <CommandItem key={item.id} value={item.id}>
|
|
932
|
+
* {item.name}
|
|
933
|
+
* </CommandItem>
|
|
934
|
+
* ))}
|
|
935
|
+
* </CommandList>
|
|
936
|
+
* ```
|
|
937
|
+
*
|
|
938
|
+
* @example
|
|
939
|
+
* ```tsx
|
|
940
|
+
* // With custom loading indicator
|
|
941
|
+
* <CommandLoading>
|
|
942
|
+
* <div className="flex items-center justify-center py-6">
|
|
943
|
+
* <Spinner className="mr-2 h-4 w-4" />
|
|
944
|
+
* <span>Loading commands...</span>
|
|
945
|
+
* </div>
|
|
946
|
+
* </CommandLoading>
|
|
947
|
+
* ```
|
|
948
|
+
*
|
|
949
|
+
* @accessibility
|
|
950
|
+
* - Announced to screen readers as loading state
|
|
951
|
+
* - Uses appropriate ARIA live region for status updates
|
|
952
|
+
* - Provides context for users while waiting for results
|
|
953
|
+
*
|
|
954
|
+
* @since 1.0.0
|
|
955
|
+
*/
|
|
956
|
+
function CommandLoading({ ...props }: React.ComponentProps<"div">) {
|
|
957
|
+
return (
|
|
958
|
+
<div
|
|
959
|
+
data-slot="command-loading"
|
|
960
|
+
className="py-6 text-center text-sm"
|
|
961
|
+
{...props}
|
|
962
|
+
/>
|
|
963
|
+
);
|
|
964
|
+
}
|
|
965
|
+
|
|
508
966
|
export {
|
|
509
967
|
Command,
|
|
510
968
|
CommandDialog,
|
|
@@ -515,4 +973,6 @@ export {
|
|
|
515
973
|
CommandItem,
|
|
516
974
|
CommandShortcut,
|
|
517
975
|
CommandSeparator,
|
|
976
|
+
CommandLoading,
|
|
977
|
+
useCommandState,
|
|
518
978
|
};
|