Skip to main content

Components Package

The @kousta-ui/components package provides a collection of reusable React components.


🚀 Features

  • TypeScript First: Full TypeScript support with comprehensive type definitions
  • Accessibility: WCAG compliant components with proper ARIA attributes
  • Customizable: Extensive theming system with CSS variables and ComponentPropsProvider
  • Performance Optimized: Lightweight components with minimal bundle impact
  • Modern Design: Clean, consistent design system out of the box
  • Flexible: Headless-friendly architecture for custom implementations

📦 Installation

npm install @kousta-ui/components
# or
yarn add @kousta-ui/components
# or
pnpm add @kousta-ui/components

Import styles

import "@kousta-ui/styles/tokens.css";

🎯 Quick Start

import { Button, Modal, Input } from "@kousta-ui/components";
import { useState } from "react";

function App() {
const [opened, setOpened] = useState(false);

return (
  <div>
    <Button onClick={() => setOpened(true)}>
      Open Modal
    </Button>

    <Modal opened={opened} onClose={() => setOpened(false)} title="Form">
      <Input label="Email" placeholder="you@example.com" />
      <Input label="Password" type="password" />
      <Button>Submit</Button>
    </Modal>
  </div>
);
}

🧩 Component Categories

Form Components

Interactive form elements with validation and accessibility built-in.

  • Input - Versatile input with labels, errors, and sections
  • Button - Theme-aware button with variants and loading states
  • Select - Dropdown selection
  • AsyncSelect - Async data loading select

Components for navigation, overlays, and layout management.

  • Modal - Flexible dialog with positioning and lifecycle callbacks
  • Menu - Lightweight dropdown with click/hover triggers
  • ContextMenu - Right-click menu with nested support

Utility Components

Helper components for performance and advanced interactions.


🎨 Customization

ComponentPropsProvider

Set global defaults and create custom variants:

import { ComponentPropsProvider } from "@kousta-ui/components";

<ComponentPropsProvider
button={{
  size: "sm",
  variant: "primary",
  variants: {
    brand: {
      className: "brand-btn",
      style: { background: "#your-brand-color" },
    },
  },
}}
>
<YourApp />
</ComponentPropsProvider>
Provider defaults (small, primary)
Custom variant (brand)

CSS Variables

Customize appearance with CSS variables:

:root {
--kui-primary-500: #3b82f6;
--kui-primary-600: #2563eb;
--kui-rounded: 0.5;
}

Learn more See ComponentPropsProvider documentation for advanced customization.


♿ Accessibility

All components are built with accessibility as a first-class concern:

  • Keyboard Navigation: Full keyboard support with proper focus management
  • Screen Readers: Comprehensive ARIA attributes and semantic HTML
  • High Contrast: Sufficient color contrast ratios for all variants
  • Touch Friendly: Appropriate touch targets and gesture support
  • Reduced Motion: Respects prefers-reduced-motion settings

🔧 TypeScript Support

Full TypeScript support with comprehensive type definitions:

import { Button, ButtonProps } from "@kousta-ui/components";
import { FC } from "react";

interface CustomButtonProps extends ButtonProps {
customProp?: string;
}

const CustomButton: FC<CustomButtonProps> = ({ customProp, ...props }) => {
return <Button {...props} />;
};

📚 Examples

Form with Validation

import { Input, Button } from "@kousta-ui/components";
import { useState } from "react";

function ContactForm() {
const [errors, setErrors] = useState<Record<string, string>>({});

return (
  <div>
    <Input
      label="Name"
      required
      errors={errors.name ? [errors.name] : []}
      onChange={(e) => {
        if (!e.target.value) {
          setErrors(prev => ({ ...prev, name: "Name is required" }));
        } else {
          setErrors(prev => ({ ...prev, name: "" }));
        }
      }}
    />

    <Input
      label="Email"
      type="email"
      required
      errors={errors.email ? [errors.email] : []}
    />

    <Button variant="primary" type="submit">
      Send Message
    </Button>
  </div>
);
}

Lazy Loading Content

import { WindowBoundary } from "@kousta-ui/components";
import { useState } from "react";

function LazyImage({ src, alt }: { src: string; alt: string }) {
const [isLoaded, setIsLoaded] = useState(false);

return (
  <WindowBoundary
    onceItemEnter={() => setIsLoaded(true)}
    threshold={0.1}
  >
    <div style={{ minHeight: "200px" }}>
      {isLoaded ? (
        <img
          src={src}
          alt={alt}
          style={{ width: "100%", height: "auto" }}
        />
      ) : (
        <div style={{
          display: "flex",
          alignItems: "center",
          justifyContent: "center",
          height: "200px",
          background: "#f5f5f5"
        }}>
          Loading...
        </div>
      )}
    </div>
  </WindowBoundary>
);
}
Loading...

🔄 Migration from Other Libraries

From Material-UI

// Material-UI
<Button variant="contained" color="primary">
Click me
</Button>

// Kousta UI
<Button variant="primary">
Click me
</Button>
Material-UI
Kousta UI

From Ant Design

// Ant Design
<Input placeholder="Enter text" />
<Select>
<Option value="1">Option 1</Option>
</Select>

// Kousta UI
<Input placeholder="Enter text" />
<Select data={[{ value: "1", label: "Option 1" }]} />
Ant Design
Kousta UI

🤝 Contributing

We welcome contributions! Please see our contributing guidelines for details.


📄 License

MIT © Oustaa



📖 Next Steps