Skip to content

Instantly share code, notes, and snippets.

@danielroe
Created March 27, 2019 16:10
Show Gist options
  • Save danielroe/494270cd38fee04c1228fd522c478bba to your computer and use it in GitHub Desktop.
Save danielroe/494270cd38fee04c1228fd522c478bba to your computer and use it in GitHub Desktop.
import { Dictionary } from '@nuxt/vue-app'
import sass from 'node-sass'
const sassUtils = require('node-sass-utils')(sass)
const theme: Dictionary<string> = require('../config/colors.js')
const hexToRGBA = (hex: string) => {
if (!/^#([A-Fa-f0-9]{3}){1,2}$/.test(hex)) {
return null
}
let hexColor = hex.substring(1).split('')
if (hexColor.length === 3) {
hexColor = [
hexColor[0],
hexColor[0],
hexColor[1],
hexColor[1],
hexColor[2],
hexColor[2],
]
}
return Number(`0xff${hexColor.join('')}`)
}
const convertStringToSassDimension = (result: string) => {
// Only attempt to convert strings
if (typeof result !== 'string') {
return result
}
const cssUnits = [
'rem',
'em',
'vh',
'vw',
'vmin',
'vmax',
'ex',
'%',
'px',
'cm',
'mm',
'in',
'pt',
'pc',
'ch',
]
const parts = result.match(/[a-zA-Z]+|[0-9]+/g)
if (!parts) return
const value = parts[0]
const unit = parts[parts.length - 1]
// If the string has a unit
if (cssUnits.indexOf(unit) !== -1) {
return new sassUtils.SassDimension(parseInt(value, 10), unit)
}
// Else if the string is a hex color string, make sure we return a sass color
// to avoid errors when using darken, lighten, etc.
if (/^#([A-Fa-f0-9]{3}){1,2}$/.test(result)) {
const rgba = hexToRGBA(result)
if (rgba) return sass.types.Color(rgba)
}
return result
}
// sass-loader function to return specific theme item
export const getThemeItem = (
keys: sass.types.String | null
): sass.types.Value => {
const themeItemValue = keys
? keys
.getValue()
.split('.')
.reduce((object, item) => object[item] || {}, theme)
: theme
let returnValue
if (themeItemValue) {
if (typeof themeItemValue === 'string') {
returnValue = convertStringToSassDimension(themeItemValue)
} else if (typeof themeItemValue === 'object') {
const emptyDictionary: Dictionary<sass.types.Value> = {}
returnValue = Object.keys(themeItemValue).reduce((object, item) => {
let itemKeys = `${keys ? `${sassUtils.castToJs(keys)}.` : ''}${item}`
let sassItemKeys = sassUtils.castToSass(itemKeys) as sass.types.String
return {
...object,
[item]: getThemeItem(sassItemKeys),
}
}, emptyDictionary)
}
}
return sassUtils.castToSass(returnValue)
}
// sass-loader function to return the entire theme
export const getTheme = () => getThemeItem(null)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment