Kosmesis
Components

Switch

A toggle switch, wrapping Morphos's Switch primitive.

Installation

npx kosmesis add switch
pnpm dlx kosmesis add switch
yarn dlx kosmesis add switch
bunx kosmesis add switch

Install the following dependencies:

npm install @morphos/inputs
pnpm add @morphos/inputs
yarn add @morphos/inputs
bun add @morphos/inputs

Copy and paste the following code into your project.

switch.tsx
import { StatelessComponent } from "@praxisjs/core";import { Component } from "@praxisjs/decorators";import { Switch as MorphosSwitch, type SwitchProps as MorphosSwitchProps  } from "@morphos/inputs";import { cn } from "@/lib/utils";export type SwitchProps = MorphosSwitchProps;/** * The thumb is a plain `span` (not a Morphos part) driven purely by the `data-checked` * attribute Morphos sets on the root, so no extra JS is needed to slide it. */@Component()export class Switch extends StatelessComponent<SwitchProps> {  render() {    const { class: cls, children, ...rest } = this.props;    return (      <MorphosSwitch        class={cn(          "inline-flex h-[1.15rem] w-8 shrink-0 items-center rounded-full border border-transparent bg-input shadow-xs outline-none transition-colors focus-visible:ring-[3px] focus-visible:ring-ring/50 focus-visible:border-ring disabled:cursor-not-allowed disabled:opacity-50 data-disabled:cursor-not-allowed data-disabled:opacity-50 data-checked:bg-primary",          cls,        )}        {...rest}      >        {children}        <span          data-slot="switch-thumb"          class="pointer-events-none block size-4 translate-x-0 rounded-full bg-background shadow-xs ring-0 transition-transform in-data-checked:translate-x-[calc(100%-2px)]"        />      </MorphosSwitch>    );  }}

Install the following dependencies:

npm install @morphos/inputs @praxisjs/css
pnpm add @morphos/inputs @praxisjs/css
yarn add @morphos/inputs @praxisjs/css
bun add @morphos/inputs @praxisjs/css

Copy and paste the following code into your project.

switch.tsx
import { StatelessComponent } from "@praxisjs/core";import { cx, Stylesheet, Styled, tokenVars } from "@praxisjs/css";import { Component } from "@praxisjs/decorators";import { Switch as MorphosSwitch, type SwitchProps as MorphosSwitchProps  } from "@morphos/inputs";import { KosmesisTokens } from "@/lib/kosmesis-theme";const t = tokenVars(KosmesisTokens);class SwitchStyles extends Stylesheet {  $root = this.css({    display: "inline-flex",    height: "1.15rem",    width: "2rem",    flexShrink: 0,    alignItems: "center",    borderRadius: "9999px",    border: "1px solid transparent",    backgroundColor: t.input,    boxShadow: "0 1px 2px 0 rgb(0 0 0 / 0.05)",    outline: "none",    transition: "background-color 120ms ease",    cursor: "pointer",  })    .focusVisible({ borderColor: t.ring, boxShadow: `0 0 0 3px color-mix(in oklab, ${t.ring} 50%, transparent)` })    .disabled({ cursor: "not-allowed", opacity: 0.5 })    .on("&[data-disabled]", { cursor: "not-allowed", opacity: 0.5 })    .on("&[data-checked]", { backgroundColor: t.primary });  /** Ancestor-prefixed nested rule — the `@praxisjs/css` equivalent of Tailwind's `in-data-checked:`. */  $thumb = this.css({    display: "block",    width: "1rem",    height: "1rem",    transform: "translateX(0)",    borderRadius: "9999px",    backgroundColor: t.background,    boxShadow: "0 1px 2px 0 rgb(0 0 0 / 0.05)",    pointerEvents: "none",    transition: "transform 120ms ease",  }).on("[data-checked] &", { transform: "translateX(calc(100% - 2px))" });}export type SwitchProps = MorphosSwitchProps;/** * The thumb is a plain `span` (not a Morphos part) driven purely by the `data-checked` * attribute Morphos sets on the root, so no extra JS is needed to slide it. */@Component()export class Switch extends StatelessComponent<SwitchProps> {  @Styled(SwitchStyles) $s!: SwitchStyles;  render() {    const { class: cls, children, ...rest } = this.props;    return (      <MorphosSwitch class={cx(this.$s.$root, cls)} {...rest}>        {children}        <span data-slot="switch-thumb" class={this.$s.$thumb} />      </MorphosSwitch>    );  }}

Examples

Usage

import { Switch } from "@/components/ui/switch";
import { Label } from "@/components/ui/label";

<div class="flex items-center gap-2">
  <Switch id="airplane-mode" />
  <Label htmlFor="airplane-mode">Airplane mode</Label>
</div>

Props

Passes through to Morphos's Switchchecked, defaultChecked, disabled, name, value, onCheckedChange.

On this page