srcdev-nuxt-components 9.1.55 → 9.1.57

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 (104) hide show
  1. package/.claude/settings.json +30 -2
  2. package/.claude/skills/components/alert-content-inner.md +60 -0
  3. package/.claude/skills/components/display-dialog.md +80 -0
  4. package/.claude/skills/components/display-prompt.md +163 -0
  5. package/.claude/skills/components/display-toast.md +235 -0
  6. package/.claude/skills/index.md +7 -3
  7. package/.claude/skills/theming-colour-ramps.md +328 -0
  8. package/.claude/skills/theming-override-default.md +115 -186
  9. package/.claude/skills/theming-partial-override.md +88 -75
  10. package/README.md +166 -0
  11. package/app/app.config.ts +44 -0
  12. package/app/assets/styles/setup/01.config/_head.css +3 -3
  13. package/app/assets/styles/setup/02.colours/_amber.css +12 -10
  14. package/app/assets/styles/setup/02.colours/_blue.css +10 -9
  15. package/app/assets/styles/setup/02.colours/_green.css +12 -11
  16. package/app/assets/styles/setup/02.colours/_orange.css +12 -10
  17. package/app/assets/styles/setup/02.colours/_red.css +10 -9
  18. package/app/assets/styles/setup/02.colours/_slate.css +12 -11
  19. package/app/assets/styles/setup/02.colours/_sunset.css +12 -10
  20. package/app/assets/styles/setup/02.colours/_theme-params.css +18 -0
  21. package/app/assets/styles/setup/02.colours/index.css +1 -0
  22. package/app/assets/styles/setup/03.theming/_default.css +87 -0
  23. package/app/assets/styles/setup/03.theming/_error.css +14 -0
  24. package/app/assets/styles/setup/03.theming/_success.css +4 -0
  25. package/app/assets/styles/setup/03.theming/_theme-slots.css +16 -0
  26. package/app/assets/styles/setup/03.theming/_warning.css +13 -0
  27. package/app/assets/styles/setup/03.theming/index.css +6 -4
  28. package/app/assets/styles/setup/03.theming/theme-ramp.css +19 -0
  29. package/app/assets/styles/setup/04.elements/forms/00.element-defaults.css +0 -7
  30. package/app/assets/styles/setup/04.elements/forms/06.button-geometry.css +1 -1
  31. package/app/assets/styles/setup/index.css +1 -1
  32. package/app/components/01.atoms/display-dialog/DisplayDialog.vue +74 -24
  33. package/app/components/01.atoms/display-dialog/tests/DisplayDialog.spec.ts +148 -14
  34. package/app/components/01.atoms/display-dialog/tests/__snapshots__/DisplayDialog.spec.ts.snap +3 -3
  35. package/app/components/01.atoms/prompt/DisplayPrompt.vue +113 -0
  36. package/app/components/01.atoms/prompt/stories/DisplayPrompt.stories.ts +112 -0
  37. package/app/components/01.atoms/prompt/tests/DisplayPrompt.spec.ts +205 -0
  38. package/app/components/01.atoms/toast/DisplayToast.vue +327 -0
  39. package/app/components/01.atoms/toast/DisplayToastProvider.vue +362 -0
  40. package/app/components/01.atoms/toast/stories/DisplayToast.stories.ts +195 -0
  41. package/app/components/01.atoms/toast/stories/DisplayToastProvider.stories.ts +142 -0
  42. package/app/components/01.atoms/toast/tests/DisplayToast.spec.ts +266 -0
  43. package/app/components/01.atoms/toast/tests/DisplayToastProvider.spec.ts +256 -0
  44. package/app/components/02.molecules/action-menu/ActionMenu.vue +8 -1
  45. package/app/components/02.molecules/action-menu/ActionMenuItemCore.vue +11 -3
  46. package/app/components/02.molecules/alert-content/AlertContent.vue +67 -0
  47. package/app/components/02.molecules/alert-content/AlertContentInner.vue +153 -0
  48. package/app/components/02.molecules/alert-content/stories/AlertContent.stories.ts +131 -0
  49. package/app/components/02.molecules/alert-content/tests/AlertContent.spec.ts +135 -0
  50. package/app/components/02.molecules/alert-content/tests/AlertContentInner.spec.ts +135 -0
  51. package/app/components/02.molecules/alert-masked-content/AlertMaskedContent.vue +78 -0
  52. package/app/components/02.molecules/alert-masked-content/stories/AlertMaskedContent.stories.ts +132 -0
  53. package/app/components/02.molecules/alert-masked-content/tests/AlertMaskedContent.spec.ts +149 -0
  54. package/app/components/05.forms/input-button/InputButtonCore.vue +35 -39
  55. package/app/components/05.forms/input-checkbox-radio/InputCheckboxRadioButton.vue +8 -8
  56. package/app/components/05.forms/input-checkbox-radio/InputCheckboxRadioCore.vue +5 -5
  57. package/app/components/05.forms/input-copy/InputCopyCore.vue +7 -7
  58. package/app/components/05.forms/input-number/InputNumberCore.vue +5 -5
  59. package/app/components/05.forms/input-select/InputSelectCore.vue +6 -6
  60. package/app/components/05.forms/input-text/InputTextCore.vue +6 -6
  61. package/app/components/05.forms/input-text/variants/InputTextAsNumberWithLabel.vue +2 -2
  62. package/app/components/05.forms/input-textarea/InputTextareaCore.vue +5 -5
  63. package/app/components/05.forms/pending-effect/PendingEffect.vue +60 -60
  64. package/app/components/05.forms/toggle-switch/ToggleSwitchCore.vue +10 -10
  65. package/app/components/05.forms/triple-toggle-switch/TripleToggleSwitchCore.vue +4 -4
  66. package/app/components/display-theme-switch/DisplayThemeSwitch.vue +4 -4
  67. package/app/components/display-tooltip/DisplayTooltip.vue +4 -4
  68. package/app/composables/useBodyLock.ts +21 -0
  69. package/app/composables/useDialogControls.ts +11 -11
  70. package/app/composables/useToastQueue.ts +39 -0
  71. package/app/layouts/default.vue +1 -1
  72. package/app/pages/ui/display-dialog.vue +275 -127
  73. package/app/pages/ui/display-prompt.vue +255 -52
  74. package/app/pages/ui/display-toast.vue +278 -299
  75. package/app/pages/ui/mask-element.vue +25 -3
  76. package/app/pages/ui/settings.vue +9 -35
  77. package/app/types/app-config.d.ts +41 -0
  78. package/app/types/components/display-prompt.d.ts +11 -0
  79. package/app/types/components/display-toast.d.ts +11 -9
  80. package/app/types/components/index.ts +2 -0
  81. package/app/types/components/semantic-theme.d.ts +1 -0
  82. package/nuxt.config.ts +16 -0
  83. package/package.json +8 -4
  84. package/ramps.config.mjs +28 -0
  85. package/scripts/check-ramps.mjs +50 -0
  86. package/scripts/generate-consumer-ramps.mjs +100 -0
  87. package/scripts/generate-ramps.mjs +92 -0
  88. package/app/assets/styles/setup/03.theming/default/_dark.css +0 -156
  89. package/app/assets/styles/setup/03.theming/default/_light.css +0 -166
  90. package/app/assets/styles/setup/03.theming/default/index.css +0 -2
  91. package/app/assets/styles/setup/03.theming/error/_dark.css +0 -56
  92. package/app/assets/styles/setup/03.theming/error/_light.css +0 -74
  93. package/app/assets/styles/setup/03.theming/error/index.css +0 -2
  94. package/app/assets/styles/setup/03.theming/success/_dark.css +0 -50
  95. package/app/assets/styles/setup/03.theming/success/_light.css +0 -65
  96. package/app/assets/styles/setup/03.theming/success/index.css +0 -2
  97. package/app/assets/styles/setup/03.theming/warning/_dark.css +0 -50
  98. package/app/assets/styles/setup/03.theming/warning/_light.css +0 -64
  99. package/app/assets/styles/setup/03.theming/warning/index.css +0 -2
  100. package/app/components/display-prompt/DisplayPromptCore.vue +0 -228
  101. package/app/components/display-prompt/variants/DisplayPromptError.vue +0 -53
  102. package/app/components/display-toast/DisplayToast.vue +0 -447
  103. package/app/components/display-toast/molecules/DefaultToastContent.vue +0 -163
  104. package/app/components/display-toast/stories/DisplayToast.stories.ts +0 -380
