Kosmesis
Components

Toggle

A two-state toggle button, wrapping Morphos's Toggle primitive.

Installation

npx kosmesis add toggle
pnpm dlx kosmesis add toggle
yarn dlx kosmesis add toggle
bunx kosmesis add toggle

Install the following dependencies:

npm install @morphos/inputs class-variance-authority
pnpm add @morphos/inputs class-variance-authority
yarn add @morphos/inputs class-variance-authority
bun add @morphos/inputs class-variance-authority

Copy and paste the following code into your project.

toggle.tsx
import { cva, type VariantProps } from "class-variance-authority";import { StatelessComponent } from "@praxisjs/core";import { Component } from "@praxisjs/decorators";import { Toggle as MorphosToggle, type ToggleProps as MorphosToggleProps  } from "@morphos/inputs";import { cn } from "@/lib/utils";export const toggleVariants = cva(  "inline-flex items-center justify-center gap-2 rounded-md text-sm font-medium outline-none transition-colors hover:bg-muted hover:text-muted-foreground disabled:pointer-events-none disabled:opacity-50 data-disabled:pointer-events-none data-disabled:opacity-50 data-pressed:bg-accent data-pressed:text-accent-foreground focus-visible:ring-[3px] focus-visible:ring-ring/50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",  {    variants: {      variant: {        default: "bg-transparent",        outline: "border border-input bg-transparent shadow-xs hover:bg-accent hover:text-accent-foreground",      },      size: {        default: "h-9 min-w-9 px-2",        sm: "h-8 min-w-8 px-1.5",        lg: "h-10 min-w-10 px-2.5",      },    },    defaultVariants: {      variant: "default",      size: "default",    },  },);export interface ToggleProps extends MorphosToggleProps, VariantProps<typeof toggleVariants> {}@Component()export class Toggle extends StatelessComponent<ToggleProps> {  render() {    const { variant, size, class: cls, ...rest } = this.props;    return <MorphosToggle class={cn(toggleVariants({ variant, size }), cls)} {...rest} />;  }}

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.

toggle.tsx
import { StatelessComponent } from "@praxisjs/core";import { cx, Stylesheet, Styled, tokenVars } from "@praxisjs/css";import { Component } from "@praxisjs/decorators";import { Toggle as MorphosToggle, type ToggleProps as MorphosToggleProps  } from "@morphos/inputs";import { KosmesisTokens } from "@/lib/kosmesis-theme";const t = tokenVars(KosmesisTokens);/** Exported so `toggle-group.tsx` can reuse the exact same scoped classes via its own `@Styled(ToggleStyles)` field. */export class ToggleStyles extends Stylesheet {  $root = this.css({    display: "inline-flex",    alignItems: "center",    justifyContent: "center",    gap: "0.5rem",    borderRadius: `calc(${t.radius} - 2px)`,    fontSize: "0.875rem",    fontWeight: 500,    outline: "none",    transition: "background-color 120ms ease, color 120ms ease",  })    .hover({ backgroundColor: t.muted, color: t.mutedForeground })    .disabled({ pointerEvents: "none", opacity: 0.5 })    .on("&[data-disabled]", { pointerEvents: "none", opacity: 0.5 })    .on("&[data-pressed]", { backgroundColor: t.accent, color: t.accentForeground })    .focusVisible({ boxShadow: `0 0 0 3px color-mix(in oklab, ${t.ring} 50%, transparent)` })    .on("& svg", { pointerEvents: "none", flexShrink: 0, width: "1rem", height: "1rem" });  $variantDefault = this.css({ backgroundColor: "transparent" });  $variantOutline = this.css({ border: `1px solid ${t.input}`, backgroundColor: "transparent", boxShadow: "0 1px 2px 0 rgb(0 0 0 / 0.05)" }).hover({    backgroundColor: t.accent,    color: t.accentForeground,  });  $sizeDefault = this.css({ height: "2.25rem", minWidth: "2.25rem", padding: "0 0.5rem" });  $sizeSm = this.css({ height: "2rem", minWidth: "2rem", padding: "0 0.375rem" });  $sizeLg = this.css({ height: "2.5rem", minWidth: "2.5rem", padding: "0 0.625rem" });}export type ToggleVariant = "default" | "outline";export type ToggleSize = "default" | "sm" | "lg";export interface ToggleProps extends MorphosToggleProps {  variant?: ToggleVariant;  size?: ToggleSize;}@Component()export class Toggle extends StatelessComponent<ToggleProps> {  @Styled(ToggleStyles) $s!: ToggleStyles;  render() {    const { variant = "default", size = "default", class: cls, ...rest } = this.props;    const variants: Record<ToggleVariant, string> = { default: this.$s.$variantDefault, outline: this.$s.$variantOutline };    const sizes: Record<ToggleSize, string> = { default: this.$s.$sizeDefault, sm: this.$s.$sizeSm, lg: this.$s.$sizeLg };    return <MorphosToggle class={cx(this.$s.$root, variants[variant], sizes[size], cls)} {...rest} />;  }}

Examples

Usage

import { Toggle } from "@/components/ui/toggle";

<Toggle aria-label="Toggle bold">B</Toggle>
<Toggle variant="outline">Outline</Toggle>
<Toggle size="sm">Small</Toggle>

Props

PropTypeDefault
variant"default" | "outline""default"
size"default" | "sm" | "lg""default"
pressed / defaultPressedboolean
onPressedChange(pressed: boolean) => void

On this page