Repository: tailwindlabs/tailwindcss
File: packages/@tailwindcss-upgrade/src/template/codemods/theme-to-var.test.ts (TypeScript)

Code before:

  // Convert the `theme(…)`, but try to move the inline modifier (e.g. `50%`),
  // to a candidate modifier.
  // Arbitrary property, with simple percentage modifier
  ['[color:theme(colors.red.500/75%)]', '[color:var(--color-red-500)]/75'],

  // Arbitrary property, with numbers (0-1) without a unit
  ['[color:theme(colors.red.500/.12)]', '[color:var(--color-red-500)]/12'],
  ['[color:theme(colors.red.500/0.12)]', '[color:var(--color-red-500)]/12'],

  // Arbitrary property, with more complex modifier (we only allow whole numbers
  // as bare modifiers). Convert the complex numbers to arbitrary values instead.
  ['[color:theme(colors.red.500/12.34%)]', '[color:var(--color-red-500)]/[12.34%]'],
  ['[color:theme(colors.red.500/var(--opacity))]', '[color:var(--color-red-500)]/[var(--opacity)]'],
  ['[color:theme(colors.red.500/.12345)]', '[color:var(--color-red-500)]/[12.345]'],
  ['[color:theme(colors.red.500/50.25%)]', '[color:var(--color-red-500)]/[50.25%]'],

  // Arbitrary value
  ['bg-[theme(colors.red.500/75%)]', 'bg-[var(--color-red-500)]/75'],
  ['bg-[theme(colors.red.500/12.34%)]', 'bg-[var(--color-red-500)]/[12.34%]'],

  // Arbitrary property that already contains a modifier
  ['[color:theme(colors.red.500/50%)]/50', '[color:theme(--color-red-500/50%)]/50'],

  // Values that don't only contain `theme(…)` calls should not be converted to
  // a candidate modifier. Because this is not a color anymore.
  [
    'shadow-[shadow:inset_0px_1px_theme(colors.white/15%)]',
    'shadow-[shadow:inset_0px_1px_theme(--color-white/15%)]',
  ],

  // Arbitrary value, where the candidate already contains a modifier
  // This should still migrate the `theme(…)` syntax to the modern syntax.
  ['bg-[theme(colors.red.500/50%)]/50', 'bg-[theme(--color-red-500/50%)]/50'],

  // Variants, we can't use `var(…)` especially inside of `@media(…)`. We can
  // still upgrade the `theme(…)` to the modern syntax.
  ['max-[theme(screens.lg)]:flex', 'max-[theme(--breakpoint-lg)]:flex'],
  // There are no variables for `--spacing` multiples, so we can't convert this
  ['max-[theme(spacing.4)]:flex', 'max-[theme(spacing.4)]:flex'],

  // This test in itself doesn't make much sense. But we need to make sure
  // that this doesn't end up as the modifier in the candidate itself.
  ['max-[theme(spacing.4/50)]:flex', 'max-[theme(spacing.4/50)]:flex'],

  // `theme(…)` calls in another CSS function is replaced correctly.
  // Additionally we remove unnecessary whitespace.
  [
    'grid-cols-[min(50%_,_theme(spacing.80))_auto]',
    'grid-cols-[min(50%,calc(var(--spacing)*80))_auto]',
  ],

Review comment (suggestion):
```suggestion
  // Values that don't contain only `theme(…)` calls should not be converted to
  // use a modifier since the color is not the whole value.
```

Code after:

  // Convert the `theme(…)`, but try to move the inline modifier (e.g. `50%`),
  // to a candidate modifier.
  // Arbitrary property, with simple percentage modifier
  ['[color:theme(colors.red.500/75%)]', '[color:var(--color-red-500)]/75'],

  // Arbitrary property, with numbers (0-1) without a unit
  ['[color:theme(colors.red.500/.12)]', '[color:var(--color-red-500)]/12'],
  ['[color:theme(colors.red.500/0.12)]', '[color:var(--color-red-500)]/12'],

  // Arbitrary property, with more complex modifier (we only allow whole numbers
  // as bare modifiers). Convert the complex numbers to arbitrary values instead.
  ['[color:theme(colors.red.500/12.34%)]', '[color:var(--color-red-500)]/[12.34%]'],
  ['[color:theme(colors.red.500/var(--opacity))]', '[color:var(--color-red-500)]/[var(--opacity)]'],
  ['[color:theme(colors.red.500/.12345)]', '[color:var(--color-red-500)]/[12.345]'],
  ['[color:theme(colors.red.500/50.25%)]', '[color:var(--color-red-500)]/[50.25%]'],

  // Arbitrary value
  ['bg-[theme(colors.red.500/75%)]', 'bg-[var(--color-red-500)]/75'],
  ['bg-[theme(colors.red.500/12.34%)]', 'bg-[var(--color-red-500)]/[12.34%]'],

  // Arbitrary property that already contains a modifier
  ['[color:theme(colors.red.500/50%)]/50', '[color:theme(--color-red-500/50%)]/50'],

  // Values that don't contain only `theme(…)` calls should not be converted to
  // use a modifier since the color is not the whole value.
  [
    'shadow-[shadow:inset_0px_1px_theme(colors.white/15%)]',
    'shadow-[shadow:inset_0px_1px_theme(--color-white/15%)]',
  ],

  // Arbitrary value, where the candidate already contains a modifier
  // This should still migrate the `theme(…)` syntax to the modern syntax.
  ['bg-[theme(colors.red.500/50%)]/50', 'bg-[theme(--color-red-500/50%)]/50'],

  // Variants, we can't use `var(…)` especially inside of `@media(…)`. We can
  // still upgrade the `theme(…)` to the modern syntax.
  ['max-[theme(screens.lg)]:flex', 'max-[theme(--breakpoint-lg)]:flex'],
  // There are no variables for `--spacing` multiples, so we can't convert this
  ['max-[theme(spacing.4)]:flex', 'max-[theme(spacing.4)]:flex'],

  // This test in itself doesn't make much sense. But we need to make sure
  // that this doesn't end up as the modifier in the candidate itself.
  ['max-[theme(spacing.4/50)]:flex', 'max-[theme(spacing.4/50)]:flex'],

  // `theme(…)` calls in another CSS function is replaced correctly.
  // Additionally we remove unnecessary whitespace.
  [
    'grid-cols-[min(50%_,_theme(spacing.80))_auto]',
    'grid-cols-[min(50%,calc(var(--spacing)*80))_auto]',
  ],