srcdev-nuxt-components 6.1.17 → 6.1.19
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.
|
@@ -1,8 +1,12 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<div
|
|
2
|
+
<div
|
|
3
|
+
class="display-prompt-core"
|
|
4
|
+
:class="[{ closed: !compopnentOpen }]"
|
|
5
|
+
:data-test-id="`display-prompt-core-${theme}`"
|
|
6
|
+
>
|
|
3
7
|
<div class="display-prompt-wrapper" :data-theme="theme" :class="[elementClasses]" data-test-id="display-prompt">
|
|
4
8
|
<div class="display-prompt-inner">
|
|
5
|
-
<div class="display-prompt-icon" data-test-id="prompt-icon">
|
|
9
|
+
<div class="display-prompt-icon" data-test-id="prompt-icon" aria-hidden="true">
|
|
6
10
|
<slot name="customDecoratorIcon">
|
|
7
11
|
<Icon :name="displayPromptIcons[theme] ?? 'akar-icons:circle-alert'" class="icon" :color="iconColor" />
|
|
8
12
|
</slot>
|
|
@@ -17,7 +21,7 @@
|
|
|
17
21
|
</div>
|
|
18
22
|
<button
|
|
19
23
|
v-if="dismissible"
|
|
20
|
-
@click.prevent="
|
|
24
|
+
@click.prevent="updateComponentState()"
|
|
21
25
|
data-test-id="display-prompt-action"
|
|
22
26
|
class="display-prompt-action"
|
|
23
27
|
>
|
|
@@ -70,12 +74,17 @@ const props = defineProps({
|
|
|
70
74
|
})
|
|
71
75
|
|
|
72
76
|
const slots = useSlots()
|
|
73
|
-
const
|
|
77
|
+
const parentComponentState = defineModel<boolean>("parentComponentState", { default: false })
|
|
78
|
+
const compopnentOpen = ref(true)
|
|
74
79
|
const { elementClasses } = useStyleClassPassthrough(props.styleClassPassthrough)
|
|
75
80
|
|
|
76
|
-
const
|
|
77
|
-
|
|
78
|
-
|
|
81
|
+
const updateComponentState = () => {
|
|
82
|
+
if (parentComponentState.value) {
|
|
83
|
+
parentComponentState.value = false
|
|
84
|
+
return
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
compopnentOpen.value = false
|
|
79
88
|
}
|
|
80
89
|
</script>
|
|
81
90
|
|
|
@@ -86,7 +95,7 @@ const dismissPrompt = () => {
|
|
|
86
95
|
opacity: 1;
|
|
87
96
|
transition: all 200ms ease-in-out;
|
|
88
97
|
|
|
89
|
-
&.
|
|
98
|
+
&.closed {
|
|
90
99
|
grid-template-rows: 0fr;
|
|
91
100
|
opacity: 0;
|
|
92
101
|
pointer-events: none;
|
|
@@ -141,7 +150,7 @@ const dismissPrompt = () => {
|
|
|
141
150
|
}
|
|
142
151
|
|
|
143
152
|
.text {
|
|
144
|
-
font-size: var(--step-
|
|
153
|
+
font-size: var(--step-4);
|
|
145
154
|
font-weight: normal;
|
|
146
155
|
line-height: 1.3;
|
|
147
156
|
color: var(--colour-theme-8);
|
|
@@ -0,0 +1,361 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<Teleport to="body">
|
|
3
|
+
<div
|
|
4
|
+
v-if="privateToastState"
|
|
5
|
+
class="display-toast"
|
|
6
|
+
:class="[
|
|
7
|
+
elementClasses,
|
|
8
|
+
{
|
|
9
|
+
[theme]: !slots.default,
|
|
10
|
+
'has-theme': !slots.default,
|
|
11
|
+
show: publicToastState && !isHiding && displayDurationInt === 0,
|
|
12
|
+
'use-timer': displayDurationInt > 0,
|
|
13
|
+
hide: isHiding,
|
|
14
|
+
},
|
|
15
|
+
]"
|
|
16
|
+
:data-theme="theme"
|
|
17
|
+
>
|
|
18
|
+
<slot v-if="slots.default"></slot>
|
|
19
|
+
|
|
20
|
+
<div v-else class="display-toast-inner">
|
|
21
|
+
<div class="toast-icon" aria-hidden="true">
|
|
22
|
+
<slot name="customToastIcon">
|
|
23
|
+
<Icon :name="defaultThemeIcons[props.theme] ?? 'akar-icons:info'" class="icon" />
|
|
24
|
+
</slot>
|
|
25
|
+
</div>
|
|
26
|
+
<div class="toast-message">{{ toastDisplayText }}</div>
|
|
27
|
+
<div class="toast-action">
|
|
28
|
+
<button @click.prevent="closeToast">
|
|
29
|
+
<Icon name="material-symbols:close" class="icon" />
|
|
30
|
+
<span class="sr-only">Close</span>
|
|
31
|
+
</button>
|
|
32
|
+
</div>
|
|
33
|
+
</div>
|
|
34
|
+
<div v-if="displayDurationInt > 0" @transitionend="closeToast()" class="display-toast-progress"></div>
|
|
35
|
+
</div>
|
|
36
|
+
</Teleport>
|
|
37
|
+
</template>
|
|
38
|
+
<script setup lang="ts">
|
|
39
|
+
const props = defineProps({
|
|
40
|
+
theme: {
|
|
41
|
+
type: String as PropType<"primary" | "secondary" | "tertiary" | "ghost" | "error" | "info" | "success" | "warning">,
|
|
42
|
+
default: "ghost",
|
|
43
|
+
validator(value: string) {
|
|
44
|
+
return ["primary", "secondary", "tertiary", "ghost", "error", "info", "success", "warning"].includes(value)
|
|
45
|
+
},
|
|
46
|
+
},
|
|
47
|
+
revealDuration: {
|
|
48
|
+
type: Number,
|
|
49
|
+
default: 3000,
|
|
50
|
+
},
|
|
51
|
+
duration: {
|
|
52
|
+
type: Number,
|
|
53
|
+
default: 5000,
|
|
54
|
+
},
|
|
55
|
+
toastDisplayText: {
|
|
56
|
+
type: String,
|
|
57
|
+
default: "",
|
|
58
|
+
},
|
|
59
|
+
styleClassPassthrough: {
|
|
60
|
+
type: Array as PropType<string[]>,
|
|
61
|
+
default: () => [],
|
|
62
|
+
},
|
|
63
|
+
})
|
|
64
|
+
|
|
65
|
+
const defaultThemeIcons = {
|
|
66
|
+
primary: "akar-icons:info",
|
|
67
|
+
secondary: "akar-icons:info",
|
|
68
|
+
tertiary: "akar-icons:info",
|
|
69
|
+
ghost: "akar-icons:info",
|
|
70
|
+
error: "akar-icons:circle-alert",
|
|
71
|
+
info: "akar-icons:info",
|
|
72
|
+
success: "akar-icons:info",
|
|
73
|
+
warning: "akar-icons:circle-alert",
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
const slots = useSlots()
|
|
77
|
+
const { elementClasses, resetElementClasses } = useStyleClassPassthrough(props.styleClassPassthrough)
|
|
78
|
+
|
|
79
|
+
const privateToastState = ref(false)
|
|
80
|
+
const isHiding = ref(false)
|
|
81
|
+
const publicToastState = defineModel<boolean>({ default: false })
|
|
82
|
+
|
|
83
|
+
const revealDurationInt = computed(() => props.revealDuration)
|
|
84
|
+
const revealDuration = computed(() => revealDurationInt.value + "ms")
|
|
85
|
+
const displayDurationInt = computed(() => props.duration)
|
|
86
|
+
const displayDuration = computed(() => displayDurationInt.value + "ms")
|
|
87
|
+
|
|
88
|
+
const progressDurationInt = computed(() => Math.floor(displayDurationInt.value - revealDurationInt.value / 2))
|
|
89
|
+
const progressDuration = computed(() => progressDurationInt.value + "ms")
|
|
90
|
+
|
|
91
|
+
const sendCloseEvent = () => {
|
|
92
|
+
publicToastState.value = false
|
|
93
|
+
privateToastState.value = false
|
|
94
|
+
isHiding.value = false
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
const closeToast = async () => {
|
|
98
|
+
isHiding.value = true
|
|
99
|
+
await useSleep(revealDurationInt.value)
|
|
100
|
+
sendCloseEvent()
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
watch(
|
|
104
|
+
() => props.styleClassPassthrough,
|
|
105
|
+
() => {
|
|
106
|
+
resetElementClasses(props.styleClassPassthrough)
|
|
107
|
+
}
|
|
108
|
+
)
|
|
109
|
+
|
|
110
|
+
watch(
|
|
111
|
+
() => publicToastState.value,
|
|
112
|
+
async (newValue, previousValue) => {
|
|
113
|
+
if (!previousValue && newValue) {
|
|
114
|
+
privateToastState.value = true
|
|
115
|
+
|
|
116
|
+
if (newValue && displayDurationInt.value > 0) {
|
|
117
|
+
await useSleep(displayDurationInt.value)
|
|
118
|
+
sendCloseEvent()
|
|
119
|
+
}
|
|
120
|
+
} else if (previousValue && !newValue) {
|
|
121
|
+
closeToast()
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
)
|
|
125
|
+
</script>
|
|
126
|
+
|
|
127
|
+
<style scoped lang="css">
|
|
128
|
+
@keyframes fade-in {
|
|
129
|
+
5% {
|
|
130
|
+
opacity: 1;
|
|
131
|
+
visibility: visible;
|
|
132
|
+
transform: translateY(0);
|
|
133
|
+
}
|
|
134
|
+
95% {
|
|
135
|
+
opacity: 1;
|
|
136
|
+
transform: translateY(0);
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
@keyframes show {
|
|
141
|
+
to {
|
|
142
|
+
opacity: 1;
|
|
143
|
+
visibility: visible;
|
|
144
|
+
transform: translateY(0);
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
@keyframes hide {
|
|
149
|
+
0% {
|
|
150
|
+
opacity: 1;
|
|
151
|
+
visibility: visible;
|
|
152
|
+
transform: translateY(0);
|
|
153
|
+
}
|
|
154
|
+
100% {
|
|
155
|
+
opacity: 0;
|
|
156
|
+
visibility: hidden;
|
|
157
|
+
transform: translateY(-30px);
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
@keyframes progress {
|
|
162
|
+
to {
|
|
163
|
+
transform: scaleX(1);
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
.display-toast {
|
|
168
|
+
display: block;
|
|
169
|
+
overflow: hidden;
|
|
170
|
+
position: fixed;
|
|
171
|
+
margin: 0;
|
|
172
|
+
opacity: 0;
|
|
173
|
+
visibility: hidden;
|
|
174
|
+
|
|
175
|
+
z-index: 100;
|
|
176
|
+
|
|
177
|
+
&.use-timer {
|
|
178
|
+
animation: fade-in v-bind(displayDuration) linear;
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
&.show {
|
|
182
|
+
animation: show v-bind(revealDuration)
|
|
183
|
+
linear(
|
|
184
|
+
0,
|
|
185
|
+
0.029 1.6%,
|
|
186
|
+
0.123 3.5%,
|
|
187
|
+
0.651 10.6%,
|
|
188
|
+
0.862 14.1%,
|
|
189
|
+
1.002 17.7%,
|
|
190
|
+
1.046 19.6%,
|
|
191
|
+
1.074 21.6%,
|
|
192
|
+
1.087 23.9%,
|
|
193
|
+
1.086 26.6%,
|
|
194
|
+
1.014 38.5%,
|
|
195
|
+
0.994 46.3%,
|
|
196
|
+
1
|
|
197
|
+
)
|
|
198
|
+
forwards;
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
&.hide {
|
|
202
|
+
animation: hide v-bind(revealDuration)
|
|
203
|
+
linear(
|
|
204
|
+
0,
|
|
205
|
+
0.006 53.7%,
|
|
206
|
+
0.986 61.5%,
|
|
207
|
+
1.014 73.4%,
|
|
208
|
+
1.087 76.1%,
|
|
209
|
+
1.074 78.4%,
|
|
210
|
+
1.046 80.4%,
|
|
211
|
+
1.002 82.3%,
|
|
212
|
+
0.862 85.9%,
|
|
213
|
+
0.651 89.4%,
|
|
214
|
+
0.123 96.5%,
|
|
215
|
+
0.029 98.4%,
|
|
216
|
+
0
|
|
217
|
+
)
|
|
218
|
+
forwards;
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
&:hover {
|
|
222
|
+
.display-toast-progress {
|
|
223
|
+
animation-play-state: paused;
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
&.full-width {
|
|
228
|
+
left: 24px;
|
|
229
|
+
right: 24px;
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
&:not(.full-width) {
|
|
233
|
+
&.left {
|
|
234
|
+
left: 24px;
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
&.right {
|
|
238
|
+
right: 24px;
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
&.center {
|
|
242
|
+
left: 50%;
|
|
243
|
+
/* transform: translateX(-50%); */
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
&.top {
|
|
248
|
+
top: 24px;
|
|
249
|
+
transform: translateY(-30px);
|
|
250
|
+
}
|
|
251
|
+
&.bottom {
|
|
252
|
+
bottom: 24px;
|
|
253
|
+
transform: translateY(30px);
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
/*
|
|
257
|
+
* Styles for the display toast component
|
|
258
|
+
*/
|
|
259
|
+
|
|
260
|
+
&.has-theme {
|
|
261
|
+
padding-inline-start: 6px;
|
|
262
|
+
background-color: var(--colour-theme-8);
|
|
263
|
+
|
|
264
|
+
border: 0.1rem solid var(--colour-theme-8);
|
|
265
|
+
border-start-start-radius: 8px;
|
|
266
|
+
border-end-start-radius: 8px;
|
|
267
|
+
overflow: hidden;
|
|
268
|
+
|
|
269
|
+
.display-toast-inner {
|
|
270
|
+
display: grid;
|
|
271
|
+
grid-template-columns: auto 1fr auto;
|
|
272
|
+
gap: 12px;
|
|
273
|
+
align-items: center;
|
|
274
|
+
background-color: var(--gray-10);
|
|
275
|
+
border-start-start-radius: 8px;
|
|
276
|
+
border-end-start-radius: 8px;
|
|
277
|
+
padding: 12px 14px;
|
|
278
|
+
overflow: hidden;
|
|
279
|
+
|
|
280
|
+
.toast-icon {
|
|
281
|
+
display: inline-flex;
|
|
282
|
+
align-items: center;
|
|
283
|
+
justify-content: center;
|
|
284
|
+
margin-right: 12px;
|
|
285
|
+
|
|
286
|
+
.icon {
|
|
287
|
+
color: var(--colour-theme-0);
|
|
288
|
+
display: inline-block;
|
|
289
|
+
font-size: 2.5rem;
|
|
290
|
+
font-style: normal;
|
|
291
|
+
font-weight: normal;
|
|
292
|
+
overflow: hidden;
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
.toast-message {
|
|
297
|
+
display: flex;
|
|
298
|
+
align-items: center;
|
|
299
|
+
font-size: var(--step-4);
|
|
300
|
+
font-weight: normal;
|
|
301
|
+
line-height: 1.3;
|
|
302
|
+
color: var(--colour-theme-0);
|
|
303
|
+
margin: 0;
|
|
304
|
+
padding: 0;
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
.toast-action {
|
|
308
|
+
display: flex;
|
|
309
|
+
align-items: center;
|
|
310
|
+
justify-content: center;
|
|
311
|
+
margin-left: 12px;
|
|
312
|
+
|
|
313
|
+
button {
|
|
314
|
+
display: flex;
|
|
315
|
+
align-items: center;
|
|
316
|
+
justify-content: center;
|
|
317
|
+
background: var(--colour-theme-10);
|
|
318
|
+
border: 0.1rem solid var(--colour-theme-8);
|
|
319
|
+
outline: 0.1rem solid transparent;
|
|
320
|
+
border-radius: 50%;
|
|
321
|
+
box-shadow: none;
|
|
322
|
+
color: var(--colour-theme-0);
|
|
323
|
+
cursor: pointer;
|
|
324
|
+
font-size: var(--step-4);
|
|
325
|
+
font-weight: bold;
|
|
326
|
+
padding: 0.5rem;
|
|
327
|
+
text-decoration: underline;
|
|
328
|
+
|
|
329
|
+
transition: all 0.3s ease;
|
|
330
|
+
|
|
331
|
+
.icon {
|
|
332
|
+
font-size: 1.5rem;
|
|
333
|
+
vertical-align: middle;
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
&:hover {
|
|
337
|
+
box-shadow: none;
|
|
338
|
+
background-color: var(--colour-theme-8);
|
|
339
|
+
color: var(--colour-theme-0);
|
|
340
|
+
outline: 0.1rem solid var(--colour-theme-3);
|
|
341
|
+
outline-offset: 0.2rem;
|
|
342
|
+
}
|
|
343
|
+
}
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
.display-toast-progress {
|
|
349
|
+
position: absolute;
|
|
350
|
+
right: 8px;
|
|
351
|
+
bottom: 4px;
|
|
352
|
+
width: calc(100% - 16px);
|
|
353
|
+
height: 3px;
|
|
354
|
+
transform: scaleX(0);
|
|
355
|
+
transform-origin: right;
|
|
356
|
+
background: linear-gradient(to right, var(--colour-theme-2), var(--colour-theme-8));
|
|
357
|
+
border-radius: inherit;
|
|
358
|
+
animation: progress v-bind(progressDuration) linear forwards;
|
|
359
|
+
}
|
|
360
|
+
}
|
|
361
|
+
</style>
|
package/package.json
CHANGED