@cnamts/synapse 0.0.2-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 (193) hide show
  1. package/README.md +1 -1
  2. package/dist/design-system-v3.d.ts +712 -27
  3. package/dist/design-system-v3.js +2745 -5384
  4. package/dist/design-system-v3.umd.cjs +10 -2
  5. package/dist/style.css +1 -1
  6. package/package.json +32 -29
  7. package/src/components/Alert/Alert.mdx +1 -1
  8. package/src/components/Alert/Alert.stories.ts +91 -1
  9. package/src/components/Alert/Alert.vue +8 -8
  10. package/src/components/BackBtn/BackBtn.mdx +1 -1
  11. package/src/components/BackBtn/BackBtn.stories.ts +84 -1
  12. package/src/components/BackToTopBtn/BackToTopBtn.mdx +3 -3
  13. package/src/components/BackToTopBtn/BackToTopBtn.stories.ts +172 -11
  14. package/src/components/CollapsibleList/CollapsibleList.mdx +2 -2
  15. package/src/components/CollapsibleList/CollapsibleList.stories.ts +37 -1
  16. package/src/components/CopyBtn/CopyBtn.mdx +1 -1
  17. package/src/components/CopyBtn/CopyBtn.stories.ts +120 -1
  18. package/src/components/CopyBtn/CopyBtn.vue +1 -1
  19. package/src/components/Customs/CustomInputSelect/CustomInputSelect.mdx +6 -8
  20. package/src/components/Customs/CustomInputSelect/CustomInputSelect.stories.ts +270 -4
  21. package/src/components/Customs/CustomInputSelect/CustomInputSelect.vue +80 -53
  22. package/src/components/Customs/CustomInputSelect/config.ts +10 -0
  23. package/src/components/Customs/CustomSelect/CustomSelect.mdx +3 -3
  24. package/src/components/Customs/CustomSelect/CustomSelect.stories.ts +158 -2
  25. package/src/components/Customs/CustomSelect/CustomSelect.vue +25 -6
  26. package/src/components/Customs/CustomTextField/CustomTextField.mdx +44 -0
  27. package/src/components/Customs/CustomTextField/CustomTextField.stories.ts +403 -0
  28. package/src/components/Customs/CustomTextField/CustomTextField.vue +110 -0
  29. package/src/components/Customs/CustomTextField/tests/CustomTextField.spec.ts +93 -0
  30. package/src/components/Customs/CustomTextField/tests/__snapshots__/CustomTextField.spec.ts.snap +59 -0
  31. package/src/components/Customs/CustomTextField/types.d.ts +3 -0
  32. package/src/components/DataList/DataList.mdx +77 -0
  33. package/src/components/DataList/DataList.stories.ts +960 -0
  34. package/src/components/DataList/DataList.vue +140 -0
  35. package/src/components/DataList/DataListLoading/DataListLoading.vue +56 -0
  36. package/src/components/DataList/DataListLoading/tests/DataListLoading.spec.ts +23 -0
  37. package/src/components/DataList/locales.ts +3 -0
  38. package/src/components/DataList/tests/DataList.spec.ts +194 -0
  39. package/src/components/DataList/types.d.ts +23 -0
  40. package/src/components/DataListGroup/DataListGroup.mdx +77 -0
  41. package/src/components/DataListGroup/DataListGroup.stories.ts +987 -0
  42. package/src/components/DataListGroup/DataListGroup.vue +59 -0
  43. package/src/components/DataListGroup/tests/DataListGroup.spec.ts +54 -0
  44. package/src/components/DataListGroup/tests/data/dataListGroupItems.ts +41 -0
  45. package/src/components/DataListGroup/types.d.ts +15 -0
  46. package/src/components/DataListItem/DataListItem.vue +135 -0
  47. package/src/components/DataListItem/config.ts +17 -0
  48. package/src/components/DataListItem/locales.ts +3 -0
  49. package/src/components/DataListItem/tests/DataListItem.spec.ts +156 -0
  50. package/src/components/DataListItem/types.d.ts +23 -0
  51. package/src/components/DownloadBtn/Accessibilite.mdx +14 -0
  52. package/src/components/DownloadBtn/Accessibilite.stories.ts +166 -0
  53. package/src/components/DownloadBtn/AccessibiliteItems.ts +129 -0
  54. package/src/components/DownloadBtn/DownloadBtn.mdx +5 -6
  55. package/src/components/DownloadBtn/DownloadBtn.stories.ts +207 -2
  56. package/src/components/DownloadBtn/constants/ExpertiseLevelEnum.ts +4 -0
  57. package/src/components/FooterBar/FooterBar.mdx +2 -2
  58. package/src/components/FooterBar/FooterBar.stories.ts +1 -1
  59. package/src/components/FranceConnectBtn/FranceConnectBtn.mdx +1 -1
  60. package/src/components/FranceConnectBtn/FranceConnectBtn.stories.ts +58 -1
  61. package/src/components/FranceConnectBtn/FranceConnectBtn.vue +2 -2
  62. package/src/components/HeaderBar/HeaderBar.mdx +256 -0
  63. package/src/components/HeaderBar/HeaderBar.stories.ts +703 -0
  64. package/src/components/HeaderBar/HeaderBar.vue +276 -0
  65. package/src/components/HeaderBar/HeaderBurgerMenu/HeaderBurgerMenu.mdx +433 -0
  66. package/src/components/HeaderBar/HeaderBurgerMenu/HeaderBurgerMenu.stories.ts +1089 -0
  67. package/src/components/HeaderBar/HeaderBurgerMenu/HeaderBurgerMenu.vue +234 -0
  68. package/src/components/HeaderBar/HeaderBurgerMenu/HeaderMenuItem/HeaderMenuItem.mdx +38 -0
  69. package/src/components/HeaderBar/HeaderBurgerMenu/HeaderMenuItem/HeaderMenuItem.stories.ts +89 -0
  70. package/src/components/HeaderBar/HeaderBurgerMenu/HeaderMenuItem/HeaderMenuItem.vue +51 -0
  71. package/src/components/HeaderBar/HeaderBurgerMenu/HeaderMenuItem/tests/HeaderMenuItem.spec.ts +16 -0
  72. package/src/components/HeaderBar/HeaderBurgerMenu/HeaderMenuItem/tests/__snapshots__/HeaderMenuItem.spec.ts.snap +3 -0
  73. package/src/components/HeaderBar/HeaderBurgerMenu/HeaderMenuSection/HeaderMenuSection.mdx +17 -0
  74. package/src/components/HeaderBar/HeaderBurgerMenu/HeaderMenuSection/HeaderMenuSection.stories.ts +121 -0
  75. package/src/components/HeaderBar/HeaderBurgerMenu/HeaderMenuSection/HeaderMenuSection.vue +51 -0
  76. package/src/components/HeaderBar/HeaderBurgerMenu/HeaderMenuSection/tests/HeaderMenuSection.spec.ts +31 -0
  77. package/src/components/HeaderBar/HeaderBurgerMenu/HeaderSubMenu/HeaderSubMenu.mdx +43 -0
  78. package/src/components/HeaderBar/HeaderBurgerMenu/HeaderSubMenu/HeaderSubMenu.stories.ts +261 -0
  79. package/src/components/HeaderBar/HeaderBurgerMenu/HeaderSubMenu/HeaderSubMenu.vue +194 -0
  80. package/src/components/HeaderBar/HeaderBurgerMenu/HeaderSubMenu/tests/HeaderSubMenu.spec.ts +63 -0
  81. package/src/components/HeaderBar/HeaderBurgerMenu/conts.ts +1 -0
  82. package/src/components/HeaderBar/HeaderBurgerMenu/locals.ts +4 -0
  83. package/src/components/HeaderBar/HeaderBurgerMenu/tests/HeaderBurgerMenu.spec.ts +180 -0
  84. package/src/components/HeaderBar/HeaderBurgerMenu/tests/__snapshots__/HeaderBurgerMenu.spec.ts.snap +13 -0
  85. package/src/components/HeaderBar/HeaderBurgerMenu/tests/__snapshots__/HeaderComplexMenu.spec.ts.snap +13 -0
  86. package/src/components/HeaderBar/HeaderBurgerMenu/tests/useHandleSubMenus.spec.ts +158 -0
  87. package/src/components/HeaderBar/HeaderBurgerMenu/useHandleSubMenus.ts +49 -0
  88. package/src/components/HeaderBar/HeaderLogo/HeaderLogo.vue +143 -0
  89. package/src/components/HeaderBar/HeaderLogo/locales.ts +3 -0
  90. package/src/components/HeaderBar/HeaderLogo/logos/Logo-mobile.vue +117 -0
  91. package/src/components/HeaderBar/HeaderLogo/logos/Logo.vue +279 -0
  92. package/src/components/HeaderBar/HeaderLogo/tests/HeaderLogo.spec.ts +119 -0
  93. package/src/components/HeaderBar/HeaderMenuBtn/HeaderMenuBtn.vue +84 -0
  94. package/src/components/HeaderBar/HeaderMenuBtn/locals.ts +4 -0
  95. package/src/components/HeaderBar/HeaderMenuBtn/tests/HeaderMenuBtn.spec.ts +70 -0
  96. package/src/components/HeaderBar/Usages.mdx +85 -0
  97. package/src/components/HeaderBar/consts.scss +6 -0
  98. package/src/components/HeaderBar/consts.ts +2 -0
  99. package/src/components/HeaderBar/locales.ts +3 -0
  100. package/src/components/HeaderBar/tests/HeaderBar.spec.ts +216 -0
  101. package/src/components/HeaderBar/tests/__snapshots__/HeaderBar.spec.ts.snap +45 -0
  102. package/src/components/HeaderBar/tests/useHeaderResponsiveMode.spec.ts +26 -0
  103. package/src/components/HeaderBar/tests/useScrollDirection.spec.ts +34 -0
  104. package/src/components/HeaderBar/useHeaderResponsiveMode.ts +25 -0
  105. package/src/components/HeaderBar/useScrollDirection.ts +26 -0
  106. package/src/components/HeaderLoading/HeaderLoading.mdx +28 -0
  107. package/src/components/HeaderLoading/HeaderLoading.stories.ts +62 -0
  108. package/src/components/HeaderLoading/HeaderLoading.vue +45 -0
  109. package/src/components/HeaderLoading/tests/HeaderLoading.spec.ts +22 -0
  110. package/src/components/HeaderNavigationBar/HeaderNavigationBar.mdx +128 -0
  111. package/src/components/HeaderNavigationBar/HeaderNavigationBar.stories.ts +784 -0
  112. package/src/components/HeaderNavigationBar/HeaderNavigationBar.vue +194 -0
  113. package/src/components/HeaderNavigationBar/HorizontalNavbar/HorizontalNavbar.vue +74 -0
  114. package/src/components/HeaderNavigationBar/HorizontalNavbar/config.ts +18 -0
  115. package/src/components/HeaderNavigationBar/tests/HeaderNavigationBar.spec.ts +127 -0
  116. package/src/components/HeaderNavigationBar/types.ts +7 -0
  117. package/src/components/HeaderToolbar/HeaderToolbar.mdx +31 -0
  118. package/src/components/HeaderToolbar/HeaderToolbar.stories.ts +343 -0
  119. package/src/components/HeaderToolbar/HeaderToolbar.vue +487 -0
  120. package/src/components/HeaderToolbar/tests/HeaderToolbar.spec.ts +196 -0
  121. package/src/components/HeaderToolbar/types.d.ts +20 -0
  122. package/src/components/LangBtn/LangBtn.mdx +1 -1
  123. package/src/components/LangBtn/LangBtn.stories.ts +125 -8
  124. package/src/components/Logo/Logo.mdx +2 -2
  125. package/src/components/Logo/Logo.stories.ts +147 -1
  126. package/src/components/LogoBrandSection/LogoBrandSection.mdx +14 -0
  127. package/src/components/LogoBrandSection/LogoBrandSection.stories.ts +158 -0
  128. package/src/components/LogoBrandSection/LogoBrandSection.vue +312 -0
  129. package/src/components/LogoBrandSection/assets/ameli-pro.svg +1 -0
  130. package/src/components/LogoBrandSection/assets/ameli.svg +1 -0
  131. package/src/components/LogoBrandSection/assets/cnam.svg +1 -0
  132. package/src/components/LogoBrandSection/assets/compte-ameli.svg +1 -0
  133. package/src/components/LogoBrandSection/dividerDimensionsMapping.ts +14 -0
  134. package/src/components/LogoBrandSection/locales.ts +14 -0
  135. package/src/components/LogoBrandSection/secondaryLogoMapping.ts +24 -0
  136. package/src/components/LogoBrandSection/tests/LogoBrandSection.spec.ts +365 -0
  137. package/src/components/LogoBrandSection/tests/__snapshots__/LogoBrandSection.spec.ts.snap +14 -0
  138. package/src/components/LogoBrandSection/types.ts +8 -0
  139. package/src/components/NotificationBar/NotificationBar.mdx +6 -6
  140. package/src/components/NotificationBar/NotificationBar.stories.ts +1 -1
  141. package/src/components/NotificationBar/NotificationBar.vue +7 -9
  142. package/src/components/NotificationBar/tests/NotificationBar.spec.ts +1 -1
  143. package/src/components/PageContainer/PageContainer.mdx +1 -1
  144. package/src/components/PageContainer/PageContainer.stories.ts +86 -1
  145. package/src/components/PageContainer/PageContainer.vue +0 -1
  146. package/src/components/PhoneField/PhoneField.mdx +49 -0
  147. package/src/components/PhoneField/PhoneField.stories.ts +869 -0
  148. package/src/components/PhoneField/PhoneField.vue +230 -0
  149. package/src/components/PhoneField/indicatifs.ts +104 -0
  150. package/src/components/PhoneField/locales.ts +4 -0
  151. package/src/components/PhoneField/tests/PhoneField.spec.ts +179 -0
  152. package/src/components/SkipLink/SkipLink.stories.ts +50 -1
  153. package/src/components/SocialMediaLinks/SocialMediaLinks.mdx +28 -1
  154. package/src/components/SocialMediaLinks/SocialMediaLinks.stories.ts +37 -1
  155. package/src/components/SubHeader/SubHeader.mdx +31 -0
  156. package/src/components/SubHeader/SubHeader.stories.ts +1032 -0
  157. package/src/components/SubHeader/SubHeader.vue +185 -0
  158. package/src/components/SubHeader/config.ts +12 -0
  159. package/src/components/SubHeader/locales.ts +3 -0
  160. package/src/components/SubHeader/tests/SubHeader.spec.ts +144 -0
  161. package/src/components/index.ts +24 -7
  162. package/src/composables/widthable/index.ts +29 -0
  163. package/src/composables/widthable/tests/widthable.spec.ts +52 -0
  164. package/src/designTokens/tokens/cnam/cnamLightTheme.ts +2 -2
  165. package/src/main.ts +1 -0
  166. package/src/modules.d.ts +4 -0
  167. package/src/services/index.ts +1 -0
  168. package/src/stories/Demarrer/Accueil.mdx +10 -0
  169. package/src/stories/Demarrer/Accueil.stories.ts +76 -0
  170. package/src/stories/Demarrer/PolitiqueDeConfidentialite.mdx +9 -0
  171. package/src/stories/Demarrer/PolitiqueDeConfidentialite.stories.ts +20 -0
  172. package/src/stories/Fondamentaux/Accessibilite/Accessibilite.mdx +1 -2
  173. package/src/stories/Fondamentaux/Accessibilite/Accessibilite.stories.ts +1 -1
  174. package/src/stories/Fondamentaux/EcoConception/Econception.stories.ts +1 -1
  175. package/src/stories/GuideDuDev/moduleDeNotification.mdx +52 -48
  176. package/src/stories/GuideDuDev/vuetifyOptions.mdx +31 -28
  177. package/src/stories/Guidelines/CustomisationEtThemes.mdx +1 -1
  178. package/src/utils/functions/throttleDisplayFn/tests/throttleDisplayFn.spec.ts +47 -0
  179. package/src/utils/functions/throttleDisplayFn/throttleDisplayFn.ts +26 -0
  180. package/src/utils/rules/exactLength/index.ts +33 -0
  181. package/src/utils/rules/exactLength/locales.ts +6 -0
  182. package/src/utils/rules/required/index.ts +25 -0
  183. package/src/utils/rules/required/locales.ts +5 -0
  184. package/src/utils/rules/required/ruleMessageHelper.ts +14 -0
  185. package/src/utils/rules/required/tests/index.spec.ts +47 -0
  186. package/src/utils/rules/required/tests/rulesMessageHelper.spec.ts +22 -0
  187. package/src/utils/rules/types.d.ts +15 -0
  188. package/src/components/Beta/beta.mdx +0 -5
  189. package/src/components/Deprecated/deprecated.mdx +0 -5
  190. package/src/stories/Home/Accueil.mdx +0 -7
  191. package/src/stories/Home/PolitiqueDeConfidentialite.mdx +0 -4
  192. package/src/stories/Home/synapse.webp +0 -0
  193. /package/src/components/Logo/{types.d.ts → types.ts} +0 -0