@@ -2,331 +2,310 @@
2
2
  <div>
3
3
  <NuxtLayout name="default">
4
4
  <template #layout-content>
5
- <PageRow tag="div" variant="full" :style-class-passthrough="['mbe-20', 'p-20']">
6
- <h2 class="page-heading-2">DisplayToast Component</h2>
7
- <HeaderBlock :tag-level="3" :class-level="3" :style-class-passthrough="['mbe-10']">
8
- Toast notification component (HeaderBlock)
9
- </HeaderBlock>
10
- <p class="page-body-normal">Trigger default toast with manual dismiss</p>
5
+ <PageRow tag="div" variant="content" :style-class-passthrough="['mbe-20', 'p-20']">
6
+ <h2 class="page-heading-2">DisplayToast Masked / DisplayToastProvider</h2>
7
+
8
+ <div v-if="isDev" class="qa-panel">
9
+ <details class="qa-panel__details">
10
+ <summary class="qa-panel__summary">
11
+ <span class="qa-panel__title">QA — DisplayToastProvider</span>
12
+ <code class="qa-panel__status">
13
+ {{ qaTheme }} · {{ qaPosition }}-{{ qaAlignment }} ·
14
+ {{ qaAutoDismiss ? `auto ${qaDuration}ms` : "manual" }} · max:{{ qaMaxVisible }} ·
15
+ {{ qaIsMasked ? "masked" : "solid" }}
16
+ </code>
17
+ </summary>
18
+ <div class="qa-panel__body">
19
+ <div class="qa-panel__group">
20
+ <span class="qa-panel__label">Theme</span>
21
+ <div class="qa-panel__chips">
22
+ <button
23
+ v-for="opt in themes"
24
+ :key="opt"
25
+ class="qa-panel__chip"
26
+ :class="{ 'is-active': qaTheme === opt }"
27
+ @click="qaTheme = opt"
28
+ >
29
+ {{ opt }}
30
+ </button>
31
+ </div>
32
+ </div>
33
+
34
+ <div class="qa-panel__group">
35
+ <span class="qa-panel__label">Position</span>
36
+ <div class="qa-panel__chips">
37
+ <button
38
+ v-for="opt in positions"
39
+ :key="opt"
40
+ class="qa-panel__chip"
41
+ :class="{ 'is-active': qaPosition === opt }"
42
+ @click="qaPosition = opt"
43
+ >
44
+ {{ opt }}
45
+ </button>
46
+ </div>
47
+ </div>
48
+
49
+ <div class="qa-panel__group">
50
+ <span class="qa-panel__label">Alignment</span>
51
+ <div class="qa-panel__chips">
52
+ <button
53
+ v-for="opt in alignments"
54
+ :key="opt"
55
+ class="qa-panel__chip"
56
+ :class="{ 'is-active': qaAlignment === opt }"
57
+ @click="qaAlignment = opt"
58
+ >
59
+ {{ opt }}
60
+ </button>
61
+ </div>
62
+ </div>
63
+
64
+ <div class="qa-panel__group">
65
+ <span class="qa-panel__label">Masked</span>
66
+ <div class="qa-panel__chips">
67
+ <button
68
+ v-for="opt in [true, false]"
69
+ :key="String(opt)"
70
+ class="qa-panel__chip"
71
+ :class="{ 'is-active': qaIsMasked === opt }"
72
+ @click="qaIsMasked = opt"
73
+ >
74
+ {{ opt ? "yes" : "no" }}
75
+ </button>
76
+ </div>
77
+ </div>
78
+
79
+ <div class="qa-panel__group">
80
+ <span class="qa-panel__label">Full Width</span>
81
+ <div class="qa-panel__chips">
82
+ <button
83
+ v-for="opt in [true, false]"
84
+ :key="String(opt)"
85
+ class="qa-panel__chip"
86
+ :class="{ 'is-active': qaFullWidth === opt }"
87
+ @click="qaFullWidth = opt"
88
+ >
89
+ {{ opt ? "yes" : "no" }}
90
+ </button>
91
+ </div>
92
+ </div>
93
+
94
+ <div class="qa-panel__group">
95
+ <span class="qa-panel__label">Auto Dismiss</span>
96
+ <div class="qa-panel__chips">
97
+ <button
98
+ v-for="opt in [true, false]"
99
+ :key="String(opt)"
100
+ class="qa-panel__chip"
101
+ :class="{ 'is-active': qaAutoDismiss === opt }"
102
+ @click="qaAutoDismiss = opt"
103
+ >
104
+ {{ opt ? "yes" : "no" }}
105
+ </button>
106
+ </div>
107
+ </div>
108
+
109
+ <div class="qa-panel__group">
110
+ <span class="qa-panel__label">Duration</span>
111
+ <div class="qa-panel__chips">
112
+ <button
113
+ v-for="opt in durations"
114
+ :key="opt"
115
+ class="qa-panel__chip"
116
+ :class="{ 'is-active': qaDuration === opt }"
117
+ @click="qaDuration = opt"
118
+ >
119
+ {{ opt }}ms
120
+ </button>
121
+ </div>
122
+ </div>
123
+
124
+ <div class="qa-panel__group">
125
+ <span class="qa-panel__label">Max Visible</span>
126
+ <div class="qa-panel__chips">
127
+ <button
128
+ v-for="opt in [1, 2, 3, 4, 5]"
129
+ :key="opt"
130
+ class="qa-panel__chip"
131
+ :class="{ 'is-active': qaMaxVisible === opt }"
132
+ @click="qaMaxVisible = opt"
133
+ >
134
+ {{ opt }}
135
+ </button>
136
+ </div>
137
+ </div>
138
+ </div>
139
+ </details>
140
+ </div>
141
+
11
142
  <form class="form-wrapper">
12
- <p>
13
- <InputButtonCore
14
- ref="firstToastButton"
15
- :readonly="firstToastActive"
16
- button-text="Trigger First Toast (current value: {{ firstToastActive }})"
17
- theme="default"
18
- :style-class-passthrough="['mbe-10']"
19
- @click.prevent="triggerFirstToast()"
20
- />
21
- </p>
22
- <hr class="mbe-20" />
23
- <p class="page-body-normal">Trigger ERROR prompt as toast with auto dismiss</p>
24
- <p>
25
- <InputButtonCore
26
- ref="secondToastButton"
27
- :readonly="secondToastActive"
28
- button-text="Trigger Second Toast (current value: {{ secondToastActive }})"
29
- theme="default"
30
- :style-class-passthrough="['mbe-10']"
31
- @click.prevent="triggerSecondToast()"
32
- />
33
- </p>
34
- <hr class="mbe-20" />
35
- <p class="page-body-normal">Trigger SUCCESS prompt as toast with manual dismiss</p>
36
- <p>
37
- <InputButtonCore
38
- ref="thirdToastButton"
39
- :readonly="thirdToastActive"
40
- button-text="Trigger Third Toast (current value: {{ thirdToastActive }})"
41
- theme="default"
42
- :style-class-passthrough="['mbe-10']"
43
- @click.prevent="triggerThirdToast()"
44
- />
45
- </p>
46
- <hr class="mbe-20" />
47
- <p class="page-body-normal">Trigger INFO prompt as toast with auto dismiss (full-width)</p>
48
- <p>
49
- <InputButtonCore
50
- ref="fourthToastButton"
51
- :readonly="fourthToastActive"
52
- button-text="Trigger Fourth Toast (current value: {{ fourthToastActive }})"
53
- theme="default"
54
- :style-class-passthrough="['mbe-10']"
55
- @click.prevent="triggerFourthToast()"
56
- />
57
- </p>
58
- <hr class="mbe-20" />
59
- <p class="page-body-normal">New config-based positioning examples:</p>
60
- <div class="button-grid">
61
- <InputButtonCore
62
- ref="bottomLeftToastButton"
63
- :readonly="bottomLeftToastActive"
64
- button-text="Bottom Left Toast"
65
- theme="default"
66
- @click.prevent="triggerBottomLeftToast()"
67
- />
68
- <InputButtonCore
69
- ref="bottomCenterToastButton"
70
- :readonly="bottomCenterToastActive"
71
- button-text="Bottom Center Toast"
72
- theme="default"
73
- @click.prevent="triggerBottomCenterToast()"
74
- />
75
- <InputButtonCore
76
- ref="customIconToastButton"
77
- :readonly="customIconToastActive"
78
- button-text="Custom Icon Toast"
79
- theme="default"
80
- @click.prevent="triggerCustomIconToast()"
81
- />
143
+ <div class="demo-buttons">
144
+ <InputButtonCore button-text="Trigger Toast" theme="default" @click.prevent="triggerToast" />
145
+ <InputButtonCore button-text="Queue Multiple" theme="default" @click.prevent="queueMultiple" />
82
146
  </div>
