@vcita/design-system 1.2.2 → 1.3.0

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 (54) hide show
  1. package/CHANGELOG.md +16 -1
  2. package/config/locales/ds.en.yml +8 -1
  3. package/config/locales/ds.he.yml +3 -0
  4. package/dist/@vcita/design-system.esm.js +1652 -958
  5. package/dist/@vcita/design-system.min.js +2 -2
  6. package/dist/@vcita/design-system.ssr.js +1468 -854
  7. package/init/DesignSystem.js +2 -0
  8. package/init/SvgIcons.js +12 -2
  9. package/package.json +1 -1
  10. package/src/components/VcAvatar/VcAvatar.stories.js +0 -1
  11. package/src/components/VcBreadcrumbs/VcBreadcrumbs.spec.js +82 -0
  12. package/src/components/VcBreadcrumbs/VcBreadcrumbs.stories.js +86 -0
  13. package/src/components/VcBreadcrumbs/VcBreadcrumbs.vue +59 -0
  14. package/src/components/VcButton/VcButton.stories.js +13 -2
  15. package/src/components/VcButton/VcButton.vue +16 -7
  16. package/src/components/VcGalleryItem/VcGalleryItem.spec.js +120 -0
  17. package/src/components/VcGalleryItem/VcGalleryItem.stories.js +94 -0
  18. package/src/components/VcGalleryItem/VcGalleryItem.vue +161 -0
  19. package/src/components/VcGalleryList/VcGalleryList.spec.js +86 -0
  20. package/src/components/VcGalleryList/VcGalleryList.stories.js +63 -0
  21. package/src/components/VcGalleryList/VcGalleryList.vue +102 -0
  22. package/src/components/VcGalleryList/mockData.js +50 -0
  23. package/src/components/VcLink/VcLink.vue +13 -1
  24. package/src/components/VcMiniBanner/VcMiniBanner.spec.js +74 -0
  25. package/src/components/VcMiniBanner/VcMiniBanner.stories.js +75 -0
  26. package/src/components/VcMiniBanner/VcMiniBanner.vue +129 -0
  27. package/src/components/VcSearchPicker/VcSearchPicker.vue +12 -5
  28. package/src/components/VcSideNav/VcSideNav.vue +2 -0
  29. package/src/components/VcTextField/VcTextField.stories.js +2 -1
  30. package/src/components/VcUpsellBlock/VcUpsellBlock.stories.js +7 -2
  31. package/src/components/VcUpsellBlock/VcUpsellBlock.vue +3 -0
  32. package/src/components/index.js +5 -0
  33. package/src/components/list/VcList/pattern/VcMobilePickerPattern.stories.js +3 -0
  34. package/src/components/modal/elements/VcModalContainer.stories.js +6 -0
  35. package/src/components/modal/elements/VcModalContainer.vue +7 -14
  36. package/src/components/page/elements/VcPageHeader.spec.js +123 -0
  37. package/src/components/page/elements/VcPageHeader.stories.js +80 -0
  38. package/src/components/page/elements/VcPageHeader.vue +96 -0
  39. package/src/components/page/layouts/SideNavPage/SideNavLayout.stories.js +223 -0
  40. package/src/components/page/layouts/centeredPage/CenteredPageLayout.stories.js +162 -0
  41. package/src/stories/assets/app-market/fc.svg +31 -0
  42. package/src/stories/assets/app-market/google.svg +1 -0
  43. package/src/stories/assets/app-market/qb.svg +9 -0
  44. package/src/stories/assets/app-market/stripe.svg +1 -0
  45. package/src/stories/assets/app-market/zapier.svg +1 -0
  46. package/src/stories/assets/pics/gallery-item-1.jpg +0 -0
  47. package/src/stories/assets/pics/gallery-item-2.jpg +0 -0
  48. package/src/stories/assets/pics/gallery-item-3.jpg +0 -0
  49. package/src/stories/assets/pics/gallery-item-4.jpg +0 -0
  50. package/src/stories/assets/pics/gallery-item-5.jpg +0 -0
  51. package/src/stories/variables.stories.mdx +9 -2
  52. package/styles/variables.scss +9 -0
  53. package/src/components/.DS_Store +0 -0
  54. package/src/components/VcMenu/.DS_Store +0 -0
