UNPKG

tw-colors

Version:

Tailwind plugin for switching color theme with just one className

271 lines (260 loc) 8.33 kB
import { Config } from 'tailwindcss'; import { resolveTwcConfig } from '../dist/lib'; import { describe, expect, test } from 'vitest'; import { createThemes } from '../dist/lib'; test('type', () => { const t = { content: ['./src/**/*.{astro,html,js,jsx,md,mdx,ts,tsx}'], theme: { extend: {} }, plugins: [ createThemes( { light: { blue: 'blue' } }, { defaultTheme: 'day', produceCssVariable: (prop) => `--c-${prop}`, strict: true, }, ), ], important: false, } satisfies Config; }); test('Variants', () => { const { variants } = resolveTwcConfig({ light: {}, dark: {}, halloween: {}, }); expect(variants).toEqual([ { name: 'light', definition: [ '.light&', ':is(.light > &:not([data-theme]))', ':is(.light &:not(.light [data-theme]:not(.light) * ))', ':is(.light:not(:has([data-theme])) &:not([data-theme]))', "[data-theme='light']&", ":is([data-theme='light'] > &:not([data-theme]))", ":is([data-theme='light'] &:not([data-theme='light'] [data-theme]:not([data-theme='light']) * ))", ":is([data-theme='light']:not(:has([data-theme])) &:not([data-theme]))", ], }, { name: 'dark', definition: [ '.dark&', ':is(.dark > &:not([data-theme]))', ':is(.dark &:not(.dark [data-theme]:not(.dark) * ))', ':is(.dark:not(:has([data-theme])) &:not([data-theme]))', "[data-theme='dark']&", ":is([data-theme='dark'] > &:not([data-theme]))", ":is([data-theme='dark'] &:not([data-theme='dark'] [data-theme]:not([data-theme='dark']) * ))", ":is([data-theme='dark']:not(:has([data-theme])) &:not([data-theme]))", ], }, { name: 'halloween', definition: [ '.halloween&', ':is(.halloween > &:not([data-theme]))', ':is(.halloween &:not(.halloween [data-theme]:not(.halloween) * ))', ':is(.halloween:not(:has([data-theme])) &:not([data-theme]))', "[data-theme='halloween']&", ":is([data-theme='halloween'] > &:not([data-theme]))", ":is([data-theme='halloween'] &:not([data-theme='halloween'] [data-theme]:not([data-theme='halloween']) * ))", ":is([data-theme='halloween']:not(:has([data-theme])) &:not([data-theme]))", ], }, ]); }); test('Utilities', () => { const { utilities } = resolveTwcConfig({ hsl: { c1: 'hsl(1, 2%, 3%)', c2: 'hsl(1 2% 3%)', c3: 'hsl(1, 2%, 3% / 0.5)', c4: 'hsla(1, 2%, 3%, 0.5)', }, rgb: { c1: 'rgb(255, 0, 0)', c2: 'rgb(255 0 0)', c3: 'rgb(255 0 0 / 0.5)', c4: 'rgba(255, 0, 0, 0.5)', }, hex: { c1: '#ff0000', c2: '#ff000080', }, colorName: { red: 'red', }, }); expect(utilities).toEqual({ '.hsl,[data-theme="hsl"]': { '--twc-c1': '1 2% 3%', '--twc-c2': '1 2% 3%', '--twc-c3': '1 2% 3%', '--twc-c3-opacity': '0.50', '--twc-c4': '1 2% 3%', '--twc-c4-opacity': '0.50', }, '.rgb,[data-theme="rgb"]': { '--twc-c1': '0 100% 50%', '--twc-c2': '0 100% 50%', '--twc-c3': '0 100% 50%', '--twc-c3-opacity': '0.50', '--twc-c4': '0 100% 50%', '--twc-c4-opacity': '0.50', }, '.hex,[data-theme="hex"]': { '--twc-c1': '0 100% 50%', '--twc-c2': '0 100% 50%', '--twc-c2-opacity': '0.50', }, '.colorName,[data-theme="colorName"]': { '--twc-red': '0 100% 50%', }, }); }); test('color-scheme', () => { const { utilities } = resolveTwcConfig(({ light, dark }) => ({ t1: { c1: 'red', 'slash/slash': 'red', }, t2: light({ c1: 'red', }), t3: dark({ c1: 'red', }), })); expect(utilities).toEqual({ '.t1,[data-theme="t1"]': { '--twc-c1': '0 100% 50%', '--twc-slash\\/slash': '0 100% 50%', }, '.t2,[data-theme="t2"]': { 'color-scheme': 'light', '--twc-c1': '0 100% 50%', }, '.t3,[data-theme="t3"]': { 'color-scheme': 'dark', '--twc-c1': '0 100% 50%', }, }); }); describe('Nested colors', () => { test('Utilities', () => { const { utilities } = resolveTwcConfig({ light: { primary: { 100: 'red', 200: 'blue', }, secondary: { 100: 'rgb(255 0 0 / 0.5)', 200: 'rgb(255 0 0 / 0.7)', }, }, dark: { primary: { 100: 'lime', 200: 'pink', }, secondary: { 100: 'rgb(255 0 0 / 0.6)', 200: 'rgb(255 0 0 / 0.8)', }, }, }); expect(utilities).toEqual({ '.light,[data-theme="light"]': { '--twc-primary-100': '0 100% 50%', '--twc-primary-200': '240 100% 50%', '--twc-secondary-100': '0 100% 50%', '--twc-secondary-100-opacity': '0.50', '--twc-secondary-200': '0 100% 50%', '--twc-secondary-200-opacity': '0.70', }, '.dark,[data-theme="dark"]': { '--twc-primary-100': '120 100% 50%', '--twc-primary-200': '349.5 100% 87.6%', '--twc-secondary-100': '0 100% 50%', '--twc-secondary-100-opacity': '0.60', '--twc-secondary-200': '0 100% 50%', '--twc-secondary-200-opacity': '0.80', }, }); }); test('color-scheme', () => { const { utilities } = resolveTwcConfig(({ light, dark }) => ({ light: light({ primary: { 100: 'red', 200: 'blue', }, secondary: { 100: 'rgb(255 0 0 / 0.5)', 200: 'rgb(255 0 0 / 0.7)', }, }), dark: dark({ primary: { 100: 'lime', 200: 'pink', }, secondary: { 100: 'rgb(255 0 0 / 0.6)', 200: 'rgb(255 0 0 / 0.8)', nested: { 100: 'rgb(255 0 0 / 0.9)', 200: 'rgb(255 0 0 / 0.1)', }, }, }), none: { primary: { 100: 'lime', 200: 'pink', }, secondary: { 100: 'hsl(50 10% 12% / 0.6)', 200: 'hsl(60 11% 13% / 0.8)', }, }, })); expect(utilities).toEqual({ '.light,[data-theme="light"]': { 'color-scheme': 'light', '--twc-primary-100': '0 100% 50%', '--twc-primary-200': '240 100% 50%', '--twc-secondary-100': '0 100% 50%', '--twc-secondary-100-opacity': '0.50', '--twc-secondary-200': '0 100% 50%', '--twc-secondary-200-opacity': '0.70', }, '.dark,[data-theme="dark"]': { 'color-scheme': 'dark', '--twc-primary-100': '120 100% 50%', '--twc-primary-200': '349.5 100% 87.6%', '--twc-secondary-100': '0 100% 50%', '--twc-secondary-100-opacity': '0.60', '--twc-secondary-200': '0 100% 50%', '--twc-secondary-200-opacity': '0.80', '--twc-secondary-nested-100': '0 100% 50%', '--twc-secondary-nested-100-opacity': '0.90', '--twc-secondary-nested-200': '0 100% 50%', '--twc-secondary-nested-200-opacity': '0.10', }, '.none,[data-theme="none"]': { '--twc-primary-100': '120 100% 50%', '--twc-primary-200': '349.5 100% 87.6%', '--twc-secondary-100': '50 10% 12%', '--twc-secondary-100-opacity': '0.60', '--twc-secondary-200': '60 11% 13%', '--twc-secondary-200-opacity': '0.80', }, }); }); });