@bethinkpl/design-system 30.3.2 → 30.4.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.
Files changed (73) hide show
  1. package/dist/design-system.css +1 -1
  2. package/dist/design-system.js +5646 -5353
  3. package/dist/design-system.js.map +1 -1
  4. package/dist/i18n/en/globals.json +2 -1
  5. package/dist/i18n/en/statsLayout.json +12 -0
  6. package/dist/i18n/pl/globals.json +2 -1
  7. package/dist/i18n/pl/statsLayout.json +12 -0
  8. package/dist/lib/js/components/Buttons/HelpButton/HelpButton.vue.d.ts +3 -0
  9. package/dist/lib/js/components/Buttons/IconButton/IconButton.vue.d.ts +1 -0
  10. package/dist/lib/js/components/Cards/CardExpandable/CardExpandable.vue.d.ts +1 -0
  11. package/dist/lib/js/components/Chip/Chip.vue.d.ts +2 -0
  12. package/dist/lib/js/components/DatePickers/DateBox/DateBox.vue.d.ts +1 -0
  13. package/dist/lib/js/components/DatePickers/DatePicker/DatePicker.vue.d.ts +1 -0
  14. package/dist/lib/js/components/DatePickers/DateRangePicker/DateRangePicker.vue.d.ts +1 -0
  15. package/dist/lib/js/components/Drawer/DrawerHeader/DrawerHeader.vue.d.ts +4 -0
  16. package/dist/lib/js/components/Drawer/DrawerListItem/DrawerListItem.vue.d.ts +1 -0
  17. package/dist/lib/js/components/Drawer/DrawerSection/DrawerSection.vue.d.ts +3 -0
  18. package/dist/lib/js/components/Form/RadioButton/RadioButton.vue.d.ts +1 -0
  19. package/dist/lib/js/components/Headers/OverlayHeader/OverlayHeader.vue.d.ts +2 -0
  20. package/dist/lib/js/components/Headers/SectionHeader/SectionHeader.vue.d.ts +2 -0
  21. package/dist/lib/js/components/Icons/Icon/Icon.consts.d.ts +1 -0
  22. package/dist/lib/js/components/Modal/Modal.vue.d.ts +1 -0
  23. package/dist/lib/js/components/Modals/Modal/Modal.vue.d.ts +2 -0
  24. package/dist/lib/js/components/Modals/ModalDialog/ModalDialog.vue.d.ts +2 -0
  25. package/dist/lib/js/components/Outline/OutlineItem/OutlineItem.vue.d.ts +1 -0
  26. package/dist/lib/js/components/Pagination/Pagination.vue.d.ts +3 -0
  27. package/dist/lib/js/components/ProgressBar/ProgressBar.vue.d.ts +1 -0
  28. package/dist/lib/js/components/ProgressDonutChart/ProgressDonutChart.vue.d.ts +1 -0
  29. package/dist/lib/js/components/RichList/BasicRichListItem/BasicRichListItem.vue.d.ts +1 -0
  30. package/dist/lib/js/components/RichList/RichListItem/RichListItem.vue.d.ts +1 -0
  31. package/dist/lib/js/components/SelectList/SelectListItem/SelectListItem.vue.d.ts +1 -0
  32. package/dist/lib/js/components/SelectList/SelectListItemToggle/SelectListItemToggle.vue.d.ts +1 -0
  33. package/dist/lib/js/components/SpinnerLoading/SpinnerLoading.vue.d.ts +15 -0
  34. package/dist/lib/js/components/StatsLayout/StatsErrorBanner/StatsErrorBanner.vue.d.ts +6 -0
  35. package/dist/lib/js/components/StatsLayout/StatsFiltersDropdown/StatsFiltersDropdown.vue.d.ts +23 -0
  36. package/dist/lib/js/components/StatsLayout/StatsLayout.vue.d.ts +41 -0
  37. package/dist/lib/js/components/StatsLayout/StatsResetBanner/StatsResetBanner.vue.d.ts +34 -0
  38. package/dist/lib/js/components/StatsLayout/StatsSectionHeader/StatsSectionHeader.vue.d.ts +40 -0
  39. package/dist/lib/js/components/Statuses/AccessStatus/AccessStatus.vue.d.ts +1 -0
  40. package/dist/lib/js/components/Statuses/BlockadeStatus/BlockadeStatus.vue.d.ts +1 -0
  41. package/dist/lib/js/components/SurveyQuestions/SurveyQuestionOpenEnded/SurveyQuestionOpenEnded.vue.d.ts +3 -0
  42. package/dist/lib/js/components/SurveyQuestions/SurveyQuestionScale/SurveyQuestionScale.vue.d.ts +3 -0
  43. package/dist/lib/js/components/Switch/Switch.vue.d.ts +1 -0
  44. package/dist/lib/js/components/Tile/Tile.sb.shared.d.ts +1 -0
  45. package/dist/lib/js/components/Toggles/ToggleButton/ToggleButton.vue.d.ts +1 -0
  46. package/dist/lib/js/i18n/en.d.ts +11 -0
  47. package/dist/lib/js/i18n/index.d.ts +22 -0
  48. package/dist/lib/js/i18n/pl.d.ts +11 -0
  49. package/dist/lib/js/icons/fontawesome.d.ts +1 -0
  50. package/dist/lib/js/index.d.ts +3 -0
  51. package/lib/js/components/Buttons/HelpButton/HelpButton.vue +20 -3
  52. package/lib/js/components/SpinnerLoading/SpinnerLoading.stories.ts +42 -0
  53. package/lib/js/components/SpinnerLoading/SpinnerLoading.vue +33 -0
  54. package/lib/js/components/StatsLayout/StatsErrorBanner/StatsErrorBanner.stories.ts +32 -0
  55. package/lib/js/components/StatsLayout/StatsErrorBanner/StatsErrorBanner.vue +24 -0
  56. package/lib/js/components/StatsLayout/StatsFiltersDropdown/StatsFiltersDropdown.stories.ts +50 -0
  57. package/lib/js/components/StatsLayout/StatsFiltersDropdown/StatsFiltersDropdown.vue +55 -0
  58. package/lib/js/components/StatsLayout/StatsLayout.spec.ts +169 -0
  59. package/lib/js/components/StatsLayout/StatsLayout.stories.ts +156 -0
  60. package/lib/js/components/StatsLayout/StatsLayout.vue +173 -0
  61. package/lib/js/components/StatsLayout/StatsResetBanner/StatsResetBanner.stories.ts +48 -0
  62. package/lib/js/components/StatsLayout/StatsResetBanner/StatsResetBanner.vue +51 -0
  63. package/lib/js/components/StatsLayout/StatsSectionHeader/StatsSectionHeader.stories.ts +68 -0
  64. package/lib/js/components/StatsLayout/StatsSectionHeader/StatsSectionHeader.vue +72 -0
  65. package/lib/js/i18n/en/globals.json +2 -1
  66. package/lib/js/i18n/en/statsLayout.json +12 -0
  67. package/lib/js/i18n/en.ts +2 -0
  68. package/lib/js/i18n/pl/globals.json +2 -1
  69. package/lib/js/i18n/pl/statsLayout.json +12 -0
  70. package/lib/js/i18n/pl.ts +2 -0
  71. package/lib/js/icons/fontawesome.ts +2 -0
  72. package/lib/js/index.ts +3 -0
  73. package/package.json +1 -1
