# Kor UI

> Complete guide for using the KorUI library (@korsolutions/ui) in React Native and Expo applications. Use this skill when building user interfaces with KorUI, customizing themes, setting up the library, working with any of the 27+ components (Button, IconButton, Input, Select, Checkbox, RadioGroup, Alert, Card, Separator, Tabs, Menu, Popover, Calendar, Toast, etc.), styling and theming, implementing compound components, debugging component issues, or when the user mentions "@korsolutions/ui", "KorUI", "UIProvider", or asks about theme customization or React Native UI components. This skill covers installation, provider setup, component usage patterns, theme customization, variant system, hooks, responsive design, and troubleshooting.

- Skill: `korsoftwaresolutions/kor-ui` (Agent Skill, multi-file: 9 files)
- Install (CLI): `npx skillmds@latest add korsoftwaresolutions/kor-ui`
- Raw SKILL.md: https://api.skillmd.com/api/skills/korsoftwaresolutions/kor-ui/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Web & Frontend
- Author: korsoftwaresolutions (https://skillmd.com/u/korsoftwaresolutions)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/korsoftwaresolutions/kor-ui

---


# KorUI Library

KorUI (@korsolutions/ui) is a minimal-dependency, cross-platform UI library for React Native and Expo. Flexible components with beautiful default styling, compound component patterns, and comprehensive theming support.

## Core Principles

- **Beautiful Defaults**: Components ship with production-ready styling and a flexible variant system
- **Compound Components**: All components follow Root + sub-component pattern
- **Variant System**: Each component offers multiple style variants
- **Minimal Dependencies**: Only React Native and Expo core dependencies
- **Full TypeScript Support**: Complete type definitions for all components
- **Cross-Platform**: iOS, Android, and Web support

## Quick Start

### Installation

```bash
npm install @korsolutions/ui
# or
yarn add @korsolutions/ui
# or
bun add @korsolutions/ui
```

### Provider Setup

Wrap your application with `UIProvider` in your root layout:

```tsx
import { UIProvider } from "@korsolutions/ui";
import { useSafeAreaInsets } from "react-native-safe-area-context";

export default function RootLayout() {
  const safeAreaInsets = useSafeAreaInsets();

  return (
    <UIProvider safeAreaInsets={safeAreaInsets}>
      <YourApp />
    </UIProvider>
  );
}
```

### Basic Import Pattern

```tsx
import { Button, Input, Card } from "@korsolutions/ui";

function MyComponent() {
  return (
    <Card.Root>
      <Card.Body>
        <Button onPress={() => console.log("Pressed")}>
          Click Me
        </Button>
      </Card.Body>
    </Card.Root>
  );
}
```

### Your First Component

```tsx
import { useState } from "react";
import { Button } from "@korsolutions/ui";

function SubmitButton() {
  const [loading, setLoading] = useState(false);

  const handleSubmit = async () => {
    setLoading(true);
    await submitForm();
    setLoading(false);
  };

  return (
    <Button variant="default" isLoading={loading} onPress={handleSubmit}>
      Submit
    </Button>
  );
}
```

## Component Overview

### Layout & Structure

| Component       | Description                                     | Variants             | Reference                                                        |
| --------------- | ----------------------------------------------- | -------------------- | ---------------------------------------------------------------- |
| **Card**              | Content container with header, body, and footer             | default                  | [Layout Components](./references/components-layout.md#card)             |
| **DescriptionList**   | Key-value pairs displayed in rows with term and details     | default                  | [Layout Components](./references/components-layout.md#descriptionlist)  |
| **Item**              | Flexible content row with media, title, description, actions | default, outline, muted  | [Layout Components](./references/components-layout.md#item)             |
| **Separator**         | Visual divider between content                              | horizontal, vertical     | [Layout Components](./references/components-layout.md#separator)        |
| **Portal**            | Render components outside hierarchy                         | -                        | [Layout Components](./references/components-layout.md#portal)           |
| **List**              | Performance-optimized list rendering                        | -                        | [Layout Components](./references/components-layout.md#list)             |
| **Table**             | Data table with header, body, rows, and cells               | default                  | [Layout Components](./references/components-layout.md#table)            |
| **Sidebar**           | Collapsible navigation sidebar with menu items              | default                  | [Layout Components](./references/components-layout.md#sidebar)          |

### Form Inputs

| Component        | Description                                          | Variants | Reference                                                          |
| ---------------- | ---------------------------------------------------- | -------- | ------------------------------------------------------------------ |
| **Input**        | Text input field                                     | default  | [Input Components](./references/components-inputs.md#input)        |
| **NumericInput** | Formatted numeric input (currency, percentage, etc.) | default  | [Input Components](./references/components-inputs.md#numericinput) |
| **PhoneInput**   | Phone number input with country selector (E.164)     | default  | [Input Components](./references/components-inputs.md#phoneinput)   |
| **Textarea**     | Multi-line text input                                | default  | [Input Components](./references/components-inputs.md#textarea)     |
| **Checkbox**     | Toggle selection with label                          | default, outlined  | [Input Components](./references/components-inputs.md#checkbox)     |
| **RadioGroup**   | Single selection from a group of options             | default, outlined  | [Input Components](./references/components-inputs.md#radiogroup)   |
| **Select**       | Dropdown selection from a list of options             | default  | [Input Components](./references/components-inputs.md#select)       |
| **Combobox**     | Generic autocomplete input with built-in filtering and item selection | default  | [Input Components](./references/components-inputs.md#combobox)     |
| **Field**        | Form field wrapper with label and validation         | -        | [Input Components](./references/components-inputs.md#field)        |

### Display Components

| Component      | Description                             | Variants                                               | Reference                                                           |
| -------------- | --------------------------------------- | ------------------------------------------------------ | ------------------------------------------------------------------- |
| **Typography** | Text with semantic variants             | heading, body (+ size: sm, md, lg)                     | [Display Components](./references/components-display.md#typography) |
| **Avatar**     | User avatar with image and fallback     | default                                                | [Display Components](./references/components-display.md#avatar)     |
| **Badge**      | Status indicators and labels            | default, secondary, success, warning, danger, info     | [Display Components](./references/components-display.md#badge)      |
| **Icon**       | Icon rendering with render prop pattern | -                                                      | [Display Components](./references/components-display.md#icon)       |
| **Empty**      | Empty state placeholders                | default                                                | [Display Components](./references/components-display.md#empty)      |
| **Progress**   | Linear progress indicators              | default                                                | [Display Components](./references/components-display.md#progress)   |

### Interactive Components

| Component    | Description                        | Variants           | Reference                                                                 |
| ------------ | ---------------------------------- | ------------------ | ------------------------------------------------------------------------- |
| **Button**     | Action buttons with loading states   | default, secondary, ghost | [Interactive Components](./references/components-interactive.md#button)     |
| **IconButton** | Icon-only pressable button           | default, secondary, ghost | [Interactive Components](./references/components-interactive.md#iconbutton) |
| **Tabs**     | Tabbed navigation                  | default, line      | [Interactive Components](./references/components-interactive.md#tabs)     |
| **Menu**     | Dropdown menus                     | default            | [Interactive Components](./references/components-interactive.md#menu)     |
| **Popover**  | Positioned overlay content         | default            | [Interactive Components](./references/components-interactive.md#popover)  |
| **Calendar** | Month date picker (compound) | default | [Interactive Components](./references/components-interactive.md#calendar) |
| **WeekCalendar** | Swipeable week strip with date selection | default | [Interactive Components](./references/components-interactive.md#weekcalendar) |
| **CalendarTimeline** | Day timeline with generic event rendering | default | [Interactive Components](./references/components-interactive.md#calendartimeline) |

### Feedback Components

| Component       | Description                     | Variants                 | Reference                                                              |
| --------------- | ------------------------------- | ------------------------ | ---------------------------------------------------------------------- |
| **Alert**       | Inline notifications with icons | default, destructive     | [Feedback Components](./references/components-feedback.md#alert)       |
| **AlertDialog** | Modal confirmation dialogs      | default                  | [Feedback Components](./references/components-feedback.md#alertdialog) |
| **Toast**       | Transient notifications         | default, success, danger | [Feedback Components](./references/components-feedback.md#toast)       |

## Compound Component Pattern

All KorUI components follow a compound component pattern where a parent component (usually `Root`) provides context to child sub-components.

### Structure

```tsx
<Component.Root {...rootProps}>
  <Component.SubComponent1 {...props} />
  <Component.SubComponent2 {...props} />
</Component.Root>
```

### Common Sub-Components

Most components share similar sub-component naming:

- **Root** - Parent container that provides context
- **Label** - Text label for the component
- **Icon** - Icon display with render prop pattern
- **Description** - Secondary descriptive text
- **Title** - Primary heading text
- **Body** - Main content area
- **Header** - Top section
- **Footer** - Bottom section

### Example: Button

```tsx
<Button variant="default" onPress={handlePress} isLoading={loading}>
  Submit Form
</Button>
```

### Example: Alert with Icon

```tsx
import { AlertCircle } from "lucide-react-native";

<Alert.Root variant="destructive">
  <Alert.Icon render={AlertCircle} />
  <Alert.Body>
    <Alert.Title>Error</Alert.Title>
    <Alert.Description>Something went wrong</Alert.Description>
  </Alert.Body>
</Alert.Root>;
```

### Example: Field with Input

```tsx
<Field.Root>
  <Field.Label for="email">Email Address</Field.Label>
  <Input id="email" value={email} onChange={setEmail} placeholder="you@example.com" />
  <Field.Description>We'll never share your email.</Field.Description>
  {error && <Field.Error>{error}</Field.Error>}
</Field.Root>
```

### Style Composition

Component styles are always composed with variant styles first, allowing user styles to override:

```tsx
// Variant styles are applied first
<Button style={{ marginTop: 16 }}>
  Custom Button
</Button>
```

This ensures your custom styles always take precedence over variant defaults.

## Theme System Basics

KorUI includes a comprehensive theming system with light/dark mode support.

### Theme Tokens

The theme provides these customizable tokens:

- **colors** - Color palette with light/dark schemes
- **radius** - Border radius (default: 10)
- **fontSize** - Base font size (default: 16)
- **fontFamily** - Font family (default: "System")
- **letterSpacing** - Letter spacing (default: 0)

### Color Tokens

Each color scheme (light/dark) includes:

- **background** - Main background color
- **foreground** - Main text color
- **primary** - Primary brand color
- **primaryForeground** - Text on primary color
- **secondary** - Secondary brand color
- **secondaryForeground** - Text on secondary color
- **muted** - Muted background color
- **mutedForeground** - Muted text color
- **border** - Border color
- **surface** - Surface/card background
- **success**, **warning**, **danger**, **info** - Semantic colors

### Using the Theme

Access the theme in your components:

```tsx
import { useTheme } from "@korsolutions/ui";

function MyComponent() {
  const theme = useTheme();

  return (
    <View
      style={{
        backgroundColor: theme.colors.background,
        borderRadius: theme.radius,
        padding: 16,
      }}
    >
      <Text
        style={{
          color: theme.colors.foreground,
          fontSize: theme.fontSize,
          fontFamily: theme.fontFamily,
        }}
      >
        Themed Content
      </Text>
    </View>
  );
}
```

### Color Scheme

Toggle between light and dark mode:

```tsx
const theme = useTheme();

// Get current scheme
console.log(theme.colorScheme); // "light" | "dark"

// Set color scheme
theme.setColorScheme("dark");
```

### Quick Customization

Customize the theme via UIProvider:

```tsx
<UIProvider
  theme={{
    radius: 12,
    fontSize: 18,
    colors: {
      light: {
        primary: "hsla(220, 90%, 56%, 1)",
        primaryForeground: "hsla(0, 0%, 100%, 1)",
      },
      dark: {
        primary: "hsla(220, 90%, 70%, 1)",
        primaryForeground: "hsla(0, 0%, 100%, 1)",
      },
    },
  }}
  safeAreaInsets={safeAreaInsets}
>
  <App />
</UIProvider>
```

For detailed theming documentation, see [Theme Customization](./references/theme-customization.md).

## Common Patterns

### Form Field with Validation

```tsx
import { Field, Input } from "@korsolutions/ui";

<Field.Root>
  <Field.Label for="email">Email</Field.Label>
  <Input id="email" value={email} onChange={setEmail} placeholder="you@example.com" />
  <Field.Description>Enter your email address</Field.Description>
  {error && <Field.Error>{error}</Field.Error>}
</Field.Root>;
```

### Icons with Render Prop

KorUI uses a render prop pattern for icons, supporting any icon library:

```tsx
import { AlertCircle, CheckCircle } from "lucide-react-native";
import { Alert } from "@korsolutions/ui";

// With lucide-react-native
<Alert.Icon render={AlertCircle} />

// With custom function
<Alert.Icon render={(props) => <CheckCircle {...props} size={20} />} />

// With lucide-react-native
import { AlertCircle } from "lucide-react-native";
<Alert.Icon render={AlertCircle} />
```

### Icon Button

A pressable button that renders a single icon. Uses the same render prop pattern as Icon:

```tsx
import { IconButton } from "@korsolutions/ui";
import { Heart, Settings, Trash } from "lucide-react-native";

// Basic usage
<IconButton render={Heart} onPress={() => console.log("Liked")} />

// Variants (matches Button variants)
<IconButton render={Settings} variant="secondary" />
<IconButton render={Settings} variant="ghost" />

// Custom size and color
<IconButton render={Trash} size={32} color="red" />

// Disabled
<IconButton render={Heart} isDisabled />
```

### Separator

A visual divider between content sections:

```tsx
import { Separator } from "@korsolutions/ui";

// Horizontal (default)
<Separator />

// Vertical
<Separator variant="vertical" />
```

### Controlled State Management

Most input components use controlled state:

```tsx
import { useState } from "react";
import { Input, Checkbox } from "@korsolutions/ui";

function Form() {
  const [text, setText] = useState("");
  const [checked, setChecked] = useState(false);

  return (
    <>
      <Input value={text} onChange={setText} />
      <Checkbox.Root checked={checked} onChange={setChecked}>
        <Checkbox.Indicator />
        <Checkbox.Content>
          <Checkbox.Title>Accept terms</Checkbox.Title>
        </Checkbox.Content>
      </Checkbox.Root>
    </>
  );
}
```

### Loading States

Buttons support loading states with built-in spinner:

```tsx
<Button isLoading={isSubmitting} onPress={handleSubmit}>
  Submit
</Button>
```

When `isLoading` is true, the button displays `ActivityIndicator` and disables interaction.

### Disabled States

Most components support disabled states:

```tsx
<Button isDisabled={!formValid} onPress={handleSubmit}>
  Submit
</Button>

<Input isDisabled value={email} onChange={setEmail} />

<Checkbox.Root disabled checked={value} onChange={setValue}>
  <Checkbox.Indicator />
  <Checkbox.Content>
    <Checkbox.Title>Disabled option</Checkbox.Title>
  </Checkbox.Content>
</Checkbox.Root>
```

### Selecting Variants

Most components offer multiple variants:

```tsx
// Button variants
<Button variant="default">
  Default Button
</Button>

<Button variant="secondary">
  Secondary Button
</Button>

<Button variant="ghost">
  Ghost Button
</Button>

// Alert variants
<Alert.Root variant="default">
  <Alert.Body>
    <Alert.Title>Info</Alert.Title>
  </Alert.Body>
</Alert.Root>

<Alert.Root variant="destructive">
  <Alert.Body>
    <Alert.Title>Error</Alert.Title>
  </Alert.Body>
</Alert.Root>

// Badge variants
<Badge variant="success">Active</Badge>
<Badge variant="danger">Inactive</Badge>
<Badge variant="warning">Pending</Badge>
```

### Style Overrides

Override component styles using the `style` prop:

```tsx
<Button
  style={{
    marginTop: 20,
    backgroundColor: "blue",
  }}
>
  Custom Styled
</Button>
```

## Import Reference

### Component Imports

```tsx
// Import individual components
import { Button, Input, Card, Alert } from "@korsolutions/ui";

// Import all components
import * as UI from "@korsolutions/ui";
```

### Hook Imports

```tsx
// Theme hook
import { useTheme } from "@korsolutions/ui";

// Responsive design hook
import { useScreenSize } from "@korsolutions/ui";

// React Navigation theme integration
import { useReactNavigationTheme } from "@korsolutions/ui";
```

### Provider Import

```tsx
import { UIProvider } from "@korsolutions/ui";
```

### Type Imports

```tsx
// Component prop types
import type { ButtonProps } from "@korsolutions/ui";
import type { InputProps } from "@korsolutions/ui";

// Theme types
import type { ThemeAssets, Colors } from "@korsolutions/ui";
```

## Quick Troubleshooting

### Provider Not Wrapping App

**Issue**: Components don't render or theme doesn't apply

**Solution**: Ensure `UIProvider` wraps your app in the root layout:

```tsx
// app/_layout.tsx
import { UIProvider } from "@korsolutions/ui";

export default function RootLayout() {
  return (
    <UIProvider>
      <Stack />
    </UIProvider>
  );
}
```

### Import Errors

**Issue**: Cannot resolve `@korsolutions/ui`

**Solution**: Install the package and restart your bundler:

```bash
npm install @korsolutions/ui
# Restart Metro bundler
```

### Theme Not Updating

**Issue**: Theme changes don't reflect in components

**Solution**: Ensure theme customization is passed to UIProvider before app renders:

```tsx
const customTheme = {
  colors: { light: { primary: "hsla(220, 90%, 56%, 1)" } },
};

<UIProvider theme={customTheme}>
  <App />
</UIProvider>;
```

### Styles Not Applying

**Issue**: Custom styles don't override component styles

**Solution**: Remember style composition order - user styles always override variant styles:

```tsx
// This works - style prop overrides variant
<Button style={{ backgroundColor: "red" }}>
  Red Button
</Button>
```

For comprehensive troubleshooting, see [Troubleshooting Guide](./references/troubleshooting.md).

## Reference Documentation

Consult these detailed references as needed:

### Component References

- [Layout Components](./references/components-layout.md) - Card, DescriptionList, Item, Separator, Portal, List, Table
- [Input Components](./references/components-inputs.md) - Input, NumericInput, Textarea, Checkbox, RadioGroup, Select, Combobox, Field
- [Display Components](./references/components-display.md) - Typography, Avatar, Badge, Icon, Empty, Progress
- [Interactive Components](./references/components-interactive.md) - Button, Tabs, Menu, Popover, Calendar
- [Feedback Components](./references/components-feedback.md) - Alert, AlertDialog, Toast

### System References

- [Theme Customization](./references/theme-customization.md) - Complete theming guide with color schemes, typography, and responsive design
- [Patterns & Recipes](./references/patterns-recipes.md) - Common implementation patterns for forms, modals, navigation, and feedback
- [Troubleshooting](./references/troubleshooting.md) - Solutions for setup, component, type, and platform-specific issues

