- 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 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:
- 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
- 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
- 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
- Separator
- Visual divider between content
- horizontal, vertical
- Layout Components
- Portal
- Render components outside hierarchy
- -
- Layout Components
- List
- Performance-optimized list rendering
- -
- Layout Components
- Table
- Data table with header, body, rows, and cells
- default
- Layout Components
- Sidebar
- Collapsible navigation sidebar with menu items
- default
- Layout Components
- Form Inputs
- Component
- Description
- Variants
- Reference
- Input
- Text input field
- default
- Input Components
- NumericInput
- Formatted numeric input (currency, percentage, etc.)
- default
- Input Components
- PhoneInput
- Phone number input with country selector (E.164)
- default
- Input Components
- Textarea
- Multi-line text input
- default
- Input Components
- Checkbox
- Toggle selection with label
- default, outlined
- Input Components
- RadioGroup
- Single selection from a group of options
- default, outlined
- Input Components
- Select
- Dropdown selection from a list of options
- default
- Input Components
- Combobox
- Generic autocomplete input with built-in filtering and item selection
- default
- Input Components
- Field
- Form field wrapper with label and validation
- -
- Input Components
- Display Components
- Component
- Description
- Variants
- Reference
- Typography
- Text with semantic variants
- heading, body (+ size: sm, md, lg)
- Display Components
- Avatar
- User avatar with image and fallback
- default
- Display Components
- Badge
- Status indicators and labels
- default, secondary, success, warning, danger, info
- Display Components
- Icon
- Icon rendering with render prop pattern
- -
- Display Components
- Empty
- Empty state placeholders
- default
- Display Components
- Progress
- Linear progress indicators
- default
- Display Components
- Interactive Components
- Component
- Description
- Variants
- Reference
- Button
- Action buttons with loading states
- default, secondary, ghost
- Interactive Components
- IconButton
- Icon-only pressable button
- default, secondary, ghost
- Interactive Components
- Tabs
- Tabbed navigation
- default, line
- Interactive Components
- Menu
- Dropdown menus
- default
- Interactive Components
- Popover
- Positioned overlay content
- default
- Interactive Components
- Calendar
- Month date picker (compound)
- default
- Interactive Components
- WeekCalendar
- Swipeable week strip with date selection
- default
- Interactive Components
- CalendarTimeline
- Day timeline with generic event rendering
- default
- Interactive Components
- Feedback Components
- Component
- Description
- Variants
- Reference
- Alert
- Inline notifications with icons
- default, destructive
- Feedback Components
- AlertDialog
- Modal confirmation dialogs
- default
- Feedback Components
- Toast
- Transient notifications
- default, success, danger
- Feedback Components
- Compound Component Pattern
- All KorUI components follow a compound component pattern where a parent component (usually
- Root
- ) provides context to child sub-components.
- Structure
- <
- 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
- <
- Button
- variant
- =
- "
- default
- "
- onPress
- =
- {
- handlePress
- }
- isLoading
- =
- {
- loading
- }
- >
- Submit Form
- </
- Button
- >
- Example: Alert with Icon
- 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
- <
- Field.Root
- >
- <
- Field.Label
- for
- =
- "
- "
- >
- Email Address
- </
- Field.Label
- >
- <
- Input
- id
- =
- "
- "
- value
- =
- {
- }
- 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:
- // 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:
- 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:
- 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:
- <
- 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
- .
- Common Patterns
- Form Field with Validation
- import
- {
- Field
- ,
- Input
- }
- from
- "@korsolutions/ui"
- ;
- <
- Field.Root
- >
- <
- Field.Label
- for
- =
- "
- "
- >
- </
- Field.Label
- >
- <
- Input
- id
- =
- "
- "
- value
- =
- {
- }
- 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:
- 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:
- 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:
- import
- {
- Separator
- }
- from
- "@korsolutions/ui"
- ;
- // Horizontal (default)
- <
- Separator
- />
- // Vertical
- <
- Separator
- variant
- =
- "
- vertical
- "
- />
- Controlled State Management
- Most input components use controlled state:
- 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:
- <
- 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:
- <
- Button
- isDisabled
- =
- {
- !
- formValid
- }
- onPress
- =
- {
- handleSubmit
- }
- >
- Submit
- </
- Button
- >
- <
- Input
- isDisabled
- value
- =
- {
- }
- 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:
- // 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:
- <
- Button
- style
- =
- {
- {
- marginTop
- :
- 20
- ,
- backgroundColor
- :
- "blue"
- ,
- }
- }
- >
- Custom Styled
- </
- Button
- >
- Import Reference
- Component Imports
- // Import individual components
- import
- {
- Button
- ,
- Input
- ,
- Card
- ,
- Alert
- }
- from
- "@korsolutions/ui"
- ;
- // Import all components
- import
- *
- as
- UI
- from
- "@korsolutions/ui"
- ;
- Hook Imports
- // 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
- import
- {
- UIProvider
- }
- from
- "@korsolutions/ui"
- ;
- Type Imports
- // 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:
- // 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: 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:
- 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:
// This works - style prop overrides variant
<
Button
style
=
{
{
backgroundColor
:
"red"
}
}
Red Button </ Button
For comprehensive troubleshooting, see Troubleshooting Guide . Reference Documentation Consult these detailed references as needed: Component References Layout Components - Card, Separator, Portal, List, Table Input Components - Input, NumericInput, Textarea, Checkbox, RadioGroup, Select, Combobox, Field Display Components - Typography, Avatar, Badge, Icon, Empty, Progress Interactive Components - Button, Tabs, Menu, Popover, Calendar Feedback Components - Alert, AlertDialog, Toast System References Theme Customization - Complete theming guide with color schemes, typography, and responsive design Patterns & Recipes - Common implementation patterns for forms, modals, navigation, and feedback Troubleshooting - Solutions for setup, component, type, and platform-specific issues