Skip to content
kerfjsGitHub

Toggle

A button that stays pressed, like Bold in an editor.

SourcePackage @kerf-js/veneerTry it

Preview

tsx
import { state } from '@kerf-js/core'import { Row, Toggle } from '@kerf-js/veneer'export function Toolbar() {  const bold = state(true)  const italic = state(false)  const code = state(false)  return (    <Row gap="tight">      <Toggle        pressed={bold.value}        onClick={() => (bold.value = !bold.value)}      >        Bold      </Toggle>      <Toggle        pressed={italic.value}        onClick={() => (italic.value = !italic.value)}      >        Italic      </Toggle>      <Toggle        pressed={code.value}        onClick={() => (code.value = !code.value)}      >        Code      </Toggle>    </Row>  )}

Installation

npm install @kerf-js/veneer

Try it

Change the controls: the preview and its code update together. The address keeps what you set, so you can link to it.

Live preview
Controls
Size
Codeupdates as you change the controls
import { Toggle } from '@kerf-js/veneer'<Toggle pressed>Bold</Toggle>

Usage

tsx
import { Toggle } from '@kerf-js/veneer'<Toggle>Bold</Toggle>

Sizes

Use size to pick sm, md or lg.

tsx
import { state } from '@kerf-js/core'import { Toggle } from '@kerf-js/veneer'export function Sizes() {  const small = state(true)  const medium = state(true)  const large = state(true)  return (    <>      <Toggle        size="sm"        pressed={small.value}        onClick={() => (small.value = !small.value)}      >        Bold      </Toggle>      <Toggle        pressed={medium.value}        onClick={() => (medium.value = !medium.value)}      >        Bold      </Toggle>      <Toggle        size="lg"        pressed={large.value}        onClick={() => (large.value = !large.value)}      >        Bold      </Toggle>    </>  )}

Icon only

Pass label for the accessible name.

tsx
import { state } from '@kerf-js/core'import { Toggle } from '@kerf-js/veneer'export function IconOnly() {  const pinned = state(true)  return (    <Toggle      icon="pin"      label="Pin this project"      pressed={pinned.value}      onClick={() => (pinned.value = !pinned.value)}    />  )}

Watch a project

Use pressed to show whether the project is being watched, and flip it in onClick.

tsx
import { state } from '@kerf-js/core'import { Row, Stack, Text, Toggle } from '@kerf-js/veneer'export function Watch() {  const watching = state(false)  return (    <Row      justify="between"      gap="group"    >      <Stack gap="hair">        <Text role="heading">storefront</Text>        <Text subtle>          {watching.value            ? 'You get a note on every deploy.'            : 'No notes from this project.'}        </Text>      </Stack>      <Toggle        size="sm"        icon="bell"        pressed={watching.value}        onClick={() => (watching.value = !watching.value)}      >        Watch      </Toggle>    </Row>  )}

When to use

Use it for

  • One setting that is on or off and acts straight away
  • A row of independent formatting options

Reach for something else

  • Switch, when it is a setting in a form or a list
  • Segmented, when exactly one of several is on

Accessibility

Enter
Toggles
Space
Toggles
  • pressed sets aria-pressed, so the state is announced. Keep the label the same in both states.

API Reference

PropTypeDefaultDescription
pressedboolean—Whether it is on. You own this value.
iconIconRef—An icon name from @kerf-js/veneer-icons, or a component.
labelstring—Its accessible name. Fields show it; icon-only controls speak it.
size"sm" | "md" | "lg"'md'Control size. md by default.
childrenunknown—What it contains.
EventTypeDefaultDescription
onClick((e: MouseEvent) => void)—Called when pressed.
onPointerEnter((e: PointerEvent) => void)—Called as the pointer comes over the button.

Parts

Every element carries a stable name, so you can style it from your own CSS: [data-scope="toggle"] [data-part="sweep"]

sweep

RelatedButtonSwitchChip