@cnamts/synapse 0.0.7-alpha → 0.0.9-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.
- package/dist/design-system-v3.d.ts +785 -372
- package/dist/design-system-v3.js +4993 -3357
- package/dist/design-system-v3.umd.cjs +1 -10
- package/dist/style.css +1 -1
- package/package.json +10 -2
- package/src/assets/settings.scss +2 -2
- package/src/assets/tokens.scss +107 -112
- package/src/components/BackBtn/BackBtn.vue +4 -4
- package/src/components/BackToTopBtn/BackToTopBtn.vue +1 -0
- package/src/components/CollapsibleList/CollapsibleList.mdx +1 -1
- package/src/components/CollapsibleList/CollapsibleList.vue +43 -44
- package/src/components/ContextualMenu/Accessibilite.mdx +14 -0
- package/src/components/ContextualMenu/Accessibilite.stories.ts +191 -0
- package/src/components/ContextualMenu/AccessibiliteItems.ts +89 -0
- package/src/components/ContextualMenu/ContextualMenu.mdx +118 -0
- package/src/components/ContextualMenu/ContextualMenu.stories.ts +430 -0
- package/src/components/ContextualMenu/ContextualMenu.vue +101 -0
- package/src/components/ContextualMenu/constants/ExpertiseLevelEnum.ts +4 -0
- package/src/components/ContextualMenu/tests/ContextualMenu.spec.ts +115 -0
- package/src/components/ContextualMenu/tests/__snapshots__/ContextualMenu.spec.ts.snap +10 -0
- package/src/components/ContextualMenu/types.ts +5 -0
- package/src/components/CookieBanner/CookieBanner.stories.ts +1 -2
- package/src/components/CookieBanner/CookieBanner.vue +13 -10
- package/src/components/CookieBanner/tests/__snapshots__/CookieBanner.spec.ts.snap +17 -15
- package/src/components/CookiesSelection/CookiesInformation/CookiesInformation.vue +6 -1
- package/src/components/CookiesSelection/CookiesInformation/locales.ts +1 -0
- package/src/components/CookiesSelection/CookiesTable/CookiesTable.vue +1 -0
- package/src/components/CookiesSelection/tests/__snapshots__/CookiesSelection.spec.ts.snap +17 -15
- package/src/components/CopyBtn/CopyBtn.vue +7 -7
- package/src/components/Customs/SyBtnSelect/SyBtnSelect.vue +26 -26
- package/src/components/Customs/SyInputSelect/SyInputSelect.vue +24 -24
- package/src/components/Customs/SySelect/SySelect.stories.ts +7 -7
- package/src/components/Customs/SySelect/SySelect.vue +36 -30
- package/src/components/Customs/SySelect/tests/SySelect.spec.ts +2 -2
- package/src/components/Customs/SyTextField/SyTextField.stories.ts +187 -2
- package/src/components/Customs/SyTextField/SyTextField.vue +185 -16
- package/src/components/Customs/SyTextField/tests/SyTextField.spec.ts +2 -4
- package/src/components/Customs/SyTextField/tests/__snapshots__/SyTextField.spec.ts.snap +18 -16
- package/src/components/Customs/SyTextField/types.d.ts +2 -2
- package/src/components/DataList/DataList.stories.ts +3 -2
- package/src/components/DataList/DataList.vue +1 -1
- package/src/components/DataListGroup/DataListGroup.stories.ts +3 -2
- package/src/components/DataListItem/DataListItem.vue +12 -12
- package/src/components/DatePicker/DatePicker.mdx +191 -0
- package/src/components/DatePicker/DatePicker.stories.ts +787 -0
- package/src/components/DatePicker/DatePicker.vue +560 -0
- package/src/components/DatePicker/DateTextInput.vue +409 -0
- package/src/components/DatePicker/tests/DatePicker.spec.ts +266 -0
- package/src/components/DialogBox/DialogBox.mdx +28 -2
- package/src/components/DialogBox/DialogBox.stories.ts +2 -2
- package/src/components/DialogBox/DialogBox.vue +3 -2
- package/src/components/DownloadBtn/DownloadBtn.vue +2 -1
- package/src/components/ExternalLinks/Accessibilite.mdx +14 -0
- package/src/components/ExternalLinks/Accessibilite.stories.ts +191 -0
- package/src/components/ExternalLinks/AccessibiliteItems.ts +197 -0
- package/src/components/ExternalLinks/ExternalLinks.mdx +86 -0
- package/src/components/ExternalLinks/ExternalLinks.stories.ts +553 -0
- package/src/components/ExternalLinks/ExternalLinks.vue +200 -0
- package/src/components/ExternalLinks/config.ts +34 -0
- package/src/components/ExternalLinks/constants/ExpertiseLevelEnum.ts +4 -0
- package/src/components/ExternalLinks/locales.ts +4 -0
- package/src/components/ExternalLinks/tests/ExternalLinks.spec.ts +154 -0
- package/src/components/ExternalLinks/tests/__snapshots__/ExternalLinks.spec.ts.snap +159 -0
- package/src/components/FileUpload/FileUpload.mdx +165 -0
- package/src/components/FileUpload/FileUpload.stories.ts +429 -0
- package/src/components/FileUpload/FileUpload.vue +195 -0
- package/src/components/FileUpload/FileUploadContent.vue +109 -0
- package/src/components/FileUpload/locales.ts +10 -0
- package/src/components/FileUpload/tests/FileUpload.spec.ts +332 -0
- package/src/components/FileUpload/tests/__snapshots__/FileUpload.spec.ts.snap +7 -0
- package/src/components/FileUpload/useFileDrop.ts +23 -0
- package/src/components/FileUpload/validateFiles.ts +39 -0
- package/src/components/FooterBar/FooterBar.vue +105 -80
- package/src/components/FranceConnectBtn/FranceConnectBtn.vue +14 -13
- package/src/components/HeaderBar/HeaderBar.vue +3 -3
- package/src/components/HeaderBar/HeaderBurgerMenu/HeaderBurgerMenu.vue +11 -7
- package/src/components/HeaderBar/HeaderBurgerMenu/HeaderMenuItem/HeaderMenuItem.vue +5 -5
- package/src/components/HeaderBar/HeaderBurgerMenu/HeaderMenuSection/HeaderMenuSection.vue +2 -2
- package/src/components/HeaderBar/HeaderBurgerMenu/HeaderSubMenu/HeaderSubMenu.vue +10 -8
- package/src/components/HeaderBar/HeaderLogo/HeaderLogo.vue +2 -2
- package/src/components/HeaderBar/HeaderLogo/logos/Logo-mobile.vue +2 -1
- package/src/components/HeaderBar/HeaderLogo/logos/Logo.vue +2 -1
- package/src/components/HeaderBar/HeaderMenuBtn/HeaderMenuBtn.vue +10 -10
- package/src/components/HeaderBar/consts.scss +1 -1
- package/src/components/HeaderLoading/HeaderLoading.vue +12 -11
- package/src/components/HeaderNavigationBar/HeaderNavigationBar.vue +2 -1
- package/src/components/HeaderNavigationBar/HorizontalNavbar/HorizontalNavbar.vue +9 -9
- package/src/components/HeaderToolbar/HeaderToolbar.vue +215 -202
- package/src/components/LangBtn/LangBtn.vue +8 -6
- package/src/components/LogoBrandSection/LogoBrandSection.stories.ts +2 -2
- package/src/components/NirField/NirField.stories.ts +8 -8
- package/src/components/NirField/NirField.vue +46 -48
- package/src/components/NotFoundPage/NotFoundPage.stories.ts +33 -2
- package/src/components/NotFoundPage/NotFoundPage.vue +17 -0
- package/src/components/NotificationBar/NotificationBar.mdx +5 -5
- package/src/components/NotificationBar/NotificationBar.stories.ts +410 -314
- package/src/components/NotificationBar/NotificationBar.vue +43 -41
- package/src/components/PageContainer/PageContainer.vue +4 -4
- package/src/components/PasswordField/Accessibilite.mdx +14 -0
- package/src/components/PasswordField/Accessibilite.stories.ts +191 -0
- package/src/components/PasswordField/AccessibiliteItems.ts +184 -0
- package/src/components/PasswordField/PasswordField.mdx +70 -0
- package/src/components/PasswordField/PasswordField.stories.ts +213 -0
- package/src/components/PasswordField/PasswordField.vue +189 -0
- package/src/components/PasswordField/config.ts +11 -0
- package/src/components/PasswordField/constants/ExpertiseLevelEnum.ts +4 -0
- package/src/components/PasswordField/locales.ts +4 -0
- package/src/components/PasswordField/tests/PasswordField.spec.ts +96 -0
- package/src/components/PhoneField/PhoneField.mdx +0 -2
- package/src/components/PhoneField/PhoneField.stories.ts +10 -50
- package/src/components/PhoneField/PhoneField.vue +77 -93
- package/src/components/PhoneField/tests/PhoneField.spec.ts +0 -15
- package/src/components/RangeField/RangeField.mdx +54 -0
- package/src/components/RangeField/RangeField.stories.ts +189 -0
- package/src/components/RangeField/RangeField.vue +157 -0
- package/src/components/RangeField/RangeSlider/RangeSlider.vue +387 -0
- package/src/components/RangeField/RangeSlider/Tooltip/Tooltip.vue +64 -0
- package/src/components/RangeField/RangeSlider/tests/__snapshots__/rangeSlider.spec.ts.snap +27 -0
- package/src/components/RangeField/RangeSlider/tests/rangeSlider.spec.ts +100 -0
- package/src/components/RangeField/RangeSlider/tests/useDoubleSlider.spec.ts +246 -0
- package/src/components/RangeField/RangeSlider/tests/useMouseSlide.spec.ts +204 -0
- package/src/components/RangeField/RangeSlider/tests/useThumb.spec.ts +22 -0
- package/src/components/RangeField/RangeSlider/tests/useThumbKeyboard.spec.ts +233 -0
- package/src/components/RangeField/RangeSlider/tests/useTooltipsNudge.spec.ts +150 -0
- package/src/components/RangeField/RangeSlider/tests/useTrack.spec.ts +314 -0
- package/src/components/RangeField/RangeSlider/tests/vAnimateClick.spec.ts +32 -0
- package/src/components/RangeField/RangeSlider/types.ts +15 -0
- package/src/components/RangeField/RangeSlider/useMouseSlide.ts +109 -0
- package/src/components/RangeField/RangeSlider/useRangeSlider.ts +126 -0
- package/src/components/RangeField/RangeSlider/useThumb.ts +18 -0
- package/src/components/RangeField/RangeSlider/useThumbKeyboard.ts +84 -0
- package/src/components/RangeField/RangeSlider/useTooltipsNudge.ts +92 -0
- package/src/components/RangeField/RangeSlider/useTrack.ts +116 -0
- package/src/components/RangeField/RangeSlider/vAnimateClick.ts +19 -0
- package/src/components/RangeField/config.ts +7 -0
- package/src/components/RangeField/locales.ts +4 -0
- package/src/components/RangeField/tests/RangeField.spec.ts +224 -0
- package/src/components/RangeField/tests/__snapshots__/RangeField.spec.ts.snap +379 -0
- package/src/components/RatingPicker/EmotionPicker/EmotionPicker.vue +205 -0
- package/src/components/RatingPicker/EmotionPicker/locales.ts +3 -0
- package/src/components/RatingPicker/EmotionPicker/tests/EmotionPicker.spec.ts +104 -0
- package/src/components/RatingPicker/EmotionPicker/tests/__snapshots__/EmotionPicker.spec.ts.snap +66 -0
- package/src/components/RatingPicker/NumberPicker/NumberPicker.vue +159 -0
- package/src/components/RatingPicker/NumberPicker/locales.ts +4 -0
- package/src/components/RatingPicker/NumberPicker/tests/NumberPicker.spec.ts +73 -0
- package/src/components/RatingPicker/NumberPicker/tests/__snapshots__/NumberPicker.spec.ts.snap +105 -0
- package/src/components/RatingPicker/Rating.ts +45 -0
- package/src/components/RatingPicker/RatingPicker.mdx +56 -0
- package/src/components/RatingPicker/RatingPicker.stories.ts +515 -0
- package/src/components/RatingPicker/RatingPicker.vue +122 -0
- package/src/components/RatingPicker/StarsPicker/StarsPicker.vue +116 -0
- package/src/components/RatingPicker/StarsPicker/tests/StarsPicker.spec.ts +95 -0
- package/src/components/RatingPicker/StarsPicker/tests/__snapshots__/StarsPicker.spec.ts.snap +36 -0
- package/src/components/RatingPicker/locales.ts +3 -0
- package/src/components/RatingPicker/tests/Rating.spec.ts +104 -0
- package/src/components/RatingPicker/tests/RatingPicker.spec.ts +187 -0
- package/src/components/RatingPicker/tests/__snapshots__/RatingPicker.spec.ts.snap +108 -0
- package/src/components/SearchListField/SearchListField.mdx +74 -0
- package/src/components/SearchListField/SearchListField.stories.ts +126 -0
- package/src/components/SearchListField/SearchListField.vue +194 -0
- package/src/components/SearchListField/locales.ts +5 -0
- package/src/components/SearchListField/tests/SearchListField.spec.ts +323 -0
- package/src/components/SearchListField/types.d.ts +4 -0
- package/src/components/SelectBtnField/SelectBtnField.mdx +50 -0
- package/src/components/SelectBtnField/SelectBtnField.stories.ts +763 -0
- package/src/components/SelectBtnField/SelectBtnField.vue +283 -0
- package/src/components/SelectBtnField/config.ts +11 -0
- package/src/components/SelectBtnField/tests/SelectBtnField.spec.ts +327 -0
- package/src/components/SelectBtnField/tests/__snapshots__/SelectBtnField.spec.ts.snap +125 -0
- package/src/components/SelectBtnField/types.d.ts +11 -0
- package/src/components/SkipLink/SkipLink.vue +10 -10
- package/src/components/SocialMediaLinks/SocialMediaLinks.vue +28 -26
- package/src/components/SubHeader/SubHeader.vue +32 -31
- package/src/components/SyAlert/SyAlert.vue +12 -12
- package/src/components/UserMenuBtn/UserMenuBtn.vue +1 -1
- package/src/components/UserMenuBtn/config.ts +1 -1
- package/src/components/index.ts +17 -7
- package/src/composables/rules/useFieldValidation.ts +172 -44
- package/src/designTokens/index.ts +6 -4
- package/src/designTokens/{bootstrapColors.md → paColors.md} +1 -1
- package/src/designTokens/tokens/cnam/cnamLightTheme.ts +2 -0
- package/src/designTokens/tokens/pa/paColors.ts +171 -0
- package/src/designTokens/tokens/pa/paContextual.ts +58 -0
- package/src/designTokens/tokens/pa/paDarkTheme.ts +5 -0
- package/src/designTokens/tokens/pa/paLightTheme.ts +123 -0
- package/src/designTokens/tokens/pa/paSemantic.ts +87 -0
- package/src/stories/Fondamentaux/CustomisationEtThemes.mdx +52 -2
- package/src/stories/GuideDuDev/CreerUneIssue.mdx +64 -0
- package/src/stories/GuideDuDev/{CommentUtiliserLesRules.mdx → UtiliserLesRules.mdx} +2 -2
- package/src/stories/GuideDuDev/components.stories.ts +9 -7
- package/src/stories/Guidelines/Vuetify/Vuetify.stories.ts +163 -88
- package/src/stories/Guidelines/Vuetify/VuetifyItems.ts +250 -23
- package/src/temp/TestDTComponent.vue +5 -6
- package/src/utils/calcHumanFileSize/index.ts +12 -0
- package/src/utils/calcHumanFileSize/tests/calcHumanFileSize.spec.ts +21 -0
- package/src/designTokens/tokens/bootstrap/bootstrapColors.ts +0 -158
- package/src/designTokens/tokens/bootstrap/bootstrapLightTheme.ts +0 -22
- package/src/stories/GuideDuDev/CommentContribuer.mdx +0 -22
|
@@ -0,0 +1,430 @@
|
|
|
1
|
+
import { fn } from '@storybook/test'
|
|
2
|
+
import type { Meta, StoryObj } from '@storybook/vue3'
|
|
3
|
+
|
|
4
|
+
import ContextualMenu from './ContextualMenu.vue'
|
|
5
|
+
import { ref, watch } from 'vue'
|
|
6
|
+
|
|
7
|
+
const meta = {
|
|
8
|
+
title: 'Composants/Navigation/ContextualMenu',
|
|
9
|
+
component: ContextualMenu,
|
|
10
|
+
decorators: [
|
|
11
|
+
() => ({
|
|
12
|
+
template: '<div style="padding: 20px;"><story/></div>',
|
|
13
|
+
}),
|
|
14
|
+
],
|
|
15
|
+
parameters: {
|
|
16
|
+
layout: 'fullscreen',
|
|
17
|
+
},
|
|
18
|
+
argTypes: {
|
|
19
|
+
'items': {
|
|
20
|
+
control: 'object',
|
|
21
|
+
description: 'Les éléments du menu',
|
|
22
|
+
table: {
|
|
23
|
+
type: {
|
|
24
|
+
summary: 'Array<{ text: string, hash: string, level?: 1 | 2 | 3 | 4 | 5 | 6 }>',
|
|
25
|
+
},
|
|
26
|
+
},
|
|
27
|
+
},
|
|
28
|
+
'modelValue': {
|
|
29
|
+
description: 'Le hash de l’élément actif',
|
|
30
|
+
control: 'text',
|
|
31
|
+
table: {
|
|
32
|
+
type: {
|
|
33
|
+
summary: 'string',
|
|
34
|
+
},
|
|
35
|
+
category: 'props',
|
|
36
|
+
},
|
|
37
|
+
},
|
|
38
|
+
'onUpdate:modelValue': {
|
|
39
|
+
description: 'Événement émis lorsqu’un élément est cliqué',
|
|
40
|
+
table: {
|
|
41
|
+
type: {
|
|
42
|
+
summary: 'string',
|
|
43
|
+
},
|
|
44
|
+
category: 'events',
|
|
45
|
+
},
|
|
46
|
+
},
|
|
47
|
+
},
|
|
48
|
+
} satisfies Meta<typeof ContextualMenu>
|
|
49
|
+
|
|
50
|
+
export default meta
|
|
51
|
+
|
|
52
|
+
type Story = StoryObj<typeof meta>
|
|
53
|
+
|
|
54
|
+
export const Default: Story = {
|
|
55
|
+
args: {
|
|
56
|
+
'items': [
|
|
57
|
+
{
|
|
58
|
+
text: 'Titre 1',
|
|
59
|
+
hash: '#example-1',
|
|
60
|
+
},
|
|
61
|
+
{
|
|
62
|
+
text: 'Titre 2',
|
|
63
|
+
hash: '#example-2',
|
|
64
|
+
},
|
|
65
|
+
{
|
|
66
|
+
text: 'Titre 3',
|
|
67
|
+
hash: '#example-3',
|
|
68
|
+
},
|
|
69
|
+
],
|
|
70
|
+
'modelValue': '#example-1',
|
|
71
|
+
'onUpdate:modelValue': fn(),
|
|
72
|
+
},
|
|
73
|
+
render: (args) => {
|
|
74
|
+
return {
|
|
75
|
+
components: { ContextualMenu },
|
|
76
|
+
setup() {
|
|
77
|
+
const hash = ref<string | null | undefined>()
|
|
78
|
+
watch(() => args.modelValue, (value) => {
|
|
79
|
+
hash.value = value
|
|
80
|
+
}, { immediate: true })
|
|
81
|
+
return { args, hash }
|
|
82
|
+
},
|
|
83
|
+
template: `
|
|
84
|
+
<ContextualMenu
|
|
85
|
+
v-bind="args"
|
|
86
|
+
v-model="hash"
|
|
87
|
+
/>
|
|
88
|
+
`,
|
|
89
|
+
}
|
|
90
|
+
},
|
|
91
|
+
parameters: {
|
|
92
|
+
sourceCode: [
|
|
93
|
+
{
|
|
94
|
+
name: 'Template',
|
|
95
|
+
code: `<template>
|
|
96
|
+
<ContextualMenu
|
|
97
|
+
:items="items"
|
|
98
|
+
/>
|
|
99
|
+
</template>
|
|
100
|
+
`,
|
|
101
|
+
},
|
|
102
|
+
{
|
|
103
|
+
name: 'Script',
|
|
104
|
+
code: `<script setup lang="ts">
|
|
105
|
+
import { ContextualMenu } from '@cnamts/synapse'
|
|
106
|
+
|
|
107
|
+
const items = [
|
|
108
|
+
{
|
|
109
|
+
text: 'Titre 1',
|
|
110
|
+
hash: '#example-1',
|
|
111
|
+
},
|
|
112
|
+
{
|
|
113
|
+
text: 'Titre 2',
|
|
114
|
+
hash: '#example-2',
|
|
115
|
+
},
|
|
116
|
+
{
|
|
117
|
+
text: 'Titre 3,
|
|
118
|
+
hash: '#example-3',
|
|
119
|
+
},
|
|
120
|
+
]
|
|
121
|
+
</script>
|
|
122
|
+
`,
|
|
123
|
+
},
|
|
124
|
+
],
|
|
125
|
+
},
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
export const WithAnchors: Story = {
|
|
129
|
+
args: {
|
|
130
|
+
'items': [{
|
|
131
|
+
text: 'section 1',
|
|
132
|
+
hash: '#section-1',
|
|
133
|
+
}, {
|
|
134
|
+
text: 'section 2',
|
|
135
|
+
hash: '#section-2',
|
|
136
|
+
}, {
|
|
137
|
+
text: 'section 3',
|
|
138
|
+
hash: '#section-3',
|
|
139
|
+
}, {
|
|
140
|
+
text: 'section 4',
|
|
141
|
+
hash: '#section-4',
|
|
142
|
+
}, {
|
|
143
|
+
text: 'section 5',
|
|
144
|
+
hash: '#section-5',
|
|
145
|
+
}],
|
|
146
|
+
'modelValue': '#section-1',
|
|
147
|
+
'onUpdate:modelValue': fn(),
|
|
148
|
+
},
|
|
149
|
+
render: (args) => {
|
|
150
|
+
return {
|
|
151
|
+
components: { ContextualMenu },
|
|
152
|
+
setup() {
|
|
153
|
+
const hash = ref<string | null | undefined>()
|
|
154
|
+
watch(() => args.modelValue, (value) => {
|
|
155
|
+
hash.value = value
|
|
156
|
+
}, { immediate: true })
|
|
157
|
+
return { args, hash }
|
|
158
|
+
},
|
|
159
|
+
template: `
|
|
160
|
+
<div style="display: flex; flex-direction: row; justify-content: space-evenly; padding-top: 20px; padding-bottom: 20px; place-items: center; width: 500px;">
|
|
161
|
+
<div style="width: 200px">
|
|
162
|
+
<ContextualMenu
|
|
163
|
+
v-bind="args"
|
|
164
|
+
v-model="hash"
|
|
165
|
+
/>
|
|
166
|
+
</div>
|
|
167
|
+
<div style="border: 1px solid black; max-height: 500px; overflow-y: auto; scroll-behavior: smooth;">
|
|
168
|
+
<section id="section-1" style="padding: 20px">
|
|
169
|
+
<h2>section 1</h2>
|
|
170
|
+
<p style="max-width: 300px">
|
|
171
|
+
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Alias, quae eligendi modi, rem consectetur cum labore voluptate nostrum molestiae asperiores dolorum, saepe perspiciatis quisquam provident placeat aut distinctio minima dolor.
|
|
172
|
+
Temporibus consequatur consectetur sequi. Sequi tempora velit soluta? Nam error, nesciunt molestiae provident possimus voluptas tempore porro at officia sint exercitationem dolore debitis eaque temporibus accusantium soluta? In, maxime excepturi.
|
|
173
|
+
</p>
|
|
174
|
+
</section>
|
|
175
|
+
<section id="section-2" style="padding: 20px">
|
|
176
|
+
<h2>section 2</h2>
|
|
177
|
+
<p style="max-width: 300px">
|
|
178
|
+
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Alias, quae eligendi modi, rem consectetur cum labore voluptate nostrum molestiae asperiores dolorum, saepe perspiciatis quisquam provident placeat aut distinctio minima dolor.
|
|
179
|
+
Temporibus consequatur consectetur sequi. Sequi tempora velit soluta? Nam error, nesciunt molestiae provident possimus voluptas tempore porro at officia sint exercitationem dolore debitis eaque temporibus accusantium soluta? In, maxime excepturi.
|
|
180
|
+
</p>
|
|
181
|
+
</section>
|
|
182
|
+
<section id="section-3" style="padding: 20px">
|
|
183
|
+
<h2>section 3</h2>
|
|
184
|
+
<p style="max-width: 300px">
|
|
185
|
+
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Alias, quae eligendi modi, rem consectetur cum labore voluptate nostrum molestiae asperiores dolorum, saepe perspiciatis quisquam provident placeat aut distinctio minima dolor.
|
|
186
|
+
Temporibus consequatur consectetur sequi. Sequi tempora velit soluta? Nam error, nesciunt molestiae provident possimus voluptas tempore porro at officia sint exercitationem dolore debitis eaque temporibus accusantium soluta? In, maxime excepturi.
|
|
187
|
+
</p>
|
|
188
|
+
</section>
|
|
189
|
+
<section id="section-4" style="padding: 20px">
|
|
190
|
+
<h2>section 4</h2>
|
|
191
|
+
<p style="max-width: 300px">
|
|
192
|
+
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Alias, quae eligendi modi, rem consectetur cum labore voluptate nostrum molestiae asperiores dolorum, saepe perspiciatis quisquam provident placeat aut distinctio minima dolor.
|
|
193
|
+
Temporibus consequatur consectetur sequi. Sequi tempora velit soluta? Nam error, nesciunt molestiae provident possimus voluptas tempore porro at officia sint exercitationem dolore debitis eaque temporibus accusantium soluta? In, maxime excepturi.
|
|
194
|
+
</p>
|
|
195
|
+
</section>
|
|
196
|
+
<section id="section-5" style="padding: 20px">
|
|
197
|
+
<h2>section 5</h2>
|
|
198
|
+
<p style="max-width: 300px">
|
|
199
|
+
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Alias, quae eligendi modi, rem consectetur cum labore voluptate nostrum molestiae asperiores dolorum, saepe perspiciatis quisquam provident placeat aut distinctio minima dolor.
|
|
200
|
+
Temporibus consequatur consectetur sequi. Sequi tempora velit soluta? Nam error, nesciunt molestiae provident possimus voluptas tempore porro at officia sint exercitationem dolore debitis eaque temporibus accusantium soluta? In, maxime excepturi.
|
|
201
|
+
</p>
|
|
202
|
+
</section>
|
|
203
|
+
</div>
|
|
204
|
+
</div>
|
|
205
|
+
`,
|
|
206
|
+
}
|
|
207
|
+
},
|
|
208
|
+
parameters: {
|
|
209
|
+
sourceCode: [
|
|
210
|
+
{
|
|
211
|
+
name: 'Template',
|
|
212
|
+
code: `<template>
|
|
213
|
+
<div class="wrapper">
|
|
214
|
+
<div class="menu">
|
|
215
|
+
<ContextualMenu
|
|
216
|
+
v-model="hash"
|
|
217
|
+
:items
|
|
218
|
+
/>
|
|
219
|
+
</div>
|
|
220
|
+
<div class="content">
|
|
221
|
+
<section id="section-1">
|
|
222
|
+
<h2>section 1</h2>
|
|
223
|
+
<p>
|
|
224
|
+
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Alias, quae eligendi modi, rem consectetur cum labore voluptate nostrum molestiae asperiores dolorum, saepe perspiciatis quisquam provident placeat aut distinctio minima dolor.
|
|
225
|
+
Temporibus consequatur consectetur sequi. Sequi tempora velit soluta? Nam error, nesciunt molestiae provident possimus voluptas tempore porro at officia sint exercitationem dolore debitis eaque temporibus accusantium soluta? In, maxime excepturi.
|
|
226
|
+
</p>
|
|
227
|
+
</section>
|
|
228
|
+
<section id="section-2">
|
|
229
|
+
<h2>section 2</h2>
|
|
230
|
+
<p>
|
|
231
|
+
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Alias, quae eligendi modi, rem consectetur cum labore voluptate nostrum molestiae asperiores dolorum, saepe perspiciatis quisquam provident placeat aut distinctio minima dolor.
|
|
232
|
+
Temporibus consequatur consectetur sequi. Sequi tempora velit soluta? Nam error, nesciunt molestiae provident possimus voluptas tempore porro at officia sint exercitationem dolore debitis eaque temporibus accusantium soluta? In, maxime excepturi.
|
|
233
|
+
</p>
|
|
234
|
+
</section>
|
|
235
|
+
<section id="section-3">
|
|
236
|
+
<h2>section 3</h2>
|
|
237
|
+
<p>
|
|
238
|
+
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Alias, quae eligendi modi, rem consectetur cum labore voluptate nostrum molestiae asperiores dolorum, saepe perspiciatis quisquam provident placeat aut distinctio minima dolor.
|
|
239
|
+
Temporibus consequatur consectetur sequi. Sequi tempora velit soluta? Nam error, nesciunt molestiae provident possimus voluptas tempore porro at officia sint exercitationem dolore debitis eaque temporibus accusantium soluta? In, maxime excepturi.
|
|
240
|
+
</p>
|
|
241
|
+
</section>
|
|
242
|
+
<section id="section-4">
|
|
243
|
+
<h2>section 4</h2>
|
|
244
|
+
<p>
|
|
245
|
+
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Alias, quae eligendi modi, rem consectetur cum labore voluptate nostrum molestiae asperiores dolorum, saepe perspiciatis quisquam provident placeat aut distinctio minima dolor.
|
|
246
|
+
Temporibus consequatur consectetur sequi. Sequi tempora velit soluta? Nam error, nesciunt molestiae provident possimus voluptas tempore porro at officia sint exercitationem dolore debitis eaque temporibus accusantium soluta? In, maxime excepturi.
|
|
247
|
+
</p>
|
|
248
|
+
</section>
|
|
249
|
+
<section id="section-5">
|
|
250
|
+
<h2>section 5</h2>
|
|
251
|
+
<p>
|
|
252
|
+
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Alias, quae eligendi modi, rem consectetur cum labore voluptate nostrum molestiae asperiores dolorum, saepe perspiciatis quisquam provident placeat aut distinctio minima dolor.
|
|
253
|
+
Temporibus consequatur consectetur sequi. Sequi tempora velit soluta? Nam error, nesciunt molestiae provident possimus voluptas tempore porro at officia sint exercitationem dolore debitis eaque temporibus accusantium soluta? In, maxime excepturi.
|
|
254
|
+
</p>
|
|
255
|
+
</section>
|
|
256
|
+
</div>
|
|
257
|
+
</div>
|
|
258
|
+
</template>
|
|
259
|
+
`,
|
|
260
|
+
},
|
|
261
|
+
{
|
|
262
|
+
name: 'Script',
|
|
263
|
+
code: `<script setup lang="ts">
|
|
264
|
+
import { ContextualMenu } from '@cnamts/synapse'
|
|
265
|
+
import { ref } from 'vue'
|
|
266
|
+
|
|
267
|
+
const items = [{
|
|
268
|
+
text: 'section 1',
|
|
269
|
+
hash: '#section-1',
|
|
270
|
+
}, {
|
|
271
|
+
text: 'section 2',
|
|
272
|
+
hash: '#section-2',
|
|
273
|
+
}, {
|
|
274
|
+
text: 'section 3',
|
|
275
|
+
hash: '#section-3',
|
|
276
|
+
}, {
|
|
277
|
+
text: 'section 4',
|
|
278
|
+
hash: '#section-4',
|
|
279
|
+
}, {
|
|
280
|
+
text: 'section 5',
|
|
281
|
+
hash: '#section-5',
|
|
282
|
+
}]
|
|
283
|
+
|
|
284
|
+
const hash = ref<string | null>(null)
|
|
285
|
+
</script>
|
|
286
|
+
`,
|
|
287
|
+
},
|
|
288
|
+
{
|
|
289
|
+
name: 'Style',
|
|
290
|
+
code: `<style lang="scss" scoped>
|
|
291
|
+
.wrapper {
|
|
292
|
+
display: flex;
|
|
293
|
+
flex-direction: row;
|
|
294
|
+
justify-content: space-evenly;
|
|
295
|
+
place-items: center;
|
|
296
|
+
height: 100dvh;
|
|
297
|
+
width: 500px;
|
|
298
|
+
}
|
|
299
|
+
.menu {
|
|
300
|
+
width: 200px;
|
|
301
|
+
}
|
|
302
|
+
.content {
|
|
303
|
+
border: 1px solid black;
|
|
304
|
+
height: 500px;
|
|
305
|
+
overflow-y: auto;
|
|
306
|
+
scroll-behavior: smooth;
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
section {
|
|
310
|
+
padding: 20px;
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
section p {
|
|
314
|
+
max-width: 300px;
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
</style>
|
|
318
|
+
`,
|
|
319
|
+
},
|
|
320
|
+
],
|
|
321
|
+
},
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
export const levels: Story = {
|
|
325
|
+
args: {
|
|
326
|
+
'items': [
|
|
327
|
+
{
|
|
328
|
+
text: 'Level 1',
|
|
329
|
+
hash: '#example-1',
|
|
330
|
+
},
|
|
331
|
+
{
|
|
332
|
+
text: 'Level 2',
|
|
333
|
+
hash: '#example-2',
|
|
334
|
+
level: 2,
|
|
335
|
+
},
|
|
336
|
+
{
|
|
337
|
+
text: 'Level 3',
|
|
338
|
+
hash: '#example-3',
|
|
339
|
+
level: 3,
|
|
340
|
+
},
|
|
341
|
+
{
|
|
342
|
+
text: 'Level 4',
|
|
343
|
+
hash: '#example-4',
|
|
344
|
+
level: 4,
|
|
345
|
+
},
|
|
346
|
+
{
|
|
347
|
+
text: 'Level 5',
|
|
348
|
+
hash: '#example-5',
|
|
349
|
+
level: 5,
|
|
350
|
+
},
|
|
351
|
+
{
|
|
352
|
+
text: 'Level 6',
|
|
353
|
+
hash: '#example-6',
|
|
354
|
+
level: 6,
|
|
355
|
+
},
|
|
356
|
+
],
|
|
357
|
+
'modelValue': '#example-1',
|
|
358
|
+
'onUpdate:modelValue': fn(),
|
|
359
|
+
},
|
|
360
|
+
render: (args) => {
|
|
361
|
+
return {
|
|
362
|
+
components: { ContextualMenu },
|
|
363
|
+
setup() {
|
|
364
|
+
const hash = ref<string | null | undefined>()
|
|
365
|
+
watch(() => args.modelValue, (value) => {
|
|
366
|
+
hash.value = value
|
|
367
|
+
}, { immediate: true })
|
|
368
|
+
return { args, hash }
|
|
369
|
+
},
|
|
370
|
+
template: `
|
|
371
|
+
<ContextualMenu
|
|
372
|
+
v-bind="args"
|
|
373
|
+
v-model="hash"
|
|
374
|
+
/>
|
|
375
|
+
`,
|
|
376
|
+
}
|
|
377
|
+
},
|
|
378
|
+
parameters: {
|
|
379
|
+
sourceCode: [
|
|
380
|
+
{
|
|
381
|
+
name: 'Template',
|
|
382
|
+
code: `<template>
|
|
383
|
+
<ContextualMenu
|
|
384
|
+
:items="items"
|
|
385
|
+
/>
|
|
386
|
+
</template>
|
|
387
|
+
`,
|
|
388
|
+
},
|
|
389
|
+
{
|
|
390
|
+
name: 'Script',
|
|
391
|
+
code: `<script setup lang="ts">
|
|
392
|
+
import { ContextualMenu } from '@cnamts/synapse'
|
|
393
|
+
|
|
394
|
+
const items = [
|
|
395
|
+
{
|
|
396
|
+
text: 'Level 1',
|
|
397
|
+
hash: '#example-1',
|
|
398
|
+
},
|
|
399
|
+
{
|
|
400
|
+
text: 'Level 2',
|
|
401
|
+
hash: '#example-2',
|
|
402
|
+
level: 2,
|
|
403
|
+
},
|
|
404
|
+
{
|
|
405
|
+
text: 'Level 3',
|
|
406
|
+
hash: '#example-3',
|
|
407
|
+
level: 3,
|
|
408
|
+
},
|
|
409
|
+
{
|
|
410
|
+
text: 'Level 4',
|
|
411
|
+
hash: '#example-4',
|
|
412
|
+
level: 4,
|
|
413
|
+
},
|
|
414
|
+
{
|
|
415
|
+
text: 'Level 5',
|
|
416
|
+
hash: '#example-5',
|
|
417
|
+
level: 5,
|
|
418
|
+
},
|
|
419
|
+
{
|
|
420
|
+
text: 'Level 6',
|
|
421
|
+
hash: '#example-6',
|
|
422
|
+
level: 6,
|
|
423
|
+
},
|
|
424
|
+
]
|
|
425
|
+
</script>
|
|
426
|
+
`,
|
|
427
|
+
},
|
|
428
|
+
],
|
|
429
|
+
},
|
|
430
|
+
}
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import { type MenuItem } from './types'
|
|
3
|
+
import { onMounted, watch } from 'vue'
|
|
4
|
+
|
|
5
|
+
const model = defineModel<string | null>()
|
|
6
|
+
|
|
7
|
+
defineProps<{
|
|
8
|
+
items: MenuItem[]
|
|
9
|
+
}>()
|
|
10
|
+
|
|
11
|
+
onMounted(() => {
|
|
12
|
+
if (!model.value && window.location.hash) {
|
|
13
|
+
model.value = window.location.hash
|
|
14
|
+
}
|
|
15
|
+
addEventListener('hashchange', () => {
|
|
16
|
+
model.value = window.location.hash
|
|
17
|
+
})
|
|
18
|
+
})
|
|
19
|
+
|
|
20
|
+
watch(
|
|
21
|
+
model,
|
|
22
|
+
(newValue, oldValue) => {
|
|
23
|
+
if (newValue && newValue !== oldValue) {
|
|
24
|
+
setHash(newValue)
|
|
25
|
+
}
|
|
26
|
+
},
|
|
27
|
+
{ immediate: true },
|
|
28
|
+
)
|
|
29
|
+
|
|
30
|
+
function setHash(hash: string) {
|
|
31
|
+
if (window.location.hash === hash) {
|
|
32
|
+
return
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
window.location.hash = hash
|
|
36
|
+
model.value = hash
|
|
37
|
+
}
|
|
38
|
+
</script>
|
|
39
|
+
|
|
40
|
+
<template>
|
|
41
|
+
<ul
|
|
42
|
+
v-if="items.length"
|
|
43
|
+
class="vd-contextual-menu"
|
|
44
|
+
>
|
|
45
|
+
<li
|
|
46
|
+
v-for="{ text, hash, level } in items"
|
|
47
|
+
:key="hash"
|
|
48
|
+
>
|
|
49
|
+
<a
|
|
50
|
+
:href="hash"
|
|
51
|
+
:class="{
|
|
52
|
+
'text-primary active': model === hash,
|
|
53
|
+
'text-medium-emphasis': model !== hash,
|
|
54
|
+
'ps-4': level === 2,
|
|
55
|
+
'ps-6': level === 3,
|
|
56
|
+
'ps-9': level === 4,
|
|
57
|
+
'ps-12': level === 5,
|
|
58
|
+
'ps-14': level === 6,
|
|
59
|
+
}"
|
|
60
|
+
class="d-flex align-center text-decoration-none text-body-1 px-4 py-2"
|
|
61
|
+
@click.prevent.stop="setHash(hash)"
|
|
62
|
+
v-text="text"
|
|
63
|
+
/>
|
|
64
|
+
</li>
|
|
65
|
+
</ul>
|
|
66
|
+
</template>
|
|
67
|
+
|
|
68
|
+
<style lang="scss" scoped>
|
|
69
|
+
ul {
|
|
70
|
+
list-style: none;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
a {
|
|
74
|
+
position: relative;
|
|
75
|
+
transition: none;
|
|
76
|
+
|
|
77
|
+
&::before {
|
|
78
|
+
content: '';
|
|
79
|
+
width: 2px;
|
|
80
|
+
background: rgb(0 0 0 / 60%);
|
|
81
|
+
position: absolute;
|
|
82
|
+
left: 0;
|
|
83
|
+
height: 100%;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
&::after {
|
|
87
|
+
content: '';
|
|
88
|
+
width: 4px;
|
|
89
|
+
border-radius: 0 2px 2px 0;
|
|
90
|
+
background: currentcolor;
|
|
91
|
+
position: absolute;
|
|
92
|
+
left: 0;
|
|
93
|
+
height: 100%;
|
|
94
|
+
opacity: 0;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
&.active::after {
|
|
98
|
+
opacity: 1;
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
</style>
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
import { describe, it, expect } from 'vitest'
|
|
2
|
+
import { mount } from '@vue/test-utils'
|
|
3
|
+
|
|
4
|
+
import ContextualMenu from '../ContextualMenu.vue'
|
|
5
|
+
import { vuetify } from '@tests/unit/setup'
|
|
6
|
+
|
|
7
|
+
describe('ContextualMenu', () => {
|
|
8
|
+
it('renders correctly with items', () => {
|
|
9
|
+
const wrapper = mount(ContextualMenu, {
|
|
10
|
+
global: {
|
|
11
|
+
plugins: [vuetify],
|
|
12
|
+
},
|
|
13
|
+
props: {
|
|
14
|
+
items: [
|
|
15
|
+
{
|
|
16
|
+
text: 'Titre 1',
|
|
17
|
+
hash: '#example-1',
|
|
18
|
+
},
|
|
19
|
+
{
|
|
20
|
+
text: 'Titre 2',
|
|
21
|
+
hash: '#example-2',
|
|
22
|
+
},
|
|
23
|
+
],
|
|
24
|
+
},
|
|
25
|
+
})
|
|
26
|
+
|
|
27
|
+
expect(wrapper.html()).toMatchSnapshot()
|
|
28
|
+
})
|
|
29
|
+
|
|
30
|
+
it('renders correctly without items', () => {
|
|
31
|
+
const wrapper = mount(ContextualMenu, {
|
|
32
|
+
global: {
|
|
33
|
+
plugins: [vuetify],
|
|
34
|
+
},
|
|
35
|
+
props: {
|
|
36
|
+
items: [],
|
|
37
|
+
},
|
|
38
|
+
})
|
|
39
|
+
|
|
40
|
+
expect(wrapper.html()).toMatchSnapshot()
|
|
41
|
+
})
|
|
42
|
+
|
|
43
|
+
it('emit an update:modelValue event when an item is updated', async () => {
|
|
44
|
+
const wrapper = mount(ContextualMenu, {
|
|
45
|
+
global: {
|
|
46
|
+
plugins: [vuetify],
|
|
47
|
+
},
|
|
48
|
+
props: {
|
|
49
|
+
items: [
|
|
50
|
+
{
|
|
51
|
+
text: 'Titre 1',
|
|
52
|
+
hash: '#example-1',
|
|
53
|
+
},
|
|
54
|
+
{
|
|
55
|
+
text: 'Titre 2',
|
|
56
|
+
hash: '#example-2',
|
|
57
|
+
},
|
|
58
|
+
],
|
|
59
|
+
},
|
|
60
|
+
})
|
|
61
|
+
|
|
62
|
+
await wrapper.find('a').trigger('click')
|
|
63
|
+
|
|
64
|
+
expect(wrapper.emitted('update:modelValue')?.[0]).toEqual(['#example-1'])
|
|
65
|
+
})
|
|
66
|
+
|
|
67
|
+
it('update the highlighted item when the modelValue is updated', async () => {
|
|
68
|
+
const wrapper = mount(ContextualMenu, {
|
|
69
|
+
global: {
|
|
70
|
+
plugins: [vuetify],
|
|
71
|
+
},
|
|
72
|
+
props: {
|
|
73
|
+
items: [
|
|
74
|
+
{
|
|
75
|
+
text: 'Titre 1',
|
|
76
|
+
hash: '#example-1',
|
|
77
|
+
},
|
|
78
|
+
{
|
|
79
|
+
text: 'Titre 2',
|
|
80
|
+
hash: '#example-2',
|
|
81
|
+
},
|
|
82
|
+
],
|
|
83
|
+
modelValue: '#example-2',
|
|
84
|
+
},
|
|
85
|
+
})
|
|
86
|
+
|
|
87
|
+
expect(wrapper.find('[href="#example-2"]').classes()).toContain('active')
|
|
88
|
+
})
|
|
89
|
+
|
|
90
|
+
it('initialize with the content of location.href', async () => {
|
|
91
|
+
window.location.hash = '#example-2'
|
|
92
|
+
|
|
93
|
+
const wrapper = mount(ContextualMenu, {
|
|
94
|
+
global: {
|
|
95
|
+
plugins: [vuetify],
|
|
96
|
+
},
|
|
97
|
+
props: {
|
|
98
|
+
items: [
|
|
99
|
+
{
|
|
100
|
+
text: 'Titre 1',
|
|
101
|
+
hash: '#example-1',
|
|
102
|
+
},
|
|
103
|
+
{
|
|
104
|
+
text: 'Titre 2',
|
|
105
|
+
hash: '#example-2',
|
|
106
|
+
},
|
|
107
|
+
],
|
|
108
|
+
},
|
|
109
|
+
})
|
|
110
|
+
|
|
111
|
+
await wrapper.vm.$nextTick()
|
|
112
|
+
expect(wrapper.find('[href="#example-2"]').classes()).toContain('active')
|
|
113
|
+
expect(wrapper.emitted('update:modelValue')?.[0]).toEqual(['#example-2'])
|
|
114
|
+
})
|
|
115
|
+
})
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
|
|
2
|
+
|
|
3
|
+
exports[`ContextualMenu > renders correctly with items 1`] = `
|
|
4
|
+
"<ul data-v-b65f24a2="" class="vd-contextual-menu">
|
|
5
|
+
<li data-v-b65f24a2=""><a data-v-b65f24a2="" href="#example-1" class="text-medium-emphasis d-flex align-center text-decoration-none text-body-1 px-4 py-2">Titre 1</a></li>
|
|
6
|
+
<li data-v-b65f24a2=""><a data-v-b65f24a2="" href="#example-2" class="text-medium-emphasis d-flex align-center text-decoration-none text-body-1 px-4 py-2">Titre 2</a></li>
|
|
7
|
+
</ul>"
|
|
8
|
+
`;
|
|
9
|
+
|
|
10
|
+
exports[`ContextualMenu > renders correctly without items 1`] = `"<!--v-if-->"`;
|
|
@@ -617,7 +617,6 @@ export const Customization: Story = {
|
|
|
617
617
|
@reject="onReject"
|
|
618
618
|
@customize="onCustomize"
|
|
619
619
|
v-model="modelValue"
|
|
620
|
-
:cookiesRoute="cookiesRoute"
|
|
621
620
|
:vuetifyOptions="vuetifyOptions"
|
|
622
621
|
/>
|
|
623
622
|
</template>`,
|
|
@@ -659,7 +658,7 @@ export const Customization: Story = {
|
|
|
659
658
|
}
|
|
660
659
|
|
|
661
660
|
const vuetifyOptions = {
|
|
662
|
-
|
|
661
|
+
banner: {
|
|
663
662
|
color: '#ced9eb',
|
|
664
663
|
},
|
|
665
664
|
customizeBtn: {
|