# PACKAGE: @nofinite/nui Accessible, composable React UI primitives with strict semantic design tokens. You are an expert React engineer using @nofinite/nui. Rules: 1. Always import components from '@nofinite/nui'. 2. Use semantic color tokens (e.g., bg-surface, text-default, border-subtle, text-danger) from @nofinite/nuicss instead of raw tailwind colors. 3. For routing polymorphism, use `asChild` (e.g. ). 4. Read the exact API Reference before constructing props. --- ## TypeScript API Reference (Props) ### Accordion - `data: AccordionItem[]` (Default: none) Array of items for Smart Default mode - `defaultOpenId: string` (Default: none) ID of the item that should be open by default - `multiple: boolean` (Default: false) If true, allows multiple accordion panels to remain open simultaneously ### Alert - `variant: enum` (Default: info) - `title: ReactNode` (Default: none) - `closable: boolean` (Default: false) Determines if the close icon button is rendered - `onClose: (() => void)` (Default: none) Callback fired when the close button is clicked. Note: The component is controlled; it does not unmount itself. - `className: string` (Default: none) - `asChild: boolean` (Default: none) Renders the component using its child element ### Attachment - `filename (required): string` (Default: none) - `filesize (required): number` (Default: none) - `filetype (required): string` (Default: none) - `src: string` (Default: none) - `isLoading: boolean` (Default: false) - `className: string` (Default: none) ### Avatar - `src: string` (Default: none) - `alt: string` (Default: none) - `name: string` (Default: none) - `size: enum` (Default: md) - `shape: enum` (Default: circle) - `status: enum` (Default: none) - `fallbackIcon: ReactNode` (Default: none) - `loading: boolean` (Default: none) - `className: string` (Default: none) ### AvatarGroup - `max: number` (Default: 3) Maximum number of avatars to display before truncating - `size: any` (Default: md) Size passed down to all nested Avatar components - `className: string` (Default: none) ### Badge - `count: number` (Default: none) Displays a numerical count inside the badge - `max: number` (Default: 99) The maximum number to display before showing a '+' (e.g., 99+) - `variant: enum` (Default: default) - `size: enum` (Default: md) - `pill: boolean` (Default: false) Rounds the edges to create a pill shape - `dot: boolean` (Default: false) Renders a small, empty circular indicator instead of text - `href: string` (Default: none) If provided, renders the badge as an tag - `onClick: MouseEventHandler` (Default: none) If provided, renders the badge as a ); } ``` --- ## NUICSS Superclass Mapping Under the hood, `@nofinite/nui` maps all variants and sizes directly to `@nofinite/nuicss` superclasses. If you are building pure HTML templates or headless components, you can use the exact same classes: ```html Sign In ``` --- ## Keyboard Interaction | Key | Behavior | | :--- | :--- | | Enter | Activates the button | | Space | Activates the button | | Tab | Moves focus to the button | | Shift + Tab | Moves focus to previous focusable element | --- ## Accessibility - Renders a native ` ``` | Component | Description | | :--- | :--- | | `Card` | The root container applying the `card` superclass, border, and elevation. | | `Card.Header` | Top header area for titles, icon badges, and status chips. | | `Card.Body` | Main content container with responsive padding. | | `Card.Divider` | Semantic horizontal rule between card sections. | | `Card.Footer` | Bottom action bar with flexible alignment for action triggers. | --- ## Usage Examples ### 1. Dashboard Metric Card Combine `Card` with `Badge` and `Button` for dashboard views: ```tsx import React from 'react'; import { Card, Badge, Button } from '@nofinite/nui'; export default function AnalyticsCard() { return ( +20.1%

