@motion-proto/live-tokens 0.1.0
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/README.md +41 -0
- package/dist-plugin/index.cjs +444 -0
- package/dist-plugin/index.d.cts +12 -0
- package/dist-plugin/index.d.ts +12 -0
- package/dist-plugin/index.js +407 -0
- package/package.json +86 -0
- package/src/components/Badge.svelte +82 -0
- package/src/components/Button.svelte +333 -0
- package/src/components/Card.svelte +83 -0
- package/src/components/CollapsibleSection.svelte +82 -0
- package/src/components/DetailNav.svelte +78 -0
- package/src/components/Dialog.svelte +269 -0
- package/src/components/InlineEditActions.svelte +73 -0
- package/src/components/Notification.svelte +308 -0
- package/src/components/ProgressBar.svelte +99 -0
- package/src/components/RadioButton.svelte +87 -0
- package/src/components/SectionDivider.svelte +121 -0
- package/src/components/TabBar.svelte +92 -0
- package/src/components/Toggle.svelte +86 -0
- package/src/components/Tooltip.svelte +64 -0
- package/src/lib/ColumnsOverlay.svelte +120 -0
- package/src/lib/LiveEditorOverlay.svelte +467 -0
- package/src/lib/columnsOverlay.ts +26 -0
- package/src/lib/cssVarSync.ts +72 -0
- package/src/lib/editorConfig.ts +9 -0
- package/src/lib/editorConfigStore.ts +14 -0
- package/src/lib/index.ts +51 -0
- package/src/lib/oklch.ts +129 -0
- package/src/lib/pageSource.ts +6 -0
- package/src/lib/tokenInit.ts +29 -0
- package/src/lib/tokenService.ts +144 -0
- package/src/lib/tokenTypes.ts +45 -0
- package/src/pages/Admin.svelte +100 -0
- package/src/pages/ShowcasePage.svelte +146 -0
- package/src/showcase/BackupBrowser.svelte +617 -0
- package/src/showcase/BezierCurveEditor.svelte +648 -0
- package/src/showcase/ColorEditPanel.svelte +498 -0
- package/src/showcase/ComponentsTab.svelte +107 -0
- package/src/showcase/EditorDialog.svelte +137 -0
- package/src/showcase/PaletteEditor.svelte +2579 -0
- package/src/showcase/PaletteSelector.svelte +627 -0
- package/src/showcase/SurfacesTab.svelte +409 -0
- package/src/showcase/TextTab.svelte +205 -0
- package/src/showcase/TokenFileManager.svelte +683 -0
- package/src/showcase/TokenMap.svelte +54 -0
- package/src/showcase/VariablesTab.svelte +2657 -0
- package/src/showcase/VisualsTab.svelte +233 -0
- package/src/showcase/curveEngine.ts +190 -0
- package/src/showcase/demos/BadgeDemo.svelte +58 -0
- package/src/showcase/demos/CardDemo.svelte +52 -0
- package/src/showcase/demos/ChoiceButtonsDemo.svelte +194 -0
- package/src/showcase/demos/CollapsibleSectionDemo.svelte +56 -0
- package/src/showcase/demos/DialogDemo.svelte +42 -0
- package/src/showcase/demos/InlineEditActionsDemo.svelte +27 -0
- package/src/showcase/demos/NotificationDemo.svelte +149 -0
- package/src/showcase/demos/ProgressBarDemo.svelte +56 -0
- package/src/showcase/demos/RadioButtonDemo.svelte +58 -0
- package/src/showcase/demos/SectionDividerDemo.svelte +79 -0
- package/src/showcase/demos/StandardButtonsDemo.svelte +457 -0
- package/src/showcase/demos/TabBarDemo.svelte +60 -0
- package/src/showcase/demos/TooltipDemo.svelte +54 -0
- package/src/showcase/editor.css +93 -0
- package/src/showcase/index.ts +17 -0
- package/src/styles/fonts/Domine/Domine-VariableFont_wght.ttf +0 -0
- package/src/styles/fonts/Domine/OFL.txt +97 -0
- package/src/styles/fonts/Domine/README.txt +66 -0
- package/src/styles/fonts.css +18 -0
- package/src/styles/form-controls.css +190 -0
|
@@ -0,0 +1,269 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import { createEventDispatcher, tick } from 'svelte';
|
|
3
|
+
|
|
4
|
+
export let show: boolean = false;
|
|
5
|
+
export let title: string = '';
|
|
6
|
+
export let confirmLabel: string = 'Confirm';
|
|
7
|
+
export let cancelLabel: string = 'Cancel';
|
|
8
|
+
export let showConfirm: boolean = true;
|
|
9
|
+
export let showCancel: boolean = true;
|
|
10
|
+
export let confirmDisabled: boolean = false;
|
|
11
|
+
export let width: string = '500px';
|
|
12
|
+
|
|
13
|
+
// Optional callbacks for parent dialogs to control behavior
|
|
14
|
+
export let onConfirm: (() => void) | undefined = undefined;
|
|
15
|
+
export let onCancel: (() => void) | undefined = undefined;
|
|
16
|
+
|
|
17
|
+
const dispatch = createEventDispatcher<{
|
|
18
|
+
confirm: void;
|
|
19
|
+
cancel: void;
|
|
20
|
+
close: void;
|
|
21
|
+
}>();
|
|
22
|
+
|
|
23
|
+
// Reference to the primary (confirm) button for focus management
|
|
24
|
+
let confirmButtonRef: HTMLButtonElement;
|
|
25
|
+
let cancelButtonRef: HTMLButtonElement;
|
|
26
|
+
let closeButtonRef: HTMLButtonElement;
|
|
27
|
+
|
|
28
|
+
// Focus the primary button when dialog opens
|
|
29
|
+
$: if (show) {
|
|
30
|
+
tick().then(() => {
|
|
31
|
+
// Focus the primary (confirm) button first, then fall back to cancel, then close
|
|
32
|
+
if (showConfirm && confirmButtonRef && !confirmDisabled) {
|
|
33
|
+
confirmButtonRef.focus();
|
|
34
|
+
} else if (showCancel && cancelButtonRef) {
|
|
35
|
+
cancelButtonRef.focus();
|
|
36
|
+
} else if (closeButtonRef) {
|
|
37
|
+
closeButtonRef.focus();
|
|
38
|
+
}
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
function handleConfirm() {
|
|
43
|
+
if (!confirmDisabled) {
|
|
44
|
+
if (onConfirm) {
|
|
45
|
+
// Parent dialog controls the flow
|
|
46
|
+
onConfirm();
|
|
47
|
+
} else {
|
|
48
|
+
// Default behavior for backward compatibility
|
|
49
|
+
dispatch('confirm');
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
function handleCancel() {
|
|
55
|
+
if (onCancel) {
|
|
56
|
+
// Parent dialog controls the flow
|
|
57
|
+
onCancel();
|
|
58
|
+
} else {
|
|
59
|
+
// Default behavior for backward compatibility
|
|
60
|
+
dispatch('cancel');
|
|
61
|
+
dispatch('close');
|
|
62
|
+
show = false;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
// No implicit keyboard or backdrop close handlers
|
|
67
|
+
// Dialog only closes via explicit button clicks (X, Cancel, or Confirm)
|
|
68
|
+
</script>
|
|
69
|
+
|
|
70
|
+
{#if show}
|
|
71
|
+
<div class="dialog-backdrop">
|
|
72
|
+
<div class="dialog" style="width: {width}; max-width: {width};">
|
|
73
|
+
<div class="dialog-content">
|
|
74
|
+
{#if title}
|
|
75
|
+
<div class="dialog-header">
|
|
76
|
+
<h3 class="dialog-title">{title}</h3>
|
|
77
|
+
<button
|
|
78
|
+
bind:this={closeButtonRef}
|
|
79
|
+
class="dialog-close"
|
|
80
|
+
on:click={handleCancel}
|
|
81
|
+
aria-label="Close"
|
|
82
|
+
tabindex="0"
|
|
83
|
+
>
|
|
84
|
+
<i class="fas fa-times"></i>
|
|
85
|
+
</button>
|
|
86
|
+
</div>
|
|
87
|
+
{/if}
|
|
88
|
+
|
|
89
|
+
<div class="dialog-body">
|
|
90
|
+
<slot />
|
|
91
|
+
</div>
|
|
92
|
+
|
|
93
|
+
{#if showConfirm || showCancel}
|
|
94
|
+
<div class="dialog-footer">
|
|
95
|
+
<div class="dialog-footer-left">
|
|
96
|
+
<slot name="footer-left" />
|
|
97
|
+
</div>
|
|
98
|
+
<div class="dialog-footer-buttons">
|
|
99
|
+
{#if showCancel}
|
|
100
|
+
<button
|
|
101
|
+
bind:this={cancelButtonRef}
|
|
102
|
+
class="dialog-button dialog-button-secondary"
|
|
103
|
+
on:click={handleCancel}
|
|
104
|
+
tabindex="0"
|
|
105
|
+
>
|
|
106
|
+
{cancelLabel}
|
|
107
|
+
</button>
|
|
108
|
+
{/if}
|
|
109
|
+
{#if showConfirm}
|
|
110
|
+
<button
|
|
111
|
+
bind:this={confirmButtonRef}
|
|
112
|
+
class="dialog-button dialog-button-primary"
|
|
113
|
+
on:click={handleConfirm}
|
|
114
|
+
disabled={confirmDisabled}
|
|
115
|
+
tabindex="0"
|
|
116
|
+
>
|
|
117
|
+
{confirmLabel}
|
|
118
|
+
</button>
|
|
119
|
+
{/if}
|
|
120
|
+
</div>
|
|
121
|
+
</div>
|
|
122
|
+
{/if}
|
|
123
|
+
</div>
|
|
124
|
+
</div>
|
|
125
|
+
</div>
|
|
126
|
+
{/if}
|
|
127
|
+
|
|
128
|
+
<style>
|
|
129
|
+
.dialog-backdrop {
|
|
130
|
+
position: fixed;
|
|
131
|
+
top: 0;
|
|
132
|
+
left: 0;
|
|
133
|
+
width: 100%;
|
|
134
|
+
height: 100%;
|
|
135
|
+
background-color: var(--overlay-high);
|
|
136
|
+
display: flex;
|
|
137
|
+
justify-content: center;
|
|
138
|
+
align-items: center;
|
|
139
|
+
z-index: var(--z-overlay);
|
|
140
|
+
pointer-events: auto;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
.dialog {
|
|
144
|
+
background: var(--surface-neutral-lowest);
|
|
145
|
+
border: 2px solid var(--border-neutral-strong);
|
|
146
|
+
border-radius: var(--radius-lg);
|
|
147
|
+
box-shadow: var(--shadow-overlay);
|
|
148
|
+
animation: dialogSlideIn var(--transition-base);
|
|
149
|
+
pointer-events: auto;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
@keyframes dialogSlideIn {
|
|
153
|
+
from {
|
|
154
|
+
opacity: 0;
|
|
155
|
+
transform: translateY(-1.25rem);
|
|
156
|
+
}
|
|
157
|
+
to {
|
|
158
|
+
opacity: 1;
|
|
159
|
+
transform: translateY(0);
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
.dialog-content {
|
|
164
|
+
padding: 0;
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
.dialog-header {
|
|
168
|
+
padding: .5rem var(--space-24);
|
|
169
|
+
border-bottom: 1px solid var(--border-neutral-subtle);
|
|
170
|
+
background: var(--empty);
|
|
171
|
+
display: flex;
|
|
172
|
+
justify-content: space-between;
|
|
173
|
+
align-items: center;
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
.dialog-title {
|
|
177
|
+
margin: 0;
|
|
178
|
+
font-size: var(--font-2xl);
|
|
179
|
+
font-weight: var(--font-weight-semibold);
|
|
180
|
+
color: var(--text-primary);
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
.dialog-close {
|
|
184
|
+
background: none;
|
|
185
|
+
border: none;
|
|
186
|
+
color: var(--text-secondary);
|
|
187
|
+
font-size: var(--font-xl);
|
|
188
|
+
cursor: pointer;
|
|
189
|
+
margin-right: -var(--space-16);
|
|
190
|
+
width: 2rem;
|
|
191
|
+
height: 2rem;
|
|
192
|
+
display: flex;
|
|
193
|
+
align-items: center;
|
|
194
|
+
justify-content: center;
|
|
195
|
+
border-radius: var(--radius-md);
|
|
196
|
+
transition: all var(--transition-base);
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
.dialog-close:hover {
|
|
200
|
+
background: var(--hover);
|
|
201
|
+
color: var(--text-primary);
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
.dialog-body {
|
|
205
|
+
padding: var(--space-16) var(--space-24);
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
.dialog-footer {
|
|
209
|
+
padding: var(--space-16);
|
|
210
|
+
border-top: 1px solid var(--border-neutral-subtle);
|
|
211
|
+
display: flex;
|
|
212
|
+
justify-content: space-between;
|
|
213
|
+
align-items: center;
|
|
214
|
+
gap: var(--space-16);
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
.dialog-footer-left {
|
|
218
|
+
display: flex;
|
|
219
|
+
align-items: center;
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
.dialog-footer-buttons {
|
|
223
|
+
display: flex;
|
|
224
|
+
gap: var(--space-8);
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
.dialog-button {
|
|
228
|
+
padding: var(--space-8) var(--space-16);
|
|
229
|
+
border: 1px solid var(--border-neutral-subtle);
|
|
230
|
+
border-radius: var(--radius-md);
|
|
231
|
+
font-size: var(--font-md);
|
|
232
|
+
font-weight: var(--font-weight-medium);
|
|
233
|
+
cursor: pointer;
|
|
234
|
+
transition: all var(--transition-base);
|
|
235
|
+
min-width: 5rem;
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
.dialog-button:disabled {
|
|
239
|
+
opacity: var(--opacity-disabled);
|
|
240
|
+
cursor: not-allowed;
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
.dialog-button-primary {
|
|
244
|
+
background: var(--btn-secondary-bg);
|
|
245
|
+
color: var(--text-primary);
|
|
246
|
+
border-color: var(--border-neutral-medium);
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
.dialog-button-primary:hover:not(:disabled) {
|
|
250
|
+
background: var(--btn-secondary-hover);
|
|
251
|
+
border-color: var(--border-neutral-strong);
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
.dialog-button-primary:focus {
|
|
255
|
+
outline: 2px solid var(--border-neutral-strong);
|
|
256
|
+
outline-offset: 0.125rem;
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
.dialog-button-secondary {
|
|
260
|
+
background: transparent;
|
|
261
|
+
color: var(--text-primary);
|
|
262
|
+
border-color: var(--border-neutral-medium);
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
.dialog-button-secondary:hover:not(:disabled) {
|
|
266
|
+
background: var(--hover-low);
|
|
267
|
+
border-color: var(--border-neutral-strong);
|
|
268
|
+
}
|
|
269
|
+
</style>
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
/**
|
|
3
|
+
* Reusable inline edit action buttons (confirm/cancel)
|
|
4
|
+
* Used for inline editing throughout the app
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
export let onSave: () => void | Promise<void>;
|
|
8
|
+
export let onCancel: () => void;
|
|
9
|
+
export let disabled = false;
|
|
10
|
+
export let saveTitle = "Save";
|
|
11
|
+
export let cancelTitle = "Cancel";
|
|
12
|
+
</script>
|
|
13
|
+
|
|
14
|
+
<div class="inline-actions">
|
|
15
|
+
<button
|
|
16
|
+
class="save-btn"
|
|
17
|
+
on:click={onSave}
|
|
18
|
+
{disabled}
|
|
19
|
+
title={saveTitle}
|
|
20
|
+
>
|
|
21
|
+
<i class="fas fa-check"></i>
|
|
22
|
+
</button>
|
|
23
|
+
<button
|
|
24
|
+
class="cancel-btn"
|
|
25
|
+
on:click={onCancel}
|
|
26
|
+
disabled={disabled}
|
|
27
|
+
title={cancelTitle}
|
|
28
|
+
>
|
|
29
|
+
<i class="fas fa-times"></i>
|
|
30
|
+
</button>
|
|
31
|
+
</div>
|
|
32
|
+
|
|
33
|
+
<style lang="scss">
|
|
34
|
+
.inline-actions {
|
|
35
|
+
display: flex;
|
|
36
|
+
gap: var(--space-8);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
.save-btn,
|
|
40
|
+
.cancel-btn {
|
|
41
|
+
padding: var(--space-4) var(--space-8);
|
|
42
|
+
border: none;
|
|
43
|
+
border-radius: var(--radius-md);
|
|
44
|
+
cursor: pointer;
|
|
45
|
+
transition: all 0.2s;
|
|
46
|
+
display: flex;
|
|
47
|
+
align-items: center;
|
|
48
|
+
gap: var(--space-8);
|
|
49
|
+
|
|
50
|
+
&:disabled {
|
|
51
|
+
opacity: 0.5;
|
|
52
|
+
cursor: not-allowed;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
.save-btn {
|
|
57
|
+
background: rgba(144, 238, 144, 0.2);
|
|
58
|
+
color: #90ee90;
|
|
59
|
+
|
|
60
|
+
&:hover:not(:disabled) {
|
|
61
|
+
background: rgba(144, 238, 144, 0.3);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
.cancel-btn {
|
|
66
|
+
background: rgba(255, 107, 107, 0.2);
|
|
67
|
+
color: #ff6b6b;
|
|
68
|
+
|
|
69
|
+
&:hover:not(:disabled) {
|
|
70
|
+
background: rgba(255, 107, 107, 0.3);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
</style>
|
|
@@ -0,0 +1,308 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import { createEventDispatcher } from 'svelte';
|
|
3
|
+
import Button from './Button.svelte';
|
|
4
|
+
|
|
5
|
+
export let title: string;
|
|
6
|
+
export let description: string;
|
|
7
|
+
export let impact: string = '';
|
|
8
|
+
export let variant: 'info' | 'warning' | 'danger' | 'success' = 'info';
|
|
9
|
+
export let size: 'normal' | 'compact' = 'normal';
|
|
10
|
+
export let icon: string = '';
|
|
11
|
+
export let dismissible: boolean = false;
|
|
12
|
+
export let emphasis: boolean = false;
|
|
13
|
+
|
|
14
|
+
// Action button props
|
|
15
|
+
export let actionText: string = '';
|
|
16
|
+
export let actionIcon: string = '';
|
|
17
|
+
export let onAction: (() => void) | undefined = undefined;
|
|
18
|
+
export let actionInline: boolean = false;
|
|
19
|
+
export let actionHeader: boolean = false; // NEW: Show action button in header row
|
|
20
|
+
|
|
21
|
+
const dispatch = createEventDispatcher();
|
|
22
|
+
|
|
23
|
+
// Default icons based on variant
|
|
24
|
+
const defaultIcons = {
|
|
25
|
+
info: 'fas fa-info-circle',
|
|
26
|
+
warning: 'fas fa-exclamation-triangle',
|
|
27
|
+
danger: 'fas fa-times-circle',
|
|
28
|
+
success: 'fas fa-check-circle'
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
$: displayIcon = icon || defaultIcons[variant];
|
|
32
|
+
|
|
33
|
+
function handleDismiss() {
|
|
34
|
+
dispatch('dismiss');
|
|
35
|
+
}
|
|
36
|
+
</script>
|
|
37
|
+
|
|
38
|
+
<div class="notification" class:info={variant === 'info'} class:warning={variant === 'warning'} class:danger={variant === 'danger'} class:success={variant === 'success'} class:emphasis={emphasis} class:compact={size === 'compact'}>
|
|
39
|
+
<div class="notification-header" class:has-action={actionHeader && onAction}>
|
|
40
|
+
<i class={displayIcon}></i>
|
|
41
|
+
<span class="notification-title">{title}</span>
|
|
42
|
+
{#if actionHeader && onAction}
|
|
43
|
+
<div class="action-button-backdrop">
|
|
44
|
+
<Button variant="outline" icon={actionIcon} on:click={onAction}>
|
|
45
|
+
{actionText}
|
|
46
|
+
</Button>
|
|
47
|
+
</div>
|
|
48
|
+
{/if}
|
|
49
|
+
{#if dismissible}
|
|
50
|
+
<button class="notification-close" on:click={handleDismiss} type="button" aria-label="Dismiss">
|
|
51
|
+
<i class="fas fa-times"></i>
|
|
52
|
+
</button>
|
|
53
|
+
{/if}
|
|
54
|
+
</div>
|
|
55
|
+
{#if description && !actionInline}
|
|
56
|
+
<div class="notification-description">{description}</div>
|
|
57
|
+
{/if}
|
|
58
|
+
{#if impact}
|
|
59
|
+
<div class="notification-impact">{impact}</div>
|
|
60
|
+
{/if}
|
|
61
|
+
<slot />
|
|
62
|
+
{#if onAction && !actionHeader}
|
|
63
|
+
{#if actionInline}
|
|
64
|
+
<div class="notification-actions-inline">
|
|
65
|
+
{#if description}
|
|
66
|
+
<span class="description-text">{description}</span>
|
|
67
|
+
{/if}
|
|
68
|
+
<Button variant="outline" icon={actionIcon} on:click={onAction}>
|
|
69
|
+
{actionText}
|
|
70
|
+
</Button>
|
|
71
|
+
</div>
|
|
72
|
+
{:else}
|
|
73
|
+
<div class="notification-actions">
|
|
74
|
+
<Button variant="outline" icon={actionIcon} on:click={onAction}>
|
|
75
|
+
{actionText}
|
|
76
|
+
</Button>
|
|
77
|
+
</div>
|
|
78
|
+
{/if}
|
|
79
|
+
{/if}
|
|
80
|
+
</div>
|
|
81
|
+
|
|
82
|
+
<style lang="scss">
|
|
83
|
+
.notification {
|
|
84
|
+
display: flex;
|
|
85
|
+
flex-direction: column;
|
|
86
|
+
align-items: flex-start;
|
|
87
|
+
width: 100%;
|
|
88
|
+
gap: 0;
|
|
89
|
+
border-radius: var(--radius-md);
|
|
90
|
+
font-size: var(--font-md);
|
|
91
|
+
border: 1px solid;
|
|
92
|
+
transition: all var(--transition-fast);
|
|
93
|
+
position: relative;
|
|
94
|
+
text-align: left;
|
|
95
|
+
overflow: hidden;
|
|
96
|
+
|
|
97
|
+
&.emphasis {
|
|
98
|
+
border-left-width: 0.375rem;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
&.compact {
|
|
102
|
+
font-size: var(--font-sm);
|
|
103
|
+
|
|
104
|
+
.notification-header {
|
|
105
|
+
padding: var(--space-6) var(--space-12);
|
|
106
|
+
|
|
107
|
+
i {
|
|
108
|
+
font-size: var(--font-sm);
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
.notification-title {
|
|
112
|
+
font-size: var(--font-md);
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
.notification-description {
|
|
117
|
+
font-size: var(--font-sm);
|
|
118
|
+
padding: var(--space-8) var(--space-12);
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
.notification-impact {
|
|
122
|
+
font-size: var(--font-sm);
|
|
123
|
+
padding: var(--space-8) var(--space-12);
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
.notification-actions-inline {
|
|
127
|
+
padding: var(--space-8) var(--space-12);
|
|
128
|
+
|
|
129
|
+
.description-text {
|
|
130
|
+
font-size: var(--font-sm);
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
.notification-actions {
|
|
135
|
+
padding: var(--space-8) var(--space-12);
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
// Info variant (blue)
|
|
140
|
+
&.info {
|
|
141
|
+
border-color: var(--border-info-darker);
|
|
142
|
+
color: var(--text-primary);
|
|
143
|
+
|
|
144
|
+
.notification-header {
|
|
145
|
+
background: var(--surface-info-low);
|
|
146
|
+
|
|
147
|
+
i {
|
|
148
|
+
color: var(--text-info);
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
// Warning variant (orange)
|
|
154
|
+
&.warning {
|
|
155
|
+
border-color: var(--border-warning);
|
|
156
|
+
color: var(--text-primary);
|
|
157
|
+
|
|
158
|
+
.notification-header {
|
|
159
|
+
background: var(--surface-warning);
|
|
160
|
+
|
|
161
|
+
i {
|
|
162
|
+
color: var(--text-warning);
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
// Danger variant (red)
|
|
168
|
+
&.danger {
|
|
169
|
+
border-color: var(--border-danger);
|
|
170
|
+
color: var(--text-primary);
|
|
171
|
+
|
|
172
|
+
.notification-header {
|
|
173
|
+
background: var(--surface-primary);
|
|
174
|
+
|
|
175
|
+
i {
|
|
176
|
+
color: var(--text-danger);
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
// Success variant (green)
|
|
182
|
+
&.success {
|
|
183
|
+
border-color: var(--border-success);
|
|
184
|
+
color: var(--text-primary);
|
|
185
|
+
|
|
186
|
+
.notification-header {
|
|
187
|
+
background: var(--surface-success);
|
|
188
|
+
|
|
189
|
+
i {
|
|
190
|
+
color: var(--text-success);
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
.notification-header {
|
|
197
|
+
display: flex;
|
|
198
|
+
align-items: center;
|
|
199
|
+
justify-content: flex-start;
|
|
200
|
+
gap: var(--space-8);
|
|
201
|
+
width: 100%;
|
|
202
|
+
padding: .5rem var(--space-16);
|
|
203
|
+
position: relative;
|
|
204
|
+
|
|
205
|
+
// When action button is in header, add spacing
|
|
206
|
+
&.has-action {
|
|
207
|
+
gap: var(--space-12);
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
i {
|
|
211
|
+
font-size: var(--font-md);
|
|
212
|
+
flex-shrink: 0;
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
.notification-title {
|
|
216
|
+
font-weight: var(--font-weight-semibold);
|
|
217
|
+
font-size: var(--font-lg);
|
|
218
|
+
text-align: left;
|
|
219
|
+
flex: 1;
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
.action-button-backdrop {
|
|
223
|
+
flex-shrink: 0;
|
|
224
|
+
background: var(--surface-neutral-lowest);
|
|
225
|
+
border-radius: var(--radius-md);
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
.notification-close {
|
|
229
|
+
position: absolute;
|
|
230
|
+
top: 50%;
|
|
231
|
+
right: 0.5rem;
|
|
232
|
+
transform: translateY(-50%);
|
|
233
|
+
background: none;
|
|
234
|
+
border: none;
|
|
235
|
+
cursor: pointer;
|
|
236
|
+
padding: var(--space-4);
|
|
237
|
+
display: flex;
|
|
238
|
+
align-items: center;
|
|
239
|
+
justify-content: center;
|
|
240
|
+
opacity: 0.7;
|
|
241
|
+
transition: opacity var(--transition-fast);
|
|
242
|
+
|
|
243
|
+
i {
|
|
244
|
+
font-size: var(--font-sm);
|
|
245
|
+
color: inherit;
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
&:hover {
|
|
249
|
+
opacity: 1;
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
&:focus {
|
|
253
|
+
outline: 2px solid currentColor;
|
|
254
|
+
outline-offset: 0.125rem;
|
|
255
|
+
border-radius: var(--radius-sm);
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
.notification-description {
|
|
261
|
+
line-height: 1.4;
|
|
262
|
+
font-size: var(--font-md);
|
|
263
|
+
font-weight: var(--font-weight-light);
|
|
264
|
+
text-align: left;
|
|
265
|
+
padding: .75rem var(--space-16);
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
.notification-impact {
|
|
269
|
+
font-weight: var(--font-weight-bold);
|
|
270
|
+
padding: var(--space-8) var(--space-16);
|
|
271
|
+
padding-bottom: var(--space-12);
|
|
272
|
+
margin-top: 0;
|
|
273
|
+
border-top: 1px solid var(--border-neutral-subtle);
|
|
274
|
+
font-size: var(--font-md);
|
|
275
|
+
text-align: left;
|
|
276
|
+
width: 100%;
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
// Action buttons - inline variant
|
|
280
|
+
.notification-actions-inline {
|
|
281
|
+
display: flex;
|
|
282
|
+
align-items: center;
|
|
283
|
+
gap: var(--space-16);
|
|
284
|
+
padding: var(--space-12) var(--space-16);
|
|
285
|
+
|
|
286
|
+
.description-text {
|
|
287
|
+
flex: 1;
|
|
288
|
+
line-height: 1.4;
|
|
289
|
+
font-size: var(--font-md);
|
|
290
|
+
font-weight: var(--font-weight-light);
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
// Button stays on the right (doesn't shrink or grow)
|
|
294
|
+
:global(button) {
|
|
295
|
+
flex-shrink: 0;
|
|
296
|
+
margin-left: auto;
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
// Action buttons - standard (below description)
|
|
301
|
+
.notification-actions {
|
|
302
|
+
display: flex;
|
|
303
|
+
gap: var(--space-8);
|
|
304
|
+
padding: var(--space-12) var(--space-16);
|
|
305
|
+
padding-top: var(--space-8);
|
|
306
|
+
border-top: 1px solid var(--border-neutral-subtle);
|
|
307
|
+
}
|
|
308
|
+
</style>
|