feat(ui) : required cohérent + astérisque label + sanitisation email (MUI-41) #60
@@ -24,6 +24,7 @@ type InputProps = {
|
|||||||
iconPosition?: 'left' | 'right'
|
iconPosition?: 'left' | 'right'
|
||||||
iconSize?: string | number
|
iconSize?: string | number
|
||||||
iconColor?: string
|
iconColor?: string
|
||||||
|
reserveMessageSpace?: boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
const InputForTest = Input as DefineComponent<InputProps>
|
const InputForTest = Input as DefineComponent<InputProps>
|
||||||
@@ -279,6 +280,25 @@ describe('MalioInputText', () => {
|
|||||||
expect(p.classes()).toContain('min-h-[1rem]')
|
expect(p.classes()).toContain('min-h-[1rem]')
|
||||||
})
|
})
|
||||||
|
|
||||||
|
it('réserve l’espace message par défaut même sans message', () => {
|
||||||
|
const wrapper = mountInput({label: 'Champ'})
|
||||||
|
const msg = wrapper.find('[id$="-describedby"]')
|
||||||
|
expect(msg.exists()).toBe(true)
|
||||||
|
expect(msg.classes()).toContain('min-h-[1rem]')
|
||||||
|
})
|
||||||
|
|
||||||
|
it('reserveMessageSpace=false sans message : pas de ligne réservée', () => {
|
||||||
|
const wrapper = mountInput({label: 'Champ', reserveMessageSpace: false})
|
||||||
|
expect(wrapper.find('[id$="-describedby"]').exists()).toBe(false)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('reserveMessageSpace=false avec message : ligne rendue sans min-h', () => {
|
||||||
|
const wrapper = mountInput({label: 'Champ', reserveMessageSpace: false, error: 'Erreur'})
|
||||||
|
const msg = wrapper.find('[id$="-describedby"]')
|
||||||
|
expect(msg.exists()).toBe(true)
|
||||||
|
expect(msg.classes()).not.toContain('min-h-[1rem]')
|
||||||
|
})
|
||||||
|
|
||||||
it('does not render label when label prop is missing', () => {
|
it('does not render label when label prop is missing', () => {
|
||||||
const wrapper = mountInput({labelClass: 'text-red-500'})
|
const wrapper = mountInput({labelClass: 'text-red-500'})
|
||||||
|
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ type InputAmountProps = {
|
|||||||
iconPosition?: 'left' | 'right'
|
iconPosition?: 'left' | 'right'
|
||||||
iconSize?: string | number
|
iconSize?: string | number
|
||||||
iconColor?: string
|
iconColor?: string
|
||||||
|
reserveMessageSpace?: boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
const InputAmountForTest = InputAmount as DefineComponent<InputAmountProps>
|
const InputAmountForTest = InputAmount as DefineComponent<InputAmountProps>
|
||||||
@@ -210,4 +211,23 @@ describe('MalioInputAmount', () => {
|
|||||||
expect(wrapper.get('label').classes()).toContain('text-black')
|
expect(wrapper.get('label').classes()).toContain('text-black')
|
||||||
expect(wrapper.get('[data-test="icon"]').classes()).toContain('text-black')
|
expect(wrapper.get('[data-test="icon"]').classes()).toContain('text-black')
|
||||||
})
|
})
|
||||||
|
|
||||||
|
it('réserve l’espace message par défaut même sans message', () => {
|
||||||
|
const wrapper = mountInputAmount({label: 'Champ'})
|
||||||
|
const msg = wrapper.find('[id$="-describedby"]')
|
||||||
|
expect(msg.exists()).toBe(true)
|
||||||
|
expect(msg.classes()).toContain('min-h-[1rem]')
|
||||||
|
})
|
||||||
|
|
||||||
|
it('reserveMessageSpace=false sans message : pas de ligne réservée', () => {
|
||||||
|
const wrapper = mountInputAmount({label: 'Champ', reserveMessageSpace: false})
|
||||||
|
expect(wrapper.find('[id$="-describedby"]').exists()).toBe(false)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('reserveMessageSpace=false avec message : ligne rendue sans min-h', () => {
|
||||||
|
const wrapper = mountInputAmount({label: 'Champ', reserveMessageSpace: false, error: 'Erreur'})
|
||||||
|
const msg = wrapper.find('[id$="-describedby"]')
|
||||||
|
expect(msg.exists()).toBe(true)
|
||||||
|
expect(msg.classes()).not.toContain('min-h-[1rem]')
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -44,6 +44,7 @@
|
|||||||
|
|
||||||
</div>
|
</div>
|
||||||
<p
|
<p
|
||||||
|
v-if="reserveMessageSpace || hint || error || success"
|
||||||
:id="`${inputId}-describedby`"
|
:id="`${inputId}-describedby`"
|
||||||
:class="[
|
:class="[
|
||||||
hasError
|
hasError
|
||||||
@@ -51,7 +52,8 @@
|
|||||||
: hasSuccess
|
: hasSuccess
|
||||||
? 'text-m-success'
|
? 'text-m-success'
|
||||||
: 'text-m-muted',
|
: 'text-m-muted',
|
||||||
'mt-1 text-xs ml-[2px] min-h-[1rem]',
|
'mt-1 text-xs ml-[2px]',
|
||||||
|
reserveMessageSpace ? 'min-h-[1rem]' : '',
|
||||||
]"
|
]"
|
||||||
>
|
>
|
||||||
{{ hint || error || success }}
|
{{ hint || error || success }}
|
||||||
@@ -89,6 +91,7 @@ const props = withDefaults(
|
|||||||
iconPosition?: 'left' | 'right'
|
iconPosition?: 'left' | 'right'
|
||||||
iconSize?: string | number
|
iconSize?: string | number
|
||||||
iconColor?: string
|
iconColor?: string
|
||||||
|
reserveMessageSpace?: boolean
|
||||||
}>(),
|
}>(),
|
||||||
{
|
{
|
||||||
id: '',
|
id: '',
|
||||||
@@ -111,6 +114,7 @@ const props = withDefaults(
|
|||||||
success: '',
|
success: '',
|
||||||
iconSize: 20,
|
iconSize: 20,
|
||||||
iconColor: 'text-m-muted',
|
iconColor: 'text-m-muted',
|
||||||
|
reserveMessageSpace: true,
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -36,6 +36,7 @@ type InputAutocompleteProps = {
|
|||||||
noResultsText?: string
|
noResultsText?: string
|
||||||
loadingText?: string
|
loadingText?: string
|
||||||
minSearchText?: string
|
minSearchText?: string
|
||||||
|
reserveMessageSpace?: boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
const InputAutocompleteForTest = InputAutocomplete as DefineComponent<InputAutocompleteProps>
|
const InputAutocompleteForTest = InputAutocomplete as DefineComponent<InputAutocompleteProps>
|
||||||
@@ -543,4 +544,23 @@ describe('MalioInputAutocomplete', () => {
|
|||||||
expect(wrapper.get('[data-test="icon-left"]').classes()).toContain('text-black')
|
expect(wrapper.get('[data-test="icon-left"]').classes()).toContain('text-black')
|
||||||
expect(wrapper.get('[data-test="chevron"]').classes()).toContain('text-black')
|
expect(wrapper.get('[data-test="chevron"]').classes()).toContain('text-black')
|
||||||
})
|
})
|
||||||
|
|
||||||
|
it('réserve l’espace message par défaut même sans message', () => {
|
||||||
|
const wrapper = mountComponent({label: 'Champ', options})
|
||||||
|
const msg = wrapper.find('[id$="-describedby"]')
|
||||||
|
expect(msg.exists()).toBe(true)
|
||||||
|
expect(msg.classes()).toContain('min-h-[1rem]')
|
||||||
|
})
|
||||||
|
|
||||||
|
it('reserveMessageSpace=false sans message : pas de ligne réservée', () => {
|
||||||
|
const wrapper = mountComponent({label: 'Champ', options, reserveMessageSpace: false})
|
||||||
|
expect(wrapper.find('[id$="-describedby"]').exists()).toBe(false)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('reserveMessageSpace=false avec message : ligne rendue sans min-h', () => {
|
||||||
|
const wrapper = mountComponent({label: 'Champ', options, reserveMessageSpace: false, error: 'Erreur'})
|
||||||
|
const msg = wrapper.find('[id$="-describedby"]')
|
||||||
|
expect(msg.exists()).toBe(true)
|
||||||
|
expect(msg.classes()).not.toContain('min-h-[1rem]')
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -136,10 +136,12 @@
|
|||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
<p
|
<p
|
||||||
|
v-if="reserveMessageSpace || hint || error || success"
|
||||||
:id="`${inputId}-describedby`"
|
:id="`${inputId}-describedby`"
|
||||||
:class="[
|
:class="[
|
||||||
hasError ? 'text-m-danger' : hasSuccess ? 'text-m-success' : 'text-m-muted',
|
hasError ? 'text-m-danger' : hasSuccess ? 'text-m-success' : 'text-m-muted',
|
||||||
'mt-1 ml-[2px] text-xs min-h-[1rem]',
|
'mt-1 ml-[2px] text-xs',
|
||||||
|
reserveMessageSpace ? 'min-h-[1rem]' : '',
|
||||||
]"
|
]"
|
||||||
>
|
>
|
||||||
{{ hint || error || success }}
|
{{ hint || error || success }}
|
||||||
@@ -188,6 +190,7 @@ const props = withDefaults(
|
|||||||
noResultsText?: string
|
noResultsText?: string
|
||||||
loadingText?: string
|
loadingText?: string
|
||||||
minSearchText?: string
|
minSearchText?: string
|
||||||
|
reserveMessageSpace?: boolean
|
||||||
}>(),
|
}>(),
|
||||||
{
|
{
|
||||||
id: '',
|
id: '',
|
||||||
@@ -216,6 +219,7 @@ const props = withDefaults(
|
|||||||
noResultsText: 'Aucun résultat',
|
noResultsText: 'Aucun résultat',
|
||||||
loadingText: 'Chargement…',
|
loadingText: 'Chargement…',
|
||||||
minSearchText: 'Tapez pour rechercher',
|
minSearchText: 'Tapez pour rechercher',
|
||||||
|
reserveMessageSpace: true,
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ type InputEmailProps = {
|
|||||||
iconSize?: string | number
|
iconSize?: string | number
|
||||||
iconColor?: string
|
iconColor?: string
|
||||||
lowercase?: boolean
|
lowercase?: boolean
|
||||||
|
reserveMessageSpace?: boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
const InputEmailForTest = InputEmail as DefineComponent<InputEmailProps>
|
const InputEmailForTest = InputEmail as DefineComponent<InputEmailProps>
|
||||||
@@ -295,4 +296,23 @@ describe('MalioInputEmail', () => {
|
|||||||
expect(wrapper.get('label').classes()).toContain('text-black')
|
expect(wrapper.get('label').classes()).toContain('text-black')
|
||||||
expect(wrapper.get('[data-test="icon"]').classes()).toContain('text-black')
|
expect(wrapper.get('[data-test="icon"]').classes()).toContain('text-black')
|
||||||
})
|
})
|
||||||
|
|
||||||
|
it('réserve l’espace message par défaut même sans message', () => {
|
||||||
|
const wrapper = mountComponent({label: 'Champ'})
|
||||||
|
const msg = wrapper.find('[id$="-describedby"]')
|
||||||
|
expect(msg.exists()).toBe(true)
|
||||||
|
expect(msg.classes()).toContain('min-h-[1rem]')
|
||||||
|
})
|
||||||
|
|
||||||
|
it('reserveMessageSpace=false sans message : pas de ligne réservée', () => {
|
||||||
|
const wrapper = mountComponent({label: 'Champ', reserveMessageSpace: false})
|
||||||
|
expect(wrapper.find('[id$="-describedby"]').exists()).toBe(false)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('reserveMessageSpace=false avec message : ligne rendue sans min-h', () => {
|
||||||
|
const wrapper = mountComponent({label: 'Champ', reserveMessageSpace: false, error: 'Erreur'})
|
||||||
|
const msg = wrapper.find('[id$="-describedby"]')
|
||||||
|
expect(msg.exists()).toBe(true)
|
||||||
|
expect(msg.classes()).not.toContain('min-h-[1rem]')
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -42,6 +42,7 @@
|
|||||||
|
|
||||||
</div>
|
</div>
|
||||||
<p
|
<p
|
||||||
|
v-if="reserveMessageSpace || hint || error || success"
|
||||||
:id="`${inputId}-describedby`"
|
:id="`${inputId}-describedby`"
|
||||||
:class="[
|
:class="[
|
||||||
hasError
|
hasError
|
||||||
@@ -49,7 +50,8 @@
|
|||||||
: hasSuccess
|
: hasSuccess
|
||||||
? 'text-m-success'
|
? 'text-m-success'
|
||||||
: 'text-m-muted',
|
: 'text-m-muted',
|
||||||
'mt-1 text-xs ml-[2px] min-h-[1rem]',
|
'mt-1 text-xs ml-[2px]',
|
||||||
|
reserveMessageSpace ? 'min-h-[1rem]' : '',
|
||||||
]"
|
]"
|
||||||
>
|
>
|
||||||
{{ hint || error || success }}
|
{{ hint || error || success }}
|
||||||
@@ -87,6 +89,7 @@ const props = withDefaults(
|
|||||||
iconSize?: string | number
|
iconSize?: string | number
|
||||||
iconColor?: string
|
iconColor?: string
|
||||||
lowercase?: boolean
|
lowercase?: boolean
|
||||||
|
reserveMessageSpace?: boolean
|
||||||
}>(),
|
}>(),
|
||||||
{
|
{
|
||||||
id: '',
|
id: '',
|
||||||
@@ -108,6 +111,7 @@ const props = withDefaults(
|
|||||||
iconSize: 24,
|
iconSize: 24,
|
||||||
iconColor: 'text-m-muted',
|
iconColor: 'text-m-muted',
|
||||||
lowercase: false,
|
lowercase: false,
|
||||||
|
reserveMessageSpace: true,
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -10,6 +10,9 @@ type InputNumberProps = {
|
|||||||
readonly?: boolean
|
readonly?: boolean
|
||||||
min?: number | string
|
min?: number | string
|
||||||
max?: number | string
|
max?: number | string
|
||||||
|
error?: string
|
||||||
|
hint?: string
|
||||||
|
reserveMessageSpace?: boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
const InputNumberForTest = InputNumber as DefineComponent<InputNumberProps>
|
const InputNumberForTest = InputNumber as DefineComponent<InputNumberProps>
|
||||||
@@ -173,4 +176,23 @@ describe('MalioInputNumber', () => {
|
|||||||
const wrapper = mountInputNumber({label: 'Champ'})
|
const wrapper = mountInputNumber({label: 'Champ'})
|
||||||
expect(wrapper.find('[data-test="required-mark"]').exists()).toBe(false)
|
expect(wrapper.find('[data-test="required-mark"]').exists()).toBe(false)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
it('réserve l’espace message par défaut même sans message', () => {
|
||||||
|
const wrapper = mountInputNumber({label: 'Champ'})
|
||||||
|
const msg = wrapper.find('[id$="-describedby"]')
|
||||||
|
expect(msg.exists()).toBe(true)
|
||||||
|
expect(msg.classes()).toContain('min-h-[1rem]')
|
||||||
|
})
|
||||||
|
|
||||||
|
it('reserveMessageSpace=false sans message : pas de ligne réservée', () => {
|
||||||
|
const wrapper = mountInputNumber({label: 'Champ', reserveMessageSpace: false})
|
||||||
|
expect(wrapper.find('[id$="-describedby"]').exists()).toBe(false)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('reserveMessageSpace=false avec message : ligne rendue sans min-h', () => {
|
||||||
|
const wrapper = mountInputNumber({label: 'Champ', reserveMessageSpace: false, error: 'Erreur'})
|
||||||
|
const msg = wrapper.find('[id$="-describedby"]')
|
||||||
|
expect(msg.exists()).toBe(true)
|
||||||
|
expect(msg.classes()).not.toContain('min-h-[1rem]')
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -51,6 +51,7 @@
|
|||||||
|
|
||||||
</div>
|
</div>
|
||||||
<p
|
<p
|
||||||
|
v-if="reserveMessageSpace || hint || error || success"
|
||||||
:id="`${inputId}-describedby`"
|
:id="`${inputId}-describedby`"
|
||||||
:class="[
|
:class="[
|
||||||
hasError
|
hasError
|
||||||
@@ -58,7 +59,8 @@
|
|||||||
: hasSuccess
|
: hasSuccess
|
||||||
? 'text-m-success'
|
? 'text-m-success'
|
||||||
: 'text-m-muted',
|
: 'text-m-muted',
|
||||||
'text-xs ml-[2px] min-h-[1rem]',
|
'text-xs ml-[2px]',
|
||||||
|
reserveMessageSpace ? 'min-h-[1rem]' : '',
|
||||||
]"
|
]"
|
||||||
>
|
>
|
||||||
{{ hint || error || success }}
|
{{ hint || error || success }}
|
||||||
@@ -91,6 +93,7 @@ const props = withDefaults(
|
|||||||
hint?: string
|
hint?: string
|
||||||
error?: string
|
error?: string
|
||||||
success?: string
|
success?: string
|
||||||
|
reserveMessageSpace?: boolean
|
||||||
}>(),
|
}>(),
|
||||||
{
|
{
|
||||||
id: '',
|
id: '',
|
||||||
@@ -108,6 +111,7 @@ const props = withDefaults(
|
|||||||
hint: '',
|
hint: '',
|
||||||
error: '',
|
error: '',
|
||||||
success: '',
|
success: '',
|
||||||
|
reserveMessageSpace: true,
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ type InputPasswordProps = {
|
|||||||
error?: string
|
error?: string
|
||||||
success?: string
|
success?: string
|
||||||
displayIcon?: boolean
|
displayIcon?: boolean
|
||||||
|
reserveMessageSpace?: boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
const InputPasswordForTest = InputPassword as DefineComponent<InputPasswordProps>
|
const InputPasswordForTest = InputPassword as DefineComponent<InputPasswordProps>
|
||||||
@@ -227,4 +228,23 @@ describe('MalioInputPassword', () => {
|
|||||||
await wrapper.get('[data-test="icon"]').trigger('click')
|
await wrapper.get('[data-test="icon"]').trigger('click')
|
||||||
expect(wrapper.get('input').attributes('type')).toBe('text')
|
expect(wrapper.get('input').attributes('type')).toBe('text')
|
||||||
})
|
})
|
||||||
|
|
||||||
|
it('réserve l’espace message par défaut même sans message', () => {
|
||||||
|
const wrapper = mountComponent({label: 'Champ'})
|
||||||
|
const msg = wrapper.find('[id$="-describedby"]')
|
||||||
|
expect(msg.exists()).toBe(true)
|
||||||
|
expect(msg.classes()).toContain('min-h-[1rem]')
|
||||||
|
})
|
||||||
|
|
||||||
|
it('reserveMessageSpace=false sans message : pas de ligne réservée', () => {
|
||||||
|
const wrapper = mountComponent({label: 'Champ', reserveMessageSpace: false})
|
||||||
|
expect(wrapper.find('[id$="-describedby"]').exists()).toBe(false)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('reserveMessageSpace=false avec message : ligne rendue sans min-h', () => {
|
||||||
|
const wrapper = mountComponent({label: 'Champ', reserveMessageSpace: false, error: 'Erreur'})
|
||||||
|
const msg = wrapper.find('[id$="-describedby"]')
|
||||||
|
expect(msg.exists()).toBe(true)
|
||||||
|
expect(msg.classes()).not.toContain('min-h-[1rem]')
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -47,6 +47,7 @@
|
|||||||
|
|
||||||
</div>
|
</div>
|
||||||
<p
|
<p
|
||||||
|
v-if="reserveMessageSpace || hint || error || success"
|
||||||
:id="`${inputId}-describedby`"
|
:id="`${inputId}-describedby`"
|
||||||
:class="[
|
:class="[
|
||||||
hasError
|
hasError
|
||||||
@@ -54,7 +55,8 @@
|
|||||||
: hasSuccess
|
: hasSuccess
|
||||||
? 'text-m-success'
|
? 'text-m-success'
|
||||||
: 'text-m-muted',
|
: 'text-m-muted',
|
||||||
'mt-1 text-xs ml-[2px] min-h-[1rem]',
|
'mt-1 text-xs ml-[2px]',
|
||||||
|
reserveMessageSpace ? 'min-h-[1rem]' : '',
|
||||||
]"
|
]"
|
||||||
>
|
>
|
||||||
{{ hint || error || success }}
|
{{ hint || error || success }}
|
||||||
@@ -90,6 +92,7 @@ const props = withDefaults(
|
|||||||
error?: string
|
error?: string
|
||||||
success?: string
|
success?: string
|
||||||
displayIcon?: boolean
|
displayIcon?: boolean
|
||||||
|
reserveMessageSpace?: boolean
|
||||||
}>(),
|
}>(),
|
||||||
{
|
{
|
||||||
id: '',
|
id: '',
|
||||||
@@ -109,6 +112,7 @@ const props = withDefaults(
|
|||||||
error: '',
|
error: '',
|
||||||
success: '',
|
success: '',
|
||||||
displayIcon: true,
|
displayIcon: true,
|
||||||
|
reserveMessageSpace: true,
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ type InputPhoneProps = {
|
|||||||
addable?: boolean
|
addable?: boolean
|
||||||
addIconName?: string
|
addIconName?: string
|
||||||
addButtonLabel?: string
|
addButtonLabel?: string
|
||||||
|
reserveMessageSpace?: boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
const InputPhoneForTest = InputPhone as DefineComponent<InputPhoneProps>
|
const InputPhoneForTest = InputPhone as DefineComponent<InputPhoneProps>
|
||||||
@@ -383,4 +384,23 @@ describe('MalioInputPhone', () => {
|
|||||||
|
|
||||||
expect(wrapper.emitted('update:modelValue')).toBeDefined()
|
expect(wrapper.emitted('update:modelValue')).toBeDefined()
|
||||||
})
|
})
|
||||||
|
|
||||||
|
it('réserve l’espace message par défaut même sans message', () => {
|
||||||
|
const wrapper = mountComponent({label: 'Champ'})
|
||||||
|
const msg = wrapper.find('[id$="-describedby"]')
|
||||||
|
expect(msg.exists()).toBe(true)
|
||||||
|
expect(msg.classes()).toContain('min-h-[1rem]')
|
||||||
|
})
|
||||||
|
|
||||||
|
it('reserveMessageSpace=false sans message : pas de ligne réservée', () => {
|
||||||
|
const wrapper = mountComponent({label: 'Champ', reserveMessageSpace: false})
|
||||||
|
expect(wrapper.find('[id$="-describedby"]').exists()).toBe(false)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('reserveMessageSpace=false avec message : ligne rendue sans min-h', () => {
|
||||||
|
const wrapper = mountComponent({label: 'Champ', reserveMessageSpace: false, error: 'Erreur'})
|
||||||
|
const msg = wrapper.find('[id$="-describedby"]')
|
||||||
|
expect(msg.exists()).toBe(true)
|
||||||
|
expect(msg.classes()).not.toContain('min-h-[1rem]')
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -60,6 +60,7 @@
|
|||||||
|
|
||||||
</div>
|
</div>
|
||||||
<p
|
<p
|
||||||
|
v-if="reserveMessageSpace || hint || error || success"
|
||||||
:id="`${inputId}-describedby`"
|
:id="`${inputId}-describedby`"
|
||||||
:class="[
|
:class="[
|
||||||
hasError
|
hasError
|
||||||
@@ -67,7 +68,8 @@
|
|||||||
: hasSuccess
|
: hasSuccess
|
||||||
? 'text-m-success'
|
? 'text-m-success'
|
||||||
: 'text-m-muted',
|
: 'text-m-muted',
|
||||||
'mt-1 text-xs ml-[2px] min-h-[1rem]',
|
'mt-1 text-xs ml-[2px]',
|
||||||
|
reserveMessageSpace ? 'min-h-[1rem]' : '',
|
||||||
]"
|
]"
|
||||||
>
|
>
|
||||||
{{ hint || error || success }}
|
{{ hint || error || success }}
|
||||||
@@ -110,6 +112,7 @@ const props = withDefaults(
|
|||||||
addable?: boolean
|
addable?: boolean
|
||||||
addIconName?: string
|
addIconName?: string
|
||||||
addButtonLabel?: string
|
addButtonLabel?: string
|
||||||
|
reserveMessageSpace?: boolean
|
||||||
}>(),
|
}>(),
|
||||||
{
|
{
|
||||||
id: '',
|
id: '',
|
||||||
@@ -134,6 +137,7 @@ const props = withDefaults(
|
|||||||
addable: false,
|
addable: false,
|
||||||
addIconName: 'mdi:plus',
|
addIconName: 'mdi:plus',
|
||||||
addButtonLabel: 'Ajouter un numéro',
|
addButtonLabel: 'Ajouter un numéro',
|
||||||
|
reserveMessageSpace: true,
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ type InputRichTextProps = {
|
|||||||
labelClass?: string
|
labelClass?: string
|
||||||
editorClass?: string
|
editorClass?: string
|
||||||
required?: boolean
|
required?: boolean
|
||||||
|
reserveMessageSpace?: boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
const InputRichTextForTest = InputRichText as DefineComponent<InputRichTextProps>
|
const InputRichTextForTest = InputRichText as DefineComponent<InputRichTextProps>
|
||||||
@@ -187,4 +188,23 @@ describe('MalioInputRichText', () => {
|
|||||||
|
|
||||||
expect(wrapper.find('[data-test="required-mark"]').exists()).toBe(false)
|
expect(wrapper.find('[data-test="required-mark"]').exists()).toBe(false)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
it('réserve l’espace message par défaut même sans message', async () => {
|
||||||
|
const wrapper = await mountComponent({label: 'Champ'})
|
||||||
|
const msg = wrapper.find('[id$="-describedby"]')
|
||||||
|
expect(msg.exists()).toBe(true)
|
||||||
|
expect(msg.classes()).toContain('min-h-[1rem]')
|
||||||
|
})
|
||||||
|
|
||||||
|
it('reserveMessageSpace=false sans message : pas de ligne réservée', async () => {
|
||||||
|
const wrapper = await mountComponent({label: 'Champ', reserveMessageSpace: false})
|
||||||
|
expect(wrapper.find('[id$="-describedby"]').exists()).toBe(false)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('reserveMessageSpace=false avec message : ligne rendue sans min-h', async () => {
|
||||||
|
const wrapper = await mountComponent({label: 'Champ', reserveMessageSpace: false, error: 'Erreur'})
|
||||||
|
const msg = wrapper.find('[id$="-describedby"]')
|
||||||
|
expect(msg.exists()).toBe(true)
|
||||||
|
expect(msg.classes()).not.toContain('min-h-[1rem]')
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -185,6 +185,7 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<p
|
<p
|
||||||
|
v-if="reserveMessageSpace || hint || error || success"
|
||||||
:id="`${editorId}-describedby`"
|
:id="`${editorId}-describedby`"
|
||||||
:class="[
|
:class="[
|
||||||
hasError
|
hasError
|
||||||
@@ -192,7 +193,8 @@
|
|||||||
: hasSuccess
|
: hasSuccess
|
||||||
? 'text-m-success'
|
? 'text-m-success'
|
||||||
: 'text-m-muted',
|
: 'text-m-muted',
|
||||||
'mt-1 text-xs ml-[2px] min-h-[1rem]',
|
'mt-1 text-xs ml-[2px]',
|
||||||
|
reserveMessageSpace ? 'min-h-[1rem]' : '',
|
||||||
]"
|
]"
|
||||||
>
|
>
|
||||||
{{ error || success || hint }}
|
{{ error || success || hint }}
|
||||||
@@ -235,6 +237,7 @@ const props = withDefaults(
|
|||||||
labelClass?: string
|
labelClass?: string
|
||||||
editorClass?: string
|
editorClass?: string
|
||||||
required?: boolean
|
required?: boolean
|
||||||
|
reserveMessageSpace?: boolean
|
||||||
}>(),
|
}>(),
|
||||||
{
|
{
|
||||||
id: '',
|
id: '',
|
||||||
@@ -253,6 +256,7 @@ const props = withDefaults(
|
|||||||
labelClass: '',
|
labelClass: '',
|
||||||
editorClass: '',
|
editorClass: '',
|
||||||
required: false,
|
required: false,
|
||||||
|
reserveMessageSpace: true,
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -44,6 +44,7 @@
|
|||||||
|
|
||||||
</div>
|
</div>
|
||||||
<p
|
<p
|
||||||
|
v-if="reserveMessageSpace || hint || error || success"
|
||||||
:id="`${inputId}-describedby`"
|
:id="`${inputId}-describedby`"
|
||||||
:class="[
|
:class="[
|
||||||
hasError
|
hasError
|
||||||
@@ -51,7 +52,8 @@
|
|||||||
: hasSuccess
|
: hasSuccess
|
||||||
? 'text-m-success'
|
? 'text-m-success'
|
||||||
: 'text-m-muted',
|
: 'text-m-muted',
|
||||||
'mt-1 text-xs ml-[2px] min-h-[1rem]',
|
'mt-1 text-xs ml-[2px]',
|
||||||
|
reserveMessageSpace ? 'min-h-[1rem]' : '',
|
||||||
]"
|
]"
|
||||||
>
|
>
|
||||||
{{ hint || error || success }}
|
{{ hint || error || success }}
|
||||||
@@ -94,6 +96,7 @@ const props = withDefaults(
|
|||||||
iconSize?: string | number
|
iconSize?: string | number
|
||||||
iconColor?: string
|
iconColor?: string
|
||||||
mask?: string | MaskInputOptions
|
mask?: string | MaskInputOptions
|
||||||
|
reserveMessageSpace?: boolean
|
||||||
}>(),
|
}>(),
|
||||||
{
|
{
|
||||||
id: '',
|
id: '',
|
||||||
@@ -117,6 +120,7 @@ const props = withDefaults(
|
|||||||
iconSize: 24,
|
iconSize: 24,
|
||||||
iconColor: 'text-m-muted',
|
iconColor: 'text-m-muted',
|
||||||
mask: undefined,
|
mask: undefined,
|
||||||
|
reserveMessageSpace: true,
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ type InputTextAreaProps = {
|
|||||||
error?: string
|
error?: string
|
||||||
success?: string
|
success?: string
|
||||||
rounded?: string
|
rounded?: string
|
||||||
|
reserveMessageSpace?: boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
const InputTextAreaForTest = InputTextArea as DefineComponent<InputTextAreaProps>
|
const InputTextAreaForTest = InputTextArea as DefineComponent<InputTextAreaProps>
|
||||||
@@ -213,4 +214,23 @@ describe('MalioInputTextArea', () => {
|
|||||||
const wrapper = mount(InputTextAreaForTest, {props: {label: 'Champ', readonly: true, modelValue: 'du texte'}})
|
const wrapper = mount(InputTextAreaForTest, {props: {label: 'Champ', readonly: true, modelValue: 'du texte'}})
|
||||||
expect(wrapper.get('label').classes()).toContain('text-black')
|
expect(wrapper.get('label').classes()).toContain('text-black')
|
||||||
})
|
})
|
||||||
|
|
||||||
|
it('réserve l’espace message par défaut même sans message', () => {
|
||||||
|
const wrapper = mount(InputTextAreaForTest, {props: {label: 'Champ'}})
|
||||||
|
const msg = wrapper.find('[data-test="message-line"]')
|
||||||
|
expect(msg.exists()).toBe(true)
|
||||||
|
expect(msg.classes()).toContain('min-h-[1rem]')
|
||||||
|
})
|
||||||
|
|
||||||
|
it('reserveMessageSpace=false sans message : pas de ligne réservée', () => {
|
||||||
|
const wrapper = mount(InputTextAreaForTest, {props: {label: 'Champ', reserveMessageSpace: false}})
|
||||||
|
expect(wrapper.find('[data-test="message-line"]').exists()).toBe(false)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('reserveMessageSpace=false avec message : ligne rendue sans min-h', () => {
|
||||||
|
const wrapper = mount(InputTextAreaForTest, {props: {label: 'Champ', reserveMessageSpace: false, error: 'Erreur'}})
|
||||||
|
const msg = wrapper.find('[data-test="message-line"]')
|
||||||
|
expect(msg.exists()).toBe(true)
|
||||||
|
expect(msg.classes()).not.toContain('min-h-[1rem]')
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -63,7 +63,10 @@
|
|||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
class="mt-1 flex items-center justify-between gap-2 text-xs min-h-[1rem]"
|
v-if="reserveMessageSpace || hint || error || success"
|
||||||
|
data-test="message-line"
|
||||||
|
class="mt-1 flex items-center justify-between gap-2 text-xs"
|
||||||
|
:class="reserveMessageSpace ? 'min-h-[1rem]' : ''"
|
||||||
>
|
>
|
||||||
<p
|
<p
|
||||||
:id="`${inputId}-describedby`"
|
:id="`${inputId}-describedby`"
|
||||||
@@ -114,6 +117,7 @@ const props = withDefaults(
|
|||||||
success?: string
|
success?: string
|
||||||
rounded?: string
|
rounded?: string
|
||||||
groupClass?: string
|
groupClass?: string
|
||||||
|
reserveMessageSpace?: boolean
|
||||||
|
|
||||||
}>(),
|
}>(),
|
||||||
{
|
{
|
||||||
@@ -140,6 +144,7 @@ const props = withDefaults(
|
|||||||
minResizeHeight: 40,
|
minResizeHeight: 40,
|
||||||
maxResizeHeight: 320,
|
maxResizeHeight: 320,
|
||||||
groupClass: '',
|
groupClass: '',
|
||||||
|
reserveMessageSpace: true,
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ type InputUploadProps = {
|
|||||||
displayIcon?: boolean
|
displayIcon?: boolean
|
||||||
accept?: string
|
accept?: string
|
||||||
required?: boolean
|
required?: boolean
|
||||||
|
reserveMessageSpace?: boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
const InputUploadForTest = InputUpload as DefineComponent<InputUploadProps>
|
const InputUploadForTest = InputUpload as DefineComponent<InputUploadProps>
|
||||||
@@ -240,4 +241,23 @@ describe('MalioInputUpload', () => {
|
|||||||
await wrapper.get('input[type="text"]').trigger('click')
|
await wrapper.get('input[type="text"]').trigger('click')
|
||||||
expect(clickSpy).not.toHaveBeenCalled()
|
expect(clickSpy).not.toHaveBeenCalled()
|
||||||
})
|
})
|
||||||
|
|
||||||
|
it('réserve l’espace message par défaut même sans message', () => {
|
||||||
|
const wrapper = mountComponent({label: 'Champ'})
|
||||||
|
const msg = wrapper.find('[id$="-describedby"]')
|
||||||
|
expect(msg.exists()).toBe(true)
|
||||||
|
expect(msg.classes()).toContain('min-h-[1rem]')
|
||||||
|
})
|
||||||
|
|
||||||
|
it('reserveMessageSpace=false sans message : pas de ligne réservée', () => {
|
||||||
|
const wrapper = mountComponent({label: 'Champ', reserveMessageSpace: false})
|
||||||
|
expect(wrapper.find('[id$="-describedby"]').exists()).toBe(false)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('reserveMessageSpace=false avec message : ligne rendue sans min-h', () => {
|
||||||
|
const wrapper = mountComponent({label: 'Champ', reserveMessageSpace: false, error: 'Erreur'})
|
||||||
|
const msg = wrapper.find('[id$="-describedby"]')
|
||||||
|
expect(msg.exists()).toBe(true)
|
||||||
|
expect(msg.classes()).not.toContain('min-h-[1rem]')
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -52,6 +52,7 @@
|
|||||||
|
|
||||||
</div>
|
</div>
|
||||||
<p
|
<p
|
||||||
|
v-if="reserveMessageSpace || hint || error || success"
|
||||||
:id="`${inputId}-describedby`"
|
:id="`${inputId}-describedby`"
|
||||||
:class="[
|
:class="[
|
||||||
hasError
|
hasError
|
||||||
@@ -59,7 +60,8 @@
|
|||||||
: hasSuccess
|
: hasSuccess
|
||||||
? 'text-m-success'
|
? 'text-m-success'
|
||||||
: 'text-m-muted',
|
: 'text-m-muted',
|
||||||
'mt-1 text-xs ml-[2px] min-h-[1rem]',
|
'mt-1 text-xs ml-[2px]',
|
||||||
|
reserveMessageSpace ? 'min-h-[1rem]' : '',
|
||||||
]"
|
]"
|
||||||
>
|
>
|
||||||
{{ hint || error || success }}
|
{{ hint || error || success }}
|
||||||
@@ -92,6 +94,7 @@ const props = withDefaults(
|
|||||||
displayIcon?: boolean
|
displayIcon?: boolean
|
||||||
accept?: string
|
accept?: string
|
||||||
required?: boolean
|
required?: boolean
|
||||||
|
reserveMessageSpace?: boolean
|
||||||
}>(),
|
}>(),
|
||||||
{
|
{
|
||||||
id: '',
|
id: '',
|
||||||
@@ -108,6 +111,7 @@ const props = withDefaults(
|
|||||||
displayIcon: true,
|
displayIcon: true,
|
||||||
accept: '',
|
accept: '',
|
||||||
required: false,
|
required: false,
|
||||||
|
reserveMessageSpace: true,
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user