UNPKG

goobs-frontend

Version:

A comprehensive React-based libary for building modern web applications

298 lines (277 loc) 8.62 kB
// -------------------------------------------------------------------------- // APPBAR THEME SYSTEM // -------------------------------------------------------------------------- import React from 'react' import { TRANSITIONS, SHADOWS } from './shared' export interface AppBarTheme { container: { backgroundColor: string backgroundImage?: string border: string borderRadius: string boxShadow: string backdropFilter?: string animation?: string } toolbar: { padding: string minHeight: string gap?: string } glyph: { color: string fontSize: string animation?: string } shimmer?: { background: string animation: string } transition: string } export interface AppBarStyles { // Theme selection theme?: 'light' | 'dark' | 'sacred' // Container styling backgroundColor?: string backgroundImage?: string borderColor?: string borderRadius?: string borderWidth?: string boxShadow?: string backdropFilter?: string containerAnimation?: string // Toolbar styling toolbarPadding?: string toolbarMinHeight?: string toolbarGap?: string // Layout and spacing margin?: string marginTop?: string marginBottom?: string marginLeft?: string marginRight?: string // Position and dimensions position?: 'static' | 'fixed' | 'absolute' | 'sticky' | 'relative' top?: string left?: string right?: string width?: string maxWidth?: string minWidth?: string height?: string maxHeight?: string minHeight?: string zIndex?: number // Glyph styling glyphColor?: string glyphFontSize?: string glyphAnimation?: string // Shimmer effect (sacred theme) shimmerBackground?: string shimmerAnimation?: string // Transitions transitionDuration?: string transitionEasing?: string // States disabled?: boolean elevated?: boolean } export const appBarThemes: Record<'light' | 'dark' | 'sacred', AppBarTheme> = { light: { container: { backgroundColor: '#ffffff', border: '1px solid rgba(229, 231, 235, 0.8)', borderRadius: '0', boxShadow: SHADOWS.light.small, backdropFilter: 'blur(10px)', }, toolbar: { padding: '0 16px', minHeight: '64px', gap: '12px', }, glyph: { color: 'rgba(107, 114, 128, 0.3)', fontSize: '16px', }, transition: TRANSITIONS.medium, }, dark: { container: { backgroundColor: 'rgba(17, 24, 39, 0.95)', border: '1px solid rgba(75, 85, 99, 0.3)', borderRadius: '0', boxShadow: SHADOWS.dark.medium, backdropFilter: 'blur(10px)', }, toolbar: { padding: '0 16px', minHeight: '64px', gap: '12px', }, glyph: { color: 'rgba(156, 163, 175, 0.3)', fontSize: '16px', }, transition: TRANSITIONS.medium, }, sacred: { container: { backgroundColor: 'rgba(0, 0, 0, 0.85)', backgroundImage: 'linear-gradient(135deg, #FFD700 0%, #F4A460 50%, #DAA520 100%)', border: '2px solid rgba(255, 215, 0, 0.5)', borderRadius: '0', boxShadow: SHADOWS.sacred.medium, backdropFilter: 'blur(10px)', animation: 'sacredGlow 4s ease-in-out infinite', }, toolbar: { padding: '0 12px', minHeight: '60px', gap: '8px', }, glyph: { color: 'rgba(255, 215, 0, 0.4)', fontSize: '16px', animation: 'sacredFloat 3s ease-in-out infinite', }, shimmer: { background: 'linear-gradient(90deg, transparent, rgba(255, 215, 0, 0.3), transparent)', animation: 'sacredShimmer 3s linear infinite', }, transition: TRANSITIONS.slow, }, } // Helper function to get computed theme with custom style overrides export const getAppBarTheme = (styles?: AppBarStyles): AppBarTheme => { const theme = styles?.theme || 'light' const baseTheme = appBarThemes[theme] if (!styles) { return baseTheme } return { container: { backgroundColor: styles.backgroundColor || baseTheme.container.backgroundColor, backgroundImage: styles.backgroundImage || baseTheme.container.backgroundImage, border: styles.borderColor ? `${styles.borderWidth || '1px'} solid ${styles.borderColor}` : baseTheme.container.border, borderRadius: styles.borderRadius || baseTheme.container.borderRadius, boxShadow: styles.boxShadow || baseTheme.container.boxShadow, backdropFilter: styles.backdropFilter || baseTheme.container.backdropFilter, animation: styles.containerAnimation || baseTheme.container.animation, }, toolbar: { padding: styles.toolbarPadding || baseTheme.toolbar.padding, minHeight: styles.toolbarMinHeight || baseTheme.toolbar.minHeight, gap: styles.toolbarGap || baseTheme.toolbar.gap, }, glyph: { color: styles.glyphColor || baseTheme.glyph.color, fontSize: styles.glyphFontSize || baseTheme.glyph.fontSize, animation: styles.glyphAnimation || baseTheme.glyph.animation, }, shimmer: baseTheme.shimmer ? { background: styles.shimmerBackground || baseTheme.shimmer.background, animation: styles.shimmerAnimation || baseTheme.shimmer.animation, } : undefined, transition: styles.transitionDuration ? `all ${styles.transitionDuration} ${styles.transitionEasing || 'cubic-bezier(0.4, 0, 0.2, 1)'}` : baseTheme.transition, } } // Main style generator function export const getAppBarStyles = ( styles?: AppBarStyles, isDisabled?: boolean ) => { const themeConfig = getAppBarTheme(styles) const containerStyle: React.CSSProperties = { position: styles?.position || 'static', top: styles?.top || (styles?.position === 'fixed' ? '0' : undefined), left: styles?.left || (styles?.position === 'fixed' ? '0' : undefined), right: styles?.right || (styles?.position === 'fixed' ? '0' : undefined), width: styles?.width || '100%', maxWidth: styles?.maxWidth, minWidth: styles?.minWidth, height: styles?.height, maxHeight: styles?.maxHeight, minHeight: styles?.minHeight || themeConfig.toolbar.minHeight, zIndex: styles?.zIndex || 1100, // Custom styles override theme defaults margin: styles?.margin !== undefined ? styles.margin : undefined, marginTop: styles?.marginTop !== undefined ? styles.marginTop : undefined, marginBottom: styles?.marginBottom !== undefined ? styles.marginBottom : undefined, marginLeft: styles?.marginLeft !== undefined ? styles.marginLeft : undefined, marginRight: styles?.marginRight !== undefined ? styles.marginRight : undefined, // Theme styles with custom overrides backgroundColor: styles?.backgroundColor || themeConfig.container.backgroundColor, backgroundImage: styles?.backgroundImage || themeConfig.container.backgroundImage, border: styles?.borderColor ? `${styles.borderWidth || '1px'} solid ${styles.borderColor}` : themeConfig.container.border, borderRadius: styles?.borderRadius || themeConfig.container.borderRadius, boxShadow: styles?.boxShadow || (styles?.elevated ? themeConfig.container.boxShadow : 'none'), backdropFilter: styles?.backdropFilter || themeConfig.container.backdropFilter, animation: styles?.containerAnimation || themeConfig.container.animation, transition: themeConfig.transition, opacity: isDisabled ? 0.5 : 1, pointerEvents: isDisabled ? 'none' : 'auto', display: 'flex', flexDirection: 'column', overflow: 'hidden', } const toolbarStyle: React.CSSProperties = { display: 'flex', alignItems: 'center', width: '100%', minHeight: themeConfig.toolbar.minHeight, padding: themeConfig.toolbar.padding, gap: themeConfig.toolbar.gap, position: 'relative', zIndex: 2, } const shimmerStyle: React.CSSProperties | undefined = themeConfig.shimmer ? { position: 'absolute', top: '0', left: '0', right: '0', height: '1px', background: themeConfig.shimmer.background, backgroundSize: '200% 100%', animation: themeConfig.shimmer.animation, zIndex: 1, } : undefined const glyphStyle: React.CSSProperties = { position: 'absolute', color: themeConfig.glyph.color, fontSize: themeConfig.glyph.fontSize, animation: themeConfig.glyph.animation, pointerEvents: 'none', zIndex: 1, } return { container: containerStyle, toolbar: toolbarStyle, shimmer: shimmerStyle, glyph: glyphStyle, } }