@cnamts/synapse 1.0.22 → 1.0.23
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{DateFilter-B5n-ZkLi.js → DateFilter-Dc-gSGwk.js} +1 -1
- package/dist/{NumberFilter-CtiZ9uj8.js → NumberFilter-vP38Wp6j.js} +1 -1
- package/dist/{PeriodFilter-DzqiMb-b.js → PeriodFilter-Ba1uYUnT.js} +1 -1
- package/dist/{SelectFilter-BOYlF7rX.js → SelectFilter-BioGT6Nn.js} +1 -1
- package/dist/{TextFilter-BOFRNfcX.js → TextFilter-B84dpnoq.js} +1 -1
- package/dist/components/Accordion/Accordion.d.ts +13 -2
- package/dist/components/Accordion/composables/useAccordionState.d.ts +2 -1
- package/dist/components/Amelipro/AmeliproAutoCompleteField/AmeliproAutoCompleteField.d.ts +7 -7
- package/dist/components/Amelipro/AmeliproCheckbox/AmeliproCheckbox.d.ts +1 -1
- package/dist/components/Amelipro/AmeliproCustomSelector/AmeliproCustomSelector.d.ts +1 -1
- package/dist/components/Amelipro/AmeliproPostalAddressField/AmeliproPostalAddressField.d.ts +1 -1
- package/dist/components/Amelipro/AmeliproSelect/AmeliproSelect.d.ts +7 -7
- package/dist/components/Amelipro/AmeliproTabs/AmeliproTabs.d.ts +16 -16
- package/dist/components/Amelipro/AmeliproTextArea/AmeliproTextArea.d.ts +1 -1
- package/dist/components/Amelipro/AmeliproTextField/AmeliproTextField.d.ts +1 -1
- package/dist/components/Customs/Selects/SyAutocomplete/SyAutocomplete.d.ts +22 -1
- package/dist/components/Customs/Selects/SyAutocomplete/locales.d.ts +5 -0
- package/dist/components/Customs/Selects/SyInputSelect/SyInputSelect.d.ts +1 -1
- package/dist/components/Customs/Selects/SySelect/SySelect.d.ts +1 -1
- package/dist/components/Customs/Selects/SySelect/locales.d.ts +1 -0
- package/dist/components/Customs/SyCheckBoxGroup/SyCheckBoxGroup.d.ts +1 -1
- package/dist/components/Customs/SyCheckbox/SyCheckbox.d.ts +1 -1
- package/dist/components/Customs/SyRadioGroup/SyRadioGroup.d.ts +1 -1
- package/dist/components/Customs/SyTextField/SyTextField.d.ts +5 -2
- package/dist/components/DatePicker/CalendarMode/DatePicker.d.ts +13 -9
- package/dist/components/DatePicker/ComplexDatePicker/ComplexDatePicker.d.ts +7 -5
- package/dist/components/DatePicker/DateTextInput/DateTextInput.d.ts +2 -1
- package/dist/components/ErrorPage/ErrorPage.d.ts +3 -1
- package/dist/components/FileList/UploadItem/UploadItem.d.ts +6 -0
- package/dist/components/FileList/UploadItem/locales.d.ts +1 -4
- package/dist/components/FileUpload/FileUploadContent.d.ts +2 -0
- package/dist/components/FileUpload/validateFiles.d.ts +2 -1
- package/dist/components/HeaderBar/HeaderBar.d.ts +2 -1
- package/dist/components/HeaderBar/HeaderLogo/HeaderLogo.d.ts +2 -1
- package/dist/components/HeaderNavigationBar/HeaderNavigationBar.d.ts +2 -1
- package/dist/components/MonthPicker/MonthPicker.d.ts +1939 -0
- package/dist/components/MonthPicker/MonthPickerText/MonthPickerInput.d.ts +1899 -0
- package/dist/components/MonthPicker/MonthPickerText/useTextField.d.ts +21 -0
- package/dist/components/MonthPicker/MonthPickerVisual/MonthPickerVisual.d.ts +21 -0
- package/dist/components/MonthPicker/MonthPickerVisual/MonthPickerVisualProps.d.ts +12 -0
- package/dist/components/MonthPicker/MonthPickerVisual/MonthSelector.d.ts +11 -0
- package/dist/components/MonthPicker/MonthPickerVisual/VisualPickerFooter.d.ts +6 -0
- package/dist/components/MonthPicker/MonthPickerVisual/VisualPickerHeader.d.ts +14 -0
- package/dist/components/MonthPicker/MonthPickerVisual/YearSelector.d.ts +14 -0
- package/dist/components/MonthPicker/MonthPickerVisual/useMonthGrid.d.ts +9 -0
- package/dist/components/MonthPicker/MonthPickerVisual/useYearGrid.d.ts +8 -0
- package/dist/components/MonthPicker/MonthPickerVisual/utils.d.ts +8 -0
- package/dist/components/MonthPicker/locales.d.ts +12 -0
- package/dist/components/MonthPicker/useMonthPickerValidation.d.ts +25 -0
- package/dist/components/NirField/NirField.d.ts +3 -1
- package/dist/components/NotificationBar/Notification/Notification.d.ts +3 -0
- package/dist/components/PasswordField/PasswordField.d.ts +1 -1
- package/dist/components/PeriodField/PeriodField.d.ts +29 -21
- package/dist/components/PhoneField/PhoneField.d.ts +2 -1
- package/dist/components/SyBtnMenu/SyBtnMenu.d.ts +1 -1
- package/dist/components/SyHeading/SyHeading.a11y.test.d.ts +1 -0
- package/dist/components/SyHeading/SyHeading.d.ts +4 -2
- package/dist/components/SyHeading/SyHeading.test.d.ts +1 -0
- package/dist/components/SyTextArea/SyTextArea.d.ts +1 -1
- package/dist/components/Tables/SyServerTable/SyServerTable.d.ts +4 -4
- package/dist/components/Tables/SyTable/SyTable.d.ts +4 -4
- package/dist/components/Tables/common/SyTablePagination.d.ts +6 -6
- package/dist/components/index.d.ts +1 -0
- package/dist/design-system-v3.js +102 -99
- package/dist/design-system-v3.umd.cjs +126 -126
- package/dist/designTokens/tokens/cnam/cnamContextual.d.ts +5 -0
- package/dist/{main-CEl4J8_T.js → main-aLKwdMi1.js} +11167 -10522
- package/dist/main.d.ts +1 -0
- package/dist/style.css +1 -1
- package/package.json +10 -4
- package/src/assets/apTokens.scss +2 -2
- package/src/assets/overrides/_btns.scss +8 -0
- package/src/assets/overrides/_forms.scss +9 -0
- package/src/assets/overrides/_icons.scss +38 -9
- package/src/assets/overrides/_tables.scss +19 -0
- package/src/components/Accordion/Accordion.mdx +23 -9
- package/src/components/Accordion/Accordion.stories.ts +153 -3
- package/src/components/Accordion/Accordion.vue +7 -6
- package/src/components/Accordion/composables/__tests__/useAccordionState.spec.ts +40 -12
- package/src/components/Accordion/composables/useAccordionState.ts +3 -4
- package/src/components/Accordion/tests/accordion.spec.ts +131 -19
- package/src/components/Amelipro/AmeliproPagination/AmeliproPagination.mdx +3 -1
- package/src/components/Amelipro/AmeliproPagination/AmeliproPagination.stories.ts +8 -0
- package/src/components/BackBtn/accessibilite/Accessibility.mdx +62 -10
- package/src/components/BackToTopBtn/BackToTopBtn.stories.ts +9 -3
- package/src/components/BackToTopBtn/accessibilite/Accessibility.mdx +86 -6
- package/src/components/Captcha/tests/Captcha.spec.ts +0 -29
- package/src/components/Captcha/tests/__snapshots__/Captcha.spec.ts.snap +2 -110
- package/src/components/Customs/Selects/SelectBtnField/accessibilite/Accessibility.mdx +133 -10
- package/src/components/Customs/Selects/SyAutocomplete/SyAutocomplete.stories.ts +379 -93
- package/src/components/Customs/Selects/SyAutocomplete/SyAutocomplete.vue +144 -83
- package/src/components/Customs/Selects/SyAutocomplete/accessibilite/Accessibilite.stories.ts +40 -1
- package/src/components/Customs/Selects/SyAutocomplete/accessibilite/Accessibility.mdx +7 -1
- package/src/components/Customs/Selects/SyAutocomplete/locales.ts +5 -0
- package/src/components/Customs/Selects/SyAutocomplete/tests/SyAutocomplete.a11y.spec.ts +96 -0
- package/src/components/Customs/Selects/SyAutocomplete/tests/SyAutocomplete.spec.ts +234 -9
- package/src/components/Customs/Selects/SyAutocomplete/utils/ariaManager.ts +13 -3
- package/src/components/Customs/Selects/SyAutocomplete/utils/useSelectionLogic.ts +9 -10
- package/src/components/Customs/Selects/SySelect/SySelect.vue +46 -3
- package/src/components/Customs/Selects/SySelect/locales.ts +1 -0
- package/src/components/Customs/SyIcon/SyIcon.vue +1 -1
- package/src/components/Customs/SyIcon/tests/SyIcon.a11y.spec.ts +20 -0
- package/src/components/Customs/SyIconButton/SyIconButton.mdx +46 -0
- package/src/components/Customs/SyIconButton/SyIconButton.stories.ts +184 -0
- package/src/components/Customs/SyIconButton/SyIconButton.vue +38 -0
- package/src/components/Customs/SyIconButton/accessibilite/Accessibility.mdx +64 -0
- package/src/components/Customs/SyIconButton/tests/SyIconButton.a11y.spec.ts +87 -0
- package/src/components/Customs/SyIconButton/tests/SyIconButton.spec.ts +152 -0
- package/src/components/Customs/SyIconButton/tests/__snapshots__/SyIconButton.spec.ts.snap +61 -0
- package/src/components/Customs/SyPagination/SyPagination.vue +5 -5
- package/src/components/Customs/SyTextField/SyTextField.vue +20 -2
- package/src/components/Customs/SyTextField/accessibilite/Accessibility.mdx +67 -9
- package/src/components/Customs/SyTextField/tests/SyTextField.a11y.spec.ts +15 -0
- package/src/components/Customs/SyTextField/tests/SyTextField.spec.ts +36 -0
- package/src/components/DataList/accessibilite/Accessibility.mdx +79 -11
- package/src/components/DataListGroup/accessibilite/Accessibility.mdx +80 -11
- package/src/components/DownloadBtn/tests/DownloadBtn.a11y.spec.ts +25 -0
- package/src/components/ErrorPage/ErrorPage.stories.ts +113 -19
- package/src/components/ErrorPage/ErrorPage.vue +17 -2
- package/src/components/ErrorPage/tests/ErrorPage.a11y.spec.ts +17 -0
- package/src/components/ErrorPage/tests/ErrorPage.spec.ts +21 -1
- package/src/components/ErrorPage/tests/__snapshots__/ErrorPage.spec.ts.snap +0 -1
- package/src/components/ExternalLinks/tests/ExternalLinks.a11y.spec.ts +23 -0
- package/src/components/FileList/FileList.stories.ts +51 -1
- package/src/components/FileList/UploadItem/UploadItem.vue +13 -6
- package/src/components/FileList/UploadItem/locales.ts +3 -12
- package/src/components/FileList/accessibilite/Accessibility.mdx +3 -0
- package/src/components/FileUpload/FileUpload.vue +2 -1
- package/src/components/FileUpload/FileUploadContent.vue +2 -1
- package/src/components/FileUpload/tests/FileUpload.spec.ts +47 -0
- package/src/components/FileUpload/validateFiles.ts +5 -2
- package/src/components/FranceConnectBtn/accessibilite/Accessibility.mdx +62 -9
- package/src/components/HeaderBar/HeaderBar.vue +2 -1
- package/src/components/HeaderBar/HeaderLogo/HeaderLogo.vue +2 -1
- package/src/components/HeaderNavigationBar/HeaderNavigationBar.vue +2 -1
- package/src/components/LunarCalendar/accessibilite/Accessibility.mdx +74 -8
- package/src/components/LunarCalendar/tests/LunarCalendar.a11y.spec.ts +163 -0
- package/src/components/MaintenancePage/MaintenancePage.vue +1 -1
- package/src/components/MaintenancePage/tests/MaintenancePage.spec.ts +4 -5
- package/src/components/MaintenancePage/tests/__snapshots__/MaintenancePage.spec.ts.snap +0 -1
- package/src/components/MonthPicker/MonthPicker.mdx +35 -0
- package/src/components/MonthPicker/MonthPicker.stories.ts +527 -0
- package/src/components/MonthPicker/MonthPicker.vue +79 -0
- package/src/components/MonthPicker/MonthPickerText/MonthPickerInput.vue +89 -0
- package/src/components/MonthPicker/MonthPickerText/useTextField.ts +27 -0
- package/src/components/MonthPicker/MonthPickerVisual/MonthPickerVisual.vue +154 -0
- package/src/components/MonthPicker/MonthPickerVisual/MonthPickerVisualProps.ts +13 -0
- package/src/components/MonthPicker/MonthPickerVisual/MonthSelector.vue +137 -0
- package/src/components/MonthPicker/MonthPickerVisual/VisualPickerFooter.vue +60 -0
- package/src/components/MonthPicker/MonthPickerVisual/VisualPickerHeader.vue +149 -0
- package/src/components/MonthPicker/MonthPickerVisual/YearSelector.vue +143 -0
- package/src/components/MonthPicker/MonthPickerVisual/useMonthGrid.ts +45 -0
- package/src/components/MonthPicker/MonthPickerVisual/useYearGrid.ts +45 -0
- package/src/components/MonthPicker/MonthPickerVisual/utils.ts +17 -0
- package/src/components/MonthPicker/accessibilite/Accessibility.mdx +59 -0
- package/src/components/MonthPicker/locales.ts +12 -0
- package/src/components/MonthPicker/tests/MonthPicker.a11y.spec.ts +71 -0
- package/src/components/MonthPicker/tests/MonthPicker.spec.ts +1248 -0
- package/src/components/MonthPicker/tests/__snapshots__/MonthPicker.spec.ts.snap +2545 -0
- package/src/components/MonthPicker/useMonthPickerValidation.ts +30 -0
- package/src/components/NirField/NirField.mdx +1 -2
- package/src/components/NirField/NirField.stories.ts +66 -6
- package/src/components/NotFoundPage/tests/NotFoundPage.spec.ts +2 -3
- package/src/components/NotFoundPage/tests/__snapshots__/NotFoundPage.spec.ts.snap +22 -14
- package/src/components/NotificationBar/Notification/Notification.vue +3 -1
- package/src/components/NotificationBar/NotificationBar.stories.ts +154 -0
- package/src/components/NotificationBar/tests/NotificationBar.a11y.spec.ts +26 -0
- package/src/components/NotificationBar/tests/NotificationBar.spec.ts +60 -0
- package/src/components/RangeField/accessibilite/Accessibility.mdx +79 -11
- package/src/components/SkipLink/tests/SkipLink.a11y.spec.ts +23 -0
- package/src/components/StatusPage/StatusPage.stories.ts +118 -0
- package/src/components/StatusPage/StatusPage.vue +5 -3
- package/src/components/StatusPage/tests/StatusPage.a11y.spec.ts +22 -0
- package/src/components/StatusPage/tests/StatusPage.spec.ts +22 -0
- package/src/components/StatusPage/tests/__snapshots__/StatusPage.spec.ts.snap +22 -14
- package/src/components/SubHeader/tests/SubHeader.a11y.spec.ts +20 -0
- package/src/components/SyAlert/SyAlert.vue +1 -0
- package/src/components/SyAlert/accessibilite/Accessibility.mdx +79 -9
- package/src/components/SyAlert/tests/SyAlert.a11y.spec.ts +23 -0
- package/src/components/SyHeading/SyHeading.a11y.test.ts +149 -0
- package/src/components/SyHeading/SyHeading.test.ts +115 -0
- package/src/components/SyHeading/SyHeading.vue +5 -3
- package/src/components/SyTextArea/accessibilite/Accessibility.mdx +80 -8
- package/src/components/SyTextArea/tests/SyTextArea.a11y.spec.ts +151 -0
- package/src/components/ToolbarContainer/tests/ToolbarContainer.a11y.spec.ts +126 -0
- package/src/components/UploadWorkflow/tests/__snapshots__/UploadWorkflow.spec.ts.snap +2 -2
- package/src/components/index.ts +1 -0
- package/src/composables/useFormFieldErrorHandling.ts +11 -2
- package/src/designTokens/tokens/cnam/cnamContextual.ts +6 -1
- package/src/main.ts +2 -0
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from '@storybook/vue3'
|
|
2
|
+
import { fn } from '@storybook/test'
|
|
3
|
+
import SyIconButton from './SyIconButton.vue'
|
|
4
|
+
import { mdiClose, mdiAlert, mdiMagnify } from '@mdi/js'
|
|
5
|
+
|
|
6
|
+
const meta = {
|
|
7
|
+
title: 'Composants/Boutons/SyIconButton',
|
|
8
|
+
component: SyIconButton,
|
|
9
|
+
decorators: [
|
|
10
|
+
() => ({
|
|
11
|
+
template: '<div style="padding: 20px;"><story/></div>',
|
|
12
|
+
}),
|
|
13
|
+
],
|
|
14
|
+
argTypes: {
|
|
15
|
+
'icon': {
|
|
16
|
+
control: { type: 'text' },
|
|
17
|
+
description: 'Nom de l\'icône à afficher (format Material Design Icons)',
|
|
18
|
+
},
|
|
19
|
+
'label': {
|
|
20
|
+
control: { type: 'text' },
|
|
21
|
+
description: 'Texte accessible obligatoire porté par `aria-label` sur le bouton',
|
|
22
|
+
},
|
|
23
|
+
'color': {
|
|
24
|
+
control: { type: 'text' },
|
|
25
|
+
description: 'Couleur de l\'icône (nom de couleur Vuetify)',
|
|
26
|
+
},
|
|
27
|
+
'size': {
|
|
28
|
+
options: ['x-small', 'small', 'default', 'large', 'x-large'],
|
|
29
|
+
control: {
|
|
30
|
+
type: 'select',
|
|
31
|
+
},
|
|
32
|
+
description: 'Taille du bouton et de l\'icône',
|
|
33
|
+
default: 'default',
|
|
34
|
+
},
|
|
35
|
+
'disabled': {
|
|
36
|
+
control: { type: 'boolean' },
|
|
37
|
+
description: 'Désactive le bouton',
|
|
38
|
+
default: false,
|
|
39
|
+
},
|
|
40
|
+
'onClick-icon-button': {
|
|
41
|
+
action: 'click-icon-button',
|
|
42
|
+
description: 'Événement émis lors du clic sur le bouton',
|
|
43
|
+
},
|
|
44
|
+
'variant': {
|
|
45
|
+
options: ['flat', 'elevated', 'tonal', 'outlined', 'text', 'plain'],
|
|
46
|
+
control: { type: 'select' },
|
|
47
|
+
description: 'Variante visuelle du bouton',
|
|
48
|
+
},
|
|
49
|
+
},
|
|
50
|
+
} satisfies Meta<typeof SyIconButton>
|
|
51
|
+
|
|
52
|
+
export default meta
|
|
53
|
+
|
|
54
|
+
type Story = StoryObj<typeof meta>
|
|
55
|
+
|
|
56
|
+
export const Default: Story = {
|
|
57
|
+
parameters: {
|
|
58
|
+
sourceCode: [
|
|
59
|
+
{
|
|
60
|
+
name: 'Template',
|
|
61
|
+
language: 'vue',
|
|
62
|
+
code: `
|
|
63
|
+
<template>
|
|
64
|
+
<SyIconButton :icon="mdiClose" label="Fermer" @click-icon-button="handleClick" />
|
|
65
|
+
</template>`,
|
|
66
|
+
},
|
|
67
|
+
],
|
|
68
|
+
},
|
|
69
|
+
args: {
|
|
70
|
+
'icon': mdiClose,
|
|
71
|
+
'label': 'Fermer',
|
|
72
|
+
'onClick-icon-button': fn(),
|
|
73
|
+
},
|
|
74
|
+
render: args => ({
|
|
75
|
+
components: { SyIconButton },
|
|
76
|
+
setup() {
|
|
77
|
+
const handleClick = () => {
|
|
78
|
+
alert('Bouton cliqué !')
|
|
79
|
+
}
|
|
80
|
+
return { args, mdiClose, handleClick }
|
|
81
|
+
},
|
|
82
|
+
template: `
|
|
83
|
+
<div class="pa-4">
|
|
84
|
+
<SyIconButton v-bind="args" @click-icon-button="handleClick" />
|
|
85
|
+
</div>
|
|
86
|
+
`,
|
|
87
|
+
}),
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
export const Disabled: Story = {
|
|
91
|
+
parameters: {
|
|
92
|
+
sourceCode: [
|
|
93
|
+
{
|
|
94
|
+
name: 'Template',
|
|
95
|
+
language: 'vue',
|
|
96
|
+
code: `
|
|
97
|
+
<template>
|
|
98
|
+
<SyIconButton :icon="mdiClose" label="Fermer" :disabled="true" />
|
|
99
|
+
</template>`,
|
|
100
|
+
},
|
|
101
|
+
],
|
|
102
|
+
},
|
|
103
|
+
args: {
|
|
104
|
+
'icon': mdiClose,
|
|
105
|
+
'label': 'Fermer',
|
|
106
|
+
'disabled': true,
|
|
107
|
+
'onClick-icon-button': fn(),
|
|
108
|
+
},
|
|
109
|
+
render: args => ({
|
|
110
|
+
components: { SyIconButton },
|
|
111
|
+
setup() {
|
|
112
|
+
return { args, mdiClose }
|
|
113
|
+
},
|
|
114
|
+
template: `
|
|
115
|
+
<div class="pa-4">
|
|
116
|
+
<SyIconButton v-bind="args" />
|
|
117
|
+
</div>
|
|
118
|
+
`,
|
|
119
|
+
}),
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
export const WithColor: Story = {
|
|
123
|
+
parameters: {
|
|
124
|
+
sourceCode: [
|
|
125
|
+
{
|
|
126
|
+
name: 'Template',
|
|
127
|
+
language: 'vue',
|
|
128
|
+
code: `
|
|
129
|
+
<template>
|
|
130
|
+
<SyIconButton :icon="mdiAlert" label="Alerte" color="red" />
|
|
131
|
+
</template>`,
|
|
132
|
+
},
|
|
133
|
+
],
|
|
134
|
+
},
|
|
135
|
+
args: {
|
|
136
|
+
'icon': mdiAlert,
|
|
137
|
+
'label': 'Alerte',
|
|
138
|
+
'color': 'red',
|
|
139
|
+
'onClick-icon-button': fn(),
|
|
140
|
+
},
|
|
141
|
+
render: args => ({
|
|
142
|
+
components: { SyIconButton },
|
|
143
|
+
setup() {
|
|
144
|
+
return { args, mdiAlert }
|
|
145
|
+
},
|
|
146
|
+
template: `
|
|
147
|
+
<div class="pa-4">
|
|
148
|
+
<SyIconButton v-bind="args" />
|
|
149
|
+
</div>
|
|
150
|
+
`,
|
|
151
|
+
}),
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
export const WithSize: Story = {
|
|
155
|
+
parameters: {
|
|
156
|
+
sourceCode: [
|
|
157
|
+
{
|
|
158
|
+
name: 'Template',
|
|
159
|
+
language: 'vue',
|
|
160
|
+
code: `
|
|
161
|
+
<template>
|
|
162
|
+
<SyIconButton :icon="mdiMagnify" label="Rechercher" size="small" />
|
|
163
|
+
</template>`,
|
|
164
|
+
},
|
|
165
|
+
],
|
|
166
|
+
},
|
|
167
|
+
args: {
|
|
168
|
+
'icon': mdiMagnify,
|
|
169
|
+
'label': 'Rechercher',
|
|
170
|
+
'onClick-icon-button': fn(),
|
|
171
|
+
},
|
|
172
|
+
render: args => ({
|
|
173
|
+
components: { SyIconButton },
|
|
174
|
+
setup() {
|
|
175
|
+
const sizes = ['x-small', 'small', 'default', 'large', 'x-large']
|
|
176
|
+
return { args, mdiMagnify, sizes }
|
|
177
|
+
},
|
|
178
|
+
template: `
|
|
179
|
+
<div class="pa-4 d-flex align-center ga-4">
|
|
180
|
+
<SyIconButton v-for="size in sizes" :key="size" v-bind="args" :size="size" />
|
|
181
|
+
</div>
|
|
182
|
+
`,
|
|
183
|
+
}),
|
|
184
|
+
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import type { IconValue } from 'vuetify/lib/composables/icons.mjs'
|
|
3
|
+
import SyIcon from '../SyIcon/SyIcon.vue'
|
|
4
|
+
|
|
5
|
+
type Size = 'x-small' | 'small' | 'default' | 'large' | 'x-large'
|
|
6
|
+
type Variant = 'flat' | 'text' | 'elevated' | 'tonal' | 'outlined' | 'plain'
|
|
7
|
+
type Color = 'primary' | 'secondary' | 'success' | 'error' | 'warning' | 'info' | (string & {})
|
|
8
|
+
|
|
9
|
+
const props = defineProps<{
|
|
10
|
+
icon: IconValue
|
|
11
|
+
label: string
|
|
12
|
+
color?: Color
|
|
13
|
+
size?: Size
|
|
14
|
+
disabled?: boolean
|
|
15
|
+
variant?: Variant
|
|
16
|
+
}>()
|
|
17
|
+
|
|
18
|
+
defineEmits<{ 'click-icon-button': [] }>()
|
|
19
|
+
</script>
|
|
20
|
+
|
|
21
|
+
<template>
|
|
22
|
+
<v-btn
|
|
23
|
+
:disabled="props.disabled"
|
|
24
|
+
:aria-label="props.label"
|
|
25
|
+
:variant="props.variant ?? 'text'"
|
|
26
|
+
:size="props.size"
|
|
27
|
+
class="rounded-circle"
|
|
28
|
+
icon
|
|
29
|
+
@click="$emit('click-icon-button')"
|
|
30
|
+
>
|
|
31
|
+
<SyIcon
|
|
32
|
+
:icon="props.icon"
|
|
33
|
+
:size="props.size"
|
|
34
|
+
:color="props.color"
|
|
35
|
+
:decorative="true"
|
|
36
|
+
/>
|
|
37
|
+
</v-btn>
|
|
38
|
+
</template>
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import { Meta, Primary } from '@storybook/blocks';
|
|
2
|
+
import * as SyIconButtonStories from '../SyIconButton.stories';
|
|
3
|
+
import AccessibilityIcon from '@/common/imgs/accessibility-svgrepo-com.svg';
|
|
4
|
+
import {
|
|
5
|
+
AccessibilityGuideLayout,
|
|
6
|
+
CriteriaSection,
|
|
7
|
+
CriteriaCard,
|
|
8
|
+
DemoSection,
|
|
9
|
+
BestPracticesSection,
|
|
10
|
+
ResourcesSection,
|
|
11
|
+
} from '@/stories/accessibility/AccessibilityGuideLayout.mdx';
|
|
12
|
+
|
|
13
|
+
<Meta of={SyIconButtonStories} />
|
|
14
|
+
|
|
15
|
+
<AccessibilityGuideLayout
|
|
16
|
+
componentName="SyIconButton"
|
|
17
|
+
iconSrc={AccessibilityIcon}
|
|
18
|
+
>
|
|
19
|
+
<CriteriaSection>
|
|
20
|
+
<CriteriaCard icon="🔍" title="Structure sémantique">
|
|
21
|
+
<ul>
|
|
22
|
+
<li><strong>Élément bouton</strong> : le composant repose sur un <code>v-btn</code> qui génère un élément <code><button></code> natif — il est nativement reconnu par les lecteurs d'écran et les outils d'assistance</li>
|
|
23
|
+
<li><strong>Prop <code>label</code> obligatoire</strong> : la prop <code>label</code> est requise et est portée par le bouton via <code>aria-label</code> — elle constitue le nom accessible du bouton</li>
|
|
24
|
+
<li><strong>Icône décorative</strong> : le composant <code>SyIcon</code> interne reçoit <code>:decorative="true"</code> — l'icône est ignorée par les lecteurs d'écran car le bouton porte déjà le nom accessible via <code>aria-label</code></li>
|
|
25
|
+
<li><strong>Prop <code>disabled</code></strong> : lorsque <code>disabled</code> est à <code>true</code>, l'attribut <code>disabled</code> est appliqué nativement sur le <code><button></code>, le rendant inaccessible au clavier et annoncé comme désactivé par les lecteurs d'écran</li>
|
|
26
|
+
<li><strong>Prop <code>variant</code></strong> : par défaut à <code>text</code> — les autres variantes (<code>outlined</code>, <code>tonal</code>, etc.) n'affectent pas l'accessibilité du bouton</li>
|
|
27
|
+
</ul>
|
|
28
|
+
</CriteriaCard>
|
|
29
|
+
|
|
30
|
+
<CriteriaCard icon="⌨️" title="Navigation clavier">
|
|
31
|
+
<ul>
|
|
32
|
+
<li><strong>Focusable</strong> : le bouton est naturellement focusable via <kbd>Tab</kbd> grâce à l'élément <code><button></code> natif</li>
|
|
33
|
+
<li><strong>Activation</strong> : le bouton peut être activé via <kbd>Entrée</kbd> ou <kbd>Espace</kbd> nativement</li>
|
|
34
|
+
<li><strong>État désactivé</strong> : lorsque <code>disabled</code> est à <code>true</code>, le bouton est retiré de l'ordre de tabulation et ne peut pas être activé au clavier</li>
|
|
35
|
+
<li><strong>Événement</strong> : le composant émet <code>click-icon-button</code> au clic ou à l'activation clavier</li>
|
|
36
|
+
</ul>
|
|
37
|
+
</CriteriaCard>
|
|
38
|
+
</CriteriaSection>
|
|
39
|
+
|
|
40
|
+
<DemoSection componentName="SyIconButton">
|
|
41
|
+
<Primary />
|
|
42
|
+
</DemoSection>
|
|
43
|
+
|
|
44
|
+
<BestPracticesSection>
|
|
45
|
+
<ul>
|
|
46
|
+
<li>La prop <code>label</code> est <strong>obligatoire</strong> — sans elle, le bouton icône n'a pas de nom accessible et sera incompréhensible pour les utilisateurs de lecteurs d'écran</li>
|
|
47
|
+
<li>Le <code>label</code> doit décrire l'<strong>action</strong> du bouton et non l'icône elle-même (ex. <em>"Fermer"</em> plutôt que <em>"Croix"</em>)</li>
|
|
48
|
+
<li>Ne jamais fournir un <code>label</code> vide (<code>""</code>) — cela rendrait le bouton inaccessible</li>
|
|
49
|
+
<li>Utiliser <code>disabled</code> plutôt que de masquer le bouton lorsqu'il est temporairement indisponible, afin de préserver la cohérence de la mise en page</li>
|
|
50
|
+
<li>Ne pas ajouter d'<code>aria-label</code> supplémentaire sur le composant parent — celui du <code>v-btn</code> est suffisant</li>
|
|
51
|
+
<li>La prop <code>variant</code> ne doit pas être choisie pour des raisons d'accessibilité — s'assurer que le contraste reste suffisant quelle que soit la variante utilisée (WCAG 1.4.3)</li>
|
|
52
|
+
</ul>
|
|
53
|
+
</BestPracticesSection>
|
|
54
|
+
|
|
55
|
+
<ResourcesSection>
|
|
56
|
+
<ul>
|
|
57
|
+
<li><a href="https://www.w3.org/WAI/WCAG21/Understanding/name-role-value.html" target="_blank" style={{ color: '#0C41BD' }}>WCAG 4.1.2 – Name, Role, Value</a></li>
|
|
58
|
+
<li><a href="https://www.w3.org/WAI/WCAG21/Understanding/non-text-content.html" target="_blank" style={{ color: '#0C41BD' }}>WCAG 1.1.1 – Non-text Content</a></li>
|
|
59
|
+
<li><a href="https://www.w3.org/WAI/WCAG21/Understanding/keyboard.html" target="_blank" style={{ color: '#0C41BD' }}>WCAG 2.1.1 – Keyboard</a></li>
|
|
60
|
+
<li><a href="https://www.w3.org/WAI/WCAG21/Understanding/contrast-minimum.html" target="_blank" style={{ color: '#0C41BD' }}>WCAG 1.4.3 – Contrast (Minimum)</a></li>
|
|
61
|
+
<li><a href="https://www.w3.org/WAI/ARIA/apg/patterns/button/" target="_blank" style={{ color: '#0C41BD' }}>ARIA Authoring Practices – Button Pattern</a></li>
|
|
62
|
+
</ul>
|
|
63
|
+
</ResourcesSection>
|
|
64
|
+
</AccessibilityGuideLayout>
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
// @vitest-environment jsdom
|
|
2
|
+
import { describe, it } from 'vitest'
|
|
3
|
+
import { mount } from '@vue/test-utils'
|
|
4
|
+
import { axe } from 'vitest-axe'
|
|
5
|
+
import { assertNoA11yViolations } from '@tests/unit/accessibility/axeUtils'
|
|
6
|
+
import SyIconButton from '../SyIconButton.vue'
|
|
7
|
+
|
|
8
|
+
const globalStubs = {
|
|
9
|
+
global: {
|
|
10
|
+
stubs: {
|
|
11
|
+
'v-btn': {
|
|
12
|
+
template: '<button :aria-label="ariaLabel" :disabled="disabled"><slot></slot></button>',
|
|
13
|
+
props: ['ariaLabel', 'disabled', 'size', 'variant', 'icon'],
|
|
14
|
+
},
|
|
15
|
+
'SyIcon': {
|
|
16
|
+
template: '<span class="sy-icon" :aria-hidden="decorative ? true : undefined"></span>',
|
|
17
|
+
props: ['icon', 'color', 'size', 'decorative'],
|
|
18
|
+
},
|
|
19
|
+
},
|
|
20
|
+
},
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
describe('SyIconButton – accessibility (axe)', () => {
|
|
24
|
+
it('has no obvious axe violations in default state', async () => {
|
|
25
|
+
const wrapper = mount(SyIconButton, {
|
|
26
|
+
props: {
|
|
27
|
+
icon: 'mdi-close',
|
|
28
|
+
label: 'Fermer',
|
|
29
|
+
},
|
|
30
|
+
...globalStubs,
|
|
31
|
+
})
|
|
32
|
+
|
|
33
|
+
const results = await axe(wrapper.element as HTMLElement)
|
|
34
|
+
assertNoA11yViolations(results, 'SyIconButton – default state', {
|
|
35
|
+
ignoreRules: ['region'],
|
|
36
|
+
})
|
|
37
|
+
})
|
|
38
|
+
|
|
39
|
+
it('has no obvious axe violations when disabled', async () => {
|
|
40
|
+
const wrapper = mount(SyIconButton, {
|
|
41
|
+
props: {
|
|
42
|
+
icon: 'mdi-close',
|
|
43
|
+
label: 'Fermer',
|
|
44
|
+
disabled: true,
|
|
45
|
+
},
|
|
46
|
+
...globalStubs,
|
|
47
|
+
})
|
|
48
|
+
|
|
49
|
+
const results = await axe(wrapper.element as HTMLElement)
|
|
50
|
+
assertNoA11yViolations(results, 'SyIconButton – disabled', {
|
|
51
|
+
ignoreRules: ['region'],
|
|
52
|
+
})
|
|
53
|
+
})
|
|
54
|
+
|
|
55
|
+
it('has no obvious axe violations with color and size', async () => {
|
|
56
|
+
const wrapper = mount(SyIconButton, {
|
|
57
|
+
props: {
|
|
58
|
+
icon: 'mdi-alert',
|
|
59
|
+
label: 'Alerte importante',
|
|
60
|
+
color: 'primary',
|
|
61
|
+
size: 'large',
|
|
62
|
+
},
|
|
63
|
+
...globalStubs,
|
|
64
|
+
})
|
|
65
|
+
|
|
66
|
+
const results = await axe(wrapper.element as HTMLElement)
|
|
67
|
+
assertNoA11yViolations(results, 'SyIconButton – color and size', {
|
|
68
|
+
ignoreRules: ['region'],
|
|
69
|
+
})
|
|
70
|
+
})
|
|
71
|
+
|
|
72
|
+
it('has aria-label on the button', async () => {
|
|
73
|
+
const wrapper = mount(SyIconButton, {
|
|
74
|
+
props: {
|
|
75
|
+
icon: 'mdi-close',
|
|
76
|
+
label: 'Fermer',
|
|
77
|
+
},
|
|
78
|
+
...globalStubs,
|
|
79
|
+
})
|
|
80
|
+
|
|
81
|
+
const results = await axe(wrapper.element as HTMLElement)
|
|
82
|
+
|
|
83
|
+
assertNoA11yViolations(results, 'SyIconButton – aria-label on button', {
|
|
84
|
+
ignoreRules: ['region'],
|
|
85
|
+
})
|
|
86
|
+
})
|
|
87
|
+
})
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
import { describe, it, expect } from 'vitest'
|
|
2
|
+
import { mount } from '@vue/test-utils'
|
|
3
|
+
import SyIconButton from '../SyIconButton.vue'
|
|
4
|
+
|
|
5
|
+
const globalStubs = {
|
|
6
|
+
global: {
|
|
7
|
+
stubs: {
|
|
8
|
+
'v-btn': {
|
|
9
|
+
template: '<button :aria-label="ariaLabel" :disabled="disabled" @click="$emit(\'click\', $event)"><slot></slot></button>',
|
|
10
|
+
props: ['ariaLabel', 'disabled', 'size', 'variant', 'icon'],
|
|
11
|
+
emits: ['click'],
|
|
12
|
+
},
|
|
13
|
+
'SyIcon': {
|
|
14
|
+
template: '<span class="sy-icon" :aria-hidden="decorative ? true : undefined"></span>',
|
|
15
|
+
props: ['icon', 'color', 'size', 'decorative'],
|
|
16
|
+
},
|
|
17
|
+
},
|
|
18
|
+
},
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
describe('SyIconButton', () => {
|
|
22
|
+
it('renders correctly', () => {
|
|
23
|
+
const wrapper = mount(SyIconButton, {
|
|
24
|
+
props: {
|
|
25
|
+
icon: 'mdi-close',
|
|
26
|
+
label: 'Fermer',
|
|
27
|
+
},
|
|
28
|
+
...globalStubs,
|
|
29
|
+
})
|
|
30
|
+
|
|
31
|
+
expect(wrapper.html()).toMatchSnapshot()
|
|
32
|
+
})
|
|
33
|
+
|
|
34
|
+
it('renders a button with the correct aria-label', () => {
|
|
35
|
+
const wrapper = mount(SyIconButton, {
|
|
36
|
+
props: {
|
|
37
|
+
icon: 'mdi-close',
|
|
38
|
+
label: 'Fermer',
|
|
39
|
+
},
|
|
40
|
+
...globalStubs,
|
|
41
|
+
})
|
|
42
|
+
|
|
43
|
+
const button = wrapper.find('button')
|
|
44
|
+
expect(button.exists()).toBe(true)
|
|
45
|
+
expect(button.attributes('aria-label')).toBe('Fermer')
|
|
46
|
+
})
|
|
47
|
+
|
|
48
|
+
it('renders the icon as decorative (aria-hidden="true")', () => {
|
|
49
|
+
const wrapper = mount(SyIconButton, {
|
|
50
|
+
props: {
|
|
51
|
+
icon: 'mdi-close',
|
|
52
|
+
label: 'Fermer',
|
|
53
|
+
},
|
|
54
|
+
...globalStubs,
|
|
55
|
+
})
|
|
56
|
+
|
|
57
|
+
const icon = wrapper.find('.sy-icon')
|
|
58
|
+
expect(icon.exists()).toBe(true)
|
|
59
|
+
expect(icon.attributes('aria-hidden')).toBe('true')
|
|
60
|
+
})
|
|
61
|
+
|
|
62
|
+
it('renders the correct icon', () => {
|
|
63
|
+
const wrapper = mount(SyIconButton, {
|
|
64
|
+
props: {
|
|
65
|
+
icon: 'mdi-close',
|
|
66
|
+
label: 'Fermer',
|
|
67
|
+
},
|
|
68
|
+
...globalStubs,
|
|
69
|
+
})
|
|
70
|
+
|
|
71
|
+
expect(wrapper.find('.sy-icon').exists()).toBe(true)
|
|
72
|
+
})
|
|
73
|
+
|
|
74
|
+
it('disables the button when disabled prop is true', () => {
|
|
75
|
+
const wrapper = mount(SyIconButton, {
|
|
76
|
+
props: {
|
|
77
|
+
icon: 'mdi-close',
|
|
78
|
+
label: 'Fermer',
|
|
79
|
+
disabled: true,
|
|
80
|
+
},
|
|
81
|
+
...globalStubs,
|
|
82
|
+
})
|
|
83
|
+
|
|
84
|
+
expect(wrapper.find('button').attributes('disabled')).toBeDefined()
|
|
85
|
+
})
|
|
86
|
+
|
|
87
|
+
it('emits click-icon-button when clicked', async () => {
|
|
88
|
+
const wrapper = mount(SyIconButton, {
|
|
89
|
+
props: {
|
|
90
|
+
icon: 'mdi-close',
|
|
91
|
+
label: 'Fermer',
|
|
92
|
+
},
|
|
93
|
+
...globalStubs,
|
|
94
|
+
})
|
|
95
|
+
|
|
96
|
+
await wrapper.find('button').trigger('click')
|
|
97
|
+
expect(wrapper.emitted('click-icon-button')).toBeTruthy()
|
|
98
|
+
})
|
|
99
|
+
|
|
100
|
+
it('passes the size prop to v-btn', () => {
|
|
101
|
+
const wrapper = mount(SyIconButton, {
|
|
102
|
+
props: {
|
|
103
|
+
icon: 'mdi-close',
|
|
104
|
+
label: 'Fermer',
|
|
105
|
+
size: 'large',
|
|
106
|
+
},
|
|
107
|
+
...globalStubs,
|
|
108
|
+
})
|
|
109
|
+
|
|
110
|
+
expect(wrapper.html()).toMatchSnapshot()
|
|
111
|
+
})
|
|
112
|
+
|
|
113
|
+
it('passes the color prop to SyIcon', () => {
|
|
114
|
+
const wrapper = mount(SyIconButton, {
|
|
115
|
+
props: {
|
|
116
|
+
icon: 'mdi-close',
|
|
117
|
+
label: 'Fermer',
|
|
118
|
+
color: 'primary',
|
|
119
|
+
},
|
|
120
|
+
...globalStubs,
|
|
121
|
+
})
|
|
122
|
+
|
|
123
|
+
expect(wrapper.html()).toMatchSnapshot()
|
|
124
|
+
})
|
|
125
|
+
|
|
126
|
+
it('passes the variant prop to v-btn', () => {
|
|
127
|
+
const wrapper = mount(SyIconButton, {
|
|
128
|
+
props: {
|
|
129
|
+
icon: 'mdi-close',
|
|
130
|
+
label: 'Fermer',
|
|
131
|
+
variant: 'outlined',
|
|
132
|
+
},
|
|
133
|
+
...globalStubs,
|
|
134
|
+
})
|
|
135
|
+
|
|
136
|
+
expect(wrapper.html()).toMatchSnapshot()
|
|
137
|
+
})
|
|
138
|
+
|
|
139
|
+
it('uses text variant by default', () => {
|
|
140
|
+
const wrapper = mount(SyIconButton, {
|
|
141
|
+
props: {
|
|
142
|
+
icon: 'mdi-close',
|
|
143
|
+
label: 'Fermer',
|
|
144
|
+
},
|
|
145
|
+
...globalStubs,
|
|
146
|
+
})
|
|
147
|
+
|
|
148
|
+
const button = wrapper.find('button')
|
|
149
|
+
expect(button.exists()).toBe(true)
|
|
150
|
+
expect(wrapper.html()).toMatchSnapshot()
|
|
151
|
+
})
|
|
152
|
+
})
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
|
|
2
|
+
|
|
3
|
+
exports[`SyIconButton > passes the color prop to SyIcon 1`] = `
|
|
4
|
+
<button
|
|
5
|
+
aria-label="Fermer"
|
|
6
|
+
class="rounded-circle"
|
|
7
|
+
>
|
|
8
|
+
<span
|
|
9
|
+
aria-hidden="true"
|
|
10
|
+
class="sy-icon"
|
|
11
|
+
></span>
|
|
12
|
+
</button>
|
|
13
|
+
`;
|
|
14
|
+
|
|
15
|
+
exports[`SyIconButton > passes the size prop to v-btn 1`] = `
|
|
16
|
+
<button
|
|
17
|
+
aria-label="Fermer"
|
|
18
|
+
class="rounded-circle"
|
|
19
|
+
>
|
|
20
|
+
<span
|
|
21
|
+
aria-hidden="true"
|
|
22
|
+
class="sy-icon"
|
|
23
|
+
></span>
|
|
24
|
+
</button>
|
|
25
|
+
`;
|
|
26
|
+
|
|
27
|
+
exports[`SyIconButton > passes the variant prop to v-btn 1`] = `
|
|
28
|
+
<button
|
|
29
|
+
aria-label="Fermer"
|
|
30
|
+
class="rounded-circle"
|
|
31
|
+
>
|
|
32
|
+
<span
|
|
33
|
+
aria-hidden="true"
|
|
34
|
+
class="sy-icon"
|
|
35
|
+
></span>
|
|
36
|
+
</button>
|
|
37
|
+
`;
|
|
38
|
+
|
|
39
|
+
exports[`SyIconButton > renders correctly 1`] = `
|
|
40
|
+
<button
|
|
41
|
+
aria-label="Fermer"
|
|
42
|
+
class="rounded-circle"
|
|
43
|
+
>
|
|
44
|
+
<span
|
|
45
|
+
aria-hidden="true"
|
|
46
|
+
class="sy-icon"
|
|
47
|
+
></span>
|
|
48
|
+
</button>
|
|
49
|
+
`;
|
|
50
|
+
|
|
51
|
+
exports[`SyIconButton > uses text variant by default 1`] = `
|
|
52
|
+
<button
|
|
53
|
+
aria-label="Fermer"
|
|
54
|
+
class="rounded-circle"
|
|
55
|
+
>
|
|
56
|
+
<span
|
|
57
|
+
aria-hidden="true"
|
|
58
|
+
class="sy-icon"
|
|
59
|
+
></span>
|
|
60
|
+
</button>
|
|
61
|
+
`;
|
|
@@ -384,8 +384,8 @@
|
|
|
384
384
|
display: inline-block;
|
|
385
385
|
padding: 0.5rem 0.75rem;
|
|
386
386
|
text-decoration: none;
|
|
387
|
-
color:
|
|
388
|
-
border: 1px solid
|
|
387
|
+
color: var(--pagination-color);
|
|
388
|
+
border: 1px solid var(--pagination-border);
|
|
389
389
|
border-radius: 4px;
|
|
390
390
|
transition: all 0.2s ease;
|
|
391
391
|
font-size: 0.875rem;
|
|
@@ -393,11 +393,11 @@
|
|
|
393
393
|
|
|
394
394
|
&:hover,
|
|
395
395
|
&:focus {
|
|
396
|
-
background-color:
|
|
396
|
+
background-color: var(--pagination-focused-background-color);
|
|
397
397
|
}
|
|
398
398
|
|
|
399
399
|
&[aria-current='page'] {
|
|
400
|
-
background-color:
|
|
400
|
+
background-color: var(--pagination-background-color);
|
|
401
401
|
color: white;
|
|
402
402
|
font-weight: 500;
|
|
403
403
|
}
|
|
@@ -414,7 +414,7 @@
|
|
|
414
414
|
border: none;
|
|
415
415
|
pointer-events: none;
|
|
416
416
|
display: inline-block;
|
|
417
|
-
color:
|
|
417
|
+
color: var(--pagination-ellipsis);
|
|
418
418
|
padding: 0.6rem;
|
|
419
419
|
}
|
|
420
420
|
}
|
|
@@ -667,7 +667,7 @@
|
|
|
667
667
|
>
|
|
668
668
|
<!-- Prepend -->
|
|
669
669
|
<template
|
|
670
|
-
v-if="props.prependIcon || props.prependTooltip"
|
|
670
|
+
v-if="props.prependIcon || props.prependTooltip || $slots['prepend']"
|
|
671
671
|
#prepend
|
|
672
672
|
>
|
|
673
673
|
<slot name="prepend">
|
|
@@ -706,7 +706,7 @@
|
|
|
706
706
|
|
|
707
707
|
<!-- Append -->
|
|
708
708
|
<template
|
|
709
|
-
v-if="props.appendIcon || props.appendTooltip"
|
|
709
|
+
v-if="props.appendIcon || props.appendTooltip || $slots['append']"
|
|
710
710
|
#append
|
|
711
711
|
>
|
|
712
712
|
<slot name="append">
|
|
@@ -743,6 +743,14 @@
|
|
|
743
743
|
</slot>
|
|
744
744
|
</template>
|
|
745
745
|
|
|
746
|
+
<!-- Default slot passthrough: renders inside v-field__input (flex-wrap container) -->
|
|
747
|
+
<template
|
|
748
|
+
v-if="$slots.default"
|
|
749
|
+
#default
|
|
750
|
+
>
|
|
751
|
+
<slot />
|
|
752
|
+
</template>
|
|
753
|
+
|
|
746
754
|
<!-- Prepend inner -->
|
|
747
755
|
<template #prepend-inner>
|
|
748
756
|
<slot name="prepend-inner">
|
|
@@ -795,6 +803,16 @@
|
|
|
795
803
|
<template #details>
|
|
796
804
|
<slot name="details" />
|
|
797
805
|
</template>
|
|
806
|
+
|
|
807
|
+
<template #loader="{ color: loaderColor, isActive: loaderActive }">
|
|
808
|
+
<VProgressLinear
|
|
809
|
+
v-if="loaderActive"
|
|
810
|
+
indeterminate
|
|
811
|
+
rounded
|
|
812
|
+
:color="loaderColor"
|
|
813
|
+
:aria-label="props.label ? `Chargement de ${props.label}` : 'Chargement en cours'"
|
|
814
|
+
/>
|
|
815
|
+
</template>
|
|
798
816
|
</VTextField>
|
|
799
817
|
|
|
800
818
|
<div
|