83
- <hr class="mbe-20" />
84
- <p class="page-body-normal">Toast with title and content slots:</p>
85
- <p>
86
- <InputButtonCore
87
- ref="slottedToastButton"
88
- :readonly="slottedToastActive"
89
- button-text="Trigger Slotted Toast (current value: {{ slottedToastActive }})"
90
- theme="default"
91
- :style-class-passthrough="['mbe-10']"
92
- @click.prevent="triggerSlottedToast()"
93
- />
94
- </p>
95
147
  </form>
96
148
  </PageRow>
97
149
 
98
- <DisplayToast
99
- v-model="firstToastActive"
100
- :config="{
101
- appearance: { theme: 'warning', position: 'top', alignment: 'right' },
102
- behavior: { autoDismiss: false, returnFocusTo: firstToastButton },
103
- content: {
104
- title: 'Warning Alert',
105
- description: 'This is a toast notification message with structured content.',
106
- },
107
- }"
150
+ <DisplayToastProvider
151
+ :position="qaPosition"
152
+ :alignment="qaAlignment"
153
+ :full-width="qaFullWidth"
154
+ :max-visible="qaMaxVisible"
108
155
  />
109
-
110
- <DisplayToast
111
- v-model="secondToastActive"
112
- :config="{
113
- appearance: { theme: 'error', position: 'top', alignment: 'right' },
114
- behavior: { returnFocusTo: secondToastButton },
115
- }"
116
- >
117
- <DisplayPromptCore
118
- v-model="secondToastActive"
119
- theme="error"
120
- :dismissible="false"
121
- :style-class-passthrough="['dark', 'outlined']"
122
- >
123
- <template #customDecoratorIcon>
124
- <Icon name="akar-icons:info" class="icon" />
125
- </template>
126
- <template #title>Info Prompt Title with content (Dismissable)</template>
127
- <template #content>This is prompt content, it can contain html or plain text.</template>
128
- </DisplayPromptCore>
129
- </DisplayToast>
130
-
131
- <DisplayToast
132
- v-model="thirdToastActive"
133
- :config="{
134
- appearance: { theme: 'success', position: 'top', alignment: 'right' },
135
- behavior: { autoDismiss: false, returnFocusTo: thirdToastButton },
136
- }"
137
- >
138
- <DisplayPromptCore
139
- v-model="thirdToastActive"
140
- theme="success"
141
- :dismissible="true"
142
- :style-class-passthrough="['dark', 'outlined']"
143
- :use-auto-focus="true"
144
- >
145
- <template #customDecoratorIcon>
146
- <Icon name="akar-icons:info" class="icon" />
147
- </template>
148
- <template #title>Success Prompt Title with content (Dismissable)</template>
149
- <template #content>This is prompt content, it can contain html or plain text.</template>
150
- <template #customCloseIcon>
151
- <Icon name="material-symbols:close-small" class="icon" />
152
- </template>
153
- <template #customTitle>Dismiss</template>
154
- </DisplayPromptCore>
155
- </DisplayToast>
156
-
157
- <DisplayToast
158
- v-model="fourthToastActive"
159
- :config="{
160
- appearance: { theme: 'info', position: 'top', fullWidth: true },
161
- behavior: { returnFocusTo: fourthToastButton },
162
- }"
163
- >
164
- <DisplayPromptCore
165
- v-model="fourthToastActive"
166
- theme="info"
167
- :dismissible="false"
168
- :style-class-passthrough="['dark', 'outlined']"
169
- >
170
- <template #title>Warning Prompt Title with content (Auto Dismiss)</template>
171
- <template #content>This is prompt content, it can contain html or plain text.</template>
172
- <template #customCloseIcon>
173
- <Icon name="material-symbols:close-small" class="icon" />
174
- </template>
175
- <template #customTitle>Dismiss</template>
176
- </DisplayPromptCore>
177
- </DisplayToast>
178
-
179
- <DisplayToast
180
- v-model="bottomLeftToastActive"
181
- :config="{
182
- appearance: { theme: 'primary', position: 'bottom', alignment: 'left' },
183
- behavior: { autoDismiss: true, duration: 3000, returnFocusTo: bottomLeftToastButton },
184
- content: {
185
- title: 'Warning Alert',
186
- description: 'This is a toast notification message with structured content.',
187
- },
188
- }"
189
- />
190
-
191
- <DisplayToast
192
- v-model="bottomCenterToastActive"
193
- :config="{
194
- appearance: { theme: 'secondary', position: 'bottom', alignment: 'center' },
195
- behavior: { autoDismiss: true, duration: 4000, returnFocusTo: bottomCenterToastButton },
196
- content: {
197
- title: 'Warning Alert',
198
- description: 'This is a toast notification message with structured content.',
199
- },
200
- }"
201
- />
202
-
203
- <DisplayToast
204
- v-model="customIconToastActive"
205
- :config="{
206
- appearance: { theme: 'success', position: 'top', alignment: 'left' },
207
- behavior: { autoDismiss: false, returnFocusTo: customIconToastButton },
208
- content: {
209
- title: 'Warning Alert',
210
- description: 'This is a toast notification message with structured content.',
211
- },
212
- }"
213
- />
214
-
215
- <DisplayToast
216
- v-model="slottedToastActive"
217
- :config="{
218
- appearance: { theme: 'info', position: 'top', alignment: 'right' },
219
- behavior: { autoDismiss: false, returnFocusTo: slottedToastButton },
220
- }"
221
- >
222
- <template #title>
223
- <strong>New Feature Available!</strong>
224
- </template>
225
- <template #description>
226
- You can now use title and content slots to create more structured toast notifications with better typography
227
- and layout.
228
- </template>
229
- </DisplayToast>
230
156
  </template>