@@ -0,0 +1,129 @@
1
+ <template>
2
+ <div class="vc-mini-banner d-flex flex-column flex-sm-row justify-space-between justify-sm-start align-start align-sm-center"
3
+ :data-qa="dataQa" :style="{ background: gradientHue
4
+ ? `linear-gradient(${ $vuetify.breakpoint.smAndUp ? 90 : 180 }deg, ${ gradientHue } 0%, #fff 42%, #fff 100%)`
5
+ : 'transparent' }"
6
+ @click="$emit('onAction')">
7
+ <div class="vc-mini-banner__thumbnail">
8
+ <div class="vc-mini-banner__image-wrap">
9
+ <div class="vc-mini-banner__image" :style="{ backgroundImage: `url(${ thumbImage })` }" />
10
+ </div>
11
+ </div>
12
+ <div class="vc-mini-banner__text-content">
13
+ <h3 class="vc-mini-banner__title" :data-qa="`${dataQa}-title`">{{ title }}</h3>
14
+ <h4 class="vc-mini-banner__subtitle" v-if="subtitle" :data-qa="`${dataQa}-subtitle`">{{ subtitle }}</h4>
15
+ </div>
16
+ <div class="vc-mini-banner__cta">
17
+ <VcButton pill small class="primary-cta" :data-qa="`${dataQa}-button`">
18
+ {{ ctaLabel }}
19
+ </VcButton>
20
+ </div>
21
+ </div>
22
+ </template>
23
+
24
+ <script>
25
+ import VcButton from "@/components/VcButton/VcButton.vue";
26
+
27
+ export default {
28
+ name: "VcBanner",
29
+ components: { VcButton },
30
+ props: {
31
+ dataQa: {
32
+ type: String,
33
+ default: 'VcMiniBanner'
34
+ },
35
+ thumbImage: {
36
+ type: String,
37
+ required: false
38
+ },
39
+ title: {
40
+ type: String,
41
+ required: true
42
+ },
43
+ subtitle: {
44
+ type: String,
45
+ required: false
46
+ },
47
+ ctaLabel: {
48
+ type: String,
49
+ required: true
50
+ },
51
+ gradientHue: {
52
+ type: String,
53
+ }
54
+ },
55
+ }
56
+ </script>
57
+
58
+ <style lang="scss" scoped>
59
+ @import "../../scss/mixins.scss";
60
+
61
+ .vc-mini-banner {
62
+ min-height: 66px;
63
+ overflow: hidden;
64
+ border-radius: var(--size-value2);
65
+ border: 1px solid var(--neutral-lighten-2);
66
+ padding: var(--size-value4);
67
+ padding-inline-start: var(--size-value5);
68
+ padding-inline-end: var(--size-value8);
69
+ grid-gap: var(--size-value5);
70
+ cursor: pointer;
71
+ background-color: var(--modal-bg-color);
72
+
73
+ &__thumbnail {
74
+ background: var(--modal-bg-color);
75
+ height: var(--size-value12);
76
+ width: var(--size-value12);
77
+ box-shadow: var(--shadow-5);
78
+ border-radius: var(--border-radius);
79
+ }
80
+
81
+ &__image-wrap {
82
+ height: inherit;
83
+ width: inherit;
84
+ padding: var(--size-value2);
85
+ }
86
+
87
+ &__image {
88
+ height: 100%;
89
+ background-repeat: no-repeat;
90
+ background-size: contain;
91
+ }
92
+
93
+ &__text-content {
94
+ color: var(--gray-darken-5);
95
+ }
96
+
97
+ &__title {
98
+ font-weight: var(--font-weight-large2);
99
+ font-size: var(--font-size-small3);
100
+
101
+ @include sm-and-up {
102
+ font-weight: var(--font-weight-large);
103
+ font-size: var(--font-size-small2);
104
+ }
105
+ }
106
+
107
+ &__subtitle {
108
+ margin-top: var(--size-value1);
109
+ font-weight: var(--font-weight-medium);
110
+ font-size: var(--font-size-small2);
111
+
112
+ @include sm-and-up {
113
+ font-weight: var(--font-weight-medium);
114
+ font-size: var(--font-size-xx-small);
115
+ }
116
+ }
117
+
118
+ &__title, &__subtitle {
119
+ user-select: none;
120
+ }
121
+
122
+ &__cta {
123
+ @include sm-and-up {
124
+ margin-inline-start: auto;
125
+ }
126
+ }
127
+
128
+ }
129
+ </style>
@@ -16,7 +16,6 @@
16
16
  @update:search-input="(text) => text && text.length && $emit('onSearchInput', text)"