@@ -194,6 +194,7 @@ declare const _default: import('vue').DefineComponent<import('vue').ExtractPropT
194
194
  readonly FA_LOCK_KEYHOLE: import('@fortawesome/fontawesome-common-types').IconDefinition;
195
195
  readonly FA_MAGNIFYING_GLASS: import('@fortawesome/fontawesome-common-types').IconDefinition;
196
196
  readonly FA_MEDAL: import('@fortawesome/fontawesome-common-types').IconDefinition;
197
+ readonly FA_MEMO: import('@fortawesome/fontawesome-common-types').IconDefinition;
197
198
  readonly FA_MEMO_CIRCLE_INFO_SOLID: import('@fortawesome/fontawesome-common-types').IconDefinition;
198
199
  readonly FA_MEMO_CIRCLE_INFO: import('@fortawesome/fontawesome-common-types').IconDefinition;
199
200
  readonly FA_MESSAGE_QUESTION_SOLID: import('@fortawesome/fontawesome-common-types').IconDefinition;
@@ -832,6 +833,7 @@ declare const _default: import('vue').DefineComponent<import('vue').ExtractPropT
832
833
  readonly FA_LOCK_KEYHOLE: import('@fortawesome/fontawesome-common-types').IconDefinition;
833
834
  readonly FA_MAGNIFYING_GLASS: import('@fortawesome/fontawesome-common-types').IconDefinition;
834
835
  readonly FA_MEDAL: import('@fortawesome/fontawesome-common-types').IconDefinition;
836
+ readonly FA_MEMO: import('@fortawesome/fontawesome-common-types').IconDefinition;
835
837
  readonly FA_MEMO_CIRCLE_INFO_SOLID: import('@fortawesome/fontawesome-common-types').IconDefinition;
836
838
  readonly FA_MEMO_CIRCLE_INFO: import('@fortawesome/fontawesome-common-types').IconDefinition;
837
839
  readonly FA_MESSAGE_QUESTION_SOLID: import('@fortawesome/fontawesome-common-types').IconDefinition;
@@ -1367,6 +1369,7 @@ declare const _default: import('vue').DefineComponent<import('vue').ExtractPropT
1367
1369
  readonly FA_LOCK_KEYHOLE: import('@fortawesome/fontawesome-common-types').IconDefinition;
1368
1370
  readonly FA_MAGNIFYING_GLASS: import('@fortawesome/fontawesome-common-types').IconDefinition;
1369
1371
  readonly FA_MEDAL: import('@fortawesome/fontawesome-common-types').IconDefinition;
1372
+ readonly FA_MEMO: import('@fortawesome/fontawesome-common-types').IconDefinition;
1370
1373
  readonly FA_MEMO_CIRCLE_INFO_SOLID: import('@fortawesome/fontawesome-common-types').IconDefinition;
1371
1374
  readonly FA_MEMO_CIRCLE_INFO: import('@fortawesome/fontawesome-common-types').IconDefinition;
1372
1375
  readonly FA_MESSAGE_QUESTION_SOLID: import('@fortawesome/fontawesome-common-types').IconDefinition;
@@ -213,6 +213,7 @@ declare const _default: import('vue').DefineComponent<import('vue').ExtractPropT
213
213
  readonly FA_LOCK_KEYHOLE: import('@fortawesome/fontawesome-common-types').IconDefinition;
214
214
  readonly FA_MAGNIFYING_GLASS: import('@fortawesome/fontawesome-common-types').IconDefinition;
215
215
  readonly FA_MEDAL: import('@fortawesome/fontawesome-common-types').IconDefinition;
216
+ readonly FA_MEMO: import('@fortawesome/fontawesome-common-types').IconDefinition;
216
217
  readonly FA_MEMO_CIRCLE_INFO_SOLID: import('@fortawesome/fontawesome-common-types').IconDefinition;
217
218
  readonly FA_MEMO_CIRCLE_INFO: import('@fortawesome/fontawesome-common-types').IconDefinition;
218
219
  readonly FA_MESSAGE_QUESTION_SOLID: import('@fortawesome/fontawesome-common-types').IconDefinition;
@@ -805,6 +806,7 @@ declare const _default: import('vue').DefineComponent<import('vue').ExtractPropT
805
806
  readonly FA_LOCK_KEYHOLE: import('@fortawesome/fontawesome-common-types').IconDefinition;
806
807
  readonly FA_MAGNIFYING_GLASS: import('@fortawesome/fontawesome-common-types').IconDefinition;
807
808
  readonly FA_MEDAL: import('@fortawesome/fontawesome-common-types').IconDefinition;
809
+ readonly FA_MEMO: import('@fortawesome/fontawesome-common-types').IconDefinition;
808
810
  readonly FA_MEMO_CIRCLE_INFO_SOLID: import('@fortawesome/fontawesome-common-types').IconDefinition;
809
811
  readonly FA_MEMO_CIRCLE_INFO: import('@fortawesome/fontawesome-common-types').IconDefinition;
810
812
  readonly FA_MESSAGE_QUESTION_SOLID: import('@fortawesome/fontawesome-common-types').IconDefinition;
@@ -1513,6 +1515,7 @@ declare const _default: import('vue').DefineComponent<import('vue').ExtractPropT
1513
1515
  readonly FA_LOCK_KEYHOLE: import('@fortawesome/fontawesome-common-types').IconDefinition;
1514
1516
  readonly FA_MAGNIFYING_GLASS: import('@fortawesome/fontawesome-common-types').IconDefinition;
1515
1517
  readonly FA_MEDAL: import('@fortawesome/fontawesome-common-types').IconDefinition;
1518
+ readonly FA_MEMO: import('@fortawesome/fontawesome-common-types').IconDefinition;
1516
1519
  readonly FA_MEMO_CIRCLE_INFO_SOLID: import('@fortawesome/fontawesome-common-types').IconDefinition;
1517
1520
  readonly FA_MEMO_CIRCLE_INFO: import('@fortawesome/fontawesome-common-types').IconDefinition;
1518
1521
  readonly FA_MESSAGE_QUESTION_SOLID: import('@fortawesome/fontawesome-common-types').IconDefinition;
@@ -213,6 +213,7 @@ declare const _default: import('vue').DefineComponent<import('vue').ExtractPropT
213
213
  readonly FA_LOCK_KEYHOLE: import('@fortawesome/fontawesome-common-types').IconDefinition;
214
214
  readonly FA_MAGNIFYING_GLASS: import('@fortawesome/fontawesome-common-types').IconDefinition;
215
215
  readonly FA_MEDAL: import('@fortawesome/fontawesome-common-types').IconDefinition;
216
+ readonly FA_MEMO: import('@fortawesome/fontawesome-common-types').IconDefinition;
216
217
  readonly FA_MEMO_CIRCLE_INFO_SOLID: import('@fortawesome/fontawesome-common-types').IconDefinition;
217
218
  readonly FA_MEMO_CIRCLE_INFO: import('@fortawesome/fontawesome-common-types').IconDefinition;
218
219
  readonly FA_MESSAGE_QUESTION_SOLID: import('@fortawesome/fontawesome-common-types').IconDefinition;
