-
-
Notifications
You must be signed in to change notification settings - Fork 184
/
createTheme.ts
66 lines (58 loc) · 1.75 KB
/
createTheme.ts
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
import dlv from 'dlv'
import { transformThemeValue, toPath } from './util/twImports'
import isObject from './util/isObject'
import type { TailwindConfig } from 'core/types'
function createTheme(
tailwindConfig: TailwindConfig
): (
dotSeparatedItem: string,
extra?: string
) => Record<string, unknown> | boolean | number {
function getConfigValue(path: string[], defaultValue?: string): unknown {
return dlv(tailwindConfig, path, defaultValue)
}
function resolveThemeValue(
path: string,
defaultValue?: string,
options = {}
): number | boolean | Record<string, unknown> {
let [pathRoot, ...subPaths] = toPath(path)
// Retain dots in spacing values, eg: `ml-[theme(spacing.0.5)]`
if (
pathRoot === 'spacing' &&
subPaths.length === 2 &&
subPaths.every(x => !Number.isNaN(Number(x)))
) {
subPaths = [subPaths.join('.')]
}
const value = getConfigValue(
path ? ['theme', pathRoot, ...subPaths] : ['theme'],
defaultValue
)
return sassifyValues(transformThemeValue(pathRoot)(value, options))
}
const out = Object.assign(
(path: string, defaultValue?: string) =>
resolveThemeValue(path, defaultValue),
{
withAlpha: (path: string, opacityValue?: string) =>
resolveThemeValue(path, undefined, { opacityValue }),
}
)
return out
}
function sassifyValues(
values: Record<string, unknown>
): Record<string, unknown> {
if (!isObject(values)) return values
const transformed: Array<[string, unknown]> = Object.entries(values).map(
([k, v]: [string, unknown]) => [
k,
(isObject(v) && sassifyValues(v)) ||
(typeof v === 'number' && String(v)) ||
v,
]
)
return Object.fromEntries(transformed)
}
export default createTheme