@hperchec/scorpion-ui-template-default
Version:
Scorpion UI - Default template
223 lines (216 loc) • 6.82 kB
JavaScript
// Lodash kebabcase
const kebabcase = require('lodash.kebabcase')
// Tailwind colors
const tailwindColors = require('tailwindcss/colors')
// Tailwind plugins
const multiThemePlugin = require('@hperchec/tailwindcss-multi-theme')
// Utils
const { generateColorVariants, flattenColors, getThemeIdentifier, getThemeVariants } = require('./utils')
const defaultColors = {
transparent: 'transparent',
current: 'currentColor',
black: { DEFAULT: tailwindColors.black },
white: { DEFAULT: tailwindColors.white },
gray: { ...tailwindColors.gray, DEFAULT: tailwindColors.gray['500'] }
}
// Tailwind config
const defaultConfig = {
// Disable dark mode -> theme management is provided by multi-theme plugin in this project
darkMode: false,
// Theme
theme: {
// Themes for multi-theme plugin
themeVariants: [], // empty by default, will be set in genConfig
// Theme colors (will be set in genConfig)
colors: defaultColors,
// Theme breakpoints
screens: {}, // empty by default, will be set in genConfig
// Theme 'fill' classes (will be set in genConfig)
fill: defaultColors,
// Theme extending
extend: {
borderRadius: {
dropdownOpen: '9999px 9999px 0'
},
width: {
'300-p': '300px'
},
boxShadow: {
DEFAULT: '0 0 10px 0 rgba(0, 0, 0, 0.3)',
inner: 'inset 0 0 10px 0 rgba(0, 0, 0, 0.3)'
},
height: {
'600-px': '600px'
},
minHeight: {
10: '2.5rem',
20: '5rem',
'500px': '500px',
'screen-custom': 'calc(100vh - 72px)',
'mobile-custom': 'calc(100vh - 119px)'
},
margin: {
'1/2-screen': '50vh',
7: '27px'
},
transitionDuration: {
0: '0ms'
}
},
container: {
center: true,
padding: {
DEFAULT: '0',
sm: '0',
lg: '0',
xl: '0'
}
}
},
variants: {
extend: {
divideColor: [
'group-hover'
],
backgroundColor: [
'hover',
'focus',
'disabled',
'@light',
'@light:hover',
'@light:focus',
'@dark',
'@dark:hover',
'@dark:focus'
],
textColor: [
'hover',
'focus',
'disabled',
'@light',
'@light:hover',
'@light:focus',
'@dark',
'@dark:hover',
'@dark:focus'
],
boxShadow: [
'active',
'hover',
'focus'
],
borderColor: [
'hover',
'focus',
'@light',
'@light:hover',
'@light:focus',
'@dark',
'@dark:hover',
'@dark:focus'
],
borderWidth: [
'hover'
],
fontWeight: [
'hover'
],
opacity: [
'disabled'
],
pointerEvents: [
'disabled'
],
fill: [
'hover',
'focus',
'@light',
'@light:hover',
'@light:focus',
'@dark',
'@dark:hover',
'@dark:focus'
]
}
},
container: {
center: true,
padding: {
default: '1rem',
sm: '1rem',
lg: '1rem',
xl: '5rem'
}
},
plugins: [
// Multi-theme plugin
multiThemePlugin({
themeClassPrefix: '' // Default: 'theme-'
})
]
}
/**
* Deep merge default config with config passed by parameter
* @param {Object} config - The custom config
* @param {Object} [options] - The options object
* @param {string} [options.themePrefix] - Option to pass to `getThemeIdentifier` util as *prefix*
* @param {Function} [options.nameFormatter] - Option to pass to `getThemeIdentifier` util as *format*. It will be also used to generate color identifiers.
* @param {Object} [options.globals = undefined] - See globals file documentation
* @param {boolean} [options.generateColorVariants = true] - Defines if it generates theme color variants.
* See also `generateColorVariants` util documentation
* @param {boolean} [options.flattenColors = true] - Defines if it must flatten colors. See also `flattenColors` util documentation
* @return {Object}
*/
function genConfig (config, options = {}) {
// Check if globals are provided
if (options.globals !== undefined) {
// Process theme variants
if (options.globals.THEMES === undefined) throw new Error('Tailwind util "genConfig": options.globals is provided but "THEMES" property is undefined')
defaultConfig.theme.themeVariants = defaultConfig.theme.themeVariants.concat(getThemeVariants(options.globals.THEMES, {
prefix: options.themePrefix,
format: options.nameFormatter
}))
// Process breakpoints
if (options.globals.BREAKPOINTS === undefined) throw new Error('Tailwind util "genConfig": options.globals is provided but "BREAKPOINTS" property is undefined')
for (const identifier in options.globals.BREAKPOINTS) {
// Transform identifier to lowercase (ex: '2XL' => '2xl')
defaultConfig.theme.screens[identifier.toLowerCase()] = options.globals.BREAKPOINTS[identifier]
}
// Inject theme colors
for (const themeKey in options.globals.THEMES) {
const themeColors = options.globals.THEMES[themeKey]
for (const colorKey in themeColors) {
// Get color identifier (ex: theme: 'LIGHT', color: 'PRIMARY' => '@light-primary')
const prefix = options.themePrefix || '@' // default: '@'
const formatter = options.nameFormatter || kebabcase // default: kebabcase
// Get theme identifier without prefix
const colorIdentifier = prefix + formatter(getThemeIdentifier(themeKey, { prefix: '' }) + '-' + colorKey)
const colorValue = themeColors[colorKey]
// Generate color variants
if (options.generateColorVariants) {
const colorVariants = generateColorVariants(colorIdentifier, colorValue)
Object.assign(defaultConfig.theme.colors, colorVariants)
Object.assign(defaultConfig.theme.fill, colorVariants)
} else {
defaultConfig.theme.colors[colorIdentifier] = colorValue
defaultConfig.theme.fill[colorIdentifier] = colorValue
}
}
}
}
if (options.flattenColors) {
defaultConfig.theme.colors = flattenColors(defaultConfig.theme.colors)
defaultConfig.theme.fill = flattenColors(defaultConfig.theme.fill)
}
const resolvedConfig = {
...config,
presets: config.presets
? [ defaultConfig, ...config.presets ]
: [ defaultConfig ]
}
return resolvedConfig
}
module.exports = {
defaultConfig,
genConfig
}