@cnamts/synapse 1.1.0 → 1.1.1
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/{AutocompleteFilter-DXd4szWO.js → AutocompleteFilter-CGF33skz.js} +1 -1
- package/dist/{DateFilter-BD59Kgwf.js → DateFilter-D7-MsKtx.js} +1 -1
- package/dist/{NumberFilter-BSMZE7uw.js → NumberFilter-bjQPPfsj.js} +1 -1
- package/dist/{PeriodFilter-keUdSSk0.js → PeriodFilter-B3wJpK8-.js} +1 -1
- package/dist/{SelectFilter-Dhvvwazl.js → SelectFilter-BN6DbKAV.js} +1 -1
- package/dist/{TextFilter-CU8FpXz0.js → TextFilter-BffP0J2f.js} +1 -1
- package/dist/{apLightTheme2026-DbS7BPUf.js → apLightTheme2026-C4ygwMHC.js} +11 -11
- package/dist/components/Amelipro/AmeliproAutoCompleteField/AmeliproAutoCompleteField.d.ts +6 -6
- package/dist/components/Amelipro/AmeliproSelect/AmeliproSelect.d.ts +6 -6
- package/dist/components/Amelipro/AmeliproTabs/AmeliproTabs.d.ts +6 -6
- package/dist/components/Captcha/Captcha.d.ts +27 -16
- package/dist/components/Captcha/CaptchaForm.d.ts +29 -3
- package/dist/components/Captcha/types.d.ts +14 -0
- package/dist/components/Captcha/useCaptchaValidation.d.ts +37 -0
- package/dist/components/Customs/Selects/SelectBtnField/SelectBtnField.d.ts +33 -13
- package/dist/components/Customs/Selects/SelectBtnField/composables/useSelectBtnFieldValidation.d.ts +23 -0
- package/dist/components/Customs/Selects/SyAutocomplete/composables/useSyAutocompleteValidation.d.ts +2 -2
- package/dist/components/Customs/Selects/SySelect/composables/useSySelectValidation.d.ts +2 -2
- package/dist/components/Customs/SyCheckBoxGroup/SyCheckBoxGroup.d.ts +17 -48
- package/dist/components/Customs/SyCheckBoxGroup/composables/useSyCheckBoxGroupValidation.d.ts +29 -0
- package/dist/components/Customs/SyCheckBoxGroup/types.d.ts +46 -0
- package/dist/components/Customs/SyCheckbox/SyCheckbox.d.ts +16 -51
- package/dist/components/Customs/SyCheckbox/composables/useSyCheckboxValidation.d.ts +27 -0
- package/dist/components/Customs/SyCheckbox/types.d.ts +49 -0
- package/dist/components/Customs/SyTextField/FieldState.d.ts +5 -0
- package/dist/components/Customs/SyTextField/useSyTextFieldValidation.d.ts +3 -3
- package/dist/components/DialogBox/DialogBox.d.ts +2 -0
- package/dist/components/DialogBox/locales.d.ts +1 -0
- package/dist/components/FilterSideBar/FilterSideBar.d.ts +4 -0
- package/dist/components/LunarCalendar/LunarCalendar.d.ts +43 -14
- package/dist/components/LunarCalendar/types.d.ts +35 -0
- package/dist/components/LunarCalendar/useLunarCalendarValidation.d.ts +11 -12
- package/dist/components/MonthPicker/MonthPicker.d.ts +72 -1747
- package/dist/components/MonthPicker/MonthPickerText/MonthPickerInput.d.ts +21 -1733
- package/dist/components/MonthPicker/MonthPickerText/useTextField.d.ts +5 -0
- package/dist/components/MonthPicker/locales.d.ts +1 -0
- package/dist/components/MonthPicker/types.d.ts +11 -0
- package/dist/components/MonthPicker/useMonthPickerValidation.d.ts +37 -24
- package/dist/components/NirField/NirField.d.ts +6 -4
- package/dist/components/NirField/useNirValidation.d.ts +7 -5
- package/dist/components/PageContainer/PageContainer.d.ts +8 -0
- package/dist/components/PasswordField/PasswordField.d.ts +2 -2
- package/dist/components/PasswordField/usePasswordFieldValidation.d.ts +2 -2
- package/dist/components/PhoneField/PhoneField.d.ts +960 -1938
- package/dist/components/PhoneField/indicatifs.d.ts +715 -8
- package/dist/components/PhoneField/locales.d.ts +7 -0
- package/dist/components/PhoneField/types.d.ts +29 -0
- package/dist/components/PhoneField/usePhoneFieldValidation.d.ts +45 -0
- package/dist/components/PhoneField/usePhoneIndicatifs.d.ts +947 -0
- package/dist/components/SyTextArea/composables/useSyTextAreaValidation.d.ts +2 -2
- package/dist/composables/unifyValidation/documentationValidationProps.d.ts +1 -1
- package/dist/composables/unifyValidation/useValidation.d.ts +4 -5
- package/dist/design-system-v3.js +2 -2
- package/dist/designTokens/tokens/amelipro/apLightTheme.d.ts +10 -10
- package/dist/designTokens/tokens/baseTokens.d.ts +18 -18
- package/dist/designTokens/tokens/cnam/cnamLightTheme.d.ts +10 -10
- package/dist/designTokens/tokens/pa/paLightTheme.d.ts +10 -10
- package/dist/designTokens/tokens/semanticTokens.d.ts +14 -14
- package/dist/{main-D8ryUoS5.js → main-C4wAktOs.js} +13718 -12991
- package/dist/synapse.css +1 -1
- package/dist/vuetifyConfig.js +1 -1
- package/package.json +7 -7
- package/src/assets/compat/_legacy-tokens.scss +91 -0
- package/src/assets/overrides/_utilities.scss +23 -0
- package/src/components/Accordion/Accordion.stories.ts +121 -1
- package/src/components/BackBtn/BackBtn.mdx +1 -1
- package/src/components/BackToTopBtn/BackToTopBtn.mdx +0 -1
- package/src/components/Captcha/Captcha.stories.ts +134 -31
- package/src/components/Captcha/Captcha.vue +95 -28
- package/src/components/Captcha/CaptchaForm.vue +51 -22
- package/src/components/Captcha/tests/Captcha.focus.spec.ts +214 -0
- package/src/components/Captcha/tests/Captcha.spec.ts +233 -24
- package/src/components/Captcha/tests/CaptchaForm.spec.ts +82 -0
- package/src/components/Captcha/tests/__snapshots__/Captcha.spec.ts.snap +16 -42
- package/src/components/Captcha/types.ts +15 -0
- package/src/components/Captcha/useCaptchaValidation.ts +87 -0
- package/src/components/Captcha/validation/validation.stories.ts +1194 -0
- package/src/components/ChipList/ChipList.mdx +0 -1
- package/src/components/CollapsibleList/CollapsibleList.mdx +0 -1
- package/src/components/CookieBanner/CookieBanner.mdx +0 -1
- package/src/components/CopyBtn/CopyBtn.mdx +0 -1
- package/src/components/Customs/Selects/SelectBtnField/SelectBtnField.stories.ts +123 -439
- package/src/components/Customs/Selects/SelectBtnField/SelectBtnField.vue +147 -41
- package/src/components/Customs/Selects/SelectBtnField/Validation/Validation.stories.ts +600 -0
- package/src/components/Customs/Selects/SelectBtnField/composables/useSelectBtnFieldValidation.ts +87 -0
- package/src/components/Customs/Selects/SelectBtnField/tests/SelectBtnField.spec.ts +402 -33
- package/src/components/Customs/Selects/SelectBtnField/tests/__snapshots__/SelectBtnField.spec.ts.snap +52 -38
- package/src/components/Customs/SyCheckBoxGroup/SyCheckBoxGroup.stories.ts +342 -162
- package/src/components/Customs/SyCheckBoxGroup/SyCheckBoxGroup.vue +77 -129
- package/src/components/Customs/SyCheckBoxGroup/Validation/Validation.stories.ts +1008 -0
- package/src/components/Customs/SyCheckBoxGroup/composables/useSyCheckBoxGroupValidation.ts +107 -0
- package/src/components/Customs/SyCheckBoxGroup/tests/SyCheckBoxGroup.spec.ts +180 -7
- package/src/components/Customs/SyCheckBoxGroup/types.ts +49 -0
- package/src/components/Customs/SyCheckbox/SyCheckbox.stories.ts +41 -161
- package/src/components/Customs/SyCheckbox/SyCheckbox.vue +71 -148
- package/src/components/Customs/SyCheckbox/Validation/Validation.stories.ts +654 -0
- package/src/components/Customs/SyCheckbox/composables/useSyCheckboxValidation.ts +105 -0
- package/src/components/Customs/SyCheckbox/tests/SyCheckbox.spec.ts +106 -0
- package/src/components/Customs/SyCheckbox/tests/useSyCheckboxValidation.spec.ts +98 -0
- package/src/components/Customs/SyCheckbox/types.ts +51 -0
- package/src/components/Customs/SyTextField/FieldState.vue +50 -0
- package/src/components/Customs/SyTextField/SyTextField.vue +12 -9
- package/src/components/Customs/SyTextField/useSyTextFieldValidation.ts +2 -11
- package/src/components/DataList/DataList.mdx +0 -1
- package/src/components/DataListGroup/DataListGroup.mdx +0 -1
- package/src/components/DiacriticPicker/DiacriticPicker.mdx +0 -1
- package/src/components/DialogBox/DialogBox.mdx +0 -1
- package/src/components/DialogBox/DialogBox.stories.ts +399 -4
- package/src/components/DialogBox/DialogBox.vue +20 -0
- package/src/components/DialogBox/locales.ts +1 -0
- package/src/components/DialogBox/tests/DialogBox.spec.ts +73 -0
- package/src/components/DialogBox/tests/DialogBox.visual.cy.ts +24 -0
- package/src/components/ErrorPage/ErrorPage.mdx +1 -1
- package/src/components/ExternalLinks/ExternalLinks.mdx +0 -1
- package/src/components/FileList/FileList.mdx +0 -1
- package/src/components/FilterInline/FilterInline.mdx +0 -1
- package/src/components/FilterSideBar/FilterSideBar.mdx +8 -1
- package/src/components/FilterSideBar/FilterSideBar.stories.ts +133 -1
- package/src/components/FilterSideBar/FilterSideBar.vue +19 -2
- package/src/components/FilterSideBar/tests/FilterSideBar.spec.ts +55 -0
- package/src/components/FooterBar/FooterBar.mdx +0 -1
- package/src/components/FranceConnectBtn/FranceConnectBtn.mdx +0 -1
- package/src/components/HeaderBar/HeaderBar.mdx +0 -1
- package/src/components/HeaderLoading/HeaderLoading.mdx +0 -1
- package/src/components/LangBtn/LangBtn.mdx +0 -1
- package/src/components/Logo/Logo.mdx +1 -1
- package/src/components/LunarCalendar/LunarCalendar.mdx +6 -9
- package/src/components/LunarCalendar/LunarCalendar.stories.ts +243 -46
- package/src/components/LunarCalendar/LunarCalendar.vue +61 -26
- package/src/components/LunarCalendar/Validation/Validation.stories.ts +717 -0
- package/src/components/LunarCalendar/tests/LunarCalendar.a11y.spec.ts +1 -1
- package/src/components/LunarCalendar/tests/LunarCalendar.spec.ts +197 -6
- package/src/components/LunarCalendar/tests/useLunarCalendarValidation.spec.ts +287 -0
- package/src/components/LunarCalendar/types.ts +39 -0
- package/src/components/LunarCalendar/useLunarCalendarValidation.ts +115 -39
- package/src/components/MonthPicker/MonthPicker.stories.ts +38 -281
- package/src/components/MonthPicker/MonthPicker.vue +66 -17
- package/src/components/MonthPicker/MonthPickerText/MonthPickerInput.vue +44 -20
- package/src/components/MonthPicker/MonthPickerText/useTextField.ts +5 -0
- package/src/components/MonthPicker/Validation/Validation.stories.ts +1117 -0
- package/src/components/MonthPicker/locales.ts +1 -0
- package/src/components/MonthPicker/tests/MonthPicker.spec.ts +353 -2
- package/src/components/MonthPicker/tests/__snapshots__/MonthPicker.spec.ts.snap +12 -8
- package/src/components/MonthPicker/types.ts +16 -0
- package/src/components/MonthPicker/useMonthPickerValidation.ts +64 -27
- package/src/components/NirField/NirField.mdx +120 -66
- package/src/components/NirField/NirField.stories.ts +216 -0
- package/src/components/NirField/useNirValidation.ts +16 -17
- package/src/components/NotFoundPage/tests/__snapshots__/NotFoundPage.spec.ts.snap +263 -245
- package/src/components/NotificationBar/NotificationBar.mdx +0 -1
- package/src/components/PageContainer/PageContainer.mdx +0 -1
- package/src/components/PageContainer/PageContainer.stories.ts +170 -2
- package/src/components/PageContainer/PageContainer.vue +63 -8
- package/src/components/PageContainer/tests/__snapshots__/PageContainer.spec.ts.snap +19 -11
- package/src/components/PaginatedTable/PaginatedTable.mdx +0 -1
- package/src/components/PeriodField/PeriodField.mdx +0 -1
- package/src/components/PhoneField/PhoneField.mdx +2 -3
- package/src/components/PhoneField/PhoneField.stories.ts +227 -410
- package/src/components/PhoneField/PhoneField.vue +204 -438
- package/src/components/PhoneField/indicatifs.ts +1 -1
- package/src/components/PhoneField/locales.ts +7 -0
- package/src/components/PhoneField/tests/PhoneField.a11y.spec.ts +0 -1
- package/src/components/PhoneField/tests/PhoneField.spec.ts +517 -220
- package/src/components/PhoneField/types.ts +30 -0
- package/src/components/PhoneField/usePhoneFieldValidation.ts +119 -0
- package/src/components/PhoneField/usePhoneIndicatifs.ts +89 -0
- package/src/components/PhoneField/validation/validation.stories.ts +717 -0
- package/src/components/RangeField/RangeField.mdx +0 -1
- package/src/components/RatingPicker/RatingPicker.mdx +0 -1
- package/src/components/SocialMediaLinks/SocialMediaLinks.mdx +0 -1
- package/src/components/StatusPage/StatusPage.vue +1 -0
- package/src/components/StatusPage/tests/__snapshots__/StatusPage.spec.ts.snap +248 -230
- package/src/components/SubHeader/SubHeader.mdx +5 -6
- package/src/components/Tables/common/tests/SyTableFilter.spec.ts +11 -12
- package/src/components/UploadWorkflow/UploadWorkflow.mdx +0 -1
- package/src/components/UserMenuBtn/UserMenuBtn.mdx +0 -1
- package/src/components/UserMenuBtn/UserMenuBtn.stories.ts +177 -0
- package/src/composables/unifyValidation/documentationValidationProps.ts +1 -1
- package/src/composables/unifyValidation/tests/useValidation.spec.ts +13 -1
- package/src/composables/unifyValidation/useValidation.ts +37 -33
- package/src/composantsVuetify/VCard/VCard.mdx +4 -0
- package/src/composantsVuetify/VCard/v-card.stories.ts +93 -1
- package/src/composantsVuetify/VCarousel/VCarousel.mdx +74 -0
- package/src/composantsVuetify/VCarousel/v-carousel.stories.ts +531 -0
- package/src/composantsVuetify/VNavigationDrawer/VNavgationDrawer.mdx +53 -0
- package/src/composantsVuetify/VNavigationDrawer/v-navigation-drawer.stories.ts +310 -0
- package/src/composantsVuetify/VSlideGroup/VSlideGroup.mdx +105 -0
- package/src/composantsVuetify/VSlideGroup/v-slide-group.stories.ts +463 -0
- package/src/designTokens/tokens/baseColors.ts +1 -1
- package/src/designTokens/tokens/baseTokens.ts +18 -18
- package/src/stories/Components/Components.stories.ts +34 -1
- package/src/stories/Demarrer/Releases.stories.ts +16 -2
- package/src/stories/DesignTokens/Arrondis.mdx +1 -1
- package/src/stories/DesignTokens/Correspondances.mdx +219 -0
- package/src/stories/DesignTokens/UtiliserLesTokens.mdx +235 -0
- package/src/stories/DesignTokens/colors.stories.ts +569 -569
- package/src/stories/GuideDuDev/Amelipro.stories.ts +335 -267
- package/dist/components/LunarCalendar/useLunarCalendarRules.d.ts +0 -5
- package/dist/components/PhoneField/tests/types.d.ts +0 -18
- package/src/components/LunarCalendar/tests/useLunarCalendarRules.spec.ts +0 -184
- package/src/components/LunarCalendar/useLunarCalendarRules.ts +0 -96
- package/src/components/PhoneField/tests/types.d.ts +0 -19
|
@@ -0,0 +1,654 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from '@storybook/vue3'
|
|
2
|
+
import { computed, onMounted, ref } from 'vue'
|
|
3
|
+
import SyCheckbox from '../SyCheckbox.vue'
|
|
4
|
+
import SyForm from '../../SyForm/SyForm.vue'
|
|
5
|
+
import { VBtn, VForm } from 'vuetify/components'
|
|
6
|
+
import { getValidationDocumentation } from '@/composables/unifyValidation/documentationValidationProps'
|
|
7
|
+
|
|
8
|
+
const meta: Meta<typeof SyCheckbox> = {
|
|
9
|
+
title: 'Composants/Formulaires/SyCheckbox/Validation',
|
|
10
|
+
component: SyCheckbox,
|
|
11
|
+
decorators: [
|
|
12
|
+
() => ({ template: '<div style="padding: 20px;"><story/></div>' }),
|
|
13
|
+
],
|
|
14
|
+
parameters: {
|
|
15
|
+
layout: 'fullscreen',
|
|
16
|
+
docs: {
|
|
17
|
+
description: {
|
|
18
|
+
component: 'Stories démontrant les différents cas de validation de SyCheckbox (système unifié). Pour une case unique, « required » signifie que la case doit être cochée.',
|
|
19
|
+
},
|
|
20
|
+
},
|
|
21
|
+
},
|
|
22
|
+
argTypes: {
|
|
23
|
+
...getValidationDocumentation(),
|
|
24
|
+
label: { control: 'text', description: 'Label de la case' },
|
|
25
|
+
},
|
|
26
|
+
args: {
|
|
27
|
+
label: 'J\'accepte les conditions générales',
|
|
28
|
+
required: true,
|
|
29
|
+
},
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export default meta
|
|
33
|
+
type Story = StoryObj<typeof SyCheckbox>
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Champ requis : la case doit être cochée, sinon une erreur s'affiche à la validation.
|
|
37
|
+
*/
|
|
38
|
+
export const WithError: Story = {
|
|
39
|
+
parameters: {
|
|
40
|
+
sourceCode: [
|
|
41
|
+
{
|
|
42
|
+
name: 'Template',
|
|
43
|
+
code: `
|
|
44
|
+
<template>
|
|
45
|
+
<SyCheckbox
|
|
46
|
+
ref="checkboxRef"
|
|
47
|
+
v-model="accepted"
|
|
48
|
+
label="J'accepte les conditions générales"
|
|
49
|
+
required
|
|
50
|
+
/>
|
|
51
|
+
</template>`,
|
|
52
|
+
},
|
|
53
|
+
{
|
|
54
|
+
name: 'Script',
|
|
55
|
+
code: `<script setup lang="ts">
|
|
56
|
+
import { onMounted, ref } from 'vue'
|
|
57
|
+
import { SyCheckbox } from '@cnamts/synapse'
|
|
58
|
+
|
|
59
|
+
const accepted = ref(false)
|
|
60
|
+
const checkboxRef = ref()
|
|
61
|
+
|
|
62
|
+
// Affiche l'état dès le chargement
|
|
63
|
+
onMounted(() => checkboxRef.value?.validateOnSubmit())
|
|
64
|
+
</script>`,
|
|
65
|
+
},
|
|
66
|
+
],
|
|
67
|
+
},
|
|
68
|
+
render: args => ({
|
|
69
|
+
components: { SyCheckbox },
|
|
70
|
+
setup() {
|
|
71
|
+
const accepted = ref(false)
|
|
72
|
+
const checkboxRef = ref<{ validateOnSubmit: () => Promise<boolean> } | null>(null)
|
|
73
|
+
onMounted(() => checkboxRef.value?.validateOnSubmit())
|
|
74
|
+
return { args, accepted, checkboxRef }
|
|
75
|
+
},
|
|
76
|
+
template: `<SyCheckbox ref="checkboxRef" v-model="accepted" v-bind="args" />`,
|
|
77
|
+
}),
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* Avertissement (customWarningRules) : non bloquant.
|
|
82
|
+
*/
|
|
83
|
+
export const WithWarning: Story = {
|
|
84
|
+
args: {
|
|
85
|
+
required: false,
|
|
86
|
+
customWarningRules: [{
|
|
87
|
+
type: 'custom',
|
|
88
|
+
options: {
|
|
89
|
+
validate: (value: unknown) => value === true,
|
|
90
|
+
warningMessage: 'Il est recommandé de cocher cette case.',
|
|
91
|
+
},
|
|
92
|
+
}],
|
|
93
|
+
},
|
|
94
|
+
parameters: {
|
|
95
|
+
sourceCode: [
|
|
96
|
+
{
|
|
97
|
+
name: 'Template',
|
|
98
|
+
code: `
|
|
99
|
+
<template>
|
|
100
|
+
<SyCheckbox
|
|
101
|
+
ref="checkboxRef"
|
|
102
|
+
v-model="accepted"
|
|
103
|
+
label="J'accepte les conditions générales"
|
|
104
|
+
:custom-warning-rules="warningRules"
|
|
105
|
+
/>
|
|
106
|
+
</template>`,
|
|
107
|
+
},
|
|
108
|
+
{
|
|
109
|
+
name: 'Script',
|
|
110
|
+
code: `<script setup lang="ts">
|
|
111
|
+
import { onMounted, ref } from 'vue'
|
|
112
|
+
import { SyCheckbox } from '@cnamts/synapse'
|
|
113
|
+
|
|
114
|
+
const accepted = ref(false)
|
|
115
|
+
const checkboxRef = ref()
|
|
116
|
+
|
|
117
|
+
const warningRules = [{
|
|
118
|
+
type: 'custom',
|
|
119
|
+
options: {
|
|
120
|
+
validate: (value: unknown) => value === true,
|
|
121
|
+
warningMessage: 'Il est recommandé de cocher cette case.',
|
|
122
|
+
},
|
|
123
|
+
}]
|
|
124
|
+
|
|
125
|
+
// Affiche l'état dès le chargement
|
|
126
|
+
onMounted(() => checkboxRef.value?.validateOnSubmit())
|
|
127
|
+
</script>`,
|
|
128
|
+
},
|
|
129
|
+
],
|
|
130
|
+
},
|
|
131
|
+
render: args => ({
|
|
132
|
+
components: { SyCheckbox },
|
|
133
|
+
setup() {
|
|
134
|
+
const accepted = ref(false)
|
|
135
|
+
const checkboxRef = ref<{ validateOnSubmit: () => Promise<boolean> } | null>(null)
|
|
136
|
+
onMounted(() => checkboxRef.value?.validateOnSubmit())
|
|
137
|
+
return { args, accepted, checkboxRef }
|
|
138
|
+
},
|
|
139
|
+
template: `<SyCheckbox ref="checkboxRef" v-model="accepted" v-bind="args" />`,
|
|
140
|
+
}),
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
/**
|
|
144
|
+
* Message de succès (customSuccessRules + showSuccessMessages).
|
|
145
|
+
*/
|
|
146
|
+
export const WithSuccess: Story = {
|
|
147
|
+
args: {
|
|
148
|
+
required: false,
|
|
149
|
+
showSuccessMessages: true,
|
|
150
|
+
customSuccessRules: [{
|
|
151
|
+
type: 'custom',
|
|
152
|
+
options: {
|
|
153
|
+
validate: (value: unknown) => value === true,
|
|
154
|
+
successMessage: 'Merci d\'avoir accepté.',
|
|
155
|
+
},
|
|
156
|
+
}],
|
|
157
|
+
},
|
|
158
|
+
parameters: {
|
|
159
|
+
sourceCode: [
|
|
160
|
+
{
|
|
161
|
+
name: 'Template',
|
|
162
|
+
code: `
|
|
163
|
+
<template>
|
|
164
|
+
<SyCheckbox
|
|
165
|
+
ref="checkboxRef"
|
|
166
|
+
v-model="accepted"
|
|
167
|
+
label="J'accepte les conditions générales"
|
|
168
|
+
:custom-success-rules="successRules"
|
|
169
|
+
show-success-messages
|
|
170
|
+
/>
|
|
171
|
+
</template>`,
|
|
172
|
+
},
|
|
173
|
+
{
|
|
174
|
+
name: 'Script',
|
|
175
|
+
code: `<script setup lang="ts">
|
|
176
|
+
import { onMounted, ref } from 'vue'
|
|
177
|
+
import { SyCheckbox } from '@cnamts/synapse'
|
|
178
|
+
|
|
179
|
+
const accepted = ref(true)
|
|
180
|
+
const checkboxRef = ref()
|
|
181
|
+
|
|
182
|
+
const successRules = [{
|
|
183
|
+
type: 'custom',
|
|
184
|
+
options: {
|
|
185
|
+
validate: (value: unknown) => value === true,
|
|
186
|
+
successMessage: 'Merci d\\'avoir accepté.',
|
|
187
|
+
},
|
|
188
|
+
}]
|
|
189
|
+
|
|
190
|
+
// Affiche l'état dès le chargement
|
|
191
|
+
onMounted(() => checkboxRef.value?.validateOnSubmit())
|
|
192
|
+
</script>`,
|
|
193
|
+
},
|
|
194
|
+
],
|
|
195
|
+
},
|
|
196
|
+
render: args => ({
|
|
197
|
+
components: { SyCheckbox },
|
|
198
|
+
setup() {
|
|
199
|
+
const accepted = ref(true)
|
|
200
|
+
const checkboxRef = ref<{ validateOnSubmit: () => Promise<boolean> } | null>(null)
|
|
201
|
+
onMounted(() => checkboxRef.value?.validateOnSubmit())
|
|
202
|
+
return { args, accepted, checkboxRef }
|
|
203
|
+
},
|
|
204
|
+
template: `<SyCheckbox ref="checkboxRef" v-model="accepted" v-bind="args" />`,
|
|
205
|
+
}),
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
/**
|
|
209
|
+
* Règle personnalisée (customRules) avec validation **contextuelle** : ici la case ne peut être
|
|
210
|
+
* cochée que si un prérequis est validé. C'est un vrai cas d'usage de `customRules`, distinct de
|
|
211
|
+
* `required` (qui se contente d'exiger que la case soit cochée).
|
|
212
|
+
*/
|
|
213
|
+
export const WithCustomRules: Story = {
|
|
214
|
+
parameters: {
|
|
215
|
+
docs: {
|
|
216
|
+
description: {
|
|
217
|
+
story: 'La règle dépend d\'un état externe (le prérequis). Cocher la case sans valider le prérequis déclenche une erreur.',
|
|
218
|
+
},
|
|
219
|
+
},
|
|
220
|
+
sourceCode: [
|
|
221
|
+
{
|
|
222
|
+
name: 'Template',
|
|
223
|
+
code: `
|
|
224
|
+
<template>
|
|
225
|
+
<SyCheckbox v-model="prerequisite" label="Prérequis : j'ai lu le document" hide-details />
|
|
226
|
+
<SyCheckbox
|
|
227
|
+
v-model="accepted"
|
|
228
|
+
label="J'accepte (uniquement si le prérequis est validé)"
|
|
229
|
+
:custom-rules="customRules"
|
|
230
|
+
:is-validate-on-blur="false"
|
|
231
|
+
/>
|
|
232
|
+
</template>`,
|
|
233
|
+
},
|
|
234
|
+
{
|
|
235
|
+
name: 'Script',
|
|
236
|
+
code: `<script setup lang="ts">
|
|
237
|
+
import { computed, ref } from 'vue'
|
|
238
|
+
import { SyCheckbox } from '@cnamts/synapse'
|
|
239
|
+
|
|
240
|
+
const prerequisite = ref(false)
|
|
241
|
+
const accepted = ref(false)
|
|
242
|
+
|
|
243
|
+
const customRules = computed(() => [{
|
|
244
|
+
type: 'custom',
|
|
245
|
+
options: {
|
|
246
|
+
// Valide tant que la case n'est pas cochée, ou que le prérequis est rempli
|
|
247
|
+
validate: (value: unknown) => value !== true || prerequisite.value,
|
|
248
|
+
message: 'Vous devez d\\'abord valider le prérequis avant de cocher cette case.',
|
|
249
|
+
},
|
|
250
|
+
}])
|
|
251
|
+
</script>`,
|
|
252
|
+
},
|
|
253
|
+
],
|
|
254
|
+
},
|
|
255
|
+
render: () => ({
|
|
256
|
+
components: { SyCheckbox },
|
|
257
|
+
setup() {
|
|
258
|
+
const prerequisite = ref(false)
|
|
259
|
+
const accepted = ref(false)
|
|
260
|
+
|
|
261
|
+
const customRules = computed(() => [{
|
|
262
|
+
type: 'custom',
|
|
263
|
+
options: {
|
|
264
|
+
validate: (value: unknown) => value !== true || prerequisite.value,
|
|
265
|
+
message: 'Vous devez d\'abord valider le prérequis avant de cocher cette case.',
|
|
266
|
+
},
|
|
267
|
+
}])
|
|
268
|
+
|
|
269
|
+
return { prerequisite, accepted, customRules }
|
|
270
|
+
},
|
|
271
|
+
template: `
|
|
272
|
+
<div class="d-flex flex-column ga-2">
|
|
273
|
+
<SyCheckbox v-model="prerequisite" label="Prérequis : j'ai lu le document" hide-details />
|
|
274
|
+
<SyCheckbox
|
|
275
|
+
v-model="accepted"
|
|
276
|
+
label="J'accepte (uniquement si le prérequis est validé)"
|
|
277
|
+
:custom-rules="customRules"
|
|
278
|
+
:is-validate-on-blur="false"
|
|
279
|
+
/>
|
|
280
|
+
</div>
|
|
281
|
+
`,
|
|
282
|
+
}),
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
/**
|
|
286
|
+
* Messages externes : l'état d'erreur est piloté par la prop errorMessages.
|
|
287
|
+
*/
|
|
288
|
+
export const ExternalMessages: Story = {
|
|
289
|
+
args: {
|
|
290
|
+
required: false,
|
|
291
|
+
hasError: true,
|
|
292
|
+
errorMessages: ['Cette case est invalide (message externe).'],
|
|
293
|
+
},
|
|
294
|
+
parameters: {
|
|
295
|
+
sourceCode: [
|
|
296
|
+
{
|
|
297
|
+
name: 'Template',
|
|
298
|
+
code: `
|
|
299
|
+
<template>
|
|
300
|
+
<SyCheckbox
|
|
301
|
+
v-model="accepted"
|
|
302
|
+
label="J'accepte les conditions générales"
|
|
303
|
+
:has-error="true"
|
|
304
|
+
:error-messages="errorMessages"
|
|
305
|
+
/>
|
|
306
|
+
</template>`,
|
|
307
|
+
},
|
|
308
|
+
{
|
|
309
|
+
name: 'Script',
|
|
310
|
+
code: `<script setup lang="ts">
|
|
311
|
+
import { ref } from 'vue'
|
|
312
|
+
import { SyCheckbox } from '@cnamts/synapse'
|
|
313
|
+
|
|
314
|
+
const accepted = ref(false)
|
|
315
|
+
const errorMessages = ['Cette case est invalide (message externe).']
|
|
316
|
+
</script>`,
|
|
317
|
+
},
|
|
318
|
+
],
|
|
319
|
+
},
|
|
320
|
+
render: args => ({
|
|
321
|
+
components: { SyCheckbox },
|
|
322
|
+
setup() {
|
|
323
|
+
const accepted = ref(false)
|
|
324
|
+
return { args, accepted }
|
|
325
|
+
},
|
|
326
|
+
template: `<SyCheckbox v-model="accepted" v-bind="args" />`,
|
|
327
|
+
}),
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
/**
|
|
331
|
+
* Avec `disableErrorHandling: true`, les règles sont ignorées visuellement : aucune erreur ne
|
|
332
|
+
* s'affiche même si la case requise reste décochée (utile quand la validation est pilotée ailleurs).
|
|
333
|
+
*/
|
|
334
|
+
export const DisableErrorHandling: Story = {
|
|
335
|
+
args: {
|
|
336
|
+
required: true,
|
|
337
|
+
disableErrorHandling: true,
|
|
338
|
+
},
|
|
339
|
+
parameters: {
|
|
340
|
+
sourceCode: [
|
|
341
|
+
{
|
|
342
|
+
name: 'Template',
|
|
343
|
+
code: `
|
|
344
|
+
<template>
|
|
345
|
+
<SyCheckbox
|
|
346
|
+
ref="checkboxRef"
|
|
347
|
+
v-model="accepted"
|
|
348
|
+
label="J'accepte les conditions générales"
|
|
349
|
+
required
|
|
350
|
+
disable-error-handling
|
|
351
|
+
/>
|
|
352
|
+
</template>`,
|
|
353
|
+
},
|
|
354
|
+
{
|
|
355
|
+
name: 'Script',
|
|
356
|
+
code: `<script setup lang="ts">
|
|
357
|
+
import { onMounted, ref } from 'vue'
|
|
358
|
+
import { SyCheckbox } from '@cnamts/synapse'
|
|
359
|
+
|
|
360
|
+
const accepted = ref(false)
|
|
361
|
+
const checkboxRef = ref()
|
|
362
|
+
|
|
363
|
+
// Même en déclenchant la validation, aucune erreur ne s'affiche
|
|
364
|
+
onMounted(() => checkboxRef.value?.validateOnSubmit())
|
|
365
|
+
</script>`,
|
|
366
|
+
},
|
|
367
|
+
],
|
|
368
|
+
},
|
|
369
|
+
render: args => ({
|
|
370
|
+
components: { SyCheckbox },
|
|
371
|
+
setup() {
|
|
372
|
+
const accepted = ref(false)
|
|
373
|
+
const checkboxRef = ref<{ validateOnSubmit: () => Promise<boolean> } | null>(null)
|
|
374
|
+
onMounted(() => checkboxRef.value?.validateOnSubmit())
|
|
375
|
+
return { args, accepted, checkboxRef }
|
|
376
|
+
},
|
|
377
|
+
template: `<SyCheckbox ref="checkboxRef" v-model="accepted" v-bind="args" />`,
|
|
378
|
+
}),
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
/**
|
|
382
|
+
* Intégration avec SyForm : la case s'enregistre automatiquement (useValidatable)
|
|
383
|
+
* et est validée à la soumission du formulaire.
|
|
384
|
+
*/
|
|
385
|
+
export const SyFormValidation: Story = {
|
|
386
|
+
parameters: {
|
|
387
|
+
docs: {
|
|
388
|
+
description: {
|
|
389
|
+
story: 'Il faut privilégier l\'utilisation de `SyForm`, qui valide automatiquement les composants enregistrés via `useValidatable`.',
|
|
390
|
+
},
|
|
391
|
+
},
|
|
392
|
+
sourceCode: [
|
|
393
|
+
{
|
|
394
|
+
name: 'Template',
|
|
395
|
+
code: `
|
|
396
|
+
<template>
|
|
397
|
+
<SyForm @submit="onSubmit">
|
|
398
|
+
<SyCheckbox v-model="accepted" label="J'accepte les conditions générales" required />
|
|
399
|
+
<VBtn type="submit" color="primary" class="mt-4">Valider</VBtn>
|
|
400
|
+
</SyForm>
|
|
401
|
+
</template>`,
|
|
402
|
+
},
|
|
403
|
+
{
|
|
404
|
+
name: 'Script',
|
|
405
|
+
code: `<script setup lang="ts">
|
|
406
|
+
import { ref } from 'vue'
|
|
407
|
+
import { SyCheckbox, SyForm } from '@cnamts/synapse'
|
|
408
|
+
import { VBtn } from 'vuetify/components'
|
|
409
|
+
|
|
410
|
+
const accepted = ref(false)
|
|
411
|
+
|
|
412
|
+
function onSubmit(e: { isValid: boolean }) {
|
|
413
|
+
alert(e.isValid ? 'Formulaire valide !' : 'Veuillez cocher la case.')
|
|
414
|
+
}
|
|
415
|
+
</script>`,
|
|
416
|
+
},
|
|
417
|
+
],
|
|
418
|
+
},
|
|
419
|
+
render: args => ({
|
|
420
|
+
components: { SyCheckbox, SyForm, VBtn },
|
|
421
|
+
setup() {
|
|
422
|
+
const accepted = ref(false)
|
|
423
|
+
function onSubmit(e: { isValid: boolean }) {
|
|
424
|
+
alert(e.isValid ? 'Formulaire valide !' : 'Veuillez cocher la case.')
|
|
425
|
+
}
|
|
426
|
+
return { args, accepted, onSubmit }
|
|
427
|
+
},
|
|
428
|
+
template: `
|
|
429
|
+
<SyForm @submit="onSubmit">
|
|
430
|
+
<SyCheckbox v-model="accepted" v-bind="args" />
|
|
431
|
+
<VBtn type="submit" color="primary" class="mt-4">Valider</VBtn>
|
|
432
|
+
</SyForm>
|
|
433
|
+
`,
|
|
434
|
+
}),
|
|
435
|
+
}
|
|
436
|
+
|
|
437
|
+
/**
|
|
438
|
+
* Intégration avec un VForm Vuetify natif : la validation est déclenchée manuellement via la ref
|
|
439
|
+
* du composant (`validateOnSubmit`). Il est toutefois recommandé d'utiliser `SyForm` pour
|
|
440
|
+
* l'intégration automatique.
|
|
441
|
+
*/
|
|
442
|
+
export const VFormValidation: Story = {
|
|
443
|
+
parameters: {
|
|
444
|
+
docs: {
|
|
445
|
+
description: {
|
|
446
|
+
story: 'Avec un `VForm` natif, la case n\'est pas auto-enregistrée : on appelle `validateOnSubmit()` via une ref. Préférez `SyForm` (cf. story SyFormValidation).',
|
|
447
|
+
},
|
|
448
|
+
},
|
|
449
|
+
sourceCode: [
|
|
450
|
+
{
|
|
451
|
+
name: 'Template',
|
|
452
|
+
code: `
|
|
453
|
+
<template>
|
|
454
|
+
<VForm @submit.prevent="handleSubmit">
|
|
455
|
+
<SyCheckbox
|
|
456
|
+
ref="checkboxRef"
|
|
457
|
+
v-model="accepted"
|
|
458
|
+
label="J'accepte les conditions générales"
|
|
459
|
+
required
|
|
460
|
+
/>
|
|
461
|
+
<VBtn type="submit" color="primary" class="mt-4">Valider</VBtn>
|
|
462
|
+
</VForm>
|
|
463
|
+
</template>`,
|
|
464
|
+
},
|
|
465
|
+
{
|
|
466
|
+
name: 'Script',
|
|
467
|
+
code: `<script setup lang="ts">
|
|
468
|
+
import { ref } from 'vue'
|
|
469
|
+
import { SyCheckbox } from '@cnamts/synapse'
|
|
470
|
+
import { VBtn, VForm } from 'vuetify/components'
|
|
471
|
+
|
|
472
|
+
const accepted = ref(false)
|
|
473
|
+
const checkboxRef = ref()
|
|
474
|
+
|
|
475
|
+
async function handleSubmit() {
|
|
476
|
+
const isValid = await checkboxRef.value?.validateOnSubmit()
|
|
477
|
+
alert(isValid ? 'Formulaire valide !' : 'Veuillez cocher la case.')
|
|
478
|
+
}
|
|
479
|
+
</script>`,
|
|
480
|
+
},
|
|
481
|
+
],
|
|
482
|
+
},
|
|
483
|
+
render: args => ({
|
|
484
|
+
components: { SyCheckbox, VForm, VBtn },
|
|
485
|
+
setup() {
|
|
486
|
+
const accepted = ref(false)
|
|
487
|
+
const checkboxRef = ref<{ validateOnSubmit: () => Promise<boolean> } | null>(null)
|
|
488
|
+
|
|
489
|
+
async function handleSubmit() {
|
|
490
|
+
const isValid = await checkboxRef.value?.validateOnSubmit()
|
|
491
|
+
alert(isValid ? 'Formulaire valide !' : 'Veuillez cocher la case.')
|
|
492
|
+
}
|
|
493
|
+
|
|
494
|
+
return { args, accepted, checkboxRef, handleSubmit }
|
|
495
|
+
},
|
|
496
|
+
template: `
|
|
497
|
+
<VForm @submit.prevent="handleSubmit">
|
|
498
|
+
<SyCheckbox ref="checkboxRef" v-model="accepted" v-bind="args" />
|
|
499
|
+
<VBtn type="submit" color="primary" class="mt-4">Valider</VBtn>
|
|
500
|
+
</VForm>
|
|
501
|
+
`,
|
|
502
|
+
}),
|
|
503
|
+
}
|
|
504
|
+
|
|
505
|
+
/**
|
|
506
|
+
* Mode de validation natif Vuetify (`useVuetifyValidation`) intégré à `SyForm`.
|
|
507
|
+
* Les règles sont de simples fonctions `(value) => true | 'message'`, comme la prop `rules` de Vuetify.
|
|
508
|
+
*/
|
|
509
|
+
export const SyFormVuetifyValidation: Story = {
|
|
510
|
+
parameters: {
|
|
511
|
+
docs: {
|
|
512
|
+
description: {
|
|
513
|
+
story: 'Avec `use-vuetify-validation`, la case délègue sa validation à Vuetify via la prop `rules` (fonctions natives), tout en restant intégrée à `SyForm`.',
|
|
514
|
+
},
|
|
515
|
+
},
|
|
516
|
+
sourceCode: [
|
|
517
|
+
{
|
|
518
|
+
name: 'Template',
|
|
519
|
+
code: `<template>
|
|
520
|
+
<SyForm @submit="handleSubmit">
|
|
521
|
+
<SyCheckbox
|
|
522
|
+
v-model="accepted"
|
|
523
|
+
label="J'accepte les conditions générales"
|
|
524
|
+
:use-vuetify-validation="true"
|
|
525
|
+
:rules="vuetifyRules"
|
|
526
|
+
/>
|
|
527
|
+
<VBtn type="submit" color="primary" class="mt-4">Valider</VBtn>
|
|
528
|
+
</SyForm>
|
|
529
|
+
</template>`,
|
|
530
|
+
},
|
|
531
|
+
{
|
|
532
|
+
name: 'Script',
|
|
533
|
+
code: `<script setup lang="ts">
|
|
534
|
+
import { ref } from 'vue'
|
|
535
|
+
import { SyCheckbox, SyForm } from '@cnamts/synapse'
|
|
536
|
+
import { VBtn } from 'vuetify/components'
|
|
537
|
+
|
|
538
|
+
const accepted = ref(false)
|
|
539
|
+
|
|
540
|
+
const vuetifyRules = [
|
|
541
|
+
(value: boolean | null) => value === true || 'Vous devez cocher cette case.',
|
|
542
|
+
]
|
|
543
|
+
|
|
544
|
+
function handleSubmit(e: { isValid: boolean }) {
|
|
545
|
+
alert(e.isValid ? 'Formulaire valide !' : 'Veuillez cocher la case.')
|
|
546
|
+
}
|
|
547
|
+
</script>`,
|
|
548
|
+
},
|
|
549
|
+
],
|
|
550
|
+
},
|
|
551
|
+
render: args => ({
|
|
552
|
+
components: { SyCheckbox, SyForm, VBtn },
|
|
553
|
+
setup() {
|
|
554
|
+
const accepted = ref(false)
|
|
555
|
+
|
|
556
|
+
const vuetifyRules = [
|
|
557
|
+
(value: boolean | null) => value === true || 'Vous devez cocher cette case.',
|
|
558
|
+
]
|
|
559
|
+
|
|
560
|
+
function handleSubmit(e: { isValid: boolean }) {
|
|
561
|
+
alert(e.isValid ? 'Formulaire valide !' : 'Veuillez cocher la case.')
|
|
562
|
+
}
|
|
563
|
+
|
|
564
|
+
return { args, accepted, vuetifyRules, handleSubmit }
|
|
565
|
+
},
|
|
566
|
+
template: `
|
|
567
|
+
<SyForm @submit="handleSubmit">
|
|
568
|
+
<SyCheckbox
|
|
569
|
+
v-bind="args"
|
|
570
|
+
v-model="accepted"
|
|
571
|
+
:use-vuetify-validation="true"
|
|
572
|
+
:rules="vuetifyRules"
|
|
573
|
+
/>
|
|
574
|
+
<VBtn type="submit" color="primary" class="mt-4">Valider</VBtn>
|
|
575
|
+
</SyForm>
|
|
576
|
+
`,
|
|
577
|
+
}),
|
|
578
|
+
}
|
|
579
|
+
|
|
580
|
+
/**
|
|
581
|
+
* Mode de validation natif Vuetify (`useVuetifyValidation`) dans un `VForm` Vuetify.
|
|
582
|
+
*/
|
|
583
|
+
export const VFormVuetifyValidation: Story = {
|
|
584
|
+
parameters: {
|
|
585
|
+
docs: {
|
|
586
|
+
description: {
|
|
587
|
+
story: 'Validation déléguée à Vuetify (`use-vuetify-validation` + `rules`) dans un `VForm` natif.',
|
|
588
|
+
},
|
|
589
|
+
},
|
|
590
|
+
sourceCode: [
|
|
591
|
+
{
|
|
592
|
+
name: 'Template',
|
|
593
|
+
code: `<template>
|
|
594
|
+
<VForm @submit.prevent="handleSubmit">
|
|
595
|
+
<SyCheckbox
|
|
596
|
+
v-model="accepted"
|
|
597
|
+
label="J'accepte les conditions générales"
|
|
598
|
+
:use-vuetify-validation="true"
|
|
599
|
+
:rules="vuetifyRules"
|
|
600
|
+
/>
|
|
601
|
+
<VBtn type="submit" color="primary" class="mt-4">Valider</VBtn>
|
|
602
|
+
</VForm>
|
|
603
|
+
</template>`,
|
|
604
|
+
},
|
|
605
|
+
{
|
|
606
|
+
name: 'Script',
|
|
607
|
+
code: `<script setup lang="ts">
|
|
608
|
+
import { ref } from 'vue'
|
|
609
|
+
import { SyCheckbox } from '@cnamts/synapse'
|
|
610
|
+
import { VBtn, VForm } from 'vuetify/components'
|
|
611
|
+
|
|
612
|
+
const accepted = ref(false)
|
|
613
|
+
|
|
614
|
+
const vuetifyRules = [
|
|
615
|
+
(value: boolean | null) => value === true || 'Vous devez cocher cette case.',
|
|
616
|
+
]
|
|
617
|
+
|
|
618
|
+
async function handleSubmit(e: Promise<{ valid: boolean }>) {
|
|
619
|
+
const { valid } = await e
|
|
620
|
+
alert(valid ? 'Formulaire valide !' : 'Veuillez cocher la case.')
|
|
621
|
+
}
|
|
622
|
+
</script>`,
|
|
623
|
+
},
|
|
624
|
+
],
|
|
625
|
+
},
|
|
626
|
+
render: args => ({
|
|
627
|
+
components: { SyCheckbox, VForm, VBtn },
|
|
628
|
+
setup() {
|
|
629
|
+
const accepted = ref(false)
|
|
630
|
+
|
|
631
|
+
const vuetifyRules = [
|
|
632
|
+
(value: boolean | null) => value === true || 'Vous devez cocher cette case.',
|
|
633
|
+
]
|
|
634
|
+
|
|
635
|
+
async function handleSubmit(e: Promise<{ valid: boolean }>) {
|
|
636
|
+
const { valid } = await e
|
|
637
|
+
alert(valid ? 'Formulaire valide !' : 'Veuillez cocher la case.')
|
|
638
|
+
}
|
|
639
|
+
|
|
640
|
+
return { args, accepted, vuetifyRules, handleSubmit }
|
|
641
|
+
},
|
|
642
|
+
template: `
|
|
643
|
+
<VForm @submit.prevent="handleSubmit">
|
|
644
|
+
<SyCheckbox
|
|
645
|
+
v-bind="args"
|
|
646
|
+
v-model="accepted"
|
|
647
|
+
:use-vuetify-validation="true"
|
|
648
|
+
:rules="vuetifyRules"
|
|
649
|
+
/>
|
|
650
|
+
<VBtn type="submit" color="primary" class="mt-4">Valider</VBtn>
|
|
651
|
+
</VForm>
|
|
652
|
+
`,
|
|
653
|
+
}),
|
|
654
|
+
}
|