From d57051c41c3ee14aa5743f4b3443af9c0b117c6d Mon Sep 17 00:00:00 2001 From: Alex Gleason Date: Wed, 23 Mar 2022 16:27:35 -0500 Subject: [PATCH] Refactor Tailwind config, add tests --- jest.config.js | 3 --- tailwind.config.js | 45 +++++++------------------------ tailwind/__tests__/colors-test.js | 35 ++++++++++++++++++++++++ tailwind/colors.js | 30 +++++++++++++++++++++ 4 files changed, 75 insertions(+), 38 deletions(-) create mode 100644 tailwind/__tests__/colors-test.js create mode 100644 tailwind/colors.js diff --git a/jest.config.js b/jest.config.js index efe164457..1f79865dc 100644 --- a/jest.config.js +++ b/jest.config.js @@ -1,7 +1,4 @@ module.exports = { - 'projects': [ - '/app/soapbox', - ], 'testPathIgnorePatterns': [ '/node_modules/', '/vendor/', diff --git a/tailwind.config.js b/tailwind.config.js index e697ea757..08fb9819d 100644 --- a/tailwind.config.js +++ b/tailwind.config.js @@ -1,37 +1,4 @@ -// https://tailwindcss.com/docs/customizing-colors#using-css-variables -function withOpacityValue(variable) { - return ({ opacityValue }) => { - if (opacityValue === undefined) { - return `rgb(var(${variable}))`; - } - return `rgb(var(${variable}) / ${opacityValue})`; - }; -} - -// Parse list of shades into Tailwind function with CSS variables -const parseShades = (color, shades) => { - return shades.reduce((obj, shade) => { - obj[shade] = withOpacityValue(`--color-${color}-${shade}`); - return obj; - }, {}); -}; - -// Parse color matrix into Tailwind colors object -const parseColors = colors => { - return Object.keys(colors).reduce((obj, color) => { - obj[color] = parseShades(color, colors[color]); - return obj; - }, {}); -}; - -// Define color matrix (of available colors) -const colors = { - gray: [50, 100, 200, 300, 400, 500, 600, 700, 800, 900], - primary: [50, 100, 200, 300, 400, 500, 600, 700, 800, 900], - success: [50, 100, 200, 300, 400, 500, 600, 700, 800, 900], - danger: [50, 100, 200, 300, 400, 500, 600, 700, 800, 900], - accent: [300, 500], -}; +const { parseColorMatrix, withOpacityValue } = require('./tailwind/colors'); module.exports = { content: ['./app/**/*.{html,js,ts,tsx}'], @@ -66,7 +33,15 @@ module.exports = { 'Noto Color Emoji', ], }, - colors: Object.assign(parseColors(colors), { + colors: Object.assign(parseColorMatrix({ + // Define color matrix (of available colors) + // Colors are configured at runtime with CSS variables in soapbox.json + gray: [50, 100, 200, 300, 400, 500, 600, 700, 800, 900], + primary: [50, 100, 200, 300, 400, 500, 600, 700, 800, 900], + success: [50, 100, 200, 300, 400, 500, 600, 700, 800, 900], + danger: [50, 100, 200, 300, 400, 500, 600, 700, 800, 900], + accent: [300, 500], + }), { 'gradient-purple': withOpacityValue('--color-gradient-purple'), 'gradient-blue': withOpacityValue('--color-gradient-blue'), 'sea-blue': withOpacityValue('--color-sea-blue'), diff --git a/tailwind/__tests__/colors-test.js b/tailwind/__tests__/colors-test.js new file mode 100644 index 000000000..6bf314bf0 --- /dev/null +++ b/tailwind/__tests__/colors-test.js @@ -0,0 +1,35 @@ +import { + withOpacityValue, + parseColorMatrix, +} from '../colors'; + +describe('withOpacityValue()', () => { + it('returns a Tailwind color function with alpha support', () => { + const result = withOpacityValue('--color-primary-500'); + + // It returns a function + expect(typeof result).toBe('function'); + + // Test calling the function + expect(result({})).toBe('rgb(var(--color-primary-500))'); + expect(result({ opacityValue: .5 })).toBe('rgb(var(--color-primary-500) / 0.5)'); + }); +}); + +describe('parseColorMatrix()', () => { + it('returns a Tailwind color object', () => { + const colorMatrix = { + gray: [50, 100, 200, 300, 400, 500, 600, 700, 800, 900], + primary: [50, 100, 200, 300, 400, 500, 600, 700, 800, 900], + success: [50, 100, 200, 300, 400, 500, 600, 700, 800, 900], + danger: [50, 100, 200, 300, 400, 500, 600, 700, 800, 900], + accent: [300, 500], + }; + + const result = parseColorMatrix(colorMatrix); + + // Colors are mapped to functions which return CSS values + expect(result.primary[500]({})).toEqual('rgb(var(--color-primary-500))'); + expect(result.accent[300]({ opacityValue: .5 })).toEqual('rgb(var(--color-accent-300) / 0.5)'); + }); +}); diff --git a/tailwind/colors.js b/tailwind/colors.js new file mode 100644 index 000000000..9fd87e6ec --- /dev/null +++ b/tailwind/colors.js @@ -0,0 +1,30 @@ +// https://tailwindcss.com/docs/customizing-colors#using-css-variables +function withOpacityValue(variable) { + return ({ opacityValue }) => { + if (opacityValue === undefined) { + return `rgb(var(${variable}))`; + } + return `rgb(var(${variable}) / ${opacityValue})`; + }; +} + +// Parse list of shades into Tailwind function with CSS variables +const parseShades = (color, shades) => { + return shades.reduce((obj, shade) => { + obj[shade] = withOpacityValue(`--color-${color}-${shade}`); + return obj; + }, {}); +}; + +// Parse color matrix into Tailwind colors object +const parseColorMatrix = colors => { + return Object.keys(colors).reduce((obj, color) => { + obj[color] = parseShades(color, colors[color]); + return obj; + }, {}); +}; + +module.exports = { + withOpacityValue, + parseColorMatrix, +};