add clearable prop to Input component

This commit is contained in:
Justin Edmund 2025-12-21 02:56:36 -08:00
parent 3340e3661f
commit b60eca43be

View file

@ -10,6 +10,8 @@
label?: string label?: string
leftIcon?: string leftIcon?: string
rightIcon?: string rightIcon?: string
clearable?: boolean
onClear?: () => void
counter?: number counter?: number
maxLength?: number maxLength?: number
hidden?: boolean hidden?: boolean
@ -31,6 +33,8 @@
label, label,
leftIcon, leftIcon,
rightIcon, rightIcon,
clearable = false,
onClear,
counter, counter,
maxLength, maxLength,
hidden = false, hidden = false,
@ -69,7 +73,12 @@
const showCounter = $derived( const showCounter = $derived(
counter !== undefined || (charsRemaining !== undefined && charsRemaining <= 5) counter !== undefined || (charsRemaining !== undefined && charsRemaining <= 5)
) )
const hasWrapper = $derived(accessory || leftIcon || rightIcon || maxLength !== undefined || validationIcon) const hasWrapper = $derived(accessory || leftIcon || rightIcon || clearable || maxLength !== undefined || validationIcon)
function handleClear() {
value = ''
onClear?.()
}
const fieldsetClasses = $derived( const fieldsetClasses = $derived(
['fieldset', hidden && 'hidden', fullWidth && 'full', className].filter(Boolean).join(' ') ['fieldset', hidden && 'hidden', fullWidth && 'full', className].filter(Boolean).join(' ')
@ -92,11 +101,6 @@
.join(' ') .join(' ')
) )
// Debug: log what's in restProps
$effect(() => {
console.log('[Input] restProps keys:', Object.keys(restProps))
console.log('[Input] hasWrapper:', hasWrapper, 'validationIcon:', validationIcon)
})
</script> </script>
<fieldset class={fieldsetClasses}> <fieldset class={fieldsetClasses}>
@ -144,6 +148,12 @@
</span> </span>
{/if} {/if}
{#if clearable && value}
<button type="button" class="clearButton" onclick={handleClear}>
<Icon name="close" size={14} />
</button>
{/if}
{#if showCounter} {#if showCounter}
<span class="counter" class:warning={charsRemaining !== undefined && charsRemaining <= 5}> <span class="counter" class:warning={charsRemaining !== undefined && charsRemaining <= 5}>
{charsRemaining !== undefined ? charsRemaining : currentCount} {charsRemaining !== undefined ? charsRemaining : currentCount}
@ -345,6 +355,32 @@
} }
} }
.clearButton {
position: absolute;
right: $unit-2x;
display: flex;
align-items: center;
justify-content: center;
width: 20px;
height: 20px;
padding: 0;
border: none;
background: transparent;
color: var(--text-secondary);
cursor: pointer;
border-radius: $unit-half;
@include smooth-transition($duration-quick, background-color, color);
&:hover {
background: var(--surface-tertiary);
color: var(--text-primary);
}
:global(svg) {
fill: currentColor;
}
}
&:has(.iconLeft) input { &:has(.iconLeft) input {
padding-left: $unit-5x; padding-left: $unit-5x;
} }
@ -357,6 +393,10 @@
padding-right: $unit-5x; padding-right: $unit-5x;
} }
&:has(.clearButton) input {
padding-right: $unit-5x;
}
&:has(.counter) input { &:has(.counter) input {
padding-right: $unit-8x; padding-right: $unit-8x;
} }