Monthly recurring revenue grew by $8,120 compared to the previous 30-day billing cycle.

); } ``` --- ### 2. Interactive & Clickable Card Add `clickable` to transform the entire card into an accessible, focusable action trigger: ```tsx import React from 'react'; import { Card } from '@nofinite/nui'; export default function SelectablePlanCard() { return ( alert('Plan selected!')} className="w-full max-w-sm" >

Pro Plan

For fast-growing product teams

Includes unlimited projects, advanced telemetry, and priority support.

); } ``` --- ## Keyboard Interaction (for Clickable Cards) | Key | Behavior | | :--- | :--- | | Tab | Moves keyboard focus to the clickable card surface. | | Enter | Activates the card's `onClick` action handler. | | Space | Activates the card's `onClick` action handler. | --- ## Accessibility (WAI-ARIA) - **Interactive Semantics:** When `clickable` is enabled, the card receives `role="button"`, `tabIndex={0}`, and active scaling feedback. - **Keyboard Handling:** Automatically handles Enter and Space key events, matching native button accessibility. - **Focus Rings:** Renders native focus-visible rings using NUICSS `--border-focus` design tokens. - **Polymorphism:** Supports `asChild` to delegate rendering to Next.js `` or custom navigation wrappers. --- ## Design Tokens & NUICSS Superclasses | Superclass / Token | Type | Usage | | :--- | :--- | :--- | | `card` | Superclass | Base container surface with rounded corners and border. | | `bg-surface` | Token | Background surface (`--bg-surface`). | | `border-default` | Token | Structural border (`--border-default`). | | `hover:shadow-md` | Utility | Elevated shadow applied when `hover` is true. | | `text-default` | Token | Primary content text (`--fg-default`). | | `text-muted` | Token | Secondary helper text (`--fg-muted`). | --- ## Best Practices ### Do - Use `hover` for cards that contain links or primary CTAs to indicate interactivity. - Combine `Card.Header`, `Card.Body`, and `Card.Footer` for clear visual hierarchy. - Use `clickable` when the entire card surface is an action target. ### Don't - Do not place nested interactive buttons inside a `clickable` card (nesting interactive controls violates HTML5 standards). - Avoid overcrowding card footers with more than two primary action buttons. --- ## API Reference --- ### Document: nui/components/carousel/page.mdx # Carousel A fully accessible, token-driven Carousel component built with strict WAI-ARIA compliance. ```tsx import { Carousel } from '@nofinite/nui'; ``` --- ## Interactive Preview --- ## Usage ### Basic Example ```tsx import { Carousel } 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/chart/page.mdx # Chart & Data Visualizations > [!NOTE] > `@nofinite/charts` is a standalone package featuring high-performance visualization primitives including AreaChart, BarChart, LineChart, PieChart, DonutChart, ScatterChart, and export utilities. Visit the dedicated [Charts Documentation Hub](/charts) for comprehensive guides. A comprehensive, universal SVG data visualization library built with modular D3 and designed to integrate seamlessly with `@nofinite/nuicss` design tokens. Supports Area, Bar, Line, Donut, Pie, and Scatter charts with multi-series datasets, interactive crosshair scrubbing, and floating glassmorphic tooltips. ```tsx import { AreaChart, BarChart, LineChart, DonutChart, PieChart, ScatterChart, ChartLegend } from '@nofinite/charts/react'; ``` --- ## Interactive Preview --- ## Unified vs Direct Component API You can render charts using either the polymorphic `` wrapper or direct component imports: ```tsx // 1. Polymorphic wrapper d.name} yAccessor={(d) => d.val} /> // 2. Direct component d.name} yAccessor={(d) => d.val} /> ``` --- ## Chart Variants ### 1. Bar Chart Ideal for discrete categorical comparisons across metrics: ```tsx import { BarChart } from '@nofinite/charts/react'; const quarterlyData = [ { quarter: 'Q1', revenue: 45000 }, { quarter: 'Q2', revenue: 58000 }, { quarter: 'Q3', revenue: 72000 }, { quarter: 'Q4', revenue: 91000 }, ]; export function RevenueBarChart() { return ( ); } ``` ### 2. Area Chart Displays cumulative volume, bandwidth, or growth trends over time with a subtle gradient fill: ```tsx import { AreaChart } from '@nofinite/charts/react'; const latencyData = [ { time: new Date('2026-03-01'), latency: 42 }, { time: new Date('2026-03-02'), latency: 38 }, { time: new Date('2026-03-03'), latency: 45 }, { time: new Date('2026-03-04'), latency: 31 }, ]; export function LatencyAreaChart() { return ( ); } ``` ### 3. Line Chart Optimized for continuous multi-point rate-of-change metrics: ```tsx import { LineChart } from '@nofinite/charts/react'; const serverLoad = [ { time: new Date('2026-03-01T00:00:00Z'), cpu: 22 }, { time: new Date('2026-03-01T04:00:00Z'), cpu: 35 }, { time: new Date('2026-03-01T08:00:00Z'), cpu: 68 }, { time: new Date('2026-03-01T12:00:00Z'), cpu: 84 }, { time: new Date('2026-03-01T16:00:00Z'), cpu: 52 }, ]; export function ServerLoadLineChart() { return ( ); } ``` ### 4. Donut & Pie Charts Perfect for proportional breakdowns, traffic distribution, and segment composition: ```tsx import { DonutChart } from '@nofinite/charts/react'; const trafficSources = [ { source: 'Direct', visitors: 4500 }, { source: 'Organic Search', visitors: 3200 }, { source: 'Referral', visitors: 1800 }, { source: 'Social', visitors: 950 }, ]; export function TrafficDonutChart() { return ( ); } ``` --- ## Semantic Tokens & Theming All charts in `@nofinite/nui` strictly eliminate hardcoded sRGB or hex values. Strokes, fills, and axes automatically synchronize with `@nofinite/nuicss` design tokens: | Element | NUICSS Token | Purpose | | :--- | :--- | :--- | | Primary Series | `var(--chart-1, var(--color-primary))` | Default stroke and gradient accent | | Axis & Grid | `var(--border-default)` | Subtle ticks and horizontal guide grids | | Tooltip Container | `var(--bg-surface)`, `var(--border-default)` | Elevated card surface for hovered points | | Tooltip Shadow | `var(--shadow-md)` | Depth and layer elevation | | Tooltip Typography | `var(--fg-default)` | Crisp legible metric values | When your application toggles between light and dark modes, chart elements immediately inherit the updated CSS variables without triggering React re-renders. --- ## Best Practices ### Do - Always wrap the chart inside a container element with an explicit height (e.g. `className="w-full h-64"`). The charts use responsive sizing (`ParentSize`) and require height bounds from their parent. - Provide clean `Date` or `number` values for time-series accessors to ensure correct axis tick scaling. - Keep tooltips informative by formatting numbers (e.g. currency, percentages) in your data accessors or labels. ### Don't - Do not pass fixed pixel `width` and `height` props unless building a non-responsive print export. - Never pass hardcoded hex values (like `#3b82f6`) when styling custom overlays; always rely on semantic tokens like `var(--color-primary)`. - Avoid rendering hundreds of data points on compact mobile screens without pre-aggregating or bucketing intervals. --- ## API Reference ### Unified Chart Props ### AreaChart Props ### BarChart Props --- ### Document: nui/components/checkbox/page.mdx # Checkbox A **binary selection control** that allows users to toggle between checked, unchecked, and indeterminate states. Supports **controlled and uncontrolled usage, labels, disabled state, and accessibility-friendly behavior**. ```tsx import { Checkbox } from '@nofinite/nui'; ``` --- ## Interactive Preview --- ## Usage ### Basic Checkbox ```tsx import { Checkbox } from '@nofinite/nui'; ``` ### Indeterminate Checkbox ```tsx ``` ### Controlled Checkbox ```tsx const [checked, setChecked] = useState(false); ; ``` ### Disabled Checkbox ```tsx ``` --- ## Variants `Checkbox` supports state-based variants. ```tsx // Unchecked // Checked // Indeterminate // Disabled ``` **Available variants:** - `unchecked` – Default empty checkbox - `checked` – Selected checkbox with checkmark - `indeterminate` – Mixed state with dash indicator - `disabled` – Non-interactive checkbox **Guidelines:** - Use `indeterminate` for parent selection logic (e.g., partial list selection). - Use controlled mode (`checked`) when state is managed externally. - Use disabled when interaction must be prevented but state remains visible. --- ## States | State | Description | | --------------- | ---------------------------------- | | `checked` | Displays checkmark indicator | | `indeterminate` | Displays dash indicator | | `unchecked` | Empty checkbox | | `disabled` | Reduced opacity and no interaction | --- ## Accessibility - Renders a native `` for full semantic support - Uses `aria-checked="mixed"` for indeterminate state - Focus-visible ring improves keyboard navigation - Label wrapping ensures large clickable target - SVG indicators are `aria-hidden` to avoid redundancy --- ## Best Practices ### Do - Use labels for clarity and accessibility - Use controlled mode when checkbox state affects other UI - Use indeterminate for hierarchical selections (e.g., tree views) ### Don’t - Rely solely on visual state without labels - Use indeterminate as a permanent state - Disable checkbox without explaining why interaction is blocked --- ## API Reference --- ### Document: nui/components/chip/page.mdx # Chip A **compact pill-shaped component** used to represent selections, filters, or small entities. Supports **selection state, removability, icons, sizes, and keyboard-accessible interaction**. ```tsx import { Chip } from '@nofinite/nui'; ``` --- ## Interactive Preview --- ## Usage ### Basic Chip ```tsx id="n2o0v1" import { Chip } from '@nofinite/nui'; React Small chip ``` ### Selectable Chip ```tsx id="wd0o2m" console.log('Selected')}> Selected Chip ``` ### Removable Chip ```tsx id="5pj6c6" console.log('Removed')}> Removable ``` ### Chip with Icons ```tsx id="70b0ie" } iconRight={}> Messages ``` ### Interactive Chip ```tsx id="5y5ksd" console.log('Clicked')}>Clickable Chip ``` --- ## Variants `Chip` supports interaction-based variants. ```tsx id="nh0yb9" // Default chip // Selected chip {}} /> // Interactive chip // Removable chip ``` **Available variants:** - `default` – Static chip - `selected` – Active chip with highlighted background - `interactive` – Chip that responds to click and keyboard interaction - `removable` – Chip with remove action **Guidelines:** - Use `selected` for filter or tag selection states. - Use `interactive` when chip triggers an action. - Use `removable` for dynamic lists like tags or recipients. --- ## Sizes | Size | Height | Font Size | Notes | | ---- | ------ | --------- | -------------------------- | | `sm` | 24px | 12px | Compact chips for dense UI | | `md` | 32px | 14px | Default size | --- ## States | State | Description | | ------------- | ------------------------ | | `default` | Neutral chip appearance | | `selected` | Highlighted active state | | `interactive` | Hover + active feedback | | `removable` | Displays remove control | --- ## Accessibility - Interactive chips receive `role="button"` - Keyboard interaction via **Enter** and **Space** - `aria-pressed` reflects selected state - Remove button is separately focusable and accessible - Focus-visible ring improves keyboard navigation --- ## Best Practices ### Do - Use chips for filters, tags, or selected items - Provide remove action for user-generated tags - Use selected state to show active filters - Keep chip text short ### Don’t - Use chips for primary navigation - Overload chips with long content - Hide remove actions behind complex gestures --- ## API Reference --- ### Document: nui/components/clipboard/page.mdx # Clipboard A fully accessible, token-driven Clipboard component built with strict WAI-ARIA compliance. ```tsx import { Clipboard } from '@nofinite/nui'; ``` --- ## Interactive Preview --- ## Usage ### Basic Example ```tsx import { Clipboard } 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/codeblock/page.mdx # Code Block A fully accessible, token-driven CodeBlock component built with strict WAI-ARIA compliance. ```tsx import { CodeBlock } from '@nofinite/nui'; ``` --- ## Interactive Preview --- ## Usage ### Basic Example ```tsx import { CodeBlock } 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/collapsible/page.mdx # Collapsible A fully accessible, token-driven Collapsible component built with strict WAI-ARIA compliance. ```tsx import { Collapsible } from '@nofinite/nui'; ``` --- ## Interactive Preview --- ## Usage ### Basic Example ```tsx import { Collapsible } 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/colorpicker/page.mdx # Color Picker A fully accessible, token-driven ColorPicker component built with strict WAI-ARIA compliance. ```tsx import { ColorPicker } from '@nofinite/nui'; ``` --- ## Interactive Preview --- ## Usage ### Basic Example ```tsx import { ColorPicker } 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/combobox/page.mdx # Combobox A **searchable dropdown input component** that allows users to filter and select options from a list. Supports **controlled/uncontrolled usage, keyboard navigation, icons, custom rendering, filtering, and accessibility-compliant listbox behavior**. ```tsx import { Combobox } from '@nofinite/nui'; ``` --- ## Interactive Preview --- ## Usage ### Basic Combobox ```tsx import { Combobox } from '@nofinite/nui'; ``` ### Controlled Combobox ```tsx const [value, setValue] = useState(""); ``` ### Combobox with Icons ```tsx } rightIcon={} options={options} /> ``` ### Custom Option Rendering ```tsx ( {opt.label} )} /> ``` ### Custom Filter ```tsx option.label.toLowerCase().startsWith(input.toLowerCase()) } /> ``` --- ## Variants `Combobox` supports interaction-based variants. ```tsx // Default combobox // Disabled combobox } /> // With icons {}} /> // Custom rendered options ``` **Available variants:** * `default` – Standard searchable combobox * `disabled` – Non-interactive combobox * `icon` – Combobox with input icons * `custom-render` – Combobox with custom option rendering **Guidelines:** * Use `default` for general dropdown selection. * Use `disabled` to prevent interaction when unavailable. * Use `icon` for contextual affordances. * Use `custom-render` for complex option UI. --- ## States | State | Description | | ---------- | --------------------------- | | `default` | Closed combobox | | `open` | Dropdown visible | | `active` | Keyboard-highlighted option | | `selected` | Currently selected option | | `empty` | No results state | --- ## Accessibility * Uses **ARIA combobox + listbox pattern** * Supports full keyboard navigation * Arrow keys for navigation * Enter for selection * Escape to close * `aria-expanded`, `aria-controls`, and `aria-activedescendant` ensure screen reader support * Click-outside handling prevents accidental focus loss * Option selection correctly updates `aria-selected` --- ## Best Practices ### Do * Use combobox for searchable selections * Provide meaningful empty state message * Use custom filter for large datasets * Keep option labels concise * Use icons for recognition ### Don’t * Use combobox for very small lists without search need * Hide essential information inside custom renderers * Disable keyboard navigation * Overload options with long content --- ## API Reference --- ### Document: nui/components/commandpalette/page.mdx # Command Palette An accessible modal command search dialog following the WAI-ARIA combobox pattern. Triggered via global keyboard shortcuts (⌘K or Ctrl+K), it provides instant fuzzy search, categorized action groups, and keyboard navigation. ```tsx import { CommandPalette } from '@nofinite/nui'; ``` --- ## Interactive Preview --- ## Key Features - **Global Hotkey Support**: Automatically listens for ⌘K / Ctrl+K and Escape triggers. - **Categorized Sections**: Group commands logically into Navigation, Quick Actions, Settings, or Recent Files. - **Fuzzy Filtering**: Fast client-side search ranking that handles typos and partial string matches. - **Accessible Focus Management**: Traps focus inside the dialog and maintains visual focus indicators across list items using ARIA `activedescendant`. --- ## Usage ### Basic Usage ```tsx import { useState, useEffect } from 'react'; import { CommandPalette, Button, Kbd } from '@nofinite/nui'; export default function AppCommandSearch() { const [isOpen, setIsOpen] = useState(false); // Optional: Global keydown listener useEffect(() => { const handleKeyDown = (e: KeyboardEvent) => { if ((e.metaKey || e.ctrlKey) && e.key === 'k') { e.preventDefault(); setIsOpen((prev) => !prev); } }; window.addEventListener('keydown', handleKeyDown); return () => window.removeEventListener('keydown', handleKeyDown); }, []); const sections = [ { title: 'Navigation', items: [ { id: '1', label: 'Go to Documentation', shortcut: '⌘D', onSelect: () => window.location.href = '/docs' }, { id: '2', label: 'Explore Components', shortcut: '⌘C', onSelect: () => window.location.href = '/nui/components/button' }, ] }, { title: 'Actions', items: [ { id: '3', label: 'Create New Document', shortcut: '⌘N', onSelect: () => alert('Document Created!') }, { id: '4', label: 'Toggle Dark Mode', shortcut: '⌘T', onSelect: () => alert('Theme Toggled!') } ] } ]; return ( <> ); } ``` --- ## Keyboard Interaction | Key | Behavior | | :--- | :--- | | ⌘K / Ctrl+K | Open or close the command palette dialog | | ArrowDown | Focus the next command item | | ArrowUp | Focus the previous command item | | Enter | Trigger the currently highlighted command | | Escape | Close the command palette and restore trigger focus | --- ## Best Practices ### Do - Provide concise, action-oriented titles for commands (e.g., "Toggle Fullscreen" rather than "Fullscreen"). - Display relevant keyboard shortcuts in command descriptions to educate users over time. - Restore focus back to the user's previous active element when the palette closes. ### Don't - Do not clutter the palette with hundreds of low-frequency or trivial links; prioritize primary workflows. - Avoid slow network requests on every keystroke; prefer fast in-memory filtering. --- ## API Reference --- ### Document: nui/components/contextmenu/page.mdx # Context Menu A composable, accessible Contextmenu component for modern React applications. ```tsx import { Contextmenu } from '@nofinite/nui'; ``` --- ## Interactive Preview --- A **right-click triggered contextual action menu** that provides spatially anchored commands with keyboard navigation, collision-aware positioning, accessibility semantics, and portal-based rendering. Supports **icons, separators, disabled items, danger actions, focus management, keyboard navigation, viewport collision detection, and trigger composition via `asChild`.** --- ## Usage ### Basic Context Menu ```tsx id="1p9azk" import { ContextMenu } from '@nofinite/nui'; rename() }, { label: 'Duplicate', onSelect: () => duplicate() }, { type: 'separator' }, { label: 'Delete', danger: true, onSelect: () => remove() }, ]} > ; ``` --- ### With Icons ```tsx id="9j3l2s" , onSelect: copy }, { label: 'Paste', icon: , onSelect: paste }, ]} > ``` --- ### Disabled Items ```tsx id="2kx8sa" ``` --- ### Using `asChild` Trigger ```tsx id="0z82xa" ``` --- ## ContextMenuItem Structure | Field | Type | Description | | ---------- | ----------------------- | ----------------------------- | | `label` | `string` | Item text | | `icon` | `ReactNode` | Optional leading icon | | `onSelect` | `() => void` | Action handler | | `danger` | `boolean` | Highlights destructive action | | `disabled` | `boolean` | Disables interaction | | `type` | `'item' \| 'separator'` | Item or divider | --- ## Variants ```tsx id="0d2kqp" // Default // Icon items // Divider groups // Danger actions ``` **Available variants** - `default` — Standard contextual actions - `icon` — Items with visual affordances - `grouped` — Separator-based grouping - `danger` — Destructive emphasis items **Guidelines** - Use `default` for simple action lists - Use `icon` when recognition speed matters - Use `grouped` to separate semantic clusters - Use `danger` only for destructive operations --- ## States | State | Description | | ---------- | -------------------------- | | `closed` | Menu hidden | | `open` | Menu visible | | `active` | Keyboard highlighted item | | `disabled` | Non-interactive item | | `danger` | Destructive action styling | --- ## Keyboard Interaction | Key | Behavior | | --------------- | ----------------------------- | | `ArrowDown` | Move to next enabled item | | `ArrowUp` | Move to previous enabled item | | `Home` | Jump to first enabled item | | `End` | Jump to last enabled item | | `Enter / Space` | Execute active item | | `Escape` | Close menu | --- ## Accessibility - Implements **ARIA menu pattern** - Focus automatically moved to menu on open - Active item tracked via keyboard navigation - `aria-disabled` for disabled items - Screen reader friendly separators - Click-outside and Escape dismissal - Scroll/resize auto-dismiss for spatial correctness --- ## Best Practices ### Do - Use for contextual object-level actions - Keep menus short and relevant - Group related commands with separators - Use danger styling for destructive actions - Provide icons for high-frequency workflows ### Don’t - Place global navigation commands inside context menu - Include too many actions causing cognitive overload - Mix unrelated destructive and safe actions - Disable keyboard navigation - Rely solely on hover for discoverability --- ## API Reference --- ### Document: nui/components/datagrid/page.mdx # Data Grid A high-velocity, virtualized data grid component capable of smoothly rendering tens of thousands of rows. Features multi-column sorting, live search filtering, pagination, row selection, and interactive column resizing. ```tsx import { DataGrid } from '@nofinite/nui'; ``` --- ## Interactive Preview --- ## Key Features - **Virtualized High Performance**: Handles large datasets (10,000+ items) with minimal DOM memory footprint. - **Interactive Sorting**: Click column headers to toggle ascending, descending, or unsorted states. - **Live Search Filtering**: Built-in fuzzy search box filters across all visible cell values instantaneously. - **Column Resizing**: Drag handles between column boundaries to dynamically customize column widths. - **Selection Support**: Optional row checkboxes for single or batch operations with "Select All" support. - **Integrated Pagination**: Seamless page jumping and page size dropdown controls. --- ## Usage ### Basic Usage ```tsx import { DataGrid } from '@nofinite/nui'; const columns = [ { key: 'id', title: 'ID', sortable: true, width: 80 }, { key: 'name', title: 'Employee Name', sortable: true }, { key: 'department', title: 'Department', sortable: true }, { key: 'status', title: 'Status' }, { key: 'salary', title: 'Compensation', sortable: true }, ]; const rows = [ { id: '1', name: 'Sophia Miller', department: 'Engineering', status: 'Active', salary: '$145,000' }, { id: '2', name: 'James Wilson', department: 'Product', status: 'Active', salary: '$130,000' }, { id: '3', name: 'Ava Johnson', department: 'Design', status: 'On Leave', salary: '$115,000' }, { id: '4', name: 'Liam Brown', department: 'Marketing', status: 'Active', salary: '$105,000' }, { id: '5', name: 'Emma Davis', department: 'Operations', status: 'Active', salary: '$95,000' }, ]; export default function MyDataView() { return ( ); } ``` ### With Row Selection ```tsx { console.log('Selected rows:', selectedIds); }} /> ``` --- ## Best Practices ### Do - Provide unique `id` or `key` fields on every data row to optimize React reconciliation. - Set explicit initial `width` numbers for columns containing short status badges or IDs to prevent layout shifts. - Keep table data in memorized state (`useMemo`) when running client-side data transformations. ### Don't - Avoid placing heavy un-memoized canvas or video players inside high-frequency scrollable grid cells. - Do not hide sorting visual indicators from keyboard users; ensure headers remain accessible via Tab and Space/Enter. --- ## API Reference --- ### Document: nui/components/datepicker/page.mdx # Date Picker A controlled/uncontrolled popover calendar component for selecting a single date. Supports keyboard navigation, min/max constraints, localization, smart popover positioning, and year/month quick selection. ```tsx import { DatePicker } from '@nofinite/nui'; ``` --- ## Interactive Preview --- ## Usage ### Basic ```tsx import { DatePicker } from '@nofinite/nui'; console.log(date)} /> ``` ### Controlled ```tsx const [date, setDate] = useState('2026-10-24'); ; ``` ### With constraints ```tsx console.log(d)} /> ``` ### Custom display formatting ```tsx `${d.getDate()}/${d.getMonth() + 1}/${d.getFullYear()}`} /> ``` --- ## Subcomponents None exposed. --- ## Variants DatePicker supports interaction-based variants. ```tsx ``` **Available variants:** - disabled — non-interactive trigger - controlled — external state manages value - uncontrolled — internal state manages value **Guidelines:** - Prefer controlled mode in forms - Use disabled variant for read-only workflows --- ## Sizes Single default size. Width controlled via CSS (trigger defaults to 240px). --- ## Shapes / Modes **Modes** - Controlled - Uncontrolled - Month/year selector mode - Calendar day selection mode **States** - Selected - Today indicator - Disabled date - Min/max constrained - Popover open/closed --- z-dropdown` --- ## Accessibility Implemented semantics: - `aria-haspopup="dialog"` - `aria-expanded` - Calendar grid with `role="grid"` - `aria-selected` on day buttons - Keyboard navigation - Arrow keys day navigation - PageUp/PageDown month switching - Enter/Space selection - Escape close - Focus restoration after popover close - Click outside detection --- ## Best practices ### Do - Use controlled mode in forms - Provide `minDate` and `maxDate` for validation boundaries - Use locale for internationalized apps - Provide custom formatter for domain-specific display ### Don’t - Store formatted display string as value (use ISO) - Disable without visual explanation - Use DatePicker for date ranges (create RangePicker) - Override popover positioning with custom CSS --- ## API Reference --- ### Document: nui/components/daterangepicker/page.mdx # Date Range Picker A popover-based dual-date calendar component for selecting a start and end date. Supports drag selection, keyboard navigation, min/max constraints, month/year navigation, smart popover positioning, and controlled/uncontrolled state patterns. ```tsx import { DateRangePicker } from '@nofinite/nui'; ``` --- ## Interactive Preview --- ## Usage ### Basic ```tsx import { DateRangePicker, DateRange } from '@nofinite/nui'; // Update with your actual import path const [cohortRange, setCohortRange] = useState({ from: '2026-03-01', to: '2026-05-30', }); console.log(r)} />; ``` ### Controlled ```tsx const [range, setRange] = useState({ from: '2026-10-01', to: '2026-10-10' }); ; ``` ### With constraints ```tsx console.log(r)} /> ``` ### Custom display formatting ```tsx `${d.getDate()}/${d.getMonth() + 1}/${d.getFullYear()}`} /> ``` ### Form integration ```tsx ``` --- ## Subcomponents None exposed. --- ## Variants ```tsx ``` **Available variants** - disabled - controlled - uncontrolled - drag-selection **Guidelines** - Prefer controlled mode in complex forms - Use constraints for booking / availability workflows - Enable drag selection for analytics dashboards or scheduling --- ## Sizes Single default size. Trigger width defaults to **280px** (expanded to accommodate range label). --- ## Shapes / Modes **Modes** - Controlled - Uncontrolled - Month/year selector - Calendar day selection - Drag selection mode - Partial selection (only start or end) **States** - Start date selected - End date selected - Range highlight - Drag highlight - Disabled date - Min/max constrained - Popover open/closed - Active part selector (start vs end) --- z-dropdown` --- ## Accessibility Implemented semantics: - `aria-haspopup="dialog"` - `aria-expanded` - Keyboard navigation - Arrow keys grid navigation - Enter/Space day selection - PageUp/PageDown month navigation - Escape close - Focus restoration after popover close - Hidden inputs for form submission - Disabled state propagation - Click outside dismissal --- ## Best practices ### Do - Use ISO date storage for backend compatibility - Apply min/max constraints in booking flows - Use controlled mode for complex validation - Provide custom display formatter for domain-specific UX - Leverage drag selection for quick range picking ### Don’t - Store formatted display string as value - Disable picker without explanation - Use for single-date selection (use DatePicker) - Override popover positioning manually --- ## API Reference --- ### Document: nui/components/dialog/page.mdx # Dialog & DialogProvider A promise-based imperative dialog system for confirmations, alerts, and critical user interactions. Rather than cluttering your component trees with repetitive `useState` boilerplate, `DialogProvider` lets you invoke asynchronous modal dialogs imperatively with `await nui.confirm()` and `await nui.alert()`. ```tsx import { DialogProvider, nui } from '@nofinite/nui'; ``` --- ## Interactive Preview --- ## Architecture Overview The NUI Dialog architecture decouples the dialog triggering logic from the React rendering tree: ``` ┌───────────────────────────────┐ │ Event Handler / Server Action │ │ await nui.confirm(...) │ └───────────────┬───────────────┘ │ Dispatches via external store ▼ ┌───────────────────────────────┐ │ (Root) │ │ Mounts Modal & Traps Focus │ └───────────────┬───────────────┘ │ Resolves Promise on User Action ▼ ┌───────────────────────────────┐ │ isConfirmed === true / false │ └───────────────────────────────┘ ``` 1. **Mount `` Once:** Place at your application root (e.g. `layout.tsx`). 2. **Call Anywhere:** Trigger `nui.confirm(...)` or `nui.alert(...)` anywhere in client handlers, async utilities, or data-fetching interceptors. 3. **Promise-Driven Flow:** Await the user's decision without managing local open/close state. --- ## Root Setup Mount `` once in your root layout: ```tsx // app/layout.tsx (Next.js App Router) import { DialogProvider } from '@nofinite/nui'; export default function RootLayout({ children, }: { children: React.ReactNode; }) { return ( {children} ); } ``` --- ## Dialog Types & Usage ### Destructive Confirm Dialog Use `nui.confirm()` to ask users for explicit confirmation before carrying out irreversible actions: ```tsx 'use client'; import { nui, Button } from '@nofinite/nui'; export function DeleteAccountButton() { const handleDelete = async () => { const isConfirmed = await nui.confirm( 'Are you absolutely sure? All data associated with this account will be permanently erased.', { title: 'Delete Account', confirmText: 'Yes, Delete', cancelText: 'Cancel', isDanger: true, } ); if (isConfirmed) { // Proceed with deletion API call nui.success('Account deleted successfully.'); } else { nui.toast('Deletion cancelled.'); } }; return ( ); } ``` ### Informational Alert Dialog Use `nui.alert()` when the user must acknowledge important information or terms before proceeding: ```tsx 'use client'; import { nui, Button } from '@nofinite/nui'; export function TermsDialogButton() { const handleShowTerms = async () => { await nui.alert( 'By clicking continue, you agree to our updated Terms of Service and Privacy Policy.', { title: 'Terms of Service Update', confirmText: 'I Understand', } ); console.log('Terms acknowledged'); }; return ( ); } ``` --- ## Dialog Options Reference `nui.confirm(message, options)` and `nui.alert(message, options)` accept an optional configuration object: | Option | Type | Default | Description | | :--- | :--- | :--- | :--- | | `title` | `string` | `'Confirm'` / `'Alert'` | The heading displayed at the top of the dialog | | `confirmText` | `string` | `'Confirm'` / `'OK'` | Label for the primary action button | | `cancelText` | `string` | `'Cancel'` | Label for the cancel button (confirm dialogs only) | | `isDanger` | `boolean` | `false` | When true, renders the primary button with `variant="danger"` | --- ## Keyboard Interaction | Key | Behavior | | :--- | :--- | | Tab | Cycles focus between active dialog buttons | | Shift + Tab | Reverse cycles focus | | Enter | Activates the currently focused button | | Escape | Dismisses alert dialogs (confirm dialogs disable outside dismissal to prevent accidents) | --- ## Accessibility - Automatically traps keyboard focus within the dialog container while active. - Employs semantic dialog roles (`role="alertdialog"` for destructive confirms). - Disables background scrolling and backdrop interaction while open. - Restores focus to the triggering element upon dialog dismissal. --- ## Best Practices ### Do - Mount `` once at the application root. - Use `isDanger: true` for permanent or destructive flows (deleting databases, removing team members). - Pair `nui.confirm()` with `nui.toast()` or `nui.success()` to deliver instant feedback upon resolution. - Keep dialog messages clear, unambiguous, and concise. ### Don't - Do not mount multiple `` instances across nested routes. - Do not trigger dialogs synchronously during component rendering; always invoke within event handlers or effects. - Avoid using confirm dialogs for minor or easily undoable operations. --- ## API Reference --- ### Document: nui/components/divider/page.mdx # Divider A fully accessible, token-driven Divider component built with strict WAI-ARIA compliance. ```tsx import { Divider } from '@nofinite/nui'; ``` --- ## Interactive Preview --- ## Usage ### Basic Example ```tsx import { Divider } 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/drawer/page.mdx # Drawer A controlled overlay panel that slides from an edge of the viewport. Implements focus trapping, scroll locking, inert background handling, escape key support, and animated mount/unmount lifecycle. ```tsx import { Drawer } from '@nofinite/nui'; ``` --- ## Interactive Preview --- ## Usage ### Basic (Right side) ```tsx import { Drawer } from '@nofinite/nui'; const [open, setOpen] = useState(false); <> setOpen(false)}> Drawer content ; ``` ### Left position ```tsx Sidebar content ``` ### Bottom sheet ```tsx Mobile sheet content ``` ### Disable Escape + Outside click ```tsx Forced interaction ``` --- ## Subcomponents None exposed. --- ## Variants Drawer supports structural and behavioral variants. ```tsx ``` **Available variants:** - right (default) - left - top - bottom - escape-disabled - outside-click-disabled **Guidelines:** - Use right/left for navigation or contextual panels - Use bottom for mobile sheet patterns - Avoid disabling both escape and outside click unless required by workflow --- ## Sizes Drawer width/height is position-dependent: | Position | Default Dimension | | ---------- | --------------------------------------- | | left/right | `max-width: 320px` | | top/bottom | `min-height: 250px`, `max-height: 90vh` | Width/height should be customized via `className` and layout utilities. --- ## Shapes / Modes **Positions** - Left - Right - Top - Bottom **States** - Mounted (in DOM) - Visible (animated open) - Closed (animated exit) - Escape-triggered close - Outside-click close - Scroll-locked background - Focus-trapped - Inert-applied siblings --- Z-index stack: - Overlay: `9998` - Drawer: `9999` Overlay uses backdrop blur + 0.5 opacity. --- ## Accessibility Implemented behavior: - `role="dialog"` - `aria-modal="true"` - Focus trapped while open - Previous focus restored on close - Escape key close (configurable) - Background content inert while open - Scroll lock applied to body - Click outside detection (configurable) - `prefers-reduced-motion` respected Note: Overlay is `aria-hidden="true"` because it is non-interactive. --- ## Animation Model Two-phase state system: - `isMounted` → Controls DOM presence - `isVisible` → Controls CSS transition state Exit animation delay: 300ms Entrance delay before activation: ~15ms (transition trigger) Uses GPU-accelerated `transform` transitions. --- ## Best practices ### Do - Control open state from parent - Use semantic heading inside drawer - Provide a visible close button - Keep drawer width constrained ### Don’t - Use Drawer for full-screen modal (use Modal) - Disable escape without strong reason - Mount heavy trees inside if frequent toggling - Stack multiple drawers without z-index management --- ## API Reference --- ### Document: nui/components/dropdown/page.mdx # Dropdown A composable, accessible Dropdown component for modern React applications. ```tsx import { Dropdown } from '@nofinite/nui'; ``` --- ## Interactive Preview --- A compound menu component for contextual actions anchored to a trigger. Implements controlled open state via internal context, keyboard navigation, focus restoration, and outside-click dismissal. NUI provides a **Dual-Mode Architecture** for Dropdown: use **Plug and Play (PnP)** mode for rapid data-driven menus, or **Compound Primitives** for complete custom layout control. --- ## Usage ### 1. Plug and Play (PnP) Mode — Zero Boilerplate Pass an array of items directly via the `data` prop. NUI automatically constructs the menu, renders items, handles separators, disabled states, and keyboard navigation without requiring manual subcomponent declarations: ```tsx import { Dropdown, Button } from '@nofinite/nui'; export function QuickDropdown() { const items = [ { label: 'View Profile', onClick: () => console.log('Profile') }, { label: 'Account Settings', onClick: () => console.log('Settings') }, { type: 'separator' as const }, { label: 'Billing & Invoices', onClick: () => console.log('Billing') }, { label: 'Admin Dashboard', disabled: true }, { type: 'separator' as const }, { label: 'Log Out', onClick: () => console.log('Logout') }, ]; return ( ); } ``` --- ### 2. Composable Compound Mode — Full Structural Control When you need custom item markup, badges, custom header blocks, or specific icon layouts, assemble the compound primitives directly: ```tsx import { Dropdown, Button } from '@nofinite/nui'; export function CustomDropdown() { return ( console.log('Profile')}>Profile console.log('Settings')}>Settings console.log('Logout')}>Logout ); } ``` --- ### End-Aligned Menu ```tsx More Edit Delete ``` --- ## Props Reference ### Dropdown (Root) | Prop | Type | Default | Description | | --------- | -------------------- | --------- | --------------------------------------------------------------------------- | | `data` | `DropdownDataItem[]` | — | **Plug and Play Mode:** Array of menu items, separators, and callbacks. | | `align` | `'start' \| 'end'` | `'start'` | Menu alignment relative to trigger. | | `children`| `ReactNode` | — | Trigger element (in PnP mode) or compound children (in compound mode). | ### Dropdown.Trigger | Prop | Type | Description | | ---------- | ----------- | -------------------------------------------------------------------- | | `children` | `ReactNode` | Element to act as the menu trigger. Automatically cloned with props. | ### Dropdown.Menu | Prop | Type | Default | Description | | ----------- | ------------------ | ----------- | ------------------------------------------ | | `align` | `'start' \| 'end'` | `'start'` | Horizontal alignment relative to trigger. | | `children` | `ReactNode` | — | Collection of `` elements. | ### Dropdown.Item | Prop | Type | Description | | ---------- | --------------------- | ------------------------------------------- | | `onClick` | `(e) => void` | Click handler. Closes dropdown upon firing. | | `disabled` | `boolean` | If true, dims item and prevents click. | | `children` | `ReactNode` | Content to render inside the menu item. | --- ## Subcomponents - `Dropdown.Trigger` - `Dropdown.Menu` - `Dropdown.Item` --- ## Accessibility - **WAI-ARIA Pattern:** Adheres strictly to the WAI-ARIA Menu button pattern. - **Keyboard Navigation:** `ArrowDown` / `ArrowUp` cycles through menu items; `Escape` closes the menu and restores focus to the trigger button. - **Outside Click:** Automatically closes when clicking anywhere outside the menu. - **Focus Restoration:** Focus is cleanly returned to the trigger element when the menu closes. --- ## API Reference --- ### Document: nui/components/editor/page.mdx # Editor > [!NOTE] > `@nofinite/markon` (v2.0.0) is the standalone rich document suite powered by TipTap 3 and ProseMirror. For full documentation including MarkonRender, custom extensions, and toolbar configs, visit the dedicated [Markon Documentation Hub](/markon). A production-ready, feature-rich WYSIWYG rich text editor powered by TipTap 3 and ProseMirror. Ships with 28 toolbar formatting tools, a floating bubble menu, slash commands (`/`), KaTeX mathematical equations, code syntax highlighting, YouTube/Vimeo video embeds, resizable images, and accessible keyboard shortcuts. ```tsx import { MarkonEditor } from '@nofinite/markon/react'; ``` --- ## Interactive Preview --- ## Key Features - **28 Toolbar Actions**: Headings (H1-H3), bold, italic, underline, strikethrough, alignment, lists, task checklists, blockquotes, code blocks, font families, font sizes, text & highlight colors. - **Contextual Bubble Menu**: Automatically emerges above text selections or media items for lightning-fast inline styling and image layout adjustments. - **Slash Commands (`/`)**: Type `/` anywhere on an empty line to invoke a keyboard-navigable command palette to insert headers, tables, callouts, and embeds. - **Mathematical Equations**: Seamless LaTeX rendering powered by KaTeX. - **Media Resizing**: Drag handles and pre-set width buttons (25%, 50%, 100%, float left, float right) for embedded images and videos. - **Zero Configuration**: Built-in styling with semantic token support and dark mode integration out of the box. --- ## Usage ### Basic Usage ```tsx import { useState } from 'react'; import { MarkonEditor } from '@nofinite/markon/react'; export default function MyEditor() { const [content, setContent] = useState('

