{#if labelText || $$slots.labelChildren} {/if} {#if showInvalid} {/if} {#if showWarn} {/if} {#if filterable}
{#if selectionCount > 0} { selectedIds = []; sortedItems = sortedItems.map((item) => ({ ...item, checked: false, })); }} translateWithId={translateWithIdSelection} {disabled} {readonly} /> {/if} { if (disabled || readonly) return; open = true; }} on:keydown on:keydown|stopPropagation={(event) => { if (readonly) return; if (event.key === "Enter") { if (highlightedId) { const highlightedItem = sortedItems.find( (item) => item.id === highlightedId, ); if (highlightedItem) selectItem(highlightedItem); } } else if (event.key === "Tab") { open = false; } else if (event.key === "ArrowDown" || event.key === "ArrowUp") { const step = event.key === "ArrowDown" ? 1 : -1; if (event.altKey) { // APG combobox pattern: Alt+ArrowDown opens a closed menu // without moving the highlight; Alt+ArrowUp closes an open one. if (event.key === "ArrowDown" && !open) { open = true; } else if (event.key === "ArrowUp" && open) { close("escape-key"); } } else { if (!open) open = true; change(step); } } else if (event.key === "Escape") { close("escape-key"); } else if (event.key === " ") { if (!open) open = true; } else if (event.key === "Backspace" && value === "") { selectedIds = []; sortedItems = sortedItems.map((item) => ({ ...item, checked: false, })); } else if (event.key === "Delete") { if (open) { value = ""; } else { value = ""; selectedIds = []; sortedItems = sortedItems.map((item) => ({ ...item, checked: false, })); } } }} on:input on:input={() => { if (!open) open = true; }} on:keyup on:focus on:focus={() => { fieldFocused = true; }} on:blur on:blur={() => { fieldFocused = false; }} on:paste {disabled} {readonly} {placeholder} {id} {name} > {#if value} { value = ""; open = false; }} translateWithId={translateWithIdSelection} {disabled} {readonly} {open} /> {/if} { if (disabled || readonly) return; event.stopPropagation(); open = !open; }} {translateWithId} {open} />
{:else}
{ fieldFocused = true; }} on:click={() => { if (disabled || readonly) return; open = !open; }} on:keydown={(event) => { if ( event.key === " " || event.key === "Enter" || event.key === "ArrowUp" || event.key === "ArrowDown" ) { // Prevent the native button from synthesizing a click (which would // toggle the menu) so these keys are handled solely below. event.preventDefault(); } if (readonly) return; if (event.key === " ") { open = !open; } else if (event.key === "Tab") { open = false; } else if (event.key === "ArrowDown" || event.key === "ArrowUp") { const step = event.key === "ArrowDown" ? 1 : -1; if (event.altKey) { // APG combobox pattern: Alt+ArrowDown opens a closed menu // without moving the highlight; Alt+ArrowUp closes an open one. if (event.key === "ArrowDown" && !open) { open = true; } else if (event.key === "ArrowUp" && open) { close("escape-key"); } } else { if (!open) open = true; change(step); } } else if (event.key === "Enter") { if (highlightedIndex > -1) { const item = (filterable ? filteredItems : sortedItems)[ highlightedIndex ]; if (item) selectItem(item); } } else if (event.key === "Escape") { close("escape-key"); } }} on:blur={(event) => { fieldFocused = false; dispatch("blur", event); }} {id} {disabled} {readonly} {translateWithId} > {#if selectionCount > 0} { selectedIds = []; sortedItems = sortedItems.map((item) => ({ ...item, checked: false, })); }} translateWithId={translateWithIdSelection} {disabled} {readonly} /> {/if} {label}
{/if}
{ listScrollTop = event.target.scrollTop; }} on:mouseleave={() => { // Clear the hover highlight when the cursor leaves the menu so the // highlighted state does not linger on the last hovered item. highlightedIndex = -1; }} bind:ref={listRef} style={effectivePortalMenu ? `max-height: ${virtualConfig ? `${virtualConfig.containerHeight}px; overflow-y: auto` : menuMaxHeight};` : virtualConfig ? `max-height: ${virtualConfig.containerHeight}px; overflow-y: auto;` : undefined} > {#if virtualData?.isVirtualized}
{#each itemsToRender as item, index (item.id)} {@const actualIndex = virtualData.startIndex + index} { if (item.disabled) { event.stopPropagation(); return; } // Label default synthesizes a second click; without this, // selectItem runs twice and the toggle nets to no change. event.preventDefault(); selectItem(item); if (filterable) { inputRef?.focus(); } else { fieldRef?.focus(); } }} on:mouseenter={() => { if (item.disabled) return; highlightedIndex = actualIndex; }} > {itemToString(item)} {/each}
{:else} {#each itemsToRender as item, index (item.id)} { if (item.disabled) { event.stopPropagation(); return; } // Label default synthesizes a second click; without this, // selectItem runs twice and the toggle nets to no change. event.preventDefault(); selectItem(item); if (filterable) { inputRef?.focus(); } else { fieldRef?.focus(); } }} on:mouseenter={() => { if (item.disabled) return; highlightedIndex = index; }} > {itemToString(item)} {/each} {/if}
{#if isFluid}
{/if} {#if isFluid && showInvalid && invalidText}
{invalidText}
{/if} {#if isFluid && showWarn && warnText}
{warnText}
{/if} {#if !inline && !isFluid && !showInvalid && !showWarn && helperText}
{helperText}
{/if}