@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
@@ -0,0 +1,156 @@
1
+ import { Args, ArgTypes, Meta, StoryObj } from '@storybook/vue3';
2
+ import StatsLayout from './StatsLayout.vue';
3
+ import type { ComponentProps } from 'vue-component-type-helpers';
4
+ import StatsSectionHeader from './StatsSectionHeader/StatsSectionHeader.vue';
5
+ import StatsResetBanner from './StatsResetBanner/StatsResetBanner.vue';
6
+ import SlotPlaceholder from '../../../../.storybook/SlotPlaceholder/SlotPlaceholder.vue';
7
+
8
+ type StatsLayoutProps = ComponentProps<typeof StatsLayout>;
9
+
10
+ const prepareItemsTemplate = (
11
+ itemsCount: number = 5,
12
+ itemTemplate: string = '<slot-placeholder/>',
13
+ ) => {
14
+ return Array.from({ length: itemsCount }, (_, index) => {
15
+ return `<template v-slot:["statsItem-${index}"]>${itemTemplate}</template>`;
16
+ }).join('');
17
+ };
18
+
19
+ const meta: Meta<StatsLayoutProps> = {
20
+ title: 'Components/StatsLayout/StatsLayout',
21
+ component: StatsLayout,
22
+ render: (args) => {
23
+ return {
24
+ components: { StatsLayout, SlotPlaceholder },
25
+ setup() {
26
+ return { args };
27
+ },
28
+ template: `
29
+ <stats-layout v-bind="args">
30
+ <template #sectionHeader>
31
+ <slot-placeholder label="Slot nagłówka sekcji" />
32
+ </template>
33
+ <template #overallStatsItem><slot-placeholder /></template>
34
+ <template #resetBanner>
35
+ <slot-placeholder label="Slot banera resetu" />
36
+ </template>
37
+ ${prepareItemsTemplate()}
38
+ </stats-layout>
39
+ `,
40
+ };
41
+ },
42
+ args: {
43
+ hasGridHeader: true,
44
+ hasRightColumn: true,
45
+ leftColumnLabel: 'Zakres',
46
+ rightColumnLabel: 'Wyniki',
47
+ statsItemsHeaderLabel: '{Nazwa użytej taksonomii}',
48
+ isLoading: false,
49
+ hasError: false,
50
+ } as Args,
51
+ argTypes: {
52
+ hasGridHeader: {
53
+ control: 'boolean',
54
+ },
55
+ hasRightColumn: {
56
+ control: 'boolean',
57
+ },
58
+ leftColumnLabel: {
59
+ control: 'text',
60
+ },
61
+ rightColumnLabel: {
62
+ control: 'text',
63
+ },
64
+ statsItemsHeaderLabel: {
65
+ control: 'text',
66
+ },
67
+ isLoading: {
68
+ control: 'boolean',
69
+ },
70
+ hasError: {
71
+ control: 'boolean',
72
+ },
73
+ } as ArgTypes,
74
+ parameters: {
75
+ design: {
76
+ type: 'figma',
77
+ url: 'https://www.figma.com/design/izQdYyiBR1GQgFkaOIfIJI/LMS---DS-Components?node-id=14877-39964&m=dev',
78
+ },
79
+ },
80
+ };
81
+ export default meta;
82
+
83
+ type Story = StoryObj<StatsLayoutProps>;
84
+
85
+ export const Raw: Story = {};
86
+
87
+ export const WithHeaders: Story = {
88
+ render: (args) => {
89
+ return {
90
+ components: { StatsLayout, StatsSectionHeader, StatsResetBanner, SlotPlaceholder },
91
+ setup() {
92
+ return {
93
+ args,
94
+ filterItems: [
95
+ { key: 'all', label: 'Wszystkie' },
96
+ { key: 'week', label: 'Tydzień' },
97
+ { key: 'month', label: 'Miesiąc' },
98
+ ],
99
+ };
100
+ },
101
+ template: `
102
+ <stats-layout v-bind="args">
103
+ <template #sectionHeader>
104
+ <stats-section-header :filter-items="filterItems" selected-filter-key="all">
105
+ <template #infoModalContent><span>Info content for filter</span></template>
106
+ </stats-section-header>
107
+ </template>
108
+ <template #overallStatsItem><slot-placeholder /></template>
109
+ <template #resetBanner>
110
+ <stats-reset-banner timeMarker="2 czerwca 2025" infoModalTitle="Info modal title">
111
+ <template #infoModalContent><p>Info content for reset banner</p></template>
112
+ </stats-reset-banner>
113
+ </template>
114
+ ${prepareItemsTemplate()}
115
+ </stats-layout>
116
+ `,
117
+ };
118
+ },
119
+ };
120
+
121
+ export const MultipleColumns: Story = {
122
+ render: (args) => {
123
+ const itemTemplate = `<div><slot-placeholder label="Slot left" /></div><div><slot-placeholder label="Slot" /></div>`;
124
+
125
+ return {
126
+ components: { StatsLayout, StatsSectionHeader, StatsResetBanner, SlotPlaceholder },
127
+ setup() {
128
+ return {
129
+ args,
130
+ filterItems: [
131
+ { key: 'all', label: 'Wszystkie' },
132
+ { key: 'week', label: 'Tydzień' },
133
+ { key: 'month', label: 'Miesiąc' },
134
+ ],
135
+ };
136
+ },
137
+ template: `
138
+ <stats-layout v-bind="args">
139
+ <template #sectionHeader>
140
+ <stats-section-header :filter-items="filterItems" selected-filter-key="all">
141
+ <template #infoModalContent><span>Info content for filter</span></template>
142
+ </stats-section-header>
143
+ </template>
144
+ <template #overallStatsItem>
145
+ ${itemTemplate}
146
+ </template>
147
+ <template #resetBanner>
148
+ <stats-reset-banner timeMarker="2 czerwca 2025" infoModalTitle="Info modal title">
149
+ <template #infoModalContent><p>Info content for reset banner</p></template>
150
+ </stats-reset-banner>
151
+ </template>
152
+ ${prepareItemsTemplate(5, itemTemplate)}
153
+ </stats-layout>`,
154
+ };
155
+ },
156
+ };
@@ -0,0 +1,173 @@
1
+ <template>
2
+ <div class="ds-statsLayout">
3
+ <slot name="sectionHeader" />
4
+
5
+ <ds-card>
6
+ <template #content>
7
+ <div v-if="isLoading" class="ds-statsLayout__loading">
8
+ <ds-spinner-loading />
9
+ </div>
10
+ <div v-else-if="hasError" class="ds-statsLayout__error">
11
+ <ds-stats-error-banner @button-clicked="$emit('retryClicked')" />
12
+ </div>
13
+ <div v-else class="ds-statsLayout__content">
14
+ <div class="ds-statsLayout__wrapper">
15
+ <div class="ds-statsLayout__summary">
16
+ <div v-if="hasGridHeader" class="ds-statsLayout__gridHeader">
17
+ <div class="ds-statsLayout__gridHeaderLeftColumn">{{
18
+ leftColumnLabel || t('ds.statsLayout.default.leftColumnLabel')
19
+ }}</div>
20
+ <div
21
+ v-if="hasRightColumn"
22
+ class="ds-statsLayout__gridHeaderRightColumn"
23
+ >
24
+ {{
25
+ rightColumnLabel ||
26
+ t('ds.statsLayout.default.rightColumnLabel')
27
+ }}
28
+ </div>
29
+ </div>
30
+ <div class="ds-statsLayout__overallStats">
31
+ <slot name="overallStatsItem" />
32
+ </div>
33
+ </div>
34
+
35
+ <div class="ds-statsLayout__stats">
36
+ <div v-if="hasGridHeader" class="ds-statsLayout__gridHeader">
37
+ <div class="ds-statsLayout__gridHeaderLeftColumn">
38
+ {{ statsItemsHeaderLabel }}
39
+ </div>
40
+ </div>
41
+
42
+ <div class="ds-statsLayout__statsList">
43
+ <template v-for="slotName in statsItems" :key="slotName">
44
+ <slot :name="slotName" />
45
+ <ds-divider class="ds-statsLayout__statsDivider" />
46
+ </template>
47
+ </div>
48
+ </div>
49
+ </div>
50
+
51
+ <slot name="resetBanner" />
52
+ </div>
53
+ </template>
54
+ </ds-card>
55
+ </div>
56
+ </template>
57
+
58
+ <style lang="scss" scoped>
59
+ @import '../../../styles/settings/spacings';
60
+ @import '../../../styles/settings/colors/tokens';
61
+ @import '../../../styles/settings/typography/tokens';
62
+
63
+ $right-column-width: 96px;
64
+
65
+ .ds-statsLayout {
66
+ display: flex;
67
+ flex-direction: column;
68
+ gap: $space-xs;
69
+
70
+ &__content,
71
+ &__summary,
72
+ &__stats {
73
+ display: flex;
74
+ flex-direction: column;
75
+ gap: $space-s;
76
+ }
77
+
78
+ &__wrapper {
79
+ display: flex;
80
+ flex-direction: column;
81
+ gap: $space-l;
82
+ }
83
+
84
+ &__gridHeader {
85
+ @include label-m-extensive-bold-uppercase();
86
+
87
+ background: $color-neutral-background;
88
+ color: $color-neutral-text;
89
+ display: flex;
90
+ }
91
+
92
+ &__gridHeaderLeftColumn,
93
+ &__gridHeaderRightColumn {
94
+ align-items: center;
95
+ display: flex;
96
+ }
97
+
98
+ &__gridHeaderLeftColumn {
99
+ flex: 1 0 0;
100
+ padding: $space-2xs;
101
+ }
102
+
103
+ &__gridHeaderRightColumn {
104
+ justify-content: flex-end;
105
+ padding: $space-2xs;
106
+ }
107
+
108
+ &__overallStats,
109
+ &__statsList {
110
+ display: grid;
111
+ grid-template-columns: 1fr auto;
112
+ }
113
+
114
+ &__statsList {
115
+ row-gap: $space-s;
116
+ }
117
+
118
+ &__statsDivider {
119
+ grid-column: 1 / -1;
120
+ grid-row: auto;
121
+ }
122
+
123
+ &__loading {
124
+ align-items: center;
125
+ display: flex;
126
+ justify-content: center;
127
+ }
128
+ }
129
+ </style>
130
+
131
+ <script setup lang="ts">
132
+ import DsCard from '../Cards/Card/Card.vue';
133
+ import DsDivider from '../Divider/Divider.vue';
134
+ import DsStatsErrorBanner from './StatsErrorBanner/StatsErrorBanner.vue';
135
+ import DsSpinnerLoading from '../SpinnerLoading/SpinnerLoading.vue';
136
+ import { computed } from 'vue';
137
+ import { useLegacyI18n } from '../../composables/useLegacyI18n';
138
+
139
+ const { t } = useLegacyI18n();
140
+
141
+ interface StatsLayoutProps {
142
+ hasGridHeader?: boolean;
143
+ hasRightColumn?: boolean;
144
+ leftColumnLabel?: string;
145
+ rightColumnLabel?: string;
146
+ statsItemsHeaderLabel?: string;
147
+ isLoading?: boolean;
148
+ hasError?: boolean;
149
+ }
150
+
151
+ const {
152
+ hasGridHeader = true,
153
+ hasRightColumn = true,
154
+ leftColumnLabel = null,
155
+ rightColumnLabel = null,
156
+ statsItemsHeaderLabel = null,
157
+ isLoading = false,
158
+ hasError = false,
159
+ } = defineProps<StatsLayoutProps>();
160
+
161
+ const slots = defineSlots<{
162
+ sectionHeader?: () => any;
163
+ overallStatsItem?: () => any;
164
+ [key: `statsItem-${number}`]: (() => any) | undefined;
165
+ resetBanner?: () => any;
166
+ }>();
167
+
168
+ const statsItems = computed(() => Object.keys(slots).filter((key) => key.startsWith('statsItem-')));
169
+
170
+ defineEmits<{
171
+ (e: 'retryClicked'): void;
172
+ }>();
173
+ </script>
@@ -0,0 +1,48 @@
1
+ import { Args, ArgTypes, Meta, StoryObj } from '@storybook/vue3';
2
+ import StatsResetBanner from './StatsResetBanner.vue';
3
+ import type { ComponentProps } from 'vue-component-type-helpers';
4
+ import Modal from '../../Modals/Modal/Modal.vue';
5
+
6
+ type StatsResetBannerProps = ComponentProps<typeof StatsResetBanner>;
7
+
8
+ const meta: Meta<StatsResetBannerProps> = {
9
+ title: 'Components/StatsLayout/StatsResetBanner',
10
+ component: StatsResetBanner,
11
+ render: (args) => {
12
+ return {
13
+ components: { StatsResetBanner, Modal },
14
+ setup() {
15
+ return {
16
+ args,
17
+ };
18
+ },
19
+ template:
20
+ '<stats-reset-banner v-bind="args"><template #infoModalContent>Default content</template><template #resetModal="{onClose}"><modal @close-modal="onClose">Modal content</modal></template></stats-reset-banner>',
21
+ };
22
+ },
23
+ parameters: {
24
+ design: {
25
+ type: 'figma',
26
+ url: 'https://www.figma.com/design/izQdYyiBR1GQgFkaOIfIJI/LMS---DS-Components?node-id=14870-10680&m=dev',
27
+ },
28
+ },
29
+ };
30
+ export default meta;
31
+
32
+ type Story = StoryObj<StatsResetBannerProps>;
33
+
34
+ export const Interactive: Story = {
35
+ args: {
36
+ timeMarker: '2 czerwca 2025',
37
+ infoModalTitle: 'Info modal title',
38
+ } as Args,
39
+ };
40
+
41
+ Interactive.argTypes = {
42
+ timeMarker: {
43
+ control: 'text',
44
+ },
45
+ infoModalTitle: {
46
+ control: 'text',
47
+ },
48
+ } as ArgTypes;
@@ -0,0 +1,51 @@
1
+ <template>
2
+ <ds-banner
3
+ :title="t('ds.statsLayout.statsResetBanner.title')"
4
+ :button-text="t('ds.statsLayout.statsResetBanner.buttonText')"
5
+ :color="BANNER_COLORS.NEUTRAL"
6
+ @button-clicked="isOpen = true"
7
+ >
8
+ <template #defaultText>
9
+ <span
10
+ >{{ t('ds.statsLayout.statsResetBanner.message') }}
11
+ <strong>{{ props.timeMarker }}</strong></span
12
+ >
13
+ </template>
14
+ <template v-if="$slots.infoModalContent" #rightSlot>
15
+ <ds-help-button :size="ICON_BUTTON_SIZES.SMALL" :modal-title="infoModalTitle">
16
+ <template #modalContent>
17
+ <slot name="infoModalContent" />
18
+ </template>
19
+ </ds-help-button>
20
+ </template>
21
+ </ds-banner>
22
+
23
+ <slot v-if="isOpen" name="resetModal" :on-close="onClose" />
24
+ </template>
25
+
26
+ <script setup lang="ts">
27
+ import { ref } from 'vue';
28
+ import { BANNER_COLORS } from '../../Banner/Banner.consts';
29
+ import DsBanner from '../../Banner/Banner.vue';
30
+ import DsHelpButton from '../../Buttons/HelpButton/HelpButton.vue';
31
+ import { useLegacyI18n } from '../../../composables/useLegacyI18n';
32
+ import { ICON_BUTTON_SIZES } from '../../Buttons/IconButton';
33
+
34
+ const { t } = useLegacyI18n();
35
+
36
+ const props = defineProps<{
37
+ timeMarker: string;
38
+ infoModalTitle?: string;
39
+ }>();
40
+
41
+ defineSlots<{
42
+ infoModalContent?: () => any;
43
+ resetModal?: (props: { onClose: () => void }) => any;
44
+ }>();
45
+
46
+ const isOpen = ref(false);
47
+
48
+ const onClose = () => {
49
+ isOpen.value = false;
50
+ };
51
+ </script>
@@ -0,0 +1,68 @@
1
+ import { Args, ArgTypes, Meta, StoryObj } from '@storybook/vue3';
2
+ import StatsSectionHeader from './StatsSectionHeader.vue';
3
+ import type { ComponentProps } from 'vue-component-type-helpers';
4
+ import { useArgs } from '@storybook/preview-api';
5
+
6
+ type StatsSectionHeaderProps = ComponentProps<typeof StatsSectionHeader>;
7
+
8
+ const meta: Meta<StatsSectionHeaderProps> = {
9
+ title: 'Components/StatsLayout/StatsSectionHeader',
10
+ component: StatsSectionHeader,
11
+ render: (args) => {
12
+ const [_, updateArgs] = useArgs();
13
+ return {
14
+ components: { StatsSectionHeader },
15
+ setup() {
16
+ return {
17
+ args,
18
+ };
19
+ },
20
+ methods: {
21
+ selectFilter(filterKey: string) {
22
+ updateArgs({
23
+ selectedFilterKey: filterKey,
24
+ });
25
+ },
26
+ },
27
+ template: `<stats-section-header v-bind="args" @select-filter="selectFilter"><template #infoModalContent><p>Info content</p></template></stats-section-header>`,
28
+ };
29
+ },
30
+ parameters: {
31
+ design: {
32
+ type: 'figma',
33
+ url: 'https://www.figma.com/design/izQdYyiBR1GQgFkaOIfIJI/LMS---DS-Components?node-id=14877-39964&m=dev',
34
+ },
35
+ },
36
+ };
37
+ export default meta;
38
+
39
+ type Story = StoryObj<StatsSectionHeaderProps>;
40
+
41
+ export const Interactive: Story = {
42
+ args: {
43
+ filterItems: [
44
+ {
45
+ key: 'all',
46
+ label: 'Wszystkie',
47
+ },
48
+ {
49
+ key: 'today',
50
+ label: 'Dzisiaj',
51
+ },
52
+ {
53
+ key: 'yesterday',
54
+ label: 'Wczoraj',
55
+ },
56
+ ],
57
+ selectedFilterKey: 'all',
58
+ } as Args,
59
+ };
60
+
61
+ Interactive.argTypes = {
62
+ filterItems: {
63
+ control: 'object',
64
+ },
65
+ selectedFilterKey: {
66
+ control: 'text',
67
+ },
68
+ } as ArgTypes;
@@ -0,0 +1,72 @@
1
+ <template>
2
+ <ds-section-header
3
+ :title="t('ds.statsLayout.sectionHeader.title')"
4
+ :icon-left="ICONS.FA_CHART_COLUMN"
5
+ :has-divider="false"
6
+ :info="!!$slots.infoModalContent"
7
+ :mobile-layout="SECTION_HEADER_MOBILE_LAYOUTS.HORIZONTAL"
8
+ @info-click="infoContentModalVisible = true"
9
+ >
10
+ <template v-if="filterItems && filterItems.length > 0" #default>
11
+ <slot name="accessory">
12
+ <ds-stats-filters-dropdown
13
+ :filter-items="filterItems"
14
+ :selected-filter-key="selectedFilterKey"
15
+ @select="selectFilter"
16
+ />
17
+ </slot>
18
+ </template>
19
+ </ds-section-header>
20
+
21
+ <ds-modal
22
+ v-if="infoContentModalVisible && !!$slots.infoModalContent"
23
+ :header-title="infoModalTitle"
24
+ @close-modal="infoContentModalVisible = false"
25
+ >
26
+ <template #default>
27
+ <slot name="infoModalContent" />
28
+ </template>
29
+ </ds-modal>
30
+ </template>
31
+
32
+ <script setup lang="ts">
33
+ import { ref } from 'vue';
34
+ import DsSectionHeader from '../../Headers/SectionHeader/SectionHeader.vue';
35
+ import DsStatsFiltersDropdown from '../StatsFiltersDropdown/StatsFiltersDropdown.vue';
36
+ import { SECTION_HEADER_MOBILE_LAYOUTS } from '../../Headers/SectionHeader/SectionHeader.consts';
37
+ import { ICONS } from '../../Icons/Icon/Icon.consts';
38
+ import DsModal from '../../Modals/Modal/Modal.vue';
39
+ import { useLegacyI18n } from '../../../composables/useLegacyI18n';
40
+
41
+ interface FilterItem {
42
+ key: string;
43
+ label: string;
44
+ }
45
+
46
+ const {
47
+ filterItems = [],
48
+ selectedFilterKey = null,
49
+ infoModalTitle,
50
+ } = defineProps<{
51
+ filterItems?: Array<FilterItem>;
52
+ selectedFilterKey?: string | null;
53
+ infoModalTitle?: string;
54
+ }>();
55
+
56
+ defineSlots<{
57
+ accessory?: string;
58
+ infoModalContent?: string;
59
+ }>();
60
+
61
+ const emit = defineEmits<{
62
+ 'select-filter': [filterKey: string];
63
+ }>();
64
+
65
+ const infoContentModalVisible = ref(false);
66
+
67
+ const selectFilter = (filterKey: string) => {
68
+ emit('select-filter', filterKey);
69
+ };
70
+
71
+ const { t } = useLegacyI18n();
72
+ </script>
@@ -1,4 +1,5 @@
1
1
  {
2
2
  "ds.globals.back": "Back",
3
- "ds.globals.confirmation": "OK, I understand"
3
+ "ds.globals.confirmation": "OK, I understand",
4
+ "ds.globals.loading": "Loading..."
4
5
  }
