@cnamts/synapse 0.0.3-alpha → 0.0.4-alpha

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.
Files changed (185) hide show
  1. package/dist/design-system-v3.d.ts +712 -27
  2. package/dist/design-system-v3.js +2715 -1485
  3. package/dist/design-system-v3.umd.cjs +10 -1
  4. package/dist/style.css +1 -1
  5. package/package.json +5 -2
  6. package/src/components/Alert/Alert.mdx +1 -1
  7. package/src/components/Alert/Alert.stories.ts +91 -1
  8. package/src/components/BackBtn/BackBtn.mdx +1 -1
  9. package/src/components/BackBtn/BackBtn.stories.ts +84 -1
  10. package/src/components/BackToTopBtn/BackToTopBtn.mdx +3 -3
  11. package/src/components/BackToTopBtn/BackToTopBtn.stories.ts +172 -11
  12. package/src/components/CollapsibleList/CollapsibleList.mdx +2 -2
  13. package/src/components/CollapsibleList/CollapsibleList.stories.ts +37 -1
  14. package/src/components/CopyBtn/CopyBtn.mdx +1 -1
  15. package/src/components/CopyBtn/CopyBtn.stories.ts +120 -1
  16. package/src/components/CopyBtn/CopyBtn.vue +1 -1
  17. package/src/components/Customs/CustomInputSelect/CustomInputSelect.mdx +6 -8
  18. package/src/components/Customs/CustomInputSelect/CustomInputSelect.stories.ts +270 -4
  19. package/src/components/Customs/CustomInputSelect/CustomInputSelect.vue +80 -53
  20. package/src/components/Customs/CustomInputSelect/config.ts +10 -0
  21. package/src/components/Customs/CustomSelect/CustomSelect.mdx +3 -3
  22. package/src/components/Customs/CustomSelect/CustomSelect.stories.ts +158 -2
  23. package/src/components/Customs/CustomSelect/CustomSelect.vue +25 -6
  24. package/src/components/Customs/CustomTextField/CustomTextField.mdx +44 -0
  25. package/src/components/Customs/CustomTextField/CustomTextField.stories.ts +403 -0
  26. package/src/components/Customs/CustomTextField/CustomTextField.vue +110 -0
  27. package/src/components/Customs/CustomTextField/tests/CustomTextField.spec.ts +93 -0
  28. package/src/components/Customs/CustomTextField/tests/__snapshots__/CustomTextField.spec.ts.snap +59 -0
  29. package/src/components/Customs/CustomTextField/types.d.ts +3 -0
  30. package/src/components/DataList/DataList.mdx +77 -0
  31. package/src/components/DataList/DataList.stories.ts +960 -0
  32. package/src/components/DataList/DataList.vue +140 -0
  33. package/src/components/DataList/DataListLoading/DataListLoading.vue +56 -0
  34. package/src/components/DataList/DataListLoading/tests/DataListLoading.spec.ts +23 -0
  35. package/src/components/DataList/locales.ts +3 -0
  36. package/src/components/DataList/tests/DataList.spec.ts +194 -0
  37. package/src/components/DataList/types.d.ts +23 -0
  38. package/src/components/DataListGroup/DataListGroup.mdx +77 -0
  39. package/src/components/DataListGroup/DataListGroup.stories.ts +987 -0
  40. package/src/components/DataListGroup/DataListGroup.vue +59 -0
  41. package/src/components/DataListGroup/tests/DataListGroup.spec.ts +54 -0
  42. package/src/components/DataListGroup/tests/data/dataListGroupItems.ts +41 -0
  43. package/src/components/DataListGroup/types.d.ts +15 -0
  44. package/src/components/DataListItem/DataListItem.vue +135 -0
  45. package/src/components/DataListItem/config.ts +17 -0
  46. package/src/components/DataListItem/locales.ts +3 -0
  47. package/src/components/DataListItem/tests/DataListItem.spec.ts +156 -0
  48. package/src/components/DataListItem/types.d.ts +23 -0
  49. package/src/components/DownloadBtn/Accessibilite.mdx +14 -0
  50. package/src/components/DownloadBtn/Accessibilite.stories.ts +166 -0
  51. package/src/components/DownloadBtn/AccessibiliteItems.ts +129 -0
  52. package/src/components/DownloadBtn/DownloadBtn.mdx +5 -6
  53. package/src/components/DownloadBtn/DownloadBtn.stories.ts +207 -2
  54. package/src/components/DownloadBtn/constants/ExpertiseLevelEnum.ts +4 -0
  55. package/src/components/FooterBar/FooterBar.mdx +2 -2
  56. package/src/components/FooterBar/FooterBar.stories.ts +1 -1
  57. package/src/components/FranceConnectBtn/FranceConnectBtn.mdx +1 -1
  58. package/src/components/FranceConnectBtn/FranceConnectBtn.stories.ts +58 -1
  59. package/src/components/HeaderBar/HeaderBar.mdx +164 -45
  60. package/src/components/HeaderBar/HeaderBar.stories.ts +559 -15
  61. package/src/components/HeaderBar/HeaderBar.vue +60 -22
  62. package/src/components/HeaderBar/HeaderBurgerMenu/HeaderBurgerMenu.mdx +433 -0
  63. package/src/components/HeaderBar/HeaderBurgerMenu/HeaderBurgerMenu.stories.ts +1089 -0
  64. package/src/components/HeaderBar/{HeaderComplexMenu/HeaderComplexMenu.vue → HeaderBurgerMenu/HeaderBurgerMenu.vue} +74 -45
  65. package/src/components/HeaderBar/HeaderBurgerMenu/HeaderMenuItem/HeaderMenuItem.mdx +38 -0
  66. package/src/components/HeaderBar/HeaderBurgerMenu/HeaderMenuItem/HeaderMenuItem.stories.ts +89 -0
  67. package/src/components/HeaderBar/{HeaderComplexMenu → HeaderBurgerMenu}/HeaderMenuItem/tests/__snapshots__/HeaderMenuItem.spec.ts.snap +1 -1
  68. package/src/components/HeaderBar/HeaderBurgerMenu/HeaderMenuSection/HeaderMenuSection.mdx +17 -0
  69. package/src/components/HeaderBar/HeaderBurgerMenu/HeaderMenuSection/HeaderMenuSection.stories.ts +121 -0
  70. package/src/components/HeaderBar/{HeaderComplexMenu → HeaderBurgerMenu}/HeaderMenuSection/HeaderMenuSection.vue +2 -2
  71. package/src/components/HeaderBar/{HeaderComplexMenu → HeaderBurgerMenu}/HeaderMenuSection/tests/HeaderMenuSection.spec.ts +1 -3
  72. package/src/components/HeaderBar/HeaderBurgerMenu/HeaderSubMenu/HeaderSubMenu.mdx +43 -0
  73. package/src/components/HeaderBar/HeaderBurgerMenu/HeaderSubMenu/HeaderSubMenu.stories.ts +261 -0
  74. package/src/components/HeaderBar/{HeaderComplexMenu → HeaderBurgerMenu}/HeaderSubMenu/HeaderSubMenu.vue +17 -3
  75. package/src/components/HeaderBar/{HeaderComplexMenu → HeaderBurgerMenu}/HeaderSubMenu/tests/HeaderSubMenu.spec.ts +1 -1
  76. package/src/components/HeaderBar/HeaderBurgerMenu/tests/HeaderBurgerMenu.spec.ts +180 -0
  77. package/src/components/HeaderBar/HeaderBurgerMenu/tests/__snapshots__/HeaderBurgerMenu.spec.ts.snap +13 -0
  78. package/src/components/HeaderBar/HeaderBurgerMenu/tests/__snapshots__/HeaderComplexMenu.spec.ts.snap +13 -0
  79. package/src/components/HeaderBar/HeaderLogo/HeaderLogo.vue +62 -25
  80. package/src/components/HeaderBar/HeaderLogo/tests/HeaderLogo.spec.ts +49 -1
  81. package/src/components/HeaderBar/HeaderMenuBtn/HeaderMenuBtn.vue +19 -23
  82. package/src/components/HeaderBar/HeaderMenuBtn/tests/HeaderMenuBtn.spec.ts +70 -0
  83. package/src/components/HeaderBar/Usages.mdx +85 -0
  84. package/src/components/HeaderBar/consts.scss +0 -1
  85. package/src/components/HeaderBar/tests/HeaderBar.spec.ts +8 -2
  86. package/src/components/HeaderBar/tests/__snapshots__/HeaderBar.spec.ts.snap +5 -10
  87. package/src/components/HeaderLoading/HeaderLoading.mdx +28 -0
  88. package/src/components/HeaderLoading/HeaderLoading.stories.ts +62 -0
  89. package/src/components/HeaderLoading/HeaderLoading.vue +45 -0
  90. package/src/components/HeaderLoading/tests/HeaderLoading.spec.ts +22 -0
  91. package/src/components/HeaderNavigationBar/HeaderNavigationBar.mdx +128 -0
  92. package/src/components/HeaderNavigationBar/HeaderNavigationBar.stories.ts +784 -0
  93. package/src/components/HeaderNavigationBar/HeaderNavigationBar.vue +194 -0
  94. package/src/components/HeaderNavigationBar/HorizontalNavbar/HorizontalNavbar.vue +74 -0
  95. package/src/components/HeaderNavigationBar/HorizontalNavbar/config.ts +18 -0
  96. package/src/components/HeaderNavigationBar/tests/HeaderNavigationBar.spec.ts +127 -0
  97. package/src/components/HeaderNavigationBar/types.ts +7 -0
  98. package/src/components/HeaderToolbar/HeaderToolbar.mdx +31 -0
  99. package/src/components/HeaderToolbar/HeaderToolbar.stories.ts +343 -0
  100. package/src/components/HeaderToolbar/HeaderToolbar.vue +487 -0
  101. package/src/components/HeaderToolbar/tests/HeaderToolbar.spec.ts +196 -0
  102. package/src/components/HeaderToolbar/types.d.ts +20 -0
  103. package/src/components/LangBtn/LangBtn.mdx +1 -1
  104. package/src/components/LangBtn/LangBtn.stories.ts +125 -8
  105. package/src/components/Logo/Logo.mdx +2 -2
  106. package/src/components/Logo/Logo.stories.ts +147 -1
  107. package/src/components/LogoBrandSection/LogoBrandSection.mdx +14 -0
  108. package/src/components/LogoBrandSection/LogoBrandSection.stories.ts +158 -0
  109. package/src/components/LogoBrandSection/LogoBrandSection.vue +312 -0
  110. package/src/components/LogoBrandSection/assets/ameli-pro.svg +1 -0
  111. package/src/components/LogoBrandSection/assets/ameli.svg +1 -0
  112. package/src/components/LogoBrandSection/assets/cnam.svg +1 -0
  113. package/src/components/LogoBrandSection/assets/compte-ameli.svg +1 -0
  114. package/src/components/LogoBrandSection/dividerDimensionsMapping.ts +14 -0
  115. package/src/components/LogoBrandSection/locales.ts +14 -0
  116. package/src/components/LogoBrandSection/secondaryLogoMapping.ts +24 -0
  117. package/src/components/LogoBrandSection/tests/LogoBrandSection.spec.ts +365 -0
  118. package/src/components/LogoBrandSection/tests/__snapshots__/LogoBrandSection.spec.ts.snap +14 -0
  119. package/src/components/LogoBrandSection/types.ts +8 -0
  120. package/src/components/NotificationBar/NotificationBar.mdx +6 -6
  121. package/src/components/NotificationBar/NotificationBar.stories.ts +1 -1
  122. package/src/components/NotificationBar/NotificationBar.vue +2 -2
  123. package/src/components/NotificationBar/tests/NotificationBar.spec.ts +1 -1
  124. package/src/components/PageContainer/PageContainer.mdx +1 -1
  125. package/src/components/PageContainer/PageContainer.stories.ts +86 -1
  126. package/src/components/PhoneField/PhoneField.mdx +49 -0
  127. package/src/components/PhoneField/PhoneField.stories.ts +869 -0
  128. package/src/components/PhoneField/PhoneField.vue +230 -0
  129. package/src/components/PhoneField/indicatifs.ts +104 -0
  130. package/src/components/PhoneField/locales.ts +4 -0
  131. package/src/components/PhoneField/tests/PhoneField.spec.ts +179 -0
  132. package/src/components/SkipLink/SkipLink.stories.ts +50 -1
  133. package/src/components/SocialMediaLinks/SocialMediaLinks.mdx +28 -1
  134. package/src/components/SocialMediaLinks/SocialMediaLinks.stories.ts +37 -1
  135. package/src/components/SubHeader/SubHeader.mdx +31 -0
  136. package/src/components/SubHeader/SubHeader.stories.ts +1032 -0
  137. package/src/components/SubHeader/SubHeader.vue +185 -0
  138. package/src/components/SubHeader/config.ts +12 -0
  139. package/src/components/SubHeader/locales.ts +3 -0
  140. package/src/components/SubHeader/tests/SubHeader.spec.ts +144 -0
  141. package/src/components/index.ts +24 -7
  142. package/src/composables/widthable/index.ts +29 -0
  143. package/src/composables/widthable/tests/widthable.spec.ts +52 -0
  144. package/src/designTokens/tokens/cnam/cnamLightTheme.ts +2 -2
  145. package/src/main.ts +1 -0
  146. package/src/modules.d.ts +4 -0
  147. package/src/services/index.ts +1 -0
  148. package/src/stories/Demarrer/Accueil.mdx +10 -0
  149. package/src/stories/Demarrer/Accueil.stories.ts +76 -0
  150. package/src/stories/Demarrer/PolitiqueDeConfidentialite.mdx +9 -0
  151. package/src/stories/Demarrer/PolitiqueDeConfidentialite.stories.ts +20 -0
  152. package/src/stories/Fondamentaux/Accessibilite/Accessibilite.mdx +1 -2
  153. package/src/stories/Fondamentaux/Accessibilite/Accessibilite.stories.ts +1 -1
  154. package/src/stories/Fondamentaux/EcoConception/Econception.stories.ts +1 -1
  155. package/src/stories/GuideDuDev/moduleDeNotification.mdx +52 -48
  156. package/src/stories/GuideDuDev/vuetifyOptions.mdx +31 -28
  157. package/src/stories/Guidelines/CustomisationEtThemes.mdx +1 -1
  158. package/src/utils/functions/throttleDisplayFn/tests/throttleDisplayFn.spec.ts +47 -0
  159. package/src/utils/functions/throttleDisplayFn/throttleDisplayFn.ts +26 -0
  160. package/src/utils/rules/exactLength/index.ts +33 -0
  161. package/src/utils/rules/exactLength/locales.ts +6 -0
  162. package/src/utils/rules/required/index.ts +25 -0
  163. package/src/utils/rules/required/locales.ts +5 -0
  164. package/src/utils/rules/required/ruleMessageHelper.ts +14 -0
  165. package/src/utils/rules/required/tests/index.spec.ts +47 -0
  166. package/src/utils/rules/required/tests/rulesMessageHelper.spec.ts +22 -0
  167. package/src/utils/rules/types.d.ts +15 -0
  168. package/src/components/Beta/beta.mdx +0 -5
  169. package/src/components/Deprecated/deprecated.mdx +0 -5
  170. package/src/components/HeaderBar/HeaderComplexMenu/HeaderComplexMenu.stories.ts +0 -272
  171. package/src/components/HeaderBar/HeaderComplexMenu/HeaderMenuItem/HeaderMenuItem.stories.ts +0 -49
  172. package/src/components/HeaderBar/HeaderComplexMenu/HeaderMenuSection/HeaderMenuSection.stories.ts +0 -56
  173. package/src/components/HeaderBar/HeaderComplexMenu/HeaderSubMenu/HeaderSubMenu.stories.ts +0 -137
  174. package/src/components/HeaderBar/HeaderComplexMenu/tests/HeaderComplexMenu.spec.ts +0 -129
  175. package/src/components/HeaderBar/HeaderComplexMenu/tests/__snapshots__/HeaderComplexMenu.spec.ts.snap +0 -18
  176. package/src/stories/Home/Accueil.mdx +0 -7
  177. package/src/stories/Home/PolitiqueDeConfidentialite.mdx +0 -4
  178. package/src/stories/Home/synapse.webp +0 -0
  179. /package/src/components/HeaderBar/{HeaderComplexMenu → HeaderBurgerMenu}/HeaderMenuItem/HeaderMenuItem.vue +0 -0
  180. /package/src/components/HeaderBar/{HeaderComplexMenu → HeaderBurgerMenu}/HeaderMenuItem/tests/HeaderMenuItem.spec.ts +0 -0
  181. /package/src/components/HeaderBar/{HeaderComplexMenu → HeaderBurgerMenu}/conts.ts +0 -0
  182. /package/src/components/HeaderBar/{HeaderComplexMenu → HeaderBurgerMenu}/locals.ts +0 -0
  183. /package/src/components/HeaderBar/{HeaderComplexMenu → HeaderBurgerMenu}/tests/useHandleSubMenus.spec.ts +0 -0
  184. /package/src/components/HeaderBar/{HeaderComplexMenu → HeaderBurgerMenu}/useHandleSubMenus.ts +0 -0
  185. /package/src/components/Logo/{types.d.ts → types.ts} +0 -0
