diff --git a/packages/config/tailwind.config.js b/packages/config/tailwind.config.js index 0377ea1ded1..fb3aac822e1 100644 --- a/packages/config/tailwind.config.js +++ b/packages/config/tailwind.config.js @@ -1,76 +1,367 @@ -/** @type {import('tailwindcss').Config} */ -module.exports = { - darkMode: ["class"], - content: [ - './pages/**/*.{ts,tsx}', - './components/**/*.{ts,tsx}', - './app/**/*.{ts,tsx}', - './src/**/*.{ts,tsx}', - ], +const ui = require('./ui.config.js') +const deepMerge = require('deepmerge') + +const color = require('./../ui/build/css/tw-extend/color') + +/** + * Generates Tailwind colors for the theme + * adds as part of the hsl value + */ +function generateTwColorClasses(globalKey, twAttributes) { + let classes = {} + Object.values(twAttributes).map((attr, i) => { + const attrKey = Object.keys(twAttributes)[i] + if (attrKey.includes(globalKey)) { + classes = { + ...classes, + [attrKey.split('-').splice(1).join('-')]: `hsl(${attr.cssVariable} / )`, + } + } + }) + /** + * mutate object into nested object for tailwind theme structure + */ + const nestedClasses = kebabToNested(classes) + // return, but nest the keys if they are kebab case named + return nestedClasses +} + +/** + * Helper to convert kebab named keys in object to nested nodes + */ +function kebabToNested(obj) { + const result = {} + for (const [key, value] of Object.entries(obj)) { + const parts = key.split('-') + let currentObj = result + for (let i = 0; i < parts.length; i++) { + const part = parts[i] + if (!currentObj[part]) { + currentObj[part] = {} + } + if (i === parts.length - 1) { + if (typeof value === 'object') { + currentObj[part] = nestObject(value) + } else { + currentObj[part] = value + } + } else { + currentObj = currentObj[part] + } + } + } + return result +} + +/** + * Main theme config + */ +const uiConfig = ui({ + mode: 'JIT', + darkMode: 'class', theme: { - container: { - center: true, - padding: "2rem", - screens: { - "2xl": "1400px", - }, - }, + /** + * Spread all theme colors and custom generated colors into theme + */ + textColor: (theme) => ({ + ...theme('colors'), + ...generateTwColorClasses('textColor', color), + }), + accentColor: (theme) => ({ + ...theme('colors'), + ...generateTwColorClasses('accentColor', color), + }), + backgroundColor: (theme) => ({ + ...theme('colors'), + ...generateTwColorClasses('backgroundColor', color), + }), + borderColor: (theme) => ({ + ...theme('colors'), + ...generateTwColorClasses('borderColor', color), + }), + boxShadowColor: (theme) => ({ + ...theme('colors'), + ...generateTwColorClasses('boxShadowColor', color), + }), + caretColor: (theme) => ({ + ...theme('colors'), + ...generateTwColorClasses('caretColor', color), + }), + divideColor: (theme) => ({ + ...theme('colors'), + ...generateTwColorClasses('divideColor', color), + }), + outlineColor: (theme) => ({ + ...theme('colors'), + ...generateTwColorClasses('outlineColor', color), + }), + placeholderColor: (theme) => ({ + ...theme('colors'), + ...generateTwColorClasses('placeholderColor', color), + }), + ringColor: (theme) => ({ + ...theme('colors'), + ...generateTwColorClasses('ringColor', color), + }), + ringOffsetColor: (theme) => ({ + ...theme('colors'), + ...generateTwColorClasses('ringOffsetColor', color), + }), + textDecorationColor: (theme) => ({ + ...theme('colors'), + ...generateTwColorClasses('textDecorationColor', color), + }), extend: { - colors: { - border: "hsl(var(--border))", - input: "hsl(var(--input))", - ring: "hsl(var(--ring))", - background: "hsl(var(--background))", - foreground: "hsl(var(--foreground))", - primary: { - DEFAULT: "hsl(var(--primary))", - foreground: "hsl(var(--primary-foreground))", + typography: ({ theme }) => ({ + // Removal of backticks in code blocks for tailwind v3.0 + // https://github.com/tailwindlabs/tailwindcss-typography/issues/135 + DEFAULT: { + css: { + 'code::before': { + content: '""', + }, + 'code::after': { + content: '""', + }, + '--tw-prose-body': theme('colors.scale[1100]'), + '--tw-prose-headings': theme('colors.scale[1200]'), + '--tw-prose-lead': theme('colors.scale[1100]'), + '--tw-prose-links': theme('colors.scale[1100]'), + '--tw-prose-bold': theme('colors.scale[1100]'), + '--tw-prose-counters': theme('colors.scale[1100]'), + '--tw-prose-bullets': theme('colors.scale[900]'), + '--tw-prose-hr': theme('colors.scale[500]'), + '--tw-prose-quotes': theme('colors.scale[1100]'), + '--tw-prose-quote-borders': theme('colors.scale[500]'), + '--tw-prose-captions': theme('colors.scale[700]'), + '--tw-prose-code': theme('colors.scale[1200]'), + '--tw-prose-pre-code': theme('colors.scale[900]'), + '--tw-prose-pre-bg': theme('colors.scale[400]'), + '--tw-prose-th-borders': theme('colors.scale[500]'), + '--tw-prose-td-borders': theme('colors.scale[200]'), + '--tw-prose-invert-body': theme('colors.scale[200]'), + '--tw-prose-invert-headings': theme('colors.white'), + '--tw-prose-invert-lead': theme('colors.scale[500]'), + '--tw-prose-invert-links': theme('colors.white'), + '--tw-prose-invert-bold': theme('colors.white'), + '--tw-prose-invert-counters': theme('colors.scale[400]'), + '--tw-prose-invert-bullets': theme('colors.scale[600]'), + '--tw-prose-invert-hr': theme('colors.scale[700]'), + '--tw-prose-invert-quotes': theme('colors.scale[100]'), + '--tw-prose-invert-quote-borders': theme('colors.scale[700]'), + '--tw-prose-invert-captions': theme('colors.scale[400]'), + // the following are typography overrides + // examples can be seen here —> https://github.com/tailwindlabs/tailwindcss-typography/blob/master/src/styles.js + // reset all header font weights + 'h1, h2, h3, h4, h5': { + fontWeight: '400', + }, + h2: { + fontWeight: '400', + }, + p: { + fontWeight: '400', + }, + pre: { + background: 'none', + padding: 0, + marginBottom: '32px', + }, + ul: { + listStyleType: 'none', + paddingLeft: '1rem', + }, + 'ul li': { + position: 'relative', + }, + 'ul li::before': { + position: 'absolute', + top: '0.75rem', + left: '-1rem', + height: '0.125rem', + width: '0.5rem', + borderRadius: '0.25rem', + backgroundColor: 'var(--colors-scale7)', + content: '""', + }, + ol: { + paddingLeft: '1rem', + counterReset: 'item', + listStyleType: 'none', + }, + 'ol li': { display: 'block', position: 'relative', paddingLeft: '1rem' }, + 'ol li::before': { + position: 'absolute', + top: '0.25rem', + left: '-1rem', + height: '1.2rem', + width: '1.2rem', + borderRadius: '0.25rem', + backgroundColor: 'var(--colors-scale3)', + border: '1px solid var(--colors-scale5)', + content: 'counter(item) " "', + counterIncrement: 'item', + fontSize: '12px', + color: 'var(--colors-scale9)', + display: 'flex', + alignItems: 'center', + justifyContent: 'center', + }, + + 'p img': { + border: '1px solid var(--colors-scale4)', + borderRadius: '4px', + overflow: 'hidden', + }, + iframe: { + border: '1px solid ' + theme('borderColor.DEFAULT'), + borderRadius: theme('borderRadius.lg'), + }, + td: { + borderBottom: '1px solid ' + theme('colors.scale[400]'), + }, + code: { + fontWeight: '400', + padding: '0.2rem 0.4rem', + backgroundColor: theme('colors.scale[400]'), + border: '1px solid ' + theme('colors.scale[500]'), + borderRadius: theme('borderRadius.lg'), + wordBreak: 'break-all', + }, + a: { + position: 'relative', + transition: 'color 0.3s ease-in-out', + paddingBottom: '2px', + fontWeight: '400', + color: 'var(--colors-scale12)', + textDecorationLine: 'underline', + textDecorationColor: 'var(--colors-brand7)', + textDecorationThickness: '1px', + textUnderlineOffset: '4px', + }, + 'a:hover': { + textDecorationColor: 'var(--colors-brand9)', + }, + figcaption: { + color: 'var(--colors-scale9)', + }, + 'figure.quote-figure p:first-child': { + marginTop: '0 !important', + }, + 'figure.quote-figure p:last-child': { + marginBottom: '0 !important', + }, + }, }, - secondary: { - DEFAULT: "hsl(var(--secondary))", - foreground: "hsl(var(--secondary-foreground))", + + toc: { + css: { + ul: { + 'list-style-type': 'none', + 'padding-left': 0, + margin: 0, + li: { + 'padding-left': 0, + }, + a: { + display: 'block', + marginBottom: '0.4rem', + 'text-decoration': 'none', + fontSize: '0.8rem', + fontWeight: '200', + color: theme('colors.scale[1100]'), + '&:hover': { + color: theme('colors.scale[1200]'), + }, + 'font-weight': '400', + }, + // margin: 0, + ul: { + 'list-style-type': 'none', + li: { + marginTop: '0.2rem', + marginBottom: '0.2rem', + 'padding-left': '0 !important', + 'margin-left': '0.5rem', + }, + a: { + fontWeight: '200', + color: theme('colors.scale[1000]'), + '&:hover': { + color: theme('colors.scale[1200]'), + }, + }, + }, + }, + }, }, - destructive: { - DEFAULT: "hsl(var(--destructive))", - foreground: "hsl(var(--destructive-foreground))", - }, - muted: { - DEFAULT: "hsl(var(--muted))", - foreground: "hsl(var(--muted-foreground))", - }, - accent: { - DEFAULT: "hsl(var(--accent))", - foreground: "hsl(var(--accent-foreground))", - }, - popover: { - DEFAULT: "hsl(var(--popover))", - foreground: "hsl(var(--popover-foreground))", - }, - card: { - DEFAULT: "hsl(var(--card))", - foreground: "hsl(var(--card-foreground))", + // used in auto docs + docs: { + css: { + '--tw-prose-body': theme('colors.scale[1100]'), + '--tw-prose-headings': theme('colors.scale[1200]'), + '--tw-prose-lead': theme('colors.scale[1100]'), + '--tw-prose-links': theme('colors.brand[900]'), + '--tw-prose-bold': theme('colors.scale[1100]'), + '--tw-prose-counters': theme('colors.scale[1100]'), + '--tw-prose-bullets': theme('colors.scale[900]'), + '--tw-prose-hr': theme('colors.scale[500]'), + '--tw-prose-quotes': theme('colors.scale[1100]'), + '--tw-prose-quote-borders': theme('colors.scale[500]'), + '--tw-prose-captions': theme('colors.scale[700]'), + '--tw-prose-code': theme('colors.scale[1200]'), + '--tw-prose-pre-code': theme('colors.scale[900]'), + '--tw-prose-pre-bg': theme('colors.scale[400]'), + '--tw-prose-th-borders': theme('colors.scale[500]'), + '--tw-prose-td-borders': theme('colors.scale[200]'), + '--tw-prose-invert-body': theme('colors.scale[200]'), + '--tw-prose-invert-headings': theme('colors.white'), + '--tw-prose-invert-lead': theme('colors.scale[500]'), + '--tw-prose-invert-links': theme('colors.white'), + '--tw-prose-invert-bold': theme('colors.white'), + '--tw-prose-invert-counters': theme('colors.scale[400]'), + '--tw-prose-invert-bullets': theme('colors.scale[600]'), + '--tw-prose-invert-hr': theme('colors.scale[700]'), + '--tw-prose-invert-quotes': theme('colors.scale[100]'), + '--tw-prose-invert-quote-borders': theme('colors.scale[700]'), + '--tw-prose-invert-captions': theme('colors.scale[400]'), + // the following are typography overrides + // examples can be seen here —> https://github.com/tailwindlabs/tailwindcss-typography/blob/master/src/styles.js + // reset all header font weights + 'h1, h2, h3, h4, h5': { + fontWeight: '400', + }, + }, }, + }), + screens: { + xs: '480px', }, - borderRadius: { - lg: "var(--radius)", - md: "calc(var(--radius) - 2px)", - sm: "calc(var(--radius) - 4px)", - }, - keyframes: { - "accordion-down": { - from: { height: 0 }, - to: { height: "var(--radix-accordion-content-height)" }, - }, - "accordion-up": { - from: { height: "var(--radix-accordion-content-height)" }, - to: { height: 0 }, - }, - }, - animation: { - "accordion-down": "accordion-down 0.2s ease-out", - "accordion-up": "accordion-up 0.2s ease-out", + fontFamily: { + sans: ['Circular', 'custom-font', 'Helvetica Neue', 'Helvetica', 'Arial', 'sans-serif'], + mono: ['Office Code Pro', 'Source Code Pro', 'Menlo', 'monospace'], }, }, }, - plugins: [require("tailwindcss-animate")], -} \ No newline at end of file + plugins: [require('@tailwindcss/typography')], +}) + +function arrayMergeFn(destinationArray, sourceArray) { + return destinationArray.concat(sourceArray).reduce((acc, cur) => { + if (acc.includes(cur)) return acc + return [...acc, cur] + }, []) +} + +/** + * Merge Supabase UI and Tailwind CSS configurations + * @param {object} tailwindConfig - Tailwind config object + * @return {object} new config object + */ +function wrapper(tailwindConfig) { + return deepMerge({ ...tailwindConfig }, uiConfig, { + arrayMerge: arrayMergeFn, + }) +} + +module.exports = wrapper diff --git a/packages/ui/components.json b/packages/ui/components.json index 3f2c79b9fc4..3e209dfd340 100644 --- a/packages/ui/components.json +++ b/packages/ui/components.json @@ -10,6 +10,6 @@ }, "aliases": { "components": "src/components/shadcn", - "utils": "@/lib/utils" + "utils": "src/lib/utils" } -} \ No newline at end of file +}