@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
@@ -59,7 +59,7 @@ describe('HeaderLogo', () => {
59
59
  serviceTitle: 'Test service title',
60
60
  },
61
61
  slots: {
62
- serviceTitle: '<h1>other title</h1>',
62
+ 'brand-content': '<h1>other title</h1>',
63
63
  },
64
64
  })
65
65
 
@@ -68,4 +68,52 @@ describe('HeaderLogo', () => {
68
68
  expect(render).toContain('other title')
69
69
  expect(render).not.toContain('Test service title')
70
70
  })
71
+
72
+ it('render a router-link when homeLink is set with `to`', async () => {
73
+ const wrapper = mount(HeaderLogo, {
74
+ global: {
75
+ plugins: [vuetify],
76
+ stubs: ['RouterLink'],
77
+ },
78
+ props: {
79
+ homeLink: {
80
+ to: '/',
81
+ },
82
+ },
83
+ })
84
+
85
+ expect(wrapper.find('router-link-stub').exists()).toBe(true)
86
+ expect(wrapper.find('router-link-stub').attributes('to')).toBe('/')
87
+ })
88
+
89
+ it('render a div when there there is no `RouterLink` component registered', async () => {
90
+ const wrapper = mount(HeaderLogo, {
91
+ global: {
92
+ plugins: [vuetify],
93
+ },
94
+ props: {
95
+ homeLink: {
96
+ to: '/',
97
+ },
98
+ },
99
+ })
100
+
101
+ expect(wrapper.find('.logo').element.tagName).toBe('DIV')
102
+ })
103
+
104
+ it('render a div when the homeLink properties `to` and `href` are both set to `undefined`', async () => {
105
+ const wrapper = mount(HeaderLogo, {
106
+ global: {
107
+ plugins: [vuetify],
108
+ },
109
+ props: {
110
+ homeLink: {
111
+ to: undefined,
112
+ href: undefined,
113
+ },
114
+ },
115
+ })
116
+
117
+ expect(wrapper.find('.logo').element.tagName).toBe('DIV')
118
+ })
71
119
  })
@@ -1,24 +1,11 @@
1
1
  <script setup lang="ts">
2
- import { computed, ref, type CSSProperties } from 'vue'
3
- import { useTheme } from 'vuetify'
2
+ import { ref } from 'vue'
4
3
  import { mdiClose, mdiMenu } from '@mdi/js'
5
4
  import locals from './locals'
6
5
 
7
- const theme = useTheme()
8
6
  const btn = ref<HTMLElement | null>(null)
9
- const btnFocused = ref(false)
10
-
11
7
  const model = defineModel<boolean>()
12
8
 
13
- const btnStyle = computed<CSSProperties>(() => {
14
- const light = model.value || btnFocused.value
15
-
16
- return ({
17
- backgroundColor: light ? '#fff' : theme.current.value.colors.primary,
18
- color: light ? theme.current.value.colors.primary : '#fff',
19
- })
20
- })
21
-
22
9
  function focus() {
23
10
  btn.value?.focus()
24
11
  }
@@ -30,13 +17,13 @@
30
17
  <button
31
18
  ref="btn"
32
19
  class="header-menu-btn"
33
- :style="btnStyle"
20
+ :class="{
21
+ 'header-menu-btn__open': model
22
+ }"
34
23
  type="button"
35
24
  :aria-label="model ? locals.closeMenu : locals.openMenu"
36
25
  :title="model ? locals.closeMenu : locals.openMenu"
37
- @click="() => (model = !model)"
38
- @focus="btnFocused = true"
39
- @blur="btnFocused = false"
26
+ @click="() => { model = !model }"
40
27
  >
41
28
  <VIcon size="48">
42
29
  {{ model ? mdiClose : mdiMenu }}
@@ -51,7 +38,7 @@
51
38
 
52
39
  .header-menu-btn {
53
40
  text-transform: Capitalize;
54
- height: $header-height - 1;
41
+ height: $header-height;
55
42
  width: 82px;
56
43
  display: flex;
57
44
  flex-direction: column;
@@ -59,14 +46,23 @@
59
46
  flex-shrink: 0;
60
47
  justify-content: center;
61
48
  font-weight: 700;
62
- transition: color 0.15s 0.1s, background-color 0.15s 0.1s;
49
+ background-color: $primary-base;
50
+ color: $neutral-white;
51
+ border-bottom: solid 1px $blue-lighten-80;
52
+ transition: color 0.15s 0.1s, background-color 0.15s 0.1s, border-bottom 0.15s 0.1s;
63
53
 
64
54
  &:focus-visible {
65
- background-color: $primary-base;
66
- color: $neutral-white;
55
+ background-color: $neutral-white;
56
+ color: $primary-base;
67
57
  }
68
58
  }
