GodUIGodUI
129Follow on X

Anatomy of the GodUI Command

One highlight that glides with your arrow keys but snaps while you type, and why those two cases need different motion.

01/03One highlight
tsx
useActiveIndicator(listRef, indicatorRef, {active: '[cmdk-item][data-selected="true"]',items: "[cmdk-item]",attributes: ["data-selected"],});
01

One highlight

cmdk marks the selected item with data-selected="true" and moves it on arrow keys and pointer moves. GodUI watches that attribute and moves one highlight element to the new item with a FLIP. Its box snaps to the new item, then translate and scale animate back from the old one.

The highlight lives inside the scrolling list, so it scrolls with the items. When cmdk scrolls a selected item into view, the highlight is already there.

02/03Snap while filtering
tsx
const mutations = new MutationObserver((records) => {// Selection moved → slide. Items added/removed (filtering) → snap.if (records.some((record) => record.type === "childList")) {  observeItems();  place(false);} else {  place(true);}});
02

Snap while filtering

Typing re-filters the list on every keystroke: items disappear, the rest shift up, and the selection jumps to the first match. If the highlight slid each time, it would chase the list around while you type.

So the shared useActiveIndicator hook slides only when the selection moves between existing items (an attribute change), and snaps when items are added or removed. Arrow keys glide; typing doesn't.

03/03Result
03

The result

Arrow through the items, move the pointer over them, then type to filter.

What's animated

The highlight is the same FLIP that Tabs uses. Before JavaScript runs, the selected item paints its own background, exactly as in shadcn.

InteractionKeyframe / mechanismPropertiesEasingDuration
Arrow keys, pointerFLIP (WAAPI) on the highlighttranslate, scaleease-spring-snappy260ms
Typing (filter)highlight snaps to the first matchnonenonenone
Dialog open / closeas Dialogopacity, scalesnappy / expo260 / 150ms

Why GPU-only

The highlight animates translate and scale. Items no longer repaint their own background on selection.

Reduced motion

The highlight jumps to the selected item without sliding. CommandDialog fades without scaling.

Replacing shadcn

npx shadcn add @godui/command overwrites components/ui/command.tsx and installs the GodUI dialog it uses. Exports, props and data-slot attributes match shadcn/ui new-york-v4, so existing imports keep working. CommandList renders one extra element, an aria-hidden <span data-slot="command-indicator">.