[FEAT] add grid metrics

This commit is contained in:
2026-01-01 17:14:21 +01:00
parent 281a37fa7e
commit 1f9fc4d5bb
5 changed files with 352 additions and 128 deletions

View File

@@ -0,0 +1,113 @@
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',
};
}