@@ -0,0 +1,276 @@
1
+ <script setup lang="ts">
2
+ import throttleDisplayFn from '@/utils/functions/throttleDisplayFn/throttleDisplayFn'
3
+ import { computed, onMounted, onUnmounted, provide, ref, watch, type CSSProperties, type DeepReadonly, type Ref } from 'vue'
4
+ import type { RouteLocationRaw } from 'vue-router'
5
+ import HeaderLogo from './HeaderLogo/HeaderLogo.vue'
6
+ import { registerHeaderMenuKey } from './consts'
7
+ import { locales } from './locales'
8
+ import useHeaderResponsiveMode from './useHeaderResponsiveMode'
9
+ import useScrollDirection from './useScrollDirection'
10
+
11
+ const menuOpen = ref<boolean>()
12
+
13
+ type SlotProps = {
14
+ menuOpen: boolean | undefined
15
+ }
16
+
17
+ type LogoProps = {
18
+ homeAriaLabel?: string
19
+ serviceTitle?: string
20
+ serviceSubtitle?: string
21
+ homeLink?: {
22
+ ariaLabel?: string
23
+ to?: RouteLocationRaw
24
+ href?: string
25
+ }
26
+ }
27
+
28
+ defineSlots<{
29
+ 'prepend': (props: SlotProps) => unknown
30
+ 'append': (props: SlotProps) => unknown
31
+ 'menu': (props: SlotProps) => unknown
32
+ 'logo': (props: SlotProps & LogoProps) => unknown
33
+ 'logo-brand-content': (props: SlotProps & LogoProps) => unknown
34
+ 'header-side': (props: SlotProps) => unknown
35
+ }>()
36
+
37
+ const props = withDefaults(defineProps<{
38
+ /** Keep the header visible */
39
+ sticky?: boolean
40
+ /**
41
+ * Show the header at sticky only when the user scroll up in mobile
42
+ * Need 'sticky' at true,
43
+ */
44
+ hideWhenDown?: boolean
45
+ homeLink?: {
46
+ ariaLabel?: string
47
+ to?: RouteLocationRaw
48
+ href?: string
49
+ }
50
+ } & LogoProps>(),
51
+ {
52
+ sticky: true,
53
+ hideWhenDown: false,
54
+ homeAriaLabel: locales.homeAriaLabel,
55
+ serviceTitle: undefined,
56
+ serviceSubtitle: undefined,
57
+ homeLink: undefined,
58
+ })
59
+
60
+ function registerHeaderMenu(childMenuStatus: DeepReadonly<Ref<boolean>>) {
61
+ watch(childMenuStatus, (newVal) => {
62
+ menuOpen.value = newVal
63
+ })
64
+ }
65
+ provide(registerHeaderMenuKey, registerHeaderMenu)
66
+
67
+ const header = ref<HTMLElement | null>(null)
68
+ const headerSticky = ref<HTMLElement | null>(null)
69
+
70
+ /** The height of the header to reserve */
71
+ const headerMinHeight = ref('auto')
72
+ /** The position of the header (when static) from the top of the page */
73
+ const headerOffset = ref(0)
74
+ /** The width of the header to have the same width when fixed and in a container */
75
+ const headerWidth = ref<string | number>('auto')
76
+ /** Is the top of the header visible in the viewport when static */
77
+ const isTopOfHeaderVisible = ref(true)
78
+ /** Is the header out of the viewport */
79
+ const isScrollBelowHeader = ref(false)
80
+ /** Activate the hide animation */
81
+ const shouldAnimateHideHeader = ref(false)
82
+
83
+ function handleScroll() {
84
+ const headerRec = header.value!.getBoundingClientRect()
85
+ headerOffset.value = headerRec.top + window.scrollY
86
+ headerMinHeight.value = `${headerSticky.value!.offsetHeight}px`
87
+ headerWidth.value = `${header.value!.offsetWidth}px`
88
+ isTopOfHeaderVisible.value = window.scrollY <= headerOffset.value
89
+ isScrollBelowHeader.value = window.scrollY > headerOffset.value + headerRec.height
90
+
91
+ // activate the header animation with a delay to avoid a flicker effect when the user scroll down
92
+ shouldAnimateHideHeader.value = window.scrollY > headerOffset.value + (headerRec.height * 2)
93
+ }
94
+
95
+ const throttledHandleScroll = throttleDisplayFn(handleScroll, 16)
96
+
97
+ onMounted(() => {
98
+ handleScroll()
99
+ window.addEventListener('scroll', throttledHandleScroll)
100
+ window.addEventListener('resize', throttledHandleScroll)
101
+ })
102
+
103
+ onUnmounted(() => {
104
+ window.removeEventListener('scroll', throttledHandleScroll)
105
+ window.removeEventListener('resize', throttledHandleScroll)
106
+ })
107
+
108
+ const headerStyle = computed<CSSProperties>(() => {
109
+ return {
110
+ minHeight: headerMinHeight.value,
111
+ }
112
+ })
113
+
114
+ const { scrollDirection } = useScrollDirection()
115
+ const { isDesktop } = useHeaderResponsiveMode()
116
+
117
+ const headerStickyStyle = computed<CSSProperties>(() => {
118
+ if (
119
+ props.hideWhenDown
120
+ && !isDesktop.value
121
+ && !menuOpen.value
122
+ ) {
123
+ const staticHeader = (
124
+ (scrollDirection.value === '' && isTopOfHeaderVisible.value)
125
+ || (scrollDirection.value === 'bottom' && !isScrollBelowHeader.value)
126
+ || (scrollDirection.value === 'top' && isTopOfHeaderVisible.value)
127
+ )
128
+
129
+ const hide = (
130
+ scrollDirection.value === 'bottom'
131
+ && isScrollBelowHeader.value
132
+ )
133
+
134
+ return {
135
+ position: staticHeader ? 'relative' : 'fixed',
136
+ width: staticHeader ? '100%' : headerWidth.value,
137
+ top: staticHeader ? 'auto' : '0',
138
+ transform: hide ? 'translateY(-100%)' : 'none',
139
+ transition: shouldAnimateHideHeader.value ? 'transform 0.3s ease' : 'none',
140
+ }
141
+ }
142
+
143
+ const fixedHeader = !isTopOfHeaderVisible.value && props.sticky
144
+ return {
145
+ position: fixedHeader ? 'fixed' : 'relative',
146
+ width: fixedHeader ? headerWidth.value : '100%',
147
+ top: fixedHeader ? '0' : 'auto',
148
+ transform: 'none',
149
+ transition: 'none',
150
+ }
151
+ })
152
+
153
+ </script>
154
+
155
+ <template>
156
+ <header
157
+ ref="header"
158
+ class="header"
159
+ :style="headerStyle"
160
+ >
161
+ <div
162
+ ref="headerSticky"
163
+ class="sticky-header"
164
+ :style="headerStickyStyle"
165
+ >
166
+ <div
167
+ v-if="$slots.prepend"
168
+ class="header-prepend"
169
+ >
170
+ <slot
171
+ name="prepend"
172
+ :menu-open
173
+ />
174
+ </div>
175
+ <div class="inner-header">
176
+ <slot
177
+ name="menu"
178
+ :menu-open
179
+ />
180
+
181
+ <div class="header-logo">
182
+ <slot
183
+ name="logo"
184
+ :menu-open
185
+ :home-aria-label
186
+ :service-title
187
+ :service-subtitle
188
+ >
189
+ <HeaderLogo
190
+ :aria-label="homeAriaLabel"
191
+ :service-title="serviceTitle"
192
+ :service-subtitle="serviceSubtitle"
193
+ :home-link
194
+ >
195
+ <template
196
+ #brand-content
197
+ >
198
+ <slot
199
+ name="logo-brand-content"
200
+ :menu-open
201
+ :home-aria-label
202
+ :service-title
203
+ :service-subtitle
204
+ :home-link
205
+ />
206
+ </template>
207
+ </HeaderLogo>
208
+ </slot>
209
+ </div>
210
+ <div
211
+ v-if="$slots['header-side']"
212
+ class="header-side"
213
+ >
214
+ <slot
215
+ name="header-side"
216
+ :menu-open
217
+ />
218
+ </div>
219
+ </div>
220
+ <div
221
+ v-if="$slots.append"
222
+ class="header-append"
223
+ >
224
+ <slot
225
+ name="append"
226
+ :menu-open
227
+ />
228
+ </div>
229
+ </div>
230
+ </header>
231
+ </template>
232
+
233
+ <style lang="scss" scoped>
234
+ @use '@/assets/tokens.scss' as *;
235
+ @use './consts' as *;
236
+
237
+ .header {
238
+ position: relative;
239
+ z-index: 1;
240
+ }
241
+
242
+ .sticky-header {
243
+ background-color: $neutral-white;
244
+ width: 100%;
245
+ z-index: 1000;
246
+ }
247
+
248
+ .inner-header {
249
+ display: flex;
250
+ align-items: center;
251
+ height: $header-height;
252
+ max-width: $header-max-width;
253
+ margin: 0 auto;
254
+ border-bottom: solid 1px $blue-lighten-80;
255
+ }
256
+
257
+ .header-logo {
258
+ margin-left: 1rem;
259
+ }
260
+
261
+ .header-side {
262
+ display: flex;
263
+ align-items: center;
264
+ margin-left: auto;
265
+ }
266
+
267
+ @media screen and (min-width: $header-breakpoint) {
268
+ .header-logo {
269
+ margin-left: 2rem;
270
+ }
271
+
272
+ .inner-header {
273
+ height: $header-height-desktop;
274
+ }
275
+ }
276
+ </style>
@@ -0,0 +1,433 @@
1
+ import { Controls, Canvas, Meta, Source } from "@storybook/blocks";
2
+ import * as HeaderBurgerMenuStories from "./HeaderBurgerMenu.stories";
3
+
4
+ <Meta of={HeaderBurgerMenuStories} />
5
+
6
+
7
+ # HeaderBurgerMenu
8
+
9
+ L'utilisation de ce menu est à privilégier pour les application à destination du publique ou pour créer des menus contenant plus de six éléments.
10
+
11
+ ## Utilisation
12
+
13
+ Ce menu est prévu pour être utilisé dans le composant `HeaderBar` via le slot `menu` de ce composant.
14
+
15
+ <Source
16
+ dark
17
+ code={`
18
+ <template>
19
+ <HeaderBar>
20
+ <template #menu>
21
+ <HeaderBurgerMenu>
22
+ menu content
23
+ </HeaderBurgerMenu>
24
+ </template>
25
+ </HeaderBar>
26
+ </template>
27
+ `}
28
+ />
29
+
30
+ Ce menu s'utilise conjointement avec les composants `HeaderMenuSection` et `HeaderMenuItem` pour structurer le menu.
31
+
32
+ Un composant `HeaderMenuSection` peut contenir plusieurs `HeaderMenuItem`.
33
+
34
+ Un Composant `HeaderMenuItem` doit obligatoirement être contenu dans un `HeaderMenuSection`.
35
+
36
+
37
+ <Canvas of={HeaderBurgerMenuStories.Default} />
38
+
39
+ ## API
40
+
41
+ <Controls of={HeaderBurgerMenuStories.Default} />
42
+
43
+ ## Menu à un seul niveau
44
+
45
+ Le menu peut être utilisé avec un seul niveau de profondeur.
46
+
47
+ <Canvas
48
+ of={HeaderBurgerMenuStories.WithAnItem}
49
+ source={{
50
+ language: 'html',
51
+ format: 'dedent',
52
+ code:`
53
+ <HeaderBar>
54
+ <template #menu>
55
+ <HeaderBurgerMenu>
56
+ <HeaderMenuSection>
57
+ <HeaderMenuItem>
58
+ <a href="/">Item 1</a>
59
+ </HeaderMenuItem>
60
+ </HeaderMenuSection>
61
+ </HeaderBurgerMenu>
62
+ </template>
63
+ </HeaderBar>
64
+ `}}
65
+ />
66
+
67
+ Il est possible d'utiliser des liens de navigation avec les composants `RouterLink` ou `NuxtLink`.
68
+
69
+ <Source
70
+ dark
71
+ code={`
72
+ <script setup lang="ts">
73
+ import { HeaderBar, HeaderBurgerMenu, HeaderMenuSection, HeaderMenuItem } from '@cnamts/synapse'
74
+ </script>
75
+
76
+ <template>
77
+ <HeaderBar>
78
+ <template #menu>
79
+ <HeaderBurgerMenu>
80
+ <HeaderMenuSection>
81
+ <HeaderMenuItem>
82
+ <a href="/">Home</a>
83
+ </HeaderMenuItem>
84
+ <HeaderMenuItem>
85
+ <a href="/about">About</a>
86
+ </HeaderMenuItem>
87
+ <HeaderMenuItem>
88
+ <RouterLink to="/services">Services</RouterLink>
89
+ </HeaderMenuItem>
90
+ <HeaderMenuItem>
91
+ <NuxtLink to="/contact">Contact</NuxtLink>
92
+ </HeaderMenuItem>
93
+ </HeaderMenuSection>
94
+ </HeaderBurgerMenu>
95
+ </template>
96
+ </HeaderBar>
97
+ </template>
98
+ `}
99
+ />
100
+
101
+
102
+
103
+ ## Menu à plusieurs niveaux
104
+
105
+ Vous pouvez également constituer votre menu avec plusieurs niveaux de profondeur. Dans ce cas là, il convient d'utiliser le composant `HeaderSubMenu` pour définir les sous-menus.
106
+
107
+ Pour conserver la logique sémantique du menu, le composant `HeaderSubMenu` doit être contenu dans un `HeaderMenuItem`.
108
+
109
+
110
+ <Canvas
111
+ of={HeaderBurgerMenuStories.Populated}
112
+ source={{
113
+ language: 'html',
114
+ code:`
115
+ <HeaderBar>
116
+ <template #menu>
117
+ <HeaderMenu>
118
+ <HeaderMenuSection >
119
+ <template #title>
120
+ Section 1
121
+ </template>
122
+ <HeaderMenuItem>
123
+ <a>Item 1</a>
124
+ </HeaderMenuItem>
125
+ <HeaderMenuItem>
126
+ <a>Item 2</a>
127
+ </HeaderMenuItem>
128
+ <headerMenuItem>
129
+ <HeaderSubMenu>
130
+ <template #title>
131
+ Menu de premier niveau 1
132
+ </template>
133
+ <HeaderMenuSection>
134
+ <template #title>
135
+ Section 1
136
+ </template>
137
+ <HeaderMenuItem>
138
+ <a>Item</a>
139
+ </HeaderMenuItem>
140
+ <HeaderSubMenu>
141
+ <template #title>
142
+ Menu de deuxième niveau 1
143
+ </template>
144
+ <HeaderMenuItem>
145
+ <a>Item</a>
146
+ </HeaderMenuItem>
147
+ </HeaderSubMenu>
148
+ </HeaderMenuSection>
149
+ </HeaderSubMenu>
150
+ </headerMenuItem>
151
+ </HeaderMenuSection>
152
+ <HeaderMenuSection>
153
+ <template #title>
154
+ Section 2
155
+ </template>
156
+ <headerMenuItem>
157
+ <HeaderSubMenu>
158
+ <template #title>
159
+ Menu de premier niveau 2
160
+ </template>
161
+ <HeaderMenuItem>
162
+ <a>Item 1</a>
163
+ </HeaderMenuItem>
164
+ <HeaderMenuItem>
165
+ <HeaderSubMenu>
166
+ <template #title>
167
+ Menu de deuxième niveau 2
168
+ </template>
169
+ <HeaderMenuItem>
170
+ <a>Item 1</a>
171
+ </HeaderMenuItem>
172
+ </HeaderSubMenu>
173
+ </HeaderMenuItem>
174
+ <HeaderMenuItem>
175
+ <HeaderSubMenu>
176
+ <template #title>
177
+ Menu de deuxième niveau 3
178
+ </template>
179
+ <HeaderMenuSection>
180
+ <template #title>
181
+ Section 1
182
+ </template>
183
+ <HeaderMenuItem>
184
+ <a>Item 1</a>
185
+ </HeaderMenuItem>
186
+ </HeaderMenuSection>
187
+ </HeaderSubMenu>
188
+ </HeaderMenuItem>
189
+ </HeaderSubMenu>
190
+ </headerMenuItem>
191
+ <HeaderMenuItem>
192
+ <a>Item 3</a>
193
+ </HeaderMenuItem>
194
+ </HeaderMenuSection>
195
+ <div class="pa-4">
196
+ <p class="font-weight-bold">Veillez vous connecter</p>
197
+ <VBtn variant="tonal" class="mt-4 font-weight-medium" color="primary">Je me connecte</VBtn>
198
+ </div>
199
+ </HeaderMenu>
200
+ </template>
201
+ </HeaderBar>
202
+ `}}
203
+ />
204
+
205
+
206
+ ## Construire un menu de façon dynamique
207
+
208
+ Voici un exemple de menu construit de façon dynamique.
209
+
210
+ <Canvas
211
+ of={HeaderBurgerMenuStories.Generated}
212
+ story={{
213
+ height: '500px',
214
+ }}
215
+ source={{
216
+ language: 'html',
217
+ format: 'dedent',
218
+ code:`
219
+ <script setup lang="ts">
220
+ import { HeaderBar, HeaderBurgerMenu, HeaderMenuSection, HeaderMenuItem, HeaderSubMenu } from '@cnamts/synapse'
221
+ import { mdiMapMarker } from '@mdi/js'
222
+
223
+ const marker = mdiMapMarker
224
+
225
+ const menu = [
226
+ {
227
+ title: 'Vous informer',
228
+ items: [
229
+ { title: 'Actualités', href: 'https://www.ameli.fr/assure/actualites' },
230
+ {
231
+ subMenuTitle: 'Droits et démarches',
232
+ subMenuSubtitle: 'selon votre situation',
233
+ sections: [
234
+ {
235
+ title: undefined,
236
+ items: [
237
+ { title: 'Les essentiels de l\'assuré', href: 'https://www.ameli.fr/assure/droits-demarches/principes' },
238
+ { title: 'Parentalité, couple', href: 'https://www.ameli.fr/assure/droits-demarches/famille' },
239
+ { title: 'Fin de vie, deuil', href: 'https://www.ameli.fr/assure/droits-demarches/fin-de-vie-deuil' },
240
+ { title: 'Etudes et stages', href: 'https://www.ameli.fr/assure/droits-demarches/etudes-stages' },
241
+ { title: 'Vie professionnelle, retraite', href: 'https://www.ameli.fr/assure/droits-demarches/vie-professionnelle-retraite' },
242
+ { title: 'Difficultés d\'accès aux droits et aux soins', href: 'https://www.ameli.fr/assure/droits-demarches/difficultes-acces-droits-soins' },
243
+ { title: 'Maladie, accident, hospitalisation', href: 'https://www.ameli.fr/assure/droits-demarches/maladie-accident-hospitalisation' },
244
+ { title: 'invalidité, handicap', href: 'https://www.ameli.fr/assure/droits-demarches/invalidite-handicap' },
245
+ { title: 'situations particulières', href: 'https://www.ameli.fr/assure/droits-demarches/situations-particulieres' },
246
+ { title: 'réclamation, médiation, recours', href: 'https://www.ameli.fr/assure/droits-demarches/reclamation-mediation-voies-de-recours' },
247
+ { title: 'Europe, international', href: 'https://www.ameli.fr/assure/droits-demarches/europe-international' },
248
+ ],
249
+ },
250
+ ],
251
+ },
252
+ {
253
+ subMenuTitle: 'Remboursements',
254
+ subMenuSubtitle: 'prestations et aides',
255
+ sections: [
256
+ {
257
+ title: undefined,
258
+ items: [
259
+ { title: 'Ce qui est remboursé', href: 'https://www.ameli.fr/assure/remboursements/rembourse' },
260
+ { title: 'ce qui reste à votre charge', href: 'https://www.ameli.fr/assure/remboursements/reste-charge' },
261
+ { title: 'Être bien remboursé', href: 'https://www.ameli.fr/assure/remboursements/etre-bien-rembourse' },
262
+ { title: 'Indemnités journalières maladie, maternité, paternité', href: 'https://www.ameli.fr/assure/remboursements/indemnites-journalieres-maladie-maternite-paternite' },
263
+ { title: 'Accident du travail : prise en charge et indemnités journalières', href: 'https://www.ameli.fr/assure/remboursements/accident-travail' },
264
+ { title: 'Maladie professionnelle : prise en charge et indemnités journalières', href: 'https://www.ameli.fr/assure/remboursements/maladie-professionnelle' },
265
+ { title: 'Pensions, allocations et rentes', href: 'https://www.ameli.fr/assure/remboursements/pensions-allocations-rentes' },
266
+ { title: 'Incapacité permanente', href: 'https://www.ameli.fr/assure/remboursements/incapacite-permanente' },
267
+ { title: 'Complémentaire santé solidaire : vous n\'avez rien à payer dans la plupart des cas ', href: 'https://www.ameli.fr/assure/remboursements/cmu-aides-financieres/complementaire-sante-solidaire' },
268
+ { title: 'Aide médicale de l\'État et soins urgents', href: 'https://www.ameli.fr/assure/remboursements/aide-medicale-etat-soins-urgents' },
269
+ { title: 'Compte ameli, mode d\'emploi', href: 'https://www.ameli.fr/assure/remboursements/suivre-remboursements' },
270
+ ],
271
+ },
272
+ ],
273
+ },
274
+ {
275
+ subMenuTitle: 'Maladies et prévention',
276
+ sections: [
277
+ {
278
+ title: undefined,
279
+ items: [
280
+ { title: 'Tous les thèmes de santé', href: 'https://www.ameli.fr/assure/sante/themes' },
281
+ { title: 'L\'Assurance Maladie vous accompagne', href: 'https://www.ameli.fr/assure/remboursements/reste-charge' },
282
+ { title: 'Mon espace santé', href: 'https://www.ameli.fr/assure/sante/mon-espace-sante' },
283
+ { title: 'Mon bilan prévention', href: 'https://www.ameli.fr/assure/sante/mon-bilan-prevention' },
284
+ { title: 'Réagir en cas d\'urgence ', href: 'https://www.ameli.fr/assure/sante/urgence' },
285
+ { title: 'Accomplir les bons gestes ', href: 'https://www.ameli.fr/assure/sante/bons-gestes' },
286
+ { title: 'Médicaments et vaccins', href: 'https://www.ameli.fr/assure/sante/medicaments' },
287
+ { title: 'Déroulement d\'un examen', href: 'https://www.ameli.fr/assure/sante/examen' },
288
+ { title: 'Certificat médical : dans quels cas et pour qui est-il obligatoire ?', href: 'https://www.ameli.fr/assure/sante/certificat-medical-quand-et-pour-qui' },
289
+ { title: 'Devenir parent', href: 'https://www.ameli.fr/assure/sante/devenir-parent' },
290
+ { title: 'Enfants', href: 'https://www.ameli.fr/assure/sante/enfants' },
291
+ { title: 'Jeunes 16-25 ans', href: 'https://www.ameli.fr/assure/sante/jeunes-16-25-ans' },
292
+ { title: 'Seniors', href: 'https://www.ameli.fr/assure/sante/seniors' },
293
+ { title: 'Télésanté, la santé à distance', href: 'https://www.ameli.fr/assure/sante/telesante' },
294
+ ],
295
+ },
296
+ ],
297
+ },
298
+ ],
299
+ },
300
+ {
301
+ title: 'Besoin d\'aide',
302
+ items: [
303
+ {
304
+ title: 'Contacter l\'Assurance Maladie',
305
+ subtitle: 'obtenir une attestation, envoyer une feuille de soins, contacter sa caisse, etc.',
306
+ href: 'https://www.ameli.fr/assure/adresses-contacts',
307
+ },
308
+ {
309
+ title: 'Trouver un professionnel de santé',
310
+ subtitle: 'médecins, infirmiers...',
311
+ href: 'https://www.ameli.fr/assure/adresses-contacts',
312
+ },
313
+ {
314
+ title: 'Télécharger un formulaire (ex: cerfa)',
315
+ href: 'https://www.ameli.fr/assure/droits-demarches/formulaires',
316
+ },
317
+ {
318
+ title: 'Consulter le forum',
319
+ href: 'https://forum-assures.ameli.fr/',
320
+ },
321
+ {
322
+ title: 'Sourds et malentendants',
323
+ href: 'https://elioz.fr/elioz-connect/annuaire/assurance-maladie-annuaire/',
324
+ },
325
+ ],
326
+ },
327
+ ]
328
+ </script>
329
+
330
+ <template>
331
+ <HeaderBar>
332
+ <template #menu>
333
+ <HeaderBurgerMenu>
334
+ <HeaderMenuSection
335
+ v-for="section in menu"
336
+ :key="section.title"
337
+ :title="section.title"
338
+ >
339
+ <HeaderMenuItem
340
+ v-for="item in section.items"
341
+ :key="item.title"
342
+ >
343
+ <HeaderSubMenu v-if="'subMenuTitle' in item">
344
+ <template #title>
345
+ {{ item.subMenuTitle }}
346
+ <em
347
+ v-if="item?.subMenuSubtitle"
348
+ style="font-style: normal; color: #757777;"
349
+ >{{ item.subMenuSubtitle }}</em>
350
+ </template>
351
+ <HeaderMenuSection
352
+ v-for="subSection in item.sections"
353
+ :key="subSection.title"
354
+ :title="subSection.title"
355
+ >
356
+ <HeaderMenuItem
357
+ v-for="subItem in subSection.items"
358
+ :key="subItem.title"
359
+ >
360
+ <a :href="subItem.href">{{ subItem.title }}</a>
361
+ </HeaderMenuItem>
362
+ </HeaderMenuSection>
363
+ </HeaderSubMenu>
364
+ <a
365
+ v-else
366
+ :href="item.href"
367
+ >
368
+ {{ item.title }}
369
+ <em
370
+ v-if="'subtitle' in item"
371
+ style="font-style: normal; color: #757777;"
372
+ >{{ item.subtitle }}</em>
373
+ </a>
374
+ </HeaderMenuItem>
375
+ </HeaderMenuSection>
376
+ <h2
377
+ class="border-b-sm mb-2"
378
+ style="font-size: 1.1rem; padding: 40px 16px 8px 20px;"
379
+ >
380
+ Votre caisse
381
+ </h2>
382
+ <div style="padding: 16px 50px 16px 20px;">
383
+ <div class="d-flex align-center ga-2 font-weight-bold">
384
+ <VIcon
385
+ aria-label="Localisation"
386
+ role="img"
387
+ aria-hidden="false"
388
+ color="primary"
389
+ >
390
+ {{ marker }}
391
+ </VIcon>
392
+ <p>Vous n'avez pas sélectionné votre caisse</p>
393
+ </div>
394
+ <VBtn
395
+ class="mt-3 mb-4 font-weight-bold text-capitalize"
396
+ base-color="primary"
397
+ density="comfortable"
398
+ flat
399
+ height="37"
400
+ >
401
+ Sélectionner
402
+ </VBtn>
403
+ <p class="mb-8">
404
+ Les pages d'ameli seront alors enrichies des informations locales de votre caisse (contacts, événements régionaux, etc.)
405
+ </p>
406
+ </div>
407
+ </HeaderBurgerMenu>
408
+ </template>
409
+ </HeaderBar>
410
+ </template>
411
+
412
+ `}}
413
+ />
414
+
415
+
416
+ ## Gérer la navigation avec un RouterLink
417
+
418
+ Si vous positionnez le composant dans un layout ou à la racine de votre application et que vous utilisez un routeur pour gérer la navigation, le menu ne se fermera pas automatiquement lors de la navigation.
419
+
420
+ Si vous souhaitez que le menu se ferme lors de la navigation, vous pouvez utiliser le `v-model` par défaut pour gérer l'état du menu.
421
+
422
+ <Source
423
+ dark
424
+ language="typescript"
425
+ format="dedent"
426
+ code={`
427
+ const menuOpen = ref(false)
428
+ const curRoute = useRoute()
429
+ watch(curRoute, () => {
430
+ menuOpen.value = false
431
+ })
432
+ `}
433
+ />