srcdev-nuxt-components 9.1.55 → 9.1.56

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 (100) hide show
  1. package/.claude/settings.json +29 -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 +6 -4
  84. package/app/assets/styles/setup/03.theming/default/_dark.css +0 -156
  85. package/app/assets/styles/setup/03.theming/default/_light.css +0 -166
  86. package/app/assets/styles/setup/03.theming/default/index.css +0 -2
  87. package/app/assets/styles/setup/03.theming/error/_dark.css +0 -56
  88. package/app/assets/styles/setup/03.theming/error/_light.css +0 -74
  89. package/app/assets/styles/setup/03.theming/error/index.css +0 -2
  90. package/app/assets/styles/setup/03.theming/success/_dark.css +0 -50
  91. package/app/assets/styles/setup/03.theming/success/_light.css +0 -65
  92. package/app/assets/styles/setup/03.theming/success/index.css +0 -2
  93. package/app/assets/styles/setup/03.theming/warning/_dark.css +0 -50
  94. package/app/assets/styles/setup/03.theming/warning/_light.css +0 -64
  95. package/app/assets/styles/setup/03.theming/warning/index.css +0 -2
  96. package/app/components/display-prompt/DisplayPromptCore.vue +0 -228
  97. package/app/components/display-prompt/variants/DisplayPromptError.vue +0 -53
  98. package/app/components/display-toast/DisplayToast.vue +0 -447
  99. package/app/components/display-toast/molecules/DefaultToastContent.vue +0 -163
  100. package/app/components/display-toast/stories/DisplayToast.stories.ts +0 -380
@@ -2,58 +2,130 @@
2
2
  <div>
3
3
  <NuxtLayout name="default">
4
4
  <template #layout-content>
5
- <PageRow tag="div" variant="popout" style-class-passthrough="['pb-12']">
5
+ <PageRow tag="div" variant="content" :style-class-passthrough="['pb-12']">
6
6
  <h1 class="page-heading-2">Display Prompts</h1>
7
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 — DisplayPrompt</span>
12
+ <code class="qa-panel__status">
13
+ {{ qaTheme }} · {{ qaDismissible ? "dismissible" : "static" }} ·
14
+ {{ qaOutlined ? "outlined" : "no-outline" }} · {{ qaHighContrast ? "high-contrast" : "standard" }} ·
15
+ {{ qaMasked ? "masked" : "unmasked" }}
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">Dismissible</span>
36
+ <div class="qa-panel__chips">
37
+ <button
38
+ v-for="opt in [true, false]"
39
+ :key="String(opt)"
40
+ class="qa-panel__chip"
41
+ :class="{ 'is-active': qaDismissible === opt }"
42
+ @click="qaDismissible = opt"
43
+ >
44
+ {{ opt ? "yes" : "no" }}
45
+ </button>
46
+ </div>
47
+ </div>
48
+
49
+ <div class="qa-panel__group">
50
+ <span class="qa-panel__label">Outlined</span>
51
+ <div class="qa-panel__chips">
52
+ <button
53
+ v-for="opt in [true, false]"
54
+ :key="String(opt)"
55
+ class="qa-panel__chip"
56
+ :class="{ 'is-active': qaOutlined === opt }"
57
+ @click="qaOutlined = opt"
58
+ >
59
+ {{ opt ? "yes" : "no" }}
60
+ </button>
61
+ </div>
62
+ </div>
63
+
64
+ <div class="qa-panel__group">
65
+ <span class="qa-panel__label">High Contrast</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': qaHighContrast === opt }"
72
+ @click="qaHighContrast = 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">Auto Focus</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': qaAutoFocus === opt }"
87
+ @click="qaAutoFocus = 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">Masked</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': qaMasked === opt }"
102
+ @click="qaMasked = opt"
103
+ >
104
+ {{ opt ? "yes" : "no" }}
105
+ </button>
106
+ </div>
107
+ </div>
108
+ </div>
109
+ </details>
110
+ </div>
111
+
8
112
  <section class="prompt-examples pb-12">
