Components
Toggle
A two-state toggle button, wrapping Morphos's Toggle primitive.
Installation
npx kosmesis add togglepnpm dlx kosmesis add toggleyarn dlx kosmesis add togglebunx kosmesis add toggleInstall the following dependencies:
npm install @morphos/inputs class-variance-authoritypnpm add @morphos/inputs class-variance-authorityyarn add @morphos/inputs class-variance-authoritybun add @morphos/inputs class-variance-authorityCopy and paste the following code into your project.
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/csspnpm add @morphos/inputs @praxisjs/cssyarn add @morphos/inputs @praxisjs/cssbun add @morphos/inputs @praxisjs/cssCopy and paste the following code into your project.
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
| Prop | Type | Default |
|---|---|---|
variant | "default" | "outline" | "default" |
size | "default" | "sm" | "lg" | "default" |
pressed / defaultPressed | boolean | — |
disabled | boolean | — |
onPressedChange | (pressed: boolean) => void | — |