/* Autocomplete styles */ .autocomplete { @apply flex flex-col gap-1; } .autocomplete__trigger { @apply relative isolate inline-flex min-h-9 rounded-field border bg-field px-3 py-2 text-sm text-field-foreground shadow-field outline-none select-none no-highlight; /** * Transitions * CRITICAL: motion-reduce must be AFTER transition for correct override specificity */ transition: background-color 150ms var(--ease-smooth), border-color 150ms var(--ease-smooth), box-shadow 150ms var(--ease-out); @apply motion-reduce:transition-none; /* Cursor */ cursor: var(--cursor-interactive); border-width: var(--border-width-field); border-color: var(--field-border); /* Add inline-end padding when indicator is present */ &:has(.autocomplete__indicator) { @apply pe-7; } /* Hover state - exclude when clear button is hovered to prevent double hover effect */ @media (hover: hover) { &:hover:not(:has(.autocomplete__clear-button:hover)), &[data-hovered="true"]:not(:has(.autocomplete__clear-button:hover)) { @apply bg-field-hover; border-color: var(--field-border-hover); } } /* Focus visible state */ &:focus-visible:not(:focus), &[data-focus-visible="true"] { @apply status-focused; border-color: var(--field-border-focus); background-color: var(--field-focus); } /* Focus state */ &:focus, &[data-focus="true"] { } /* Invalid state */ .autocomplete[data-invalid="true"] &, .autocomplete[aria-invalid="true"] & { @apply status-invalid-field; background-color: var(--field-focus); } /* Disabled state */ &:disabled, &[data-disabled="true"], &[aria-disabled="true"] { @apply status-disabled; } } /* Variant property definitions */ .autocomplete--primary { /* Default styles */ } .autocomplete--secondary .autocomplete__trigger { @apply shadow-none; background-color: var(--autocomplete-trigger-bg); --autocomplete-trigger-bg: var(--default); --autocomplete-trigger-bg-hover: var(--default-hover); --autocomplete-trigger-bg-focus: var(--default); /* Exclude when clear button is hovered to prevent double hover effect */ @media (hover: hover) { &:hover:not(:has(.autocomplete__clear-button:hover)), &[data-hovered="true"]:not(:has(.autocomplete__clear-button:hover)) { background-color: var(--autocomplete-trigger-bg-hover); } } &:focus-visible:not(:focus), &[data-focus-visible="true"] { background-color: var(--autocomplete-trigger-bg-focus); } &:focus, &[data-focus="true"] { } .autocomplete[data-invalid="true"] &, .autocomplete[aria-invalid="true"] & { background-color: var(--autocomplete-trigger-bg-focus); } } .autocomplete__value { @apply flex-1 text-start text-base wrap-break-word text-current sm:text-sm; &[data-placeholder="true"] { @apply text-field-placeholder; } /* Removes the list-box-item indicator element from the autocomplete value*/ [data-slot="list-box-item-indicator"] { @apply hidden; } } .autocomplete__indicator { @apply absolute inset-y-0 end-2 my-auto flex shrink-0 items-center justify-center text-field-placeholder transition duration-150; /* Cursor */ cursor: var(--cursor-interactive); &[data-open="true"] { @apply rotate-180; } &[data-slot="autocomplete-default-indicator"] { @apply size-4; } } /* Similar to popover content styles */ .autocomplete__popover { @apply w-(--trigger-width) max-w-(--trigger-width) origin-(--trigger-anchor-point) scroll-py-1 overflow-hidden overscroll-contain bg-overlay p-0 pt-2 text-sm; border-radius: min(32px, var(--radius-3xl)); box-shadow: var(--shadow-overlay); /* Focus state */ &:focus-visible:not(:focus), &[data-focus-visible="true"] { @apply outline-none; } /* Entering animations */ &[data-entering="true"] { @apply animate-in duration-250 ease-out-fluid fade-in-0 zoom-in-95; /* Placement-specific translations */ &[data-placement="top"] { @apply slide-in-from-bottom-1; } &[data-placement="bottom"] { @apply slide-in-from-top-1; } &[data-placement="left"] { @apply slide-in-from-right-1; } &[data-placement="right"] { @apply slide-in-from-left-1; } } /* Exiting animations */ &[data-exiting="true"] { @apply animate-out duration-100 ease-out-quad zoom-out-95 fade-out; } &[data-exiting="true"], &[data-entering="true"] { @apply transition-[opacity,transform] will-change-[opacity,transform]; } /* Arrow styling */ & [data-slot="popover-overlay-arrow"] { fill: var(--overlay); } /* Arrow rotation based on placement */ &[data-placement="bottom"] [data-slot="popover-overlay-arrow"] { rotate: 180deg; } &[data-placement="left"] [data-slot="popover-overlay-arrow"] { rotate: -90deg; } &[data-placement="right"] [data-slot="popover-overlay-arrow"] { rotate: 90deg; } /* Listbox styles */ [data-slot="list-box"] { @apply max-h-[320px] scrollbar overflow-y-auto p-1.5 outline-none; } [data-slot="list-box-item"] { @apply px-2.5; } /* Virtualized rows: react-aria's Virtualizer wraps each row in an absolutely-positioned * [role="presentation"] element whose width equals the scroll container's clientWidth * (which includes the list-box horizontal padding) while sitting inside the padded content * box. Without this, rows overflow the right padding and the hover background reaches the * popover edge. Subtract the horizontal padding (2 × p-1.5 = 12px) to keep rows aligned. */ [role="presentation"] > [data-slot="list-box-item"] { width: calc(100% - var(--spacing) * 3); } /* As the popover closes fast in single-select mode, the default item indicator transition is not even visible - so we disable it only for single-select */ [data-slot="list-box"]:not([aria-multiselectable="true"]) [data-slot="list-box-item-indicator"], [data-slot="list-box"]:not([aria-multiselectable="true"]) [data-slot="list-box-item-indicator"] [data-slot="list-box-item-indicator--checkmark"] { @apply transition-none; } /* Search Field styles */ [data-slot="search-field"] { @apply px-3 py-1 outline-none; } /* Empty State */ [data-slot="empty-state"] { @apply text-center text-sm text-overlay-foreground/60; } } /* Popover dialog — mirrors Popover.Dialog focus management without a visible focus ring */ .autocomplete__popover-dialog { @apply outline-none; &:focus, &:focus-visible, &[data-focus-visible="true"] { @apply outline-none; } } /* Full width modifier */ .autocomplete--full-width { @apply w-full; } .autocomplete__trigger--full-width { @apply w-full; } /* Clear Button styles */ .autocomplete__clear-button { @apply relative isolate inline-flex h-6 w-6 shrink-0 origin-center items-center justify-center rounded-xl p-1 text-muted select-none no-highlight; @apply me-0 size-5 shrink-0 self-center bg-transparent; /* Cursor */ cursor: var(--cursor-interactive); @apply transform-gpu; /* Transition only when visible - disappears immediately when cleared */ &:not([data-empty="true"]) { transition: opacity 150ms var(--ease-smooth); @apply motion-reduce:transition-none; } &[data-empty="true"] { @apply pointer-events-none opacity-0; } [data-slot="autocomplete-clear-button-icon"] { @apply size-3.5; } &:active, &[data-pressed="true"] { } @media (hover: hover) { &:hover, &[data-hovered="true"] { @apply bg-default-hover; } } &:active, &[data-pressed="true"] { transform: scale(0.93); } }