`.
---
## Variants
MegaMenu supports interaction-based variants.
```tsx
```
**Available variants:**
- closed
- open
- trigger-active
- content-visible
**Guidelines:**
- Use MegaMenu for high-density navigation only
- Avoid using for simple dropdown patterns
---
## Sizes
No intrinsic size variants.
Sizing is consumer-driven via custom class overrides.
Default behavior:
- Trigger: intrinsic content width
- Content: `min-width: 480px`
- Panel supports responsive overrides
---
## Shapes / Modes
**Behavioral modes**
- Closed (default)
- Open (context-driven)
**Interaction modes**
- Toggle click
- Outside click dismissal
- Escape key dismissal
- Trigger focus restoration
**Layout modes**
- Single column
- Multi-column grid
- Marketing hero panel
- Mixed content navigation
---
z-dropdown`
- `--color-primary`
- `--fg-default`
Shadow and spacing tokens define panel elevation and density.
---
## Accessibility
Implemented:
- `aria-expanded` on trigger
- `aria-controls` linkage
- Unique ID generation
- Escape key close + focus restore
- Focus-visible outline
- Outside click dismissal
Limitations:
- No roving tabindex menu navigation
- No arrow-key navigation
- No typeahead navigation
- Role `menu` without menuitem semantics
- No focus trap
---
## Animation
Entrance animation:
- Scale + translate + fade
- Transform origin anchored to trigger
- Motion respects `prefers-reduced-motion`
Chevron rotation indicates state transition.
---
## Architectural notes
Key behaviors:
- Context-driven open state
- Compound component pattern
- Ref synchronization between root and trigger
- Document-level listeners for dismissal
- Lazy mount of content (performance)
- ID-based accessibility linkage
- CSS animation entrance for GPU-accelerated motion
Tradeoffs:
- No portal rendering → constrained by stacking context
- Menu positioning not collision-aware
- Outside click detection relies on DOM containment
---
## Best practices
### Do
- Use for complex product navigation
- Compose with Grid/Flex for panel structure
- Provide large touch targets inside panel
- Keep trigger labels concise
- Implement responsive content layout
### Don’t
- Use as replacement for simple dropdown
- Overload with excessive nested menus
- Place inside overflow-hidden containers
- Depend on default width for mobile layouts
- Mix unrelated navigation categories
---
## API Reference
---
### Document: nui/components/modal/page.mdx
# Modal
A portal-based, fully accessible dialog primitive engineered for interruptive workflows, confirmations, and multi-step forms. Implements WAI-ARIA 1.2 modal dialog standards, focus trapping, background inerting, body scroll locking, and physics-based entrance/exit transitions.
```tsx
import { Modal } from '@nofinite/nui';
```
---
## Interactive Preview
---
## Anatomy & Modes
NUI Modal can be used as a self-contained single element via declarative props (matching Storybook's default pattern) or composed via structured compound components for custom layout arrangements:
### Declarative Props Mode (Recommended)
```tsx
Cancel
Confirm
>
}
>
Modal body content goes here.
```
### Compound Components Mode
```tsx
Modal Title
Descriptive helper subtitle.
{/* Scrollable content area */}
{/* Action buttons */}
```
| Component / Prop | Description |
| :--- | :--- |
| `Modal` | The root portal controller and backdrop overlay container. |
| `title` | Accessible title prop rendered into `h2.modal-title`. |
| `description` | Accessible description subtitle rendered into `p.modal-description`. |
| `footer` | Custom footer actions container rendered with border separation and flex-end alignment. |
| `Modal.Header` | Container for the dialog title and descriptive subtitle. |
| `Modal.Title` | Accessible heading (``) linked via `aria-labelledby`. |
| `Modal.Description` | Accessible subtitle (` `) linked via `aria-describedby`. |
| `Modal.Body` | Main scrollable content region with responsive padding. |
| `Modal.Footer` | Bottom action bar with border separation and flex-end alignment. |
---
## Usage Examples
### 1. Standard Declarative Modal
Self-contained modal using `title`, `description`, and `footer` props:
```tsx
import React, { useState } from 'react';
import { Button, Modal } from '@nofinite/nui';
export default function DeploymentSettings() {
const [open, setOpen] = useState(false);
return (
<>
setOpen(true)}>
Deployment Settings
setOpen(false)}
title="Production Deployment"
description="Configure edge nodes and SSL certificate options."
footer={
<>
setOpen(false)}>Cancel
setOpen(false)}>Deploy Now
>
}
>
Your application will be distributed across 35 edge regions with automated fallback routing and instant cache invalidation.
>
);
}
```
---
### 2. Form Dialog with Initial Focus
Automatically focus an input field when the dialog opens using `initialFocusRef`:
```tsx
import React, { useState, useRef } from 'react';
import { Button, Modal, Input } from '@nofinite/nui';
export default function RenameProjectModal() {
const [open, setOpen] = useState(false);
const inputRef = useRef(null);
return (
<>
setOpen(true)}>Rename Project
setOpen(false)}
initialFocusRef={inputRef}
>
Rename Project
Choose a unique identifier for your workspace.
setOpen(false)}>Cancel
setOpen(false)}>Save Name
>
);
}
```
---
### 3. Non-Dismissible Transactional Modal
Prevent accidental dismissal during critical or destructive workflows:
```tsx
{}}
disableClickOutside
disableEsc
hideCloseButton
>
Migrating Database
Please do not close this window while the migration executes.
```
---
## Keyboard Interaction
| Key | Behavior |
| :--- | :--- |
| Escape | Closes the modal and restores focus to the previously focused trigger element (unless `disableEsc` is active). |
| Tab | Traps and cycles focus forward through all interactive elements within the modal dialog. |
| Shift + Tab | Cycles focus backwards within the modal focus trap. |
---
## Accessibility (WAI-ARIA)
- **Role & Semantics:** Root dialog renders `role="dialog"` and `aria-modal="true"`.
- **Labeling:** Automatically links `aria-labelledby` to `Modal.Title` and `aria-describedby` to `Modal.Description`.
- **Focus Management:** Focus is automatically trapped inside the dialog upon mounting and returned to the trigger element on close.
- **Background Inerting:** All sibling nodes outside the portal are marked `inert` to prevent screen reader bleed.
- **Scroll Locking:** Automatically locks body scroll with padding compensation to avoid layout shift.
---
## Design Tokens & NUICSS Superclasses
NUI Modal strictly adheres to semantic NUICSS tokens and superclasses:
| Superclass / Token | Type | Usage |
| :--- | :--- | :--- |
| `modal-box` | Superclass | Dialog container surface with elevation, radius, and max-width. |
| `modal-header` | Superclass | Top header area with title spacing. |
| `modal-title` | Superclass | Semantically styled dialog title. |
| `modal-description`| Superclass | Muted subtitle text. |
| `modal-body` | Superclass | Scrollable body area with responsive gutters. |
| `modal-footer` | Superclass | Bottom border-separated action bar. |
| `modal-close` | Superclass | Absolute close button in the upper-right corner. |
| `bg-overlay` | Token | Semi-transparent dimmed backdrop (`--bg-overlay`). |
| `bg-surface` | Token | Dialog panel background surface (`--bg-surface`). |
| `border-default` | Token | Container border token (`--border-default`). |
---
## Best Practices
### Do
- Always provide clear `Modal.Title` and `Modal.Description` for screen reader context.
- Use `initialFocusRef` for form dialogs to guide keyboard users directly to the first input.
- Provide explicit action buttons in `Modal.Footer` to clearly communicate outcomes.
### Don't
- Do not nest modals inside other modals; use sequential drawers or full-page workflows instead.
- Avoid using modals for non-interruptive information that could live directly on the page canvas.
- Do not disable outside click or Escape dismissal without an explicit functional reason (such as unsaved changes).
---
## API Reference
---
### Document: nui/components/multiselect/page.mdx
# Multi Select
A fully accessible, token-driven MultiSelect component built with strict WAI-ARIA compliance.
```tsx
import { MultiSelect } from '@nofinite/nui';
```
---
## Interactive Preview
---
## Usage
### Basic Example
```tsx
import { MultiSelect } from '@nofinite/nui';
```
---
## API Reference
---
## Accessibility & Guidelines
- **Semantic Tokens:** Built strictly using Nuicss semantic tokens (`bg-surface`, `text-default`, `border-subtle`, `bg-primary`).
- **Keyboard Navigation:** Adheres to strict WAI-ARIA standards.
- **Screen Reader Support:** Includes semantic roles and live regions where appropriate.
---
### Document: nui/components/nuiprovider/page.mdx
# NUI Provider
The `NUIProvider` is the root context wrapper for all NUI applications. It manages global theme state (`light`, `dark`, or `system`), synchronizes preferences with `localStorage`, listens for operating system theme changes, and exposes the `useTheme` hook.
```tsx
import { NUIProvider, useTheme } from '@nofinite/nui';
```
---
## Overview
Unlike standard interactive UI widgets, `NUIProvider` is an application-level wrapper component. It injects and manages the `.dark` theme class on your root `` or `` element, ensuring that all NUI component styles automatically adapt between light and dark modes across your application.
All NUI components rely on `NUIProvider` being present at the root of your component tree.
---
## Interactive Demo
---
## Setup & Integration
### Next.js App Router Setup
Place `NUIProvider` in your root layout (`src/app/layout.tsx`). We recommend adding `suppressHydrationWarning` to `` to avoid React hydration mismatches when reading theme preference from `localStorage`:
```tsx
import { NUIProvider } from '@nofinite/nui';
export default function RootLayout({
children,
}: {
children: React.ReactNode;
}) {
return (
{children}
);
}
```
---
### Vite / React SPA Setup
In single-page React applications, wrap your root application tree in `main.tsx` or `App.tsx`:
```tsx
import React from 'react';
import ReactDOM from 'react-dom/client';
import { NUIProvider } from '@nofinite/nui';
import App from './App';
ReactDOM.createRoot(document.getElementById('root')!).render(
);
```
---
## Switching Themes with `useTheme`
Use the `useTheme()` hook inside any child component to read the current theme, inspect the resolved DOM theme, or trigger theme changes:
```tsx
import { useTheme, Button, Flex } from '@nofinite/nui';
export function ThemeSwitcher() {
const { theme, resolvedTheme, setTheme } = useTheme();
return (
Current theme: {resolvedTheme}
setTheme('light')}
>
Light
setTheme('dark')}
>
Dark
setTheme('system')}
>
System
);
}
```
---
## API Reference
### `NUIProvider` Props
### `useTheme` Hook Return Values
| Property | Type | Description |
| :--- | :--- | :--- |
| `theme` | `'light' \| 'dark' \| 'system'` | The user's active theme setting (including `'system'`). |
| `resolvedTheme` | `'light' \| 'dark'` | The actual computed theme active on the page (`'light'` or `'dark'`). |
| `setTheme` | `(theme: ThemeMode) => void` | Updates the active theme and persists the preference to `localStorage`. |
---
## Best Practices
- **Place at Root:** Always mount `` as close to the root of your application tree as possible.
- **Hydration Safety:** When using Next.js or SSR frameworks, add `suppressHydrationWarning` to the `` tag to prevent client-server theme mismatch warnings.
- **Persistent Key:** The `storageKey` prop defaults to `'nui-theme'`. If you run multiple apps on the same domain, configure unique storage keys to prevent theme conflicts.
---
### Document: nui/components/numberinput/page.mdx
# Number Input
A fully accessible, token-driven NumberInput component built with strict WAI-ARIA compliance.
```tsx
import { NumberInput } from '@nofinite/nui';
```
---
## Interactive Preview
---
## Usage
### Basic Example
```tsx
import { NumberInput } from '@nofinite/nui';
```
---
## API Reference
---
## Accessibility & Guidelines
- **Semantic Tokens:** Built strictly using Nuicss semantic tokens (`bg-surface`, `text-default`, `border-subtle`, `bg-primary`).
- **Keyboard Navigation:** Adheres to strict WAI-ARIA standards.
- **Screen Reader Support:** Includes semantic roles and live regions where appropriate.
---
### Document: nui/components/pagination/page.mdx
# Pagination
A fully accessible, WAI-ARIA compliant pagination component for navigating through pages. Supports first/prev/next/last controls, arrow key navigation, and gap indicators similar to GitHub-style pagination.
```tsx
import { Pagination } from '@nofinite/nui';
```
---
## Interactive Preview
---
## Usage
### Basic Pagination
```tsx
import { Pagination } from '@nofinite/nui';
;
```
---
### Sibling Page Control
```tsx
```
---
### Disabled Pagination
```tsx
```
---
## Page Generation Logic
The component implements **adaptive pagination math**:
- Displays all pages when total is small
- Shows ellipsis only when more than 2 pages are hidden
- Maintains first + last page visibility
- Uses sibling window around current page
Generated item types:
| Type | Description |
| ---------------- | -------------------------- |
| `number` | Page index |
| `left-ellipsis` | Hidden pages before window |
| `right-ellipsis` | Hidden pages after window |
---
## Variants
```tsx
// Default
// Extended window
// Disabled
// Styled
```
**Available variants**
- `default` — Standard pagination
- `extended` — Larger sibling window
- `disabled` — Interaction blocked
- `styled` — Custom styling override
**Guidelines**
- Increase `siblings` for data-heavy navigation
- Keep default sibling size for compact UI
- Disable pagination during async loading states
- Avoid large sibling counts on small screens
---
## States
| State | Description |
| ---------- | ------------------------ |
| `idle` | Default rendering |
| `active` | Current page highlighted |
| `disabled` | Navigation locked |
| `ellipsis` | Hidden page ranges |
| `focused` | Keyboard focus visible |
---
## Keyboard Interaction
| Key | Behavior |
| ------- | ------------------------- |
| `Enter` | Navigate to page |
| `Space` | Trigger page button |
| `Tab` | Move focus across buttons |
---
## Accessibility
- Semantic `` with pagination label
- `aria-current="page"` for active page
- ARIA labels for navigation buttons
- Focus-visible outline for keyboard users
- Ellipsis hidden from assistive tech via `aria-hidden`
---
## Best Practices
### Do
- Use controlled state for predictable navigation
- Provide meaningful page totals
- Keep sibling count minimal for mobile
- Disable during server pagination fetch
- Maintain visual consistency with design tokens
### Don’t
- Hide first/last page in long lists
- Use pagination for small datasets
- Disable without visual feedback
- Overload pagination with extra actions
- Remove focus outline for accessibility
---
## API Reference
---
### Document: nui/components/passwordinput/page.mdx
# Password Input
A fully accessible, token-driven PasswordInput component built with strict WAI-ARIA compliance.
```tsx
import { PasswordInput } from '@nofinite/nui';
```
---
## Interactive Preview
---
## Usage
### Basic Example
```tsx
import { PasswordInput } from '@nofinite/nui';
```
---
## API Reference
---
## Accessibility & Guidelines
- **Semantic Tokens:** Built strictly using Nuicss semantic tokens (`bg-surface`, `text-default`, `border-subtle`, `bg-primary`).
- **Keyboard Navigation:** Adheres to strict WAI-ARIA standards.
- **Screen Reader Support:** Includes semantic roles and live regions where appropriate.
---
### Document: nui/components/pininput/page.mdx
# Pin Input
A fully accessible, token-driven PinInput component built with strict WAI-ARIA compliance.
```tsx
import { PinInput } from '@nofinite/nui';
```
---
## Interactive Preview
---
## Usage
### Basic Example
```tsx
import { PinInput } from '@nofinite/nui';
```
---
## API Reference
---
## Accessibility & Guidelines
- **Semantic Tokens:** Built strictly using Nuicss semantic tokens (`bg-surface`, `text-default`, `border-subtle`, `bg-primary`).
- **Keyboard Navigation:** Adheres to strict WAI-ARIA standards.
- **Screen Reader Support:** Includes semantic roles and live regions where appropriate.
---
### Document: nui/components/popover/page.mdx
# Popover
`Popover` is a versatile overlay component used to display contextual content or interactive elements anchored to a trigger. It supports portal rendering, automatic positioning, and accessibility features like ARIA compliance and focus management.
```tsx
import { Popover } from '@nofinite/nui';
```
---
## Interactive Preview
---
## Usage
### Basic Popover
```tsx
import { Popover } from '@nofinite/nui';
Open
Popover content
;
```
---
### Placement Control
```tsx
Open
Top popover
```
---
### Close Action
```tsx
Open
Close
```
---
### Default Open State
```tsx
import { Popover } from '@nofinite/nui';
Open
Default open popover
```
---
### Popover Content
| Prop | Type | Default | Description |
| ----------- | ---------------------------------------- | -------- | --------------------- |
| `placement` | `'top' \| 'bottom' \| 'left' \| 'right'` | `bottom` | Preferred placement |
| `offset` | `number` | `8` | Distance from trigger |
| `className` | `string` | — | Custom styling |
---
## Compound API
| Component | Responsibility |
| ----------------- | ------------------------------------ |
| `Popover` | State container and context provider |
| `Popover.Trigger` | Toggle control with ARIA wiring |
| `Popover.Content` | Positioned overlay surface |
| `Popover.Close` | Optional close action wrapper |
---
## Variants
```tsx
... // Default
... // Open
// Top
// Left
// Right
```
**Available variants**
- `default` — Bottom placement
- `top` — Above trigger
- `left` — Left of trigger
- `right` — Right of trigger
- `open` — Default open state
**Guidelines**
- Use bottom placement for primary contextual content
- Prefer top for dropdown-like behaviors near viewport bottom
- Avoid horizontal placements on narrow screens
- Provide explicit close actions for interactive content
---
## States
| State | Description |
| ----------- | ---------------------------------------- |
| `closed` | Not rendered |
| `open` | Visible overlay |
| `focused` | Focus trapped within content |
| `dismissed` | Closed via outside click or Escape |
| `flipped` | Placement auto-adjusted due to collision |
---
## Keyboard Interaction
| Key | Behavior |
| --------------- | --------------------------------------- |
| `Enter / Space` | Toggle popover via trigger |
| `Escape` | Close popover |
| `Tab` | Cycle focus inside popover (focus trap) |
---
## Accessibility
- ARIA dialog pattern (`role="dialog"`, `aria-modal`)
- Trigger uses `aria-haspopup`, `aria-expanded`, and `aria-controls`
- Focus restoration to trigger on close
- Keyboard dismissal via Escape
- Focus trap inside popover content
- Click outside detection for dismissal
---
## Positioning Behavior
The component implements **adaptive overlay positioning**:
- Viewport boundary collision detection
- Placement flipping when clipping occurs
- Arrow offset recalculation for accurate pointing
- Scroll and resize reflow updates
- Safe padding from viewport edges
---
## Best Practices
### Do
- Use compound API for composability
- Provide explicit close actions for complex popovers
- Keep content lightweight for performance
- Prefer portal rendering for layering safety
- Ensure trigger has clear affordance
### Don’t
- Use popovers for large modal workflows
- Nest multiple popovers without focus management
- Place destructive actions without visual separation
- Disable Escape dismissal
- Overuse horizontal placements in responsive layouts
---
## API Reference
---
### Document: nui/components/progress/page.mdx
# Progress
A composable, accessible Progress component for modern React applications.
```tsx
import { Progress } from '@nofinite/nui';
```
---
## Interactive Preview
---
A **visual feedback component** used to represent task completion or loading state with support for **determinate and indeterminate modes, size scaling, semantic variants, and GPU-accelerated animations**.
Implements **ARIA progressbar semantics** ensuring accessibility for assistive technologies while maintaining smooth 60fps rendering via transform-based animation.
---
## Usage
### Basic Progress
```tsx
import { Progress } from '@nofinite/nui';
;
```
---
### Indeterminate Loading
```tsx
```
---
### Sizes
```tsx
```
---
### Semantic Variants
```tsx
```
---
### Custom Max Value
```tsx
```
---
## Variants
```tsx
// Default
// Success
// Warning
// Danger
// Loading
```
**Available variants**
- `default` — Primary progress indicator
- `success` — Positive completion state
- `warning` — Partial or caution state
- `danger` — Error or critical state
- `loading` — Indeterminate animation
**Guidelines**
- Use determinate mode for measurable tasks
- Use indeterminate mode when duration is unknown
- Prefer semantic variants to communicate status
- Keep large sizes for prominent workflows
---
## States
| State | Description |
| ---------------- | ------------------------ |
| `idle` | Zero or initial value |
| `progressing` | Value increasing |
| `complete` | Reached maximum |
| `indeterminate` | Infinite animation |
| `reduced-motion` | Pulse animation fallback |
---
## Accessibility
- Implements `role="progressbar"`
- Supports `aria-valuemin`, `aria-valuemax`, and `aria-valuenow`
- Indeterminate mode omits `aria-valuenow`
- Hidden label via `aria-label`
- Motion reduction respects OS accessibility preferences
---
## Performance Characteristics
The component uses **transform-based progress animation** instead of width changes:
- GPU-accelerated rendering
- Avoids layout thrashing
- Ensures consistent 60fps transitions
- Safari overflow clipping workaround via `translateZ(0)`
---
## Best Practices
### Do
- Clamp values within valid ranges
- Use indeterminate mode for unknown durations
- Apply semantic variants for status communication
- Respect reduced motion preferences
- Keep progress feedback consistent with task context
### Don’t
- Use indeterminate mode for long operations without context
- Animate via width causing layout reflow
- Rely solely on color for status indication
- Exceed max value without normalization
- Overuse large progress bars in dense layouts
---
## API Reference
---
### Document: nui/components/radiogroup/page.mdx
# Radio Group
A composable, accessible RadioGroup component for modern React applications.
```tsx
import { RadioGroup } from '@nofinite/nui';
```
---
## Interactive Preview
---
A **controlled/uncontrolled selection component** that enables users to choose a single option from a set while preserving **native radio behavior, accessibility semantics, keyboard navigation, and layout orientation control**.
Implements a **compound component architecture** with context-driven state synchronization between `RadioGroup` and `RadioGroup.Item`.
---
## Usage
### Basic Usage
```tsx
import { RadioGroup } from '@nofinite/nui';
;
```
---
### Controlled Usage
```tsx
const [value, setValue] = useState('apple');
;
```
---
### Horizontal Orientation
```tsx
```
---
### Disabled Group
```tsx
```
---
### RadioGroup.Item
| Prop | Type | Default | Description |
| ----------- | --------- | -------------- | -------------------------- |
| `value` | `string` | — | Unique option value |
| `disabled` | `boolean` | `false` | Disable specific item |
| `id` | `string` | auto-generated | Input id for label linking |
| `className` | `string` | — | Custom styling |
---
## Variants
```tsx
// Vertical (default)
// Horizontal
// Disabled
// Controlled
```
**Available variants**
- `vertical` — Stacked layout
- `horizontal` — Inline layout
- `disabled` — Non-interactive group
- `controlled` — External state management
- `uncontrolled` — Internal state management
**Guidelines**
- Use controlled mode for form libraries
- Prefer horizontal layout for small option sets
- Maintain consistent naming for grouping semantics
- Use disabled state to prevent invalid selections
---
## States
| State | Description |
| --------------- | ---------------------- |
| `unchecked` | Default state |
| `checked` | Selected option |
| `hover` | Pointer hover feedback |
| `focus-visible` | Keyboard focus ring |
| `disabled` | Non-interactive state |
---
## Keyboard Interaction
| Key | Behavior |
| ------------ | ----------------------------- |
| `Arrow keys` | Navigate options within group |
| `Space` | Select focused radio |
| `Tab` | Move focus into/out of group |
Native browser radio semantics ensure **automatic roving focus and selection behavior**.
---
## Accessibility
- Implements `role="radiogroup"`
- Uses native ` ` for full accessibility support
- Automatic shared `name` attribute for grouping semantics
- Supports `aria-orientation`
- Uses `aria-checked` state synchronization
- Focus-visible ring for keyboard navigation
- Compatible with `` associations
---
## Best Practices
### Do
- Use consistent values across items
- Provide labels using ``
- Prefer controlled mode for form integration
- Group logically related options
- Use horizontal layout only for limited choices
### Don’t
- Use radios for multi-select scenarios
- Leave items without accessible labels
- Mix controlled and uncontrolled patterns
- Overcrowd horizontal layouts
- Disable individual items without context
---
## API Reference
---
### Document: nui/components/rating/page.mdx
# Rating
A visual input component that allows users to select a rating value using icons (typically stars). It supports controlled and uncontrolled modes, fractional selection, keyboard interaction, and custom icon rendering.
```tsx
import { Rating } from '@nofinite/nui';
```
---
## Interactive Preview
---
## Usage
### Basic usage
```tsx
import { Rating } from '@nofinite/nui';
export function Example() {
return ;
}
```
### Controlled usage
```tsx
const [value, setValue] = useState(4);
;
```
### Half rating
```tsx
```
### Read-only display
```tsx
```
### Custom icons
```tsx
} iconFilled={ } />
```
---
## Variants
### Sizes
```tsx
```
**Available variants**
- sm
- md
- lg
**Guidelines**
- Use **sm** inside dense layouts (tables, cards)
- Use **md** as default
- Use **lg** for emphasis or hero sections
---
## States
- Default
- Hover preview (temporary fill during pointer move)
- Focus visible (keyboard focus ring)
- Read-only
- Disabled
- Fractional display
- Controlled vs uncontrolled value
---
## Keyboard Interaction
| Key | Behavior |
| --------------------- | --------------------------------- |
| ArrowRight / ArrowUp | Increase rating (step = 1 or 0.5) |
| ArrowLeft / ArrowDown | Decrease rating |
| Home | Set to minimum (0) |
| End | Set to maximum |
Component uses `role="slider"` semantics.
---
## Accessibility
- Uses **slider pattern** with:
- `aria-valuemin`
- `aria-valuemax`
- `aria-valuenow`
- `aria-disabled`
- `aria-readonly`
- Keyboard operable
- Focus visible outline
- Tab navigation disabled when readOnly or disabled
---
## Best Practices
### Do
- Use half rating when precision matters (reviews)
- Use readOnly for aggregated scores
- Keep max ≤ 10 to avoid cognitive overload
- Use custom icons for domain-specific ratings
### Don’t
- Use rating as the only feedback control for critical flows
- Combine disabled and readOnly simultaneously unless intentional
- Allow fractional ratings without clear visual affordance
- Overuse large size in dense UI contexts
---
## API Reference
---
### Document: nui/components/resizable/page.mdx
# Resizable
A composable, accessible Resizable component for modern React applications.
```tsx
import { Resizable } from '@nofinite/nui';
```
---
## Interactive Preview
---
A layout primitive that enables users to resize adjacent panels via drag or keyboard interaction. It supports horizontal and vertical orientations, flexible panel constraints, and WAI-ARIA compliant separator behavior.
The component is composed of:
- `Resizable` (root container)
- `Resizable.Panel`
- `Resizable.Handle`
---
## Usage
### Basic horizontal split
```tsx id="4ng9k5"
import { Resizable } from '@nofinite/nui';
export function Example() {
return (
Left
Right
);
}
```
### Vertical split
```tsx id="snkz2o"
Top
Bottom
```
### With constraints
```tsx id="e7i6kq"
```
### With grip icon
```tsx id="s8sdhi"
```
### Layout change callback
```tsx id="3h3s38"
console.log(sizes)} />
```
---
### Resizable.Panel
| Prop | Type | Default | Description |
| ------------- | -------- | ------- | ---------------------------- |
| `defaultSize` | `number` | — | Initial flex grow percentage |
| `minSize` | `number` | `0` | Minimum size percentage |
| `maxSize` | `number` | `100` | Maximum size percentage |
| `className` | `string` | — | Additional class names |
---
### Resizable.Handle
| Prop | Type | Default | Description |
| ----------- | --------- | ------- | ----------------------------- |
| `withIcon` | `boolean` | `false` | Shows grip icon inside handle |
| `className` | `string ` | — | Additional class names |
---
## Variants
### Direction
```tsx id="sbq9u0"
```
**Available variants**
- horizontal
- vertical
**Guidelines**
- Use **horizontal** for sidebars and split editors
- Use **vertical** for stacked panes and dashboards
- Prefer consistent orientation across a workspace
---
### Handle visual variant
```tsx id="p02s3n"
```
**Available variants**
- default
- withIcon
**Guidelines**
- Use icon grip for discoverability
- Use default for minimal UI
- Prefer icon when drag affordance is unclear
---
## States
- Default
- Hover (handle highlight)
- Focus visible (keyboard)
- Dragging
- Constraint-limited resize
- Keyboard resize
- Orientation-dependent cursor
---
## Keyboard Interaction
| Key | Behavior |
| ------------- | ---------------------------------- |
| Arrow keys | Resize panels based on orientation |
| Shift + Arrow | Resize by 10% step |
| Home | Move toward minimum bound |
| End | Move toward maximum bound |
Handles follow separator interaction pattern.
---
## Accessibility
- Uses `role="separator"` on handle
- Orientation via `aria-orientation`
- Dynamic `aria-valuenow` updates
- Keyboard operable resizing
- Focusable handle with visible focus ring
- Pointer drag does not remove keyboard operability (manual focus restoration)
---
## Best Practices
### Do
- Define min/max constraints for predictable layouts
- Use icon grips in complex editors
- Persist layout using onLayout
- Ensure panels contain overflow-safe content
- Use consistent panel sizing strategy
### Don’t
- Nest many resizable groups without performance consideration
- Omit constraints in critical layouts
- Place scroll containers directly on handles
- Use vertical + horizontal nesting without UX clarity
---
## API Reference
---
### Document: nui/components/scrollarea/page.mdx
# Scroll Area
A fully accessible, token-driven ScrollArea component built with strict WAI-ARIA compliance.
```tsx
import { ScrollArea } from '@nofinite/nui';
```
---
## Interactive Preview
---
## Usage
### Basic Example
```tsx
import { ScrollArea } from '@nofinite/nui';
```
---
## API Reference
---
## Accessibility & Guidelines
- **Semantic Tokens:** Built strictly using Nuicss semantic tokens (`bg-surface`, `text-default`, `border-subtle`, `bg-primary`).
- **Keyboard Navigation:** Adheres to strict WAI-ARIA standards.
- **Screen Reader Support:** Includes semantic roles and live regions where appropriate.
---
### Document: nui/components/segmentedcontrol/page.mdx
# Segmented Control
A fully accessible, token-driven SegmentedControl component built with strict WAI-ARIA compliance.
```tsx
import { SegmentedControl } from '@nofinite/nui';
```
---
## Interactive Preview
---
## Usage
### Basic Example
```tsx
import { SegmentedControl } from '@nofinite/nui';
```
---
## API Reference
---
## Accessibility & Guidelines
- **Semantic Tokens:** Built strictly using Nuicss semantic tokens (`bg-surface`, `text-default`, `border-subtle`, `bg-primary`).
- **Keyboard Navigation:** Adheres to strict WAI-ARIA standards.
- **Screen Reader Support:** Includes semantic roles and live regions where appropriate.
---
### Document: nui/components/select/page.mdx
# Select
A fully accessible dropdown component that allows users to choose a single option from a list. It supports controlled and uncontrolled modes, portal-based positioning, keyboard navigation with typeahead search, and error/disabled states.
```tsx
import { Select } from '@nofinite/nui';
```
---
## Interactive Preview
---
## Usage
### Basic usage
```tsx id="1w3l5k"
import { Select } from '@nofinite/nui';
const options = [
{ value: 'apple', label: 'Apple' },
{ value: 'banana', label: 'Banana' },
{ value: 'orange', label: 'Orange' },
];
;
```
### Controlled usage
```tsx id="n3f3a0"
const [value, setValue] = useState('apple');
;
```
### With placeholder
```tsx id="k8ldp2"
```
### Disabled options
```tsx id="2smc9k"
```
### Error state
```tsx id="z6f0r9"
```
### Form integration
```tsx id="7qk4wx"
```
---
## Variants
### Validation state
```tsx id="0qj8n5"
```
**Available variants**
- default
- error
- disabled
**Guidelines**
- Use **error** for validation feedback
- Use **disabled** when input is unavailable
- Avoid mixing disabled and error simultaneously
---
## States
- Default
- Open / closed
- Hover
- Focus visible
- Active option (keyboard)
- Selected option
- Disabled option
- Error
- Typeahead navigation
---
## Keyboard Interaction
| Key | Behavior |
| ------------------------ | ---------------------------- |
| ArrowDown / ArrowUp | Navigate options |
| Enter / Space | Select active option |
| Home | Jump to first enabled option |
| End | Jump to last enabled option |
| Escape | Close dropdown |
| Character typing | Typeahead search |
| Enter / Space on trigger | Open dropdown |
---
## Accessibility
- Uses `button` trigger with `aria-haspopup="listbox"`
- `aria-expanded` and `aria-controls` reflect open state
- List uses `role="listbox"`
- Options use `role="option"`
- `aria-selected` and `aria-disabled` per option
- Focus restored to trigger after close
- Typeahead navigation for screen reader parity
- Hidden input ensures form compatibility
---
## Best Practices
### Do
- Use portal positioning for overflow-safe dropdowns
- Provide placeholder for clarity
- Keep option labels concise
- Disable unavailable options instead of removing them
- Use error state with supporting helper text
### Don’t
- Use extremely long option labels without truncation
- Nest interactive elements inside options
- Use dropdowns for very large datasets (prefer combobox)
- Disable typeahead in keyboard-heavy workflows
- Omit name prop when using in forms
---
## API Reference
---
### Document: nui/components/skeleton/page.mdx
# Skeleton
A placeholder component used to indicate loading content while preserving layout structure. It supports multiple sizes, shimmer animation, shape variants, and composable helpers for common UI patterns.
```tsx
import { Skeleton } from '@nofinite/nui';
```
---
## Interactive Preview
---
## Usage
### Basic usage
```tsx id="b6t0p2"
import { Skeleton } from '@nofinite/nui';
;
```
### Custom width and height
```tsx id="h4y9m1"
```
### Circle skeleton
```tsx id="g1u6v8"
```
### Disable animation
```tsx id="q9r2c5"
```
---
## Helper Components
### Text
```tsx id="v3k8x0"
```
### Paragraph
```tsx id="e5f0d3"
```
### Avatar
```tsx id="w7p6s9"
```
### Button
```tsx id="z0l4y2"
```
### Card
```tsx id="c3b7t6"
```
---
## Variants
### Size variants
```tsx id="m5r1o9"
```
**Available variants**
- xs
- sm
- md
- lg
- xl
**Guidelines**
- xs/sm → dense UI or metadata lines
- md → default text placeholders
- lg/xl → headings or large elements
---
## States
- Animated shimmer
- Static (animation disabled)
- Circle shape
- Explicit size override
- Dark mode
- Reduced motion (respects OS preference)
---
## Accessibility
- Uses `role="presentation"`
- Hidden from assistive technologies by default (`aria-hidden`)
- Respects `prefers-reduced-motion`
- Prevents pointer interaction
- Preserves layout to avoid CLS (Cumulative Layout Shift)
---
## Best Practices
### Do
- Match skeleton layout with real content
- Disable animation for long-loading screens if performance sensitive
- Use circle skeleton for avatars and icons
- Use paragraph helper for text-heavy layouts
- Combine helpers to mirror complex UI
### Don’t
- Use skeleton for extremely short loading durations
- Animate excessively in data-dense views
- Display skeleton after content is partially loaded
- Replace error states with skeleton
- Use mismatched skeleton sizes causing layout shift
---
## API Reference
---
### Document: nui/components/slider/page.mdx
# Slider
An interactive input control that allows users to select a numeric value within a defined range using pointer dragging, track clicking, or keyboard navigation. Supports controlled and uncontrolled usage, step snapping, and full accessibility semantics.
```tsx
import { Slider } from '@nofinite/nui';
```
---
## Interactive Preview
---
## Usage
### Basic usage
```tsx id="a1s2d3"
import { Slider } from '@nofinite/nui';
;
```
### Controlled slider
```tsx id="f4g5h6"
const [value, setValue] = useState(50);
;
```
### Custom range and step
```tsx id="j7k8l9"
```
### Disabled slider
```tsx id="m1n2o3"
```
---
## Variants
### Range configuration
```tsx id="p4q5r6"
```
### Controlled vs uncontrolled
```tsx id="s7t8u9"
```
### Disabled
```tsx id="v1w2x3"
```
**Available variants**
- Default range
- Custom range
- Controlled
- Uncontrolled
- Disabled
**Guidelines**
- Use controlled mode when value must sync with external state
- Use uncontrolled mode for simple forms
- Prefer smaller step values for precision inputs
- Avoid extremely small steps causing excessive updates
---
## States
- Idle
- Hover thumb
- Dragging
- Focus-visible
- Keyboard interaction
- Disabled
- Reduced motion
---
## Keyboard Interaction
| Key | Behavior |
| --------------------- | --------------------- |
| ArrowRight / ArrowUp | Increase by step |
| ArrowLeft / ArrowDown | Decrease by step |
| PageUp | Increase by step × 10 |
| PageDown | Decrease by step × 10 |
| Home | Jump to min |
| End | Jump to max |
---
## Accessibility
- Uses `role="slider"`
- Provides `aria-valuemin`, `aria-valuemax`, `aria-valuenow`
- Keyboard operable with full navigation semantics
- Focus is programmatically applied on pointer interaction
- Disabled state exposed via `aria-disabled`
- Respects `prefers-reduced-motion`
- Large invisible hit target improves touch usability
---
## Best Practices
### Do
- Match slider range with meaningful domain values
- Use stepping for predictable snapping behavior
- Provide visible labels or value indicators in forms
- Use controlled mode when slider drives UI changes
- Ensure adequate width for precise interaction
### Don’t
- Use extremely small step sizes for long ranges
- Hide numeric meaning of slider value
- Rely solely on slider for critical precision input
- Disable keyboard navigation
- Use sliders for binary choices (prefer toggle)
---
## API Reference
---
### Document: nui/components/spinner/page.mdx
# Spinner
A visual loading indicator that communicates ongoing asynchronous activity. Designed for inline usage, button loading states, and page-level placeholders. Supports multiple sizes, color variants, and accessible status semantics.
```tsx
import { Spinner } from '@nofinite/nui';
```
---
## Interactive Preview
---
## Usage
### Basic usage
```tsx id="sp1"
import { Spinner } from '@nofinite/nui';
;
```
### Custom size
```tsx id="sp2"
```
### Variant usage
```tsx id="sp3"
```
### Button loading pattern
```tsx id="sp4"
```
---
## Variants
### Size variants
```tsx id="sp5"
```
### Color variants
```tsx id="sp6"
```
**Available variants**
- Primary
- Muted
- Inverse
- Small
- Medium
- Large
- Extra large
**Guidelines**
- Use `primary` for component-level loading
- Use `muted` for page-level or background loading
- Use `inverse` for dark surfaces and buttons
- Prefer smaller sizes for inline usage
- Avoid oversized spinners in dense layouts
---
## States
- Idle animation
- Reduced motion
- Button loading
- Inline loading
- Page loading
---
## Accessibility
- Uses `role="status"` for assistive announcement
- Hidden descriptive label ensures screen reader clarity
- Supports custom loading message via `label`
- Respects `prefers-reduced-motion`
- Color variants maintain sufficient contrast
---
## Best Practices
### Do
- Pair spinner with contextual loading text for long operations
- Use inverse spinner inside buttons or dark surfaces
- Prefer skeleton loaders for complex layout loading
- Use spinner sparingly to avoid perceived latency
- Combine with optimistic UI where possible
### Don’t
- Show spinner for ultra-fast operations (less than 300ms)
- Stack multiple spinners in one region
- Use spinner as the only feedback for long processes
- Place spinner without context in large empty layouts
- Ignore reduced motion preferences
---
## API Reference
---
### Document: nui/components/statcard/page.mdx
# Stat Card
A fully accessible, token-driven StatCard component built with strict WAI-ARIA compliance.
```tsx
import { StatCard } from '@nofinite/nui';
```
---
## Interactive Preview
---
## Usage
### Basic Example
```tsx
import { StatCard } from '@nofinite/nui';
```
---
## API Reference
---
## Accessibility & Guidelines
- **Semantic Tokens:** Built strictly using Nuicss semantic tokens (`bg-surface`, `text-default`, `border-subtle`, `bg-primary`).
- **Keyboard Navigation:** Adheres to strict WAI-ARIA standards.
- **Screen Reader Support:** Includes semantic roles and live regions where appropriate.
---
### Document: nui/components/stepper/page.mdx
# Stepper
A horizontal progress navigation component that visualizes multi-step workflows such as onboarding, checkout, and forms. Supports interactive navigation, optional steps, validation locking, and completed state indicators.
```tsx
import { Stepper } from '@nofinite/nui';
```
---
## Interactive Preview
---
## Usage
### Basic usage
```tsx id="st1"
import { Stepper } from '@nofinite/nui';
;
```
### Interactive navigation
```tsx id="st2"
```
### Rich step data
```tsx id="st3"
```
### Validation lock (disable future steps)
```tsx id="st4"
```
---
## Sub-definitions
### StepItem
| Field | Type | Description |
| ----------- | --------- | -------------------------- |
| label | ReactNode | Step title |
| description | ReactNode | Secondary step information |
| optional | boolean | Indicates optional step |
---
## Variants
### Step data variants
```tsx id="st5"
```
### Interaction variants
```tsx id="st6"
```
**Available variants**
- Static stepper
- Interactive stepper
- Validation locked stepper
- Optional step flow
- Rich description stepper
**Guidelines**
- Use interactive mode for editable workflows
- Use disableFuture for validation-driven flows
- Keep step labels concise
- Prefer descriptions only for complex flows
- Mark non-critical steps as optional
---
## States
- Default
- Active
- Completed
- Disabled future step
- Focus-visible
- Optional step
---
## Keyboard Interaction
- Tab → moves focus between step buttons
- Enter / Space → activates focused step (if enabled)
- Focus ring visible for accessibility
- Disabled steps removed from tab order
---
## Accessibility
- Uses semantic `` with `aria-label="Progress Steps"`
- Active step exposed via `aria-current="step"`
- Disabled steps use button disabled semantics
- Focus-visible styling for keyboard users
- Step numbers replaced with checkmark when completed
- Optional indicator clearly announced
---
## Best Practices
### Do
- Keep steps under 6–7 for cognitive clarity
- Use disableFuture for validation-driven workflows
- Provide clear labels describing user action
- Combine with form validation states
- Use optional steps for progressive completion
### Don’t
- Overload steps with long descriptions
- Allow navigation to invalid steps without validation
- Use stepper for non-linear navigation patterns
- Mix unrelated workflows in one stepper
- Hide step progression context
---
## API Reference
---
### Document: nui/components/switch/page.mdx
# Switch
A toggle control that allows users to switch between binary states (on/off). Supports controlled and uncontrolled usage, form integration, accessibility semantics, and optional label/description content.
```tsx
import { Switch } from '@nofinite/nui';
```
---
## Interactive Preview
---
## Usage
### Basic usage
```tsx id="sw1"
import { Switch } from '@nofinite/nui';
;
```
### Controlled usage
```tsx id="sw2"
```
### With label and description
```tsx id="sw3"
```
### Form integration
```tsx id="sw4"
```
---
## Variants
### Size variants
```tsx id="sw5"
```
### Content variants
```tsx id="sw6"
```
### Interaction variants
```tsx id="sw7"
```
**Available variants**
- Controlled switch
- Uncontrolled switch
- Labelled switch
- Descriptive switch
- Disabled switch
- Small switch
- Medium switch
- Form-integrated switch
**Guidelines**
- Use switches for immediate state changes
- Prefer checkbox for multi-select scenarios
- Always include labels for clarity
- Add descriptions for complex implications
- Use disabled state for restricted actions
---
## States
- Default
- Checked
- Disabled
- Focus-visible
- Hover (checked)
- Form-submitted
- Label/description present
---
## Keyboard Interaction
- Tab → focuses switch
- Space / Enter → toggles state
- Focus-visible ring displayed
- Disabled removes interaction
---
## Accessibility
- Uses `role="switch"` with `aria-checked`
- Description linked via `aria-describedby`
- Keyboard operable via Space and Enter
- Focus-visible styling for WCAG compliance
- Hidden input enables native form submission
- Label linked using `htmlFor`
- Disabled exposed via `aria-disabled`
---
## Best Practices
### Do
- Use switches for instant toggles
- Provide descriptive labels
- Pair with validation when required
- Use form integration for settings pages
- Maintain consistent size across UI
### Don’t
- Use switches for irreversible actions
- Replace checkboxes in multi-select lists
- Hide consequences of toggling
- Allow toggling when disabled state required
- Use long descriptions that distract from action
---
## API Reference
---
### Document: nui/components/table/page.mdx
# Data Table
A polymorphic table component that supports both **Plug and Play (PnP) Smart Mode** with automatic sorting and typed cell formatters, and **Composable Compound Primitives** for full layout flexibility.
```tsx
import { Table } from '@nofinite/nui';
```
---
## Interactive Preview
---
## Usage
### 1. Plug and Play (PnP) Smart Mode — Zero Boilerplate
Pass `columns` and `data` arrays directly to ``. NUI automatically builds the table headers, rows, sortable header triggers, and empty states:
```tsx
import { Table, Badge } from '@nofinite/nui';
interface User {
id: string;
name: string;
role: string;
status: 'Active' | 'Inactive';
}
const users: User[] = [
{ id: '1', name: 'Alice Johnson', role: 'Engineering Lead', status: 'Active' },
{ id: '2', name: 'Bob Smith', role: 'Product Manager', status: 'Active' },
{ id: '3', name: 'Charlie Brown', role: 'Designer', status: 'Inactive' },
];
export function QuickTable() {
return (
(
{user.status}
),
},
]}
/>
);
}
```
---
### 2. Composable Compound Mode — Full Structural Control
When you need custom table rows, grouped headers, or customized cell markup, assemble the compound primitives directly:
```tsx
import { Table, Badge } from '@nofinite/nui';
export function CustomTable() {
return (
Name
Role
Status
Alice Johnson
Engineering Lead
Active
Bob Smith
Product Manager
Active
);
}
```
---
### Custom Sorting & Column Alignment
In Smart PnP mode, you can customize the alignment and sorting logic:
```tsx
`$${row.revenue.toLocaleString()}`,
},
]}
/>
```
---
## Props Reference
### Table (Root)
| Prop | Type | Default | Description |
| ----------- | -------------------- | ------- | ------------------------------------------------------------------------- |
| `data` | `T[]` | — | **Plug and Play Mode:** Array of row objects to render. |
| `columns` | `TableColumn[]` | — | **Plug and Play Mode:** Column definitions with keys, sorting, and render.|
| `rowKey` | `keyof T \| fn` | `'id'` | Unique key property or resolver function for each row. |
| `emptyText` | `ReactNode` | `'No data available'` | Displayed when `data` array is empty. |
| `children` | `ReactNode` | — | Compound primitives (used in compound mode). |
### TableColumn Configuration
| Property | Type | Description |
| ---------- | ----------------------------- | ------------------------------------------------------- |
| `key` | `keyof T` | Object key to extract cell value from. |
| `label` | `string` | Text label displayed in column header. |
| `sortable` | `boolean` | Enables interactive click-to-sort on the header. |
| `align` | `'left' \| 'center' \| 'right'`| Content alignment for header and cells. |
| `render` | `(row: T) => ReactNode` | Custom cell renderer callback. |
| `sortFn` | `(a: T, b: T) => number` | Custom comparison function overriding default sort. |
---
## Subcomponents
- `Table.Header`
- `Table.Body`
- `Table.Row`
- `Table.Head`
- `Table.Cell`
---
## Accessibility
- Strict semantic HTML table elements (``, ``, ` `, ``, ``, ` `).
- Sortable headers provide proper `role="columnheader"` and accessible labels.
- Responsive horizontal scroll wrapper prevents layout overflow on mobile screens.
---
## API Reference
---
### Document: nui/components/tabs/page.mdx
# Tabs
A composable, accessible Tabs component for modern React applications.
```tsx
import { Tabs } from '@nofinite/nui';
```
---
## Interactive Preview
---
A composable, accessible tabs component implementing **Dual-Mode Architecture**, controlled and uncontrolled state, roving tabindex keyboard navigation, and ARIA-linked triggers and panels.
NUI lets you choose between **Plug and Play (PnP)** mode for rapid data-driven tab rendering, or **Composable Compound Primitives** for full layout customization.
---
## Usage
### 1. Plug and Play (PnP) Mode — Zero Boilerplate
Pass an array of tab definitions directly via the `data` prop. NUI automatically constructs the tab bar, keyboard navigation, and panel visibility without manual subcomponent declarations:
```tsx
import { Tabs } from '@nofinite/nui';
export function QuickTabs() {
const tabs = [
{ value: 'account', label: 'Account', content: },
{ value: 'password', label: 'Password', content: },
{ value: 'billing', label: 'Billing', content: },
];
return ;
}
```
---
### 2. Composable Compound Mode — Full Structural Control
When you need custom layouts, right-aligned toolbar buttons, or customized trigger styles, assemble the compound primitives directly:
```tsx
import { Tabs } from '@nofinite/nui';
export function CustomTabs() {
return (
Account
Password
Billing
Account content
Password content
Billing content
);
}
```
---
### Controlled State
```tsx
import { useState } from 'react';
import { Tabs } from '@nofinite/nui';
export function ControlledTabs() {
const [activeTab, setActiveTab] = useState('account');
return (
Account
Billing
Current: {activeTab}
Current: {activeTab}
);
}
```
---
## Props Reference
### Tabs (Root)
| Prop | Type | Default | Description |
| -------------- | -------------------- | ------- | ------------------------------------------------------------------------- |
| `data` | `TabDataItem[]` | — | **Plug and Play Mode:** Array of tab items `{ value, label, content }`. |
| `defaultValue` | `string` | — | The initial active tab value (uncontrolled). |
| `value` | `string` | — | Controlled active tab value. |
| `onChange` | `(val: string) => void` | — | Callback fired when the active tab changes. |
| `children` | `ReactNode` | — | Compound primitives (used in compound mode). |
### Tabs.Trigger
| Prop | Type | Default | Description |
| ---------- | ----------- | ------- | ------------------------------------------------------- |
| `value` | `string` | **required** | Unique identifier matching corresponding `Tabs.Content`.|
| `disabled` | `boolean` | `false` | If true, disables tab and skips in keyboard sequence. |
| `children` | `ReactNode` | — | Tab label or icon content. |
### Tabs.Content
| Prop | Type | Default | Description |
| ---------- | ----------- | ------- | ------------------------------------------------------- |
| `value` | `string` | **required** | Unique identifier matching corresponding `Tabs.Trigger`.|
| `children` | `ReactNode` | — | Panel content rendered when active. |
---
## Subcomponents
- `Tabs.List`
- `Tabs.Trigger`
- `Tabs.Content`
---
## Accessibility
- **Roving Tabindex:** Arrow keys cycle through tabs; only the active tab has `tabIndex={0}`.
- **WAI-ARIA Attributes:** `role="tablist"`, `role="tab"`, and `role="tabpanel"` are automatically configured with `aria-controls` and `aria-labelledby`.
- **Keyboard Navigation:** `ArrowLeft` / `ArrowRight` seamlessly move between tabs.
---
## API Reference
---
### Document: nui/components/textarea/page.mdx
# Textarea
A controlled/uncontrolled multiline input supporting **auto-growing height**, **character counting**, **error state**, and robust accessibility semantics. Designed for form-heavy interfaces with dynamic content entry.
```tsx
import { Textarea } from '@nofinite/nui';
```
---
## Interactive Preview
---
## Usage
### Basic usage
```tsx id="r7f9c2"
import { Textarea } from '@nofinite/nui';
```
### Controlled usage
```tsx id="1yd0ab"
const [value, setValue] = useState("");