231
157
  </NuxtLayout>
232
158
  </div>
233
159
  </template>
234
160
 
235
161
  <script setup lang="ts">
236
- /**
237
- * DisplayToast Playground - Updated to use new config-based props system
238
- *
239
- * This playground demonstrates:
240
- * 1. Legacy examples converted to new config structure
241
- * 2. New positioning capabilities (bottom left, bottom center)
242
- * 3. Custom icon support through config
243
- * 4. Different behavior configurations (autoDismiss, duration)
244
- * 5. Return focus functionality for accessibility
245
- *
246
- * The new config system groups props into logical sections:
247
- * - appearance: theme, position, alignment, fullWidth
248
- * - behavior: autoDismiss, duration, revealDuration, returnFocusTo
249
- * - content: text, customIcon
250
- *
251
- * The returnFocusTo property accepts an HTMLElement or ComponentPublicInstance
252
- * and will focus that element when the toast is dismissed, improving accessibility.
253
- */
254
-
255
- definePageMeta({
256
- layout: false,
257
- });
162
+ import type { DisplayToastTheme, DisplayToastPosition, DisplayToastAlignment } from "~/types/components";
163
+
164
+ definePageMeta({ layout: false });
258
165
 
259
166
  useHead({
260
- title: "DisplayToast",
261
- meta: [
262
- {
263
- name: "description",
264
- content: "DisplayToast Meta description content",
265
- },
266
- ],
267
- bodyAttrs: {
268
- class: "displayToast-page",
269
- },
167
+ title: "DisplayToast Masked / DisplayToastProvider",
168
+ meta: [{ name: "description", content: "DisplayToast Masked component demo" }],
169
+ bodyAttrs: { class: "displayToast-page" },
270
170
  });