9
- <DisplayPromptCore
10
- theme="success"
11
- :dismissible="true"
12
- :use-local-style-overrides="true"
13
- :style-class-passthrough="['your-scope-class', 'outlined', 'dark']"
14
- >
15
- <template #customDecoratorIcon>
16
- <Icon name="akar-icons:info" class="icon" />
17
- </template>
18
- <template #title>Success Prompt Title with content (Dismissable)</template>
19
- <template #content>This is prompt content, it can contain html or plain text.</template>
20
- <template #customCloseIcon>
21
- <Icon name="material-symbols:close-small" class="icon" />
22
- </template>
23
- <template #customTitle>Dismiss</template>
24
- </DisplayPromptCore>
25
-
26
- <DisplayPromptCore theme="secondary" :dismissible="true" :style-class-passthrough="['your-scope-class']">
27
- <template #customDecoratorIcon>
28
- <Icon name="akar-icons:info" class="icon" />
29
- </template>
30
- <template #title>Secondary Prompt Title with content (Dismissable)</template>
31
- <template #content>This is prompt content, it can contain html or plain text.</template>
32
- </DisplayPromptCore>
33
-
34
- <DisplayPromptCore theme="info" :dismissible="true" :style-class-passthrough="['your-scope-class']">
35
- <template #customDecoratorIcon>
36
- <Icon name="akar-icons:info" class="icon" />
37
- </template>
38
- <template #title>Info Prompt Title with content (Dismissable)</template>
39
- <template #content>This is prompt content, it can contain html or plain text.</template>
40
- </DisplayPromptCore>
41
-
42
- <DisplayPromptCore theme="error" :dismissible="true" :style-class-passthrough="['your-scope-class']">
43
- <template #customDecoratorIcon>
44
- <Icon name="akar-icons:circle-alert" class="icon" />
45
- </template>
46
- <template #title>Error Prompt Title with content (Dismissable)</template>
47
- <template #content>This is prompt content, it can contain html or plain text.</template>
48
- </DisplayPromptCore>
49
-
50
- <DisplayPromptCore theme="warning" :dismissible="true" :style-class-passthrough="['your-scope-class']">
51
- <template #customDecoratorIcon>
52
- <Icon name="akar-icons:circle-alert" class="icon" />
53
- </template>
54
- <template #title>Warning Prompt Title with content (Dismissable)</template>
55
- <template #content>This is prompt content, it can contain html or plain text.</template>
56
- </DisplayPromptCore>
113
+ <div :class="{ 'masked-bg': qaMasked }">
114
+ <DisplayPrompt
115
+ :key="promptKey"
116
+ :theme="qaTheme"
117
+ :dismissible="qaDismissible"
118
+ :use-auto-focus="qaAutoFocus"
119
+ :masked="qaMasked"
120
+ :style-class-passthrough="styleClasses"
121
+ >
122
+ <template #customDecoratorIcon>
123
+ <Icon :name="themeIcons[qaTheme]" class="icon" />
124
+ </template>
125
+ <template #title>{{ themeLabels[qaTheme] }} Prompt Title</template>
126
+ <template #content>This is prompt content, it can contain html or plain text.</template>
127
+ </DisplayPrompt>
128
+ </div>
57
129
  </section>
58
130
  </PageRow>
59
131
  </template>
@@ -62,14 +134,49 @@
62
134
  </template>
63
135
 
64
136
  <script setup lang="ts">
65
- definePageMeta({
66
- layout: false,
67
- });
137
+ import type { DisplayPromptTheme } from "~/types/components";
138
+
139
+ definePageMeta({ layout: false });
68
140
 
69
141
  useHead({
70
142
  title: "UI Display Prompts",
71
143
  meta: [{ name: "description", content: "Examples of UI Display Prompts" }],
144
+ bodyAttrs: { class: "displayPrompt-page" },
72
145
  });