@@ -0,0 +1,59 @@
1
+ <script lang="ts" setup>
2
+ import type { PropType } from 'vue'
3
+ import type { DataListIcons } from '../DataList/types'
4
+ import type { DataListGroupItems, DataListActionEvent } from './types'
5
+ import DataList from '../DataList/DataList.vue'
6
+
7
+ const props = defineProps({
8
+ items: {
9
+ type: Array as PropType<DataListGroupItems>,
10
+ required: true,
11
+ },
12
+ icons: {
13
+ type: Object as PropType<DataListIcons | undefined>,
14
+ default: undefined,
15
+ },
16
+ itemWidth: {
17
+ type: String,
18
+ default: '200px',
19
+ },
20
+ loading: {
21
+ type: Boolean,
22
+ default: false,
23
+ },
24
+ renderHtmlValue: {
25
+ type: Boolean,
26
+ default: false,
27
+ },
28
+ })
29
+
30
+ const emit = defineEmits(['click:list-item'])
31
+
32
+ const emitItemAction = (dataListIndex: number, itemIndex: number): void => {
33
+ const eventValue: DataListActionEvent = {
34
+ dataListIndex,
35
+ itemIndex,
36
+ }
37
+
38
+ emit('click:list-item', eventValue)
39
+ }
40
+ </script>
41
+
42
+ <template>
43
+ <div class="vd-data-list-group d-flex flex-wrap max-width-none ma-n4">
44
+ <DataList
45
+ v-for="(dataList, index) in props.items"
46
+ :key="`vd-data-list-${index}`"
47
+ :loading="props.loading"
48
+ :render-html-value="props.renderHtmlValue"
49
+ :list-title="dataList.title"
50
+ :items="dataList.items"
51
+ :items-number-loading="dataList.itemsNumberLoading"
52
+ :heading-loading="dataList.headingLoading"
53
+ :width="props.itemWidth"
54
+ :icons="props.icons"
55
+ class="ma-4"
56
+ @click:item-action="emitItemAction(index, $event)"
57
+ />
58
+ </div>
59
+ </template>
@@ -0,0 +1,54 @@
1
+ import { describe, it, expect } from 'vitest'
2
+ import { mount } from '@vue/test-utils'
3
+
4
+ import DataListGroup from '../DataListGroup.vue'
5
+
6
+ import { dataListGroupItems } from './data/dataListGroupItems'
7
+ import { vuetify } from '@tests/unit/setup'
8
+
9
+ describe('DataListGroup', () => {
10
+ it('renders correctly', () => {
11
+ const wrapper = mount(DataListGroup, {
12
+ props: {
13
+ items: dataListGroupItems,
14
+ },
15
+ global: {
16
+ plugins: [vuetify],
17
+ },
18
+ })
19
+
20
+ expect(wrapper.find('h4').text()).toBe('Catégorie 1')
21
+ })
22
+
23
+ it('renders loading state correctly', async () => {
24
+ const wrapper = mount(DataListGroup, {
25
+ props: {
26
+ loading: true,
27
+ items: dataListGroupItems,
28
+ },
29
+ global: {
30
+ plugins: [vuetify],
31
+ },
32
+ })
33
+
34
+ expect(wrapper.find('.vd-data-list-loading').exists()).toBe(true)
35
+ })
36
+
37
+ it('emit the right event when clicking on a item button', async () => {
38
+ const wrapper = mount(DataListGroup, {
39
+ props: {
40
+ items: dataListGroupItems,
41
+ },
42
+ global: {
43
+ plugins: [vuetify],
44
+ },
45
+ })
46
+
47
+ const button = wrapper.find('button')
48
+ await button.trigger('click')
49
+
50
+ expect(wrapper.emitted('click:list-item')).toEqual([
51
+ [{ dataListIndex: 1, itemIndex: 0 }],
52
+ ])
53
+ })
54
+ })
@@ -0,0 +1,41 @@
1
+ import type { DataList } from '../../../DataList/types'
2
+ import type { DataListGroupItems } from '../../types'
3
+
4
+ export const dataListItems: DataList = [
5
+ {
6
+ key: 'Libellé',
7
+ value: 'Texte saisi',
8
+ },
9
+ {
10
+ key: 'Libellé',
11
+ value: 'Texte saisi',
12
+ },
13
+ ]
14
+
15
+ export const dataListItemsActions: DataList = [
16
+ {
17
+ key: 'Libellé',
18
+ value: 'Texte à modifier',
19
+ action: 'Modifier',
20
+ },
21
+ {
22
+ key: 'Libellé',
23
+ value: 'Texte à modifier',
24
+ action: 'Modifier',
25
+ },
26
+ ]
27
+
28
+ export const dataListGroupItems: DataListGroupItems = [
29
+ {
30
+ title: 'Catégorie 1',
31
+ items: dataListItems,
32
+ itemsNumberLoading: 2,
33
+ headingLoading: true,
34
+ },
35
+ {
36
+ title: 'Catégorie 2',
37
+ items: dataListItemsActions,
38
+ itemsNumberLoading: 2,
39
+ headingLoading: true,
40
+ },
41
+ ]
@@ -0,0 +1,15 @@
1
+ import type { DataList } from '../DataList/types'
2
+
3
+ export interface DataListActionEvent {
4
+ dataListIndex: number
5
+ itemIndex: number
6
+ }
7
+
8
+ export interface DataListGroupItem {
9
+ title?: string
10
+ items: DataList
11
+ headingLoading?: boolean
12
+ itemsNumberLoading?: number
13
+ }
14
+
15
+ export type DataListGroupItems = DataListGroupItem[]
@@ -0,0 +1,135 @@
1
+ <script lang="ts" setup>
2
+ import { computed } from 'vue'
3
+ import { useTheme } from 'vuetify'
4
+
5
+ import useCustomizableOptions, { type CustomizableOptions } from '@/composables/useCustomizableOptions'
6
+
7
+ import { config } from './config'
8
+ import { locales } from './locales'
9
+
10
+ const props = withDefaults(defineProps<CustomizableOptions & {
11
+ label: string
12
+ value?: string | number
13
+ action?: string
14
+ placeholder?: string
15
+ chip?: boolean
16
+ icon?: string
17
+ row?: boolean
18
+ renderHtmlValue?: boolean
19
+ }>(), {
20
+ label: '',
21
+ value: undefined,
22
+ action: undefined,
23
+ placeholder: locales.placeholder,
24
+ chip: false,
25
+ icon: undefined,
26
+ row: false,
27
+ renderHtmlValue: false,
28
+ })
29
+
30
+ const emits = defineEmits(['click:action'])
31
+
32
+ const options = useCustomizableOptions(config, props)
33
+ const theme = useTheme()
34
+
35
+ const labelColor = computed(() => {
36
+ return theme.current.value.dark
37
+ ? 'rgba(255, 255, 255, .7)'
38
+ : 'rgba(0, 0, 0, .6)'
39
+ })
40
+
41
+ const itemValue = computed(() => {
42
+ if (typeof props.value === 'number') {
43
+ return isNaN(props.value)
44
+ ? props.placeholder
45
+ : props.value.toString()
46
+ }
47
+ return props.value || props.placeholder
48
+ })
49
+ </script>
50
+
51
+ <template>
52
+ <li class="vd-data-list-item d-flex flex-wrap">
53
+ <slot name="icon">
54
+ <VIcon
55
+ v-if="icon"
56
+ v-bind="options.icon"
57
+ >
58
+ {{ icon }}
59
+ </VIcon>
60
+ </slot>
61
+
62
+ <div class="vd-data-list-item-content">
63
+ <div :class="{ 'vd-row': row }">
64
+ <div
65
+ class="vd-data-list-item-label text-caption"
66
+ :style="{ color: labelColor }"
67
+ >
68
+ {{ label }}
69
+ </div>
70
+
71
+ <div class="vd-data-list-item-value">
72
+ <slot
73
+ name="value"
74
+ v-bind="{ itemValue }"
75
+ >
76
+ <VChip
77
+ v-if="chip"
78
+ v-bind="options.chip"
79
+ >
80
+ {{ itemValue }}
81
+ </VChip>
82
+
83
+ <span
84
+ v-else-if="renderHtmlValue"
85
+ class="text-body-1"
86
+ v-html="itemValue"
87
+ />
88
+
89
+ <span
90
+ v-else
91
+ class="text-body-1"
92
+ v-text="itemValue"
93
+ />
94
+ </slot>
95
+ </div>
96
+ </div>
97
+
98
+ <slot name="action">
99
+ <VBtn
100
+ v-if="action"
101
+ v-bind="options.actionBtn"
102
+ class="vd-data-list-item-action-btn"
103
+ @click="emits('click:action')"
104
+ >
105
+ {{ action }}
106
+ </VBtn>
107
+ </slot>
108
+ </div>
109
+ </li>
110
+ </template>
111
+
112
+ <style lang="scss" scoped>
113
+ .vd-row {
114
+ display: flex;
115
+ flex-wrap: wrap;
116
+
117
+ .vd-data-list-item-label {
118
+ align-self: center;
119
+
120
+ &::after {
121
+ content: ':';
122
+ margin: 0 4px;
123
+ }
124
+ }
125
+ }
126
+
127
+ .vd-data-list-item-action-btn.v-btn {
128
+ min-width: 0;
129
+ margin: 0 -1px;
130
+ }
131
+
132
+ .v-icon.v-theme--light {
133
+ color: rgba(0, 0, 0, 0.54);
134
+ }
135
+ </style>
@@ -0,0 +1,17 @@
1
+ import type { VariantType } from '@/types/vuetifyTypes'
2
+
3
+ export const config = {
4
+ icon: {
5
+ size: 24,
6
+ class: 'mr-4 mt-2',
7
+ },
8
+ chip: {
9
+ class: 'mt-1',
10
+ },
11
+ actionBtn: {
12
+ variant: 'text' as VariantType,
13
+ size: 'small',
14
+ color: 'secondary',
15
+ class: 'text-body-1 pa-0',
16
+ },
17
+ }
@@ -0,0 +1,3 @@
1
+ export const locales = {
2
+ placeholder: '…',
3
+ }
@@ -0,0 +1,156 @@
1
+ import { mount } from '@vue/test-utils'
2
+ import { describe, it, expect } from 'vitest'
3
+ import { vuetify } from '@tests/unit/setup'
4
+
5
+ import DataListItem from '../DataListItem.vue'
6
+
7
+ describe('DataListItem', () => {
8
+ it('renders correctly', () => {
9
+ const wrapper = mount(DataListItem, {
10
+ global: {
11
+ plugins: [vuetify],
12
+ },
13
+ props: {
14
+ label: 'Test',
15
+ value: 'Sample Value',
16
+ action: 'Click Me',
17
+ chip: false,
18
+ row: true,
19
+ },
20
+ slots: {
21
+ icon: '<VIcon>mdi-home</VIcon>',
22
+ value: '<span>Custom Value</span>',
23
+ action: '<VBtn>Custom Action</VBtn>',
24
+ },
25
+ })
26
+
27
+ expect(wrapper.vm.value).toBe('Sample Value')
28
+ })
29
+
30
+ it('renders correctly with a number value', () => {
31
+ const wrapper = mount(DataListItem, {
32
+ global: {
33
+ plugins: [vuetify],
34
+ },
35
+ props: {
36
+ label: 'Test',
37
+ value: 123,
38
+ },
39
+ })
40
+
41
+ expect(wrapper.vm.value).toBe(123)
42
+ })
43
+
44
+ it('renders correctly with a NaN value', () => {
45
+ const wrapper = mount(DataListItem, {
46
+ global: {
47
+ plugins: [vuetify],
48
+ },
49
+ props: {
50
+ label: 'Test',
51
+ value: parseInt('test', 10),
52
+ },
53
+ })
54
+
55
+ expect(wrapper.vm.value).toBe(NaN)
56
+ })
57
+
58
+ it('renders correctly a value with HTML as text', () => {
59
+ const wrapper = mount(DataListItem, {
60
+ global: {
61
+ plugins: [vuetify],
62
+ },
63
+ props: {
64
+ label: 'Test',
65
+ value: '<span>Custom Value</span>',
66
+ },
67
+ })
68
+
69
+ const elValue = wrapper.find('.vd-data-list-item-value span')
70
+
71
+ expect(elValue.text()).toBe('<span>Custom Value</span>')
72
+ })
73
+
74
+ it('renders correctly a value as plain HTML', () => {
75
+ const wrapper = mount(DataListItem, {
76
+ global: {
77
+ plugins: [vuetify],
78
+ },
79
+ props: {
80
+ label: 'Test',
81
+ value: 'Paul<br> Dupont',
82
+ renderHtmlValue: true,
83
+ },
84
+ })
85
+
86
+ const elValue = wrapper.find('.vd-data-list-item-value span')
87
+
88
+ expect(elValue.text()).toBe('Paul Dupont')
89
+ })
90
+
91
+ it('renders correctly value in a chip', () => {
92
+ const wrapper = mount(DataListItem, {
93
+ global: {
94
+ plugins: [vuetify],
95
+ },
96
+ props: {
97
+ label: 'Test',
98
+ value: 'Chip Value',
99
+ chip: true,
100
+ },
101
+ })
102
+
103
+ const elChip = wrapper.find('.v-chip__content')
104
+ expect(elChip.text()).toBe('Chip Value')
105
+ })
106
+
107
+ it('renders correctly with an action', () => {
108
+ const wrapper = mount(DataListItem, {
109
+ global: {
110
+ plugins: [vuetify],
111
+ },
112
+ props: {
113
+ label: 'Test',
114
+ action: 'Click Me',
115
+ },
116
+ })
117
+
118
+ const elAction = wrapper.find('.vd-data-list-item-action-btn')
119
+ expect(elAction.text()).toBe('Click Me')
120
+ })
121
+
122
+ it('emits click:action event on button click', async () => {
123
+ const wrapper = mount(DataListItem, {
124
+ global: {
125
+ plugins: [vuetify],
126
+ },
127
+ props: {
128
+ label: 'Test',
129
+ action: 'Click Me',
130
+ },
131
+ })
132
+
133
+ const button = wrapper.find('.vd-data-list-item-action-btn')
134
+ await button.trigger('click')
135
+
136
+ expect(wrapper.emitted('click:action')).toBeTruthy()
137
+ })
138
+
139
+ it('renders correctly in row mode', () => {
140
+ const wrapper = mount(DataListItem, {
141
+ global: {
142
+ plugins: [vuetify],
143
+ },
144
+ props: {
145
+ label: 'Test',
146
+ value: 'Sample Value',
147
+ action: 'Click Me',
148
+ chip: false,
149
+ row: true,
150
+ },
151
+ })
152
+
153
+ const elRow = wrapper.find('.vd-row')
154
+ expect(elRow.exists()).toBe(true)
155
+ })
156
+ })
@@ -0,0 +1,23 @@
1
+ import { useCustomizableOptions } from '@/composables/useCustomizableOptions'
2
+
3
+ export interface IndexedObject<Type = string> {
4
+ [key: string]: Type
5
+ }
6
+
7
+ export interface DataListItem {
8
+ key: string
9
+ value?: string | number
10
+ action?: string
11
+ chip?: boolean
12
+ icon?: string
13
+ options?: useCustomizableOptions
14
+ class?: string
15
+ }
16
+
17
+ export type DataList = DataListItem[]
18
+
19
+ export interface DataListIcons {
20
+ [iconName: string]: string
21
+ }
22
+
23
+ export type ItemClass = (string | undefined | IndexedObject<boolean>)[]
@@ -0,0 +1,14 @@
1
+ import { Meta, Story } from '@storybook/addon-docs';
2
+ import * as AccessStories from './Accessibilite.stories.ts';
3
+
4
+ <Meta of={AccessStories} />
5
+
6
+ Accessibilité
7
+ =============
8
+ <Story of={AccessStories.Legende} />
9
+ <br />
10
+
11
+ --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
12
+
13
+ <Story of={AccessStories.AccessibilitePanel} />
14
+ <br />
@@ -0,0 +1,166 @@
1
+ import { VExpansionPanels, VExpansionPanel, VExpansionPanelTitle, VExpansionPanelText, VDataTable, VIcon } from 'vuetify/components'
2
+ import type { StoryObj } from '@storybook/vue3'
3
+ import { AccessibiliteItemsIndeterminate, AccessibiliteItemsValidated } from './AccessibiliteItems'
4
+ import { mdiCheckboxMarkedCircle, mdiLink, mdiEye } from '@mdi/js'
5
+
6
+ const checkIcon = mdiCheckboxMarkedCircle
7
+ const iconEye = mdiEye
8
+ const linkICon = mdiLink
9
+
10
+ export default {
11
+ title: 'Composants/Boutons/DownloadBtn/Accessibilité',
12
+ }
13
+
14
+ export const AccessibilitePanel: StoryObj = {
15
+
16
+ render: () => {
17
+ return {
18
+ components: { VExpansionPanels, VExpansionPanel, VExpansionPanelTitle, VExpansionPanelText, VDataTable, VIcon },
19
+
20
+ setup() {
21
+ const icon = checkIcon
22
+
23
+ return { AccessibiliteItemsIndeterminate, AccessibiliteItemsValidated, icon, linkICon, iconEye }
24
+ },
25
+ template: `
26
+ <div class="accessibiliteItems" style="display:flex; max-width: none !important;">
27
+ <v-col cols="6">
28
+ <div style="display:flex; margin-bottom: 10px; justify-content: space-between; align-items: center;">
29
+ <h5>{{ AccessibiliteItemsIndeterminate.length }} critères à prendre en charge par le projet</h5>
30
+ <div style="display: flex; align-items: center;">
31
+ <v-btn variant="tonal" color="red" size="x-small" style="margin: 4px;font-size: 8px;"
32
+ rounded>Tanaguru
33
+ </v-btn>
34
+ </div>
35
+ </div>
36
+
37
+ <v-expansion-panels value="opened" multiple>
38
+ <v-expansion-panel v-for="(item, index) in AccessibiliteItemsIndeterminate" :key="index" style="background-color: rgba(42, 96, 158, 0.1); margin-bottom: 10px;">
39
+ <v-expansion-panel-title>
40
+ <VIcon :icon="iconEye" style="margin-right: 5px; color:#5778b7;"/>
41
+ {{ item.title }}
42
+ </v-expansion-panel-title>
43
+ <v-expansion-panel-text>
44
+ <v-expansion-panels>
45
+ <v-expansion-panel>
46
+ <v-expansion-panel-title
47
+ style="font-weight: bold; font-size: 13px; line-height: 16px;">
48
+ {{ item.subtitle }}
49
+ </v-expansion-panel-title>
50
+ <v-expansion-panel-text>
51
+ <div v-for="(value, i) in item.items" :key="i">
52
+ <p style="font-size: 13px;line-height: 16px;">
53
+ {{ value.precision }}
54
+ </p>
55
+ <div v-for="element in value.solution"
56
+ style="margin-top:15px; font-size: 13px;line-height: 16px;">
57
+ <p style="font-weight: bold;">Méthodologie du test : <a
58
+ href="value.link" target="blank">
59
+ <VIcon :icon="linkICon"/>
60
+ </a></p>
61
+
62
+ <p>{{ element.info1 }}</p>
63
+ <p>{{ element.info2 }}</p>
64
+ <p>{{ element.info3 }}</p>
65
+
66
+ </div>
67
+ <span style="display:flex; justify-content:center; margin-bottom:5px;">______</span>
68
+ </div>
69
+ </v-expansion-panel-text>
70
+ </v-expansion-panel>
71
+ </v-expansion-panels>
72
+ </v-expansion-panel-text>
73
+ </v-expansion-panel>
74
+ </v-expansion-panels>
75
+ </v-col>
76
+ <v-col cols="6">
77
+ <div style="display:flex; margin-bottom: 10px; justify-content: space-between; align-items: center;">
78
+ <h5>{{ AccessibiliteItemsValidated.length }} critères pris en charge par l'équipe Design System</h5>
79
+ <div style="display: flex; align-items: center;">
80
+ <v-btn variant="tonal" color="red" size="x-small" style="margin: 4px;font-size: 8px;"
81
+ rounded>Tanaguru
82
+ </v-btn>
83
+ </div>
84
+ </div>
85
+ <v-expansion-panels value="opened" multiple>
86
+ <v-expansion-panel
87
+ v-for="(item, index) in AccessibiliteItemsValidated"
88
+ :key="index" style="background-color: rgba(53,135,0,0.1); margin-bottom: 10px;">
89
+ <v-expansion-panel-title>
90
+ <VIcon color="green" :icon="icon" style="margin-right: 5px;"/>
91
+ {{ item.title }}
92
+ </v-expansion-panel-title>
93
+ <v-expansion-panel-text>
94
+ <v-expansion-panels>
95
+ <v-expansion-panel>
96
+ <v-expansion-panel-title style="font-weight: bold;font-size: 13px; line-height: 16px;">
97
+ {{ item.subtitle }}
98
+ </v-expansion-panel-title>
99
+ <v-expansion-panel-text>
100
+ <div v-for="(value, i) in item.items" :key="i">
101
+ <p style="font-size: 13px;line-height: 16px;">
102
+ {{ value.precision }}
103
+ </p>
104
+ <div v-for="element in value.solution"
105
+ style="margin-top:15px; font-size: 13px;line-height: 16px;">
106
+ <p style="font-weight: bold;">Méthodologie du test : <a
107
+ href="value.link" target="blank">
108
+ <VIcon :icon="linkICon"/>
109
+ </a></p>
110
+ <p>{{ element.info1 }}</p>
111
+ <p>{{ element.info2 }}</p>
112
+ <p>{{ element.info3 }}</p>
113
+ </div>
114
+ <span style="display:flex; justify-content:center; margin-bottom:5px;">______</span>
115
+ </div>
116
+ </v-expansion-panel-text>
117
+ </v-expansion-panel>
118
+ </v-expansion-panels>
119
+ </v-expansion-panel-text>
120
+ </v-expansion-panel>
121
+ </v-expansion-panels>
122
+ </v-col>
123
+ </div>
124
+ `,
125
+ }
126
+ },
127
+ tags: ['!dev'],
128
+ }
129
+
130
+ export const Legende: StoryObj = {
131
+ args: {
132
+ icon: checkIcon,
133
+ },
134
+ render: (args) => {
135
+ return {
136
+ components: { VIcon },
137
+ setup() {
138
+ return { args }
139
+ },
140
+ template: `
141
+ <p style="color: grey;font-size: 11px; margin-bottom: 12px;">Date de conception: 20/11/2024</p>
142
+ <div>
143
+ <p>Le tableau ci-dessous liste nos recommandations suivant les <a target="blank" style="color:#0C41BD;" href="https://www.numerique.gouv.fr/publications/rgaa-accessibilite/#contenu">catégories du RGAA</a>.</p>
144
+ <p style="margin-bottom: 12px;font-weight:bold;">Pour rappel le composant seul ne garantie pas
145
+ l'accessibilité du site.</p>
146
+ <div style="font-size: 14px">
147
+ <p>Nous avons deux façons de relever les problèmes d'accessibilité des composants :</p>
148
+ <div>
149
+ <v-btn variant="tonal" color="grey" size="x-small" style="margin: 2px;font-size: 8px;" rounded>
150
+ Audit
151
+ </v-btn>
152
+ Problèmes relevés par le projet
153
+ </div>
154
+ <div>
155
+ <v-btn variant="tonal" color="red" size="x-small" style="margin: 2px;font-size: 8px;" rounded>
156
+ Tanaguru
157
+ </v-btn>
158
+ Problèmes relevés par Tanaguru
159
+ </div>
160
+ </div>
161
+ </div>
162
+ `,
163
+ }
164
+ },
165
+ tags: ['!dev'],
166
+ }