@cnamts/synapse 0.0.9-alpha → 0.0.10-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 (55) hide show
  1. package/dist/design-system-v3.d.ts +631 -62
  2. package/dist/design-system-v3.js +3451 -2650
  3. package/dist/design-system-v3.umd.cjs +1 -1
  4. package/dist/style.css +1 -1
  5. package/package.json +1 -1
  6. package/src/components/DatePicker/Accessibilite.mdx +14 -0
  7. package/src/components/DatePicker/Accessibilite.stories.ts +191 -0
  8. package/src/components/DatePicker/AccessibiliteItems.ts +233 -0
  9. package/src/components/DatePicker/DatePicker.mdx +1 -6
  10. package/src/components/DatePicker/DatePicker.stories.ts +16 -16
  11. package/src/components/DatePicker/DatePicker.vue +20 -6
  12. package/src/components/DatePicker/constants/ExpertiseLevelEnum.ts +4 -0
  13. package/src/components/FileList/FileList.mdx +103 -0
  14. package/src/components/FileList/FileList.stories.ts +562 -0
  15. package/src/components/FileList/FileList.vue +78 -0
  16. package/src/components/FileList/UploadItem/UploadItem.vue +270 -0
  17. package/src/components/FileList/UploadItem/locales.ts +9 -0
  18. package/src/components/FileList/tests/FileList.spec.ts +176 -0
  19. package/src/components/FilePreview/FilePreview.mdx +82 -0
  20. package/src/components/FilePreview/FilePreview.stories.ts +242 -0
  21. package/src/components/FilePreview/FilePreview.vue +68 -0
  22. package/src/components/FilePreview/config.ts +10 -0
  23. package/src/components/FilePreview/locales.ts +4 -0
  24. package/src/components/FilePreview/tests/FilePreview.spec.ts +124 -0
  25. package/src/components/FilePreview/tests/__snapshots__/FilePreview.spec.ts.snap +11 -0
  26. package/src/components/PeriodField/PeriodField.mdx +32 -0
  27. package/src/components/PeriodField/PeriodField.stories.ts +807 -0
  28. package/src/components/PeriodField/PeriodField.vue +355 -0
  29. package/src/components/PeriodField/tests/PeriodField.spec.ts +348 -0
  30. package/src/components/RangeField/Accessibilite.mdx +14 -0
  31. package/src/components/RangeField/Accessibilite.stories.ts +191 -0
  32. package/src/components/RangeField/AccessibiliteItems.ts +179 -0
  33. package/src/components/RangeField/constants/ExpertiseLevelEnum.ts +4 -0
  34. package/src/components/RatingPicker/Accessibilite.mdx +14 -0
  35. package/src/components/RatingPicker/Accessibilite.stories.ts +191 -0
  36. package/src/components/RatingPicker/AccessibiliteItems.ts +208 -0
  37. package/src/components/RatingPicker/constants/ExpertiseLevelEnum.ts +4 -0
  38. package/src/components/SearchListField/Accessibilite.mdx +14 -0
  39. package/src/components/SearchListField/Accessibilite.stories.ts +191 -0
  40. package/src/components/SearchListField/AccessibiliteItems.ts +310 -0
  41. package/src/components/SearchListField/constants/ExpertiseLevelEnum.ts +4 -0
  42. package/src/components/SelectBtnField/Accessibilite.mdx +14 -0
  43. package/src/components/SelectBtnField/Accessibilite.stories.ts +191 -0
  44. package/src/components/SelectBtnField/AccessibiliteItems.ts +191 -0
  45. package/src/components/SelectBtnField/constants/ExpertiseLevelEnum.ts +4 -0
  46. package/src/components/SyAlert/SyAlert.vue +11 -9
  47. package/src/components/TableToolbar/TableToolbar.mdx +130 -0
  48. package/src/components/TableToolbar/TableToolbar.stories.ts +935 -0
  49. package/src/components/TableToolbar/TableToolbar.vue +168 -0
  50. package/src/components/TableToolbar/config.ts +24 -0
  51. package/src/components/TableToolbar/locales.ts +6 -0
  52. package/src/components/TableToolbar/tests/TableToolbar.spec.ts +166 -0
  53. package/src/components/TableToolbar/tests/__snapshots__/TableToolbar.spec.ts.snap +359 -0
  54. package/src/components/index.ts +3 -0
  55. package/src/composables/rules/useFieldValidation.ts +17 -15