146
+
147
+ const isDev = import.meta.dev;
148
+
149
+ const themes = ["info", "success", "warning", "error"] as const;
150
+
151
+ const qaTheme = ref<DisplayPromptTheme>("info");
152
+ const qaDismissible = ref(true);
153
+ const qaOutlined = ref(false);
154
+ const qaHighContrast = ref(false);
155
+ const qaAutoFocus = ref(false);
156
+ const qaMasked = ref(false);
157
+
158
+ const themeIcons: Record<DisplayPromptTheme, string> = {
159
+ info: "akar-icons:info",
160
+ success: "akar-icons:check",
161
+ warning: "akar-icons:circle-alert",
162
+ error: "akar-icons:circle-alert",
163
+ };
164
+
165
+ const themeLabels: Record<DisplayPromptTheme, string> = {
166
+ info: "Info",
167
+ success: "Success",
168
+ warning: "Warning",
169
+ error: "Error",
170
+ };
171
+
172
+ const styleClasses = computed(() => {
173
+ const classes: string[] = [];
174
+ if (qaOutlined.value) classes.push("outlined");
175
+ if (qaHighContrast.value) classes.push("high-contrast");
176
+ return classes;
177
+ });
178
+
179
+ const promptKey = computed(() => `${qaTheme.value}-${qaDismissible.value}-${qaMasked.value}`);
73
180
  </script>
74
181
 
75
182
  <style lang="css">
@@ -77,5 +184,101 @@ useHead({
77
184
  display: flex;
78
185
  flex-direction: column;
79
186
  gap: 1rem;
187
+
188
+ .masked-bg {
189
+ padding: 2rem;
190
+ border-radius: 0.8rem;
191
+ background: linear-gradient(135deg, oklch(40% 0.15 250), oklch(25% 0.1 300));
192
+ }
193
+ }
194
+
195
+ .displayPrompt-page {
196
+ .qa-panel {
197
+ background: oklch(15% 0 0);
198
+ color: white;
199
+ font-size: 1.3rem;
200
+ margin-block: 1.2rem;
201
+ }
202
+
203
+ .qa-panel__details {
204
+ padding: 1rem 2rem;
205
+ }
206
+
207
+ .qa-panel__summary {
208
+ cursor: pointer;
209
+ display: flex;
210
+ align-items: center;
211
+ gap: 1.6rem;
212
+ list-style: none;
213
+ user-select: none;
214
+
215
+ &::-webkit-details-marker {
216
+ display: none;
217
+ }
218
+ }
219
+
220
+ .qa-panel__title {
221
+ font-weight: 600;
222
+ font-size: 1.1rem;
223
+ text-transform: uppercase;
224
+ letter-spacing: 0.08em;
225
+ }
226
+
227
+ .qa-panel__status {
228
+ font-family: monospace;
229
+ font-size: 1.2rem;
230
+ background: oklch(0% 0 0 / 0.3);
231
+ padding: 0.2rem 0.8rem;
232
+ border-radius: 0.4rem;
233
+ user-select: text;
234
+ cursor: text;
235
+ }
236
+
237
+ .qa-panel__body {
238
+ display: flex;
239
+ flex-wrap: wrap;
240
+ gap: 2.4rem;
241
+ padding-block: 1.2rem 0.4rem;
242
+ }
243
+
244
+ .qa-panel__group {
245
+ display: flex;
246
+ flex-direction: column;
247
+ gap: 0.6rem;
248
+ }
249
+
250
+ .qa-panel__label {
251
+ font-size: 1.1rem;
252
+ text-transform: uppercase;
253
+ letter-spacing: 0.08em;
254
+ opacity: 0.55;
255
+ }
256
+
257
+ .qa-panel__chips {
258
+ display: flex;
259
+ flex-wrap: wrap;
260
+ gap: 0.4rem;
261
+ }
262
+
263
+ .qa-panel__chip {
264
+ font-family: monospace;
265
+ font-size: 1.2rem;
266
+ color: white;
267
+ background: oklch(0% 0 0 / 0.25);
268
+ border: 1px solid oklch(100% 0 0 / 0.18);
269
+ padding: 0.3rem 1rem;
270
+ border-radius: 0.4rem;
271
+ cursor: pointer;
272
+ transition: background 0.15s;
273
+
274
+ &:hover {
275
+ background: oklch(0% 0 0 / 0.4);
276
+ }
277
+
278
+ &.is-active {
279
+ background: oklch(55% 0.18 240);
280
+ border-color: oklch(55% 0.18 240);
281
+ }
282
+ }
80
283
  }
81
284
  </style>