mirror of
https://github.com/Memo-2023/mana-monorepo.git
synced 2026-05-14 20:21:09 +02:00
feat(web): wallpaper system + sticky PageHeader
Wallpaper system with four sources (predefined images, CSS gradients, custom uploads via mana-media, and theme default). Configurable per-scene or globally, with overlay controls (blur + opacity) and hover preview. Adds sticky prop to shared PageHeader component and applies it across themes, settings, credits, subscription, help, and profile pages. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
a9c51517eb
commit
8c2f9306e9
22 changed files with 1557 additions and 66 deletions
|
|
@ -1,10 +1,6 @@
|
|||
<script lang="ts">
|
||||
import type {
|
||||
ThemeVariant,
|
||||
ThemeMode,
|
||||
A11yStore,
|
||||
UserSettingsStore,
|
||||
} from '@mana/shared-theme';
|
||||
import type { Snippet } from 'svelte';
|
||||
import type { ThemeVariant, ThemeMode, A11yStore, UserSettingsStore } from '@mana/shared-theme';
|
||||
import { ArrowLeft, Sun, Moon, Desktop } from '@mana/shared-icons';
|
||||
import type { ThemeCardData, ThemePageTranslations, A11yTranslations } from '../types';
|
||||
import { defaultTranslations, defaultA11yTranslations } from '../types';
|
||||
|
|
@ -26,7 +22,7 @@
|
|||
currentMode?: ThemeMode;
|
||||
onModeChange?: (mode: ThemeMode) => void;
|
||||
|
||||
// Back navigation
|
||||
// Back navigation (deprecated — use PageHeader sticky on the consuming page instead)
|
||||
showBackButton?: boolean;
|
||||
onBack?: () => void;
|
||||
|
||||
|
|
@ -46,6 +42,13 @@
|
|||
userSettingsStore?: UserSettingsStore;
|
||||
pinnedThemes?: ThemeVariant[];
|
||||
onTogglePin?: (variant: ThemeVariant) => void;
|
||||
|
||||
// Visual
|
||||
/** Make outer wrapper transparent (so a wallpaper layer behind it shows through). */
|
||||
transparent?: boolean;
|
||||
|
||||
/** Extra content rendered below the theme grid (e.g. wallpaper picker). */
|
||||
children?: Snippet;
|
||||
}
|
||||
|
||||
let {
|
||||
|
|
@ -67,6 +70,8 @@
|
|||
a11yTranslations = {},
|
||||
pinnedThemes = [],
|
||||
onTogglePin,
|
||||
transparent = false,
|
||||
children,
|
||||
}: Props = $props();
|
||||
|
||||
// Merge translations with defaults
|
||||
|
|
@ -80,8 +85,8 @@
|
|||
]);
|
||||
</script>
|
||||
|
||||
<div class="min-h-screen bg-background">
|
||||
<div class="max-w-4xl mx-auto px-4 py-8">
|
||||
<div class="min-h-screen" class:bg-background={!transparent}>
|
||||
<div class="max-w-3xl mx-auto px-4 py-8" class:theme-page-card={transparent}>
|
||||
<!-- Header -->
|
||||
<header class="mb-6">
|
||||
<div class="flex items-center gap-3 mb-2">
|
||||
|
|
@ -155,5 +160,25 @@
|
|||
<A11ySettings store={a11yStore} translations={a11yTranslations} />
|
||||
</section>
|
||||
{/if}
|
||||
|
||||
<!-- Extra content (e.g. wallpaper picker) -->
|
||||
{#if children}
|
||||
{@render children()}
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.theme-page-card {
|
||||
background: hsl(var(--color-card, 0 0% 100%) / 0.82);
|
||||
backdrop-filter: blur(20px);
|
||||
-webkit-backdrop-filter: blur(20px);
|
||||
border-radius: 1.25rem;
|
||||
margin-top: 2rem;
|
||||
margin-bottom: 2rem;
|
||||
padding-left: 2rem;
|
||||
padding-right: 2rem;
|
||||
border: 1px solid hsl(var(--color-border) / 0.2);
|
||||
box-shadow: 0 8px 32px rgba(0, 0, 0, 0.08);
|
||||
}
|
||||
</style>
|
||||
|
|
|
|||
|
|
@ -28,6 +28,16 @@ export type {
|
|||
StartPageConfig,
|
||||
WeekStartDay,
|
||||
GeneralSettings,
|
||||
// Wallpaper Types
|
||||
WallpaperSource,
|
||||
WallpaperSourceNone,
|
||||
WallpaperSourcePredefined,
|
||||
WallpaperSourceGenerated,
|
||||
WallpaperSourceUpload,
|
||||
WallpaperSolid,
|
||||
WallpaperGradient,
|
||||
WallpaperOverlay,
|
||||
WallpaperConfig,
|
||||
} from './types';
|
||||
|
||||
// User Settings Constants
|
||||
|
|
|
|||
|
|
@ -182,6 +182,68 @@ export interface ThemeStore {
|
|||
initialize: () => () => void;
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// Wallpaper / Background Types
|
||||
// ============================================================================
|
||||
|
||||
/** No wallpaper — the theme's default bg-background color shows through. */
|
||||
export interface WallpaperSourceNone {
|
||||
type: 'none';
|
||||
}
|
||||
|
||||
/** A bundled, predefined wallpaper image (e.g. "ocean-1"). */
|
||||
export interface WallpaperSourcePredefined {
|
||||
type: 'predefined';
|
||||
id: string;
|
||||
}
|
||||
|
||||
/** Solid color background for generated wallpapers. */
|
||||
export interface WallpaperSolid {
|
||||
type: 'solid';
|
||||
color: string;
|
||||
}
|
||||
|
||||
/** Gradient background for generated wallpapers. */
|
||||
export interface WallpaperGradient {
|
||||
type: 'gradient';
|
||||
colors: string[];
|
||||
angle?: number;
|
||||
}
|
||||
|
||||
/** A CSS gradient or solid color generated client-side. Only parameters are stored. */
|
||||
export interface WallpaperSourceGenerated {
|
||||
type: 'generated';
|
||||
params: WallpaperSolid | WallpaperGradient;
|
||||
}
|
||||
|
||||
/** A user-uploaded image served by mana-media / MinIO. */
|
||||
export interface WallpaperSourceUpload {
|
||||
type: 'upload';
|
||||
mediaId: string;
|
||||
url: string;
|
||||
}
|
||||
|
||||
/** All wallpaper source types. */
|
||||
export type WallpaperSource =
|
||||
| WallpaperSourceNone
|
||||
| WallpaperSourcePredefined
|
||||
| WallpaperSourceGenerated
|
||||
| WallpaperSourceUpload;
|
||||
|
||||
/** Overlay applied on top of the wallpaper for readability. */
|
||||
export interface WallpaperOverlay {
|
||||
/** Backdrop blur in px (0–20, default 0). */
|
||||
blur?: number;
|
||||
/** Semi-transparent overlay darkness (0–0.6, default 0). */
|
||||
opacity?: number;
|
||||
}
|
||||
|
||||
/** Complete wallpaper configuration. */
|
||||
export interface WallpaperConfig {
|
||||
source: WallpaperSource;
|
||||
overlay?: WallpaperOverlay;
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// Accessibility (A11y) Types
|
||||
// ============================================================================
|
||||
|
|
@ -322,6 +384,8 @@ export interface GlobalSettings {
|
|||
general: GeneralSettings;
|
||||
/** Recently used emojis (shared across all apps) - max 16 */
|
||||
recentEmojis?: string[];
|
||||
/** Global wallpaper / background config (can be overridden per scene) */
|
||||
wallpaper?: WallpaperConfig;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -267,6 +267,7 @@ export function createUserSettingsStore(config: UserSettingsStoreConfig): UserSe
|
|||
},
|
||||
},
|
||||
recentEmojis: settings.recentEmojis ?? globalSettings.recentEmojis,
|
||||
wallpaper: settings.wallpaper !== undefined ? settings.wallpaper : globalSettings.wallpaper,
|
||||
};
|
||||
saveToStorage();
|
||||
|
||||
|
|
|
|||
|
|
@ -58,6 +58,8 @@
|
|||
centered?: boolean;
|
||||
/** Back navigation href (shows back arrow button) */
|
||||
backHref?: string;
|
||||
/** Sticky position at top of viewport with frosted-glass background */
|
||||
sticky?: boolean;
|
||||
/** Icon snippet (before title) */
|
||||
icon?: Snippet;
|
||||
/** Breadcrumb snippet (above title) */
|
||||
|
|
@ -77,6 +79,7 @@
|
|||
bordered = false,
|
||||
centered = false,
|
||||
backHref,
|
||||
sticky = false,
|
||||
icon,
|
||||
breadcrumb,
|
||||
actions,
|
||||
|
|
@ -84,6 +87,9 @@
|
|||
class: className = '',
|
||||
}: Props = $props();
|
||||
|
||||
const stickyClasses =
|
||||
'sticky top-0 z-40 backdrop-blur-lg bg-[hsl(var(--color-background,0_0%_100%)/0.8)] border-b border-[hsl(var(--color-border)/0.3)]';
|
||||
|
||||
const sizeClasses: Record<HeaderSize, { container: string; title: string }> = {
|
||||
sm: {
|
||||
container: 'py-3',
|
||||
|
|
@ -101,8 +107,8 @@
|
|||
</script>
|
||||
|
||||
<header
|
||||
class="page-header {sizeClasses[size].container} {bordered
|
||||
? 'border-b border-theme'
|
||||
class="page-header {sizeClasses[size].container} {bordered ? 'border-b border-theme' : ''} {sticky
|
||||
? stickyClasses
|
||||
: ''} {className}"
|
||||
>
|
||||
<!-- Breadcrumb -->
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue