srcdev-nuxt-components 9.1.54 → 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.
- package/.claude/settings.json +29 -2
- package/.claude/skills/components/alert-content-inner.md +60 -0
- package/.claude/skills/components/display-dialog.md +80 -0
- package/.claude/skills/components/display-prompt.md +163 -0
- package/.claude/skills/components/display-toast.md +235 -0
- package/.claude/skills/index.md +7 -3
- package/.claude/skills/theming-colour-ramps.md +328 -0
- package/.claude/skills/theming-override-default.md +115 -186
- package/.claude/skills/theming-partial-override.md +88 -75
- package/README.md +166 -0
- package/app/app.config.ts +44 -0
- package/app/assets/styles/setup/01.config/_head.css +3 -3
- package/app/assets/styles/setup/02.colours/_amber.css +12 -10
- package/app/assets/styles/setup/02.colours/_blue.css +10 -9
- package/app/assets/styles/setup/02.colours/_green.css +12 -11
- package/app/assets/styles/setup/02.colours/_orange.css +12 -10
- package/app/assets/styles/setup/02.colours/_red.css +10 -9
- package/app/assets/styles/setup/02.colours/_slate.css +12 -11
- package/app/assets/styles/setup/02.colours/_sunset.css +12 -10
- package/app/assets/styles/setup/02.colours/_theme-params.css +18 -0
- package/app/assets/styles/setup/02.colours/index.css +1 -0
- package/app/assets/styles/setup/03.theming/_default.css +87 -0
- package/app/assets/styles/setup/03.theming/_error.css +14 -0
- package/app/assets/styles/setup/03.theming/_success.css +4 -0
- package/app/assets/styles/setup/03.theming/_theme-slots.css +16 -0
- package/app/assets/styles/setup/03.theming/_warning.css +13 -0
- package/app/assets/styles/setup/03.theming/index.css +6 -4
- package/app/assets/styles/setup/03.theming/theme-ramp.css +19 -0
- package/app/assets/styles/setup/04.elements/forms/00.element-defaults.css +0 -7
- package/app/assets/styles/setup/04.elements/forms/06.button-geometry.css +1 -1
- package/app/assets/styles/setup/index.css +1 -1
- package/app/components/01.atoms/display-dialog/DisplayDialog.vue +74 -24
- package/app/components/01.atoms/display-dialog/tests/DisplayDialog.spec.ts +148 -14
- package/app/components/01.atoms/display-dialog/tests/__snapshots__/DisplayDialog.spec.ts.snap +3 -3
- package/app/components/01.atoms/page-row/PageRow.vue +5 -0
- package/app/components/01.atoms/prompt/DisplayPrompt.vue +113 -0
- package/app/components/01.atoms/prompt/stories/DisplayPrompt.stories.ts +112 -0
- package/app/components/01.atoms/prompt/tests/DisplayPrompt.spec.ts +205 -0
- package/app/components/01.atoms/toast/DisplayToast.vue +327 -0
- package/app/components/01.atoms/toast/DisplayToastProvider.vue +362 -0
- package/app/components/01.atoms/toast/stories/DisplayToast.stories.ts +195 -0
- package/app/components/01.atoms/toast/stories/DisplayToastProvider.stories.ts +142 -0
- package/app/components/01.atoms/toast/tests/DisplayToast.spec.ts +266 -0
- package/app/components/01.atoms/toast/tests/DisplayToastProvider.spec.ts +256 -0
- package/app/components/02.molecules/action-menu/ActionMenu.vue +8 -1
- package/app/components/02.molecules/action-menu/ActionMenuItemCore.vue +11 -3
- package/app/components/02.molecules/alert-content/AlertContent.vue +67 -0
- package/app/components/02.molecules/alert-content/AlertContentInner.vue +153 -0
- package/app/components/02.molecules/alert-content/stories/AlertContent.stories.ts +131 -0
- package/app/components/02.molecules/alert-content/tests/AlertContent.spec.ts +135 -0
- package/app/components/02.molecules/alert-content/tests/AlertContentInner.spec.ts +135 -0
- package/app/components/02.molecules/alert-masked-content/AlertMaskedContent.vue +78 -0
- package/app/components/02.molecules/alert-masked-content/stories/AlertMaskedContent.stories.ts +132 -0
- package/app/components/02.molecules/alert-masked-content/tests/AlertMaskedContent.spec.ts +149 -0
- package/app/components/05.forms/input-button/InputButtonCore.vue +35 -39
- package/app/components/05.forms/input-checkbox-radio/InputCheckboxRadioButton.vue +8 -8
- package/app/components/05.forms/input-checkbox-radio/InputCheckboxRadioCore.vue +5 -5
- package/app/components/05.forms/input-copy/InputCopyCore.vue +7 -7
- package/app/components/05.forms/input-number/InputNumberCore.vue +5 -5
- package/app/components/05.forms/input-select/InputSelectCore.vue +6 -6
- package/app/components/05.forms/input-text/InputTextCore.vue +6 -6
- package/app/components/05.forms/input-text/variants/InputTextAsNumberWithLabel.vue +2 -2
- package/app/components/05.forms/input-textarea/InputTextareaCore.vue +5 -5
- package/app/components/05.forms/pending-effect/PendingEffect.vue +60 -60
- package/app/components/05.forms/toggle-switch/ToggleSwitchCore.vue +10 -10
- package/app/components/05.forms/triple-toggle-switch/TripleToggleSwitchCore.vue +4 -4
- package/app/components/display-theme-switch/DisplayThemeSwitch.vue +4 -4
- package/app/components/display-tooltip/DisplayTooltip.vue +4 -4
- package/app/composables/useBodyLock.ts +21 -0
- package/app/composables/useDialogControls.ts +11 -11
- package/app/composables/useToastQueue.ts +39 -0
- package/app/layouts/default.vue +1 -1
- package/app/pages/ui/display-dialog.vue +275 -127
- package/app/pages/ui/display-prompt.vue +255 -52
- package/app/pages/ui/display-toast.vue +278 -299
- package/app/pages/ui/mask-element.vue +25 -3
- package/app/pages/ui/settings.vue +9 -35
- package/app/types/app-config.d.ts +41 -0
- package/app/types/components/display-prompt.d.ts +11 -0
- package/app/types/components/display-toast.d.ts +11 -9
- package/app/types/components/index.ts +2 -0
- package/app/types/components/semantic-theme.d.ts +1 -0
- package/nuxt.config.ts +16 -0
- package/package.json +6 -4
- package/app/assets/styles/setup/03.theming/default/_dark.css +0 -156
- package/app/assets/styles/setup/03.theming/default/_light.css +0 -166
- package/app/assets/styles/setup/03.theming/default/index.css +0 -2
- package/app/assets/styles/setup/03.theming/error/_dark.css +0 -56
- package/app/assets/styles/setup/03.theming/error/_light.css +0 -74
- package/app/assets/styles/setup/03.theming/error/index.css +0 -2
- package/app/assets/styles/setup/03.theming/success/_dark.css +0 -50
- package/app/assets/styles/setup/03.theming/success/_light.css +0 -65
- package/app/assets/styles/setup/03.theming/success/index.css +0 -2
- package/app/assets/styles/setup/03.theming/warning/_dark.css +0 -50
- package/app/assets/styles/setup/03.theming/warning/_light.css +0 -64
- package/app/assets/styles/setup/03.theming/warning/index.css +0 -2
- package/app/components/display-prompt/DisplayPromptCore.vue +0 -228
- package/app/components/display-prompt/variants/DisplayPromptError.vue +0 -53
- package/app/components/display-toast/DisplayToast.vue +0 -447
- package/app/components/display-toast/molecules/DefaultToastContent.vue +0 -163
- package/app/components/display-toast/stories/DisplayToast.stories.ts +0 -380
|
@@ -2,157 +2,158 @@
|
|
|
2
2
|
<div>
|
|
3
3
|
<NuxtLayout name="default">
|
|
4
4
|
<template #layout-content>
|
|
5
|
-
<PageRow tag="div" variant="
|
|
6
|
-
<h1 class="page-heading-2">Dialog
|
|
7
|
-
<p><button type="button" @click.prevent="openDialog('sample1')">Show Dialog</button></p>
|
|
5
|
+
<PageRow tag="div" variant="content" :style-class-passthrough="['mbe-20']">
|
|
6
|
+
<h1 class="page-heading-2">Display Dialog</h1>
|
|
8
7
|
|
|
9
|
-
<
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
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 — DisplayDialog</span>
|
|
12
|
+
<code class="qa-panel__status">
|
|
13
|
+
{{ qaVariant }} · {{ qaTheme ?? "no theme" }}
|
|
14
|
+
</code>
|
|
15
|
+
</summary>
|
|
16
|
+
<div class="qa-panel__body">
|
|
17
|
+
<div class="qa-panel__group">
|
|
18
|
+
<span class="qa-panel__label">Variant</span>
|
|
19
|
+
<div class="qa-panel__chips">
|
|
20
|
+
<button
|
|
21
|
+
v-for="opt in variants"
|
|
22
|
+
:key="opt"
|
|
23
|
+
class="qa-panel__chip"
|
|
24
|
+
:class="{ 'is-active': qaVariant === opt }"
|
|
25
|
+
@click="qaVariant = opt"
|
|
26
|
+
>
|
|
27
|
+
{{ opt }}
|
|
28
|
+
</button>
|
|
29
|
+
</div>
|
|
30
|
+
</div>
|
|
20
31
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
lacus dapibus; nunc enim vestibulum finibus. Lorem commodo tortor blandit nisl curabitur interdum
|
|
36
|
-
ultricies magnis. Dui vehicula ex; congue sagittis commodo tincidunt. Varius sociosqu finibus facilisi
|
|
37
|
-
per, vel quisque. Ornare fames cubilia diam maximus habitant nulla nisl. Sollicitudin cubilia inceptos
|
|
38
|
-
taciti hac tristique mauris hendrerit vestibulum.
|
|
39
|
-
</p>
|
|
40
|
-
<p class="text-normal">
|
|
41
|
-
Lobortis efficitur enim litora dictum montes. Sagittis eget etiam curae suspendisse cubilia. Ante
|
|
42
|
-
aliquam orci mus ultricies nostra. Ad augue quam egestas ipsum sem lacus tempus. Magnis enim posuere
|
|
43
|
-
eros montes fermentum velit. Montes lacinia nisl facilisi volutpat vehicula porttitor auctor
|
|
44
|
-
condimentum venenatis. Semper varius nascetur imperdiet laoreet vivamus montes praesent purus nostra.
|
|
45
|
-
Magna nascetur augue curae proin nascetur sagittis urna adipiscing.
|
|
46
|
-
</p>
|
|
47
|
-
<p class="text-normal">
|
|
48
|
-
Venenatis adipiscing integer eget donec ridiculus risus. Nulla quis sollicitudin sem nam bibendum
|
|
49
|
-
ligula. Curabitur malesuada platea egestas venenatis in torquent. Eget eros euismod vehicula consequat
|
|
50
|
-
at, efficitur ullamcorper. Donec nibh molestie semper nulla vehicula. Vulputate porta euismod cras;
|
|
51
|
-
inceptos vel erat. Vehicula urna mattis suscipit iaculis nostra eget. Eleifend vivamus nullam porta
|
|
52
|
-
urna nulla dictum praesent aenean. Etiam ipsum placerat bibendum nullam rhoncus egestas. Mollis
|
|
53
|
-
pretium nullam nullam donec eget imperdiet.
|
|
54
|
-
</p>
|
|
55
|
-
<p class="text-normal">
|
|
56
|
-
Curae maximus nam tortor porta sodales at, feugiat iaculis integer. Lacus habitasse odio fames natoque
|
|
57
|
-
neque varius nostra. Imperdiet tellus libero ornare lobortis maximus rutrum parturient litora viverra.
|
|
58
|
-
Praesent proin sem nulla mauris justo mi morbi. Neque diam sodales nam nascetur commodo risus. Ornare
|
|
59
|
-
at sit, mattis erat aenean ipsum. Dictum integer ipsum suspendisse sagittis nisl sollicitudin.
|
|
60
|
-
</p>
|
|
32
|
+
<div class="qa-panel__group">
|
|
33
|
+
<span class="qa-panel__label">Theme</span>
|
|
34
|
+
<div class="qa-panel__chips">
|
|
35
|
+
<button
|
|
36
|
+
v-for="opt in themes"
|
|
37
|
+
:key="String(opt)"
|
|
38
|
+
class="qa-panel__chip"
|
|
39
|
+
:class="{ 'is-active': qaTheme === opt }"
|
|
40
|
+
@click="qaTheme = opt"
|
|
41
|
+
>
|
|
42
|
+
{{ opt ?? "none" }}
|
|
43
|
+
</button>
|
|
44
|
+
</div>
|
|
45
|
+
</div>
|
|
61
46
|
</div>
|
|
62
|
-
</
|
|
63
|
-
|
|
64
|
-
<button type="submit" @click.prevent="closeDialog('sample1', 'cancel')">Cancel</button>
|
|
65
|
-
</template>
|
|
66
|
-
<template #actionButtonRight>
|
|
67
|
-
<button type="submit" @click.prevent="closeDialog('sample1', 'confirm')">Confirm</button>
|
|
68
|
-
</template>
|
|
69
|
-
</DisplayDialog>
|
|
70
|
-
</PageRow>
|
|
47
|
+
</details>
|
|
48
|
+
</div>
|
|
71
49
|
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
50
|
+
<p>
|
|
51
|
+
<button type="button" @click.prevent="openDialog('demo')">Open Dialog</button>
|
|
52
|
+
</p>
|
|
75
53
|
|
|
76
54
|
<DisplayDialog
|
|
77
|
-
v-if="dialogsConfig['
|
|
78
|
-
v-model="dialogsConfig['
|
|
79
|
-
variant="
|
|
80
|
-
:
|
|
81
|
-
|
|
55
|
+
v-if="dialogsConfig['demo']"
|
|
56
|
+
v-model="dialogsConfig['demo']"
|
|
57
|
+
:variant="qaVariant"
|
|
58
|
+
:theme="qaTheme"
|
|
59
|
+
:allow-content-scroll="qaVariant === 'dialog'"
|
|
60
|
+
data-dialog-id="demo"
|
|
82
61
|
>
|
|
83
62
|
<template #dialogTitle>
|
|
84
|
-
<p class="text-normal wght-700 m-0">
|
|
63
|
+
<p class="text-normal wght-700 m-0">{{ dialogTitle }}</p>
|
|
85
64
|
</template>
|
|
86
65
|
|
|
87
66
|
<template #dialogContent>
|
|
88
|
-
<div class="
|
|
89
|
-
<p class="text-normal">
|
|
67
|
+
<div class="pt-12 pb-12">
|
|
68
|
+
<p class="text-normal">{{ dialogBody }}</p>
|
|
69
|
+
<template v-if="qaVariant === 'dialog'">
|
|
70
|
+
<p class="text-normal">
|
|
71
|
+
Justo molestie felis tellus tellus taciti? Ullamcorper viverra quis felis donec aliquam torquent
|
|
72
|
+
imperdiet. Curabitur vitae quis malesuada imperdiet hendrerit felis quam dictum. Aptent curabitur
|
|
73
|
+
lacus dapibus; nunc enim vestibulum finibus. Lorem commodo tortor blandit nisl curabitur interdum
|
|
74
|
+
ultricies magnis.
|
|
75
|
+
</p>
|
|
76
|
+
<p class="text-normal">
|
|
77
|
+
Lobortis efficitur enim litora dictum montes. Sagittis eget etiam curae suspendisse cubilia. Ante
|
|
78
|
+
aliquam orci mus ultricies nostra. Ad augue quam egestas ipsum sem lacus tempus. Magnis enim posuere
|
|
79
|
+
eros montes fermentum velit.
|
|
80
|
+
</p>
|
|
81
|
+
<p class="text-normal">
|
|
82
|
+
Venenatis adipiscing integer eget donec ridiculus risus. Nulla quis sollicitudin sem nam bibendum
|
|
83
|
+
ligula. Curabitur malesuada platea egestas venenatis in torquent. Eget eros euismod vehicula consequat
|
|
84
|
+
at, efficitur ullamcorper.
|
|
85
|
+
</p>
|
|
86
|
+
</template>
|
|
90
87
|
</div>
|
|
91
88
|
</template>
|
|
89
|
+
|
|
92
90
|
<template #actionButtonLeft>
|
|
93
|
-
<button type="
|
|
91
|
+
<button type="button" @click.prevent="closeDialog('demo', 'cancel')">Cancel</button>
|
|
94
92
|
</template>
|
|
95
93
|
<template #actionButtonRight>
|
|
96
|
-
<button type="
|
|
94
|
+
<button type="button" @click.prevent="closeDialog('demo', 'confirm')">{{ confirmLabel }}</button>
|
|
97
95
|
</template>
|
|
98
96
|
</DisplayDialog>
|
|
99
97
|
</PageRow>
|
|
100
98
|
|
|
101
|
-
<PageRow tag="div" variant="
|
|
102
|
-
<h2 class="page-heading-2">
|
|
103
|
-
<p class="text-normal">
|
|
104
|
-
|
|
99
|
+
<PageRow tag="div" variant="content" :style-class-passthrough="['mbe-20']">
|
|
100
|
+
<h2 class="page-heading-2">Nested dialog pattern</h2>
|
|
101
|
+
<p class="text-normal">
|
|
102
|
+
A dialog managing its own internal confirm sub-dialog via a local
|
|
103
|
+
<code>useDialogControls</code> instance. Tick "Simulate unsaved changes" before
|
|
104
|
+
clicking Cancel to trigger the nested confirm.
|
|
105
|
+
</p>
|
|
106
|
+
<p>
|
|
107
|
+
<button type="button" @click.prevent="openNestedDialog('editProfile')">Open nested dialog demo</button>
|
|
108
|
+
</p>
|
|
105
109
|
|
|
106
110
|
<DisplayDialog
|
|
107
|
-
v-if="
|
|
108
|
-
v-model="
|
|
109
|
-
variant="
|
|
110
|
-
|
|
111
|
-
data-dialog-id="deleteAccount"
|
|
111
|
+
v-if="nestedDialogsConfig['editProfile']"
|
|
112
|
+
v-model="nestedDialogsConfig['editProfile']"
|
|
113
|
+
variant="dialog"
|
|
114
|
+
data-dialog-id="nested-edit"
|
|
112
115
|
>
|
|
113
116
|
<template #dialogTitle>
|
|
114
|
-
<p class="text-normal wght-700 m-0">
|
|
117
|
+
<p class="text-normal wght-700 m-0">Edit profile</p>
|
|
115
118
|
</template>
|
|
116
|
-
|
|
117
119
|
<template #dialogContent>
|
|
118
|
-
<div class="
|
|
119
|
-
<p class="text-normal">
|
|
120
|
+
<div class="pt-12 pb-12 nested-demo-content">
|
|
121
|
+
<p class="text-normal">Make some changes below, then click Cancel to trigger the nested confirm dialog.</p>
|
|
122
|
+
<label class="nested-demo-label">
|
|
123
|
+
<input v-model="nestedHasChanges" type="checkbox" />
|
|
124
|
+
Simulate unsaved changes
|
|
125
|
+
</label>
|
|
120
126
|
</div>
|
|
121
127
|
</template>
|
|
122
128
|
<template #actionButtonLeft>
|
|
123
|
-
<button type="button" @click
|
|
129
|
+
<button type="button" @click="handleNestedCancel">Cancel</button>
|
|
124
130
|
</template>
|
|
125
131
|
<template #actionButtonRight>
|
|
126
|
-
<button type="button" @click
|
|
132
|
+
<button type="button" @click="closeNestedDialog('editProfile', 'confirm')">Save</button>
|
|
127
133
|
</template>
|
|
128
134
|
</DisplayDialog>
|
|
129
|
-
</PageRow>
|
|
130
|
-
|
|
131
|
-
<PageRow tag="div" variant="popout" :style-class-passthrough="['mbe-20']">
|
|
132
|
-
<h2 class="page-heading-2">Fullscreen Dialog</h2>
|
|
133
|
-
<p><button type="button" @click.prevent="openDialog('fullscreen')">Show Fullscreen Dialog</button></p>
|
|
134
135
|
|
|
135
136
|
<DisplayDialog
|
|
136
|
-
v-if="
|
|
137
|
-
v-model="
|
|
138
|
-
variant="
|
|
139
|
-
|
|
140
|
-
|
|
137
|
+
v-if="nestedDialogsConfig['confirmDiscard']"
|
|
138
|
+
v-model="nestedDialogsConfig['confirmDiscard']"
|
|
139
|
+
variant="confirm"
|
|
140
|
+
theme="warning"
|
|
141
|
+
:lock-viewport="false"
|
|
142
|
+
data-dialog-id="nested-confirm"
|
|
141
143
|
>
|
|
142
144
|
<template #dialogTitle>
|
|
143
|
-
<p class="text-normal wght-700 m-0">
|
|
145
|
+
<p class="text-normal wght-700 m-0">Discard changes?</p>
|
|
144
146
|
</template>
|
|
145
|
-
|
|
146
147
|
<template #dialogContent>
|
|
147
|
-
<div class="
|
|
148
|
-
<p class="text-normal">
|
|
148
|
+
<div class="m-0">
|
|
149
|
+
<p class="text-normal">Your unsaved changes will be lost.</p>
|
|
149
150
|
</div>
|
|
150
151
|
</template>
|
|
151
152
|
<template #actionButtonLeft>
|
|
152
|
-
<button type="button" @click
|
|
153
|
+
<button type="button" @click="closeNestedDialog('confirmDiscard', 'cancel')">Keep editing</button>
|
|
153
154
|
</template>
|
|
154
155
|
<template #actionButtonRight>
|
|
155
|
-
<button type="button" @click
|
|
156
|
+
<button type="button" @click="closeNestedDialog('confirmDiscard', 'confirm')">Discard</button>
|
|
156
157
|
</template>
|
|
157
158
|
</DisplayDialog>
|
|
158
159
|
</PageRow>
|
|
@@ -162,35 +163,182 @@
|
|
|
162
163
|
</template>
|
|
163
164
|
|
|
164
165
|
<script setup lang="ts">
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
});
|
|
166
|
+
import type { SemanticTheme } from "~/types/components";
|
|
167
|
+
|
|
168
|
+
definePageMeta({ layout: false });
|
|
168
169
|
|
|
169
170
|
useHead({
|
|
170
171
|
title: "UI Dialogs",
|
|
171
172
|
meta: [{ name: "description", content: "Examples of Dialogs" }],
|
|
172
|
-
bodyAttrs: {
|
|
173
|
-
|
|
174
|
-
|
|
173
|
+
bodyAttrs: { class: "displayDialog-page" },
|
|
174
|
+
});
|
|
175
|
+
|
|
176
|
+
const isDev = import.meta.dev;
|
|
177
|
+
|
|
178
|
+
const variants = ["dialog", "modal", "confirm", "alert", "fullscreen"] as const;
|
|
179
|
+
type DialogVariant = (typeof variants)[number];
|
|
180
|
+
|
|
181
|
+
const themes = [undefined, "info", "success", "warning", "error"] as const;
|
|
182
|
+
|
|
183
|
+
const qaVariant = ref<DialogVariant>("confirm");
|
|
184
|
+
const qaTheme = ref<SemanticTheme | undefined>(undefined);
|
|
185
|
+
|
|
186
|
+
const dialogTitle = computed(() => {
|
|
187
|
+
if (qaTheme.value === "error") return "Delete account?";
|
|
188
|
+
if (qaTheme.value === "warning") return "Confirm action";
|
|
189
|
+
if (qaVariant.value === "dialog") return "Dialog with scrollable content";
|
|
190
|
+
if (qaVariant.value === "confirm") return "Confirm logout?";
|
|
191
|
+
if (qaVariant.value === "alert") return "Alert — action required";
|
|
192
|
+
if (qaVariant.value === "fullscreen") return "Fullscreen dialog";
|
|
193
|
+
return "Dialog";
|
|
194
|
+
});
|
|
195
|
+
|
|
196
|
+
const dialogBody = computed(() => {
|
|
197
|
+
if (qaTheme.value === "error")
|
|
198
|
+
return "This action is permanent and cannot be undone. All your data will be removed.";
|
|
199
|
+
if (qaVariant.value === "alert")
|
|
200
|
+
return "Cannot be dismissed by clicking outside or pressing Escape — an explicit action is required.";
|
|
201
|
+
if (qaVariant.value === "fullscreen")
|
|
202
|
+
return "This dialog fills the entire viewport. Useful for immersive flows such as onboarding, image editors, or multi-step wizards.";
|
|
203
|
+
if (qaVariant.value === "dialog")
|
|
204
|
+
return "Lorem ipsum odor amet, consectetuer adipiscing elit. Scelerisque tincidunt vestibulum litora torquent aliquam a. Sem litora tellus mattis nisi vehicula sodales arcu egestas.";
|
|
205
|
+
return "Are you sure you want to continue? This will apply the selected action.";
|
|
206
|
+
});
|
|
207
|
+
|
|
208
|
+
const confirmLabel = computed(() => {
|
|
209
|
+
if (qaTheme.value === "error") return "Delete account";
|
|
210
|
+
if (qaVariant.value === "confirm") return "Log out";
|
|
211
|
+
return "Confirm";
|
|
175
212
|
});
|
|
176
213
|
|
|
177
214
|
const { dialogsConfig, openDialog, closeDialog } = useDialogControls({
|
|
178
|
-
|
|
179
|
-
onConfirm: () =>
|
|
180
|
-
onCancel: () =>
|
|
181
|
-
},
|
|
182
|
-
logout: {
|
|
183
|
-
onConfirm: () => console.log("User logged out"),
|
|
184
|
-
onCancel: () => console.log("Logout cancelled"),
|
|
185
|
-
},
|
|
186
|
-
deleteAccount: {
|
|
187
|
-
onConfirm: () => console.log("Account deleted"),
|
|
188
|
-
onCancel: () => console.log("Delete account cancelled"),
|
|
215
|
+
demo: {
|
|
216
|
+
onConfirm: () => {},
|
|
217
|
+
onCancel: () => {},
|
|
189
218
|
},
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
219
|
+
});
|
|
220
|
+
|
|
221
|
+
const nestedHasChanges = ref(false);
|
|
222
|
+
|
|
223
|
+
const { dialogsConfig: nestedDialogsConfig, openDialog: openNestedDialog, closeDialog: closeNestedDialog } = useDialogControls({
|
|
224
|
+
editProfile: { onConfirm: () => {}, onCancel: () => {} },
|
|
225
|
+
confirmDiscard: {
|
|
226
|
+
onConfirm: () => { nestedDialogsConfig.editProfile = false; },
|
|
227
|
+
onCancel: () => {},
|
|
193
228
|
},
|
|
194
229
|
});
|
|
230
|
+
|
|
231
|
+
const handleNestedCancel = () => {
|
|
232
|
+
if (nestedHasChanges.value) {
|
|
233
|
+
openNestedDialog("confirmDiscard");
|
|
234
|
+
} else {
|
|
235
|
+
closeNestedDialog("editProfile", "cancel");
|
|
236
|
+
}
|
|
237
|
+
};
|
|
195
238
|
</script>
|
|
196
239
|
|
|
240
|
+
<style lang="css">
|
|
241
|
+
.displayDialog-page {
|
|
242
|
+
.qa-panel {
|
|
243
|
+
background: oklch(15% 0 0);
|
|
244
|
+
color: white;
|
|
245
|
+
font-size: 1.3rem;
|
|
246
|
+
margin-block: 1.2rem;
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
.qa-panel__details {
|
|
250
|
+
padding: 1rem 2rem;
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
.qa-panel__summary {
|
|
254
|
+
cursor: pointer;
|
|
255
|
+
display: flex;
|
|
256
|
+
align-items: center;
|
|
257
|
+
gap: 1.6rem;
|
|
258
|
+
list-style: none;
|
|
259
|
+
user-select: none;
|
|
260
|
+
|
|
261
|
+
&::-webkit-details-marker {
|
|
262
|
+
display: none;
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
.qa-panel__title {
|
|
267
|
+
font-weight: 600;
|
|
268
|
+
font-size: 1.1rem;
|
|
269
|
+
text-transform: uppercase;
|
|
270
|
+
letter-spacing: 0.08em;
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
.qa-panel__status {
|
|
274
|
+
font-family: monospace;
|
|
275
|
+
font-size: 1.2rem;
|
|
276
|
+
background: oklch(0% 0 0 / 0.3);
|
|
277
|
+
padding: 0.2rem 0.8rem;
|
|
278
|
+
border-radius: 0.4rem;
|
|
279
|
+
user-select: text;
|
|
280
|
+
cursor: text;
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
.qa-panel__body {
|
|
284
|
+
display: flex;
|
|
285
|
+
flex-wrap: wrap;
|
|
286
|
+
gap: 2.4rem;
|
|
287
|
+
padding-block: 1.2rem 0.4rem;
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
.qa-panel__group {
|
|
291
|
+
display: flex;
|
|
292
|
+
flex-direction: column;
|
|
293
|
+
gap: 0.6rem;
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
.qa-panel__label {
|
|
297
|
+
font-size: 1.1rem;
|
|
298
|
+
text-transform: uppercase;
|
|
299
|
+
letter-spacing: 0.08em;
|
|
300
|
+
opacity: 0.55;
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
.qa-panel__chips {
|
|
304
|
+
display: flex;
|
|
305
|
+
flex-wrap: wrap;
|
|
306
|
+
gap: 0.4rem;
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
.nested-demo-content {
|
|
310
|
+
display: flex;
|
|
311
|
+
flex-direction: column;
|
|
312
|
+
gap: 1.6rem;
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
.nested-demo-label {
|
|
316
|
+
display: flex;
|
|
317
|
+
align-items: center;
|
|
318
|
+
gap: 0.8rem;
|
|
319
|
+
cursor: pointer;
|
|
320
|
+
font-size: 1.4rem;
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
.qa-panel__chip {
|
|
324
|
+
font-family: monospace;
|
|
325
|
+
font-size: 1.2rem;
|
|
326
|
+
color: white;
|
|
327
|
+
background: oklch(0% 0 0 / 0.25);
|
|
328
|
+
border: 1px solid oklch(100% 0 0 / 0.18);
|
|
329
|
+
padding: 0.3rem 1rem;
|
|
330
|
+
border-radius: 0.4rem;
|
|
331
|
+
cursor: pointer;
|
|
332
|
+
transition: background 0.15s;
|
|
333
|
+
|
|
334
|
+
&:hover {
|
|
335
|
+
background: oklch(0% 0 0 / 0.4);
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
&.is-active {
|
|
339
|
+
background: oklch(55% 0.18 240);
|
|
340
|
+
border-color: oklch(55% 0.18 240);
|
|
341
|
+
}
|
|
342
|
+
}
|
|
343
|
+
}
|
|
344
|
+
</style>
|