@@ -0,0 +1,12 @@
1
+ {
2
+ "ds.statsLayout.default.leftColumnLabel": "Range",
3
+ "ds.statsLayout.default.rightColumnLabel": "Results",
4
+ "ds.statsLayout.filtersDropdown.title": "Filter",
5
+ "ds.statsLayout.sectionHeader.title": "Your statistics",
6
+ "ds.statsLayout.statsErrorBanner.buttonText": "Try again",
7
+ "ds.statsLayout.statsErrorBanner.message": "Refresh the page to try again",
8
+ "ds.statsLayout.statsErrorBanner.title": "Failed to load statistics",
9
+ "ds.statsLayout.statsResetBanner.buttonText": "RESET STATISTICS",
10
+ "ds.statsLayout.statsResetBanner.message": "Statistics counted from",
11
+ "ds.statsLayout.statsResetBanner.title": "Reset statistics"
12
+ }
package/lib/js/i18n/en.ts CHANGED
@@ -1,9 +1,11 @@
1
1
  import globals from './en/globals.json';
2
2
  import accessStatus from './en/accessStatus.json';
3
3
  import pagination from './en/pagination.json';
4
+ import statsLayout from './en/statsLayout.json';
4
5
 
5
6
  export default {
6
7
  ...globals,
7
8
  ...accessStatus,
8
9
  ...pagination,
10
+ ...statsLayout,
9
11
  };
