import { computed, type Ref, type ComputedRef } from 'vue'; export interface BackgroundStylesOptions { backgroundColor: Ref | ComputedRef | string; checkerboardEnabled?: Ref | ComputedRef | boolean; darkMode?: Ref | ComputedRef | boolean; } export interface BackgroundStyles { backgroundColor: string; backgroundImage: string; backgroundSize: string; backgroundPosition: string; } /** * Composable for generating consistent background styles across components. * Handles transparent backgrounds with checkerboard patterns and dark mode. */ export function useBackgroundStyles(options: BackgroundStylesOptions) { // Helper to get reactive values const getBackgroundColor = () => (typeof options.backgroundColor === 'string' ? options.backgroundColor : options.backgroundColor.value); const getCheckerboardEnabled = () => (typeof options.checkerboardEnabled === 'boolean' ? options.checkerboardEnabled : (options.checkerboardEnabled?.value ?? true)); const getDarkMode = () => (typeof options.darkMode === 'boolean' ? options.darkMode : (options.darkMode?.value ?? false)); /** * Get the background color. */ const backgroundColor = computed(() => { const bg = getBackgroundColor(); return bg === 'transparent' ? 'transparent' : bg; }); /** * Get the background image (checkerboard pattern for transparent backgrounds). */ const backgroundImage = computed(() => { const bg = getBackgroundColor(); const checkerboardEnabled = getCheckerboardEnabled(); const darkMode = getDarkMode(); if (bg === 'transparent' && checkerboardEnabled) { // Checkerboard pattern for transparent backgrounds (dark mode friendly) const color = darkMode ? '#4b5563' : '#d1d5db'; return `linear-gradient(45deg, ${color} 25%, transparent 25%), linear-gradient(-45deg, ${color} 25%, transparent 25%), linear-gradient(45deg, transparent 75%, ${color} 75%), linear-gradient(-45deg, transparent 75%, ${color} 75%)`; } return 'none'; }); /** * Get the background size. */ const backgroundSize = computed(() => { const bg = getBackgroundColor(); return bg === 'transparent' ? '20px 20px' : 'auto'; }); /** * Get the background position. */ const backgroundPosition = computed(() => { const bg = getBackgroundColor(); return bg === 'transparent' ? '0 0, 0 10px, 10px -10px, -10px 0px' : '0 0'; }); /** * Get all background styles as a single object. */ const backgroundStyles = computed(() => ({ backgroundColor: backgroundColor.value, backgroundImage: backgroundImage.value, backgroundSize: backgroundSize.value, backgroundPosition: backgroundPosition.value, })); return { backgroundColor, backgroundImage, backgroundSize, backgroundPosition, backgroundStyles, }; } /** * Standalone helper to get background styles. * Useful when you don't need the full composable. */ export function getBackgroundStyles( backgroundColor: string, options: { checkerboardEnabled?: boolean; darkMode?: boolean; } = {} ): BackgroundStyles { const checkerboardEnabled = options.checkerboardEnabled ?? true; const darkMode = options.darkMode ?? false; const bg = backgroundColor === 'transparent' ? 'transparent' : backgroundColor; let bgImage = 'none'; if (backgroundColor === 'transparent' && checkerboardEnabled) { const color = darkMode ? '#4b5563' : '#d1d5db'; bgImage = `linear-gradient(45deg, ${color} 25%, transparent 25%), linear-gradient(-45deg, ${color} 25%, transparent 25%), linear-gradient(45deg, transparent 75%, ${color} 75%), linear-gradient(-45deg, transparent 75%, ${color} 75%)`; } return { backgroundColor: bg, backgroundImage: bgImage, backgroundSize: backgroundColor === 'transparent' ? '20px 20px' : 'auto', backgroundPosition: backgroundColor === 'transparent' ? '0 0, 0 10px, 10px -10px, -10px 0px' : '0 0', }; }