# no-unnecessary-arbitrary-value

oxlint rule that replaces a Tailwind CSS arbitrary value with the named class that emits the same
CSS in your theme, like `w-[100%]` → `w-full`.

## At a glance

| Autofix | Editor suggestions | Design system           | Options      |
| ------- | ------------------ | ----------------------- | ------------ |
| Yes     | Yes                | Required (`entryPoint`) | `entryPoint` |

## What this rule does

Detects utilities written with an arbitrary value (`w-[200px]`, `h-[auto]`,
`bg-[var(--color-red-500)]`) where the design system already exposes a named utility that produces
the exact same CSS, and rewrites the arbitrary form to the named one. The lookup goes through the
precomputed `arbitraryEquivalents` map (built once per `@theme` — for every named utility, the
precompute step enumerates every dash split point so multi-segment utilities like `bg-red-500`
register both `bg-[<value>]` and `bg-red-[<value>]`). Auto-fix lands on the first hit, suggestions
cover the rest in the same string. Variants and `!` (important) are preserved.

The check fires only when an arbitrary value is present in the utility (`hasArbitraryValue(cls)` is
true) AND the cache returns a `getNamedEquivalent` match. That keeps the rule cheap and focused — no
fuzzy resolution, no DS round-trip per class.

DS-dependent — requires `settings.tailwindcss.entryPoint`. If the design system can't load, the rule
emits a single fatal `designSystemUnavailable` diagnostic per file instead of silently passing.

## Options

This rule has no per-rule options beyond the standard `entryPoint` override (string, defaults to
`settings.tailwindcss.entryPoint`). Configure the entry point in `settings.tailwindcss.entryPoint`
for the whole project instead of per-rule whenever possible.

## Examples

### ✗ Incorrect

```tsx
// `h-[auto]` is just `h-auto`
<div className="h-[auto] w-[auto]" />
// → <div className="h-auto w-auto" />

// var() reference to a theme color that has a named utility
<div className="bg-[var(--color-red-500)] text-[var(--color-blue-700)]" />
// → <div className="bg-red-500 text-blue-700" />

// Variant prefix and important are preserved
<div className="hover:h-[auto] !w-[auto]" />
// → <div className="hover:h-auto !w-auto" />
```

### ✓ Correct

```tsx
// Named utilities produce the same CSS
<div className="h-auto w-auto" />

<div className="bg-red-500 text-blue-700" />

<div className="hover:h-auto !w-auto" />

// Arbitrary value with no named equivalent — leave it
<div className="w-[200px] bg-[#custom]" />
```

## Interactions with other rules

- **`enforce-canonical`**: complementary, no double-fire. Both act only when the arbitrary form and
  its named replacement emit **identical** CSS. This rule owns the direct arbitrary→named case
  (`h-[auto]` → `h-auto`, `bg-[var(--color-red-500)]` → `bg-red-500`); `enforce-canonical` owns the
  canonicalizations where the arbitrary maps to a differently-named utility
  (`rounded-[var(--radius-sm)]` → `rounded-sm`). The two carve up the arbitrary→named space cleanly
  — and the plain `[var(--x)]` ↔ `(--x)` syntax swap is `enforce-consistent-variable-syntax`'s, not
  either of theirs.
- **`prefer-scale-token`**: owns what neither of the above touches — a value that is only
  _numerically_ equal to a scale step or theme token (`p-[2px]` → `p-0.5`), whose CSS text differs
  (`calc(var(--spacing) * 0.5)` vs `2px`). Report-only, off by default.
- **`prefer-theme-tokens`**: also complementary. It fires for CSS-var references in the
  `prefix-(--name)` / `prefix-[var(--name)]` paren shorthand when no bracket-equivalent exists —
  that's the heuristic- only case this rule explicitly rejects (see the `getNamedEquivalent` guard).
- **`no-deprecated-classes`**: orthogonal. Deprecated names like `flex-grow` don't have arbitrary
  values, so the two rules never touch the same class.

## When to disable it

- **You intentionally keep arbitrary values for readability** — some teams prefer `w-[200px]` to a
  token alias when the value is one-off or pixel-precise. Disable the rule and rely on
  `prefer-theme-tokens` + `enforce-canonical` for the cases you do want flagged.
- **Migrating from a different tooling chain** that produced arbitrary values for everything — run
  as `warn` until cleanup is complete, then bump to `error`.
