srcdev-nuxt-components 6.1.38 → 6.1.40

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.
@@ -3,6 +3,8 @@
3
3
  class="display-prompt-core"
4
4
  :class="[{ closed: !compopnentOpen }]"
5
5
  :data-test-id="`display-prompt-core-${theme}`"
6
+ ref="promptElementRef"
7
+ tabindex="0"
6
8
  >
7
9
  <div class="display-prompt-wrapper" :data-theme="theme" :class="[elementClasses]" data-test-id="display-prompt">
8
10
  <div class="display-prompt-inner">
@@ -11,7 +13,7 @@
11
13
  <Icon :name="displayPromptIcons[theme] ?? 'akar-icons:circle-alert'" class="icon" :color="iconColor" />
12
14
  </slot>
13
15
  </div>
14
- <div class="display-prompt-content">
16
+ <div class="display-prompt-content" :aria-live="useAutoFocus ? 'polite' : undefined">
15
17
  <p class="title" data-test-id="display-prompt-title">
16
18
  <slot name="title"></slot>
17
19
  </p>
@@ -65,9 +67,14 @@ const props = defineProps({
65
67
  secondary: "akar-icons:info",
66
68
  }),
67
69
  },
70
+ useAutoFocus: {
71
+ type: Boolean,
72
+ default: false,
73
+ },
68
74
  })
69
75
 
70
76
  const slots = useSlots()
77
+ const promptElementRef = useTemplateRef<HTMLElement>("promptElementRef")
71
78
  const parentComponentState = defineModel<boolean>("parentComponentState", { default: false })
72
79
  const compopnentOpen = ref(true)
73
80
  const { elementClasses } = useStyleClassPassthrough(props.styleClassPassthrough)
@@ -80,6 +87,12 @@ const updateComponentState = () => {
80
87
 
81
88
  compopnentOpen.value = false
82
89
  }
90
+
91
+ onMounted(async () => {
92
+ if (props.useAutoFocus && promptElementRef.value) {
93
+ promptElementRef.value.focus()
94
+ }
95
+ })
83
96
  </script>
84
97
 
85
98
  <style lang="css">
@@ -2,7 +2,7 @@
2
2
  <Teleport to="body">
3
3
  <div
4
4
  v-if="privateDisplayToast"
5
- ref="toastElement"
5
+ ref="toastElementRef"
6
6
  class="display-toast"
7
7
  :class="[
8
8
  elementClasses,
@@ -28,7 +28,7 @@
28
28
  </slot>
29
29
  </div>
30
30
  <div class="toast-message" :id="'toast-message-' + toastId">{{ toastDisplayText }}</div>
31
- <div class="toast-action">
31
+ <div v-if="!autoDismiss" class="toast-action">
32
32
  <button @click.prevent="setDismissToast()">
33
33
  <Icon name="material-symbols:close" class="icon" />
34
34
  <span class="sr-only">Close</span>