@@ -173,6 +173,7 @@ export declare const data: () => {
173
173
  readonly FA_LOCK_KEYHOLE: import('@fortawesome/fontawesome-common-types').IconDefinition;
174
174
  readonly FA_MAGNIFYING_GLASS: import('@fortawesome/fontawesome-common-types').IconDefinition;
175
175
  readonly FA_MEDAL: import('@fortawesome/fontawesome-common-types').IconDefinition;
176
+ readonly FA_MEMO: import('@fortawesome/fontawesome-common-types').IconDefinition;
176
177
  readonly FA_MEMO_CIRCLE_INFO_SOLID: import('@fortawesome/fontawesome-common-types').IconDefinition;
177
178
  readonly FA_MEMO_CIRCLE_INFO: import('@fortawesome/fontawesome-common-types').IconDefinition;
178
179
  readonly FA_MESSAGE_QUESTION_SOLID: import('@fortawesome/fontawesome-common-types').IconDefinition;
@@ -229,6 +229,7 @@ declare const _default: import('vue').DefineComponent<import('vue').ExtractPropT
229
229
  readonly FA_LOCK_KEYHOLE: import('@fortawesome/fontawesome-common-types').IconDefinition;
230
230
  readonly FA_MAGNIFYING_GLASS: import('@fortawesome/fontawesome-common-types').IconDefinition;
231
231
  readonly FA_MEDAL: import('@fortawesome/fontawesome-common-types').IconDefinition;
232
+ readonly FA_MEMO: import('@fortawesome/fontawesome-common-types').IconDefinition;
232
233
  readonly FA_MEMO_CIRCLE_INFO_SOLID: import('@fortawesome/fontawesome-common-types').IconDefinition;
233
234
  readonly FA_MEMO_CIRCLE_INFO: import('@fortawesome/fontawesome-common-types').IconDefinition;
234
235
  readonly FA_MESSAGE_QUESTION_SOLID: import('@fortawesome/fontawesome-common-types').IconDefinition;
@@ -1,4 +1,14 @@
1
1
  declare const _default: {
2
+ "ds.statsLayout.default.leftColumnLabel": string;
3
+ "ds.statsLayout.default.rightColumnLabel": string;
4
+ "ds.statsLayout.filtersDropdown.title": string;
5
+ "ds.statsLayout.sectionHeader.title": string;
6
+ "ds.statsLayout.statsErrorBanner.buttonText": string;
7
+ "ds.statsLayout.statsErrorBanner.message": string;
8
+ "ds.statsLayout.statsErrorBanner.title": string;
9
+ "ds.statsLayout.statsResetBanner.buttonText": string;
10
+ "ds.statsLayout.statsResetBanner.message": string;
11
+ "ds.statsLayout.statsResetBanner.title": string;
2
12
  "ds.pagination.from": string;
3
13
  "ds.accessStatus.status.active": string;
4
14
  "ds.accessStatus.status.awaiting": string;
@@ -7,5 +17,6 @@ declare const _default: {
7
17
  "ds.accessStatus.status.suspended": string;
8
18
  "ds.globals.back": string;
9
19
  "ds.globals.confirmation": string;
20
+ "ds.globals.loading": string;
10
21
  };
11
22
  export default _default;
@@ -4,6 +4,16 @@ import { default as pl } from './pl';
4
4
  export type MessageSchema = typeof pl;
5
5
  export declare const messages: {
6
6
  pl: {
7
+ "ds.statsLayout.default.leftColumnLabel": string;
8
+ "ds.statsLayout.default.rightColumnLabel": string;
9
+ "ds.statsLayout.filtersDropdown.title": string;
10
+ "ds.statsLayout.sectionHeader.title": string;
11
+ "ds.statsLayout.statsErrorBanner.buttonText": string;
12
+ "ds.statsLayout.statsErrorBanner.message": string;
13
+ "ds.statsLayout.statsErrorBanner.title": string;
14
+ "ds.statsLayout.statsResetBanner.buttonText": string;
15
+ "ds.statsLayout.statsResetBanner.message": string;
16
+ "ds.statsLayout.statsResetBanner.title": string;
7
17
  "ds.pagination.from": string;
8
18
  "ds.accessStatus.status.active": string;
9
19
  "ds.accessStatus.status.awaiting": string;
@@ -12,8 +22,19 @@ export declare const messages: {
12
22
  "ds.accessStatus.status.suspended": string;
13
23
  "ds.globals.back": string;
14
24
  "ds.globals.confirmation": string;
25
+ "ds.globals.loading": string;
15
26
  };
16
27
  en: {
28
+ "ds.statsLayout.default.leftColumnLabel": string;
29
+ "ds.statsLayout.default.rightColumnLabel": string;
30
+ "ds.statsLayout.filtersDropdown.title": string;
31
+ "ds.statsLayout.sectionHeader.title": string;
32
+ "ds.statsLayout.statsErrorBanner.buttonText": string;
33
+ "ds.statsLayout.statsErrorBanner.message": string;
34
+ "ds.statsLayout.statsErrorBanner.title": string;
35
+ "ds.statsLayout.statsResetBanner.buttonText": string;
36
+ "ds.statsLayout.statsResetBanner.message": string;
37
+ "ds.statsLayout.statsResetBanner.title": string;
17
38
  "ds.pagination.from": string;
18
39
  "ds.accessStatus.status.active": string;
19
40
  "ds.accessStatus.status.awaiting": string;
@@ -22,6 +43,7 @@ export declare const messages: {
22
43
  "ds.accessStatus.status.suspended": string;
23
44
  "ds.globals.back": string;
24
45
  "ds.globals.confirmation": string;
46
+ "ds.globals.loading": string;
25
47
  };
26
48
  };
27
49
  export type ValidI18nKey = keyof MessageSchema;
@@ -1,4 +1,14 @@
1
1
  declare const _default: {
2
+ "ds.statsLayout.default.leftColumnLabel": string;
3
+ "ds.statsLayout.default.rightColumnLabel": string;
4
+ "ds.statsLayout.filtersDropdown.title": string;
5
+ "ds.statsLayout.sectionHeader.title": string;
6
+ "ds.statsLayout.statsErrorBanner.buttonText": string;
7
+ "ds.statsLayout.statsErrorBanner.message": string;
8
+ "ds.statsLayout.statsErrorBanner.title": string;
9
+ "ds.statsLayout.statsResetBanner.buttonText": string;
10
+ "ds.statsLayout.statsResetBanner.message": string;
11
+ "ds.statsLayout.statsResetBanner.title": string;
2
12
  "ds.pagination.from": string;
3
13
  "ds.accessStatus.status.active": string;
4
14
  "ds.accessStatus.status.awaiting": string;
@@ -7,5 +17,6 @@ declare const _default: {
7
17
  "ds.accessStatus.status.suspended": string;
8
18
  "ds.globals.back": string;
9
19
  "ds.globals.confirmation": string;
20
+ "ds.globals.loading": string;
10
21
  };
11
22
  export default _default;
@@ -160,6 +160,7 @@ export declare const FONTAWESOME_ICONS: {
160
160
  readonly FA_LOCK_KEYHOLE: import('@fortawesome/fontawesome-common-types').IconDefinition;
161
161
  readonly FA_MAGNIFYING_GLASS: import('@fortawesome/fontawesome-common-types').IconDefinition;
162
162
  readonly FA_MEDAL: import('@fortawesome/fontawesome-common-types').IconDefinition;
163
+ readonly FA_MEMO: import('@fortawesome/fontawesome-common-types').IconDefinition;
163
164
  readonly FA_MEMO_CIRCLE_INFO_SOLID: import('@fortawesome/fontawesome-common-types').IconDefinition;
164
165
  readonly FA_MEMO_CIRCLE_INFO: import('@fortawesome/fontawesome-common-types').IconDefinition;
165
166
  readonly FA_MESSAGE_QUESTION_SOLID: import('@fortawesome/fontawesome-common-types').IconDefinition;
@@ -179,6 +179,9 @@ export * from './components/Tooltip/Tooltip.consts';
179
179
  export { default as DsImage } from './components/Image';
180
180
  export * from './components/Skeleton/Skeleton.consts';
181
181
  export { default as DsSkeleton } from './components/Skeleton/Skeleton.vue';
182
+ export { default as DsStatsLayout } from './components/StatsLayout/StatsLayout.vue';
183
+ export { default as DsStatsResetBanner } from './components/StatsLayout/StatsResetBanner/StatsResetBanner.vue';
184
+ export { default as DsStatsSectionHeader } from './components/StatsLayout/StatsSectionHeader/StatsSectionHeader.vue';
182
185
  export { initializePrimeVue } from './primevue';
183
186
  export { initialize as initializeIcons, initializeWithDomWatcher as initializeIconsWithDomWatcher, } from './icons/fontawesome';
184
187
  export type { IconDefinition } from './icons/fontawesome';
@@ -3,7 +3,7 @@
3
3
  <icon-button
4
4
  :icon="ICONS.FA_CIRCLE_QUESTION"
5
5
  :color="ICON_BUTTON_COLORS.NEUTRAL_WEAK"
6
- :size="ICON_BUTTON_SIZES.X_SMALL"
6
+ :size="size"
7
7
  :state="isDisabled ? ICON_BUTTON_STATES.DISABLED : ICON_BUTTON_STATES.DEFAULT"
8
8
  :touchable="false"
9
9
  v-bind="$attrs"
@@ -11,7 +11,13 @@
11
11
  />
12
12
  </tooltip>
13
13
  <slot v-if="isOpen" name="modal" :on-close="onClose">
14
- <modal :header-title="modalTitle" :size="modalSize" @close-modal="onClose">
14
+ <modal
15
+ :header-title="modalTitle"
16
+ :size="modalSize"
17
+ :footer-primary-button-text="t('ds.globals.confirmation')"
18
+ @close-modal="onClose"
19
+ @primary-button-click="onClose"
20
+ >
15
21
  <slot name="modalContent" />
16
22
  </modal>
17
23
  </slot>
@@ -23,16 +29,27 @@ import IconButton, {
23
29
  ICON_BUTTON_COLORS,
24
30
  ICON_BUTTON_SIZES,
25
31
  ICON_BUTTON_STATES,
32
+ IconButtonSize,
26
33
  } from '../IconButton';
27
34
  import Tooltip from '../../Tooltip';
28
35
  import { ICONS } from '../../Icons/Icon';
29
36
  import Modal, { ModalSize } from '../../Modals/Modal';
37
+ import { useLegacyI18n } from '../../../composables/useLegacyI18n';
30
38
 
31
- defineProps<{
39
+ const { t } = useLegacyI18n();
40
+
41
+ const {
42
+ tooltipText,
43
+ isDisabled,
44
+ modalTitle,
45
+ modalSize,
46
+ size = ICON_BUTTON_SIZES.X_SMALL,
47
+ } = defineProps<{
32
48
  tooltipText?: string;
33
49
  isDisabled?: boolean;
34
50
  modalTitle?: string;
35
51
  modalSize?: ModalSize;
52
+ size?: IconButtonSize;
36
53
  }>();
37
54
 
38
55
  defineSlots<{
@@ -0,0 +1,42 @@
1
+ import { Args, ArgTypes, Meta, StoryObj } from '@storybook/vue3';
2
+ import SpinnerLoading from './SpinnerLoading.vue';
3
+ import type { ComponentProps } from 'vue-component-type-helpers';
4
+
5
+ type SpinnerLoadingProps = ComponentProps<typeof SpinnerLoading>;
6
+
7
+ const meta: Meta<SpinnerLoadingProps> = {
8
+ title: 'Components/SpinnerLoading',
9
+ component: SpinnerLoading,
10
+ render: (args) => {
11
+ return {
12
+ components: { SpinnerLoading },
13
+ setup() {
14
+ return {
15
+ args,
16
+ };
17
+ },
18
+ template: '<spinner-loading v-bind="args" />',
19
+ };
20
+ },
21
+ parameters: {
22
+ design: {
23
+ type: 'figma',
24
+ url: 'https://www.figma.com/design/WeJCbVlnkL9HmEcoBpu5NU/LMS---Specific-Components---Limbo?node-id=108-7632&m=dev',
25
+ },
26
+ },
27
+ };
28
+ export default meta;
29
+
30
+ type Story = StoryObj<SpinnerLoadingProps>;
31
+
32
+ export const Interactive: Story = {
33
+ args: {
34
+ message: '',
35
+ } as Args,
36
+ };
37
+
38
+ Interactive.argTypes = {
39
+ message: {
40
+ control: 'text',
41
+ },
42
+ } as ArgTypes;
@@ -0,0 +1,33 @@
1
+ <template>
2
+ <div class="ds-spinnerLoading">
3
+ <ds-icon :icon="ICONS.FAD_SPINNER_THIRD" :size="ICON_SIZES.SMALL" spinning />
4
+ <div>{{ message || t('ds.globals.loading') }}</div>
5
+ </div>
6
+ </template>
7
+
8
+ <style scoped lang="scss">
9
+ @import '../../../styles/settings/typography/tokens';
10
+ @import '../../../styles/settings/colors/tokens';
11
+ @import '../../../styles/settings/spacings';
12
+
13
+ .ds-spinnerLoading {
14
+ @include text-m-default-regular();
15
+
16
+ align-items: center;
17
+ color: $color-neutral-text;
18
+ display: inline-flex;
19
+ gap: $space-2xs;
20
+ }
21
+ </style>
22
+
23
+ <script setup lang="ts">
24
+ import { ICON_SIZES, ICONS } from '../Icons/Icon/Icon.consts';
25
+ import DsIcon from '../Icons/Icon/Icon.vue';
26
+ import { useLegacyI18n } from '../../composables/useLegacyI18n';
27
+
28
+ const { t } = useLegacyI18n();
29
+
30
+ const { message } = defineProps<{
31
+ message?: string;
32
+ }>();
33
+ </script>
@@ -0,0 +1,32 @@
1
+ import { Meta, StoryObj } from '@storybook/vue3';
2
+ import StatsErrorBanner from './StatsErrorBanner.vue';
3
+ import type { ComponentProps } from 'vue-component-type-helpers';
4
+
5
+ type StatsErrorBannerProps = ComponentProps<typeof StatsErrorBanner>;
6
+
7
+ const meta: Meta<StatsErrorBannerProps> = {
8
+ title: 'Components/StatsLayout/StatsErrorBanner',
9
+ component: StatsErrorBanner,
10
+ render: (args) => {
11
+ return {
12
+ components: { StatsErrorBanner },
13
+ setup() {
14
+ return {
15
+ args,
16
+ };
17
+ },
18
+ template: '<stats-error-banner v-bind="args"></stats-error-banner>',
19
+ };
20
+ },
21
+ parameters: {
22
+ design: {
23
+ type: 'figma',
24
+ url: 'https://www.figma.com/design/izQdYyiBR1GQgFkaOIfIJI/LMS---DS-Components?node-id=14870-10790&m=dev',
25
+ },
26
+ },
27
+ };
28
+ export default meta;
29
+
30
+ type Story = StoryObj<StatsErrorBannerProps>;
31
+
32
+ export const Interactive: Story = {};
@@ -0,0 +1,24 @@
1
+ <template>
2
+ <ds-banner
3
+ :title="t('ds.statsLayout.statsErrorBanner.title')"
4
+ :button-text="t('ds.statsLayout.statsErrorBanner.buttonText')"
5
+ :icon="ICONS.FA_CIRCLE_EXCLAMATION"
6
+ :color="BANNER_COLORS.DANGER"
7
+ @button-clicked="$emit('button-clicked')"
8
+ >
9
+ <template #defaultText> {{ t('ds.statsLayout.statsErrorBanner.message') }} </template>
10
+ </ds-banner>
11
+ </template>
12
+
13
+ <script setup lang="ts">
14
+ import { ICONS } from '../../Icons/Icon';
15
+ import { BANNER_COLORS } from '../../Banner/Banner.consts';
16
+ import DsBanner from '../../Banner/Banner.vue';
17
+ import { useLegacyI18n } from '../../../composables/useLegacyI18n';
18
+
19
+ const { t } = useLegacyI18n();
20
+
21
+ defineEmits<{
22
+ (e: 'button-clicked'): void;
23
+ }>();
24
+ </script>
@@ -0,0 +1,50 @@
1
+ import { Args, ArgTypes, Meta, StoryObj } from '@storybook/vue3';
2
+ import StatsFiltersDropdown from './StatsFiltersDropdown.vue';
3
+ import type { ComponentProps } from 'vue-component-type-helpers';
4
+
5
+ type StatsFiltersDropdownProps = ComponentProps<typeof StatsFiltersDropdown>;
6
+
7
+ const meta: Meta<StatsFiltersDropdownProps> = {
8
+ title: 'Components/StatsLayout/StatsFiltersDropdown',
9
+ component: StatsFiltersDropdown,
10
+ render: (args) => {
11
+ return {
12
+ components: { StatsFiltersDropdown },
13
+ setup() {
14
+ return {
15
+ args,
16
+ };
17
+ },
18
+ template: '<stats-filters-dropdown v-bind="args"></stats-filters-dropdown>',
19
+ };
20
+ },
21
+ parameters: {
22
+ design: {
23
+ type: 'figma',
24
+ url: 'https://www.figma.com/design/izQdYyiBR1GQgFkaOIfIJI/LMS---DS-Components?node-id=14870-10787&m=dev',
25
+ },
26
+ },
27
+ };
28
+ export default meta;
29
+
30
+ type Story = StoryObj<StatsFiltersDropdownProps>;
31
+
32
+ export const Interactive: Story = {
33
+ args: {
34
+ filterItems: [
35
+ { key: 'all', label: 'All' },
36
+ { key: 'active', label: 'Active' },
37
+ { key: 'inactive', label: 'Inactive' },
38
+ ],
39
+ selectedFilterKey: 'all',
40
+ } as Args,
41
+ };
42
+
43
+ Interactive.argTypes = {
44
+ filterItems: {
45
+ control: 'object',
46
+ },
47
+ selectedFilterKey: {
48
+ control: 'text',
49
+ },
50
+ } as ArgTypes;
@@ -0,0 +1,55 @@
1
+ <template>
2
+ <ds-dropdown :placement="DROPDOWN_PLACEMENTS.BOTTOM_END">
3
+ <template #reference="{ isOpened }">
4
+ <ds-button
5
+ :icon-left="ICONS.FA_CHART_COLUMN"
6
+ :icon-right="isOpened ? ICONS.FA_ANGLE_UP : ICONS.FA_ANGLE_DOWN"
7
+ :type="BUTTON_TYPES.TEXT"
8
+ >{{ t('ds.statsLayout.filtersDropdown.title') }}</ds-button
9
+ >
10
+ </template>
11
+ <template #default="{ close }">
12
+ <ds-select-list>
13
+ <ds-select-list-item
14
+ v-for="filterItem in filterItems"
15
+ :key="filterItem.key"
16
+ :label="filterItem.label"
17
+ :is-selected="filterItem.key === selectedFilterKey"
18
+ @click="select(filterItem, close)"
19
+ />
20
+ </ds-select-list>
21
+ </template>
22
+ </ds-dropdown>
23
+ </template>
24
+
25
+ <script setup lang="ts">
26
+ import DsButton from '../../Buttons/Button';
27
+ import { ICONS } from '../../Icons/Icon/Icon.consts';
28
+ import DsDropdown from '../../Dropdown/Dropdown.vue';
29
+ import DsSelectList from '../../SelectList/SelectList.vue';
30
+ import DsSelectListItem from '../../SelectList/SelectListItem/SelectListItem.vue';
31
+ import { BUTTON_TYPES } from '../../Buttons/Button/Button.consts';
32
+ import { DROPDOWN_PLACEMENTS } from '../../Dropdown/Dropdown.consts';
33
+ import { useLegacyI18n } from '../../../composables/useLegacyI18n';
34
+
35
+ interface FilterItem {
36
+ key: string;
37
+ label: string;
38
+ }
39
+
40
+ export interface StatsFiltersDropdownProps {
41
+ filterItems?: Array<FilterItem>;
42
+ selectedFilterKey?: string | null;
43
+ }
44
+
45
+ const { filterItems = [], selectedFilterKey = null } = defineProps<StatsFiltersDropdownProps>();
46
+
47
+ const emit = defineEmits<{ select: [key: string] }>();
48
+
49
+ const { t } = useLegacyI18n();
50
+
51
+ const select = (filterItem: FilterItem, close: () => void) => {
52
+ emit('select', filterItem.key);
53
+ close();
54
+ };
55
+ </script>
@@ -0,0 +1,169 @@
1
+ import { describe, expect, it } from 'vitest';
2
+ import { ComponentMountingOptions, mount } from '@vue/test-utils';
3
+ import { h } from 'vue';
4
+
5
+ import StatsLayout from './StatsLayout.vue';
6
+
7
+ describe('StatsLayout', () => {
8
+ const createComponent = (options: ComponentMountingOptions<typeof StatsLayout> = {}) => {
9
+ return mount(StatsLayout, options);
10
+ };
11
+
12
+ it('should create', () => {
13
+ const component = createComponent();
14
+
15
+ expect(component.exists()).toBe(true);
16
+ });
17
+
18
+ it('should render main layout class', () => {
19
+ const component = createComponent();
20
+
21
+ expect(component.find('.ds-statsLayout').exists()).toBe(true);
22
+ });
23
+
24
+ describe('slots', () => {
25
+ it('should render dynamic statsItem slots', () => {
26
+ const component = createComponent({
27
+ slots: {
28
+ 'statsItem-0': () => [h('div', { class: 'test-item-0' }, 'Item 0')],
29
+ 'statsItem-1': () => [h('div', { class: 'test-item-1' }, 'Item 1')],
30
+ 'statsItem-2': () => [h('div', { class: 'test-item-2' }, 'Item 2')],
31
+ },
32
+ });
33
+
34
+ expect(component.find('.test-item-0').exists()).toBe(true);
35
+ expect(component.find('.test-item-1').exists()).toBe(true);
36
+ expect(component.find('.test-item-2').exists()).toBe(true);
37
+ });
38
+
39
+ it('should render dividers between statsItems', () => {
40
+ const component = createComponent({
41
+ slots: {
42
+ 'statsItem-0': () => [h('div', 'Item 0')],
43
+ 'statsItem-1': () => [h('div', 'Item 1')],
44
+ },
45
+ });
46
+
47
+ const dividers = component.findAll('.ds-statsLayout__statsDivider');
48
+ expect(dividers.length).toBe(2);
49
+ });
50
+ });
51
+
52
+ describe('props', () => {
53
+ describe('hasGridHeader', () => {
54
+ it('should render grid headers by default', () => {
55
+ const component = createComponent();
56
+
57
+ const gridHeaders = component.findAll('.ds-statsLayout__gridHeader');
58
+ expect(gridHeaders.length).toBe(2);
59
+ });
60
+
61
+ it('should not render grid headers when hasGridHeader is false', () => {
62
+ const component = createComponent({
63
+ props: {
64
+ hasGridHeader: false,
65
+ },
66
+ });
67
+
68
+ const gridHeaders = component.findAll('.ds-statsLayout__gridHeader');
69
+ expect(gridHeaders.length).toBe(0);
70
+ });
71
+ });
72
+
73
+ describe('hasRightColumn', () => {
74
+ it('should render right column by default', () => {
75
+ const component = createComponent();
76
+
77
+ const rightColumns = component.findAll('.ds-statsLayout__gridHeaderRightColumn');
78
+ expect(rightColumns.length).toBeGreaterThan(0);
79
+ });
80
+
81
+ it('should not render right column when hasRightColumn is false', () => {
82
+ const component = createComponent({
83
+ props: {
84
+ hasRightColumn: false,
85
+ },
86
+ });
87
+
88
+ const rightColumns = component.findAll('.ds-statsLayout__gridHeaderRightColumn');
89
+ expect(rightColumns.length).toBe(0);
90
+ });
91
+ });
92
+
93
+ describe('isLoading', () => {
94
+ it('should not show loading state by default', () => {
95
+ const component = createComponent();
96
+
97
+ expect(component.find('.ds-statsLayout__loading').exists()).toBe(false);
98
+ });
99
+
100
+ it('should show loading state when isLoading is true', () => {
101
+ const component = createComponent({
102
+ props: {
103
+ isLoading: true,
104
+ },
105
+ });
106
+
107
+ expect(component.find('.ds-statsLayout__loading').exists()).toBe(true);
108
+ });
109
+
110
+ it('should hide content when loading', () => {
111
+ const component = createComponent({
112
+ props: {
113
+ isLoading: true,
114
+ },
115
+ slots: {
116
+ overallStatsItem: () => [h('div', { class: 'test-content' }, 'Content')],
117
+ },
118
+ });
119
+
120
+ expect(component.find('.ds-statsLayout__content').exists()).toBe(false);
121
+ expect(component.find('.test-content').exists()).toBe(false);
122
+ });
123
+ });
124
+
125
+ describe('hasError', () => {
126
+ it('should not show error state by default', () => {
127
+ const component = createComponent();
128
+
129
+ expect(component.find('.ds-statsLayout__error').exists()).toBe(false);
130
+ });
131
+
132
+ it('should show error state when hasError is true', () => {
133
+ const component = createComponent({
134
+ props: {
135
+ hasError: true,
136
+ },
137
+ });
138
+
139
+ expect(component.find('.ds-statsLayout__error').exists()).toBe(true);
140
+ });
141
+
142
+ it('should hide content when error', () => {
143
+ const component = createComponent({
144
+ props: {
145
+ hasError: true,
146
+ },
147
+ slots: {
148
+ overallStatsItem: () => [h('div', { class: 'test-content' }, 'Content')],
149
+ },
150
+ });
151
+
152
+ expect(component.find('.ds-statsLayout__content').exists()).toBe(false);
153
+ expect(component.find('.test-content').exists()).toBe(false);
154
+ });
155
+
156
+ it('should prioritize loading over error', () => {
157
+ const component = createComponent({
158
+ props: {
159
+ isLoading: true,
160
+ hasError: true,
161
+ },
162
+ });
163
+
164
+ expect(component.find('.ds-statsLayout__loading').exists()).toBe(true);
165
+ expect(component.find('.ds-statsLayout__error').exists()).toBe(false);
166
+ });
167
+ });
168
+ });
169
+ });