271
171
 
272
- // Toast state variables
273
- const firstToastActive = ref(false);
274
- const secondToastActive = ref(false);
275
- const thirdToastActive = ref(false);
276
- const fourthToastActive = ref(false);
277
- const bottomLeftToastActive = ref(false);
278
- const bottomCenterToastActive = ref(false);
279
- const customIconToastActive = ref(false);
280
- const slottedToastActive = ref(false);
281
-
282
- // Template refs for focus return
283
- const firstToastButton = useTemplateRef<HTMLButtonElement>("firstToastButton");
284
- const secondToastButton = useTemplateRef<HTMLButtonElement>("secondToastButton");
285
- const thirdToastButton = useTemplateRef<HTMLButtonElement>("thirdToastButton");
286
- const fourthToastButton = useTemplateRef<HTMLButtonElement>("fourthToastButton");
287
- const bottomLeftToastButton = useTemplateRef<HTMLButtonElement>("bottomLeftToastButton");
288
- const bottomCenterToastButton = useTemplateRef<HTMLButtonElement>("bottomCenterToastButton");
289
- const customIconToastButton = useTemplateRef<HTMLButtonElement>("customIconToastButton");
290
- const slottedToastButton = useTemplateRef<HTMLButtonElement>("slottedToastButton");
291
-
292
- const triggerFirstToast = () => {
293
- firstToastActive.value = true;
294
- };
172
+ const isDev = import.meta.dev;
173
+ const { show } = useToastQueue();
295
174
 
