---
name: sheriff-web-components
description: >
    Assists developers using @politiet/sheriff-web-components — Lit-based custom
    elements with the sds-* prefix. Covers all 22 components (alert, button, card,
    checkbox, chip, details, dialog, heading, icon, loader, radio, select, stepper,
    switch, tag, text, textarea, textfield), React wrappers, form-associated
    elements, slots, events, and data-palette theming. Use when the user references
    sds-* components, @politiet/sheriff-web-components imports, or React wrappers.
    Do not use for CSS-only questions, icon loading configuration, or SSR/RSC usage.
---

# Sheriff Web Components

## Source File Conventions

When looking up component details not covered here, read the source directly:

-   Most components: `packages/sheriff/web-components/src/sds-{name}/sds-{name}.ts`
-   Exception components (alert, button, heading, icon, text): `packages/sheriff/web-components/src/sds-{name}/sds-{name}.component.ts`
-   Usage examples: `packages/sheriff/web-components/src/sds-{name}/sds-{name}.stories.ts`
-   Documentation: `packages/sheriff/web-components/src/sds-{name}/sds-{name}.mdx`

## Architecture

1. Components that dispatch events extend `LitElement` via `SDSEventDispatcherMixin`.
2. Properties use `@property({ reflect: true })` — settable as HTML attributes or JS properties.
3. Content distribution uses named slots (`slot="before"`, `slot="after"`) and a default slot.
4. Form-associated components implement `ElementInternals` with `formAssociated = true`.
5. Events dispatch via `dispatchSheriffEvent()` as `CustomEvent` with `bubbles: true, composed: true`.
6. Color theming uses the `data-palette` attribute (see `@politiet/sheriff-css-framework` skill for palette details).

## Prerequisites

Import the CSS framework (components depend on it for CSS custom properties):

```js
import '@politiet/sheriff-css-framework';
```

Recommended to apply `sds-reset` to the root container. Not required for components:

```html
<body class="sds-reset">
	...
</body>
```

## Register Components

Import once early at app entry point for performance. Importing a component multiple times is harmless but wasteful.

For `sds-icon` specifically, repeated imports can overwrite resolver/loader configuration.
This can cause loading bugs where the intended resolve/loader is overwritten.

Import all components:

```js
import '@politiet/sheriff-web-components';
```

Or import individually for tree-shaking:

```js
import '@politiet/sheriff-web-components/sds-button';
import '@politiet/sheriff-web-components/sds-textfield';
```

## Component Quick Reference

All components use the `sds-` prefix. Sizes are `"lg"` | `"md"` | `"sm"` (default `"md"`).

| Component            | Description                                  | Key Props                                                        |
| -------------------- | -------------------------------------------- | ---------------------------------------------------------------- |
| `sds-alert`          | Contextual alert banner                      | `variant`, `data-palette`, `removable-label`, `size`             |
| `sds-button`         | Button or link-as-button                     | `variant`, `size`, `type`, `disabled`, `loading`, `icon`, `href` |
| `sds-card`           | Content container; link card when `link` set | `link`                                                           |
| `sds-checkbox`       | Single checkbox                              | `label`, `name`, `value`, `checked`, `error`                     |
| `sds-checkbox-group` | Grouped checkboxes with legend               | `legend`, `error-message`, `help-text`                           |
| `sds-chip`           | Selectable or removable chip/pill            | `variant`, `checked`, `name`, `value`                            |
| `sds-details`        | Expandable accordion                         | `open`, `standalone`, `name` (exclusive group)                   |
| `sds-dialog`         | Modal/dialog wrapping native `<dialog>`      | `open`, `modal`, `closedby`                                      |
| `sds-heading`        | Semantic heading                             | `level`, `size`                                                  |
| `sds-icon`           | Dynamic SVG icon                             | `name`, `size`, `label`, `data-palette`                          |
| `sds-loader`         | Loading spinner                              | `size`, `contrast`                                               |
| `sds-notification`   | **Deprecated** — use `sds-alert`             | `variant`, `removable-label`                                     |
| `sds-radio`          | Single radio button                          | `label`, `name`, `value`, `checked`                              |
| `sds-radio-group`    | Grouped radios with legend                   | `legend`, `direction`, `error-message`                           |
| `sds-select`         | Dropdown select                              | `label`, `name`, `default-value`, `error-message`                |
| `sds-stepper`        | Step indicator for multi-step flows          | `orientation`                                                    |
| `sds-stepper-step`   | Individual step in stepper                   | `complete`, `interactive`, `active`                              |
| `sds-switch`         | Toggle switch                                | `label`, `name`, `checked`, `reverse`, `hide-label`              |
| `sds-tag`            | Non-interactive label/badge                  | `size`, `data-palette`                                           |
| `sds-text`           | Text container with typography               | `size`, `strong`, `tall`                                         |
| `sds-textarea`       | Multi-line text input                        | `label`, `name`, `counter`, `error-message`                      |
| `sds-textfield`      | Single-line text input                       | `label`, `name`, `type`, `error-message`                         |

For full component API (all props, slots, events, code examples), see `references/components.md`.

## React Wrappers

React versions before v19 do not natively handle web component events. Use the provided wrappers from `@politiet/sheriff-web-components/react-wrappers`:

```tsx
import { SDSButtonWrapper, SDSTextFieldWrapper } from '@politiet/sheriff-web-components/react-wrappers';

function MyForm() {
	return (
		<form>
			<SDSTextFieldWrapper label="Name" name="name" />
			<SDSButtonWrapper variant="primary" type="submit">
				Submit
			</SDSButtonWrapper>
		</form>
	);
}
```

React 19+ supports custom elements natively — can use web components directly without wrappers.

For the full list of available wrappers and event mappings, see `references/react-wrappers.md`.

## Common Patterns

### Form layout

```html
<div class="sds-stack-y-xs">
	<sds-textfield label="Name" name="name" required></sds-textfield>
	<sds-textfield label="Email" name="email" type="email" required></sds-textfield>
	<sds-textarea label="Message" name="message" rows="4"></sds-textarea>
	<div class="sds-stack-x-sm">
		<sds-button variant="secondary">Cancel</sds-button>
		<sds-button variant="primary" type="submit">Submit</sds-button>
	</div>
</div>
```

### Dialog with actions

```html
<sds-dialog modal closedby="any">
	<sds-heading level="h2" size="md" slot="header">Confirm</sds-heading>
	<sds-text>Are you sure?</sds-text>
	<div slot="footer" class="sds-stack-x-2xs">
		<sds-button size="md">Confirm</sds-button>
		<sds-button size="md" variant="secondary" data-command="close">Cancel</sds-button>
	</div>
</sds-dialog>
```

### Alert with title

```html
<sds-alert data-palette="success">
	<h2 slot="title">Success!</h2>
	<p slot="message">Your changes have been saved.</p>
</sds-alert>
```

### Danger button

```html
<sds-button variant="primary" data-palette="danger">Delete</sds-button>
```

## Error Handling

-   **Component does not render or render weird**: Verify the CSS framework is imported. This is needed for CSS custom properties.
-   **Events do not fire in React (pre-v19)**: Confirm React wrappers are used instead of web components.
-   **Icons do not load**: Check the icon name format (`{name}-{source}-{variant}`) and network access to jsDelivr CDN. If in secure/isolated network, use Artifactory. If needed, see `@politiet/sheriff-icons` for icon skill.
-   **Form values not submitted**: Ensure the component has both `name` and `value` attributes set.
