This repository has been archived by the owner on Aug 3, 2020. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 9
/
Copy pathindex.js
123 lines (99 loc) · 4.08 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
const _ = require('lodash')
const flatten = require('flat')
const plugin = require('tailwindcss/plugin')
const FLATTEN_CONFIG = { delimiter: '-', maxDepth: 2 }
const handleName = (name, className) => {
const split = name.split(`${className}-`)
const prefixedName = `${split[0]}${prefixNegativeModifiers(className, split[1])}`
return prefixedName.split('-default').join('')
}
const prefixNegativeModifiers = function(base, modifier) {
return _.startsWith(modifier, '-')
? `-${base}-${modifier.slice(1)}`
: `${base}-${modifier}`
}
function pluginFactory(spinnerConfig = {}) {
return function ({
addUtilities, addComponents, addBase, addVariant,
e, prefix, theme, variants, config,
}) {
const buildConfig = (themeKey, ...fallbackKeys) => {
return buildConfigFromTheme(themeKey, ...fallbackKeys) || buildConfigFromArray(themeKey)
}
const buildConfigFromTheme = (themeKey, ...fallbackKeys) => {
const buildObject = ([ modifier, value ]) => [ modifier, { [themeKey]: value } ]
const getThemeSettings = (themeKey, fallbackKeys) => {
const [newThemeKey, ...newFallbackKeys] = fallbackKeys || []
return theme(themeKey, false) || (fallbackKeys.length && getThemeSettings(newThemeKey, [...newFallbackKeys]))
}
const themeSettings = getThemeSettings(themeKey, fallbackKeys)
const themeObject = _.isArray(themeSettings) ? _.zipObject(themeSettings, themeSettings) : themeSettings
const themeEntries = themeSettings && Object
.entries(flatten(themeObject, FLATTEN_CONFIG))
.map(entry => buildObject(entry))
return themeSettings ? _.fromPairs(themeEntries) : false
}
const buildConfigFromArray = (property) => {
const defaultSettings = defaultValues[property]
const defaultEntries = defaultSettings && defaultSettings
.map(value => ([value, { [property]: value }]))
return defaultSettings ? _.fromPairs(defaultEntries) : false
}
const buildPluginUtilityObject = ({ color, size, border, speed }) => {
return {
'position': 'relative',
'color': 'transparent !important',
'pointer-events': 'none',
'&::after': {
'content': `''`,
'position': 'absolute !important',
'top': `calc(50% - (${size} / 2))`,
'left': `calc(50% - (${size} / 2))`,
'display': 'block',
'width': size,
'height': size,
'border': `${border} solid ${color}`,
'border-radius': '9999px',
'border-right-color': 'transparent',
'border-top-color': 'transparent',
'animation': `spinAround ${speed} infinite linear`,
},
}
}
const buildDefaultValuesObject = (defaultConfig, themeKey, ...fallbackKeys) => {
const defaultEntries = Object.entries(theme(themeKey, { default: defaultConfig }))
.map(([ modifier, config ]) => [ modifier, buildPluginUtilityObject({ ...defaultConfig, ...config }) ])
return _.fromPairs(defaultEntries)
}
const defaultValues = {}
const defaultConfig = {
color: 'currentColor',
size: '1em',
border: '2px',
speed: '500ms',
}
const baseClassName = spinnerConfig.className || 'spinner'
const themeKey = spinnerConfig.themeKey || 'spinner'
const pluginUtilities = {
[baseClassName]: buildDefaultValuesObject(defaultConfig, themeKey),
}
Object.entries(pluginUtilities)
.filter(([ modifier, values ]) => !_.isEmpty(values))
.forEach(([ modifier, values ]) => {
const className = _.kebabCase(modifier)
const variantName = Object.keys(Object.entries(values)[0][1])[0]
const utilities = flatten({ [`.${e(`${className}`)}`]: values }, FLATTEN_CONFIG)
addUtilities(
_.mapKeys(utilities, (value, key) => handleName(key, className)),
variants(variantName, ['responsive'])
)
})
addUtilities({
'@keyframes spinAround': {
'from': { 'transform': 'rotate(0deg)' },
'to': { 'transform': 'rotate(360deg)' },
},
})
}
}
module.exports = plugin.withOptions(pluginFactory)