From dc33cf4135673194d304542030d832e598b3c63e Mon Sep 17 00:00:00 2001 From: tristan Date: Fri, 29 May 2026 15:19:41 +0200 Subject: [PATCH] feat(inputs): UX polish across input family + localFilter + focus scrollbar MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Polish across the form input components, plus two new features and a few standalone fixes. Fixes ----- * Reserve hint/error/success paragraph space (min-h-[1rem]) in 15 components so a single error message no longer shifts neighboring grid cells: InputText, Email, Password, Phone, Amount, Number, Upload, Autocomplete, RichText, TextArea, Select, SelectCheckbox, Time, TimePicker, CalendarField, Checkbox. * InputPhone: the '+' add button now follows the icon-state cascade (muted / primary on focus / black when filled / danger / success) like the other field icons instead of being permanently primary. * Select and SelectCheckbox: chevron color follows the field state (muted by default, primary when open, black when an option is selected, danger / success on error / success) instead of always being text-current. * InputTextArea: single-root component (was multi-root). The message wrapper used to occupy its own grid cell, breaking row-span layouts. Now flex flex-col, with the textarea area filling the available height via flex-1 and the message inside the same root. * Disabled labels use text-m-muted (border-gray) instead of text-black/60 (dark) across InputText, Email, Password, Amount, Phone, Upload, Autocomplete, TextArea, RichText. Also removes an unreachable peer-[&:not(:placeholder-shown):not(:focus)]:text-black/60 rule that twMerge was silently overriding with text-black. * InputAutocomplete: eliminates four sources of visual jitter when focusing / opening a field that already has a selected value. - Drop peer-focus:-translate-y-[1.55rem] extra label translate. - Drop the .grow-height:focus padding rule (no more height growth or downward text shift on focus). - Drop focus:pl-[11px] (no more 1px horizontal jump). - Replace !border-b-0 with !border-b-transparent so the bottom border still reserves its 1px while remaining invisible against the dropdown. * Select / SelectCheckbox: same anti-jitter treatment. - Drop .grow-height:focus padding rule (~12px height growth gone). - Replace !border-b-0 / !border-t-0 with !border-b-transparent / !border-t-transparent across danger / success / primary branches. * Button: default width 240px -> 200px to match the form button sizing used across the app. Test updated to match. Features -------- * InputTextArea: scrollbar turns primary blue on focus (scrollbar-color: rgb(var(--m-primary)) transparent), matching the Select listbox styling. * InputAutocomplete: new localFilter prop (default false). When enabled, filters the options prop client-side based on the input value (case-insensitive label.includes(query)), so static lists no longer need a @search listener. Async/API usage keeps the existing behavior. Playground "Simple statique" and "Avec icône à gauche" examples use local-filter. Playground ---------- * client.vue: tighter grid gap (gap-y-5) plus an example error on a SelectCheckbox to visually exercise the message-space fix. Tests ----- All component test files include regression coverage for the above. 720/720 tests pass. Co-Authored-By: Claude Opus 4.7 (1M context) --- .playground/pages/composant/form/client.vue | 7 +- .../composant/input/inputAutocomplete.vue | 2 + CHANGELOG.md | 10 ++ COMPONENTS.md | 7 +- app/components/malio/button/Button.test.ts | 2 +- app/components/malio/button/Button.vue | 2 +- app/components/malio/checkbox/Checkbox.vue | 3 +- .../malio/date/internal/CalendarField.vue | 3 +- app/components/malio/input/Input.test.ts | 16 ++ app/components/malio/input/InputAmount.vue | 10 +- .../malio/input/InputAutocomplete.test.ts | 79 ++++++++++ .../malio/input/InputAutocomplete.vue | 48 +++--- app/components/malio/input/InputEmail.vue | 8 +- app/components/malio/input/InputNumber.vue | 3 +- app/components/malio/input/InputPassword.vue | 8 +- app/components/malio/input/InputPhone.test.ts | 35 +++++ app/components/malio/input/InputPhone.vue | 11 +- app/components/malio/input/InputRichText.vue | 12 +- app/components/malio/input/InputText.vue | 8 +- .../malio/input/InputTextArea.test.ts | 34 ++++ app/components/malio/input/InputTextArea.vue | 147 +++++++++--------- app/components/malio/input/InputUpload.vue | 8 +- app/components/malio/select/Select.test.ts | 66 ++++++++ app/components/malio/select/Select.vue | 31 ++-- .../malio/select/SelectCheckbox.test.ts | 66 ++++++++ .../malio/select/SelectCheckbox.vue | 31 ++-- app/components/malio/time/Time.vue | 3 +- app/components/malio/time/TimePicker.vue | 3 +- 28 files changed, 489 insertions(+), 174 deletions(-) diff --git a/.playground/pages/composant/form/client.vue b/.playground/pages/composant/form/client.vue index e2887a1..3650407 100644 --- a/.playground/pages/composant/form/client.vue +++ b/.playground/pages/composant/form/client.vue @@ -10,7 +10,7 @@ />

Ajouter un client

-
+
@@ -22,6 +22,7 @@ />