--- name: kor-ui description: Complete guide for using the Kor UI library (@korsolutions/ui) in React Native and Expo applications. Use this skill when building user interfaces with Universal UI, customizing themes, setting up the library, working with any of the 24+ components (Button, Input, Select, Alert, Card, Tabs, Menu, Popover, Calendar, Toast, etc.), styling and theming, implementing compound components, debugging component issues, or when the user mentions "@korsolutions/ui", "Universal UI", "UIProvider", or asks about unstyled primitives, 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. --- # Universal UI Library Universal UI (@korsolutions/ui) is a library of unstyled UI primitives for React Native and Expo applications. It provides production-ready components with a focus on minimal dependencies, compound component patterns, and comprehensive theming support. ## Core Principles - **Unstyled Primitives**: Components are unstyled by default with variant-based styling - **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 ( ); } ``` ### Basic Import Pattern ```tsx import { Button, Input, Card } from "@korsolutions/ui"; function MyComponent() { return ( console.log("Pressed")}> Click Me ); } ``` ### 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 ( Submit ); } ``` ## Component Overview ### Layout & Structure | Component | Description | Variants | Reference | | ------------- | ----------------------------------------------- | -------- | ---------------------------------------------------------------- | | **Card** | Content container with header, body, and footer | default | [Layout Components](./references/components-layout.md#card) | | **ScrollBar** | Custom scrollbar styling | default | [Layout Components](./references/components-layout.md#scrollbar) | | **Portal** | Render components outside hierarchy | - | [Layout Components](./references/components-layout.md#portal) | | **List** | Performance-optimized list rendering | - | [Layout Components](./references/components-layout.md#list) | ### 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) | | **Textarea** | Multi-line text input | default | [Input Components](./references/components-inputs.md#textarea) | | **Checkbox** | Toggle selection with label | default | [Input Components](./references/components-inputs.md#checkbox) | | **Select** | Dropdown selection with search | default | [Input Components](./references/components-inputs.md#select) | | **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-xs to 3xl, body-xs to lg, label, code, caption | [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 | [Interactive Components](./references/components-interactive.md#button) | | **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** | Date picker with range selection | default | [Interactive Components](./references/components-interactive.md#calendar) | ### 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 Universal UI components follow a compound component pattern where a parent component (usually `Root`) provides context to child sub-components. ### Structure ```tsx ``` ### 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 Submit Form ``` ### Example: Alert with Icon ```tsx import { AlertCircle } from "lucide-react-native"; Error Something went wrong ; ``` ### Example: Field with Input ```tsx Email Address We'll never share your email. {error && {error}} ``` ### Style Composition Component styles are always composed with variant styles first, allowing user styles to override: ```tsx // Variant styles are applied first Custom Button ``` This ensures your custom styles always take precedence over variant defaults. ## Theme System Basics Universal UI 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 ( Themed Content ); } ``` ### 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 ``` For detailed theming documentation, see [Theme Customization](./references/theme-customization.md). ## Common Patterns ### Form Field with Validation ```tsx import { Field, Input } from "@korsolutions/ui"; Email Enter your email address {error && {error}} ; ``` ### Icons with Render Prop Universal UI 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 // With custom function } /> // With @expo/vector-icons import { MaterialCommunityIcons } from "@expo/vector-icons"; ( )} /> ``` ### 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 ( <> Accept terms ); } ``` ### Loading States Buttons support loading states with built-in spinner: ```tsx Submit ``` When `isLoading` is true, the button displays `Button.Spinner` and disables interaction. ### Disabled States Most components support disabled states: ```tsx Submit Disabled option ``` ### Selecting Variants Most components offer multiple variants: ```tsx // Button variants Default Button Secondary Button // Alert variants Info Error // Badge variants Active Inactive Pending ``` ### Style Overrides Override component styles using the `style` prop: ```tsx Custom Styled ``` ## 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 { ButtonRootProps } 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 ( ); } ``` ### 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)" } }, }; ; ``` ### 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 Red 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, ScrollBar, Portal, List - [Input Components](./references/components-inputs.md) - Input, NumericInput, Textarea, Checkbox, Select, 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