Keyboard-initiated events shouldn't be animated

By Kacper Szarkiewicz

Arrow keys vs. mouse

With animation

PressKto open/close

Without animation

PressKto open/close

cmdk is Paco Coursey's headless command menu - it ships filtering, keyboard navigation, and ARIA roles, and leaves styling to you. Install it:

pnpm add cmdk

We lean on one detail: Command.Item gets data-selected="true" on whichever item is active - arrow key or hover. That single attribute is our hook for both modalities.

Each item carries four classes:

transition-colors
hover:bg-white/10
data-[selected=true]:bg-white/10
group-data-kbd/menu:transition-none

cmdk sets data-selected="true" on the active item, so hover and keyboard share the same background rule. The last class kills the transition while the menu carries data-kbd - flipped on by onKeyDown, off by onPointerMove.

const [kbd, setKbd] = useState(false);
const dataKbd = kbd ? "" : undefined;

<Command
  data-kbd={dataKbd}
  onKeyDown={() => setKbd(true)}
  onPointerMove={() => setKbd(false)}
/>

Pass undefined when off so React omits the attribute - data-kbd="false" would still match [data-kbd].

Newsletter

Stay updated with my latest articles and projects. No spam, no nonsense.