@@ -1,4 +1,5 @@
1
1
  {
2
2
  "ds.globals.back": "Wróć",
3
- "ds.globals.confirmation": "OK, rozumiem"
3
+ "ds.globals.confirmation": "OK, rozumiem",
4
+ "ds.globals.loading": "Momencik, ładuję dane..."
4
5
  }
@@ -0,0 +1,12 @@
1
+ {
2
+ "ds.statsLayout.default.leftColumnLabel": "Zakres",
3
+ "ds.statsLayout.default.rightColumnLabel": "Wyniki",
4
+ "ds.statsLayout.filtersDropdown.title": "Filtruj",
5
+ "ds.statsLayout.sectionHeader.title": "Twoje statystyki",
6
+ "ds.statsLayout.statsErrorBanner.buttonText": "Spróbuj ponownie",
7
+ "ds.statsLayout.statsErrorBanner.message": "Odśwież stronę, aby spróbować ponownie",
8
+ "ds.statsLayout.statsErrorBanner.title": "Nie udało się załadować statystyk",
9
+ "ds.statsLayout.statsResetBanner.buttonText": "Resetuj statystyki",
10
+ "ds.statsLayout.statsResetBanner.message": "Statystyki liczone od",
11
+ "ds.statsLayout.statsResetBanner.title": "Reset statystyk"
12
+ }
package/lib/js/i18n/pl.ts CHANGED
@@ -1,9 +1,11 @@
1
1
  import globals from './pl/globals.json';
2
2
  import accessStatus from './pl/accessStatus.json';
3
3
  import pagination from './pl/pagination.json';
4
+ import statsLayout from './pl/statsLayout.json';
4
5
 
5
6
  export default {
6
7
  ...globals,
7
8
  ...accessStatus,
8
9
  ...pagination,
10
+ ...statsLayout,
9
11
  };
@@ -118,6 +118,7 @@ import { faLocationDot } from '@fortawesome/pro-regular-svg-icons/faLocationDot'
118
118
  import { faLockKeyhole } from '@fortawesome/pro-regular-svg-icons/faLockKeyhole';
119
119
  import { faMagnifyingGlass } from '@fortawesome/pro-regular-svg-icons/faMagnifyingGlass';
120
120
  import { faMedal } from '@fortawesome/pro-regular-svg-icons/faMedal';
121
+ import { faMemo } from '@fortawesome/pro-regular-svg-icons/faMemo';
121
122
  import { faMemoCircleInfo } from '@fortawesome/pro-regular-svg-icons/faMemoCircleInfo';
122
123
  import { faMinus } from '@fortawesome/pro-regular-svg-icons/faMinus';
123
124
  import { faMobileRotate } from '@fortawesome/pro-regular-svg-icons/faMobileRotate';
@@ -404,6 +405,7 @@ export const FONTAWESOME_ICONS = {
404
405
  FA_LOCK_KEYHOLE: faLockKeyhole,
405
406
  FA_MAGNIFYING_GLASS: faMagnifyingGlass,
406
407
  FA_MEDAL: faMedal,
408
+ FA_MEMO: faMemo,
407
409
  FA_MEMO_CIRCLE_INFO_SOLID: fasMemoCircleInfo,
408
410
  FA_MEMO_CIRCLE_INFO: faMemoCircleInfo,
409
411
  FA_MESSAGE_QUESTION_SOLID: fasMessageQuestion,
package/lib/js/index.ts CHANGED
@@ -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
 
183
186
  export { initializePrimeVue } from './primevue';
184
187
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bethinkpl/design-system",
3
- "version": "30.3.2",
3
+ "version": "30.4.1",
4
4
  "description": "Bethink universe design-system",
5
5
  "repository": {
6
6
  "type": "git",