Home / Function/ createThemeFn() — tailwindcss Function Reference

createThemeFn() — tailwindcss Function Reference

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

Function typescript OxideCore Scanner calls 8 called by 2

Entity Profile

Dependency Diagram

graph TD
  67fcef46_defb_2c9b_ab9b_59ae912b91f5["createThemeFn()"]
  4a84e1ef_30b3_afde_8b94_8682bdf64dc7["mergeTheme()"]
  4a84e1ef_30b3_afde_8b94_8682bdf64dc7 -->|calls| 67fcef46_defb_2c9b_ab9b_59ae912b91f5
  3b6a2079_7f12_42cd_ba9f_a57ecec4366d["buildPluginApi()"]
  3b6a2079_7f12_42cd_ba9f_a57ecec4366d -->|calls| 67fcef46_defb_2c9b_ab9b_59ae912b91f5
  16014564_86ad_a5a3_1531_579a4693b33c["toKeyPath()"]
  67fcef46_defb_2c9b_ab9b_59ae912b91f5 -->|calls| 16014564_86ad_a5a3_1531_579a4693b33c
  57934fd1_bd18_f9cc_3777_870ee6aa0bf0["readFromCss()"]
  67fcef46_defb_2c9b_ab9b_59ae912b91f5 -->|calls| 57934fd1_bd18_f9cc_3777_870ee6aa0bf0
  f8828bcc_a9b4_73c4_863d_9b59d159d819["resolveValue()"]
  67fcef46_defb_2c9b_ab9b_59ae912b91f5 -->|calls| f8828bcc_a9b4_73c4_863d_9b59d159d819
  fc2ae801_cb46_a61e_e1f0_f0d633f4f67e["get()"]
  67fcef46_defb_2c9b_ab9b_59ae912b91f5 -->|calls| fc2ae801_cb46_a61e_e1f0_f0d633f4f67e
  6496e14a_c764_9611_76f5_9db2d4cacd3b["deepMerge()"]
  67fcef46_defb_2c9b_ab9b_59ae912b91f5 -->|calls| 6496e14a_c764_9611_76f5_9db2d4cacd3b
  34b0044c_2d6b_fc6e_9b23_05c422d2c036["unescape()"]
  67fcef46_defb_2c9b_ab9b_59ae912b91f5 -->|calls| 34b0044c_2d6b_fc6e_9b23_05c422d2c036
  d46194d6_d268_5afb_c1d5_b75ab4689ab7["keys()"]
  67fcef46_defb_2c9b_ab9b_59ae912b91f5 -->|calls| d46194d6_d268_5afb_c1d5_b75ab4689ab7
  8412278d_9a59_ef02_8a3b_9c8e8ab65674["withAlpha()"]
  67fcef46_defb_2c9b_ab9b_59ae912b91f5 -->|calls| 8412278d_9a59_ef02_8a3b_9c8e8ab65674
  style 67fcef46_defb_2c9b_ab9b_59ae912b91f5 fill:#6366f1,stroke:#818cf8,color:#fff

Relationship Graph

Source Code

packages/tailwindcss/src/compat/plugin-functions.ts lines 11–114

export function createThemeFn(
  designSystem: DesignSystem,
  configTheme: () => UserConfig['theme'],
  resolveValue: (value: any) => any,
) {
  return function theme(path: string, defaultValue?: unknown) {
    // Extract an eventual modifier from the path. e.g.:
    // - "colors.red.500 / 50%" -> "50%"
    // - "foo/bar/baz/50%"      -> "50%"
    let lastSlash = path.lastIndexOf('/')
    let modifier: string | null = null
    if (lastSlash !== -1) {
      modifier = path.slice(lastSlash + 1).trim()
      path = path.slice(0, lastSlash).trim()
    }

    let resolvedValue = (() => {
      let keypath = toKeyPath(path)
      let [cssValue, options] = readFromCss(designSystem.theme, keypath)

      let configValue = resolveValue(get(configTheme() ?? {}, keypath) ?? null)

      if (typeof configValue === 'string') {
        configValue = configValue.replace('<alpha-value>', '1')
      }

      // Resolved to a primitive value.
      if (typeof cssValue !== 'object') {
        if (typeof options !== 'object' && options & ThemeOptions.DEFAULT) {
          return configValue ?? cssValue
        }

        return cssValue
      }

      if (configValue !== null && typeof configValue === 'object' && !Array.isArray(configValue)) {
        let configValueCopy: Record<string, unknown> & { __CSS_VALUES__?: Record<string, number> } =
          // We want to make sure that we don't mutate the original config
          // value. Ideally we use `structuredClone` here, but it's not possible
          // because it can contain functions.
          deepMerge({}, [configValue], (_, b) => b)

        // There is no `cssValue`, which means we can back-fill it with values
        // from the `configValue`.
        if (cssValue === null && Object.hasOwn(configValue, '__CSS_VALUES__')) {
          let localCssValue: Record<string, unknown> = {}
          for (let key in configValue.__CSS_VALUES__) {
            localCssValue[key] = configValue[key]
            delete configValueCopy[key]
          }
          cssValue = localCssValue
        }

        for (let key in cssValue) {
          if (key === '__CSS_VALUES__') continue

          // If the value is coming from a default source (`@theme default`),
          // then we keep the value from the JS config (which is also a
          // default source, but wins over the built-in defaults).
          if (
            configValue?.__CSS_VALUES__?.[key] & ThemeOptions.DEFAULT &&
            get(configValueCopy, key.split('-')) !== undefined
          ) {
            continue
          }

          // CSS values from `@theme` win over values from the config
          configValueCopy[unescape(key)] = cssValue[key]
        }

        return configValueCopy
      }

      // Handle the tuple case
      if (Array.isArray(cssValue) && Array.isArray(options) && Array.isArray(configValue)) {
        let base = cssValue[0]
        let extra = cssValue[1]

        // Values from the config overwrite any default values from the CSS theme
        if (options[0] & ThemeOptions.DEFAULT) {
          base = configValue[0] ?? base
        }

        for (let key of Object.keys(extra)) {
          if (options[1][key] & ThemeOptions.DEFAULT) {
            extra[key] = configValue[1][key] ?? extra[key]
          }
        }

        return [base, extra]
      }

      // Values from CSS take precedence over values from the config
      return cssValue ?? configValue
    })()

    // Apply the opacity modifier if present
    if (modifier && typeof resolvedValue === 'string') {
      resolvedValue = withAlpha(resolvedValue, modifier)
    }

    return resolvedValue ?? defaultValue
  }
}

Domain

Subdomains

Frequently Asked Questions

What does createThemeFn() do?
createThemeFn() is a function in the tailwindcss codebase.
What does createThemeFn() call?
createThemeFn() calls 8 function(s): deepMerge, get, keys, readFromCss, resolveValue, toKeyPath, unescape, withAlpha.
What calls createThemeFn()?
createThemeFn() is called by 2 function(s): buildPluginApi, mergeTheme.

Analyze Your Own Codebase

Get architecture documentation, dependency graphs, and domain analysis for your codebase in minutes.

Try Supermodel Free