Skip to content

Commit 30bfd82

Browse files
fix(command-palette): accept HTML input attributes on CommandPalette.Input (#451)
1 parent 6ed3d52 commit 30bfd82

7 files changed

Lines changed: 108 additions & 12 deletions

File tree

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@cloudflare/kumo": patch
3+
---
4+
5+
Allow `CommandPalette.Input` to accept standard HTML input attributes (`autoComplete`, `autoCorrect`, `autoCapitalize`, `spellCheck`, `data-*`, etc.) by extending its props type with `InputHTMLAttributes<HTMLInputElement>`. Export new `CommandPaletteInputProps` type.

packages/kumo-docs-astro/src/components/demos/CommandPaletteDemo.tsx

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -292,6 +292,78 @@ export function CommandPaletteLoadingDemo() {
292292
);
293293
}
294294

295+
/** Demonstrates disabling browser autocomplete and spellcheck on the command palette input. */
296+
export function CommandPaletteNoAutocompleteDemo() {
297+
const [open, setOpen] = useState(false);
298+
const [search, setSearch] = useState("");
299+
300+
const filteredGroups = filterGroupsWithItems(sampleGroups, search);
301+
302+
return (
303+
<div className="flex flex-col items-start gap-4">
304+
<Button onClick={() => setOpen(true)}>
305+
Open Palette (No Autocomplete)
306+
</Button>
307+
308+
<CommandPalette.Root
309+
open={open}
310+
onOpenChange={setOpen}
311+
items={filteredGroups}
312+
value={search}
313+
onValueChange={setSearch}
314+
itemToStringValue={(group) => group.label}
315+
onSelect={(item) => {
316+
console.log("Selected:", item.title);
317+
setOpen(false);
318+
setSearch("");
319+
}}
320+
getSelectableItems={getSelectableItems}
321+
>
322+
<CommandPalette.Input
323+
placeholder="Search commands..."
324+
autoComplete="off"
325+
autoCorrect="off"
326+
autoCapitalize="none"
327+
spellCheck={false}
328+
data-1p-ignore="true"
329+
data-lpignore="true"
330+
/>
331+
<CommandPalette.List>
332+
<CommandPalette.Results>
333+
{(group: CommandGroup) => (
334+
<CommandPalette.Group key={group.id} items={group.items}>
335+
<CommandPalette.GroupLabel>
336+
{group.label}
337+
</CommandPalette.GroupLabel>
338+
<CommandPalette.Items>
339+
{(item: CommandItem) => (
340+
<CommandPalette.Item
341+
key={item.id}
342+
value={item}
343+
onClick={() => {
344+
setOpen(false);
345+
setSearch("");
346+
}}
347+
>
348+
<span className="flex items-center gap-3">
349+
{item.icon && (
350+
<span className="text-kumo-subtle">{item.icon}</span>
351+
)}
352+
<span>{item.title}</span>
353+
</span>
354+
</CommandPalette.Item>
355+
)}
356+
</CommandPalette.Items>
357+
</CommandPalette.Group>
358+
)}
359+
</CommandPalette.Results>
360+
<CommandPalette.Empty>No commands found</CommandPalette.Empty>
361+
</CommandPalette.List>
362+
</CommandPalette.Root>
363+
</div>
364+
);
365+
}
366+
295367
// ResultItem with breadcrumbs and highlights
296368
interface SearchResult {
297369
id: string;

packages/kumo-docs-astro/src/pages/components/command-palette.mdx

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import {
1313
CommandPaletteBasicDemo,
1414
CommandPaletteSimpleDemo,
1515
CommandPaletteLoadingDemo,
16+
CommandPaletteNoAutocompleteDemo,
1617
CommandPaletteResultItemDemo,
1718
} from "~/components/demos/CommandPaletteDemo";
1819

@@ -153,6 +154,13 @@ export default function Example() {
153154
<CommandPaletteLoadingDemo client:visible />
154155
</ComponentExample>
155156

157+
### Disabling Browser Autocomplete
158+
159+
<p>Pass standard HTML input attributes like `autoComplete`, `autoCorrect`, `spellCheck`, and `data-*` to suppress browser and password manager autocomplete overlays.</p>
160+
<ComponentExample demo="CommandPaletteNoAutocompleteDemo">
161+
<CommandPaletteNoAutocompleteDemo client:visible />
162+
</ComponentExample>
163+
156164
### ResultItem with Breadcrumbs
157165

158166
<p>

packages/kumo/src/components/command-palette/command-palette.tsx

Lines changed: 3 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ import {
2525
import type {
2626
HighlightRange,
2727
CommandPaletteRootProps,
28+
CommandPaletteInputProps,
2829
CommandPaletteListProps,
2930
CommandPaletteGroupProps,
3031
CommandPaletteGroupLabelProps,
@@ -731,21 +732,12 @@ function PanelInput({
731732
leading,
732733
trailing,
733734
...props
734-
}: {
735-
autoFocus?: boolean;
736-
placeholder?: string;
737-
className?: string;
738-
onKeyDown?: (e: React.KeyboardEvent) => void;
739-
/** Optional leading content (e.g., back button) */
740-
leading?: React.ReactNode;
741-
/** Optional trailing content (e.g., Esc button) */
742-
trailing?: React.ReactNode;
743-
}) {
735+
}: CommandPaletteInputProps) {
744736
const { onInputKeyDown } = useContext(PanelContext);
745737
const { onClose } = useContext(DialogContext);
746738

747739
const handleKeyDown = useCallback(
748-
(e: React.KeyboardEvent) => {
740+
(e: React.KeyboardEvent<HTMLInputElement>) => {
749741
// Let consumer handle first (e.g., for custom Escape/Backspace behavior)
750742
onKeyDownProp?.(e);
751743
if (e.defaultPrevented) return;

packages/kumo/src/components/command-palette/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ export {
66
export type {
77
HighlightRange,
88
CommandPaletteRootProps,
9+
CommandPaletteInputProps,
910
CommandPaletteItemProps,
1011
CommandPaletteFooterProps,
1112
CommandPaletteListProps,

packages/kumo/src/components/command-palette/types.ts

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import type { ReactNode } from "react";
1+
import type { ReactNode, InputHTMLAttributes } from "react";
22
import type { PortalContainer } from "../../utils/portal-provider";
33

44
/** A single highlight range within a string [startIndex, endIndex] (inclusive) */
@@ -160,3 +160,20 @@ export interface CommandPaletteResultItemProps<T = unknown> {
160160
/** Whether this item is non-interactive (no hover/highlight) */
161161
nonInteractive?: boolean;
162162
}
163+
164+
/**
165+
* Props for the CommandPalette.Input component - search input inside the palette.
166+
*
167+
* Extends standard HTML input attributes so you can pass props like
168+
* `autoComplete`, `autoCorrect`, `autoCapitalize`, `spellCheck`, `data-*`, etc.
169+
*/
170+
export interface CommandPaletteInputProps
171+
extends Omit<
172+
InputHTMLAttributes<HTMLInputElement>,
173+
"children" | "defaultValue" | "defaultChecked" | "color"
174+
> {
175+
/** Optional leading content (e.g., back button) */
176+
leading?: ReactNode;
177+
/** Optional trailing content (e.g., Esc button) */
178+
trailing?: ReactNode;
179+
}

packages/kumo/src/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,7 @@ export {
172172
KUMO_COMMAND_PALETTE_VARIANTS,
173173
KUMO_COMMAND_PALETTE_DEFAULT_VARIANTS,
174174
type CommandPaletteRootProps,
175+
type CommandPaletteInputProps,
175176
type CommandPaletteItemProps,
176177
type CommandPaletteResultItemProps,
177178
type CommandPaletteFooterProps,

0 commit comments

Comments
 (0)