114 lines
3.9 KiB
TypeScript
114 lines
3.9 KiB
TypeScript
import { computed, type Ref, type ComputedRef } from 'vue';
|
|
|
|
export interface BackgroundStylesOptions {
|
|
backgroundColor: Ref<string> | ComputedRef<string> | string;
|
|
checkerboardEnabled?: Ref<boolean> | ComputedRef<boolean> | boolean;
|
|
darkMode?: Ref<boolean> | ComputedRef<boolean> | 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<BackgroundStyles>(() => ({
|
|
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',
|
|
};
|
|
}
|