17
17
  @change="(newVal) => $emit('onSelectionChange', newVal)"
18
18
  @click.native="toggleMenu"
19
- @click:append="toggleMenu"
20
19
  @blur="focused = false;$emit('onMenuToggled', { isOpen: false })"
21
20
  multiple
22
21
  >
@@ -271,12 +270,20 @@ export default {
271
270
  }
272
271
  }
273
272
 
274
- ::v-deep .v-list-item--link {
275
- font-size: var(--font-size-x-small);
273
+ ::v-deep {
274
+ .v-list-item--link {
275
+ font-size: var(--font-size-x-small);
276
276
 
277
- &:before {
278
- content: initial;
277
+ &:before {
278
+ content: initial;
279
+ }
280
+ }
281
+
282
+ .v-input__append-inner {
283
+ pointer-events: none;
279
284
  }
280
285
  }
281
286
 
287
+
288
+
282
289
  </style>
@@ -30,7 +30,9 @@
30
30
  </div>
31
31
  </template>
32
32
  <script>
33
+
33
34
  import VcIcon from "@/components/VcIcon/VcIcon.vue";
35
+
34
36
  export default {
35
37
  name: "VcSideNav",
36
38
  components: {VcIcon},
@@ -63,7 +63,8 @@ const TextFieldTemplate = (args, {argTypes}) => ({
63
63
  :google-address-auto-complete="googleAddressAutoComplete"
64
64
  :google-address-country-options="googleAddressCountryOptions"
65
65
  @click="onClick"
66
- @input="onInput"/>
66
+ @input="onInput"
67
+ @onPlaceSelected="onPlaceSelected"/>
67
68
  </v-layout>`,
68
69
  })
69
70
 
@@ -62,11 +62,13 @@ const dialogTemplate = (args, {argTypes}) => ({
62
62
  :showCloseButton="true"
63
63
  :size="modalSize"
64
64
  :showFooterDivider="false"
65
+ :useOffset="false"
66
+ flavor="input"
65
67
  @click-outside="$emit('onClickOutside')"
66
68
  @onCloseButtonClicked="$emit('onCloseButtonClicked')">
67
69
  <template #content>
68
70
  <VcUpsellBlock
69
- mode="dialog"
71
+ :mode="mode"
70
72
  :imageUrl="imageUrl"
71
73
  :titleText="titleText"
72
74
  :subtitleText="subtitleText"
@@ -126,7 +128,10 @@ export default {
126
128
  component: VcUpsellBlockCmp,
127
129
  argTypes: {
128
130
  description: {table: {disable: true}},
129
- modalSize: {table: {disable: true}},
131
+ modalSize: {
132
+ options: ['sm', 'md', 'lg', 'xl', 'responsive'],
133
+ control: {type: 'radio'}
134
+ },
130
135
  showDialog: {table: {disable: true}},
131
136
  linkText: {table: {category: 'link'}},
132
137
  linkUrl: {table: {category: 'link'}},
@@ -96,6 +96,9 @@ export default {
96
96
  font-style: normal;
97
97
  @include md-and-up{
98
98
  overflow-x: visible;
99
+ &.dialog {
100
+ overflow: hidden;
101
+ }
99
102
  }
100
103
 
101
104
  &:before{
@@ -65,3 +65,8 @@ export {default as VcSearchPicker} from './VcSearchPicker/VcSearchPicker.vue';
65
65
  export {default as VcDraggableList} from './VcDraggableList/VcDraggableList.vue';
66
66
  export {default as VcTabs} from './VcTabs/VcTabs.vue';
67
67
  export {default as VcSideNav} from './VcSideNav/VcSideNav.vue';
68
+ export {default as VcMiniBanner} from './VcMiniBanner/VcMiniBanner.vue';
69
+ export {default as VcGalleryItem} from './VcGalleryItem/VcGalleryItem.vue';
70
+ export {default as VcGalleryList} from './VcGalleryList/VcGalleryList.vue';
71
+ export {default as VcBreadcrumbs} from './VcBreadcrumbs/VcBreadcrumbs.vue';
72
+ export {default as VcPageHeader} from './page/elements/VcPageHeader.vue';
@@ -272,6 +272,8 @@ MobileSingleSelectPickerWithAvatars.parameters = {
272
272
  </VcInputModal>
273
273
  </template>
274
274
 
275
+ <script>
276
+
275
277
  /**
276
278
  TODO: - to get this code running you need to
277
279
  1. Implement selected item - display the current selected item
@@ -305,6 +307,7 @@ MobileSingleSelectPickerWithAvatars.parameters = {
305
307
  },
306
308
  },
307
309
  }
310
+ </script>
308
311
 
309
312
  <style lang="scss" scoped>
310
313
  // Your css here
@@ -11,6 +11,7 @@ const Template = (args, {argTypes}) => ({
11
11
  :showCloseButton="showCloseButton"
12
12
  :showFooterDivider="showFooterDivider"
13
13
  :showHeaderDivider="showHeaderDivider"
14
+ :flavor="flavor"
14
15
  :use-offset="useOffset"
15
16
  :closeOnEsc="closeOnEsc"
16
17
  :data-qa="dataQa"
@@ -48,6 +49,7 @@ Playground.args = {
48
49
  closeOnEsc: true,
49
50
  showCloseButton: false,
50
51
  useOffset: false,
52
+ flavor: 'input',
51
53
  dataQa: 'VcModalContainer',
52
54
  }
53
55
 
@@ -60,6 +62,10 @@ export default {
60
62
  options: ['sm', 'md', 'lg', 'xl', 'responsive'],
61
63
  control: {type: 'radio'}
62
64
  },
65
+ flavor: {
66
+ options: ['input', 'confirm', 'notice', 'prominent'],
67
+ control: {type: 'radio'}
68
+ },
63
69
  },
64
70
  parameters: {
65
71
  design: {
@@ -10,7 +10,7 @@
10
10
  <v-layout column :data-qa="dataQa">
11
11
  <header :class="{'showDivider': showHeaderDivider}">
12
12
  <slot name="header"/>
13
- <VcButton class="VcModalCloseButton" v-if="displayCloseButton" icon fab small
13
+ <VcButton class="VcModalCloseButton" v-if="showCloseButton" icon fab small
14
14
  @click="$emit('onCloseButtonClicked')">
15
15
  <template #prepend>
16
16
  <svg width="14" height="14" viewBox="0 0 14 14" fill="none" xmlns="http://www.w3.org/2000/svg">
@@ -81,13 +81,6 @@ export default {
81
81
  default: 'VcModalContainer',
82
82
  }
83
83
  },
84
- computed: {
85
- displayCloseButton() {
86
- if (this.flavor === 'input' && !this.$vuetify.breakpoint.mdAndUp)
87
- return false;
88
- return this.showCloseButton;
89
- },
90
- }
91
84
  }
92
85
  </script>
93
86
 
@@ -161,7 +154,7 @@ export default {
161
154
 
162
155
  footer {
163
156
  padding: var(--size-value3) var(--size-value4) var(--size-value3);
164
- @include i-text-align(right);
157
+ text-align: end;
165
158
 
166
159
  &.showDivider {
167
160
  border-top: 1px solid rgba(0, 0, 0, 0.12);
@@ -177,7 +170,7 @@ export default {
177
170
  header {
178
171
  font-weight: var(--font-weight-xl);
179
172
  font-size: var(--font-size-medium2);
180
- padding-bottom: 0px;
173
+ padding-bottom: 0;
181
174
  padding-top: var(--size-value10);
182
175
  }
183
176
 
@@ -217,7 +210,7 @@ export default {
217
210
  }
218
211
 
219
212
  .VcModalContainerContent {
220
- min-height: 0px;
213
+ min-height: 0;
221
214
  margin-left: var(--size-value16);
222
215
  padding-right: var(--size-value16);
223
216
  }
@@ -235,12 +228,12 @@ export default {
235
228
  &.responsive {
236
229
  height: 100%;
237
230
  margin: 0;
238
- border-bottom-left-radius: 0px;
239
- border-bottom-right-radius: 0px;
231
+ border-bottom-left-radius: 0;
232
+ border-bottom-right-radius: 0;
240
233
  }
241
234
 
242
235
  .VcModalContainerContent {
243
- padding: 0px;
236
+ padding: 0;
244
237
  }
245
238
  }
246
239
  }
@@ -0,0 +1,123 @@
1
+ import '@testing-library/jest-dom'
2
+ import VcPageHeader from "./VcPageHeader.vue";
3
+ import Vue from 'vue'
4
+ import Vuetify from 'vuetify'
5
+ import {render} from "@testing-library/vue";
6
+ import init from "../../../../testing-library.config";
7
+ import {fireEvent} from "@testing-library/dom";
8
+
9
+ init();
10
+
11
+ Vue.use(Vuetify)
12
+
13
+ describe("VcPageHeader.vue", () => {
14
+
15
+ const renderWithVuetify = (component, options, callback, isMobile = false) => {
16
+ const root = document.createElement('div')
17
+ root.setAttribute('data-app', 'true')
18
+
19
+ const vuetify = new Vuetify()
20
+ if (isMobile) {
21
+ const breakpoint = {
22
+ init: jest.fn(),
23
+ framework: {},
24
+ smAndDown: true,
25
+ }
26
+
27
+ vuetify.framework.breakpoint = breakpoint;
28
+ }
29
+
30
+ return render(
31
+ component,
32
+ {
33
+ container: document.body.appendChild(root),
34
+ // for Vuetify components that use the vuetify instance property
35
+ vuetify,
36
+ ...options,
37
+ mocks: {
38
+ $t: value => value,
39
+ $dst: value => value, // <- for the design system
40
+ },
41
+ },
42
+ callback,
43
+ )
44
+ }
45
+
46
+ it("mounts with breadcrumbs and subtitle", () => {
47
+ // Queries: https://testing-library.com/docs/queries/about#types-of-queries
48
+ const {container, getByTestId, getByText, emitted} = renderWithVuetify(VcPageHeader, {
49
+ props: {
50
+ title: 'Payments',
51
+ subtitle: 'Payments subtitle',
52
+ breadcrumbs: [
53
+ {
54
+ text: 'item 1',
55
+ disabled: false,
56
+ href: 'item_1',
57
+ },
58
+ {
59
+ text: 'item 2',
60
+ disabled: false,
61
+ href: 'item_2',
62
+ },
63
+ {
64
+ text: 'item 3',
65
+ disabled: false,
66
+ href: 'item_3',
67
+ },
68
+ ],
69
+ }
70
+ })
71
+
72
+ // Expect options: https://github.com/testing-library/jest-dom
73
+ expect(container).toHaveAttribute('data-app', 'true');
74
+
75
+ // Make sure the component has the data-qa attribute
76
+ const component = getByTestId('VcPageHeader');
77
+ expect(component).toBeInTheDocument();
78
+
79
+ const breadcrumbs = getByTestId('VcBreadcrumbs');
80
+ expect(breadcrumbs).toBeInTheDocument();
81
+
82
+ expect(getByText('Payments')).toBeInTheDocument();
83
+ expect(getByText('Payments subtitle')).toBeInTheDocument();
84
+
85
+ const backButton = getByTestId('VcPageHeader-backButton');
86
+ expect(backButton).toBeInTheDocument();
87
+ fireEvent.click(backButton);
88
+ expect(emitted().onBackClicked.length).toBe(1);
89
+
90
+ const saveButton = getByTestId('VcPageHeader-saveButton');
91
+ expect(saveButton).toBeInTheDocument();
92
+ fireEvent.click(saveButton);
93
+ expect(emitted().onSaveClicked.length).toBe(1);
94
+ });
95
+
96
+ it("has no breadcrumbs and disabled save button", () => {
97
+ const {queryByTestId, getByTestId} = renderWithVuetify(VcPageHeader, {
98
+ props: {
99
+ title: 'Payments',
100
+ buttonData: {save: {disabled: true}},
101
+ }
102
+ });
103
+
104
+ const breadcrumbs = queryByTestId('VcBreadcrumbs');
105
+ expect(breadcrumbs).toBe(null);
106
+
107
+ const saveButton = getByTestId('VcPageHeader-saveButton');
108
+ expect(saveButton).toBeDisabled();
109
+ });
110
+
111
+ it("has no back button", () => {
112
+ const {queryByTestId} = renderWithVuetify(VcPageHeader, {
113
+ props: {
114
+ title: 'Payments',
115
+ showBackButton: false,
116
+ }
117
+ });
118
+
119
+ const backButton = queryByTestId('VcPageHeader-backButton');
120
+ expect(backButton).not.toBeInTheDocument();
121
+ });
122
+
123
+ });
@@ -0,0 +1,80 @@
1
+ import VcPageHeaderCmp from './VcPageHeader';
2
+ import VcBaseDocs from '@/stories/VcBaseDocs.mdx';
3
+
4
+ const baseProps = {
5
+ title: 'Payments',
6
+ subtitle: 'This page contains information on all your payments, past, present and future',
7
+ breadcrumbs: [
8
+ {
9
+ text: 'item 1',
10
+ disabled: false,
11
+ href: 'item_1',
12
+ },
13
+ {
14
+ text: 'item 2',
15
+ disabled: false,
16
+ href: 'item_2',
17
+ },
18
+ {
19
+ text: 'item 3',
20
+ disabled: false,
21
+ href: 'item_3',
22
+ },
23
+ ],
24
+ showBackButton: true,
25
+ buttonData: {},
26
+ dataQa: 'VcPageHeader',
27
+ };
28
+
29
+ const Template = (args, {argTypes}) => ({
30
+ components: {VcPageHeader: VcPageHeaderCmp},
31
+ props: Object.keys(argTypes),
32
+ template: `
33
+ <div>
34
+ <VcPageHeader :title="title"
35
+ :subtitle="subtitle"
36
+ :breadcrumbs="breadcrumbs"
37
+ :show-back-button="showBackButton"
38
+ :button-data="buttonData"
39
+ @onBackClicked="onBackClicked"
40
+ @onSaveClicked="onSaveClicked"/>
41
+ </div>`,
42
+ })
43
+
44
+ export const Playground = Template.bind({});
45
+
46
+ Playground.args = {
47
+ ...baseProps,
48
+ }
49
+
50
+ export const NoBreadcrumbs = Template.bind({});
51
+
52
+ NoBreadcrumbs.args = {
53
+ ...baseProps,
54
+ breadcrumbs: undefined,
55
+ }
56
+
57
+ export const DisabledSaveButton = Template.bind({});
58
+
59
+ DisabledSaveButton.args = {
60
+ ...baseProps,
61
+ buttonData: {save: {disabled: true}},
62
+ }
63
+
64
+ export default {
65
+ title: 'page / elements / VcPageHeader', // This will control the story sidebar position
66
+ id: 'VcPageHeader', // This will be the permanent link to this component
67
+ component: VcPageHeaderCmp,
68
+ parameters: {
69
+ design: {
70
+ type: 'figma',
71
+ url: 'https://www.figma.com/file/xIOY6fBoA1wpy1tHv3i5js/vcita---ui-library?node-id=12049%3A261603',
72
+ },
73
+ status: {
74
+ type: 'beta', // 'beta' | 'stable' | 'deprecated' | 'releaseCandidate'
75
+ },
76
+ docs: {
77
+ page: VcBaseDocs,
78
+ },
79
+ },
80
+ };
@@ -0,0 +1,96 @@
1
+ <template>
2
+ <VcLayout align-center class="VcPageHeader">
3
+ <VcLayout column :data-qa="dataQa">
4
+ <VcBreadcrumbs v-if="breadcrumbs && breadcrumbs.length > 0" :items="breadcrumbs"/>
5
+ <span class="VcHeader--title">
6
+ <VcButton v-if="showBackButton" icon small
7
+ :data-qa="`${dataQa}-backButton`"
8
+ @click="$emit('onBackClicked')">
9
+ <template #prepend>
10
+ <VcIcon color="black" size="var(--font-size-small)">$chevron_left</VcIcon>
11
+ </template>
12
+ </VcButton>
13
+ {{ title }}
14
+ </span>
15
+ <span v-if="subtitle && subtitle.length > 0" class="VcHeader--subtitle">
16
+ {{ subtitle }}
17
+ </span>
18
+ </VcLayout>
19
+ <VcLayout justify-end>
20
+ <slot name="buttons">
21
+ <VcButton :icon-size="12"
22
+ :disabled="buttonData.save && buttonData.save.disabled"
23
+ prepend-default-icon prepend-icon="check_button"
24
+ :data-qa="`${dataQa}-saveButton`"
25
+ @click="$emit('onSaveClicked')">
26
+ {{ saveButtonLabel }}
27
+ </VcButton>
28
+ </slot>
29
+ </VcLayout>
30
+ </VcLayout>
31
+ </template>
32
+
33
+ <script>
34
+ import VcBreadcrumbs from "@/components/VcBreadcrumbs/VcBreadcrumbs.vue";
35
+ import VcLayout from "@/components/VcLayout/VcLayout.vue";
36
+ import VcIcon from "@/components/VcIcon/VcIcon.vue";
37
+ import VcButton from "@/components/VcButton/VcButton.vue";
38
+
39
+ export default {
40
+ name: "VcPageHeader",
41
+ components: {VcButton, VcIcon, VcLayout, VcBreadcrumbs},
42
+ props: {
43
+ breadcrumbs: {
44
+ type: Array,
45
+ validator: items => items.every(item => item.text && item.href)
46
+ },
47
+ title: {
48
+ type: String,
49
+ required: true
50
+ },
51
+ subtitle: {
52
+ type: String,
53
+ default: ''
54
+ },
55
+ showBackButton: {
56
+ type: Boolean,
57
+ default: true,
58
+ },
59
+ buttonData: {
60
+ type: Object,
61
+ default: () => ({}),
62
+ },
63
+ dataQa: {
64
+ type: String,
65
+ default: 'VcPageHeader'
66
+ }
67
+ },
68
+ computed: {
69
+ saveButtonLabel() {
70
+ return this.buttonData.save?.label || this.$dst('ds.page.saveButton.label')
71
+ },
72
+ },
73
+ }
74
+ </script>
75
+
76
+ <style lang="scss" scoped>
77
+
78
+ .VcPageHeader {
79
+ margin-bottom: var(--size-value10);
80
+ }
81
+
82
+ .VcHeader--title {
83
+ font-size: var(--font-size-medium0);
84
+ font-weight: var(--font-weight-large2);
85
+ line-height: var(--size-value8);
86
+ color: var(--gray-darken-5);
87
+ margin-top: var(--size-value1);
88
+ }
89
+
90
+ .VcHeader--subtitle {
91
+ font-size: var(--font-size-x-small);
92
+ font-weight: var(--font-weight-medium);
93
+ line-height: var(--size-value5);
94
+ }
95
+
96
+ </style>