React

How to install and use Kaida components in your React application.

Installation

  1. Install Tailwind CSS v4 in your React project:
  1. Copy the theme CSS variables to your index.css or globals.css.

  2. Copy the component files into your project (e.g., src/components/).

Usage

Kaida components are divided into two types:

Components without JavaScript

Components like Button, Badge, Input, Card work with pure CSS/Tailwind. No JavaScript initialization needed — just copy the HTML and convert attributes to JSX:

Always convert to camelCase:
- HTML: classclassName, forhtmlFor, tabindextabIndex
- Events: onclickonClick, onchangeonChange
- SVG: stroke-widthstrokeWidth, fill-opacityfillOpacity, clip-pathclipPath

Keep as-is (no conversion):
- data-* attributes (e.g., data-accordion, data-accordion-trigger)
- aria-* attributes (e.g., aria-expanded, aria-hidden)
- id, type, name, placeholder, href, src, target

export function Example() {
  return (
    <button
      name="button"
      type="button"
      className="flex gap-8px items-center justify-center whitespace-nowrap py-4px px-16px text-btn2 [&>svg]:w-16px [&>svg]:h-16px rounded-8px text-white dark:text-accent-900 border disabled:opacity-30 focus:shadow-[0_0_0_2px_#FFFFFF,0_0_0_4px_#0F172A] dark:focus:shadow-[0_0_0_2px_#2d2e33,0_0_0_4px_#FFFFFF] bg-accent-900 border-accent-900 hover:bg-accent-700 hover:border-accent-700 focus:bg-accent-700 focus:border-accent-700 active:bg-accent-500 active:border-accent-500 dark:bg-white dark:border-white dark:hover:bg-accent-200 dark:hover:border-accent-200 dark:focus:bg-accent-200 dark:focus:border-accent-200 dark:active:bg-accent-400 dark:active:border-accent-400"
      title="Get started">
      Get started
    </button>
  );
}

Tip: Use online converters for automatic conversion: transform.tools or magic.reactjs.

Components with JavaScript

Components like Accordion, Toast, Dropdown require JavaScript initialization.

Basic initialization

Copy the JS file to your project (e.g., src/lib/accordion.ts) and initialize in useEffect:

import { useEffect } from 'react';
import { init_accordions } from '@/lib/accordion';

export function AccordionExample() {
  useEffect(() => {
    init_accordions();
  }, []);

  return (
    <div data-accordion="open">
      {/* accordion items */}
    </div>
  );
}

Important: Use an empty dependency array [] to initialize only once. Calling init_accordions() multiple times will create duplicate instances.

Global initialization (recommended)

For better performance, initialize all components once in your root file:

// src/main.tsx or src/index.tsx
import { useEffect } from 'react';
import { init_accordions } from '@/lib/accordion';
// import other init functions as needed

export default function App() {
  useEffect(() => {
    init_accordions();
    // init_other_components();
  }, []);

  return <>{children}</>;
}

Then use components anywhere without worrying about initialization:

// Any component - no useEffect needed
export function FAQ() {
  return (
    <div data-accordion="open">
      {/* accordion items */}
    </div>
  );
}

Note for Next.js users: If you're using Next.js App Router (13+), add 'use client' directive at the top of files that use useEffect or other React hooks. See Next.js documentation for more details.

Example

Here's a complete example using the Accordion component:

import { useEffect } from 'react';
import { init_accordions } from '@/lib/accordion';

export function FAQ() {
  useEffect(() => {
    init_accordions();
  }, []);

  return (
    <div data-accordion="open">
      <button
        type="button"
        data-accordion-trigger="#panel-0"
        aria-expanded="false"
        className="flex items-center justify-between gap-16px w-full pt-20px pb-20px px-24px text-h9 rtl:text-right border-t border-accent-200 dark:border-black-600 [&.active]:pb-12px will-change:padding-bottom [&>span]:will-change:opacity transition-all [&>span]:transition-all hover:[&>span]:opacity-70"
      >
        <span>Text</span>
        <svg
          data-accordion-icon=""
          className="rotate-180 shrink-0"
          aria-hidden="true"
          width={24}
          height={24}
          viewBox="0 0 24 24"
          fill="none"
          xmlns="http://www.w3.org/2000/svg"
        >
          <path
            d="M18 15L12 9L6 15"
            stroke="currentColor"
            strokeWidth="1.5"
            strokeLinecap="round"
            strokeLinejoin="round"
          ></path>
        </svg>
      </button>
      <div id="panel-0" className="hidden">
        <div className="px-24px pb-20px text-p2">
          <p>Description</p>
        </div>
      </div>
      
      <button
        type="button"
        data-accordion-trigger="#panel-1"
        aria-expanded="false"
        className="flex items-center justify-between gap-16px w-full pt-20px pb-20px px-24px text-h9 rtl:text-right border-t border-accent-200 dark:border-black-600 [&.active]:pb-12px will-change:padding-bottom [&>span]:will-change:opacity transition-all [&>span]:transition-all hover:[&>span]:opacity-70"
      >
        <span>Text</span>
        <svg
          data-accordion-icon=""
          className="rotate-180 shrink-0"
          aria-hidden="true"
          width={24}
          height={24}
          viewBox="0 0 24 24"
          fill="none"
          xmlns="http://www.w3.org/2000/svg"
        >
          <path
            d="M18 15L12 9L6 15"
            stroke="currentColor"
            strokeWidth="1.5"
            strokeLinecap="round"
            strokeLinejoin="round"
          ></path>
        </svg>
      </button>
      <div id="panel-1" className="hidden">
        <div className="px-24px pb-20px text-p2">
          <p>Description</p>
        </div>
      </div>
    </div>
  );
}

Key points:

  • No JS components (Button, Badge, Input, Card, etc.) — just copy HTML, no initialization
  • JS components (Accordion, Toast, Dropdown, etc.) — initialize once in useEffect
  • Use className instead of class in React/TSX
  • Initialize with empty dependency array [] to avoid duplicates
  • For multiple JS components, initialize globally in your root file (src/main.tsx)
  • Data attributes (data-accordion, data-accordion-trigger, etc.) remain the same
  • Next.js App Router: Add 'use client' directive in files that use hooks (see note above)