Home / Function/ parseVariant() — tailwindcss Function Reference

parseVariant() — tailwindcss Function Reference

Architecture documentation for the parseVariant() function in candidate.ts from the tailwindcss codebase.

Entity Profile

Dependency Diagram

graph TD
  7ba77268_84c7_7083_8f22_251a4a791d25["parseVariant()"]
  669e6a28_c71f_3c5e_9c53_915cede7da78["candidate.ts"]
  7ba77268_84c7_7083_8f22_251a4a791d25 -->|defined in| 669e6a28_c71f_3c5e_9c53_915cede7da78
  bc19ae8d_4f83_e280_be05_e35eee14b3e7["migrateArbitraryVariants()"]
  bc19ae8d_4f83_e280_be05_e35eee14b3e7 -->|calls| 7ba77268_84c7_7083_8f22_251a4a791d25
  9f73b711_0f71_129f_7fdb_764a3c0df282["migrateModernizeArbitraryValues()"]
  9f73b711_0f71_129f_7fdb_764a3c0df282 -->|calls| 7ba77268_84c7_7083_8f22_251a4a791d25
  d4b90da0_01b5_b21d_ff05_b37798744576["parseCandidate()"]
  d4b90da0_01b5_b21d_ff05_b37798744576 -->|calls| 7ba77268_84c7_7083_8f22_251a4a791d25
  33cdfd56_8951_3531_38f7_dd0b0f31dbab["arbitraryVariants()"]
  33cdfd56_8951_3531_38f7_dd0b0f31dbab -->|calls| 7ba77268_84c7_7083_8f22_251a4a791d25
  8097972e_4628_663f_72e8_08883183690d["modernizeArbitraryValuesVariant()"]
  8097972e_4628_663f_72e8_08883183690d -->|calls| 7ba77268_84c7_7083_8f22_251a4a791d25
  9b965fd7_d8e9_0b43_cd5d_c9294ab598ed["buildDesignSystem()"]
  9b965fd7_d8e9_0b43_cd5d_c9294ab598ed -->|calls| 7ba77268_84c7_7083_8f22_251a4a791d25
  0ec6110b_085e_e69b_cc4a_37d966dc5ace["substituteAtVariant()"]
  0ec6110b_085e_e69b_cc4a_37d966dc5ace -->|calls| 7ba77268_84c7_7083_8f22_251a4a791d25
  2e1adb5d_9a16_16d9_9e0d_e7ef80a3ec69["decodeArbitraryValue()"]
  7ba77268_84c7_7083_8f22_251a4a791d25 -->|calls| 2e1adb5d_9a16_16d9_9e0d_e7ef80a3ec69
  872c3879_82c7_fd6e_ce14_258e27bc4877["isValidArbitrary()"]
  7ba77268_84c7_7083_8f22_251a4a791d25 -->|calls| 872c3879_82c7_fd6e_ce14_258e27bc4877
  f712ed47_45d4_4e5a_dd73_fdefa1da71da["segment()"]
  7ba77268_84c7_7083_8f22_251a4a791d25 -->|calls| f712ed47_45d4_4e5a_dd73_fdefa1da71da
  2cc1f17b_e38e_b87e_1ea3_47b971c81bf9["findRoots()"]
  7ba77268_84c7_7083_8f22_251a4a791d25 -->|calls| 2cc1f17b_e38e_b87e_1ea3_47b971c81bf9
  0cad61e7_3577_6e5c_a58f_e653598f37ea["parseModifier()"]
  7ba77268_84c7_7083_8f22_251a4a791d25 -->|calls| 0cad61e7_3577_6e5c_a58f_e653598f37ea
  style 7ba77268_84c7_7083_8f22_251a4a791d25 fill:#6366f1,stroke:#818cf8,color:#fff

Relationship Graph

Source Code

packages/tailwindcss/src/candidate.ts lines 661–849

export function parseVariant(variant: string, designSystem: DesignSystem): Variant | null {
  // Arbitrary variants
  if (variant[0] === '[' && variant[variant.length - 1] === ']') {
    /**
     * TODO: Breaking change
     *
     * @deprecated Arbitrary variants containing at-rules with other selectors
     * are deprecated. Use stacked variants instead.
     *
     * Before:
     *  - `[@media(width>=123px){&:hover}]:`
     *
     * After:
     *  - `[@media(width>=123px)]:[&:hover]:`
     *  - `[@media(width>=123px)]:hover:`
     */
    if (variant[1] === '@' && variant.includes('&')) return null

    let selector = decodeArbitraryValue(variant.slice(1, -1))

    // Values can't contain `;` or `}` characters at the top-level.
    if (!isValidArbitrary(selector)) return null

    // Empty arbitrary values are invalid. E.g.: `[]:`
    //                                            ^^
    if (selector.length === 0 || selector.trim().length === 0) return null

    let relative = selector[0] === '>' || selector[0] === '+' || selector[0] === '~'

    // Ensure `&` is always present by wrapping the selector in `&:is(…)`,
    // unless it's a relative selector like `> img`.
    //
    // E.g.:
    //
    // - `[p]:flex`
    if (!relative && selector[0] !== '@' && !selector.includes('&')) {
      selector = `&:is(${selector})`
    }

    return {
      kind: 'arbitrary',
      selector,
      relative,
    }
  }

  // Static, functional and compound variants
  {
    // group-hover/group-name
    // ^^^^^^^^^^^            -> Variant without modifier
    //             ^^^^^^^^^^ -> Modifier
    let [variantWithoutModifier, modifier = null, additionalModifier] = segment(variant, '/')

    // If there's more than one modifier, the variant is invalid.
    //
    // E.g.:
    //
    // - `group-hover/foo/bar`
    if (additionalModifier) return null

    let roots = findRoots(variantWithoutModifier, (root) => {
      return designSystem.variants.has(root)
    })

    for (let [root, value] of roots) {
      switch (designSystem.variants.kind(root)) {
        case 'static': {
          // Static variants do not have a value
          if (value !== null) return null

          // Static variants do not have a modifier
          if (modifier !== null) return null

          return {
            kind: 'static',
            root,
          }
        }

        case 'functional': {
          let parsedModifier = modifier === null ? null : parseModifier(modifier)

Domain

Subdomains

Frequently Asked Questions

What does parseVariant() do?
parseVariant() is a function in the tailwindcss codebase, defined in packages/tailwindcss/src/candidate.ts.
Where is parseVariant() defined?
parseVariant() is defined in packages/tailwindcss/src/candidate.ts at line 661.
What does parseVariant() call?
parseVariant() calls 5 function(s): decodeArbitraryValue, findRoots, isValidArbitrary, parseModifier, segment.
What calls parseVariant()?
parseVariant() is called by 7 function(s): arbitraryVariants, buildDesignSystem, migrateArbitraryVariants, migrateModernizeArbitraryValues, modernizeArbitraryValuesVariant, parseCandidate, substituteAtVariant.

Analyze Your Own Codebase

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

Try Supermodel Free