@@ -176,7 +176,7 @@ const positionClasses = computed(() => {
176
176
  * Accessibility setup
177
177
  */
178
178
  const toastId = useId()
179
- const toastElement = ref<HTMLElement>()
179
+ const toastElementRef = useTemplateRef<HTMLElement>("toastElementRef")
180
180
 
181
181
  // Determine appropriate ARIA attributes based on theme
182
182
  const toastRole = computed(() => {
@@ -232,7 +232,7 @@ watch(
232
232
  await nextTick()
233
233
  // Wait for animation to start before focusing
234
234
  setTimeout(() => {
235
- toastElement.value?.focus()
235
+ toastElementRef.value?.focus()
236
236
  }, 100)
237
237
  }
238
238
 
@@ -249,7 +249,6 @@ watch(
249
249
  @keyframes show {
250
250
  to {
251
251
  opacity: 1;
252
- /* visibility: visible; */
253
252
  transform: translateY(0);
254
253
  }
255
254
  }
@@ -257,12 +256,10 @@ watch(
257
256
  @keyframes hide {
258
257
  0% {
259
258
  opacity: 1;
260
- /* visibility: visible; */
261
259
  transform: translateY(0);
262
260
  }
263
261
  100% {
264
262
  opacity: 0;
265
- /* visibility: hidden; */
266
263
  transform: translateY(-30px);
267
264
  }
268
265
  }
@@ -274,12 +271,16 @@ watch(
274
271
  }
275
272
 
276
273
  .display-toast {
274
+ --_toast-gutter: 12px;
275
+ @media (width >= 600px) {
276
+ --_toast-gutter: 24px;
277
+ }
278
+
277
279
  display: block;
278
280
  overflow: hidden;
279
281
  position: fixed;
280
282
  margin: 0;
281
283
  opacity: 0;
282
- /* visibility: hidden; */
283
284
 
284
285
  z-index: 100;
285
286
 
@@ -294,47 +295,63 @@ watch(
294
295
  }
295
296
 
296
297
  &.show {
297
- animation: show v-bind(revealDurationMs) var(--spring-easing) forwards;
298
- /* animation: show v-bind(revealDurationMs) linear forwards; */
298
+ @supports (animation-timing-function: linear(0, 1)) {
299
+ animation: show v-bind(revealDurationMs) var(--spring-easing) forwards;
300
+ }
301
+
302
+ @supports not (animation-timing-function: linear(0, 1)) {
303
+ animation: show calc(v-bind(revealDurationMs) / 2) linear forwards;
304
+ }
299
305
  }
300
306
 
301
307
  &.hide {
302
- animation: hide v-bind(revealDurationMs) var(--spring-easing) forwards;
303
- /* animation: hide v-bind(revealDurationMs) linear forwards; */
304
- }
308
+ @supports (animation-timing-function: linear(0, 1)) {
309
+ animation: hide v-bind(revealDurationMs) var(--spring-easing) forwards;
310
+ }
305
311
 
306
- &.full-width {
307
- left: 24px;
308
- right: 24px;
312
+ @supports not (animation-timing-function: linear(0, 1)) {
313
+ animation: hide calc(v-bind(revealDurationMs) / 2) linear forwards;
314
+ }
309
315
  }
310
316
 
311
- &:not(.full-width) {
317
+ /*
318
+ * Default is centre for smaller screens
319
+ */
320
+
321
+ inset-inline: var(--_toast-gutter);
322
+ margin-inline: auto;
323
+
324
+ @media (width >= 600px) {
312
325
  &.left {
313
- left: 24px;
326
+ inset-inline-start: var(--_toast-gutter);
327
+ inset-inline-end: unset;
314
328
  }
315
329
 
316
330
  &.right {
317
- right: 24px;
331
+ inset-inline-end: var(--_toast-gutter);
332
+ inset-inline-start: unset;
318
333
  }
319
334
 
320
335
  &.center {
321
- inset-inline: 0;
322
- margin-inline: auto;
323
- width: max-content;
336
+ &:not(.full-width) {
337
+ inset-inline: 0;
338
+ margin-inline: auto;
339
+ width: max-content;
340
+ }
324
341
  }
325
342
  }
326
343
 
327
344
  &.top {
328
- top: 24px;
345
+ inset-block-start: var(--_toast-gutter);
329
346
  transform: translateY(-30px);
330
347
  }
331
348
  &.bottom {
332
- bottom: 24px;
349
+ inset-block-end: var(--_toast-gutter);
333
350
  transform: translateY(30px);
334
351
  }
335
352
 
336
353
  /*
337
- * Styles for the display toast component
354
+ * Styles for the display toast component if slot is empty
338
355
  */
339
356
  &.has-theme {
340
357
  padding-inline-start: 6px;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "srcdev-nuxt-components",
3
3
  "type": "module",
4
- "version": "6.1.38",
4
+ "version": "6.1.40",
5
5
  "main": "nuxt.config.ts",
6
6
  "scripts": {
7
7
  "clean": "rm -rf .nuxt && rm -rf .output && rm -rf .playground/.nuxt && rm -rf .playground/.output",