Framework examples
Complete component examples using tailess in React, Vue and Svelte, including compound variants and a caller-supplied className.
React
A whole component className in one call: a breakpoint group gated on a prop, a nested dark group for the compound variant, match for the tone, and the caller's className as the last argument.
import { ss, match } from "tailess"; export function Card({ tone, wide, disabled, className,}: { tone: "info" | "danger"; wide: boolean; disabled: boolean; className?: string;}) { return ( <div className={ss( { base: "rounded-lg border p-4", md: wide && "p-6", dark: { base: "border-neutral-800", hover: "border-neutral-700" }, hover: "shadow-md", "focus-visible": "ring-2 ring-offset-2", }, disabled && { base: "opacity-50 pointer-events-none" }, match(tone, { info: "bg-blue-50", danger: "bg-red-50" }), className, )} /> );}Arguments are never reordered, so that trailing className wins over anything the component set itself — see the ss API for the ordering rules.
Vue
ss returns a plain string, so it drops straight into :class with no wrapper and no computed property. Single-file components are scanned out of the box — vue is in the plugin's default extension list.
<script setup lang="ts">import { ss } from "tailess";const props = defineProps<{ active: boolean }>();</script> <template> <div :class="ss( { base: 'rounded p-4', md: 'p-6', dark: { hover: 'bg-neutral-800' } }, props.active && { base: 'ring-2' }, )" > It's fine to write prose with apostrophes here. </div></template>Svelte
The same call in Svelte markup, with svelte likewise in the default extension list. Nothing about the API changes with the framework — only where you write the call.
<script lang="ts"> import { ss } from "tailess"; let { active = false } = $props();</script> <div class={ss( { base: "rounded p-4", md: "p-6", dark: { hover: "bg-neutral-800" } }, active && { base: "ring-2" }, )}> Let's go — apostrophes in markup are fine.</div>