# elm-chadcn

Reusable Elm implementations of [shadcn/ui](https://ui.shadcn.com/) components.
They render ordinary Elm `Html` and preserve the shadcn Base UI DOM structure,
accessibility attributes, variants, sizes, and Nova defaults where those
concepts apply. Their configuration and state APIs are idiomatic Elm rather
than direct ports of the React APIs.

The package implements a subset of the shadcn component registry rather than a
complete set. To request a missing component, open an issue rather than a pull
request.

## Use

Install the package from the Elm package registry:

```console
elm install mbr/elm-chadcn
```

Import components through the `ChadCn` namespace:

```elm
import ChadCn.Button as Button
import Html exposing (text)


saveButton =
    Button.new [ text "Save" ]
        |> Button.withVariant Button.Default
        |> Button.withOnClick Save
        |> Button.view
```

Stateless components generally expose `new`, `withX`, and `view`. Stateful
components additionally expose opaque models, messages, update functions, and
subscriptions where needed.

### Styling

Components emit Tailwind CSS 4.3 utilities using semantic theme tokens.
Tailwind must scan the package's `src/ChadCn` directory in addition to the
consumer's sources. The exact path depends on whether the package source is
installed under `ELM_HOME`, supplied by Nix, or vendored locally. Components
also use the named data-attribute variants from `shadcn/tailwind.css`. For a
checkout of this repository, the required imports and source are:

```css
@import "tailwindcss";
@import "shadcn/tailwind.css";
@source "../elm-chadcn/src/ChadCn";
```

The `shadcn/tailwind.css` import requires the `shadcn` npm package. Consumers
that do not use that package may instead define equivalent `data-open`,
`data-selected`, `data-disabled`, `data-active`, `data-horizontal`, and
`data-vertical` custom variants.

The repository follows the [shadcn theme convention](https://ui.shadcn.com/docs/theming)
but does not provide concrete theme values. Use the
[shadcn theme creator](https://ui.shadcn.com/create) to generate a palette and
its light and dark token values. A consuming stylesheet must provide the
following configuration:

- Register class-based dark mode with
  `@custom-variant dark (&:is(.dark *));`.
- Under `@theme inline`, map the semantic colors `background`, `foreground`,
  `card`, `card-foreground`, `popover`, `popover-foreground`, `primary`,
  `primary-foreground`, `secondary`, `secondary-foreground`, `muted`,
  `muted-foreground`, `accent`, `accent-foreground`, `destructive`, `border`,
  `input`, `ring`, `sidebar`, `sidebar-foreground`, `sidebar-accent`,
  `sidebar-accent-foreground`, `sidebar-border`, and `sidebar-ring`. Each mapping
  has the form `--color-primary: var(--primary);`.
- Define those source color variables under both `:root` and `.dark`.
- Define `--radius` and expose `--radius-sm` through `--radius-4xl` under
  `@theme inline`, following the shadcn radius scale.
- Define the `--font-heading` Tailwind theme token. Components otherwise inherit
  the consumer's normal font configuration.
- Define `--sidebar-width: 16rem` and `--sidebar-width-icon: 3rem` for
  `ChadCn.Sidebar`, or override those Nova defaults with application-specific
  widths.
- Apply the conventional base styles `border-border outline-ring/50` to `*` and
  `bg-background text-foreground` to `body`.

The full conventional shadcn scaffold additionally defines `chart-1` through
`chart-5`, plus `sidebar-primary` and `sidebar-primary-foreground`. Current
ChadCn components do not consume those tokens, but defining them keeps a theme
compatible with the wider shadcn ecosystem.

## Development

Enter the Nix development environment with `direnv allow`, then run all package,
unit, and headless-browser checks with:

```console
./check.sh
```

The checks validate formatting and generated package documentation, run the Elm
unit tests, compile the browser fixture, and compare its interactions with the
checked-in Chromium baseline. Run formatting after the checks pass:

```console
./format.sh
```

`nix build` runs the reproducible package build and non-browser checks used by
CI. CI runs the browser checks from the pinned development environment because
Chromium cannot run reliably inside a Nix build sandbox.

## License

elm-chadcn is distributed under the [MIT license](LICENSE). It incorporates
material from shadcn/ui, Base UI, and Lucide under compatible permissive
licenses; see [the third-party notices](THIRD_PARTY_NOTICES.md).

This is an independent project and is not affiliated with or endorsed by those
projects.
