Utilities

Helper functions for styling, responsive design, form layout, and component composition.

Utilities

Utility functions help you build components and layouts more efficiently. These are foundational tools for styling, responsiveness, form structure, and polymorphic component patterns.

Essential utilities

cn — Merge and resolve Tailwind classes

Use cn to merge class names while intelligently resolving Tailwind conflicts. This is your go-to for combining base styles with conditional or override classes.

import { cn } from "@loke/design-system/cn";

// Merge classes with conflict resolution
const buttonClasses = cn("px-4 py-2 rounded", "px-6"); // Result: "py-2 rounded px-6"

// Conditional classes
function Card({ variant, className }) {
  return (
    <div
      className={cn(
        "rounded border p-4",
        variant === "elevated" && "shadow-lg",
        className
      )}
    >
      {/* content */}
    </div>
  );
}

// Override parent styles
<button className={cn(buttonVariants({ size: "default" }), "bg-purple-600")}>
  Custom Button
</button>

When to use: Whenever you need to merge multiple class strings or conditionally add classes without Tailwind conflicts appearing.

responsive — Breakpoint-aware variant generation

Use responsive to generate Tailwind classes for multiple breakpoints. Create size, color, and dimension variants that change based on screen size.

import { cva } from "class-variance-authority";
import {
  createResponsiveComponent,
  getSizeVariants,
} from "@loke/design-system/responsive";

// Define responsive component with size variants
const boxVariants = cva("box", {
  variants: {
    padding: getSizeVariants("p"), // p-0, p-1, ..., p-32, small, medium, large
  },
});

const { createResponsive } = createResponsiveComponent(boxVariants);

// Use responsive array: [default, sm:, md:, lg:]
const classes = createResponsive({
  padding: [2, 4, 6, 8], // p-2 at default, sm:p-4, md:p-6, lg:p-8
});

// In a component
function ResponsiveGrid() {
  const gridClasses = createResponsive({
    cols: [1, 2, 3, 4], // 1 column mobile → 4 columns desktop
    gap: [2, 4, 6],     // smaller gaps on mobile
  });

  return <div className={gridClasses}>{/* items */}</div>;
}

When to use: Building layouts that adapt to screen sizes, creating responsive spacing or sizing without manual breakpoint prefixes.

Supporting utilities

Use form-classes to structure accessible form layouts with react-hook-form. It exports predefined CSS class names for form items, labels, descriptions, and error messages.

import { formClasses } from "@loke/design-system/form";

function MyForm() {
  return (
    <form>
      <div className={formClasses.formItem}>
        <label className={formClasses.formLabel}>Name</label>
        <input type="text" />
        <p className={formClasses.formDescription}>
          Your full name as it appears on documents.
        </p>
      </div>
    </form>
  );
}

Use slot to build polymorphic components with asChild composition. Slot merges parent props onto child elements, enabling flexible rendering without extra DOM nodes.

import { Slot } from "@loke/design-system/slot";

// Button can render as button, link, or custom component
<Button asChild>
  <a href="/docs">Go to Docs</a>
</Button>

// Props and classes merge onto the child
<Button asChild className="text-lg">
  <a href="/docs" className="underline">
    Docs
  </a>
</Button>
// Result: <a href="/docs" class="button-classes text-lg underline">Docs</a>

Components

UtilityPurposeCommon use case
cnMerge and deduplicate Tailwind classes with conflict resolutionConditional styling, overrides, combining base + variant styles
responsiveGenerate typed responsive variants across breakpoints (sm, md, lg)Responsive spacing, sizing, grids that adapt to screen size
form-classesCSS class names for form field layout structureForm layouts with react-hook-form
slotMerge props onto child elements for polymorphic renderingasChild pattern, flexible component APIs

Quick decision tree

  • Merging class strings without Tailwind conflicts? → cn
  • Different spacing/sizing at different breakpoints? → responsive
  • Building form field layouts with react-hook-form? → form-classes
  • Rendering Button as a link or custom component? → slot with asChild