Files
supabase/packages/config/ui.config.js
Terry Sutton 723b188cec Chore/fix code padding (#29399)
Address the indecency of the unbalanced padding on code blocks
2024-09-19 16:03:25 -02:30

434 lines
13 KiB
JavaScript

const deepMerge = require('deepmerge')
const forms = require('@tailwindcss/forms')
const radixUiColors = require('@radix-ui/colors')
const brandColors = require('./default-colors')
const svgToDataUri = require('mini-svg-data-uri')
const { default: flattenColorPalette } = require('tailwindcss/lib/util/flattenColorPalette')
// exclude these colors from the included set from Radix
const excludedRadixColors = [
'bronze',
'brown',
'cyan',
'grass',
'olive',
'mauve',
'mint',
'lime',
'plum',
'sage',
'sand',
'sky',
'teal',
]
// generates fixed scales
// based on the root/light mode version
const fixedOptions = ['scale', 'scaleA']
function radixColorKeys() {
let keys = Object.keys(radixUiColors)
/**
* Filter array items based on search criteria (query)
*/
function filterItems(arr, query) {
return arr.filter(function (el) {
return el.toLowerCase().indexOf(query.toLowerCase()) == -1
})
}
keys = filterItems(keys, 'Dark')
// remove excluded colors
keys = keys.filter(
(key) => !excludedRadixColors.some((excludeColor) => key.startsWith(excludeColor))
)
return keys
}
function generateColorClasses() {
const brandColors = ['scale', 'scaleA']
const colors = [...radixColorKeys(), ...brandColors]
let mappedColors = {}
// generate the shape of the colors object
colors.map((x) => {
// create empty obj for each color
mappedColors[x] = {}
// create empty obj for each fixed color
if (fixedOptions.some((v) => x.indexOf(v) >= 0)) {
mappedColors[`${x}-fixed`] = {}
}
})
colors.map((x) => {
for (let index = 0; index < 12; index++) {
const step = index + 1
mappedColors[x][step * 100] = `var(--colors-${x}${step})`
if (fixedOptions.some((v) => x.indexOf(v) >= 0)) {
mappedColors[`${x}-fixed`][step * 100] = `var(--colors-fixed-${x}${step})`
}
}
})
return mappedColors
}
const colorClasses = generateColorClasses()
// generate the CSS variables for tailwind to use
function generateCssVariables() {
// potential options
// { fixedOptions, brandColors }
let rootColors = {}
let darkColors = {}
const radixArray = Object.entries(radixUiColors)
.filter(
([key, value]) => !excludedRadixColors.some((excludeColor) => key.startsWith(excludeColor))
)
.map(([, value]) => value)
const brandArray = Object.values(brandColors)
function generateColors(colors, index, colorSet) {
const key = Object.keys(colorSet)[index]
if (key.includes('Dark')) {
darkColors = { ...darkColors, ...colors }
} else {
rootColors = { ...rootColors, ...colors }
// generate an optional 'fixed' scale of colors
if (
fixedOptions.some(function (v) {
return key.indexOf(v) >= 0
})
) {
rootColors.fixed = { ...rootColors?.fixed, ...colors }
}
}
}
radixArray.map((x, i) => {
generateColors(x, i, radixUiColors)
})
brandArray.map((x, i) => {
generateColors(x, i, brandColors)
})
return {
root: { ...rootColors },
dark: { ...darkColors },
}
}
const variables = generateCssVariables()
const uiConfig = {
theme: {
variables: {
DEFAULT: {
width: {
listbox: '320px',
},
colors: { ...variables.root },
},
"[data-theme*='dark']": {
colors: { ...variables.dark },
},
},
extend: {
// dropdown extensions
transformOrigin: {
// tailwind class for this is `origin-dropdown`
dropdown: 'var(--radix-dropdown-menu-content-transform-origin)',
popover: 'var(--radix-popover-menu-content-transform-origin);',
},
width: {
listbox: 'var(--width-listbox);',
},
keyframes: {
fadeIn: {
'0%': { transform: 'scale(0.95)', opacity: 0 },
'100%': { transform: 'scale(1)', opacity: 1 },
},
fadeOut: {
'0%': { transform: 'scale(1)', opacity: 1 },
'100%': { transform: 'scale(0.95)', opacity: 0 },
},
overlayContentShow: {
'0%': { opacity: 0, transform: 'translate(0%, -2%) scale(1)' },
'100%': { opacity: 1, transform: 'translate(0%, 0%) scale(1)' },
},
overlayContentHide: {
'0%': { opacity: 1, transform: 'translate(0%, 0%) scale(1)' },
'100%': { opacity: 0, transform: 'translate(0%, -2%) scale(1)' },
},
dropdownFadeIn: {
'0%': { transform: 'scale(0.95)', opacity: 0 },
'100%': { transform: 'scale(1)', opacity: 1 },
},
dropdownFadeOut: {
'0%': { transform: 'scale(1)', opacity: 1 },
'100%': { transform: 'scale(0.95)', opacity: 0 },
},
fadeInOverlayBg: {
'0%': { opacity: 0 },
'100%': { opacity: 0.75 },
},
fadeOutOverlayBg: {
'0%': { opacity: 0.75 },
'100%': { opacity: 0 },
},
slideDown: {
'0%': { height: 0, opacity: 0 },
'100%': {
height: 'var(--radix-accordion-content-height)',
opacity: 1,
},
},
slideUp: {
'0%': { height: 'var(--radix-accordion-content-height)', opacity: 1 },
'100%': { height: 0, opacity: 0 },
},
slideDownNormal: {
'0%': { height: 0, opacity: 0 },
'100%': {
height: 'inherit',
opacity: 1,
},
},
slideUpNormal: {
'0%': { height: 'inherit', opacity: 1 },
'100%': { height: 0, opacity: 0 },
},
panelSlideLeftOut: {
'0%': { transform: 'translateX(-100%)', opacity: 0 },
'100%': {
transform: 'translate-x-0',
opacity: 1,
},
},
panelSlideLeftIn: {
'0%': { transform: 'translate-x-0', opacity: 1 },
'100%': { transform: 'translateX(-100%)', opacity: 0 },
},
panelSlideRightOut: {
'0%': { transform: 'translateX(100%)', opacity: 0 },
'100%': {
transform: 'translate-x-0',
opacity: 1,
},
},
panelSlideRightIn: {
'0%': { transform: 'translate-x-0', opacity: 1 },
'100%': { transform: 'translateX(100%)', opacity: 0 },
},
lineLoading: {
'0%': {
marginLeft: '-10%',
width: '80px',
},
'25%': {
width: ' 240px',
},
'50%': {
marginLeft: '100%',
width: '80px',
},
'75%': {
width: '240px',
},
'100%': {
marginLeft: '-10%',
width: '80px',
},
},
},
animation: {
'fade-in': 'fadeIn 300ms both',
'fade-out': 'fadeOut 300ms both',
'dropdown-content-show': 'overlayContentShow 100ms cubic-bezier(0.16, 1, 0.3, 1)',
'dropdown-content-hide': 'overlayContentHide 100ms cubic-bezier(0.16, 1, 0.3, 1)',
'overlay-show': 'overlayContentShow 300ms cubic-bezier(0.16, 1, 0.3, 1)',
'overlay-hide': 'overlayContentHide 300ms cubic-bezier(0.16, 1, 0.3, 1)',
'fade-in-overlay-bg': 'fadeInOverlayBg 300ms',
'fade-out-overlay-bg': 'fadeOutOverlayBg 300ms',
'slide-down': 'slideDown 300ms cubic-bezier(0.87, 0, 0.13, 1)',
'slide-up': 'slideUp 300ms cubic-bezier(0.87, 0, 0.13, 1)',
'slide-down-normal': 'slideDownNormal 300ms cubic-bezier(0.87, 0, 0.13, 1)',
'slide-up-normal': 'slideUpNormal 300ms cubic-bezier(0.87, 0, 0.13, 1)',
'panel-slide-left-out': 'panelSlideLeftOut 200ms cubic-bezier(0.87, 0, 0.13, 1)',
'panel-slide-left-in': 'panelSlideLeftIn 250ms cubic-bezier(0.87, 0, 0.13, 1)',
'panel-slide-right-out': 'panelSlideRightOut 200ms cubic-bezier(0.87, 0, 0.13, 1)',
'panel-slide-right-in': 'panelSlideRightIn 250ms cubic-bezier(0.87, 0, 0.13, 1)',
'line-loading': 'lineLoading 1.8s infinite',
'line-loading-slower': 'lineLoading 2.3s infinite',
// tailwind class for this is `animate-dropdownFadeIn`
dropdownFadeIn: 'dropdownFadeIn 0.1s ease-out',
// tailwind class for this is `animate-dropdownFadeOut`
dropdownFadeOut: 'dropdownFadeOut 0.1s ease-out',
},
colors: {
...colorClasses,
'hi-contrast': `hsl(var(--foreground-default))`,
'lo-contrast': `hsl(var(--background-alternative-default))`,
warning: {
default: 'red',
100: '#342355',
},
},
},
},
plugins: [
require('@mertasan/tailwindcss-variables'),
function ({ addUtilities, addVariant }) {
// addVariant('data-open', '&:[data-state=open]')
addUtilities({
'.line-loading-bg': {
background: 'rgb(0, 0, 0)',
background:
'linear-gradient(90deg,rgba(0, 0, 0, 0) 0%,rgba(255, 255, 255, 0.65) 50%,rgba(0, 0, 0, 0) 100%)',
},
'.line-loading-bg-light': {
background: 'rgb(0, 0, 0)',
background:
'linear-gradient(90deg,rgba(0, 0, 0, 0) 0%,rgba(33, 33, 33, 0.65) 50%,rgba(0, 0, 0, 0) 100%)',
},
".dropdown-content[data-state='open']": {
animation: 'fadeIn 50ms ease-out',
},
".dropdown-content[data-state='closed']": {
animation: 'fadeOut 50ms ease-in',
},
// "[data-state='open'] .accordion-content-animation": {
// animation: 'slideDown 200ms ease-out',
// }
// "[data-state='closed'] .accordion-content-animation": {
// animation: 'slideUp 200ms ease-in',
// },
'.text-code': {
margin: '0 0.2em',
padding: '0.05em 0.4em 0.05em',
background: 'hsla(0, 0%, 58.8%, 0.1)',
border: '1px solid hsla(0, 0%, 39.2%, 0.2)',
borderRadius: '3px',
},
'.no-scrollbar': {
/* Hide scrollbar for IE, Edge*/
'-ms-overflow-style': 'none',
/* Firefox */
'scrollbar-width': 'none' /* Firefox */,
/* Hide scrollbar for Chrome, Safari and Opera */
'&::-webkit-scrollbar': {
display: 'none',
},
},
/* Add fadeout effect */
'.mask-fadeout-right': {
'-webkit-mask-image': 'linear-gradient(to right, white 98%, transparent 100%)',
'mask-image': 'linear-gradient(to right, white 98%, transparent 100%)',
},
'.mask-fadeout-left': {
'-webkit-mask-image': 'linear-gradient(to left, white 98%, transparent 100%)',
'mask-image': 'linear-gradient(to left, white 98%, transparent 100%)',
},
'input[type="number"]::-webkit-outer-spin-button, input[type="number"]::-webkit-inner-spin-button':
{
'-webkit-appearance': 'none',
margin: '0',
},
})
addVariant('data-open-parent', '[data-state="open"] &')
addVariant('data-closed-parent', '[data-state="closed"] &')
addVariant('data-open', '&[data-state="open"]')
addVariant('data-closed', '&[data-state="closed"]')
addVariant('data-show', '&[data-state="show"]')
addVariant('data-hide', '&[data-state="hide"]')
addVariant('data-checked', '&[data-state="checked"]')
addVariant('data-unchecked', '&[data-state="unchecked"]')
addVariant('aria-expanded', '&[aria-expanded="true"]')
// addVariant('parent-data-open', '[data-state="open"]&')
},
function ({ matchUtilities, theme }) {
matchUtilities(
{
highlight: (value) => ({ boxShadow: `inset 0 1px 0 0 ${value}` }),
},
{ values: flattenColorPalette(theme('backgroundColor')), type: 'color' }
)
matchUtilities(
{
subhighlight: (value) => ({
boxShadow: `inset 0 -1px 0 0 ${value}`,
}),
},
{
values: flattenColorPalette(theme('backgroundColor')),
type: 'color',
}
)
matchUtilities(
{
'bg-grid': (value) => ({
backgroundImage: `url("${svgToDataUri(
`<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32" width="32" height="32" fill="none" stroke="${value}"><path d="M0 .5H31.5V32"/></svg>`
)}")`,
}),
},
{ values: flattenColorPalette(theme('backgroundColor')), type: 'color' }
)
},
require('tailwindcss-radix')(),
forms,
],
}
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) {
let purge
if (Array.isArray(tailwindConfig.purge)) {
purge = {
content: tailwindConfig.purge,
}
} else {
purge = tailwindConfig.purge
}
return deepMerge({ ...tailwindConfig, purge }, uiConfig, {
arrayMerge: arrayMergeFn,
})
}
module.exports = wrapper