Home / Function/ upgradeToFullPluginSupport() — tailwindcss Function Reference

upgradeToFullPluginSupport() — tailwindcss Function Reference

Architecture documentation for the upgradeToFullPluginSupport() function in apply-compat-hooks.ts from the tailwindcss codebase.

Function typescript OxideCore Scanner calls 12 called by 1

Entity Profile

Dependency Diagram

graph TD
  9056089b_151f_3027_844b_242ce55294db["upgradeToFullPluginSupport()"]
  d0cd8e91_7dbc_4e3d_f621_705d53f7a49e["applyCompatibilityHooks()"]
  d0cd8e91_7dbc_4e3d_f621_705d53f7a49e -->|calls| 9056089b_151f_3027_844b_242ce55294db
  6b5865d6_780d_1bbb_5df1_7ecca0e9b1a1["resolveConfig()"]
  9056089b_151f_3027_844b_242ce55294db -->|calls| 6b5865d6_780d_1bbb_5df1_7ecca0e9b1a1
  956ed885_5b3c_18ac_e843_dacfdbbb7845["createCompatConfig()"]
  9056089b_151f_3027_844b_242ce55294db -->|calls| 956ed885_5b3c_18ac_e843_dacfdbbb7845
  3b6a2079_7f12_42cd_ba9f_a57ecec4366d["buildPluginApi()"]
  9056089b_151f_3027_844b_242ce55294db -->|calls| 3b6a2079_7f12_42cd_ba9f_a57ecec4366d
  4b7a4cd6_9f02_0b91_8991_3889a44cd62f["resolveThemeValue()"]
  9056089b_151f_3027_844b_242ce55294db -->|calls| 4b7a4cd6_9f02_0b91_8991_3889a44cd62f
  0a0af711_c5b8_1a31_60fe_678ff9771f13["applyConfigToTheme()"]
  9056089b_151f_3027_844b_242ce55294db -->|calls| 0a0af711_c5b8_1a31_60fe_678ff9771f13
  30ad0416_ebef_28e3_eff4_e5d85df47b9a["applyKeyframesToTheme()"]
  9056089b_151f_3027_844b_242ce55294db -->|calls| 30ad0416_ebef_28e3_eff4_e5d85df47b9a
  46ffaf90_4cd7_10d3_def1_7f8106191837["registerThemeVariantOverrides()"]
  9056089b_151f_3027_844b_242ce55294db -->|calls| 46ffaf90_4cd7_10d3_def1_7f8106191837
  ad8b6949_6736_d448_c51c_07f6658ef959["registerScreensConfig()"]
  9056089b_151f_3027_844b_242ce55294db -->|calls| ad8b6949_6736_d448_c51c_07f6658ef959
  e730a60e_a8ab_64b1_3594_f7bec2a8ae1a["registerContainerCompat()"]
  9056089b_151f_3027_844b_242ce55294db -->|calls| e730a60e_a8ab_64b1_3594_f7bec2a8ae1a
  4883e410_7ef0_3846_5ee9_bba194796fa1["cssContext()"]
  9056089b_151f_3027_844b_242ce55294db -->|calls| 4883e410_7ef0_3846_5ee9_bba194796fa1
  9db2a11b_4852_e036_e394_622c7a90dd1f["styleRule()"]
  9056089b_151f_3027_844b_242ce55294db -->|calls| 9db2a11b_4852_e036_e394_622c7a90dd1f
  a32bba76_f60d_883f_1ff1_276a0bb9db9f["walk()"]
  9056089b_151f_3027_844b_242ce55294db -->|calls| a32bba76_f60d_883f_1ff1_276a0bb9db9f
  style 9056089b_151f_3027_844b_242ce55294db fill:#6366f1,stroke:#818cf8,color:#fff

Relationship Graph

Source Code

packages/tailwindcss/src/compat/apply-compat-hooks.ts lines 217–423

