feat(ui) : cohérence du mode disabled sur la famille formulaire
Calqué sur InputText (texte + label grisés, cursor-not-allowed, aucune affordance interactive). Quand disabled : - bouton « + » d'ajout masqué (InputPhone, InputEmail) - œil de révélation masqué (InputPassword) - chevron masqué (Select, SelectCheckbox, InputAutocomplete) - croix d'effacement déjà masquée (date, upload, time) - label en text-m-muted (Select, SelectCheckbox, CalendarField → famille Date, TimePicker, InputNumber aligné) - tags du SelectCheckbox + valeur du Select grisés ; icône horloge (TimePicker) et icône calendrier (date, même rempli) grisées Playground : page « Champs disabled » (DIVERS) en miroir de la page readonly, avec le SelectCheckbox en version tags. Tests par composant ajoutés/adaptés. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -237,12 +237,21 @@ describe('MalioSelect', () => {
|
||||
expect(wrapper.get('[data-test="chevron"]').classes()).toContain('text-black')
|
||||
})
|
||||
|
||||
it('shows muted chevron color when disabled', () => {
|
||||
it('hides the chevron when disabled', () => {
|
||||
const wrapper = mount(SelectForTest, {
|
||||
props: {modelValue: 'fr', options, disabled: true},
|
||||
})
|
||||
|
||||
expect(wrapper.get('[data-test="chevron"]').classes()).toContain('text-m-muted')
|
||||
expect(wrapper.find('[data-test="chevron"]').exists()).toBe(false)
|
||||
})
|
||||
|
||||
it('greys the label and the selected value when disabled', () => {
|
||||
const wrapper = mount(SelectForTest, {
|
||||
props: {modelValue: 'fr', label: 'Pays', options, disabled: true},
|
||||
})
|
||||
|
||||
expect(wrapper.get('label').classes()).toContain('text-m-muted')
|
||||
expect(wrapper.get('button span.block').classes()).toContain('text-black/60')
|
||||
})
|
||||
|
||||
it('shows danger chevron color on error even when open', async () => {
|
||||
|
||||
@@ -65,15 +65,17 @@
|
||||
? 'text-m-danger'
|
||||
: hasSuccess
|
||||
? 'text-m-success'
|
||||
: isReadonly
|
||||
? isOptionSelected
|
||||
? 'text-black'
|
||||
: 'text-m-muted'
|
||||
: isOpen
|
||||
? 'text-m-primary'
|
||||
: isOptionSelected
|
||||
: disabled
|
||||
? 'text-m-muted'
|
||||
: isReadonly
|
||||
? isOptionSelected
|
||||
? 'text-black'
|
||||
: 'text-m-muted',
|
||||
: 'text-m-muted'
|
||||
: isOpen
|
||||
? 'text-m-primary'
|
||||
: isOptionSelected
|
||||
? 'text-black'
|
||||
: 'text-m-muted',
|
||||
textLabel,
|
||||
]"
|
||||
:style="labelTransformStyle"
|
||||
@@ -85,13 +87,14 @@
|
||||
class="block truncate"
|
||||
:class="[
|
||||
textValue,
|
||||
isOptionSelected ? 'text-black' : 'select-none text-transparent'
|
||||
isOptionSelected ? (disabled ? 'text-black/60' : 'text-black') : 'select-none text-transparent'
|
||||
]"
|
||||
>
|
||||
{{ selectedLabel || '\u00A0' }}
|
||||
</span>
|
||||
|
||||
<span
|
||||
v-if="!disabled"
|
||||
data-test="chevron"
|
||||
class="absolute right-3 top-1/2 -translate-y-1/2"
|
||||
:class="[
|
||||
|
||||
@@ -227,12 +227,23 @@ describe('MalioSelectCheckbox', () => {
|
||||
expect(wrapper.get('[data-test="chevron"]').classes()).toContain('text-black')
|
||||
})
|
||||
|
||||
it('shows muted chevron color when disabled', () => {
|
||||
it('hides the chevron when disabled', () => {
|
||||
const wrapper = mount(SelectCheckboxForTest, {
|
||||
props: {modelValue: ['fr'], options, disabled: true},
|
||||
})
|
||||
|
||||
expect(wrapper.get('[data-test="chevron"]').classes()).toContain('text-m-muted')
|
||||
expect(wrapper.find('[data-test="chevron"]').exists()).toBe(false)
|
||||
})
|
||||
|
||||
it('greys the label and the tags when disabled', () => {
|
||||
const wrapper = mount(SelectCheckboxForTest, {
|
||||
props: {modelValue: ['fr'], label: 'Pays', options, displayTag: true, disabled: true},
|
||||
})
|
||||
|
||||
expect(wrapper.get('label').classes()).toContain('text-m-muted')
|
||||
const tag = wrapper.findAll('span.inline-flex')[0]
|
||||
expect(tag.classes()).toContain('text-black/60')
|
||||
expect(tag.classes()).not.toContain('text-black')
|
||||
})
|
||||
|
||||
it('shows danger chevron color on error even when open', async () => {
|
||||
|
||||
@@ -65,15 +65,17 @@
|
||||
? 'text-m-danger'
|
||||
: hasSuccess
|
||||
? 'text-m-success'
|
||||
: isReadonly
|
||||
? isOptionSelected
|
||||
? 'text-black'
|
||||
: 'text-m-muted'
|
||||
: isOpen
|
||||
? 'text-m-primary'
|
||||
: isOptionSelected
|
||||
: disabled
|
||||
? 'text-m-muted'
|
||||
: isReadonly
|
||||
? isOptionSelected
|
||||
? 'text-black'
|
||||
: 'text-m-muted',
|
||||
: 'text-m-muted'
|
||||
: isOpen
|
||||
? 'text-m-primary'
|
||||
: isOptionSelected
|
||||
? 'text-black'
|
||||
: 'text-m-muted',
|
||||
textLabel,
|
||||
]"
|
||||
:style="labelTransformStyle"
|
||||
@@ -89,7 +91,8 @@
|
||||
<span
|
||||
v-for="option in selectedOptions"
|
||||
:key="String(option.value)"
|
||||
class="inline-flex max-w-full items-center rounded-md border border-black px-2 text-sm leading-none text-black"
|
||||
class="inline-flex max-w-full items-center rounded-md border px-2 text-sm leading-none"
|
||||
:class="disabled ? 'border-black/40 text-black/60' : 'border-black text-black'"
|
||||
>
|
||||
<span class="truncate pb-[2px]">{{ option.label }}</span>
|
||||
</span>
|
||||
@@ -113,13 +116,14 @@
|
||||
:class="[
|
||||
textValue,
|
||||
label ? 'pl-24' : '',
|
||||
isOptionSelected ? 'text-black' : 'text-m-muted'
|
||||
disabled ? 'text-black/60' : isOptionSelected ? 'text-black' : 'text-m-muted'
|
||||
]"
|
||||
>
|
||||
{{ selectionSummary }}
|
||||
</span>
|
||||
|
||||
<span
|
||||
v-if="!disabled"
|
||||
data-test="chevron"
|
||||
class="absolute right-3 top-1/2 -translate-y-1/2"
|
||||
:class="[
|
||||
|
||||
Reference in New Issue
Block a user