69
59
 
60
+ .header-menu-btn__open {
61
+ background-color: $neutral-white;
62
+ color: $primary-base;
63
+ border-color: $neutral-white;
64
+ }
65
+
70
66
  @media screen and (max-width: ($header-breakpoint + 1)) {
71
67
  .header-menu-btn__label {
72
68
  clip: rect(0 0 0 0);
@@ -81,7 +77,7 @@
81
77
 
82
78
  @media screen and (min-width: $header-breakpoint) {
83
79
  .header-menu-btn {
84
- height: $header-height-desktop - 1;
80
+ height: $header-height-desktop;
85
81
  width: $header-height-desktop;
86
82
  }
87
83
  }
@@ -0,0 +1,70 @@
1
+ import { vuetify } from '@tests/unit/setup'
2
+ import { mount } from '@vue/test-utils'
3
+ import { describe, expect, it } from 'vitest'
4
+ import HeaderMenuBtn from '../HeaderMenuBtn.vue'
5
+ import locals from '../locals'
6
+
7
+ describe('HeaderMenuBtn', () => {
8
+ it('should render the component', async () => {
9
+ const wrapper = mount(HeaderMenuBtn, {
10
+ global: {
11
+ plugins: [vuetify],
12
+ },
13
+ props: {
14
+ modelValue: false,
15
+ },
16
+ })
17
+
18
+ expect(wrapper.html()).toContain(locals.openMenu)
19
+
20
+ await wrapper.setProps({
21
+ modelValue: true,
22
+ })
23
+
24
+ expect(wrapper.html()).toContain(locals.closeMenu)
25
+ })
26
+
27
+ it('emit an event when the button is clicked', async () => {
28
+ const wrapper = mount(HeaderMenuBtn, {
29
+ global: {
30
+ plugins: [vuetify],
31
+ },
32
+ props: {
33
+ modelValue: false,
34
+ },
35
+ })
36
+
37
+ const button = wrapper.find('button')
38
+
39
+ await button.trigger('click')
40
+
41
+ expect(wrapper.emitted('update:modelValue')).toBeTruthy()
42
+ expect(wrapper.emitted('update:modelValue')?.[0]).toEqual([true])
43
+ })
44
+
45
+ it('focus when the focus exposed function is called', async () => {
46
+ const wrapper = mount(HeaderMenuBtn, {
47
+ global: {
48
+ plugins: [vuetify],
49
+ },
50
+ props: {
51
+ modelValue: false,
52
+ },
53
+ attachTo: document.body,
54
+ })
55
+
56
+ const button = wrapper.find('button')
57
+
58
+ expect(button.element).not.toBe(document.activeElement)
59
+
60
+ await wrapper.vm.focus()
61
+
62
+ expect(button.element).toBe(document.activeElement)
63
+
64
+ document.body.focus()
65
+
66
+ expect(button.element).not.toBe(document.activeElement)
67
+
68
+ wrapper.unmount()
69
+ })
70
+ })
@@ -0,0 +1,85 @@
1
+ import { Meta } from "@storybook/blocks";
2
+ import * as HeaderBarStories from "./HeaderBar.stories";
3
+
4
+ <Meta of={HeaderBarStories} />
5
+
6
+ # Usages
7
+
8
+ <br />
9
+
10
+ <img alt="HeaderBar1" src={'/HeaderBar1.jpg'} style={{ border: '1px solid rgba(0, 0, 0, 0.05)', boxShadow: 'rgba(0, 0, 0, 0.10) 0 1px 3px 0' }} />
11
+
12
+ <br /><br />
13
+
14
+ <img alt="HeaderBar2" src={'/HeaderBar2.jpg'} style={{ border: '1px solid rgba(0, 0, 0, 0.05)', boxShadow: 'rgba(0, 0, 0, 0.10) 0 1px 3px 0' }} />
15
+
16
+ <br /><br />
17
+
18
+ Pour les produits avec un faible nombre d’entrées dans le menu (inférieur à 6) la barre de navigation prend la forme d’une liste d’onglet. Cet affichage permet un aperçu direct des différentes fonctionnalités de la plateforme ainsi qu’un accès plus rapide à ces dernières.
19
+
20
+ <br />
21
+
22
+ <img alt="HeaderBar3" src={'/HeaderBar3.jpg'} style={{ border: '1px solid rgba(0, 0, 0, 0.05)', boxShadow: 'rgba(0, 0, 0, 0.10) 0 1px 3px 0' }} />
23
+
24
+ <br /><br />
25
+
26
+ Pour les produits possédant (ou allant posséder) plus de 6 entrées, nous utilisons le menu burger issu de la refonte d’Ameli.fr. Anticipez dès la phase de conception le nombre de fonctionnalités prévues en version cible afin de choisir la version adaptée.
27
+
28
+ <br />
29
+
30
+ <img alt="HeaderBar4" src={'/HeaderBar4.jpg'} style={{ border: '1px solid rgba(0, 0, 0, 0.05)', boxShadow: 'rgba(0, 0, 0, 0.10) 0 1px 3px 0' }} />
31
+
32
+ <br /><br />
33
+
34
+ <img alt="HeaderBar5" src={'/HeaderBar5.jpg'} style={{ border: '1px solid rgba(0, 0, 0, 0.05)', boxShadow: 'rgba(0, 0, 0, 0.10) 0 1px 3px 0' }} />
35
+
36
+ <br /><br />
37
+
38
+ <img alt="HeaderBar6" src={'/HeaderBar6.jpg'} style={{ border: '1px solid rgba(0, 0, 0, 0.05)', boxShadow: 'rgba(0, 0, 0, 0.10) 0 1px 3px 0' }} />
39
+
40
+ <br /><br />
41
+
42
+ <img alt="HeaderBar7" src={'/HeaderBar7.jpg'} style={{ border: '1px solid rgba(0, 0, 0, 0.05)', boxShadow: 'rgba(0, 0, 0, 0.10) 0 1px 3px 0' }} />
43
+
44
+ <br /><br />
45
+
46
+ En mobile, quel que soit le nombre d’entrées nous utilisons toujours le burger menu.
47
+
48
+ <br />
49
+
50
+ <div style={{ display: 'flex', justifyContent: 'center', alignItems: 'flex-start' }}>
51
+ <img alt="HeaderBar8" src={'/HeaderBar8.jpg'} style={{ maxWidth: '30%', marginRight: '20px', border: '1px solid rgba(0, 0, 0, 0.05)', boxShadow: 'rgba(0, 0, 0, 0.10) 0 1px 3px 0' }} />
52
+ <img alt="HeaderBar9" src={'/HeaderBar9.jpg'} style={{ maxWidth: '30%', border: '1px solid rgba(0, 0, 0, 0.05)', boxShadow: 'rgba(0, 0, 0, 0.10) 0 1px 3px 0' }} />
53
+ </div>
54
+
55
+ <br /><br />
56
+
57
+ Lorsque la toolbar est nécessaire, elle se trouve systématiquement en tant que premier élément du header. Il est possible de l’utiliser sans la partie permettant de sélectionner un public.
58
+
59
+ <br />
60
+
61
+ <img alt="HeaderBar10" src={'/HeaderBar10.jpg'} style={{ border: '1px solid rgba(0, 0, 0, 0.05)', boxShadow: 'rgba(0, 0, 0, 0.10) 0 1px 3px 0' }} />
62
+
63
+ <br /><br />
64
+
65
+ <img alt="HeaderBar11" src={'/HeaderBar11.jpg'} style={{ border: '1px solid rgba(0, 0, 0, 0.05)', boxShadow: 'rgba(0, 0, 0, 0.10) 0 1px 3px 0' }} />
66
+
67
+ <br /><br />
68
+
69
+ Le slot de droite est à la main de chaque équipe produit.<br />
70
+ Il contiendra généralement un bouton de connexion devenant l’identifiant de connexion le cas échéant.<br />
71
+ Il est également possible d’y ajouter d’autres fonctionnalités selon les besoins, comme une recherche, un accès aux notifications...
72
+
73
+ <br />
74
+
75
+ <div style={{ display: 'flex', justifyContent: 'center', alignItems: 'flex-start', marginBottom: '10px' }}>
76
+ <figcaption style={{ width: '30%', marginRight: '20px' }}>Exemple non-connecté</figcaption>
77
+ <figcaption style={{ width: '30%', marginRight: '20px' }}>Exemple connecté</figcaption>
78
+ <figcaption style={{ width: '30%' }}>Exemple connecté - active</figcaption>
79
+ </div>
80
+
81
+ <div style={{ display: 'flex', justifyContent: 'center', alignItems: 'flex-start' }}>
82
+ <img alt="HeaderBar12" src={'/HeaderBar12.jpg'} style={{ maxWidth: '30%', marginRight: '20px', border: '1px solid rgba(0, 0, 0, 0.05)', boxShadow: 'rgba(0, 0, 0, 0.10) 0 1px 3px 0' }} />
83
+ <img alt="HeaderBar13" src={'/HeaderBar13.jpg'} style={{ maxWidth: '30%', marginRight: '20px', border: '1px solid rgba(0, 0, 0, 0.05)', boxShadow: 'rgba(0, 0, 0, 0.10) 0 1px 3px 0' }} />
84
+ <img alt="HeaderBar14" src={'/HeaderBar14.jpg'} style={{ maxWidth: '30%', border: '1px solid rgba(0, 0, 0, 0.05)', boxShadow: 'rgba(0, 0, 0, 0.10) 0 1px 3px 0' }} />
85
+ </div>
@@ -3,5 +3,4 @@ $header-height-desktop: 95px;
3
3
  $header-height: 77px;
4
4
  $header-max-width: 1712px;
5
5
  $menu-border-color: #e0e0e0;
6
- $menu-height: 70vh;
7
6
  $menu-width: 350px;
@@ -1,12 +1,16 @@
1
1
  import { vuetify } from '@tests/unit/setup'
2
2
  import { mount } from '@vue/test-utils'
3
- import { afterEach, describe, expect, it, vi } from 'vitest'
3
+ import { afterAll, describe, expect, it, vi } from 'vitest'
4
4
  import { defineComponent, inject, onMounted, ref, type Ref } from 'vue'
5
5
  import HeaderBar from '../HeaderBar.vue'
6
6
  import { registerHeaderMenuKey } from '../consts'
7
7
 
8
8
  describe('HeaderBar', () => {
9
- afterEach(() => {
9
+ vi.mock('@/utils/functions/throttleDisplayFn/throttleDisplayFn.ts', () => ({
10
+ default: (fn: (...args: unknown[]) => void) => fn,
11
+ }))
12
+
13
+ afterAll(() => {
10
14
  vi.restoreAllMocks()
11
15
  document.body.innerHTML = ''
12
16
  })
@@ -56,6 +60,7 @@ describe('HeaderBar', () => {
56
60
  'menu': '<div>Menu slot</div>',
57
61
  'logo': '<div>Logo slot</div>',
58
62
  'header-side': '<div>Header side slot</div>',
63
+ 'logo-brand-content': '<div>Logo brand content slot</div>',
59
64
  },
60
65
  })
61
66
 
@@ -67,6 +72,7 @@ describe('HeaderBar', () => {
67
72
  expect(text).toContain('Menu slot')
68
73
  expect(text).toContain('Logo slot')
69
74
  expect(text).toContain('Header side slot')
75
+ expect(text).not.toContain('Logo brand content slot')
70
76
 
71
77
  wrapper.unmount()
72
78
  })
@@ -2,11 +2,10 @@
2
2
 
3
3
  exports[`HeaderBar > should render the component 1`] = `
4
4
  "<header data-v-efdbe191="" class="header" style="min-height: auto;">
5
- <div data-v-efdbe191="" class="sticky-header" style="position: relative; top: auto; transform: none; transition: none;">
5
+ <div data-v-efdbe191="" class="sticky-header" style="position: relative; width: 100%; top: auto; transform: none; transition: none;">
6
6
  <!--v-if-->
7
- <div data-v-efdbe191="" class="inner-header d-flex">
8
- <div data-v-efdbe191="" class="header-logo">
9
- <div data-v-a3ce97de="" data-v-efdbe191="" class="logo"><svg data-v-d1ac2910="" data-v-a3ce97de="" fill="#0c419a" width="141" height="42" viewBox="0 0 211 64" role="img" focusable="false" xmlns="http://www.w3.org/2000/svg" aria-label="Logo de l'Assurance Maladie, cliquez pour revenir à l'accueil">
7
+ <div data-v-efdbe191="" class="inner-header">
8
+ <div data-v-efdbe191="" class="header-logo"><a data-v-a3ce97de="" data-v-efdbe191="" href="/" class="logo"><svg data-v-d1ac2910="" data-v-a3ce97de="" fill="#0c419a" width="141" height="42" viewBox="0 0 211 64" role="img" focusable="false" xmlns="http://www.w3.org/2000/svg" aria-label="Logo de l'Assurance Maladie, cliquez pour revenir à l'accueil">
10
9
  <g data-v-d1ac2910="">
11
10
  <path d="M100.1 45V30.6h3.8v14.6c0 .8.4 1 .7 1h.5l.5 2.9a5 5 0 0 1-2 .3c-2.6 0-3.5-1.7-3.5-4.4Z" data-v-d1ac2910=""></path>
12
11
  <path d="m75.7 40.4 3.8-8.5h4V49h-3.6V38.4l-3 7.8h-2.4l-3-7.8v10.7H68V32h4l3.8 8.5Z" data-v-d1ac2910=""></path>
@@ -36,12 +35,8 @@ exports[`HeaderBar > should render the component 1`] = `
36
35
  <path d="M50.3 17.3c-.1 0-.3 0-.3-.2A22 22 0 0 0 36.5 10c-.2 0-.4-.3-.3-.5 0-.3.2-.4.5-.4a23 23 0 0 1 14 7.5v.7h-.4Z" data-v-d1ac2910=""></path>
37
36
  </svg>
38
37
  <!--v-if-->
39
- <div data-v-a3ce97de="" if="serviceTitle">
40
- <div data-v-a3ce97de="" class="service-title"></div>
41
- <!--v-if-->
42
- </div>
43
- </div>
44
- </div>
38
+ <!--v-if-->
39
+ </a></div>
45
40
  <!--v-if-->
46
41
  </div>
47
42
  <!--v-if-->
@@ -0,0 +1,28 @@
1
+ import { Controls, Canvas, Meta, Source } from '@storybook/blocks';
2
+ import * as HeaderLoading from './HeaderLoading.stories';
3
+
4
+ <Meta of={HeaderLoading} />
5
+
6
+ # HeaderLoading
7
+
8
+ L’élément `HeaderLoading` est une extension du composant `VSkeletonLoader` de Vuetify, il est utilisé pour afficher un élément de chargement avec des dimensions personnalisées.
9
+
10
+ <Canvas of={HeaderLoading.Default} />
11
+
12
+ # API
13
+
14
+ <Controls of={HeaderLoading.Default} />
15
+
16
+ # Exemple d'utilisation
17
+
18
+ <Source dark code={`
19
+ <script setup lang="ts">
20
+ import HeaderLoading from '@cnamts/synapse'
21
+ </script>
22
+
23
+ <template>
24
+ <div class="pa-4">
25
+ <HeaderLoading width="200px" />
26
+ </div>
27
+ </template>
28
+ `} />
@@ -0,0 +1,62 @@
1
+ import HeaderLoading from './HeaderLoading.vue'
2
+ import type { Meta, StoryObj } from '@storybook/vue3'
3
+
4
+ const meta: Meta<typeof HeaderLoading> = {
5
+ title: 'Composants/Structure/HeaderLoading',
6
+ component: HeaderLoading,
7
+ parameters: {
8
+ layout: 'fullscreen',
9
+ controls: { exclude: ['heading', 'itemsNumber', 'row'] },
10
+ },
11
+ argTypes: {
12
+ width: { control: 'text' },
13
+ height: { control: 'text' },
14
+ },
15
+ }
16
+
17
+ export default meta
18
+
19
+ type Story = StoryObj<typeof meta>
20
+
21
+ export const Default: Story = {
22
+ parameters: {
23
+ sourceCode: [
24
+ {
25
+ name: 'Template',
26
+ code: `
27
+ <template>
28
+ <HeaderLoading :width="width" :height="height" />
29
+ </template>
30
+ `,
31
+ },
32
+ {
33
+ name: 'Script',
34
+ code: `
35
+ <script setup lang="ts">
36
+ import HeaderLoading from '@cnamts/synapse'
37
+
38
+ const width = '100px'
39
+ const height = '1rem'
40
+ </script>
41
+ `,
42
+ },
43
+ ],
44
+ },
45
+ args: {
46
+ width: '100px',
47
+ height: '1rem',
48
+ },
49
+ render: (args) => {
50
+ return {
51
+ components: { HeaderLoading },
52
+ setup() {
53
+ return { args }
54
+ },
55
+ template: `
56
+ <div class="pa-4">
57
+ <HeaderLoading v-bind="args" />
58
+ </div>
59
+ `,
60
+ }
61
+ },
62
+ }
@@ -0,0 +1,45 @@
1
+ <script lang="ts" setup>
2
+ import { VSkeletonLoader } from 'vuetify/components/VSkeletonLoader'
3
+
4
+ const props = defineProps({
5
+ width: {
6
+ type: String,
7
+ default: '100px',
8
+ },
9
+ height: {
10
+ type: String,
11
+ default: '1rem',
12
+ },
13
+ })
14
+ </script>
15
+
16
+ <template>
17
+ <VSkeletonLoader
18
+ v-bind="$attrs"
19
+ :width="props.width"
20
+ :height="props.height"
21
+ type="heading"
22
+ aria-hidden="true"
23
+ class="vd-header-loading"
24
+ />
25
+ </template>
26
+
27
+ <style lang="scss" scoped>
28
+ .vd-header-loading :deep() {
29
+ background: transparent;
30
+ .v-skeleton-loader__heading {
31
+ width: 100%;
32
+ height: 100%;
33
+ border-radius: 35px;
34
+ margin: 0;
35
+ background: rgba(grey, var(--v-border-opacity));
36
+ }
37
+ }
38
+
39
+ // Remove border radius when tile option is activated
40
+ .vd-header-loading.v-skeleton-loader--tile :deep() {
41
+ .v-skeleton-loader__heading {
42
+ border-radius: 0;
43
+ }
44
+ }
45
+ </style>
@@ -0,0 +1,22 @@
1
+ import { describe, it, expect } from 'vitest'
2
+ import { mount } from '@vue/test-utils'
3
+ import { vuetify } from '@tests/unit/setup'
4
+
5
+ import HeaderLoading from '../HeaderLoading.vue'
6
+
7
+ describe('HeaderLoading', () => {
8
+ it('renders correctly', () => {
9
+ const wrapper = mount(HeaderLoading, {
10
+ global: {
11
+ plugins: [vuetify],
12
+ },
13
+ props: {
14
+ width: '100px',
15
+ height: '1rem',
16
+ },
17
+ })
18
+
19
+ const elExists = wrapper.find('.vd-header-loading').exists()
20
+ expect(elExists).toBe(true)
21
+ })
22
+ })
@@ -0,0 +1,128 @@
1
+ import { Controls, Canvas, Meta, Source } from "@storybook/blocks";
2
+ import * as HeaderNavigationBarStories from "./HeaderNavigationBar.stories";
3
+
4
+ <Meta of={HeaderNavigationBarStories} />
5
+
6
+ # HeaderNavigationBar
7
+
8
+ Le composant `HeaderNavigationBar` est un composant de navigation qui permet de naviguer entre les différentes pages de l'application.
9
+
10
+ Il est basé sur les composants `HeaderBar` et `HeaderBurgerMenu` du design system.
11
+
12
+ Ce composant propose un navigation à l'aide d'un menu horizontal en mode desktop ce qui peut être util pour les produits ayant peut de page a destination des agents.
13
+
14
+ Si vous n'avez pas besoin du menu horizontal, vous devriez utiliser le composant `HeaderBar` directement.
15
+
16
+ Il est conseillé de ne pas utiliser le menu horizontal pour afficher plus de 6 liens. Vous pouvez configurer le nombre de lien affiché dans le menu horizontal en utilisant la prop `maxHorizontalMenuItems`. Au-delà de ce chiffre, le menu passera en mode burger. Par défaut, le menu horizontal affiche au maximum six items.
17
+
18
+
19
+ <Canvas of={HeaderNavigationBarStories.Default} />
20
+
21
+ ## API
22
+
23
+ <Controls of={HeaderNavigationBarStories.Default} />
24
+
25
+
26
+ ## Exemple d'utilisation
27
+
28
+ <Source
29
+ dark
30
+ code={`
31
+ <HeaderNavigationBar
32
+ home-aria-label="Home"
33
+ service-title="Synapse"
34
+ service-subtitle="design system de la CNAM"
35
+ :sticky="true"
36
+ :items="[
37
+ { label: 'Home', to: '/' },
38
+ { label: 'About', to: '/about' },
39
+ { label: 'Services', to: '/services' },
40
+ { label: 'Contact', to: '/contact' },
41
+ { label: 'Blog', to: '/blog' },
42
+ ]"
43
+ />
44
+ `}
45
+ />
46
+
47
+ ## Les slots
48
+
49
+ ### HeaderSide
50
+
51
+ Le slot `header-side` permet d'ajouter du contenu à droite du header. Il est possible d'ajouter plusieurs éléments dans ce slot.
52
+ Il sera principalement utilisé pour ajouter un bouton de connexion, d'accès à un compte ou de recherche.
53
+ Il est nécessaire de faire attention à la place que prendront les éléments en mode mobile et de prévoir un mode réduit ou bien de les déporter dans le menu burger.
54
+
55
+ <Source dark code={`
56
+ <script setup lang="ts">
57
+ import { mdiMagnify, mdiAccountCircleOutline } from '@mdi/js'
58
+ </script>
59
+
60
+ <template>
61
+ <HeaderNavigationBar>
62
+ <template #header-side>
63
+ <div class="d-flex justify-center h-100 ga-4 pr-4">
64
+ <VBtn
65
+ variant="text"
66
+ :prepend-icon="mdiMagnify"
67
+ color="primary"
68
+ >
69
+ Rechercher
70
+ </VBtn>
71
+ <VBtn
72
+ color="primary"
73
+ :prepend-icon="mdiAccountCircleOutline"
74
+ >
75
+ Login
76
+ </VBtn>
77
+ </div>
78
+ </template>
79
+ </HeaderNavigationBar>
80
+ </template>
81
+ `} />
82
+
83
+ ### Les slots concernant le menu
84
+
85
+
86
+ <Canvas of={HeaderNavigationBarStories.WithSlots} />
87
+
88
+ #### le slot `logo-brand-section`
89
+
90
+ <Canvas of={HeaderNavigationBarStories.WithLogoSlot} />
91
+
92
+ #### Le menu horizontal
93
+
94
+ Quand le menu est en mode horizontal, les slots `navigation-bar-prepend` et `navigation-bar-append` permettent d'ajouter du contenu avant et après le menu.
95
+
96
+ Le slot `navigation-bar-content` quant à lui, remplace les items du menu tel que généré avec la props `items`. Il n'écrase pas les slots `navigation-bar-prepend` et `navigation-bar-append`.
97
+
98
+ ##### Slot `Navigation-bar-prepend`
99
+
100
+ <Canvas of={HeaderNavigationBarStories.WithNavigationBarPrependSlot} />
101
+
102
+
103
+ ##### Slot `Navigation-bar-append`
104
+
105
+ <Canvas of={HeaderNavigationBarStories.WithNavigationBarAppendSlot} />
106
+
107
+
108
+ #### Les slots concernant le menu burger
109
+
110
+ Le menu burger est généré automatiquement à partir des items passés en props, il utilise en interne le composant `HeaderBurgerMenu`.
111
+
112
+
113
+ les slots `burger-menu-prepend` et `burger-menu-append` permettent d'ajouter du contenu en haut et en bas du menu burger.
114
+
115
+
116
+ Le slot `burger-menu-content` permet de remplacer le contenu du menu burger. Il n'écrase pas les slots `burger-menu-prepend` et `burger-menu-append` et permet d'utiliser les composants `HeaderMenuItem` et `HeaderMenuGroup` pour construire le menu.
117
+ Pour plus de d'information sur la manière de construire un menu avec le composant `HeaderBurgerMenu`, vous pouvez consulter la documentation de ce [composant](/docs/components-headerbar-headerburgermenu--docs).
118
+
119
+ ##### Slot `burger-menu-append`
120
+
121
+ <Canvas of={HeaderNavigationBarStories.WithNavigationMenuAppendSlot} />
122
+
123
+
124
+ ## Configuration des composants Vuetify internes.
125
+
126
+ Le composant `HeaderNavigationBar` utilise les composants `VSheet`, `VTabs` et `VTab` de Vuetify pour construire le menu horizontal. Il est possible de configurer ces composants en utilisant la props `vuetifyOptions`.
127
+
128
+ <Canvas of={HeaderNavigationBarStories.WithVuetifyOptions} />