Home / Function/ migrateAtLayerUtilities() — tailwindcss Function Reference

migrateAtLayerUtilities() — tailwindcss Function Reference

Architecture documentation for the migrateAtLayerUtilities() function in migrate-at-layer-utilities.ts from the tailwindcss codebase.

Entity Profile

Dependency Diagram

graph TD
  e51a3fe6_3191_e68f_1630_91cacde3ff71["migrateAtLayerUtilities()"]
  77d861d8_8b87_a313_eab0_24f31d10c887["migrate-at-layer-utilities.ts"]
  e51a3fe6_3191_e68f_1630_91cacde3ff71 -->|defined in| 77d861d8_8b87_a313_eab0_24f31d10c887
  387299a1_c1c8_f247_fb50_178f39c9b272["migrate()"]
  387299a1_c1c8_f247_fb50_178f39c9b272 -->|calls| e51a3fe6_3191_e68f_1630_91cacde3ff71
  9a38c9c3_5b83_41df_cdee_3103ff69e5e8["migrateContents()"]
  9a38c9c3_5b83_41df_cdee_3103ff69e5e8 -->|calls| e51a3fe6_3191_e68f_1630_91cacde3ff71
  b93711ba_f1f1_9f0f_a389_75e4b3358eb4["isMajor()"]
  e51a3fe6_3191_e68f_1630_91cacde3ff71 -->|calls| b93711ba_f1f1_9f0f_a389_75e4b3358eb4
  272d9ec6_74fb_0a06_d468_4c51b7ed1831["walk()"]
  e51a3fe6_3191_e68f_1630_91cacde3ff71 -->|calls| 272d9ec6_74fb_0a06_d468_4c51b7ed1831
  862e1f3f_8472_e5af_6d9d_2fa3de254d30["segment()"]
  e51a3fe6_3191_e68f_1630_91cacde3ff71 -->|calls| 862e1f3f_8472_e5af_6d9d_2fa3de254d30
  e693977b_7155_b0ce_b660_e63ed1f83938["layers()"]
  e51a3fe6_3191_e68f_1630_91cacde3ff71 -->|calls| e693977b_7155_b0ce_b660_e63ed1f83938
  ad72ccb6_0261_6760_6833_1de8b50eeffe["walkDepth()"]
  e51a3fe6_3191_e68f_1630_91cacde3ff71 -->|calls| ad72ccb6_0261_6760_6833_1de8b50eeffe
  style e51a3fe6_3191_e68f_1630_91cacde3ff71 fill:#6366f1,stroke:#818cf8,color:#fff

Relationship Graph

Source Code

packages/@tailwindcss-upgrade/src/codemods/css/migrate-at-layer-utilities.ts lines 8–318

export function migrateAtLayerUtilities(stylesheet: Stylesheet): Plugin {
  function migrate(atRule: AtRule) {
    // Migrating `@layer utilities` to `@utility` is only supported in Tailwind
    // CSS v3 projects. Tailwind CSS v4 projects could also have `@layer
    // utilities` but those aren't actual utilities.
    if (!version.isMajor(3)) return

    // Only migrate `@layer utilities` and `@layer components`.
    if (atRule.params !== 'utilities' && atRule.params !== 'components') return

    // Keep rules that should not be turned into utilities as is. This will
    // include rules with element or ID selectors.
    let defaultsAtRule = atRule.clone()

    // Clone each rule with multiple selectors into their own rule with a single
    // selector.
    walk(atRule, (node) => {
      if (node.type !== 'rule') return

      // Clone the node for each selector
      let selectors = segment(node.selector, ',')
      if (selectors.length > 1) {
        let clonedNodes: Rule[] = []
        for (let selector of selectors) {
          let clone = node.clone({ selector })
          clonedNodes.push(clone)
        }
        node.replaceWith(clonedNodes)
      }

      return WalkAction.Skip
    })

    // Track all the classes that we want to create an `@utility` for.
    let classes = new Set<string>()

    walk(atRule, (node) => {
      if (node.type !== 'rule') return

      // Find all the classes in the selector
      SelectorParser((selectors) => {
        selectors.each((selector) => {
          walk(selector, (selectorNode) => {
            // Ignore everything in `:not(…)`
            if (selectorNode.type === 'pseudo' && selectorNode.value === ':not') {
              return WalkAction.Skip
            }

            if (selectorNode.type === 'class') {
              classes.add(selectorNode.value)
            }
          })
        })
      }).processSync(node.selector, { updateSelector: false })

      return WalkAction.Skip
    })

    // Remove all the nodes from the default `@layer utilities` that we know
    // should be turned into `@utility` at-rules.
    walk(defaultsAtRule, (node) => {
      if (node.type !== 'rule') return

      SelectorParser((selectors) => {
        selectors.each((selector) => {
          walk(selector, (selectorNode) => {
            // Ignore everything in `:not(…)`
            if (selectorNode.type === 'pseudo' && selectorNode.value === ':not') {
              return WalkAction.Skip
            }

            // Remove the node if the class is in the list
            if (selectorNode.type === 'class' && classes.has(selectorNode.value)) {
              node.remove()
              return WalkAction.Stop
            }
          })
        })
      }).processSync(node, { updateSelector: true })
    })

Domain

Subdomains

Frequently Asked Questions

What does migrateAtLayerUtilities() do?
migrateAtLayerUtilities() is a function in the tailwindcss codebase, defined in packages/@tailwindcss-upgrade/src/codemods/css/migrate-at-layer-utilities.ts.
Where is migrateAtLayerUtilities() defined?
migrateAtLayerUtilities() is defined in packages/@tailwindcss-upgrade/src/codemods/css/migrate-at-layer-utilities.ts at line 8.
What does migrateAtLayerUtilities() call?
migrateAtLayerUtilities() calls 5 function(s): isMajor, layers, segment, walk, walkDepth.
What calls migrateAtLayerUtilities()?
migrateAtLayerUtilities() is called by 2 function(s): migrate, migrateContents.

Analyze Your Own Codebase

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

Try Supermodel Free