import { useMemo, useState, type KeyboardEvent, type ReactNode } from 'react' import { Button as BaseButton } from '@base-ui/react/button' import { Combobox } from '@base-ui/react/combobox' import { IconX } from '@tabler/icons-react' import { cn } from './cn' import { MenuItem, MenuPanel } from './Menu' import { ScrollArea } from './ScrollArea' import { BARE_INPUT_CLASSES, FIELD_SHELL_CLASSES } from './looks' /* The chip's own look, written once: `InputChip` draws it for a caller who wants a chip on its own, and `ChipInput` gives the same classes to Base UI's `Combobox.Chip`, which is the one that joins the input's keyboard. */ const CHIP_BOX = // Curved, not a pill (Katerina, 2026-09-01): the Avatar keeps its own // rounded-sm corners — never a forced circle — and the chip's corner // follows concentrically: 4px face + 2px inset = rounded-md. 'inline-flex items-center gap-1.5 bg-bg-elevated border border-border-subtle rounded-md py-0.5 max-h-[24px]' const CHIP_LABEL = 'text-caption font-medium text-text-primary' const CHIP_REMOVE = 'size-4 flex items-center justify-center rounded-full hover:bg-bg-hover text-text-secondary' // The padding follows the contents (Katerina, 2026-09-01): a face sits 2px // from the edge, a bare label needs 8px of air; the ✕ brings its own box, so // 4px behind it — 8px when there isn't one. const chipPadding = (leading: boolean, removable: boolean) => cn(leading ? 'pl-[2px]' : 'pl-2', removable ? 'pr-1' : 'pr-2') /** * The chip a `ChipInput` is made of: a 24px pill with an optional 16px * leading (a face, an icon), a 12px label, and the ✕ that removes it. * Exported on its own (Katerina, 2026-09-01) under a name that promises * nothing about people — a chip like this may one day hold a label, a file, * a filter. * * Inside a `ChipInput` the chip is Base UI's `Combobox.Chip` wearing these * same classes, because there it has to answer the arrow keys and Backspace * along with the input. This component is for a chip standing alone. */ export interface InputChipProps { label: string /** Before the label, 16px — an Avatar, an icon. */ leading?: ReactNode /** Draws the ✕; absent, the chip is display-only. */ onRemove?: () => void /** * The ✕'s name for a screen reader. `Remove