readFromCss() — tailwindcss Function Reference
Architecture documentation for the readFromCss() function in plugin-functions.ts from the tailwindcss codebase.
Entity Profile
Dependency Diagram
graph TD 57934fd1_bd18_f9cc_3777_870ee6aa0bf0["readFromCss()"] 67fcef46_defb_2c9b_ab9b_59ae912b91f5["createThemeFn()"] 67fcef46_defb_2c9b_ab9b_59ae912b91f5 -->|calls| 57934fd1_bd18_f9cc_3777_870ee6aa0bf0 fc2ae801_cb46_a61e_e1f0_f0d633f4f67e["get()"] 57934fd1_bd18_f9cc_3777_870ee6aa0bf0 -->|calls| fc2ae801_cb46_a61e_e1f0_f0d633f4f67e c8189e3c_da83_8664_ad35_d7e6af6bc483["getOptions()"] 57934fd1_bd18_f9cc_3777_870ee6aa0bf0 -->|calls| c8189e3c_da83_8664_ad35_d7e6af6bc483 f8dcf272_aab9_d786_7975_56fd563c0739["keyPathToCssProperty()"] 57934fd1_bd18_f9cc_3777_870ee6aa0bf0 -->|calls| f8dcf272_aab9_d786_7975_56fd563c0739 aa57ed8e_9804_d9ba_b480_f0584cdac61b["namespace()"] 57934fd1_bd18_f9cc_3777_870ee6aa0bf0 -->|calls| aa57ed8e_9804_d9ba_b480_f0584cdac61b acbbaf1a_ddba_e9d2_f7c6_4bfdb7a5772a["set()"] 57934fd1_bd18_f9cc_3777_870ee6aa0bf0 -->|calls| acbbaf1a_ddba_e9d2_f7c6_4bfdb7a5772a d46194d6_d268_5afb_c1d5_b75ab4689ab7["keys()"] 57934fd1_bd18_f9cc_3777_870ee6aa0bf0 -->|calls| d46194d6_d268_5afb_c1d5_b75ab4689ab7 style 57934fd1_bd18_f9cc_3777_870ee6aa0bf0 fill:#6366f1,stroke:#818cf8,color:#fff
Relationship Graph
Source Code
packages/tailwindcss/src/compat/plugin-functions.ts lines 116–220
function readFromCss(
theme: Theme,
path: string[],
):
| [value: string | null | Record<string, unknown>, options: number]
| [value: Record<string, unknown>, options: Record<string, number>] {
// `--color-red-500` should resolve to the theme variable directly, no look up
// and handling of nested objects is required.
if (path.length === 1 && path[0].startsWith('--')) {
return [theme.get([path[0] as ThemeKey]), theme.getOptions(path[0])] as const
}
type ThemeValue =
// A normal string value
| string
// A nested tuple with additional data
| [main: string, extra: Record<string, string>]
let themeKey = keyPathToCssProperty(path)
let map = new Map<string | null, ThemeValue>()
let nested = new DefaultMap<string | null, Map<string, [value: string, options: number]>>(
() => new Map(),
)
let ns = theme.namespace(`--${themeKey}`)
if (ns.size === 0) {
return [null, ThemeOptions.NONE]
}
let options = new Map()
for (let [key, value] of ns) {
// Non-nested values can be set directly
if (!key || !key.includes('--')) {
map.set(key, value)
options.set(key, theme.getOptions(!key ? `--${themeKey}` : `--${themeKey}-${key}`))
continue
}
// Nested values are stored separately
let nestedIndex = key.indexOf('--')
let mainKey = key.slice(0, nestedIndex)
let nestedKey = key.slice(nestedIndex + 2)
// Make `nestedKey` camel case:
nestedKey = nestedKey.replace(/-([a-z])/g, (_, a) => a.toUpperCase())
nested
.get(mainKey === '' ? null : mainKey)
.set(nestedKey, [value, theme.getOptions(`--${themeKey}${key}`)])
}
let baseOptions = theme.getOptions(`--${themeKey}`)
for (let [key, extra] of nested) {
let value = map.get(key)
if (typeof value !== 'string') continue
let extraObj: Record<string, string> = {}
let extraOptionsObj: Record<string, number> = {}
for (let [nestedKey, [nestedValue, nestedOptions]] of extra) {
extraObj[nestedKey] = nestedValue
extraOptionsObj[nestedKey] = nestedOptions
}
map.set(key, [value, extraObj])
options.set(key, [baseOptions, extraOptionsObj])
}
// We have to turn the map into object-like structure for v3 compatibility
let obj: Record<string, unknown> = {}
let optionsObj: Record<string, number> = {}
for (let [key, value] of map) {
set(obj, [key ?? 'DEFAULT'], value)
}
for (let [key, value] of options) {
set(optionsObj, [key ?? 'DEFAULT'], value)
}
// If the request looked like `theme('animation.DEFAULT')` it would have been
// turned into a lookup for `--animation-*` so we should extract the value for
// the `DEFAULT` key from the list of possible values. If there is no
// `DEFAULT` in the list, there is no match so return `null`.
if (path[path.length - 1] === 'DEFAULT') {
return [(obj?.DEFAULT ?? null) as any, optionsObj.DEFAULT ?? ThemeOptions.NONE] as const
}
// The request looked like `theme('animation.spin')` and was turned into a
// lookup for `--animation-spin-*` which had only one entry which means it
// should be returned directly.
if ('DEFAULT' in obj && Object.keys(obj).length === 1) {
return [obj.DEFAULT as any, optionsObj.DEFAULT ?? ThemeOptions.NONE] as const
}
// Attach the CSS values to the object for later use. This object could be
// mutated by the user so we want to keep the original CSS values around.
obj.__CSS_VALUES__ = optionsObj
return [obj, optionsObj] as const
}
Domain
Subdomains
Called By
Source
Frequently Asked Questions
What does readFromCss() do?
readFromCss() is a function in the tailwindcss codebase.
What does readFromCss() call?
readFromCss() calls 6 function(s): get, getOptions, keyPathToCssProperty, keys, namespace, set.
What calls readFromCss()?
readFromCss() is called by 1 function(s): createThemeFn.
Analyze Your Own Codebase
Get architecture documentation, dependency graphs, and domain analysis for your codebase in minutes.
Try Supermodel Free