# jb-switch

[![Published on webcomponents.org](https://img.shields.io/badge/webcomponents.org-published-blue.svg)](https://www.webcomponents.org/element/jb-switch)
[![GitHub license](https://img.shields.io/badge/license-MIT-brightgreen.svg)](https://raw.githubusercontent.com/javadbat/jb-switch/main/LICENSE)
[![NPM Version](https://img.shields.io/npm/v/jb-switch)](https://www.npmjs.com/package/jb-switch)
![GitHub Created At](https://img.shields.io/github/created-at/javadbat/jb-switch)

`jb-switch` is a form-associated boolean switch web component with captions, loading state, validation, and cancellable change flow.

- Submits `"true"` or `"false"` as a form value.
- Supports true and false captions.
- Supports loading animation.
- Supports disabled and required states.
- Dispatches cancellable `before-change` before committing a new value.
- Uses `jb-validation` for custom validation.

## When to use

Use `jb-switch` for a boolean setting that can be turned on or off. See the [basic switch demo](https://javadbat.github.io/design-system/?path=/story/components-form-elements-jbswitch--normal) for the default interaction.

Use `jb-checkbox` when the UI should look like a checkbox or when the boolean is part of a list of choices.

## Demo

- Explore the [switch examples](https://javadbat.github.io/design-system/?path=/story/components-form-elements-jbswitch--normal), including [loading behavior](https://javadbat.github.io/design-system/?path=/story/components-form-elements-jbswitch--loading-action-test), [cancellable changes](https://javadbat.github.io/design-system/?path=/story/components-form-elements-jbswitch--event-test), and [RTL captions](https://javadbat.github.io/design-system/?path=/story/components-form-elements-jbswitch--rtl).

## Using With JS Frameworks

<a href="https://github.com/javadbat/jb-switch/tree/main/react" target="_blank" rel="noopener noreferrer"><img src="https://img.shields.io/badge/React.js-jb--switch%2Freact-000.svg?logo=react&logoColor=%2361DAFB" height="30" /></a>

Other integrations: <a href="https://javadbat.github.io/design-system/?path=/docs/getting-started-framework-integration--docs#angular" target="_blank" rel="noopener noreferrer">Angular</a> · <a href="https://javadbat.github.io/design-system/?path=/docs/getting-started-framework-integration--docs#vue" target="_blank" rel="noopener noreferrer">Vue</a> · <a href="https://javadbat.github.io/design-system/?path=/docs/getting-started-framework-integration--docs#nuxt" target="_blank" rel="noopener noreferrer">Nuxt</a> · <a href="https://javadbat.github.io/design-system/?path=/docs/getting-started-framework-integration--docs#svelte" target="_blank" rel="noopener noreferrer">Svelte</a> · <a href="https://javadbat.github.io/design-system/?path=/docs/getting-started-framework-integration--docs#sveltekit" target="_blank" rel="noopener noreferrer">SvelteKit</a> · <a href="https://javadbat.github.io/design-system/?path=/docs/getting-started-framework-integration--docs#solidjs" target="_blank" rel="noopener noreferrer">SolidJS</a> · <a href="https://javadbat.github.io/design-system/?path=/docs/getting-started-framework-integration--docs#lit" target="_blank" rel="noopener noreferrer">Lit</a> · <a href="https://javadbat.github.io/design-system/?path=/docs/getting-started-framework-integration--docs#nextjs" target="_blank" rel="noopener noreferrer">Next.js</a> · <a href="https://javadbat.github.io/design-system/?path=/docs/getting-started-framework-integration--docs#astro" target="_blank" rel="noopener noreferrer">Astro</a> · <a href="https://javadbat.github.io/design-system/?path=/docs/getting-started-framework-integration--docs#blazor" target="_blank" rel="noopener noreferrer">Blazor</a> · <a href="https://javadbat.github.io/design-system/?path=/docs/getting-started-framework-integration--docs#server-rendered-templates" target="_blank" rel="noopener noreferrer">Server-rendered templates</a> · <a href="https://javadbat.github.io/design-system/?path=/docs/getting-started-framework-integration--docs#wordpress" target="_blank" rel="noopener noreferrer">WordPress</a> · <a href="https://javadbat.github.io/design-system/?path=/docs/getting-started-framework-integration--docs#alpinejs-and-htmx" target="_blank" rel="noopener noreferrer">Alpine.js and HTMX</a>

## Installation

```sh
npm i jb-switch
```

```js
import 'jb-switch';
```

```html
<jb-switch name="enabled" true-title="Enabled" false-title="Disabled"></jb-switch>
```

## API reference

### Attributes

| name | type | default | description |
| --- | --- | --- | --- |
| `value` | `boolean` | `false` | Switch value. Only `"true"` means true; see the [value demo](https://javadbat.github.io/design-system/?path=/story/components-form-elements-jbswitch--normal). |
| `name` | `string` | `""` | Form field name. |
| `true-title` | `string` | `""` | Caption shown on the true side; see [RTL captions](https://javadbat.github.io/design-system/?path=/story/components-form-elements-jbswitch--rtl). |
| `false-title` | `string` | `""` | Caption shown on the false side; see [RTL captions](https://javadbat.github.io/design-system/?path=/story/components-form-elements-jbswitch--rtl). |
| `disabled` | `boolean` | `false` | Disables user interaction. Empty attribute and `"true"` mean true. |
| `loading` | `boolean` | `false` | Shows loading animation. Empty attribute and `"true"` mean true; see the [loading demo](https://javadbat.github.io/design-system/?path=/story/components-form-elements-jbswitch--loading-action-test). |
| `required` | `boolean` | `false` | Requires the value to be true for validation. Empty attribute and `"true"` mean true; see [validation](https://javadbat.github.io/design-system/?path=/story/components-form-elements-jbswitch--event-test). |

### Properties

| name | type | readonly | description |
| --- | --- | --- | --- |
| `value` | `boolean` | no | Current boolean value; see [initial and controlled values](https://javadbat.github.io/design-system/?path=/story/components-form-elements-jbswitch--initial-value). |
| `isLoading` | `boolean` | no | Shows or hides loading animation; see the [loading action demo](https://javadbat.github.io/design-system/?path=/story/components-form-elements-jbswitch--loading-action-test). |
| `disabled` | `boolean` | no | Enables or disables user interaction. |
| `required` | `boolean` | no | Requires the value to be true for validation; see [validation](https://javadbat.github.io/design-system/?path=/story/components-form-elements-jbswitch--event-test). |
| `validation` | `ValidationHelper<boolean>` | yes | Validation helper from `jb-validation`; set `validation.list` for custom rules. |
| `form` | `HTMLFormElement \| null` | yes | Associated form from `ElementInternals`. |
| `name` | `string` | yes | Form field name from the `name` attribute. |
| `initialValue` | `boolean` | no | Default and reset value. It initializes `value` until the live value is explicitly set; see [initial value](https://javadbat.github.io/design-system/?path=/story/components-form-elements-jbswitch--initial-value). |
| `isDirty` | `boolean` | yes | `true` when current value differs from `initialValue`. |
| `validationMessage` | `string` | yes | Current validation message from `ElementInternals`. |

### Methods

| name | returns | description |
| --- | --- | --- |
| `checkValidity()` | `boolean` | Runs validation without showing an error message; see the [event/validation demo](https://javadbat.github.io/design-system/?path=/story/components-form-elements-jbswitch--event-test). |
| `reportValidity()` | `boolean` | Runs validation and requests visible error handling; see [required validation](https://javadbat.github.io/design-system/?path=/story/components-form-elements-jbswitch--event-test). |
| `focus()` | `void` | Public focus method placeholder. Keyboard focus management is not currently implemented. |
| `clearValidationError()` | `void` | Placeholder for clearing visible validation error UI. |

### Events

| event | cancelable | description |
| --- | --- | --- |
| `load` | no | Dispatched from `connectedCallback` before initialization; see the [event demo](https://javadbat.github.io/design-system/?path=/story/components-form-elements-jbswitch--event-test). |
| `init` | no | Dispatched from `connectedCallback` after initialization; see the [event demo](https://javadbat.github.io/design-system/?path=/story/components-form-elements-jbswitch--event-test). |
| `before-change` | yes | Dispatched before committing a user-triggered value change. Call `preventDefault()` to cancel; see [cancellable changes](https://javadbat.github.io/design-system/?path=/story/components-form-elements-jbswitch--event-test). |
| `change` | yes | Dispatched after value changes. Call `preventDefault()` to revert the committed change; see [cancellable changes](https://javadbat.github.io/design-system/?path=/story/components-form-elements-jbswitch--event-test). |

## Value

Use the boolean `value` property for runtime updates; see the [normal value demo](https://javadbat.github.io/design-system/?path=/story/components-form-elements-jbswitch--normal), [initial value/reset flow](https://javadbat.github.io/design-system/?path=/story/components-form-elements-jbswitch--initial-value), and [controlled value precedence](https://javadbat.github.io/design-system/?path=/story/components-form-elements-jbswitch--initial-value-does-not-override-value).

```js
const switchEl = document.querySelector('jb-switch');

console.log(switchEl.value);
switchEl.value = true;
```

```html
<jb-switch value="true"></jb-switch>
<jb-switch value="false"></jb-switch>
```

Only `value="true"` sets the value to true. `value="false"`, an empty value, or a missing value sets it to false.

## Cancellable change

Use `before-change` to reject a toggle before it commits, or cancel `change` to revert it. The [event demo](https://javadbat.github.io/design-system/?path=/story/components-form-elements-jbswitch--event-test) covers both paths.

During `before-change`, `event.target.value` returns the intended next value.

```js
const switchEl = document.querySelector('jb-switch');

switchEl.addEventListener('before-change', (event) => {
  if (event.target.value === true && !canEnable()) {
    event.preventDefault();
  }
});
```

`change` is also cancelable. If you call `preventDefault()` on `change`, the component reverts the value.

## Loading state

Set `loading` in HTML or `isLoading` in JavaScript while an async save is running; see the [loading action demo](https://javadbat.github.io/design-system/?path=/story/components-form-elements-jbswitch--loading-action-test).

```html
<jb-switch loading></jb-switch>
```

```js
const switchEl = document.querySelector('jb-switch');

switchEl.isLoading = true;
switchEl.isLoading = false;
```

## Captions and RTL

Use `true-title` and `false-title` to explain both states. The [RTL demo](https://javadbat.github.io/design-system/?path=/story/components-form-elements-jbswitch--rtl) shows captions in a right-to-left layout.

## Validation

Use `required` when the switch must be true and `validation.list` for custom rules; see the [validation and events demo](https://javadbat.github.io/design-system/?path=/story/components-form-elements-jbswitch--event-test).

```html
<jb-switch required></jb-switch>
```

Use `validation.list` for custom validation rules. For advanced validators, see [`jb-validation`](https://github.com/javadbat/jb-validation).

```js
const switchEl = document.querySelector('jb-switch');

switchEl.validation.list = [
  {
    validator: (value) => value === true,
    message: 'Switch must be enabled',
  },
];
```

## CSS parts and variables

For complete styling guidance, live examples, official parts, custom states, and copyable style recipes, see [Styling](https://javadbat.github.io/design-system/?path=/docs/components-form-elements-jbswitch-styling) and the [style gallery](https://javadbat.github.io/design-system/?path=/story/components-form-elements-jbswitch-style--gallery).

```css
jb-switch {
  --jb-switch-bg-color-active: green;
  --jb-switch-ring-color-active: green;
}
```

## Accessibility notes

- The component attaches `ElementInternals` and sets role to `switch` where supported. See the [basic switch demo](https://javadbat.github.io/design-system/?path=/story/components-form-elements-jbswitch--normal) for the rendered control.
- Keyboard control and focus behavior are not currently implemented.
- Use clear captions or surrounding label text so users know what setting the switch controls.

## Related Docs

- See [`jb-switch/react`](https://github.com/javadbat/jb-switch/tree/main/react) if you want to use this component in React.
- See [`jb-validation`](https://github.com/javadbat/jb-validation) for validation rules.
- See [All JB Design System Component List](https://javadbat.github.io/design-system/) for more components.
- Use [Contribution Guide](https://github.com/javadbat/design-system/blob/main/docs/contribution-guide.md) if you want to contribute to this component.

## AI agent notes

- Import `jb-switch` once before using `<jb-switch>`.
- Use `value="true"` in HTML for true; `value="false"` is false.
- Use the `value` property for programmatic boolean updates.
- Use `isLoading` in JavaScript and `loading` in HTML.
- Listen to `before-change` to validate or confirm before committing.
- Listen to `change` for committed value changes.
- This package includes [`custom-elements.json`](./custom-elements.json) and points to it with the package.json `customElements` field. The field is documented by the Custom Elements Manifest project in [Referencing manifests from npm packages](https://github.com/webcomponents/custom-elements-manifest#referencing-manifests-from-npm-packages).
- In `custom-elements.json`, `exports.kind: "js"` describes JavaScript/TypeScript exports and `exports.kind: "custom-element-definition"` maps the `jb-switch` tag name to `JBSwitchWebComponent`.