function upgradeToFullPluginSupport({
  designSystem,
  base,
  ast,
  sources,
  configs,
  pluginDetails,
}: {
  designSystem: DesignSystem
  base: string
  ast: AstNode[]
  sources: { base: string; pattern: string; negated: boolean }[]
  configs: {
    path: string
    base: string
    config: UserConfig
    reference: boolean
    src: SourceLocation | undefined
  }[]
  pluginDetails: {
    path: string
    base: string
    plugin: Plugin
    options: CssPluginOptions | null
    reference: boolean
    src: SourceLocation | undefined
  }[]
}) {
  let features = Features.None
  let pluginConfigs = pluginDetails.map((detail) => {
    if (!detail.options) {
      return {
        config: { plugins: [detail.plugin] },
        base: detail.base,
        reference: detail.reference,
        src: detail.src,
      }
    }

    if ('__isOptionsFunction' in detail.plugin) {
      return {
        config: { plugins: [detail.plugin(detail.options)] },
        base: detail.base,
        reference: detail.reference,
        src: detail.src,
      }
    }

    throw new Error(`The plugin "${detail.path}" does not accept options`)
  })

  let userConfig = [...pluginConfigs, ...configs]

  let { resolvedConfig } = resolveConfig(designSystem, [
    { config: createCompatConfig(designSystem.theme), base, reference: true, src: undefined },
    ...userConfig,
    { config: { plugins: [darkModePlugin] }, base, reference: true, src: undefined },
  ])
  let { resolvedConfig: resolvedUserConfig, replacedThemeKeys } = resolveConfig(
    designSystem,
    userConfig,
  )

  let pluginApiConfig = {
    designSystem,
    ast,
    resolvedConfig,
    featuresRef: {
      set current(value: number) {
        features |= value
      },
    },
  }

  let sharedPluginApi = buildPluginApi({
    ...pluginApiConfig,
    referenceMode: false,
    src: undefined,
  })

  // Replace `resolveThemeValue` with a version that is backwards compatible
  // with dot-notation but also aware of any JS theme configurations registered
  // by plugins or JS config files. This is significantly slower than just
  // upgrading dot-notation keys so we only use this version if plugins or
  // config files are actually being used. In the future we may want to optimize
  // this further by only doing this if plugins or config files _actually_
  // registered JS config objects.
  let defaultResolveThemeValue = designSystem.resolveThemeValue
  designSystem.resolveThemeValue = function resolveThemeValue(path: string, forceInline?: boolean) {
    if (path[0] === '-' && path[1] === '-') {
      return defaultResolveThemeValue(path, forceInline)
    }

    let resolvedValue = sharedPluginApi.theme(path, undefined)

    // When a tuple is returned, return the first element
    if (Array.isArray(resolvedValue) && resolvedValue.length === 2) {
      return resolvedValue[0]
    }

    // Arrays get serialized into a comma-separated lists
    else if (Array.isArray(resolvedValue)) {
      return resolvedValue.join(', ')
    }

    // If we're dealing with an object that has the `DEFAULT` key, return the
    // default value
    else if (
      typeof resolvedValue === 'object' &&
      resolvedValue !== null &&
      'DEFAULT' in resolvedValue
    ) {
      return resolvedValue.DEFAULT
    }

    // Otherwise only allow string values here, objects (and namespace maps)
    // are treated as non-resolved values for the CSS `theme()` function.
    else if (typeof resolvedValue === 'string') {
      return resolvedValue
    }
  }

  for (let { handler, reference, src } of resolvedConfig.plugins) {
    // Each plugin gets its own instance of the plugin API because nodes added
    // to the AST may need to point to the `@config` or `@plugin` that they
    // originated from
    let api = buildPluginApi({
      ...pluginApiConfig,
      referenceMode: reference ?? false,
      src,
    })

    handler(api)
  }

  // Merge the user-configured theme keys into the design system. The compat
  // config would otherwise expand into namespaces like `background-color` which
  // core utilities already read from.
  applyConfigToTheme(designSystem, resolvedUserConfig, replacedThemeKeys)
  applyKeyframesToTheme(designSystem, resolvedUserConfig)

  registerThemeVariantOverrides(resolvedUserConfig, designSystem)
  registerScreensConfig(resolvedUserConfig, designSystem)
  registerContainerCompat(resolvedUserConfig, designSystem)

  // If a prefix has already been set in CSS don't override it
  if (!designSystem.theme.prefix && resolvedConfig.prefix) {
    if (resolvedConfig.prefix.endsWith('-')) {
      resolvedConfig.prefix = resolvedConfig.prefix.slice(0, -1)

      console.warn(
        `The prefix "${resolvedConfig.prefix}" is invalid. Prefixes must be lowercase ASCII letters (a-z) only and is written as a variant before all utilities. We have fixed up the prefix for you. Remove the trailing \`-\` to silence this warning.`,
      )
    }

    if (!IS_VALID_PREFIX.test(resolvedConfig.prefix)) {
      throw new Error(
        `The prefix "${resolvedConfig.prefix}" is invalid. Prefixes must be lowercase ASCII letters (a-z) only.`,
      )
    }

    designSystem.theme.prefix = resolvedConfig.prefix
  }

  // If an important strategy has already been set in CSS don't override it
  if (!designSystem.important && resolvedConfig.important === true) {
    designSystem.important = true
  }

  if (typeof resolvedConfig.important === 'string') {
    let wrappingSelector = resolvedConfig.important

    walk(ast, (node, _ctx) => {
      if (node.kind !== 'at-rule') return
      if (node.name !== '@tailwind' || node.params !== 'utilities') return

      let ctx = cssContext(_ctx)

      // The AST node was already manually wrapped so there's nothing to do
      if (ctx.parent?.kind === 'rule' && ctx.parent.selector === wrappingSelector) {
        return WalkAction.Stop
      }

      return WalkAction.ReplaceStop(styleRule(wrappingSelector, [node]))
    })
  }

  for (let candidate of resolvedConfig.blocklist) {
    designSystem.invalidCandidates.add(candidate)
  }

  for (let file of resolvedConfig.content.files) {
    if ('raw' in file) {
      throw new Error(
        `Error in the config file/plugin/preset. The \`content\` key contains a \`raw\` entry:\n\n${JSON.stringify(file, null, 2)}\n\nThis feature is not currently supported.`,
      )
    }

    let negated = false
    if (file.pattern[0] == '!') {
      negated = true
      file.pattern = file.pattern.slice(1)
    }
    sources.push({ ...file, negated })
  }
  return features
}

Domain

Subdomains

Frequently Asked Questions

What does upgradeToFullPluginSupport() do?
upgradeToFullPluginSupport() is a function in the tailwindcss codebase.
What does upgradeToFullPluginSupport() call?
upgradeToFullPluginSupport() calls 12 function(s): applyConfigToTheme, applyKeyframesToTheme, buildPluginApi, createCompatConfig, cssContext, registerContainerCompat, registerScreensConfig, registerThemeVariantOverrides, and 4 more.
What calls upgradeToFullPluginSupport()?
upgradeToFullPluginSupport() is called by 1 function(s): applyCompatibilityHooks.

Analyze Your Own Codebase

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

Try Supermodel Free