# @moderneinc/biome-plugins

Biome GritQL lint plugins for enforcing Moderne design token usage in styled components.

## Plugins

| Plugin | Description |
|--------|-------------|
| `no-hardcoded-colors` | Flags hex colors — use `semanticColors.*` or `colors.*` tokens |
| `no-hardcoded-font-sizes` | Flags numeric font sizes — use `theme.typography.pxToRem()` or `typography.fontSize.*` |
| `no-hardcoded-font-weights` | Flags numeric font weights — use `typography.fontWeight.*` tokens |
| `no-hardcoded-spacing` | Flags hardcoded spacing — use `theme.spacing()` or `spacing.*` tokens |
| `no-hardcoded-shadows` | Flags hardcoded box shadows — use `shadows.*` tokens |
| `no-pxToRem-non-font` | Flags `pxToRem()` on non-fontSize properties |
| `no-hardcoded-border-radius` | Flags hardcoded border radius — use `borderRadius.*` tokens |
| `no-hardcoded-mui-classes` | Flags hardcoded `.Mui*` class selectors — use `*Classes` imports |
| `no-css-variables` | Flags `var(--)` usage — import tokens directly |

## Usage

Install the package:

```sh
npm install --save-dev @moderneinc/biome-plugins
```

Add the plugin paths to your `biome.json`. These rules are about how *source* is
written, so scope them away from your tests — see [Scoping](#scoping) below:

```json
{
  "overrides": [
    {
      "includes": ["**", "!**/tests/**"],
      "plugins": [
        "./node_modules/@moderneinc/biome-plugins/plugins/no-hardcoded-colors.grit",
        "./node_modules/@moderneinc/biome-plugins/plugins/no-hardcoded-font-sizes.grit",
        "./node_modules/@moderneinc/biome-plugins/plugins/no-hardcoded-font-weights.grit",
        "./node_modules/@moderneinc/biome-plugins/plugins/no-hardcoded-spacing.grit",
        "./node_modules/@moderneinc/biome-plugins/plugins/no-hardcoded-shadows.grit",
        "./node_modules/@moderneinc/biome-plugins/plugins/no-pxToRem-non-font.grit",
        "./node_modules/@moderneinc/biome-plugins/plugins/no-hardcoded-border-radius.grit",
        "./node_modules/@moderneinc/biome-plugins/plugins/no-hardcoded-mui-classes.grit",
        "./node_modules/@moderneinc/biome-plugins/plugins/no-css-variables.grit"
      ]
    }
  ]
}
```

## Scoping

A test asserting what a token resolves to has to spell the literal out, so
pointing these rules at a test suite turns every such assertion into an error.
Scoping the plugin list, as above, is what exempts them.

Keep the leading `"**"`. `includes` is an allowlist, so `["!**/tests/**"]` alone
matches nothing and silently disables every plugin in the list.

Per-plugin scoping works too on Biome 2.5+, if you want different globs per rule
(earlier versions reject `path` as an unknown key):

```json
{ "plugins": [{ "path": "./…/no-hardcoded-colors.grit", "includes": ["**", "!**/tests/**"] }] }
```

What does *not* work is subtracting in an override: `overrides[].plugins` adds to
the top-level list rather than replacing it, so there is no way to switch a
plugin off for a path once it is declared at the top level. For a one-off escape,
`// biome-ignore lint/plugin: reason` suppresses at a single site — note the
selector is `lint/plugin`, not the `plugin` category the diagnostic reports, and
it silences every plugin there rather than one.

## Requirements

- [Biome](https://biomejs.dev/) v2.0+ with GritQL plugin support
