/** * dsh-ui-tweaks — themed select menu (shared browser primitive). * * Reproduces the host's General-settings language selector * (`@deepseek-ai/dsh-client-locale` `LanguageRow`): a pill trigger plus a * portalled `role="menu"` card painted with the host menu tokens — lg-radius * translucent surface, prominent elevation, 34px rows with md-radius hover * fill, and a trailing check on the selected row. The primitives' own `Menu` * component is NOT importable here — that package is absent from this * plugin's `dsh.client.inject` whitelist, so the same markup and behavior is * reproduced with no new host dependency: * * - the trigger opens the card; arrows walk the rows; Enter/Space activate; * Escape closes and returns focus to the trigger (host Menu behavior); * - the card is portalled to `document.body` at z-index 1100 so it floats * above modal overlays, re-places itself on scroll/resize, and flips above * the trigger when the viewport has no room below; * - long lists (e.g. the GitBar branch picker) scroll inside a bounded card * with the host's scrollbar tokens, as the host Menu does. * * Styles install lazily and idempotently from the component itself, so every * consumer gets them without wiring. * @module dsh-ui-tweaks/client/select-menu */ /** One entry of a themed select menu. */ export interface SelectMenuEntry { value: string; label: string; } export declare const SELECT_MENU_CSS = "\n.dut-select-wrap{position:relative;display:inline-flex;flex:none}\n/* Chevron mirrors the language selector's trailing icon: the pill trigger is\n * a plain button (no native arrow), so the caret is drawn here with the\n * label-tertiary token (currentColor cannot reach a data-URI background). */\n.dut-select-wrap::after{content:'';position:absolute;right:14px;top:50%;width:7px;height:7px;margin-top:-4px;border-right:1.5px solid var(--dsw-alias-label-tertiary);border-bottom:1.5px solid var(--dsw-alias-label-tertiary);transform:rotate(45deg);pointer-events:none;transition:border-color .15s ease,opacity .15s ease}\n.dut-select-wrap:hover::after{border-color:var(--dsw-alias-label-primary)}\n.dut-select-wrap:has(button:disabled)::after{opacity:.45}\n/* Language-selector pill: radius-md token, module-platform fill, no border,\n * 36px height, 14px type \u2014 the host's General-settings selector recipe. */\n.dut-select-trigger{appearance:none;box-sizing:border-box;height:36px;min-width:200px;padding:0 36px 0 14px;border:none;border-radius:var(--dsw-radius-md);background:var(--dsw-alias-bg-module-platform);color:var(--dsw-alias-label-primary);font:inherit;font-size:14px;line-height:22px;text-align:left;cursor:pointer;transition:background .15s ease}\n.dut-select-trigger:hover{background:var(--dsw-alias-interactive-bg-hover)}\n.dut-select-trigger:focus-visible{outline:2px solid var(--dsw-alias-state-business-primary);outline-offset:1px}\n.dut-select-trigger:disabled{opacity:.5;cursor:not-allowed}\n/* Fill mode: the trigger stretches across the row's remaining width (GitBar\n * base-branch row), and the card pins to that same width so the two never\n * disagree. The wrap must take part in flex distribution (flex:1, not\n * width:100% \u2014 the base rule's flex:none would make an unshrinkable full-width\n * item and push the pill past its container). */\n.dut-select-wrap.dut-select-fill{display:flex;flex:1;min-width:0}\n.dut-select-wrap.dut-select-fill .dut-select-trigger{flex:1;min-width:0}\n/* Themed card mirroring the host Menu tokens (primitives Menu.module.css /\n * MenuSurface.module.css): 4px inset, lg-radius translucent surface,\n * prominent elevation, content-hugging width between the host's compact and\n * readable bounds (never the anchor's width \u2014 a fill-mode pill would stretch\n * the card across its dialog), host scrollbar rebinding for the bounded\n * viewport. */\n.dut-select-menu{position:fixed;z-index:1100;box-sizing:border-box;padding:4px;display:flex;flex-direction:column;gap:0;border:0;border-radius:var(--dsw-radius-lg);box-shadow:var(--dsw-elevation-prominent,var(--dsw-shadow-lv3));background:var(--dsw-menu-surface-fill,var(--dsw-alias-bg-layer-2));backdrop-filter:var(--dsw-menu-backdrop-filter,none);min-width:144px;max-width:360px;max-height:min(320px,calc(100vh - 24px));overflow-y:auto;--dsh-scrollbar-thumb:var(--dsw-alias-scrollbar-bg-l2);--dsh-scrollbar-thumb-hover:var(--dsw-alias-scrollbar-hover-l2)}\n.dut-select-menu-item{display:flex;align-items:center;gap:6px;width:100%;min-height:34px;padding:6px 8px;border:none;border-radius:var(--dsw-radius-md);background:transparent;cursor:pointer;font:inherit;font-size:13px;line-height:20px;color:var(--dsw-alias-label-primary);text-align:left}\n.dut-select-menu-item:hover,.dut-select-menu-item:focus-visible{background:var(--dsw-alias-interactive-bg-hover);outline:none}\n.dut-select-menu-label{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}\n.dut-select-menu-check{flex:none;display:inline-flex;width:14px;height:14px;color:var(--dsw-alias-label-primary);visibility:hidden}\n.dut-select-menu-item[aria-selected=\"true\"] .dut-select-menu-check{visibility:visible}\n"; /** Install the select-menu stylesheet once (idempotent); returns the disposer. */ export declare function installSelectMenuStyles(): () => void; export interface SelectMenuProps { /** Current value; the matching entry's label paints the trigger. */ value: string; entries: readonly SelectMenuEntry[]; disabled?: boolean; /** Accessible name for the trigger when no visible label points at it. */ ariaLabel?: string; /** * Stretch the trigger across its row (GitBar's base-branch row). A fill-mode * card pins to the trigger's exact width so the popup and the box stay * identical; the default content-hugging bounds (144–360px) apply otherwise. */ fill?: boolean; onChange: (value: string) => void; } export declare function SelectMenu({ value, entries, disabled, ariaLabel, fill, onChange }: SelectMenuProps): import("react").JSX.Element; //# sourceMappingURL=select-menu.d.ts.map