mirror of
https://github.com/Memo-2023/mana-monorepo.git
synced 2026-05-14 19:41:09 +02:00
feat(ui): add elevation system for overlays and modals
- Add 3-level elevation CSS variables to themes.css for all theme variants - elevation-1: dropdowns, pills (16% in dark mode) - elevation-2: modals, overlays (20% in dark mode) - elevation-3: context menus, tooltips (24% in dark mode) - Update ContextMenu to use elevation-3 - Update Modal to use elevation-2 with theme-aware borders - Update QuickEventOverlay to use elevation-2 with matching footer - Update PillTimeRangeSelector dropdown to use elevation-1 - Update ConfirmationModal and FormModal to use theme variables - Remove shadows from overlay components for cleaner look 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
parent
8eb295d491
commit
bd89871f8b
7 changed files with 104 additions and 27 deletions
|
|
@ -1070,12 +1070,9 @@
|
|||
position: fixed;
|
||||
width: 380px;
|
||||
max-height: 450px;
|
||||
background: hsl(var(--color-surface-elevated-2));
|
||||
background: var(--color-surface-elevated-2);
|
||||
border: 1px solid hsl(var(--color-border));
|
||||
border-radius: var(--radius-lg);
|
||||
box-shadow:
|
||||
0 20px 60px hsl(var(--color-foreground) / 0.2),
|
||||
0 4px 16px hsl(var(--color-foreground) / 0.1);
|
||||
z-index: 99999 !important;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
|
@ -1320,14 +1317,17 @@
|
|||
.overlay-actions {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: flex-end;
|
||||
gap: 0.75rem;
|
||||
padding: 1rem 1.25rem;
|
||||
border-top: 1px solid hsl(var(--color-border));
|
||||
background: hsl(var(--color-surface));
|
||||
background: var(--color-surface-elevated-2);
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.overlay-actions .btn-primary {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.btn-ghost {
|
||||
padding: 0.5rem 1rem;
|
||||
border: none;
|
||||
|
|
|
|||
|
|
@ -33,6 +33,11 @@
|
|||
--color-surface: var(--theme-surface);
|
||||
--color-surface-hover: var(--theme-surface-hover);
|
||||
--color-surface-elevated: var(--theme-surface-elevated);
|
||||
|
||||
/* Elevation system - progressively lighter surfaces for overlays */
|
||||
--color-surface-elevated-1: var(--theme-surface-elevated-1);
|
||||
--color-surface-elevated-2: var(--theme-surface-elevated-2);
|
||||
--color-surface-elevated-3: var(--theme-surface-elevated-3);
|
||||
--color-muted: var(--theme-muted);
|
||||
--color-muted-foreground: var(--theme-muted-foreground);
|
||||
--color-border: var(--theme-border);
|
||||
|
|
@ -129,6 +134,10 @@
|
|||
--theme-surface: hsl(0 0% 100%);
|
||||
--theme-surface-hover: hsl(0 0% 96%);
|
||||
--theme-surface-elevated: hsl(0 0% 100%);
|
||||
/* Elevation system - progressively lighter surfaces for overlays */
|
||||
--theme-surface-elevated-1: hsl(0 0% 100%);
|
||||
--theme-surface-elevated-2: hsl(0 0% 100%);
|
||||
--theme-surface-elevated-3: hsl(0 0% 100%);
|
||||
--theme-muted: hsl(0 0% 90%);
|
||||
--theme-muted-foreground: hsl(0 0% 40%);
|
||||
--theme-border: hsl(0 0% 90%);
|
||||
|
|
@ -192,6 +201,10 @@
|
|||
--theme-surface: hsl(0 0% 12%);
|
||||
--theme-surface-hover: hsl(0 0% 16%);
|
||||
--theme-surface-elevated: hsl(0 0% 14%);
|
||||
/* Elevation system - progressively lighter surfaces for overlays */
|
||||
--theme-surface-elevated-1: hsl(0 0% 16%);
|
||||
--theme-surface-elevated-2: hsl(0 0% 20%);
|
||||
--theme-surface-elevated-3: hsl(0 0% 24%);
|
||||
--theme-muted: hsl(0 0% 20%);
|
||||
--theme-muted-foreground: hsl(0 0% 60%);
|
||||
--theme-border: hsl(0 0% 26%);
|
||||
|
|
@ -244,6 +257,9 @@
|
|||
--theme-surface: hsl(0 0% 100%);
|
||||
--theme-surface-hover: hsl(0 0% 96%);
|
||||
--theme-surface-elevated: hsl(0 0% 100%);
|
||||
--theme-surface-elevated-1: hsl(0 0% 100%);
|
||||
--theme-surface-elevated-2: hsl(0 0% 100%);
|
||||
--theme-surface-elevated-3: hsl(0 0% 100%);
|
||||
--theme-muted: hsl(0 0% 90%);
|
||||
--theme-muted-foreground: hsl(0 0% 40%);
|
||||
--theme-border: hsl(0 0% 90%);
|
||||
|
|
@ -275,6 +291,9 @@
|
|||
--theme-surface: hsl(0 0% 12%);
|
||||
--theme-surface-hover: hsl(0 0% 16%);
|
||||
--theme-surface-elevated: hsl(0 0% 14%);
|
||||
--theme-surface-elevated-1: hsl(0 0% 16%);
|
||||
--theme-surface-elevated-2: hsl(0 0% 20%);
|
||||
--theme-surface-elevated-3: hsl(0 0% 24%);
|
||||
--theme-muted: hsl(0 0% 20%);
|
||||
--theme-muted-foreground: hsl(0 0% 60%);
|
||||
--theme-border: hsl(0 0% 26%);
|
||||
|
|
@ -306,6 +325,9 @@
|
|||
--theme-surface: hsl(0 0% 100%);
|
||||
--theme-surface-hover: hsl(120 25% 95%);
|
||||
--theme-surface-elevated: hsl(0 0% 100%);
|
||||
--theme-surface-elevated-1: hsl(0 0% 100%);
|
||||
--theme-surface-elevated-2: hsl(0 0% 100%);
|
||||
--theme-surface-elevated-3: hsl(0 0% 100%);
|
||||
--theme-muted: hsl(120 25% 95%);
|
||||
--theme-muted-foreground: hsl(122 20% 40%);
|
||||
--theme-border: hsl(120 25% 91%);
|
||||
|
|
@ -337,6 +359,9 @@
|
|||
--theme-surface: hsl(120 10% 12%);
|
||||
--theme-surface-hover: hsl(120 10% 16%);
|
||||
--theme-surface-elevated: hsl(120 10% 14%);
|
||||
--theme-surface-elevated-1: hsl(120 10% 16%);
|
||||
--theme-surface-elevated-2: hsl(120 10% 20%);
|
||||
--theme-surface-elevated-3: hsl(120 10% 24%);
|
||||
--theme-muted: hsl(120 10% 20%);
|
||||
--theme-muted-foreground: hsl(120 10% 60%);
|
||||
--theme-border: hsl(120 10% 25%);
|
||||
|
|
@ -368,6 +393,9 @@
|
|||
--theme-surface: hsl(0 0% 100%);
|
||||
--theme-surface-hover: hsl(200 10% 94%);
|
||||
--theme-surface-elevated: hsl(0 0% 100%);
|
||||
--theme-surface-elevated-1: hsl(0 0% 100%);
|
||||
--theme-surface-elevated-2: hsl(0 0% 100%);
|
||||
--theme-surface-elevated-3: hsl(0 0% 100%);
|
||||
--theme-muted: hsl(200 10% 94%);
|
||||
--theme-muted-foreground: hsl(200 10% 45%);
|
||||
--theme-border: hsl(200 10% 88%);
|
||||
|
|
@ -399,6 +427,9 @@
|
|||
--theme-surface: hsl(200 10% 12%);
|
||||
--theme-surface-hover: hsl(200 10% 16%);
|
||||
--theme-surface-elevated: hsl(200 10% 14%);
|
||||
--theme-surface-elevated-1: hsl(200 10% 16%);
|
||||
--theme-surface-elevated-2: hsl(200 10% 20%);
|
||||
--theme-surface-elevated-3: hsl(200 10% 24%);
|
||||
--theme-muted: hsl(200 10% 20%);
|
||||
--theme-muted-foreground: hsl(200 10% 60%);
|
||||
--theme-border: hsl(200 10% 25%);
|
||||
|
|
@ -430,6 +461,9 @@
|
|||
--theme-surface: hsl(0 0% 100%);
|
||||
--theme-surface-hover: hsl(199 100% 94%);
|
||||
--theme-surface-elevated: hsl(0 0% 100%);
|
||||
--theme-surface-elevated-1: hsl(0 0% 100%);
|
||||
--theme-surface-elevated-2: hsl(0 0% 100%);
|
||||
--theme-surface-elevated-3: hsl(0 0% 100%);
|
||||
--theme-muted: hsl(199 100% 94%);
|
||||
--theme-muted-foreground: hsl(199 50% 40%);
|
||||
--theme-border: hsl(199 71% 87%);
|
||||
|
|
@ -461,6 +495,9 @@
|
|||
--theme-surface: hsl(199 30% 12%);
|
||||
--theme-surface-hover: hsl(199 30% 16%);
|
||||
--theme-surface-elevated: hsl(199 30% 14%);
|
||||
--theme-surface-elevated-1: hsl(199 30% 16%);
|
||||
--theme-surface-elevated-2: hsl(199 30% 20%);
|
||||
--theme-surface-elevated-3: hsl(199 30% 24%);
|
||||
--theme-muted: hsl(199 20% 20%);
|
||||
--theme-muted-foreground: hsl(199 20% 60%);
|
||||
--theme-border: hsl(199 20% 25%);
|
||||
|
|
@ -493,6 +530,9 @@
|
|||
--theme-surface: hsl(0 0% 12%);
|
||||
--theme-surface-hover: hsl(0 0% 16%);
|
||||
--theme-surface-elevated: hsl(0 0% 14%);
|
||||
--theme-surface-elevated-1: hsl(0 0% 16%);
|
||||
--theme-surface-elevated-2: hsl(0 0% 20%);
|
||||
--theme-surface-elevated-3: hsl(0 0% 24%);
|
||||
--theme-muted: hsl(0 0% 20%);
|
||||
--theme-muted-foreground: hsl(0 0% 60%);
|
||||
--theme-border: hsl(0 0% 26%);
|
||||
|
|
|
|||
|
|
@ -105,11 +105,18 @@
|
|||
class="menu-item"
|
||||
class:disabled={item.disabled}
|
||||
class:danger={item.variant === 'danger'}
|
||||
class:has-toggle={item.toggle}
|
||||
onclick={() => handleItemClick(item)}
|
||||
role="menuitem"
|
||||
disabled={item.disabled}
|
||||
>
|
||||
{#if item.icon}
|
||||
{#if item.toggle}
|
||||
<span class="item-toggle" class:checked={item.checked}>
|
||||
<span class="toggle-track">
|
||||
<span class="toggle-thumb"></span>
|
||||
</span>
|
||||
</span>
|
||||
{:else if item.icon}
|
||||
<span class="item-icon">
|
||||
<item.icon size={16} />
|
||||
</span>
|
||||
|
|
@ -131,12 +138,9 @@
|
|||
min-width: 180px;
|
||||
max-width: 280px;
|
||||
padding: 0.375rem;
|
||||
background: hsl(var(--color-surface));
|
||||
background: var(--color-surface-elevated-3);
|
||||
border: 1px solid hsl(var(--color-border));
|
||||
border-radius: var(--radius-lg);
|
||||
box-shadow:
|
||||
0 10px 38px -10px rgba(0, 0, 0, 0.35),
|
||||
0 10px 20px -15px rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
|
||||
.menu-item {
|
||||
|
|
@ -205,4 +209,44 @@
|
|||
margin: 0.375rem 0.5rem;
|
||||
background: hsl(var(--color-border));
|
||||
}
|
||||
|
||||
/* Toggle switch styles */
|
||||
.menu-item.has-toggle {
|
||||
gap: 0.5rem;
|
||||
}
|
||||
|
||||
.item-toggle {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.toggle-track {
|
||||
position: relative;
|
||||
width: 28px;
|
||||
height: 16px;
|
||||
background: hsl(var(--color-muted));
|
||||
border-radius: 8px;
|
||||
transition: background-color 150ms ease;
|
||||
}
|
||||
|
||||
.toggle-thumb {
|
||||
position: absolute;
|
||||
top: 2px;
|
||||
left: 2px;
|
||||
width: 12px;
|
||||
height: 12px;
|
||||
background: hsl(var(--color-background));
|
||||
border-radius: 50%;
|
||||
transition: transform 150ms ease;
|
||||
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
|
||||
.item-toggle.checked .toggle-track {
|
||||
background: hsl(var(--color-primary));
|
||||
}
|
||||
|
||||
.item-toggle.checked .toggle-thumb {
|
||||
transform: translateX(12px);
|
||||
}
|
||||
</style>
|
||||
|
|
|
|||
|
|
@ -389,13 +389,10 @@
|
|||
}
|
||||
|
||||
.glass-dropdown {
|
||||
background: hsl(var(--color-surface) / 0.95);
|
||||
background: color-mix(in srgb, var(--color-surface-elevated-1) 95%, transparent);
|
||||
backdrop-filter: blur(16px);
|
||||
-webkit-backdrop-filter: blur(16px);
|
||||
border: 1px solid hsl(var(--color-border));
|
||||
box-shadow:
|
||||
0 20px 25px -5px hsl(var(--color-foreground) / 0.1),
|
||||
0 10px 10px -5px hsl(var(--color-foreground) / 0.04);
|
||||
}
|
||||
|
||||
.dropdown-header {
|
||||
|
|
|
|||
|
|
@ -162,8 +162,8 @@
|
|||
onclick={onClose}
|
||||
disabled={loading}
|
||||
class="w-full flex items-center justify-center gap-2 px-4 py-3 rounded-xl font-semibold text-sm
|
||||
bg-black/5 dark:bg-white/10 text-foreground
|
||||
hover:bg-black/10 dark:hover:bg-white/20 hover:shadow-md
|
||||
bg-foreground/5 text-foreground
|
||||
hover:bg-foreground/10 hover:shadow-md
|
||||
transition-all duration-200 hover:-translate-y-0.5 active:translate-y-0
|
||||
disabled:opacity-50 disabled:cursor-not-allowed disabled:hover:translate-y-0"
|
||||
>
|
||||
|
|
|
|||
|
|
@ -88,10 +88,8 @@
|
|||
<form onsubmit={handleSubmit} onkeydown={handleKeydown} class="space-y-4">
|
||||
<!-- Error message -->
|
||||
{#if error}
|
||||
<div
|
||||
class="rounded-lg bg-red-50 dark:bg-red-900/20 border border-red-200 dark:border-red-800 p-3"
|
||||
>
|
||||
<Text variant="small" class="text-red-600 dark:text-red-400">
|
||||
<div class="rounded-lg bg-error/10 border border-error/30 p-3">
|
||||
<Text variant="small" class="text-error">
|
||||
{error}
|
||||
</Text>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -65,15 +65,13 @@
|
|||
<div
|
||||
class="relative flex max-h-[90vh] w-full {maxWidthClasses[
|
||||
maxWidth
|
||||
]} flex-col rounded-2xl border border-black/10 dark:border-white/20 bg-white/80 dark:bg-white/10 backdrop-blur-xl shadow-2xl"
|
||||
]} flex-col rounded-2xl border border-border bg-surface-elevated-2 backdrop-blur-xl shadow-2xl"
|
||||
onclick={(e) => e.stopPropagation()}
|
||||
onkeydown={(e) => e.stopPropagation()}
|
||||
>
|
||||
{#if showHeader}
|
||||
<!-- Header -->
|
||||
<div
|
||||
class="flex items-center justify-between p-6 border-b border-black/10 dark:border-white/10"
|
||||
>
|
||||
<div class="flex items-center justify-between p-6 border-b border-border">
|
||||
<div class="flex items-center gap-3 flex-1">
|
||||
{#if icon}
|
||||
{@render icon()}
|
||||
|
|
@ -86,7 +84,7 @@
|
|||
</div>
|
||||
<button
|
||||
onclick={onClose}
|
||||
class="p-2 rounded-xl bg-black/5 dark:bg-white/10 hover:bg-black/10 dark:hover:bg-white/20 transition-all duration-200 hover:scale-105"
|
||||
class="p-2 rounded-xl bg-foreground/5 hover:bg-foreground/10 transition-all duration-200 hover:scale-105"
|
||||
aria-label="Close"
|
||||
>
|
||||
<X size={18} weight="bold" class="text-muted-foreground" />
|
||||
|
|
@ -101,7 +99,7 @@
|
|||
|
||||
<!-- Footer (optional) -->
|
||||
{#if footer}
|
||||
<div class="border-t border-black/10 dark:border-white/10 p-6">
|
||||
<div class="border-t border-border p-6">
|
||||
{@render footer()}
|
||||
</div>
|
||||
{/if}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue