Skip to main content

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.

Card.tsx
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.

Card.vue
<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.

Card.svelte
<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>