Hello World!

'); return ( ); } ``` ### With Custom File Upload Handler Handle drag-and-drop or file picker image uploads with an async cloud upload provider: ```tsx { const formData = new FormData(); formData.append('file', file); const res = await fetch('/api/upload', { method: 'POST', body: formData }); const { url } = await res.json(); return url; }} /> ``` --- ## Keyboard Shortcuts | Shortcut | Action | | :--- | :--- | | ⌘ + B / Ctrl + B | Toggle Bold | | ⌘ + I / Ctrl + I | Toggle Italic | | ⌘ + U / Ctrl + U | Toggle Underline | | ⌘ + K / Ctrl + K | Set or Edit Hyperlink | | / | Trigger Slash Commands Menu | | Shift + Enter | Soft Line Break (`
`) | --- ## Best Practices ### Do - Provide an `onUploadFile` callback when using image uploads to prevent heavy base64 strings from bloating your database. - Utilize the placeholder prop to guide users when the document is empty. - Rely on semantic tokens for dark mode compatibility. ### Don't - Do not wrap the editor in unstyled containers with `overflow: hidden` that may clip the floating Bubble Menu or slash command list. - Avoid passing un-sanitized external HTML into the editor if rendering raw untrusted user input elsewhere. --- ## API Reference --- ### Document: nui/components/emptystate/page.mdx # Empty State A fully accessible, token-driven EmptyState component built with strict WAI-ARIA compliance. ```tsx import { EmptyState } from '@nofinite/nui'; ``` --- ## Interactive Preview --- ## Usage ### Basic Example ```tsx import { EmptyState } 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/fileuploader/page.mdx # File Uploader `FileUploader` is a flexible file upload component that supports drag-and-drop, click-to-upload, keyboard interaction, file previews, and file removal. It works for both single and multiple file uploads with optional file type filtering. ```tsx import { FileUploader } from '@nofinite/nui'; ``` --- ## Interactive Preview --- ## Usage ### Basic usage ```tsx import { FileUploader } from '@nofinite/nui'; console.log(files)} />; ``` --- ### Multiple files ```tsx ``` --- ### Controlled state ```tsx const [files, setFiles] = useState([]); ; ``` --- ### With restrictions ```tsx ``` --- ### Disabled ```tsx ``` --- ## Subcomponents None exposed. --- ## Variants ```tsx ``` **Available variants:** - single (default) - multiple - disabled - type-restricted - size-restricted **Guidelines:** - Use multiple for gallery or document uploads - Always provide accept when backend enforces MIME - Use size restriction to avoid unnecessary network cost --- ## Sizes Layout behavior: | Element | Behavior | | --------- | --------------------------- | | Dropzone | full-width container | | File list | vertical stack | | File item | auto height with truncation | | Icons | fixed (16–24px) | Sizing is controlled via layout utilities and token spacing. --- ## Shapes / Modes **Interaction states** - Idle - Drag-over - File-selected - File-removed - Disabled **Data modes** - Controlled - Uncontrolled - Multi-file aggregation - Size-filtered - MIME-filtered (native) --- ## Accessibility Implemented: - Dropzone - `role="button"` - keyboard activation (Enter/Space) - focus-visible outline - `aria-disabled` - drag event semantics - Remove button - aria-label per file - Hidden input remains native for browser accessibility - Programmatic focus preserved Limitations: - No upload progress semantics - No aria-live updates for file list - No error announcement for rejected files - Drag announcements depend on browser behavior --- ## Animation model - File item pop-in via translateY + fade - Duration: 200ms - Drag-over visual highlight - Motion disabled with `prefers-reduced-motion` No exit animation for removal. --- ## Architectural notes Key design decisions: - Input proxy pattern - Controlled/uncontrolled duality - Immutable file list replacement - Size validation pre-merge - Stable file key generation using name + size + lastModified - Drag state isolation - Event propagation control Potential caveat: - File object identity used for removal (same file reselect handled via input reset) --- ## Best practices ### Do - Validate server-side regardless of client filters - Provide accept to guide user selection - Use multiple for batch uploads - Display upload progress externally if needed ### Don’t - Depend on client MIME filtering for security - Upload extremely large files without chunking - Store File objects long-term in global state - Render heavy previews synchronously --- ## API Reference --- ### Document: nui/components/form/page.mdx # Form A fully accessible, token-driven Form component built with strict WAI-ARIA compliance. ```tsx import { Form } from '@nofinite/nui'; ``` --- ## Interactive Preview --- ## Usage ### Basic Example ```tsx import { Form } 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/hovercard/page.mdx # Hover Card `HoverCard` is a floating content container that appears when a user hovers over or focuses on a trigger element. It is useful for previews, tooltips with rich content, user cards, and contextual details. ```tsx import { HoverCard } from '@nofinite/nui'; ``` --- ## Interactive Preview --- ## Usage ### Basic usage ```tsx import { HoverCard } from '@nofinite/nui'; User preview ; ``` --- ### Top placement ```tsx Top card ``` --- ### Custom delays ```tsx Delayed card ``` --- ### Content | Prop | Type | Default | Description | | --------- | ----------------------- | -------- | ---------------------------- | | placement | `'top' \| 'bottom'` | `bottom` | Preferred vertical placement | | offset | number | 8 | Distance from trigger | | className | string | — | Style override | | children | ReactNode | — | Content body | Extends `React.HTMLAttributes`. --- ## Subcomponents - HoverCard.Trigger - HoverCard.Content --- ## Variants ```tsx ``` **Available variants:** - default-delay - custom-delay - top - bottom - auto-flip **Guidelines:** - Use hovercard for previews or metadata - Avoid embedding critical actions - Maintain short dwell open delays --- ## Sizes | Element | Behavior | | ------- | --------------------- | | Content | min 240px / max 360px | | Padding | token-based spacing | | Width | intrinsic with clamp | Sizing should be customized via tokens or class overrides. --- ## Shapes / Modes **Interaction states** - Closed - Scheduled-open - Visible - Scheduled-close - Hover-persistent - Escape-dismissed - Outside-click dismissed **Placement states** - Bottom - Top - Collision-flipped --- z-dropdown` Shadow uses soft dual-layer elevation. --- ## Accessibility Implemented: - Trigger - `aria-haspopup="dialog"` - `aria-expanded` - `aria-controls` - focus-triggered open - Content - `role="dialog"` - ESC dismiss - click-outside dismiss - Hover persistence prevents premature close - Portal avoids stacking context clipping Limitations: - No focus trap (intentional for hover semantics) - No aria-live announcements - Screen reader discovery relies on focus - Keyboard navigation inside card not enforced --- ## Animation model - Entry animation: scale + translate + fade - Duration: 150ms cubic-bezier easing - Placement-aware transform origin - Motion disabled via `prefers-reduced-motion` No exit animation (timer-based unmount). --- ## Architectural notes Key behaviors: - Timer orchestration prevents hover jitter - Portal rendering solves overflow clipping - Collision-aware vertical flipping - Horizontal clamp with viewport padding - Scroll + resize reactive positioning - Hover-safe bridging between trigger and card - Layout-safe positioning via `useLayoutEffect` - Compound component architecture with shared context Potential caveat: - Position recalculation may be expensive under heavy scroll containers --- ## Best practices ### Do - Use for previews, metadata, secondary info - Keep content lightweight - Maintain open delay to avoid accidental triggers - Provide keyboard focusable content if interactive ### Don’t - Use as replacement for tooltip or modal - Put destructive actions inside - Depend on hovercard for critical information - Render large trees inside portal --- ## API Reference --- ### Document: nui/components/image/page.mdx # Image A fully accessible, token-driven Image component built with strict WAI-ARIA compliance. ```tsx import { Image } from '@nofinite/nui'; ``` --- ## Interactive Preview --- ## Usage ### Basic Example ```tsx import { Image } 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/input/page.mdx # Input A composable text entry primitive supporting label association, validation messaging, icon affordances, and token-driven sizing. Implements WCAG-compliant labeling, dynamic `aria-describedby` linkage, and visual state management for error and disabled conditions. ```tsx import { Input } from '@nofinite/nui'; ``` --- ## Interactive Preview --- ## Usage ### Basic ```tsx import { Input } from '@nofinite/nui'; ``` --- ### With description ```tsx ``` --- ### Error state ```tsx ``` --- ### With icons ```tsx } rightIcon={⌘K} /> ``` --- ### Sizes ```tsx ``` --- ## Variants ```tsx } /> } /> ``` **Available variants:** - default - sm - md - lg - error - with-left-icon - with-right-icon - disabled - required **Guidelines:** - Prefer description for guidance, error for validation - Avoid both description and error simultaneously - Maintain icon visual balance across sizes --- ## Sizes | Size | Height | Padding | Font | | ---- | ------ | ------- | ---- | | sm | 32px | space-2 | xs | | md | 40px | space-3 | sm | | lg | 48px | space-4 | base | Icon padding dynamically adjusts via `--has-left` and `--has-right`. --- ## Shapes / Modes **Interaction states** - Default - Hover - Focus-visible - Disabled - Error - Required - With-left-icon - With-right-icon **Content states** - Label present - Description present - Error present (description suppressed) --- ## Accessibility Implemented: - `label` → `htmlFor` association - Auto-generated id via `useId` - Dynamic `aria-describedby` - `aria-invalid` on error - `aria-live="polite"` error announcement - Required indicator with `aria-hidden` - Keyboard focus ring using `:focus-visible` - Disabled semantic state Limitations: - No input masking semantics - No explicit autocomplete guidance - No validation role mapping beyond `aria-invalid` --- ## Animation model - Border and shadow transitions (200ms) - Focus ring expansion - No layout animations - Motion reduction inherits browser preference --- ## Architectural notes Key behaviors: - WCAG linkage via deterministic id generation - Error precedence over description - Absolute positioned icons with padding compensation - Token-driven sizing architecture - CSS-only icon alignment (no JS measurement) - ForwardRef enables form library interoperability - Minimal re-render footprint (pure render) Potential caveat: - Fixed icon width assumption (16px) may misalign with custom icon sets --- ## Best practices ### Do - Use label for accessibility even if visually hidden - Provide descriptive error messages - Keep icon semantics decorative unless interactive - Maintain consistent size usage within forms - Use `required` only when validation enforced ### Don’t - Replace labels with placeholders - Place interactive elements inside icon slots - Depend solely on color for validation signaling - Render heavy nodes inside description/error --- ## API Reference --- ### Document: nui/components/kanban/page.mdx # Kanban Board > [!NOTE] > `@nofinite/kanban` is a standalone package powered by Atlassian Pragmatic Drag-and-Drop, featuring WIP limits, column reordering, search filtering, and imperative handles. Visit the dedicated [Kanban Documentation Hub](/kanban) for the complete guide. An accessible, responsive drag-and-drop workflow board powered by `@atlaskit/pragmatic-drag-and-drop`. Supports reorderable columns, draggable task cards, member avatars, priority status badges, and custom drag events. ```tsx import { Kanban } from '@nofinite/kanban/react'; ``` --- ## Interactive Preview --- ## Key Features - **Smooth Drag-and-Drop**: Fluid physics powered by Pragmatic DnD with clear drop targets and drag elevation shadows. - **Card Metadata**: Native support for tags, assignees, dates, and priority indicators (`low`, `medium`, `high`, `urgent`). - **Flexible Column Config**: Customize titles, column actions, card limits, and add-card buttons. - **Accessible Interactions**: Keyboard support for moving cards between columns with arrow keys. - **Mobile Friendly**: Horizontal scroll containers with responsive touch-friendly cards. --- ## Usage ### Basic Usage ```tsx import React, { useState } from 'react'; import { Kanban } from '@nofinite/kanban/react'; export default function MyBoard() { const [columns, setColumns] = useState([ { id: 'backlog', title: 'Backlog', items: [ { id: '1', content: }, { id: '2', content: } ] }, { id: 'in-progress', title: 'In Progress', items: [ { id: '3', content: } ] }, { id: 'completed', title: 'Completed', items: [ { id: '4', content: } ] } ]); return ( ); } ``` --- ## Best Practices ### Do - Provide unique string identifiers for every column and card (`id`). - Persist state changes via the `onCardMove` callback to keep your remote backend synchronized. - Keep card titles concise and move lengthy notes into card descriptions or popovers. ### Don't - Avoid placing dense nested clickable inputs inside cards that interfere with drag event listeners. - Do not overload a single column with thousands of un-paginated cards; consider archiving completed tasks. --- ## API Reference --- ### Document: nui/components/kbd/page.mdx # Kbd A fully accessible, token-driven Kbd component built with strict WAI-ARIA compliance. ```tsx import { Kbd } from '@nofinite/nui'; ``` --- ## Interactive Preview --- ## Usage ### Basic Example ```tsx import { Kbd } 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/layout/page.mdx # Layout A low-level layout system providing constraint-based width management, flexbox composition, and responsive grid orchestration. Implements attribute-driven styling, CSS variable gap control, and compositional wrappers for common layout patterns. ```tsx import { Container } from '@nofinite/nui'; ``` --- ## Interactive Preview --- ## Usage ### Container ```tsx import { Container } from '@nofinite/nui'; Content ``` --- ### Flex ```tsx import { Flex } from '@nofinite/nui'; ``` --- ### Stack (vertical sugar) ```tsx import { Stack } from '@nofinite/nui'; ``` --- ### HStack (horizontal sugar) ```tsx Name ``` --- ### Grid responsive auto-fit ```tsx ``` --- ### Grid fixed columns ```tsx ``` --- ### Flex | Prop | Type | Default | Description | | ----------- | ------------------------------------------------------------------- | ------- | ------------------------ | | `direction` | `'row' \| 'column' \| 'row-reverse' \| 'column-reverse'` | row | Flex direction | | `align` | `'start' \| 'center' \| 'end' \| 'stretch' \| 'baseline' ` | stretch | Cross-axis alignment | | `justify` | `'start' \| 'center' \| 'end' \| 'between' \| 'around' \| 'evenly'` | start | Main-axis alignment | | `wrap` | `'wrap' \| 'nowrap' \| 'wrap-reverse'` | nowrap | Wrapping behavior | | `gap` | `number \| string ` | 0 | Spacing between children | Extends `React.HTMLAttributes`. --- ### Grid | Prop | Type | Default | Description | | ------------- | ------------------------------------- | ------------ | --------------------------- | | `columns` | `number \| 'auto-fit' \| 'auto-fill'` | `'auto-fit'` | Column strategy | | `gap` | `number \| string` | `16` | Grid spacing | | `minColWidth` | `string` | `250px` | Min width for auto-fit/fill | Extends `React.HTMLAttributes`. --- ## Variants ```tsx ``` **Available variants:** - container-sm - container-md - container-lg - container-xl - container-full - flex-row - flex-column - flex-wrap - flex-between - grid-fixed - grid-auto-fit - grid-auto-fill **Guidelines:** - Use container only for page-level width constraints - Prefer Stack/HStack for semantic layout clarity - Use grid auto-fit for responsive card systems --- ## Sizes ### Container | Size | Max width | | ---- | --------- | | sm | 640px | | md | 768px | | lg | 1024px | | xl | 1280px | | full | 100% | --- ## Shapes / Modes **Flex states** - Direction variants - Alignment variants - Justification variants - Wrap variants - Dynamic gap **Grid states** - Fixed columns - Auto-fit responsive - Auto-fill responsive - Variable gap - Dynamic min column width **Container states** - Constrained - Full width --- zontal padding uses spacing token fallback. --- ## Accessibility Implemented: - Pure structural layout primitives - No semantic role overrides - Maintains DOM reading order - Stack/HStack improve readability through composition - Grid maintains source-order navigation Limitations: - No landmark roles - No spatial navigation hints - Visual grouping not announced to assistive tech --- ## Animation model - No intrinsic animation - Gap and direction changes reflow naturally - Motion delegated to consumer layer --- ## Architectural notes Key behaviors: - Attribute-driven CSS mapping (low runtime cost) - CSS variable gap allows dynamic spacing without class explosion - Stack/HStack are syntactic composition wrappers - Grid responsive behavior using `minmax` - Container provides centralized layout constraint primitive - ForwardRef enables integration with measurement libraries Potential caveats: - CSS variable gap prevents static extraction in some atomic CSS systems - Auto-fit grid may create uneven column counts with extreme widths --- ## Best practices ### Do - Prefer Stack/HStack over manual flex direction for readability - Use auto-fit grid for responsive cards - Keep container usage at layout boundaries - Standardize gap tokens for visual rhythm - Combine grid + flex for complex layouts ### Don’t - Nest containers excessively - Mix grid and flex alignment semantics incorrectly - Use fixed column grid for highly dynamic content - Depend on layout primitives for spacing-only concerns --- ## API Reference --- ### Document: nui/components/link/page.mdx # Link Typographic navigation element designed for inline navigation inside paragraphs, lists, and breadcrumbs. For action-oriented links that require button affordance (padding/background), use **Button with `asChild`** instead. ```tsx import { Link } from '@nofinite/nui'; ``` --- ## Interactive Preview --- ## Usage ### Basic usage ```tsx import { Link } from '@nofinite/nui'; Documentation; ``` --- ### Variants ```tsx Default Primary Muted Danger ``` --- ### Underline control ```tsx Hover underline Always underline No underline ``` --- ### External link Automatically applies secure routing attributes. ```tsx External resource ``` --- ### Framework routing (polymorphic) ```tsx 'use client'; import NextLink from 'next/link'; import { Link } from '@nofinite/nui'; Go to card ; ``` --- ### Button as link (CTA pattern) ```tsx 'use client'; import NextLink from 'next/link'; import { Button } from '@nofinite/nui'; ; ``` --- ## Variants ### Color variants - **default** — neutral text color - **primary** — accent navigation link - **muted** — low emphasis navigation - **danger** — destructive navigation ### Underline variants - **none** — removes underline - **hover** — underline appears on hover - **always** — persistent underline **Guidelines** - Use **primary** for contextual navigation emphasis - Use **muted** for secondary inline links - Use **danger** only for destructive navigation contexts - Prefer **hover underline** for body text readability --- ## States - Default - Hover - Focus visible - Active (browser native) - Disabled (via native anchor behavior) - External link state --- ## Keyboard Interaction | Key | Behavior | | ----------- | -------------------- | | Tab | Moves focus to link | | Enter | Activates navigation | | Shift + Tab | Moves focus backward | --- ## Accessibility - Uses semantic `` element by default - Preserves accessibility when `asChild` is used - `focus-visible` outline ensures keyboard focus visibility - External links include security attributes preventing tabnabbing - Underline ensures link affordance in text contexts - Compatible with screen readers via native anchor semantics --- ## Best Practices ### Do - Use for inline navigation inside text - Use `asChild` for framework router integration - Use `isExternal` for outbound links - Maintain underline in long-form content ### Don’t - Use for button-like CTAs with backgrounds - Remove underline in dense paragraph navigation without other affordance - Use danger variant for non-destructive navigation --- ## API Reference --- ### Document: nui/components/linkpreview/page.mdx # Link Preview A rich URL bookmark preview card that displays fetched OpenGraph metadata including page titles, descriptions, domain hostnames, and hero thumbnails. Includes built-in loading skeletons and error fallbacks. ```tsx import { LinkPreview } from '@nofinite/nui'; ``` --- ## Interactive Preview --- ## Key Features - **Rich OpenGraph Presentation**: Visual cards that elevate standard hyperlinks into rich media bookmarks. - **Loading Skeleton State**: Clean shimmer animations while asynchronous URL metadata resolves. - **Graceful Error Handling**: Automatically renders a safe fallback anchor if metadata extraction fails. - **Accessible Anchor Semantics**: Preserves standard keyboard navigation and screen reader link announcements. --- ## Usage ### Basic Usage ```tsx import { LinkPreview } from '@nofinite/nui'; export default function BookmarkExample() { return ( ); } ``` ### Loading State ```tsx ``` --- ## Best Practices ### Do - Use LinkPreview in rich text feeds, documentation footnotes, and chat messengers to give users visual context before clicking external links. - Cache OpenGraph server responses to avoid repeated scraping of external URLs. ### Don't - Do not use LinkPreview as a substitute for inline navigation menus or dense breadcrumbs. --- ## API Reference --- ### Document: nui/components/megamenu/page.mdx # Mega Menu A compositional navigation primitive implementing a trigger-controlled expandable panel for complex multi-column navigation, category exploration, and marketing content. Built with context-driven state orchestration, outside-click dismissal, and keyboard escape handling. ```tsx import { MegaMenu } from '@nofinite/nui'; ``` --- ## Interactive Preview --- ## Usage ### Basic ```tsx import { MegaMenu } from '@nofinite/nui'; Products Content ``` --- ### Multi-column layout ```tsx Solutions ``` --- ### Rich marketing panel ```tsx Platform ``` --- ### MegaMenu.Trigger | Prop | Type | Default | Description | | --------- | ----------------- | ------- | -------------------- | | className | string | — | Trigger override | | onClick | MouseEventHandler | — | Custom click handler | | children | ReactNode | — | Label / content | Extends `React.ButtonHTMLAttributes`. --- ### MegaMenu.Content | Prop | Type | Default | Description | | --------- | --------- | ------- | -------------- | | className | string | — | Panel override | | children | ReactNode | — | Panel content | Extends `React.HTMLAttributes`. --- ## 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 } >

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(false)} title="Production Deployment" description="Configure edge nodes and SSL certificate options." footer={ <> } >

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(false)} initialFocusRef={inputRef} > Rename Project Choose a unique identifier for your workspace. ); } ``` --- ### 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} ); } ``` --- ## 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 `