Created
March 27, 2019 16:10
-
-
Save danielroe/494270cd38fee04c1228fd522c478bba to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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