Home / Function/ readFromCss() — tailwindcss Function Reference

readFromCss() — tailwindcss Function Reference

Architecture documentation for the readFromCss() function in plugin-functions.ts from the tailwindcss codebase.

Entity Profile

Dependency Diagram

graph TD
  1176a137_5b06_095c_fa3b_a8db365b8b18["readFromCss()"]
  1ea8fd4a_634f_c2f0_5465_01d387d5207b["createThemeFn()"]
  1ea8fd4a_634f_c2f0_5465_01d387d5207b -->|calls| 1176a137_5b06_095c_fa3b_a8db365b8b18
  a0c16668_c872_21fc_296d_76c8221fee87["get()"]
  1176a137_5b06_095c_fa3b_a8db365b8b18 -->|calls| a0c16668_c872_21fc_296d_76c8221fee87
  be7a0843_7490_00b8_ff59_a27552035f10["getOptions()"]
  1176a137_5b06_095c_fa3b_a8db365b8b18 -->|calls| be7a0843_7490_00b8_ff59_a27552035f10
  971f7bc7_6ac2_a554_ba52_47038ff41b13["keyPathToCssProperty()"]
  1176a137_5b06_095c_fa3b_a8db365b8b18 -->|calls| 971f7bc7_6ac2_a554_ba52_47038ff41b13
  91679534_d150_0695_fd00_c41815eb6754["namespace()"]
  1176a137_5b06_095c_fa3b_a8db365b8b18 -->|calls| 91679534_d150_0695_fd00_c41815eb6754
  09703bc3_87d5_bb32_57b1_c6125a46ec90["set()"]
  1176a137_5b06_095c_fa3b_a8db365b8b18 -->|calls| 09703bc3_87d5_bb32_57b1_c6125a46ec90
  318e504e_be93_f95b_211e_84e3eabd9029["keys()"]
  1176a137_5b06_095c_fa3b_a8db365b8b18 -->|calls| 318e504e_be93_f95b_211e_84e3eabd9029
  style 1176a137_5b06_095c_fa3b_a8db365b8b18 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
}

Subdomains

Called By

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