@bethinkpl/design-system 43.0.0 → 45.0.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.
- package/dist/design-system.css +1 -1
- package/dist/design-system.js +13826 -13252
- package/dist/design-system.js.map +1 -1
- package/dist/lib/js/components/Buttons/IconButton/IconButton.vue.d.ts +1 -1
- package/dist/lib/js/components/Callout/Callout.consts.d.ts +32 -0
- package/dist/lib/js/components/{ActionContent/ActionContent.vue.d.ts → Callout/Callout.vue.d.ts} +17 -6
- package/dist/lib/js/components/Callout/index.d.ts +4 -0
- package/dist/lib/js/components/DatePickers/DateBox/DateBox.vue.d.ts +1 -1
- package/dist/lib/js/components/DatePickers/DatePicker/DatePicker.vue.d.ts +5 -5
- package/dist/lib/js/components/DatePickers/DateRangePicker/DateRangePicker.vue.d.ts +2 -2
- package/dist/lib/js/components/Divider/Divider.vue.d.ts +1 -1
- package/dist/lib/js/components/Drawer/DrawerDivider/DrawerDivider.vue.d.ts +1 -1
- package/dist/lib/js/components/Drawer/DrawerSection/DrawerSection.vue.d.ts +4 -4
- package/dist/lib/js/components/Drawer/DrawerTile/DrawerTile.vue.d.ts +4 -4
- package/dist/lib/js/components/Dropdown/Dropdown.vue.d.ts +1 -1
- package/dist/lib/js/components/Form/FormField/FormField.utils.d.ts +1 -1
- package/dist/lib/js/components/Form/InputField/InputField.vue.d.ts +2 -2
- package/dist/lib/js/components/Form/PasswordField/PasswordField.vue.d.ts +2 -2
- package/dist/lib/js/components/Form/PinInputField/PinInputField.consts.d.ts +14 -0
- package/dist/lib/js/components/Form/PinInputField/PinInputField.types.d.ts +12 -0
- package/dist/lib/js/components/Form/PinInputField/PinInputField.utils.d.ts +2 -0
- package/dist/lib/js/components/Form/PinInputField/PinInputField.vue.d.ts +91 -0
- package/dist/lib/js/components/Form/PinInputField/index.d.ts +5 -0
- package/dist/lib/js/components/Form/PinInputField/usePinInputFieldWithinForm.d.ts +8 -0
- package/dist/lib/js/components/Form/SelectField/SelectField.vue.d.ts +2 -2
- package/dist/lib/js/components/Form/TextAreaField/TextAreaField.types.d.ts +9 -0
- package/dist/lib/js/components/Form/TextAreaField/TextAreaField.vue.d.ts +76 -0
- package/dist/lib/js/components/Form/TextAreaField/TextAreaFieldAutosized.vue.d.ts +6 -0
- package/dist/lib/js/components/Form/TextAreaField/index.d.ts +4 -0
- package/dist/lib/js/components/Headers/OverlayHeader/OverlayHeader.vue.d.ts +5 -5
- package/dist/lib/js/components/Headers/PageHeader/PageHeader.vue.d.ts +1 -1
- package/dist/lib/js/components/Headers/SectionHeader/SectionHeader.vue.d.ts +3 -3
- package/dist/lib/js/components/IconText/IconText.vue.d.ts +1 -1
- package/dist/lib/js/components/Image/Image.vue.d.ts +1 -1
- package/dist/lib/js/components/LabelValue/LabelValueItem/LabelValueItem.vue.d.ts +12 -1
- package/dist/lib/js/components/Menu/MenuDivider/MenuDivider.vue.d.ts +1 -1
- package/dist/lib/js/components/Modals/Modal/Modal.vue.d.ts +2 -2
- package/dist/lib/js/components/Modals/ModalDialog/ModalDialog.vue.d.ts +2 -2
- package/dist/lib/js/components/Pagination/Pagination.vue.d.ts +2 -2
- package/dist/lib/js/components/RichList/BasicRichListItem/BasicRichListItem.vue.d.ts +7 -7
- package/dist/lib/js/components/RichList/RichListItem/RichListItem.vue.d.ts +3 -3
- package/dist/lib/js/components/SelectList/SelectListItemDivider/SelectListItemDivider.vue.d.ts +1 -1
- package/dist/lib/js/components/Skeleton/Skeleton.vue.d.ts +1 -1
- package/dist/lib/js/components/SurveyQuestions/SurveyQuestionOpenEnded/SurveyQuestionOpenEnded.vue.d.ts +3 -3
- package/dist/lib/js/components/SurveyQuestions/SurveyQuestionScale/SurveyQuestionScale.vue.d.ts +3 -3
- package/dist/lib/js/components/Tile/Tile.sb.shared.d.ts +2 -2
- package/dist/lib/js/components/Tile/Tile.vue.d.ts +2 -2
- package/dist/lib/js/components/Toast/Toast.consts.d.ts +11 -9
- package/dist/lib/js/components/Toast/Toast.vue.d.ts +51 -433
- package/dist/lib/js/components/Toggles/ToggleButton/ToggleButton.vue.d.ts +1 -1
- package/dist/lib/js/{components/Form/InputField/useInputFieldWithinForm.d.ts → composables/useTextFieldWithinForm.d.ts} +1 -1
- package/dist/lib/js/index.d.ts +6 -1
- package/lib/js/components/Callout/Callout.consts.ts +25 -0
- package/lib/js/components/Callout/Callout.spec.ts +257 -0
- package/lib/js/components/Callout/Callout.stories.ts +209 -0
- package/lib/js/components/Callout/Callout.vue +161 -0
- package/lib/js/components/Callout/index.ts +4 -0
- package/lib/js/components/Cards/Card/Card.vue +1 -1
- package/lib/js/components/Form/CheckboxGroupField/CheckboxGroupField.spec.ts +15 -0
- package/lib/js/components/Form/CheckboxGroupField/CheckboxGroupField.vue +5 -2
- package/lib/js/components/Form/Form.stories.ts +23 -2
- package/lib/js/components/Form/InputField/InputField.spec.ts +11 -1
- package/lib/js/components/Form/InputField/InputField.vue +7 -4
- package/lib/js/components/Form/PasswordField/PasswordField.vue +1 -1
- package/lib/js/components/Form/PinInputField/PinInputField.consts.ts +18 -0
- package/lib/js/components/Form/PinInputField/PinInputField.spec.ts +394 -0
- package/lib/js/components/Form/PinInputField/PinInputField.stories.ts +124 -0
- package/lib/js/components/Form/PinInputField/PinInputField.types.ts +42 -0
- package/lib/js/components/Form/PinInputField/PinInputField.utils.ts +5 -0
- package/lib/js/components/Form/PinInputField/PinInputField.vue +211 -0
- package/lib/js/components/Form/PinInputField/index.ts +6 -0
- package/lib/js/components/Form/PinInputField/usePinInputFieldWithinForm.ts +29 -0
- package/lib/js/components/Form/SelectField/SelectField.stories.ts +0 -5
- package/lib/js/components/Form/SelectField/useSelectFieldWithinForm.ts +1 -1
- package/lib/js/components/Form/TextAreaField/TextAreaField.spec.ts +341 -0
- package/lib/js/components/Form/TextAreaField/TextAreaField.stories.ts +99 -0
- package/lib/js/components/Form/TextAreaField/TextAreaField.types.ts +23 -0
- package/lib/js/components/Form/TextAreaField/TextAreaField.vue +190 -0
- package/lib/js/components/Form/TextAreaField/TextAreaFieldAutosized.vue +19 -0
- package/lib/js/components/Form/TextAreaField/index.ts +5 -0
- package/lib/js/components/LabelValue/LabelValueItem/LabelValueItem.spec.ts +26 -0
- package/lib/js/components/LabelValue/LabelValueItem/LabelValueItem.stories.ts +16 -3
- package/lib/js/components/LabelValue/LabelValueItem/LabelValueItem.vue +5 -0
- package/lib/js/components/LoadingBar/LoadingBar.spec.ts +84 -0
- package/lib/js/components/LoadingBar/LoadingBar.vue +30 -19
- package/lib/js/components/Toast/Toast.consts.ts +4 -2
- package/lib/js/components/Toast/Toast.spec.ts +177 -0
- package/lib/js/components/Toast/Toast.stories.ts +65 -31
- package/lib/js/components/Toast/Toast.vue +176 -195
- package/lib/js/{components/Form/InputField/useInputFieldWithinForm.ts → composables/useTextFieldWithinForm.ts} +7 -2
- package/lib/js/index.ts +6 -1
- package/package.json +1 -1
- package/dist/lib/js/components/ActionContent/index.d.ts +0 -3
- package/lib/js/components/ActionContent/ActionContent.spec.ts +0 -99
- package/lib/js/components/ActionContent/ActionContent.stories.ts +0 -141
- package/lib/js/components/ActionContent/ActionContent.vue +0 -104
- package/lib/js/components/ActionContent/index.ts +0 -3
|
@@ -1,9 +1,14 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<div
|
|
2
|
+
<div
|
|
3
|
+
:class="['ds-toast', toastSize, toastPosition, toastColor, { '-ds-closable': isClosable }]"
|
|
4
|
+
>
|
|
3
5
|
<ds-card :loading-bar-color="color" has-loading-bar :loading-bar-time="disappearingTimeout">
|
|
4
6
|
<template #content>
|
|
5
|
-
<div class="ds-
|
|
6
|
-
<
|
|
7
|
+
<div class="ds-toast__body">
|
|
8
|
+
<div v-if="title" class="ds-toast__title">{{ title }}</div>
|
|
9
|
+
<div class="ds-toast__content">
|
|
10
|
+
<slot name="content" />
|
|
11
|
+
</div>
|
|
7
12
|
</div>
|
|
8
13
|
</template>
|
|
9
14
|
<template
|
|
@@ -14,6 +19,7 @@
|
|
|
14
19
|
<ds-button
|
|
15
20
|
v-if="footerSecondaryButtonText.length"
|
|
16
21
|
:color="buttonSecondaryColor"
|
|
22
|
+
:size="buttonSize"
|
|
17
23
|
:icon-right="footerSecondaryButtonIcon"
|
|
18
24
|
:type="BUTTON_TYPES.OUTLINED"
|
|
19
25
|
:radius="BUTTON_RADIUSES.ROUNDED"
|
|
@@ -23,6 +29,7 @@
|
|
|
23
29
|
<ds-button
|
|
24
30
|
v-if="footerPrimaryButtonText.length"
|
|
25
31
|
:color="buttonPrimaryColor"
|
|
32
|
+
:size="buttonSize"
|
|
26
33
|
:icon-right="footerPrimaryButtonIcon"
|
|
27
34
|
:radius="BUTTON_RADIUSES.ROUNDED"
|
|
28
35
|
@click="$emit('primary-button-click')"
|
|
@@ -31,49 +38,113 @@
|
|
|
31
38
|
</div>
|
|
32
39
|
</template>
|
|
33
40
|
</ds-card>
|
|
41
|
+
<div v-if="isClosable" class="ds-toast__close">
|
|
42
|
+
<ds-icon-button
|
|
43
|
+
:icon="ICONS.FA_XMARK"
|
|
44
|
+
:size="ICON_BUTTON_SIZES.SMALL"
|
|
45
|
+
:color="ICON_BUTTON_COLORS.NEUTRAL_WEAK"
|
|
46
|
+
@click="close"
|
|
47
|
+
/>
|
|
48
|
+
</div>
|
|
34
49
|
</div>
|
|
35
50
|
</template>
|
|
36
51
|
|
|
37
52
|
<style scoped lang="scss">
|
|
53
|
+
@import '../../../styles/settings/colors/tokens';
|
|
38
54
|
@import '../../../styles/settings/spacings';
|
|
39
55
|
@import '../../../styles/settings/typography/tokens';
|
|
40
56
|
@import '../../../styles/settings/media-queries';
|
|
41
57
|
|
|
42
58
|
.ds-toast {
|
|
43
|
-
|
|
59
|
+
$root: &;
|
|
60
|
+
|
|
61
|
+
max-width: var(--ds-toast-max-width);
|
|
62
|
+
// anchors the absolutely positioned close button, including under `position: none`
|
|
63
|
+
position: relative;
|
|
44
64
|
width: 100%;
|
|
45
65
|
|
|
46
66
|
&.-ds-size-small {
|
|
47
|
-
max-width: 320px
|
|
48
|
-
padding: $space-8;
|
|
67
|
+
--ds-toast-max-width: 320px;
|
|
49
68
|
}
|
|
50
69
|
|
|
51
70
|
&.-ds-size-medium {
|
|
52
|
-
max-width: 500px
|
|
53
|
-
|
|
71
|
+
--ds-toast-max-width: 500px;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
&.-ds-size-large {
|
|
75
|
+
--ds-toast-max-width: 700px;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
// The viewport spacing lives in the offsets rather than in padding, so it applies only to the
|
|
79
|
+
// fixed positions — `none` lets the consumer place (and space) the toast themselves.
|
|
80
|
+
&.-ds-position-left,
|
|
81
|
+
&.-ds-position-center,
|
|
82
|
+
&.-ds-position-right {
|
|
83
|
+
--ds-toast-offset: #{$space-8};
|
|
84
|
+
|
|
85
|
+
bottom: var(--ds-toast-offset);
|
|
86
|
+
max-width: min(var(--ds-toast-max-width), calc(100% - var(--ds-toast-offset) * 2));
|
|
87
|
+
position: fixed;
|
|
54
88
|
|
|
55
89
|
@media (#{breakpoint-s()}) {
|
|
56
|
-
|
|
57
|
-
|
|
90
|
+
&.-ds-size-medium,
|
|
91
|
+
&.-ds-size-large {
|
|
92
|
+
--ds-toast-offset: #{$space-12};
|
|
93
|
+
}
|
|
58
94
|
}
|
|
59
95
|
}
|
|
60
96
|
|
|
61
97
|
&.-ds-position-left {
|
|
62
|
-
|
|
63
|
-
left: 0;
|
|
98
|
+
left: var(--ds-toast-offset);
|
|
64
99
|
}
|
|
65
100
|
|
|
66
101
|
&.-ds-position-right {
|
|
67
|
-
|
|
68
|
-
right: 0;
|
|
102
|
+
right: var(--ds-toast-offset);
|
|
69
103
|
}
|
|
70
104
|
|
|
71
105
|
&.-ds-position-center {
|
|
72
|
-
bottom: 0;
|
|
73
106
|
left: 50%;
|
|
74
107
|
transform: translateX(-50%);
|
|
75
108
|
}
|
|
76
109
|
|
|
110
|
+
&__body {
|
|
111
|
+
display: flex;
|
|
112
|
+
flex-direction: column;
|
|
113
|
+
row-gap: $space-2;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
&__close {
|
|
117
|
+
position: absolute;
|
|
118
|
+
right: $space-1;
|
|
119
|
+
top: $space-3;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
&__title {
|
|
123
|
+
@include heading-s-default-bold;
|
|
124
|
+
|
|
125
|
+
color: $color-neutral-text-strong;
|
|
126
|
+
|
|
127
|
+
#{$root}.-ds-size-large & {
|
|
128
|
+
@include heading-m-default-bold;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
#{$root}.-ds-color-success & {
|
|
132
|
+
color: $color-success-text-strong;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
#{$root}.-ds-color-warning & {
|
|
136
|
+
color: $color-warning-text-strong;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
#{$root}.-ds-color-danger & {
|
|
140
|
+
color: $color-danger-text-strong;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
#{$root}.-ds-color-info & {
|
|
144
|
+
color: $color-info-text-strong;
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
|
|
77
148
|
&__content {
|
|
78
149
|
@include text-m-default-regular;
|
|
79
150
|
}
|
|
@@ -87,9 +158,15 @@
|
|
|
87
158
|
}
|
|
88
159
|
</style>
|
|
89
160
|
|
|
90
|
-
<script lang="ts">
|
|
91
|
-
import DsButton, {
|
|
161
|
+
<script lang="ts" setup>
|
|
162
|
+
import DsButton, {
|
|
163
|
+
BUTTON_COLORS,
|
|
164
|
+
BUTTON_RADIUSES,
|
|
165
|
+
BUTTON_SIZES,
|
|
166
|
+
BUTTON_TYPES,
|
|
167
|
+
} from '../Buttons/Button';
|
|
92
168
|
import DsCard from '../Cards/Card';
|
|
169
|
+
import DsIconButton, { ICON_BUTTON_COLORS, ICON_BUTTON_SIZES } from '../Buttons/IconButton';
|
|
93
170
|
import {
|
|
94
171
|
TOAST_COLORS,
|
|
95
172
|
TOAST_POSITIONS,
|
|
@@ -98,184 +175,88 @@ import {
|
|
|
98
175
|
ToastPositions,
|
|
99
176
|
ToastSizes,
|
|
100
177
|
} from './Toast.consts';
|
|
101
|
-
import {
|
|
102
|
-
import { ICONS } from '../Icons/Icon';
|
|
103
|
-
|
|
104
|
-
function calculateBoundariesOffset(boundariesElement: HTMLElement) {
|
|
105
|
-
const borderLeftWidth = window.getComputedStyle(boundariesElement).borderLeftWidth;
|
|
106
|
-
const borderRightWidth = window.getComputedStyle(boundariesElement).borderRightWidth;
|
|
107
|
-
const boundingClientRect = boundariesElement.getBoundingClientRect();
|
|
108
|
-
const boundariesOffsetLeft = boundingClientRect.left + parseInt(borderLeftWidth, 10);
|
|
109
|
-
const boundariesOffsetRight =
|
|
110
|
-
boundingClientRect.right - parseInt(borderRightWidth, 10) - parseInt(borderLeftWidth, 10);
|
|
111
|
-
const boundariesOffsetWidth = boundingClientRect.width;
|
|
112
|
-
return {
|
|
113
|
-
left: {
|
|
114
|
-
left: `${boundariesOffsetLeft}px`,
|
|
115
|
-
},
|
|
116
|
-
right: {
|
|
117
|
-
left: `${boundariesOffsetRight}px`,
|
|
118
|
-
transform: 'translateX(-100%)',
|
|
119
|
-
},
|
|
120
|
-
center: {
|
|
121
|
-
left: `${boundariesOffsetLeft + boundariesOffsetWidth / 2}px`,
|
|
122
|
-
transform: 'translateX(-50%)',
|
|
123
|
-
},
|
|
124
|
-
};
|
|
125
|
-
}
|
|
178
|
+
import { computed, onMounted, onUnmounted } from 'vue';
|
|
179
|
+
import { ICONS, IconItem } from '../Icons/Icon';
|
|
126
180
|
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
BUTTON_TYPES: Object.freeze(BUTTON_TYPES),
|
|
206
|
-
TOAST_SIZES: Object.freeze(TOAST_SIZES),
|
|
207
|
-
TOAST_POSITIONS: Object.freeze(TOAST_POSITIONS),
|
|
208
|
-
};
|
|
209
|
-
},
|
|
210
|
-
computed: {
|
|
211
|
-
buttonPrimaryColor() {
|
|
212
|
-
return this.color === TOAST_COLORS.DANGER
|
|
213
|
-
? BUTTON_COLORS.NEUTRAL
|
|
214
|
-
: BUTTON_COLORS.PRIMARY;
|
|
215
|
-
},
|
|
216
|
-
buttonSecondaryColor() {
|
|
217
|
-
return this.color === TOAST_COLORS.DANGER
|
|
218
|
-
? BUTTON_COLORS.DANGER
|
|
219
|
-
: BUTTON_COLORS.NEUTRAL;
|
|
220
|
-
},
|
|
221
|
-
toastPosition() {
|
|
222
|
-
return `-ds-position-${this.position.toLowerCase()}`;
|
|
223
|
-
},
|
|
224
|
-
toastSize() {
|
|
225
|
-
return `-ds-size-${this.size.toLowerCase()}`;
|
|
226
|
-
},
|
|
227
|
-
},
|
|
228
|
-
mounted() {
|
|
229
|
-
this.setBoundariesSelectorElement();
|
|
230
|
-
this.calculateStyles();
|
|
231
|
-
this.boundariesSelectorElementResizeObserver?.disconnect();
|
|
232
|
-
this.boundariesSelectorElementResizeObserver = new ResizeObserver(() => {
|
|
233
|
-
this.calculateStyles();
|
|
234
|
-
});
|
|
235
|
-
if (this.boundariesSelectorElement) {
|
|
236
|
-
this.boundariesSelectorElementResizeObserver.observe(this.boundariesSelectorElement);
|
|
237
|
-
} else {
|
|
238
|
-
//window resize does not work for some reason, so we observe body
|
|
239
|
-
this.boundariesSelectorElementResizeObserver.observe(document.querySelector('body'));
|
|
240
|
-
}
|
|
241
|
-
if (this.isDisappearing && this.disappearingTimeout !== '0') {
|
|
242
|
-
setTimeout(
|
|
243
|
-
() => this.$emit('close'),
|
|
244
|
-
parseInt(this.disappearingTimeout, 10) * 1000 + 100, // 100 ms is to let loading bar animation to finish
|
|
245
|
-
);
|
|
246
|
-
}
|
|
247
|
-
},
|
|
248
|
-
beforeUnmount() {
|
|
249
|
-
this.boundariesSelectorElementResizeObserver.disconnect();
|
|
250
|
-
this.boundariesSelectorElementResizeObserver = null;
|
|
251
|
-
},
|
|
252
|
-
updated() {
|
|
253
|
-
const { right, left } = this.$el.getClientRects()[0];
|
|
254
|
-
if (parseInt(left, 10) < 0 || right > document.documentElement.clientWidth) {
|
|
255
|
-
this.styles = {
|
|
256
|
-
left: '50%',
|
|
257
|
-
transform: 'translateX(-50%)',
|
|
258
|
-
};
|
|
259
|
-
}
|
|
260
|
-
},
|
|
261
|
-
methods: {
|
|
262
|
-
calculateStyles() {
|
|
263
|
-
if (this.boundariesSelectorElement) {
|
|
264
|
-
this.styles = calculateBoundariesOffset(this.boundariesSelectorElement)[
|
|
265
|
-
this.position
|
|
266
|
-
];
|
|
267
|
-
} else {
|
|
268
|
-
this.styles = {};
|
|
269
|
-
}
|
|
270
|
-
},
|
|
271
|
-
setBoundariesSelectorElement() {
|
|
272
|
-
if (typeof this.boundariesSelector === 'string') {
|
|
273
|
-
this.boundariesSelectorElement =
|
|
274
|
-
document.querySelector(this.boundariesSelector) || null;
|
|
275
|
-
} else if (this.boundariesSelector instanceof HTMLElement) {
|
|
276
|
-
this.boundariesSelectorElement = this.boundariesSelector;
|
|
277
|
-
}
|
|
278
|
-
},
|
|
279
|
-
},
|
|
181
|
+
const {
|
|
182
|
+
title = '',
|
|
183
|
+
size = TOAST_SIZES.MEDIUM,
|
|
184
|
+
position = TOAST_POSITIONS.CENTER,
|
|
185
|
+
color = TOAST_COLORS.INFO,
|
|
186
|
+
footerPrimaryButtonText = '',
|
|
187
|
+
footerPrimaryButtonIcon = null,
|
|
188
|
+
footerSecondaryButtonText = '',
|
|
189
|
+
footerSecondaryButtonIcon = null,
|
|
190
|
+
isDisappearing = true,
|
|
191
|
+
disappearingTimeout = '0',
|
|
192
|
+
isClosable = false,
|
|
193
|
+
} = defineProps<{
|
|
194
|
+
title?: string;
|
|
195
|
+
size?: ToastSizes;
|
|
196
|
+
position?: ToastPositions;
|
|
197
|
+
color?: ToastColors;
|
|
198
|
+
footerPrimaryButtonText?: string;
|
|
199
|
+
footerPrimaryButtonIcon?: IconItem | null;
|
|
200
|
+
footerSecondaryButtonText?: string;
|
|
201
|
+
footerSecondaryButtonIcon?: IconItem | null;
|
|
202
|
+
isDisappearing?: boolean;
|
|
203
|
+
/** Seconds, as a numeric string. `'0'` disables the auto-close. */
|
|
204
|
+
disappearingTimeout?: string;
|
|
205
|
+
isClosable?: boolean;
|
|
206
|
+
}>();
|
|
207
|
+
|
|
208
|
+
const emit = defineEmits<{
|
|
209
|
+
close: [];
|
|
210
|
+
'primary-button-click': [];
|
|
211
|
+
'secondary-button-click': [];
|
|
212
|
+
}>();
|
|
213
|
+
|
|
214
|
+
defineSlots<{
|
|
215
|
+
content?: () => any;
|
|
216
|
+
}>();
|
|
217
|
+
|
|
218
|
+
const buttonPrimaryColor = computed(() =>
|
|
219
|
+
color === TOAST_COLORS.DANGER ? BUTTON_COLORS.NEUTRAL : BUTTON_COLORS.PRIMARY,
|
|
220
|
+
);
|
|
221
|
+
|
|
222
|
+
const buttonSecondaryColor = computed(() =>
|
|
223
|
+
color === TOAST_COLORS.DANGER ? BUTTON_COLORS.DANGER : BUTTON_COLORS.NEUTRAL,
|
|
224
|
+
);
|
|
225
|
+
|
|
226
|
+
const buttonSize = computed(() =>
|
|
227
|
+
size === TOAST_SIZES.SMALL ? BUTTON_SIZES.SMALL : BUTTON_SIZES.MEDIUM,
|
|
228
|
+
);
|
|
229
|
+
|
|
230
|
+
const toastSize = computed(() => `-ds-size-${size.toLowerCase()}`);
|
|
231
|
+
|
|
232
|
+
const toastPosition = computed(() => `-ds-position-${position.toLowerCase()}`);
|
|
233
|
+
|
|
234
|
+
const toastColor = computed(() => `-ds-color-${color}`);
|
|
235
|
+
|
|
236
|
+
let disappearingTimeoutId: ReturnType<typeof setTimeout> | null = null;
|
|
237
|
+
|
|
238
|
+
const clearDisappearingTimeout = () => {
|
|
239
|
+
if (disappearingTimeoutId !== null) {
|
|
240
|
+
clearTimeout(disappearingTimeoutId);
|
|
241
|
+
disappearingTimeoutId = null;
|
|
242
|
+
}
|
|
243
|
+
};
|
|
244
|
+
|
|
245
|
+
// `close` is emitted at most once per toast — dismissing it by hand cancels the pending auto-close
|
|
246
|
+
// so consumers driving a queue (or analytics) off the event never see it twice.
|
|
247
|
+
const close = () => {
|
|
248
|
+
clearDisappearingTimeout();
|
|
249
|
+
emit('close');
|
|
250
|
+
};
|
|
251
|
+
|
|
252
|
+
onMounted(() => {
|
|
253
|
+
if (isDisappearing && disappearingTimeout !== '0') {
|
|
254
|
+
disappearingTimeoutId = setTimeout(
|
|
255
|
+
close,
|
|
256
|
+
parseInt(disappearingTimeout, 10) * 1000 + 100, // 100 ms is to let loading bar animation to finish
|
|
257
|
+
);
|
|
258
|
+
}
|
|
280
259
|
});
|
|
260
|
+
|
|
261
|
+
onUnmounted(clearDisappearingTimeout);
|
|
281
262
|
</script>
|
|
@@ -1,7 +1,12 @@
|
|
|
1
1
|
import { MaybeRefOrGetter, ref, Ref } from 'vue';
|
|
2
|
-
import { useFormFieldWithinForm } from '
|
|
2
|
+
import { useFormFieldWithinForm } from './useFormFieldWithinForm';
|
|
3
3
|
|
|
4
|
-
|
|
4
|
+
/**
|
|
5
|
+
* vee-validate bridge shared by the free-text fields (`InputField`, `TextAreaField`). Validation on
|
|
6
|
+
* `input` only starts once the field has been blurred, so a half-typed value is never marked
|
|
7
|
+
* invalid while the user is still filling it in.
|
|
8
|
+
*/
|
|
9
|
+
export function useTextFieldWithinForm(
|
|
5
10
|
name: MaybeRefOrGetter<string | undefined>,
|
|
6
11
|
modelValue: Ref<string | undefined>,
|
|
7
12
|
) {
|
package/lib/js/index.ts
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
export { default as DsActionContent } from './components/ActionContent';
|
|
2
1
|
export { default as Avatar } from './components/Avatar';
|
|
3
2
|
export * from './components/Avatar/Avatar.consts';
|
|
4
3
|
export { default as Badge } from './components/Badge';
|
|
@@ -15,6 +14,8 @@ export * from './components/Buttons/Button/Button.consts';
|
|
|
15
14
|
export { default as ToggleButton } from './components/Toggles/ToggleButton';
|
|
16
15
|
export { default as DsToggleButton } from './components/Toggles/ToggleButton';
|
|
17
16
|
export * from './components/Toggles/ToggleButton/ToggleButton.consts';
|
|
17
|
+
export { default as DsCallout } from './components/Callout';
|
|
18
|
+
export * from './components/Callout/Callout.consts';
|
|
18
19
|
export { default as Card } from './components/Cards/Card/';
|
|
19
20
|
export * from './components/Cards/Card';
|
|
20
21
|
export { default as DsCard } from './components/Cards/Card';
|
|
@@ -53,11 +54,15 @@ export { default as NumberInCircle } from './components/NumberInCircle';
|
|
|
53
54
|
export { default as DsNumberInCircle } from './components/NumberInCircle';
|
|
54
55
|
export * from './components/NumberInCircle/NumberInCircle.consts';
|
|
55
56
|
export { default as DsPasswordField } from './components/Form/PasswordField';
|
|
57
|
+
export { default as DsPinInputField } from './components/Form/PinInputField';
|
|
58
|
+
export * from './components/Form/PinInputField';
|
|
56
59
|
export { default as DsSelectField } from './components/Form/SelectField';
|
|
57
60
|
export * from './components/Form/SelectField';
|
|
58
61
|
export { default as TabItem } from './components/TabItem';
|
|
59
62
|
export { default as DsTabItem } from './components/TabItem';
|
|
60
63
|
export * from './components/TabItem/TabItem.consts';
|
|
64
|
+
export { default as DsTextAreaField } from './components/Form/TextAreaField';
|
|
65
|
+
export * from './components/Form/TextAreaField';
|
|
61
66
|
export { default as Tile } from './components/Tile';
|
|
62
67
|
export { default as DsTile } from './components/Tile';
|
|
63
68
|
export * from './components/Tile/Tile.consts';
|
package/package.json
CHANGED
|
@@ -1,99 +0,0 @@
|
|
|
1
|
-
import { describe, it, expect } from 'vitest';
|
|
2
|
-
import { mount } from '@vue/test-utils';
|
|
3
|
-
import { h } from 'vue';
|
|
4
|
-
import ActionContent from './ActionContent.vue';
|
|
5
|
-
import DsFeatureIcon from '../Icons/FeatureIcon';
|
|
6
|
-
import DsButton from '../Buttons/Button';
|
|
7
|
-
import { ICONS } from '../Icons/Icon';
|
|
8
|
-
|
|
9
|
-
describe('ActionContent', () => {
|
|
10
|
-
it('renders', () => {
|
|
11
|
-
const wrapper = mount(ActionContent);
|
|
12
|
-
|
|
13
|
-
expect(wrapper.exists()).toBe(true);
|
|
14
|
-
});
|
|
15
|
-
|
|
16
|
-
it('renders the feature icon when icon is provided', () => {
|
|
17
|
-
const wrapper = mount(ActionContent, {
|
|
18
|
-
props: {
|
|
19
|
-
icon: ICONS.FA_COMMENT_DOTS,
|
|
20
|
-
},
|
|
21
|
-
});
|
|
22
|
-
|
|
23
|
-
expect(wrapper.findComponent(DsFeatureIcon).exists()).toBe(true);
|
|
24
|
-
});
|
|
25
|
-
|
|
26
|
-
it('does not render the feature icon when icon is not provided', () => {
|
|
27
|
-
const wrapper = mount(ActionContent);
|
|
28
|
-
|
|
29
|
-
expect(wrapper.findComponent(DsFeatureIcon).exists()).toBe(false);
|
|
30
|
-
});
|
|
31
|
-
|
|
32
|
-
it('passes main and supporting text to the text group', () => {
|
|
33
|
-
const wrapper = mount(ActionContent, {
|
|
34
|
-
props: {
|
|
35
|
-
mainText: 'Main text',
|
|
36
|
-
supportingText: 'Supporting text',
|
|
37
|
-
},
|
|
38
|
-
});
|
|
39
|
-
|
|
40
|
-
expect(wrapper.find('.ds-actionContent__text').text()).toContain('Main text');
|
|
41
|
-
expect(wrapper.find('.ds-actionContent__text').text()).toContain('Supporting text');
|
|
42
|
-
});
|
|
43
|
-
|
|
44
|
-
it('renders a default primary button with the button label and icon', () => {
|
|
45
|
-
const wrapper = mount(ActionContent, {
|
|
46
|
-
props: {
|
|
47
|
-
buttonLabel: 'Confirm',
|
|
48
|
-
buttonIcon: ICONS.FA_COMMENT_DOTS,
|
|
49
|
-
},
|
|
50
|
-
});
|
|
51
|
-
|
|
52
|
-
const button = wrapper.findComponent(DsButton);
|
|
53
|
-
expect(button.exists()).toBe(true);
|
|
54
|
-
expect(button.text()).toBe('Confirm');
|
|
55
|
-
expect(button.props('iconLeft')).toStrictEqual(ICONS.FA_COMMENT_DOTS);
|
|
56
|
-
});
|
|
57
|
-
|
|
58
|
-
it('emits button-clicked when the default button is clicked', async () => {
|
|
59
|
-
const wrapper = mount(ActionContent, {
|
|
60
|
-
props: {
|
|
61
|
-
buttonLabel: 'Confirm',
|
|
62
|
-
},
|
|
63
|
-
});
|
|
64
|
-
|
|
65
|
-
await wrapper.findComponent(DsButton).trigger('click');
|
|
66
|
-
|
|
67
|
-
expect(wrapper.emitted('button-clicked')).toHaveLength(1);
|
|
68
|
-
});
|
|
69
|
-
|
|
70
|
-
it('renders the actions slot instead of the default button', () => {
|
|
71
|
-
const wrapper = mount(ActionContent, {
|
|
72
|
-
props: {
|
|
73
|
-
buttonLabel: 'Default button',
|
|
74
|
-
},
|
|
75
|
-
slots: {
|
|
76
|
-
actions: () => h('span', { class: 'custom-action' }, 'Custom action'),
|
|
77
|
-
},
|
|
78
|
-
});
|
|
79
|
-
|
|
80
|
-
expect(wrapper.find('.custom-action').exists()).toBe(true);
|
|
81
|
-
expect(wrapper.findComponent(DsButton).exists()).toBe(false);
|
|
82
|
-
});
|
|
83
|
-
|
|
84
|
-
it('adds the vertical modifier when isActionVertical is set', () => {
|
|
85
|
-
const wrapper = mount(ActionContent, {
|
|
86
|
-
props: {
|
|
87
|
-
isActionVertical: true,
|
|
88
|
-
},
|
|
89
|
-
});
|
|
90
|
-
|
|
91
|
-
expect(wrapper.find('.ds-actionContent__actions').classes()).toContain('-ds-vertical');
|
|
92
|
-
});
|
|
93
|
-
|
|
94
|
-
it('does not add the vertical modifier by default', () => {
|
|
95
|
-
const wrapper = mount(ActionContent);
|
|
96
|
-
|
|
97
|
-
expect(wrapper.find('.ds-actionContent__actions').classes()).not.toContain('-ds-vertical');
|
|
98
|
-
});
|
|
99
|
-
});
|