From 3d240048c797d2d4a1ab3fcceb9dad296211a5eb Mon Sep 17 00:00:00 2001 From: Elijah Duffy Date: Tue, 10 Mar 2026 14:55:44 -0700 Subject: [PATCH] combobox: improve icon padding behaviour Tween the value and make it more consistent with the underlying StyledRawInput type. --- src/lib/Combobox.svelte | 33 ++++++++++++++++++++++++++++----- 1 file changed, 28 insertions(+), 5 deletions(-) diff --git a/src/lib/Combobox.svelte b/src/lib/Combobox.svelte index b5fa110..0dcd0f6 100644 --- a/src/lib/Combobox.svelte +++ b/src/lib/Combobox.svelte @@ -50,6 +50,8 @@ import { matchSorter } from 'match-sorter'; import Spinner from './Spinner.svelte'; import type { KeyOption } from 'match-sorter'; + import { Tween } from 'svelte/motion'; + import { cubicOut } from 'svelte/easing'; interface Props { /** @@ -147,7 +149,6 @@ */ searchKeys?: ('value' | 'label' | 'preview' | 'infotext')[]; - // TODO: implement searchKeys above. /** Additional classes applied to the persistent div container */ class?: ClassValue | null | undefined; /** Optional action applied to the main input */ @@ -216,7 +217,6 @@ let searchValue = $state(''); let pickerPosition = $state<'top' | 'bottom'>('bottom'); let searching = $state(false); - let iconWidth = $state(undefined); let searchInput = $state(null); let searchContainer = $state(null); @@ -264,6 +264,29 @@ /** validation options build from props */ const validateOpts: ValidatorOptions = $derived({ required }); + /** calculates padding for the input based on icon visibility and size */ + const calculatePadding = () => { + const gap = 5; // gap between icon and text + // base padding when no icon is visible, see StyledRawInput padding + const basePadding = compact ? 12 : 18; + // if icon is visible, padding is icon width + gap + base padding, + // otherwise it's just base padding + return iconVisible ? iconWidth + gap + basePadding : basePadding; + }; + let iconWidth = $state(0); + /** tweens main input padding */ + const inputPadding = new Tween(calculatePadding(), { + duration: 150, + easing: cubicOut + }); + $effect(() => { + if (iconWidth >= 0) { + untrack(() => { + inputPadding.target = calculatePadding(); + }); + } + }); + /*** HELPER FUNCTIONS ***/ /** returns the index of the highlighted item in filteredItems */ @@ -637,8 +660,8 @@ {#if iconVisible}