UNPKG

@indielayer/ui

Version:

Indielayer UI Components with Tailwind CSS build for Vue 3

99 lines (77 loc) 2.5 kB
import { computed, inject, unref } from 'vue' import { injectThemeKey } from './keys' import { isValidColor, tailwindColors, colorShade, setOpacity } from '../common/colors' import { mergeRightDeep } from '../common/utils' export type Tone = '50' | '100' | '200' | '300' | '400' | '500' | '600' | '700' | '800' | '900' | '950' export interface ColorPalette { 50: string; 100: string; 200: string; 300: string; 400: string; 500: string; 600: string; 700: string; 800: string; 900: string; 950: string; } export type ColorLibrary = Record<string, ColorPalette> export interface ColorsProps { color?: string; } export interface ColorComposition { getPalette: (color?: string) => ColorPalette; getColorOpacity: (color: string, opacity: number) => string; } const colorCache: ColorLibrary = {} const defaultColors = { primary: tailwindColors.emerald, secondary: tailwindColors.slate, success: tailwindColors.green, warning: tailwindColors.yellow, error: tailwindColors.red, } const getTailwindColor = (color: string) => tailwindColors[color] const getColorOpacity = (color: string, opacity: number) => setOpacity(color, opacity) export const useColors = (): ColorComposition => { const globalTheme = inject(injectThemeKey, {}) const customColors = computed(() => mergeRightDeep(defaultColors, unref(globalTheme).colors || {})) const getPalette = (color?: string): ColorPalette => { if (!color) return getTailwindColor('gray') const twColor = getTailwindColor(color) if (twColor) return twColor if (colorCache[color]) return colorCache[color] if (customColors.value[color]) return customColors.value[color] if (!isValidColor(color)) { console.warn(`Invalid color: ${color}`) return getTailwindColor('gray') } const palette = { 50: colorShade(color, 0.9), 100: colorShade(color, 0.8), 200: colorShade(color, 0.6), 300: colorShade(color, 0.4), 400: colorShade(color, 0.1), 500: color, 600: colorShade(color, -0.1), 700: colorShade(color, -0.25), 800: colorShade(color, -0.58), 900: colorShade(color, -0.7), 950: colorShade(color, -0.8), } colorCache[color] = palette return palette } return { getPalette, getColorOpacity, } } export type UseColorsProps = ReturnType<typeof useColors.props> useColors.props = (defaultColor?: string) => ({ color: { type: String, default: defaultColor, }, } as const)