diff --git a/.playground/pages/composant/input/inputUpload.vue b/.playground/pages/composant/input/inputUpload.vue index abb474a..5762dba 100644 --- a/.playground/pages/composant/input/inputUpload.vue +++ b/.playground/pages/composant/input/inputUpload.vue @@ -14,6 +14,17 @@

Valeur : {{ uploadValue || '(aucun)' }}

+
+

Clearable (croix pour vider)

+ +

Valeur : {{ clearableUpload || '(aucun)' }}

+
+

Avec accept (PDF)

{ + clearableUpload.value = '' +} const dynamicError = computed(() => { if (!dynamicUpload.value) return '' diff --git a/app/components/malio/input/InputUpload.vue b/app/components/malio/input/InputUpload.vue index 2923ae9..0c7861d 100644 --- a/app/components/malio/input/InputUpload.vue +++ b/app/components/malio/input/InputUpload.vue @@ -26,8 +26,10 @@ placeholder="_" type="text" @click="openFilePicker" - @focus="isFocused = true" - @blur="isFocused = false" + @keydown.enter.prevent="openFilePicker" + @keydown.space.prevent="openFilePicker" + @focus="isFocused = true; onKbdFocus()" + @blur="isFocused = false; onKbdBlur()" > - +
+ + +

(), { @@ -111,6 +133,7 @@ const props = withDefaults( displayIcon: true, accept: '', required: false, + clearable: false, reserveMessageSpace: true, }, ) @@ -143,6 +166,7 @@ const mergedGroupClass = computed(() => const mergedInputClass = computed(() => twMerge( 'floating-input peer min-h-[40px] w-full border bg-white pl-3 pr-3 py-1 outline-none placeholder:text-transparent text-lg rounded-md cursor-pointer', + keyboardFocused.value ? 'm-focus-ring-kbd' : '', isReadonly.value ? '' : 'grow-height', isReadonly.value ? 'border-black' @@ -153,7 +177,9 @@ const mergedInputClass = computed(() => : hasSuccess.value ? 'border-m-success focus:border-m-success [&:not(:placeholder-shown)]:border-m-success' : isReadonly.value ? '' : 'focus:border-m-primary', - props.displayIcon ? '!pr-10' : '', + showClear.value + ? (props.displayIcon ? '!pr-16' : '!pr-10') + : (props.displayIcon ? '!pr-10' : ''), isReadonly.value ? '' : 'focus:pl-[11px]', isReadonly.value ? 'cursor-default' : '', disabled.value ? 'cursor-not-allowed' : '', @@ -191,8 +217,21 @@ const describedBy = computed(() => { const emit = defineEmits<{ (event: 'update:modelValue', value: string): void (event: 'file-selected', file: File): void + (event: 'clear'): void }>() +const showClear = computed(() => + props.clearable && isFilled.value && !props.disabled && !isReadonly.value, +) + +const onClear = () => { + if (props.disabled || isReadonly.value) return + if (!isControlled.value) localValue.value = '' + if (fileInputRef.value) fileInputRef.value.value = '' + emit('update:modelValue', '') + emit('clear') +} + const openFilePicker = () => { if (props.disabled || props.readonly) return fileInputRef.value?.click()