296
- const triggerSecondToast = () => {
297
- secondToastActive.value = true;
298
- };
175
+ const themes = ["info", "success", "warning", "error"] as const;
176
+ const positions = ["top", "bottom"] as const;
177
+ const alignments = ["left", "center", "right"] as const;
178
+ const durations = [2000, 3000, 5000, 8000] as const;
299
179
 
300
- const triggerThirdToast = () => {
301
- thirdToastActive.value = true;
302
- };
180
+ const qaTheme = ref<DisplayToastTheme>("info");
181
+ const qaPosition = ref<DisplayToastPosition>("top");
182
+ const qaAlignment = ref<DisplayToastAlignment>("right");
183
+ const qaIsMasked = ref(true);
184
+ const qaFullWidth = ref(false);
185
+ const qaAutoDismiss = ref(true);
186
+ const qaDuration = ref(5000);
187
+ const qaMaxVisible = ref(1);
303
188
 
304
- const triggerFourthToast = () => {
305
- fourthToastActive.value = true;
189
+ const messages: Record<DisplayToastTheme, { title: string; description: string }> = {
190
+ info: { title: "Information", description: "This is an informational notification." },
191
+ success: { title: "Success!", description: "Your action completed successfully." },
192
+ warning: { title: "Warning", description: "Please review this before continuing." },
193
+ error: { title: "Error", description: "Something went wrong. Please try again." },
306
194
  };
307
195
 
308
- const triggerBottomLeftToast = () => {
309
- bottomLeftToastActive.value = true;
196
+ const triggerToast = () => {
197
+ show({
198
+ appearance: { theme: qaTheme.value, masked: qaIsMasked.value },
199
+ behavior: { autoDismiss: qaAutoDismiss.value, duration: qaDuration.value },
200
+ content: messages[qaTheme.value],
201
+ });
310
202
  };
311
203
 
312
- const triggerBottomCenterToast = () => {
313
- bottomCenterToastActive.value = true;
204
+ const queueMultiple = () => {
205
+ themes.forEach((theme) => {
206
+ show({
207
+ appearance: { theme, masked: qaIsMasked.value },
208
+ behavior: { autoDismiss: qaAutoDismiss.value, duration: qaDuration.value },
209
+ content: messages[theme],
210
+ });
211
+ });
314
212
  };
213
+ </script>
315
214
 
316
- const triggerCustomIconToast = () => {
317
- customIconToastActive.value = true;
318
- };
215
+ <style lang="css">
216
+ .demo-buttons {
217
+ display: flex;
218
+ flex-wrap: wrap;
219
+ gap: 1.2rem;
220
+ }
319
221
 
320
- const triggerSlottedToast = () => {
321
- slottedToastActive.value = true;
322
- };
323
- </script>
222
+ .displayToast-page {
223
+ .qa-panel {
224
+ background: oklch(15% 0 0);
225
+ color: white;
226
+ font-size: 1.3rem;
227
+ margin-block: 1.2rem;
228
+ }
229
+
230
+ .qa-panel__details {
231
+ padding: 1rem 2rem;
232
+ }
233
+
234
+ .qa-panel__summary {
235
+ cursor: pointer;
236
+ display: flex;
237
+ align-items: center;
238
+ gap: 1.6rem;
239
+ list-style: none;
240
+ user-select: none;
241
+
242
+ &::-webkit-details-marker {
243
+ display: none;
244
+ }
245
+ }
246
+
247
+ .qa-panel__title {
248
+ font-weight: 600;
249
+ font-size: 1.1rem;
250
+ text-transform: uppercase;
251
+ letter-spacing: 0.08em;
252
+ }
253
+
254
+ .qa-panel__status {
255
+ font-family: monospace;
256
+ font-size: 1.2rem;
257
+ background: oklch(0% 0 0 / 0.3);
258
+ padding: 0.2rem 0.8rem;
259
+ border-radius: 0.4rem;
260
+ user-select: text;
261
+ cursor: text;
262
+ }
263
+
264
+ .qa-panel__body {
265
+ display: flex;
266
+ flex-wrap: wrap;
267
+ gap: 2.4rem;
268
+ padding-block: 1.2rem 0.4rem;
269
+ }
270
+
271
+ .qa-panel__group {
272
+ display: flex;
273
+ flex-direction: column;
274
+ gap: 0.6rem;
275
+ }
276
+
277
+ .qa-panel__label {
278
+ font-size: 1.1rem;
279
+ text-transform: uppercase;
280
+ letter-spacing: 0.08em;
281
+ opacity: 0.55;
282
+ }
283
+
284
+ .qa-panel__chips {
285
+ display: flex;
286
+ flex-wrap: wrap;
287
+ gap: 0.4rem;
288
+ }
289
+
290
+ .qa-panel__chip {
291
+ font-family: monospace;
292
+ font-size: 1.2rem;
293
+ color: white;
294
+ background-color: oklch(0% 0 0 / 0.25);
295
+ border: 1px solid oklch(100% 0 0 / 0.18);
296
+ padding: 0.3rem 1rem;
297
+ border-radius: 0.4rem;
298
+ cursor: pointer;
299
+ transition: background-color 0.15s;
300
+
301
+ &:hover {
302
+ background-color: oklch(0% 0 0 / 0.4);
303
+ }
324
304
 
325
- <style scoped lang="css">
326
- .button-grid {
327
- display: grid;
328
- grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
329
- gap: 1rem;
330
- margin-bottom: 1rem;
305
+ &.is-active {
306
+ background-color: oklch(55% 0.18 240);
307
+ border-color: oklch(55% 0.18 240);
308
+ }
309
+ }
331
310
  }
332
311
  </style>
@@ -9,7 +9,7 @@
9
9
  <AlertMaskCore
10
10
  :config="{
11
11
  backgroundColour: 'rgba(0,0,0,0.25)',
12
- borderColour: 'var(--orange-08)',
12
+ borderColour: 'var(--orange-06)',
13
13
  radiusLeft: 12,
14
14
  radiusRight: 4,
15
15
  borderLeft: 12,
@@ -23,6 +23,27 @@
23
23
  <p>Constant-radius masked border demo, and some more text</p>
24
24
  </div>
25
25
  </AlertMaskCore>
26
+
27
+ <div class="test-mask-element">
28
+ <AlertMaskCore
29
+ :left-border-only="true"
30
+ :config="{
31
+ backgroundColour: 'rgba(0,0,0,0.25)',
32
+ borderColour: 'var(--red-06)',
33
+ radiusLeft: 12,
34
+ radiusRight: 4,
35
+ borderLeft: 12,
36
+ borderTop: 1,
37
+ borderRight: 1,
38
+ borderBottom: 1,
39
+ }"
40
+ :style-class-passthrough="['test-alert']"
41
+ >
42
+ <div class="some-local-class">
43
+ <p>Compact</p>
44
+ </div>
45
+ </AlertMaskCore>
46
+ </div>
26
47
  </div>
27
48
  </PageRow>
28
49
  </template>
@@ -67,12 +88,13 @@ useHead({
67
88
 
68
89
  .alert-mask-core {
69
90
  &.test-alert {
70
- width: 600px;
91
+ /* width: 600px; */
71
92
 
72
93
  .alert-mask-content-slot {
73
94
  .some-local-class {
74
95
  color: white;
75
- padding: 1.2rem;
96
+ padding-block: 0.4rem;
97
+ padding-inline: 0.8rem;
76
98
  }
77
99
  }
78
100
  }