diff --git a/app/components/malio/input/InputRichText.test.ts b/app/components/malio/input/InputRichText.test.ts index 15ee4ca..9bb8321 100644 --- a/app/components/malio/input/InputRichText.test.ts +++ b/app/components/malio/input/InputRichText.test.ts @@ -19,6 +19,7 @@ type InputRichTextProps = { groupClass?: string labelClass?: string editorClass?: string + required?: boolean } const InputRichTextForTest = InputRichText as DefineComponent @@ -162,4 +163,16 @@ describe('MalioInputRichText', () => { expect(html).toContain('Mon titre') expect(html).toContain('Un paragraphe.') }) + + it('affiche l\'astérisque quand required est vrai', async () => { + const wrapper = await mountComponent({label: 'Champ', required: true}) + + expect(wrapper.find('[data-test="required-mark"]').exists()).toBe(true) + }) + + it('n\'affiche pas l\'astérisque par défaut', async () => { + const wrapper = await mountComponent({label: 'Champ'}) + + expect(wrapper.find('[data-test="required-mark"]').exists()).toBe(false) + }) }) diff --git a/app/components/malio/input/InputRichText.vue b/app/components/malio/input/InputRichText.vue index a2e9ddc..338da49 100644 --- a/app/components/malio/input/InputRichText.vue +++ b/app/components/malio/input/InputRichText.vue @@ -5,7 +5,7 @@ :for="editorId" :class="mergedLabelClass" > - {{ label }} + {{ label }} @@ -22,6 +22,7 @@ v-else :id="editorId" :class="mergedEditorWrapperClass" + :aria-required="required || undefined" @click="focusEditor" >
import { computed, onBeforeUnmount, onMounted, ref, shallowRef, useId, watch } from 'vue' import { Icon as IconifyIcon } from '@iconify/vue' +import MalioRequiredMark from '../shared/RequiredMark.vue' import { Editor, EditorContent } from '@tiptap/vue-3' import StarterKit from '@tiptap/starter-kit' import Placeholder from '@tiptap/extension-placeholder' @@ -232,6 +234,7 @@ const props = withDefaults( groupClass?: string labelClass?: string editorClass?: string + required?: boolean }>(), { id: '', @@ -249,6 +252,7 @@ const props = withDefaults( groupClass: '', labelClass: '', editorClass: '', + required: false, }, ) diff --git a/app/components/malio/input/InputUpload.test.ts b/app/components/malio/input/InputUpload.test.ts index 0a71ab4..69a7c0b 100644 --- a/app/components/malio/input/InputUpload.test.ts +++ b/app/components/malio/input/InputUpload.test.ts @@ -17,6 +17,7 @@ type InputUploadProps = { success?: string displayIcon?: boolean accept?: string + required?: boolean } const InputUploadForTest = InputUpload as DefineComponent @@ -186,4 +187,16 @@ describe('MalioInputUpload', () => { expect(wrapper.get('[data-test="icon"]').classes()).toContain('text-black') }) + + it('affiche l\'astérisque quand required est vrai', () => { + const wrapper = mountComponent({label: 'Champ', required: true}) + + expect(wrapper.find('[data-test="required-mark"]').exists()).toBe(true) + }) + + it('n\'affiche pas l\'astérisque par défaut', () => { + const wrapper = mountComponent({label: 'Champ'}) + + expect(wrapper.find('[data-test="required-mark"]').exists()).toBe(false) + }) }) diff --git a/app/components/malio/input/InputUpload.vue b/app/components/malio/input/InputUpload.vue index fd22bfe..d491a60 100644 --- a/app/components/malio/input/InputUpload.vue +++ b/app/components/malio/input/InputUpload.vue @@ -9,6 +9,7 @@ :accept="accept" class="hidden" :disabled="disabled" + :required="required" @change="onFileChange" > @@ -33,7 +34,7 @@ :for="inputId" :class="mergedLabelClass" > - {{ label }} + {{ label }} (), { id: '', @@ -101,6 +104,7 @@ const props = withDefaults( success: '', displayIcon: true, accept: '', + required: false, }, ) diff --git a/app/components/malio/select/Select.test.ts b/app/components/malio/select/Select.test.ts index 0e4cbce..cce6cdc 100644 --- a/app/components/malio/select/Select.test.ts +++ b/app/components/malio/select/Select.test.ts @@ -21,6 +21,7 @@ type SelectProps = { textLabel?: string rounded?: string disabled?: boolean + required?: boolean } const SelectForTest = Select as DefineComponent @@ -260,6 +261,22 @@ describe('MalioSelect', () => { expect(wrapper.get('[data-test="chevron"]').classes()).toContain('text-m-success') }) + it('affiche l\'astérisque quand required est vrai', () => { + const wrapper = mount(SelectForTest, { + props: {modelValue: null, label: 'Champ', required: true}, + }) + + expect(wrapper.find('[data-test="required-mark"]').exists()).toBe(true) + }) + + it('n\'affiche pas l\'astérisque par défaut', () => { + const wrapper = mount(SelectForTest, { + props: {modelValue: null, label: 'Champ'}, + }) + + expect(wrapper.find('[data-test="required-mark"]').exists()).toBe(false) + }) + it('keeps the bottom border allocation when open downward (transparent, not zero)', async () => { const wrapper = mount(SelectForTest, { props: {modelValue: null, options}, diff --git a/app/components/malio/select/Select.vue b/app/components/malio/select/Select.vue index 2d4540c..9276da1 100644 --- a/app/components/malio/select/Select.vue +++ b/app/components/malio/select/Select.vue @@ -38,6 +38,7 @@ :aria-controls="listboxId" :aria-invalid="hasError" :aria-describedby="describedBy" + :aria-required="required || undefined" :disabled="disabled" @click="toggle" > @@ -59,7 +60,7 @@ ]" :style="labelTransformStyle" > - {{ label }} + {{ label }} (), { options: () => [], emptyOptionLabel: '', @@ -207,6 +210,7 @@ const props = withDefaults(defineProps<{ disabled: false, groupClass: '', noOptionsText: 'Aucune option disponible', + required: false, }) const emit = defineEmits<{ diff --git a/app/components/malio/select/SelectCheckbox.test.ts b/app/components/malio/select/SelectCheckbox.test.ts index db9c5aa..d7ff21f 100644 --- a/app/components/malio/select/SelectCheckbox.test.ts +++ b/app/components/malio/select/SelectCheckbox.test.ts @@ -25,6 +25,7 @@ type SelectCheckboxProps = { selectAllLabel?: string disabled?: boolean groupClass?: string + required?: boolean } const SelectCheckboxForTest = SelectCheckbox as DefineComponent @@ -235,6 +236,22 @@ describe('MalioSelectCheckbox', () => { expect(wrapper.get('[data-test="chevron"]').classes()).toContain('text-m-success') }) + it('affiche l\'astérisque quand required est vrai', () => { + const wrapper = mount(SelectCheckboxForTest, { + props: {modelValue: [], label: 'Champ', required: true}, + }) + + expect(wrapper.find('[data-test="required-mark"]').exists()).toBe(true) + }) + + it('n\'affiche pas l\'astérisque par défaut', () => { + const wrapper = mount(SelectCheckboxForTest, { + props: {modelValue: [], label: 'Champ'}, + }) + + expect(wrapper.find('[data-test="required-mark"]').exists()).toBe(false) + }) + it('keeps the bottom border allocation when open downward (transparent, not zero)', async () => { const wrapper = mount(SelectCheckboxForTest, { props: {modelValue: [], options}, diff --git a/app/components/malio/select/SelectCheckbox.vue b/app/components/malio/select/SelectCheckbox.vue index 673f12b..5b23495 100644 --- a/app/components/malio/select/SelectCheckbox.vue +++ b/app/components/malio/select/SelectCheckbox.vue @@ -38,6 +38,7 @@ :aria-controls="listboxId" :aria-invalid="hasError" :aria-describedby="describedBy" + :aria-required="required || undefined" :disabled="disabled" @click="toggle" > @@ -59,7 +60,7 @@ ]" :style="labelTransformStyle" > - {{ label }} + {{ label }}
(), { options: () => [], emptyOptionLabel: '', @@ -263,6 +266,7 @@ const props = withDefaults(defineProps<{ disabled: false, groupClass: '', noOptionsText: 'Aucune option disponible', + required: false, }) const emit = defineEmits<{