@@ -0,0 +1,168 @@
1
+ <script setup lang="ts">
2
+ import useCustomizableOptions, { type CustomizableOptions } from '@/composables/useCustomizableOptions'
3
+ import { mdiMagnify, mdiPlus } from '@mdi/js'
4
+ import { computed } from 'vue'
5
+ import { useDisplay, useTheme } from 'vuetify'
6
+ import { config } from './config'
7
+ import { locales as defaultLocales } from './locales'
8
+
9
+ const props = withDefaults(defineProps<{
10
+ nbTotal: number
11
+ nbFiltered?: number
12
+ search?: string
13
+ searchLabel?: string
14
+ showAddButton?: boolean
15
+ addButtonLabel?: string
16
+ loading?: boolean
17
+ locales?: typeof defaultLocales
18
+ } & CustomizableOptions>(), {
19
+ nbFiltered: undefined,
20
+ search: undefined,
21
+ searchLabel: defaultLocales.search,
22
+ showAddButton: false,
23
+ addButtonLabel: defaultLocales.addBtnLabel,
24
+ loading: false,
25
+ locales: () => defaultLocales,
26
+ })
27
+
28
+ defineEmits<{
29
+ (e: 'update:search', value: string): void
30
+ (e: 'add'): void
31
+ }>()
32
+
33
+ const options = useCustomizableOptions(config, props)
34
+ const display = useDisplay()
35
+ const theme = useTheme()
36
+
37
+ const textFieldClasses = computed(() => ({
38
+ 'sy-form-input--s': display.xs.value,
39
+ 'flex-grow-0': display.xs.value,
40
+ 'flex-grow-1': !display.xs.value,
41
+ 'mr-6': props.showAddButton,
42
+ 'loading': props.loading,
43
+ }))
44
+
45
+ const displayNbRows = computed(() => {
46
+ const lines = props.nbFiltered ? `${props.nbFiltered}/${props.nbTotal}` : String(props.nbTotal)
47
+ return props.locales.rowText(
48
+ lines,
49
+ props.nbTotal > 1,
50
+ )
51
+ })
52
+ </script>
53
+
54
+ <template>
55
+ <VToolbar
56
+ v-bind="options.toolbar"
57
+ :class="{ 'v-theme-dark': theme.current.value.dark}"
58
+ class="sy-table-toolbar px-4 py-2 d-flex flex-wrap align-center justify-space-between"
59
+ >
60
+ <p
61
+ v-if="nbTotal > 0"
62
+ class="mb-0 font-weight-bold mr-4 my-3"
63
+ data-test-id="nb-rows"
64
+ >
65
+ {{ displayNbRows }}
66
+ </p>
67
+
68
+ <div class="sy-table-toolbar__search">
69
+ <slot name="search-left" />
70
+ <VTextField
71
+ v-bind="options.textField"
72
+ color="primary"
73
+ :model-value="search"
74
+ class="sy-form-input"
75
+ :class="textFieldClasses"
76
+ :disabled="loading"
77
+ :append-inner-icon="mdiMagnify"
78
+ :label="searchLabel"
79
+ data-test-id="search-input"
80
+ @update:model-value="$emit('update:search', $event)"
81
+ />
82
+ <VBtn
83
+ v-if="showAddButton"
84
+ v-bind="options.addBtn"
85
+ :disabled="loading"
86
+ class="ml-3 mb-0"
87
+ data-test-id="add-btn"
88
+ @click="$emit('add')"
89
+ >
90
+ <VIcon v-bind="options.addIcon">
91
+ {{ mdiPlus }}
92
+ </VIcon>
93
+
94
+ <span
95
+ v-show="!display.xs.value"
96
+ v-bind="options.addIconLabel"
97
+ >
98
+ {{ addButtonLabel }}
99
+ </span>
100
+ </VBtn>
101
+
102
+ <slot name="search-right" />
103
+ </div>
104
+ </VToolbar>
105
+ </template>
106
+
107
+ <style lang="scss" scoped>
108
+ @use '@/assets/tokens';
109
+
110
+ .sy-table-toolbar {
111
+ min-height: 56px;
112
+ }
113
+
114
+ .loading :deep(.v-field__append-inner) {
115
+ opacity: 0.6 !important;
116
+ }
117
+
118
+ :deep(.v-field--disabled) {
119
+ opacity: 0.7 !important;
120
+ }
121
+
122
+ .sy-table-toolbar__search {
123
+ display: grid;
124
+ grid-auto-columns: auto;
125
+ grid-auto-flow: column;
126
+ margin-left: auto;
127
+ align-items: end;
128
+ }
129
+
130
+ .sy-form-input {
131
+ width: 328px;
132
+ }
133
+
134
+ .sy-form-input--s {
135
+ z-index: 1; // Display content above the table on mobile
136
+ contain: none; // Allow fixed elements to be displayed properly
137
+
138
+ :deep(.v-toolbar__content) {
139
+ width: 100%;
140
+ flex-wrap: wrap;
141
+ }
142
+ }
143
+
144
+ .sy-table-toolbar.v-theme--dark :deep() {
145
+ background-color: tokens.$grey-darken-20 !important;
146
+
147
+ p,
148
+ .text-primary {
149
+ color: rgba(tokens.$colors-text-ondark, 0.6) !important;
150
+ }
151
+
152
+ svg {
153
+ fill: tokens.$colors-text-ondark !important;
154
+ }
155
+
156
+ .v-label {
157
+ color: rgba(tokens.$colors-text-ondark, 0.6) !important;
158
+ }
159
+
160
+ .v-field__input {
161
+ color: tokens.$colors-text-ondark !important;
162
+ }
163
+ }
164
+
165
+ .v-theme--dark button.v-btn:hover :deep() {
166
+ background: rgba(tokens.$colors-text-ondark, 0.1);
167
+ }
168
+ </style>
@@ -0,0 +1,24 @@
1
+ export const config = {
2
+ toolbar: {
3
+ flat: true,
4
+ color: '#FFFFFF',
5
+ height: 'auto',
6
+ minHeight: '56px',
7
+ },
8
+ addBtn: {
9
+ variant: 'outlined',
10
+ color: 'primary',
11
+ class: 'my-1 px-2 px-md-4',
12
+ minWidth: '44px',
13
+ },
14
+ addIconLabel: {
15
+ class: 'mr-1',
16
+ },
17
+ textField: {
18
+ variant: 'underlined',
19
+ clearable: true,
20
+ singleLine: true,
21
+ hideDetails: true,
22
+ density: 'compact',
23
+ },
24
+ } as const
@@ -0,0 +1,6 @@
1
+ export const locales = {
2
+ rowText: (lignes: string, plural: boolean): string =>
3
+ `${lignes} ligne${plural ? 's' : ''}`,
4
+ search: 'Rechercher',
5
+ addBtnLabel: 'Ajouter',
6
+ }
@@ -0,0 +1,166 @@
1
+ import { describe, it, expect } from 'vitest'
2
+ import { mount } from '@vue/test-utils'
3
+ import { vuetify } from '@tests/unit/setup'
4
+ import TableToolbar from '../TableToolbar.vue'
5
+
6
+ describe('TableToolbar', () => {
7
+ it('should render', () => {
8
+ const wrapper = mount(TableToolbar, {
9
+ global: {
10
+ plugins: [vuetify],
11
+ },
12
+ props: {
13
+ nbFiltered: 1,
14
+ nbTotal: 2,
15
+ showAddBtn: true,
16
+ },
17
+ })
18
+
19
+ expect(wrapper.html()).toMatchSnapshot()
20
+ expect(wrapper.find('[data-test-id="nb-rows"]').text()).toContain('1/2')
21
+ })
22
+
23
+ it('renders correctly when all the item are displayed', () => {
24
+ const wrapper = mount(TableToolbar, {
25
+ global: {
26
+ plugins: [vuetify],
27
+ },
28
+ props: {
29
+ nbFiltered: 5,
30
+ nbTotal: 5,
31
+ },
32
+ })
33
+
34
+ expect(wrapper.html()).toMatchSnapshot()
35
+ expect(wrapper.find('[data-test-id="nb-rows"]').text()).toContain('5/5')
36
+ })
37
+
38
+ it('renders correctly when loading', () => {
39
+ const wrapper = mount(TableToolbar, {
40
+ global: {
41
+ plugins: [vuetify],
42
+ },
43
+ props: {
44
+ loading: true,
45
+ nbFiltered: 0,
46
+ nbTotal: 1,
47
+ },
48
+ })
49
+
50
+ expect(wrapper.html()).toMatchSnapshot()
51
+ expect(wrapper.find('.v-progress-linear').exists()).toBe(true)
52
+ })
53
+
54
+ it('renders correctly when the screen width <= 600px', async () => {
55
+ // @ts-expect-error - Property 'happyDOM' does not exist on type 'Window & typeof globalThis'.
56
+ window.happyDOM.setInnerWidth(600)
57
+
58
+ const wrapper = mount(TableToolbar, {
59
+ global: {
60
+ plugins: [vuetify],
61
+ },
62
+ props: {
63
+ nbFiltered: 0,
64
+ nbTotal: 1,
65
+ },
66
+ })
67
+
68
+ await wrapper.vm.$nextTick()
69
+
70
+ expect(wrapper.html()).toMatchSnapshot()
71
+ })
72
+
73
+ it('renders correctly with content slot', () => {
74
+ const wrapper = mount(TableToolbar, {
75
+ global: {
76
+ plugins: [vuetify],
77
+ },
78
+ props: {
79
+ nbFiltered: 0,
80
+ nbTotal: 1,
81
+ },
82
+ slots: {
83
+ searchLeft: '<p>search-left</p>',
84
+ },
85
+ })
86
+
87
+ expect(wrapper.html()).toMatchSnapshot()
88
+ })
89
+
90
+ it('renders correctly with no items', () => {
91
+ const wrapper = mount(TableToolbar, {
92
+ global: {
93
+ plugins: [vuetify],
94
+ },
95
+ props: {
96
+ nbFiltered: 0,
97
+ nbTotal: 0,
98
+ },
99
+ })
100
+
101
+ expect(wrapper.html()).toMatchSnapshot()
102
+ expect(wrapper.find('[data-test-id="nb-rows"]').exists()).toBe(false)
103
+ })
104
+
105
+ it('renders correctly with no nbFilters', () => {
106
+ const wrapper = mount(TableToolbar, {
107
+ global: {
108
+ plugins: [vuetify],
109
+ },
110
+ propsData: {
111
+ nbFiltered: undefined,
112
+ nbTotal: 50,
113
+ },
114
+ })
115
+ expect(wrapper.find('[data-test-id="nb-rows"]').text()).not.toContain('/')
116
+ expect(wrapper.find('[data-test-id="nb-rows"]').text()).toContain('50')
117
+ })
118
+
119
+ it('render correctly with the button add', () => {
120
+ const wrapper = mount(TableToolbar, {
121
+ global: {
122
+ plugins: [vuetify],
123
+ },
124
+ props: {
125
+ nbFiltered: 0,
126
+ nbTotal: 1,
127
+ showAddButton: true,
128
+ },
129
+ })
130
+
131
+ expect(wrapper.find('[data-test-id="add-btn"]').exists()).toBe(true)
132
+ })
133
+
134
+ it('emit an update:search event when the search input is updated', async () => {
135
+ const wrapper = mount(TableToolbar, {
136
+ global: {
137
+ plugins: [vuetify],
138
+ },
139
+ props: {
140
+ nbFiltered: 0,
141
+ nbTotal: 1,
142
+ },
143
+ })
144
+
145
+ await wrapper.find('[data-test-id="search-input"] input').setValue('search')
146
+
147
+ expect(wrapper.emitted('update:search')).toEqual([['search']])
148
+ })
149
+
150
+ it('emit an add event when the add button is clicked', async () => {
151
+ const wrapper = mount(TableToolbar, {
152
+ global: {
153
+ plugins: [vuetify],
154
+ },
155
+ props: {
156
+ nbFiltered: 0,
157
+ nbTotal: 1,
158
+ showAddButton: true,
159
+ },
160
+ })
161
+
162
+ await wrapper.find('[data-test-id="add-btn"]').trigger('click')
163
+
164
+ expect(wrapper.emitted('add')).toBeTruthy()
165
+ })
166
+ })