# @nice2dev/ui

**Universal, themeable, i18n-ready React component library** — 160+ production-grade UI components with zero external runtime dependencies. Built as a complete replacement for DevExtreme with a modern, lightweight architecture.

[![npm](https://img.shields.io/npm/v/@nice2dev/ui)](https://www.npmjs.com/package/@nice2dev/ui)
[![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](LICENSE)
[![TypeScript](https://img.shields.io/badge/TypeScript-5.x-3178C6?logo=typescript&logoColor=white)](https://www.typescriptlang.org/)
[![React](https://img.shields.io/badge/React-17%2B-61DAFB?logo=react&logoColor=white)](https://react.dev/)
[![Bundle Size](https://img.shields.io/badge/bundle-347kB%20gzipped-brightgreen)](https://www.npmjs.com/package/@nice2dev/ui)
[![Zero Dependencies](https://img.shields.io/badge/dependencies-0-success)](https://www.npmjs.com/package/@nice2dev/ui)

---

## 📦 Per-Package Import Matrix

Three ways to import the same component — pick the strategy that fits your bundling model:

```ts
// 1. Monolith (simplest)
import { NiceDataGrid } from '@nice2dev/ui';

// 2. Subpath export (better code splitting, single package install)
import { NiceDataGrid } from '@nice2dev/ui/data';

// 3. Per-domain facade package (best for microfrontends / RSC)
import { NiceDataGrid } from '@nice2dev/ui-data';
```

**Canonical, exhaustive matrix:** [docs/PER_PACKAGE_IMPORT_MATRIX.md](../../docs/PER_PACKAGE_IMPORT_MATRIX.md) — covers all 200+ components, 11 subpath exports, and the per-domain facade packages (`@nice2dev/ui-data`, `-charts`, `-feedback`, `-overlays`, `-nav`, `-display`, `-editors`, `-planning`, `-mobile`, ...).

Quick reference — most common areas:

| Area                                         | Subpath                       | Facade package          |
| -------------------------------------------- | ----------------------------- | ----------------------- |
| Charts & gauges                              | `@nice2dev/ui/charts`         | `@nice2dev/ui-charts`   |
| Grids, tables, lists, kanban                 | `@nice2dev/ui/data`           | `@nice2dev/ui-data`     |
| Inputs, pickers, editors                     | `@nice2dev/ui/editors`        | `@nice2dev/ui-editors`  |
| Alerts, modals, toasts                       | `@nice2dev/ui/feedback`       | `@nice2dev/ui-feedback` |
| Tabs, menu, layouts, breadcrumb              | `@nice2dev/ui/navigation`     | `@nice2dev/ui-nav`      |
| Windows, popovers, command palette           | `@nice2dev/ui/overlays`       | `@nice2dev/ui-overlays` |
| Git tools / CI/CD                            | `@nice2dev/ui/devops`         | —                       |
| Low-code studio, page builder                | `@nice2dev/ui/no-code`        | —                       |
| Git-like data versioning (ERP)               | `@nice2dev/ui/data-branching` | —                       |
| Buttons, badges, display widgets             | `@nice2dev/ui` (root)         | `@nice2dev/ui-display`  |
| Scheduler, gantt, timeline                   | `@nice2dev/ui` (root)         | `@nice2dev/ui-planning` |
| Touch & mobile (bottom sheet, gestures, ...) | — (extracted in v1.0.10)      | `@nice2dev/ui-mobile`   |

> Facade packages are pure re-exports — same singleton, zero duplication. They require `@nice2dev/ui` as a peer dependency.

---

## Table of Contents

- [Features](#features)
- [Installation](#installation)
- [Quick Start](#quick-start)
- [Component Catalog](#component-catalog)
  - [Editors (28)](#editors-28-components)
  - [Buttons (5)](#buttons-5-components)
  - [Data Display (13)](#data-display-13-components)
  - [Feedback (6 + 1 hook)](#feedback-6-components--1-hook)
  - [Navigation (16)](#navigation-16-components)
  - [Data (11)](#data-11-components)
  - [Charts (16)](#charts-16-components)
  - [Overlays & Layout (9)](#overlays--layout-9-components)
  - [Planning (4)](#planning-4-components)
  - [Tools (14)](#tools-14-components)
  - [Validation (3 + 1 hook)](#validation-3-components--1-hook)
- [Core Infrastructure](#core-infrastructure)
  - [Shared Types](#shared-types)
  - [Hooks](#hooks)
  - [Icon System](#icon-system)
  - [Internationalization (i18n)](#internationalization-i18n)
- [Theming](#theming)
  - [CSS Custom Properties](#css-custom-properties)
  - [Dark Mode](#dark-mode)
  - [Custom Themes](#custom-themes)
- [Build & Development](#build--development)
- [Architecture](#architecture)
- [Companion Package: @nice2dev/icons](#companion-package-nice2devicons)

---

## Features

- **160+ components** covering all major UI categories (editors, data grids, charts, planning, overlays, navigation, desktop, and more)
- **Zero runtime dependencies** — only `react` and `react-dom` as peer dependencies
- **78 built-in SVG icons** — no icon library required for common UI chrome
- **Pluggable icon system** — swap in FontAwesome, Material Icons, or any custom set via `NiceIconProvider`
- **i18n-ready** — plug in any translation function (react-i18next, custom) via `NiceI18nProvider`; works without a provider out of the box
- **CSS custom properties theming** — 7 built-in theme presets, live Theme Designer, full dark mode
- **Dark mode** — automatic (`prefers-color-scheme`) and manual (class or `data-theme` attribute)
- **Touch & mobile optimized** — adaptive 44px+ touch targets, pointer event support, responsive breakpoints, no hover stickiness
- **Access control** — built-in per-component access modes (`full`, `readOnly`, `disabled`, `hidden`) with `NiceAccessControl` provider
- **Responsive utilities** — `useBreakpoint`, `useMediaQuery`, `useResponsiveValue`, `useContainerSize` hooks + responsive CSS
- **Tree-shakeable** — ESM output for optimal bundling
- **TypeScript-first** — strict mode, full type definitions shipped with the package
- **Embeddable Showcase** — `<NiceShowcase />` component with About page, live demos, theme designer, and component configurator

---

## Installation

```bash
npm install @nice2dev/ui
# or
yarn add @nice2dev/ui
# or
pnpm add @nice2dev/ui
```

**Peer dependencies:** `react >= 17.0.0`, `react-dom >= 17.0.0`

---

## Quick Start

```tsx
import { NiceButton, NiceTextInput, NiceIcon } from '@nice2dev/ui';
import '@nice2dev/ui/style.css';

function App() {
  return (
    <div>
      <NiceTextInput label="Name" placeholder="Enter your name" />
      <NiceButton variant="primary" icon={<NiceIcon name="check" />}>
        Submit
      </NiceButton>
    </div>
  );
}
```

---

## Code Splitting & Tree Shaking

For optimal bundle size, import only the components you need. The library supports multiple entry points for code splitting:

```tsx
// Import everything (full bundle)
import { NiceButton, NiceDataGrid, NiceChart } from '@nice2dev/ui';

// Or import from specific submodules for smaller bundles
import { NiceDataGrid, NiceTreeGrid } from '@nice2dev/ui/data';
import { NiceChart, NicePieChart } from '@nice2dev/ui/charts';
import { NiceTextInput, NiceSelect } from '@nice2dev/ui/editors';
import { NiceAlert, NiceModal, useNiceToast } from '@nice2dev/ui/feedback';
import { NiceTabs, NiceNavbar } from '@nice2dev/ui/navigation';
import { NiceWindow, NiceLoadPanel } from '@nice2dev/ui/overlays';
```

### Lazy Loading Heavy Components

For code-heavy components like code editors and document viewers, use the built-in lazy loading:

```tsx
import { LazyComponents, createLazyComponent, usePreloadOnIdle } from '@nice2dev/ui';

// Use pre-built lazy components
<LazyComponents.CodeEditor value={code} language="typescript" onChange={setCode} />;

// Or create your own lazy wrapper
const LazyChart = createLazyComponent(() => import('@nice2dev/ui/charts').then((m) => ({ default: m.NiceChart })), {
  preloadOnHover: true,
  displayName: 'LazyChart',
});

// Preload components when browser is idle
usePreloadOnIdle([LazyComponents.CodeEditor.preload, LazyComponents.HtmlEditor.preload]);
```

---

## Component Catalog

### Editors (28 components)

Form input components with consistent `NiceFormFieldProps` interface: `label`, `helperText`, `error`, `required`, `disabled`, `readOnly`, `size`, `name`.

| Component          | Key Props                                                               | Description                 |
| ------------------ | ----------------------------------------------------------------------- | --------------------------- |
| `NiceTextInput`    | `value`, `onChange`, `placeholder`, `type`, `clearable`                 | Standard text input         |
| `NiceTextArea`     | `value`, `onChange`, `rows`, `autoResize`, `maxLength`                  | Multi-line text input       |
| `NiceNumberInput`  | `value`, `onChange`, `min`, `max`, `step`, `format`                     | Numeric input with stepper  |
| `NiceDatePicker`   | `value`, `onChange`, `format`, `minDate`, `maxDate`                     | Date selection              |
| `NiceSelect`       | `value`, `onChange`, `options[]`, `searchable`, `clearable`, `multiple` | Dropdown select             |
| `NiceCheckbox`     | `checked`, `onChange`, `indeterminate`                                  | Checkbox                    |
| `NiceToggle`       | `checked`, `onChange`, `labelOn`, `labelOff`                            | Toggle switch               |
| `NiceRadioGroup`   | `value`, `onChange`, `options[]`, `direction`                           | Radio button group          |
| `NiceSlider`       | `value`, `onChange`, `min`, `max`, `step`, `showTooltip`                | Single-value slider         |
| `NiceColorPicker`  | `value`, `onChange`, `format`, `presets[]`                              | Color picker with presets   |
| `NiceAutocomplete` | `value`, `onChange`, `options[]`, `onSearch`, `debounce`                | Autocomplete input          |
| `NiceLookup`       | `value`, `onChange`, `dataSource`, `displayExpr`, `valueExpr`           | Lookup field                |
| `NiceCalendar`     | `value`, `onChange`, `minDate`, `maxDate`, `disabledDates`              | Inline calendar             |
| `NiceDateRangeBox` | `startDate`, `endDate`, `onChange`, `format`                            | Date range picker           |
| `NiceTagBox`       | `value`, `onChange`, `options[]`, `maxTags`, `allowCustom`              | Tag/chip input              |
| `NiceRangeSlider`  | `value` (tuple), `onChange`, `min`, `max`, `step`                       | Dual-handle range slider    |
| `NiceDropDownBox`  | `value`, `onChange`, `renderContent`, `displayValue`                    | Generic drop-down container |
| `NiceHtmlEditor`   | `value`, `onChange`, `toolbar`, `placeholder`                           | Rich text (HTML) editor     |
| `NiceForm`         | `children`, `onSubmit`, `layout`, `labelPosition`                       | Form layout wrapper         |
| `NiceRating`       | `value`, `onChange`, `max`, `icon`, `allowHalf`                         | Star/icon rating input      |
| `NiceOtpInput`     | `value`, `onChange`, `length`, `type`                                   | One-time password input     |
| `NiceSignaturePad` | `value`, `onChange`, `width`, `height`, `penColor`                      | Signature capture pad       |
| `NiceMentionInput` | `value`, `onChange`, `users[]`, `trigger`                               | Text input with @mentions   |
| `NiceTreeSelect`   | `value`, `onChange`, `nodes[]`, `multiple`                              | Tree-based selection        |
| `NiceMaskedInput`  | `value`, `onChange`, `mask`, `placeholder`                              | Masked/formatted input      |
| `NiceKnob`         | `value`, `onChange`, `min`, `max`, `draggable`                          | Rotary knob input           |
| `NicePickList`     | `source[]`, `target[]`, `onChange`                                      | Dual-list pick transfer     |
| `NiceInlineEdit`   | `value`, `onChange`, `renderDisplay`, `renderEditor`                    | Click-to-edit inline        |
| `NiceLookup`       | `value`, `onChange`, `dataSource`, `displayExpr`, `valueExpr`           | Lookup field                |

### Buttons (5 components)

| Component             | Key Props                                                   | Description                  |
| --------------------- | ----------------------------------------------------------- | ---------------------------- |
| `NiceButton`          | `variant`, `size`, `icon`, `loading`, `disabled`, `onClick` | Standard button              |
| `NiceButtonGroup`     | `items[]`, `selectedIndex`, `onSelect`, `variant`           | Grouped buttons              |
| `NiceIconButton`      | `icon`, `size`, `variant`, `onClick`, `tooltip`             | Icon-only button             |
| `NiceDropDownButton`  | `text`, `items[]`, `onItemClick`, `variant`, `icon`         | Button with dropdown menu    |
| `NiceSpeedDialAction` | `icon`, `actions[]`, `position`, `onClick`                  | Floating action button (FAB) |

### Data Display (13 components)

| Component             | Key Props                                                      | Description                         |
| --------------------- | -------------------------------------------------------------- | ----------------------------------- |
| `NiceBadge`           | `count`, `variant`, `dot`, `max`, `children`                   | Notification badge                  |
| `NiceTag`             | `children`, `variant`, `closable`, `onClose`, `icon`           | Tag/chip                            |
| `NiceAvatar`          | `src`, `alt`, `size`, `fallback`, `shape`                      | User avatar                         |
| `NiceAvatarGroup`     | `items[]`, `max`, `size`                                       | Stacked avatar group                |
| `NiceProgress`        | `value`, `max`, `variant`, `showLabel`, `size`                 | Progress bar                        |
| `NiceDivider`         | `orientation`, `label`, `variant`                              | Horizontal/vertical divider         |
| `NiceTooltip`         | `content`, `position`, `delay`, `children`                     | Tooltip wrapper                     |
| `NiceSkeleton`        | `variant` (`text`/`circle`/`rect`), `width`, `height`, `count` | Loading skeleton                    |
| `NiceSpinner`         | `size`, `variant`, `overlay`                                   | Loading spinner                     |
| `NiceEmpty`           | `icon`, `title`, `description`, `action`                       | Empty state placeholder             |
| `NiceTimeline`        | `items[]`, `mode`, `pending`                                   | Vertical/horizontal timeline        |
| `NiceCarousel`        | `items[]`, `autoPlay`, `interval`, `dots`                      | Image/content carousel              |
| `NiceVirtualScroller` | `items[]`, `itemHeight`, `renderItem`                          | Virtualized list for large datasets |

### Feedback (6 components + 1 hook)

| Component            | Key Props                                                                        | Description                                           |
| -------------------- | -------------------------------------------------------------------------------- | ----------------------------------------------------- |
| `NiceAlert`          | `variant` (`info`/`success`/`warning`/`error`), `title`, `closable`, `icon`      | Alert banner                                          |
| `NiceModal`          | `open`, `onClose`, `title`, `size`, `footer`, `closeOnOverlay`, `closeOnEscape`  | Modal dialog                                          |
| `NiceDrawer`         | `open`, `onClose`, `title`, `placement` (`left`/`right`/`top`/`bottom`), `width` | Slide-out drawer                                      |
| `NiceToastContainer` | —                                                                                | Container for toast notifications (mount once)        |
| `useNiceToast()`     | —                                                                                | Hook: `{ show: (message, type?, duration?) => void }` |
| `NiceConfirmDialog`  | `open`, `onConfirm`, `onCancel`, `title`, `message`                              | Confirmation prompt                                   |
| `NiceCookieConsent`  | `onAccept`, `onDecline`, `privacyUrl`                                            | GDPR cookie consent bar                               |
| `NiceLoginForm`      | `onLogin`, `onForgotPassword`, `logo`                                            | Pre-built login form                                  |

### Navigation (16 components)

| Component              | Key Props                                                                               | Description                           |
| ---------------------- | --------------------------------------------------------------------------------------- | ------------------------------------- |
| `NiceTabs`             | `tabs[]`, `activeTab`, `onChange`, `variant` (`default`/`pills`/`enclosed`), `vertical` | Tab navigation                        |
| `NiceAccordion`        | `items[]`, `multiple`, `defaultOpen`                                                    | Collapsible accordion panels          |
| `NiceBreadcrumb`       | `items[]`, `separator`                                                                  | Breadcrumb trail                      |
| `NicePagination`       | `current`, `total`, `onChange`, `pageSize`, `showSizeChanger`                           | Pagination controls                   |
| `NiceCard`             | `title`, `extra`, `bordered`, `hoverable`, `loading`, `children`                        | Card container                        |
| `NiceMenu`             | `items[]`, `theme`, `mode` (`vertical`/`horizontal`)                                    | Navigation menu                       |
| `NiceContextMenu`      | `items[]`, `onAction`, `children`                                                       | Right-click context menu              |
| `NiceMultiView`        | `views[]`, `activeView`, `onChange`                                                     | Multi-view container                  |
| `NiceTabPanel`         | `label`, `icon`, `children`                                                             | Tab panel (used inside NiceMultiView) |
| `NiceSplitter`         | `direction` (`horizontal`/`vertical`), `sizes`, `children`                              | Resizable split panes                 |
| `NiceToolbar`          | `items[]`, `theme`, `mode`                                                              | Toolbar with configurable items       |
| `NiceAppLayout`        | `sidebar`, `header`, `footer`, `children`                                               | Application shell layout              |
| `NiceBottomNavigation` | `items[]`, `active`, `onChange`                                                         | Mobile bottom navigation bar          |
| `NiceDashboardLayout`  | `widgets[]`, `columns`, `draggable`                                                     | Dashboard grid layout                 |
| `NiceDesktop`          | `windows[]`, `wallpaper`, `onWindowChange`                                              | Desktop window manager                |
| `NiceConsole`          | `commands[]`, `onCommand`, `history`                                                    | Terminal/console emulator             |

### Data (11 components)

| Component                   | Key Props                                                                    | Description                               |
| --------------------------- | ---------------------------------------------------------------------------- | ----------------------------------------- |
| `NiceTable`                 | `columns[]`, `data[]`, `striped`, `compact`, `emptyText`                     | Simple data table                         |
| `NiceDataGrid`              | `columns[]`, `data[]`, `virtualized`, `sortable`, `filterable`, `selectable` | Full-featured data grid                   |
| `NiceList`                  | `items[]`, `renderItem`, `emptyText`, `virtualized`                          | List view                                 |
| `NiceTreeView`              | `nodes[]`, `onSelect`, `selectable`, `expandable`                            | Tree structure viewer                     |
| `NiceTreeList`              | `nodes[]`, `renderNode`, `editable`                                          | Editable tree list                        |
| `NiceCardView`              | `items[]`, `renderCard`, `columns`, `gap`                                    | Card grid layout                          |
| `NiceTileView`              | `items[]`, `renderTile`, `columns`                                           | Tile grid layout                          |
| `NicePivotGrid`             | `data[]`, `fields[]`, `rowGrandTotal`, `columnGrandTotal`                    | Pivot table                               |
| `NicePivotGridFieldChooser` | —                                                                            | Field chooser companion for NicePivotGrid |
| `NiceKanbanBoard`           | `columns[]`, `cards[]`, `onCardMove`                                         | Kanban board                              |
| `NiceSpreadsheet`           | `data[][]`, `columns[]`, `editable`                                          | Excel-like spreadsheet                    |

### Charts (16 components)

| Component               | Key Props                                                                      | Description            |
| ----------------------- | ------------------------------------------------------------------------------ | ---------------------- |
| `NiceChart`             | `data[]`, `series[]`, `type` (`line`/`bar`/`area`/`scatter`), `xAxis`, `yAxis` | Multi-type chart       |
| `NicePieChart`          | `data[]`, `legend`, `donut`                                                    | Pie / donut chart      |
| `NicePolarChart`        | `data[]`, `series[]`, `angleAxis`, `radiusAxis`                                | Polar coordinate chart |
| `NiceCircularGauge`     | `value`, `min`, `max`, `threshold`, `unit`                                     | Circular gauge         |
| `NiceLinearGauge`       | `value`, `min`, `max`, `orientation`                                           | Linear gauge           |
| `NiceBarGauge`          | `value`, `max`, `count`                                                        | Bar gauge              |
| `NiceSparkline`         | `data[]`, `type`, `trend`                                                      | Inline sparkline       |
| `NiceBullet`            | `value`, `ranges[]`, `measure`, `comparative`                                  | Bullet chart           |
| `NiceFunnel`            | `data[]`, `link`                                                               | Funnel chart           |
| `NiceSankey`            | `nodes[]`, `links[]`                                                           | Sankey diagram         |
| `NiceRangeSelector`     | `data[]`, `onRangeChange`                                                      | Range selector chart   |
| `NiceVectorMap`         | `regions[]`, `mapName`, `onRegionClick`                                        | Vector map             |
| `NiceHeatMap`           | `data[][]`, `xLabels`, `yLabels`, `colorScale`                                 | Heat map grid          |
| `NiceTreeMap`           | `data[]`, `valueField`, `labelField`                                           | Hierarchical tree map  |
| `NiceStockChart`        | `data[]`, `type` (`candlestick`/`ohlc`), `volume`                              | Financial stock chart  |
| `NiceOrganizationChart` | `nodes[]`, `direction`, `onNodeClick`                                          | Org chart / hierarchy  |

### Overlays & Layout (9 components)

| Component           | Key Props                                                          | Description                 |
| ------------------- | ------------------------------------------------------------------ | --------------------------- |
| `NiceActionSheet`   | `open`, `onClose`, `items[]`, `title`                              | Mobile-style action sheet   |
| `NicePopover`       | `content`, `trigger`, `position`, `visible`, `children`            | Popover                     |
| `NiceLoadPanel`     | `visible`, `message`                                               | Full-screen loading overlay |
| `NiceBox`           | `padding`, `margin`, `border`, `background`, `children`            | Box layout container        |
| `NiceResponsiveBox` | `items[]`, `children`                                              | Responsive layout container |
| `NiceResizable`     | `width`, `height`, `minWidth`, `minHeight`, `onResize`, `children` | Resizable container         |
| `NiceScrollView`    | `horizontal`, `vertical`, `showTrack`, `children`                  | Custom scroll container     |
| `NiceBlockUI`       | `blocked`, `message`, `children`                                   | Block UI overlay            |
| `NiceWindow`        | `title`, `open`, `onClose`, `resizable`, `draggable`               | Draggable/resizable window  |

### Planning (4 components)

| Component       | Key Props                                                      | Description        |
| --------------- | -------------------------------------------------------------- | ------------------ |
| `NiceScheduler` | `events[]`, `onEventChange`, `view`, `resources[]`, `workDays` | Calendar scheduler |
| `NiceGantt`     | `tasks[]`, `columns[]`, `scale`, `onTaskChange`                | Gantt chart        |
| `NiceDiagram`   | `nodes[]`, `edges[]`, `onNodeClick`, `onEdgeClick`             | Node/edge diagram  |
| `NiceStepper`   | `steps[]`, `currentStep`, `onStepChange`, `vertical`           | Step wizard        |

### Tools (14 components)

| Component                 | Key Props                                               | Description                          |
| ------------------------- | ------------------------------------------------------- | ------------------------------------ |
| `NiceChat`                | `messages[]`, `onSendMessage`, `currentUser`            | Chat widget                          |
| `NiceDraggable`           | `onDrag`, `ghostImage`, `children`                      | Drag source wrapper                  |
| `NiceSortable`            | `items[]`, `onSort`, `direction`                        | Sortable list                        |
| `NiceFileUploader`        | `onUpload`, `accept`, `multiple`, `maxSize`, `maxFiles` | File upload                          |
| `NiceFileManager`         | `items[]`, `onDelete`, `onRename`, `onNavigate`         | File browser                         |
| `NiceFilterBuilder`       | `fields[]`, `onChange`, `value`                         | Visual filter/query builder          |
| `NiceGallery`             | `items[]`, `columns`, `gap`, `onItemClick`              | Image gallery                        |
| `NiceMap`                 | `markers[]`, `center`, `zoom`, `onMarkerClick`          | Map with markers                     |
| `NiceSpeechToText`        | `onResult`, `language`, `continuous`                    | Speech recognition                   |
| `NiceThemeDesigner`       | `onChange`, `onSave`, `onExport`                        | Live theme editor                    |
| `NiceThemeBuilder`        | `sections[]`, `onChange`, `onExport`                    | Theme builder with CSS export        |
| `NiceControlConfigurator` | `controlType`, `propDescriptors[]`, `renderPreview`     | Interactive prop configurator        |
| `NiceViewBuilder`         | `definition`, `onChange`, `controlRegistry`             | Drag-and-drop view builder           |
| `NiceShowcase`            | `defaultTab`, `showAbout`, `packageName`, `version`     | Embeddable component showcase & docs |

### Validation (3 components + 1 hook)

| Component               | Key Props                      | Description                                          |
| ----------------------- | ------------------------------ | ---------------------------------------------------- |
| `NiceValidationGroup`   | `onSubmit`, `children`         | Validation group wrapper                             |
| `NiceValidator`         | `rules[]`, `value`, `onChange` | Field-level validator                                |
| `NiceValidationSummary` | `errors`                       | Error summary display                                |
| `useNiceValidation()`   | —                              | Hook: `{ validate: (data) => NiceValidationRule[] }` |

---

## Core Infrastructure

### Shared Types

All components build on a shared type system defined in `src/core/types.ts`:

```typescript
type NiceSize = 'xs' | 'sm' | 'md' | 'lg' | 'xl';

type NiceVariant = 'primary' | 'secondary' | 'success' | 'warning' | 'error' | 'info' | 'ghost' | 'outline';

type NiceDensity = 'compact' | 'normal' | 'comfortable';

interface NiceBaseProps {
  className?: string;
  style?: React.CSSProperties;
  id?: string;
  'data-testid'?: string;
}

interface NiceFormFieldProps extends NiceBaseProps {
  label?: string;
  helperText?: string;
  error?: string;
  required?: boolean;
  disabled?: boolean;
  readOnly?: boolean;
  size?: NiceSize;
  name?: string;
}

type NiceOption<T = string> = {
  value: T;
  label: string;
  disabled?: boolean;
  icon?: React.ReactNode;
  description?: string;
  group?: string;
};
```

### Hooks

Utility hooks exported from the package:

| Hook                 | Signature                                                    | Description                                                                                                                           |
| -------------------- | ------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------- |
| `useControlId`       | `(externalId?: string) => string`                            | Generates a stable unique ID for form field–label associations. Uses the provided ID if given, otherwise generates one via `useId()`. |
| `useDebouncedValue`  | `<T>(value: T, delayMs: number) => T`                        | Returns a debounced version of the input value.                                                                                       |
| `useClickOutside`    | `(ref: RefObject<HTMLElement>, handler: () => void) => void` | Fires `handler` when a click or touch occurs outside the referenced element.                                                          |
| `useFocusTrap`       | `(ref: RefObject<HTMLElement>, active: boolean) => void`     | Traps keyboard focus within the referenced element (Tab/Shift+Tab cycling). Used by modals and drawers.                               |
| `useIsTouchDevice`   | `() => boolean`                                              | Detects `(pointer: coarse)` media query — returns `true` on touch devices.                                                            |
| `useInputMode`       | `() => 'touch' \| 'mouse'`                                   | Dynamically switches based on last input type (touchstart vs pointerdown).                                                            |
| `useLongPress`       | `(callback, holdMs?) => PointerHandlers`                     | Long-press gesture detection for touch (default 500ms).                                                                               |
| `useBreakpoint`      | `() => 'xs' \| 'sm' \| 'md' \| 'lg' \| 'xl'`                 | Current viewport breakpoint.                                                                                                          |
| `useMediaQuery`      | `(query: string) => boolean`                                 | CSS media query match.                                                                                                                |
| `useResponsiveValue` | `<T>(map: Record<Breakpoint, T>) => T`                       | Returns value matching current breakpoint.                                                                                            |
| `useContainerSize`   | `(ref: RefObject) => { width, height }`                      | Container element dimensions.                                                                                                         |
| `useNiceToast`       | `() => { show: (msg, type?, duration?) => void }`            | Programmatic toast notifications.                                                                                                     |
| `useNiceTranslation` | `() => { t: NiceTranslateFn }`                               | Access the current translation function.                                                                                              |
| `useNiceIcon`        | `(name: string, size: number) => ReactNode \| undefined`     | Resolve an icon name via the current icon provider.                                                                                   |
| `useNiceValidation`  | `() => { validate: (data) => NiceValidationRule[] }`         | Form validation.                                                                                                                      |

### Icon System

The library ships with **78 built-in SVG icons** covering common UI needs. No external icon library is required for basic usage.

#### Built-in Icon Categories

| Category   | Count | Examples                                                                                                   |
| ---------- | ----- | ---------------------------------------------------------------------------------------------------------- |
| Navigation | 8     | `chevron-down`, `arrow-left`, `arrow-right`, `arrow-up`                                                    |
| Actions    | 10    | `close`, `plus`, `minus`, `check`, `edit`, `trash`, `copy`, `download`, `upload`, `refresh`                |
| UI Chrome  | 10    | `search`, `filter`, `sort-asc`, `sort-desc`, `menu`, `more-vertical`, `settings`, `eye`, `eye-off`, `lock` |
| Status     | 6     | `info`, `warning`, `error`, `success`, `help`, `bell`                                                      |
| Content    | 12    | `calendar`, `clock`, `file`, `folder`, `image`, `link`, `mail`, `phone`, `user`, `users`, `home`, `star`   |
| Media      | 3     | `play`, `pause`, `stop`                                                                                    |
| Toggle     | 3     | `expand`, `collapse`, `external-link`                                                                      |
| Misc       | 3+    | `heart`, `grip`, `more-horizontal`                                                                         |

#### Using Icons

```tsx
import { NiceIcon } from '@nice2dev/ui';

// Built-in icon (no provider needed)
<NiceIcon name="check" size="md" />
<NiceIcon name="search" size={24} color="#3b82f6" />

// Icons can be used in any component that accepts an icon prop
<NiceButton icon={<NiceIcon name="plus" />}>Add Item</NiceButton>
```

#### Pluggable Icon Resolver

You can replace or extend the built-in icons by wrapping your app with `NiceIconProvider`:

```tsx
import { NiceIconProvider, NiceIconResolver } from '@nice2dev/ui';

const myResolver: NiceIconResolver = (name, size) => {
  // Return a ReactNode for known icon names, or undefined to fall back to built-in
  return <MyCustomIcon name={name} size={size} />;
};

<NiceIconProvider resolver={myResolver}>
  <App />
</NiceIconProvider>;
```

The `NiceIconResolver` type signature:

```typescript
type NiceIconResolver = (name: string, size: number) => React.ReactNode | undefined;
```

The companion package [`@nice2dev/icons`](#companion-package-nice2devicons) provides a ready-made FontAwesome resolver.

#### Icon Sizes

| Size Key | Pixels |
| -------- | ------ |
| `xs`     | 12     |
| `sm`     | 16     |
| `md`     | 20     |
| `lg`     | 24     |
| `xl`     | 32     |

You can also pass a numeric value directly: `<NiceIcon name="check" size={18} />`

### Internationalization (i18n)

The library is fully i18n-ready with a pluggable translation system. It works **without any configuration** — all components render with sensible default English strings.

```tsx
import { NiceI18nProvider, NiceTranslateFn } from '@nice2dev/ui';

// With react-i18next:
import { useTranslation } from 'react-i18next';

function App() {
  const { t } = useTranslation();
  return (
    <NiceI18nProvider t={t}>
      <MyPage />
    </NiceI18nProvider>
  );
}

// Custom translation function:
const myTranslate: NiceTranslateFn = (key, defaultValue) => {
  const translations: Record<string, string> = {
    'nice.button.submit': 'Enviar',
    'nice.empty.noData': 'Sin datos',
  };
  return translations[key] ?? defaultValue;
};

<NiceI18nProvider t={myTranslate}>
  <App />
</NiceI18nProvider>;
```

The `NiceTranslateFn` type:

```typescript
type NiceTranslateFn = (key: string, defaultValue: string) => string;
```

---

## NiceShowcase — Embeddable Documentation

Drop `<NiceShowcase />` into any React app to get a full interactive component library showcase with live demos, About page, theme designer, and configurator:

```tsx
import { NiceShowcase } from '@nice2dev/ui';
import '@nice2dev/ui/style.css';

function DocsPage() {
  return <NiceShowcase defaultTab="about" version="1.0.0" />;
}
```

Props:

- `defaultTab` — initial tab (`'about'`, `'dashboard'`, `'forms'`, `'controls'`, etc.)
- `showAbout` — show/hide the About & Installation tab (default: `true`)
- `tabs` — array of visible tabs (default: all)
- `packageName` — package name shown in install instructions (default: `'@nice2dev/ui'`)
- `version` — version shown in hero section
- `renderPage` — custom page renderer for overriding built-in pages

---

## Access Control

Built-in per-component access modes allow controlling visibility and interactivity globally or per-component:

```tsx
import { NiceAccessControl, NiceTextInput, NiceButton } from '@nice2dev/ui';

// Provider-level permissions:
<NiceAccessControl defaultMode="full" permissions={{ 'salary-field': 'readOnly', 'delete-btn': 'hidden' }}>
  <NiceTextInput accessMode="full" label="Name" />
  <NiceTextInput componentId="salary-field" label="Salary" />
  <NiceButton componentId="delete-btn" variant="error">
    Delete
  </NiceButton>
</NiceAccessControl>;
```

Modes: `'full'` (default), `'readOnly'`, `'disabled'`, `'hidden'`

---

## Theming

### CSS Custom Properties

The entire design system is driven by CSS custom properties. Import the stylesheet and override variables to customize:

```tsx
import '@nice2dev/ui/style.css';
```

#### Available Variables

```css
:root {
  /* Colors */
  --color-primary: #3b82f6;
  --color-primary-hover: #2563eb;
  --color-success: #10b981;
  --color-warning: #f59e0b;
  --color-error: #ef4444;
  --color-info: #06b6d4;

  /* Backgrounds */
  --bg-primary: #ffffff;
  --bg-secondary: #f8fafc;
  --bg-tertiary: #f1f5f9;

  /* Text */
  --text-primary: #0f172a;
  --text-secondary: #475569;
  --text-muted: #94a3b8;

  /* Borders & Interactions */
  --border-color: #e2e8f0;
  --hover-bg: #f1f5f9;

  /* Shadows */
  --shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.05);
  --shadow-md: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -2px rgba(0, 0, 0, 0.1);
  --shadow-lg: 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -4px rgba(0, 0, 0, 0.1);
  --shadow-xl: 0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 8px 10px -6px rgba(0, 0, 0, 0.1);
}
```

### Dark Mode

Dark mode is supported in three ways:

1. **Automatic** — Follows `prefers-color-scheme: dark` media query by default
2. **Class-based** — Add `nice-dark` class to any ancestor element
3. **Attribute-based** — Set `data-theme="dark"` on any ancestor element

```html
<!-- Auto: follows OS preference (default behavior, no extra code) -->

<!-- Manual toggle via class: -->
<body class="nice-dark">
  ...
</body>

<!-- Manual toggle via attribute: -->
<body data-theme="dark">
  ...
</body>

<!-- Opt-in light mode when OS is dark: -->
<body data-theme="light">
  ...
</body>
```

### Custom Themes

Create a custom theme by overriding CSS variables:

```css
/* my-theme.css */
:root {
  --color-primary: #8b5cf6; /* purple primary */
  --color-primary-hover: #7c3aed;
  --bg-primary: #faf5ff;
  --border-color: #ddd6fe;
}
```

### Legacy shorthand alias layer (opt-in)

If your app already uses the conventional shorthand variables
(`--bg-primary`, `--text-primary`, `--border-color`, `--shadow-sm/md/lg`,
etc.) — for example when porting from a custom design-token system
like OmniVerk's `--s-*` table — import the opt-in alias stylesheet so
those names inherit values from the active Nice token set without
being redefined by hand:

```ts
import '@nice2dev/ui/style.css';
import '@nice2dev/ui/css/legacy-bg-text-aliases.css'; // opt-in
```

The alias file only fills in gaps (it never overrides values you set
yourself) and follows the active Nice theme (light / dark) automatically.

---

## Build & Development

### Prerequisites

- Node.js 18+
- npm 9+

### Scripts

```bash
npm run dev        # Start Vite dev server with demo app
npm run build      # Build library (tsc + vite)
npm run preview    # Preview built library
```

### Build Output

| File              | Format     | Size    | Purpose                                   |
| ----------------- | ---------- | ------- | ----------------------------------------- |
| `dist/index.mjs`  | ESM        | ~207 KB | Modern bundlers (Vite, webpack 5, Rollup) |
| `dist/index.cjs`  | CJS        | ~146 KB | Node.js, older bundlers                   |
| `dist/style.css`  | CSS        | ~79 KB  | All component styles                      |
| `dist/index.d.ts` | TypeScript | —       | Type definitions                          |

### Build Configuration

- **Bundler:** Vite 5 with `@vitejs/plugin-react`
- **Types:** `vite-plugin-dts` with `rollupTypes: true` (single `.d.ts` bundle)
- **Target:** ES2020
- **External:** `react`, `react-dom`, `react/jsx-runtime`
- **CSS:** Single file output (`cssCodeSplit: false`)
- **TypeScript:** Strict mode, declaration maps, source maps

### Project Structure

```
nice2dev-ui/
├── src/
│   ├── core/                   # Types, hooks, i18n, icon system
│   │   ├── types.ts            # NiceSize, NiceVariant, NiceBaseProps, etc.
│   │   ├── hooks.ts            # useControlId, useDebouncedValue, useClickOutside, useFocusTrap
│   │   ├── i18n.tsx            # NiceI18nProvider, useNiceTranslation
│   │   └── icons.tsx           # 78 built-in SVG icons, NiceIcon, NiceIconProvider
│   ├── styles/
│   │   ├── controls.css        # Base design system (CSS custom properties)
│   │   └── controls-extended.css  # Extended component styles
│   ├── editors/                # 18 form input components
│   ├── buttons/                # NiceButton, NiceButtonGroup, NiceDropDownButton, etc.
│   ├── display/                # NiceBadge, NiceTag, NiceAvatar, NiceProgress, etc.
│   ├── feedback/               # NiceAlert, NiceModal, NiceDrawer, NiceToastContainer
│   ├── navigation/             # NiceTabs, NiceAccordion, NiceMenu, NiceSplitter, etc.
│   ├── data/                   # NiceTable, NiceDataGrid, NiceTreeView, NicePivotGrid, etc.
│   ├── charts/                 # NiceChart, NicePieChart, gauges, sparklines, maps
│   ├── overlays/               # NicePopover, NiceActionSheet, NiceResizable, etc.
│   ├── planning/               # NiceScheduler, NiceGantt, NiceDiagram, NiceStepper
│   ├── tools/                  # NiceChat, NiceFileUploader, NiceFilterBuilder, etc.
│   └── index.ts                # Main barrel export
├── demo/
│   └── Demo.tsx                # Comprehensive component demo application
├── package.json
├── vite.config.ts
├── tsconfig.json
└── tsconfig.build.json
```

---

## Architecture

### Design Principles

1. **Zero dependencies** — The library depends only on React. No lodash, no date-fns, no external CSS frameworks.
2. **Consistent API** — All form components extend `NiceFormFieldProps` for uniform `label`, `error`, `disabled`, `size`, etc.
3. **Composable** — Components are designed to work together. `NiceIcon` can be used inside `NiceButton`, `NiceSelect` options, `NiceMenu` items, etc.
4. **Themeable at every level** — CSS custom properties for global theming, `className`/`style` props for per-instance customization, `variant`/`size` props for semantic variations.
5. **Progressive enhancement** — i18n and custom icons are opt-in. Everything works out of the box with sensible defaults.

### Provider Stack (optional)

```tsx
import { NiceI18nProvider, NiceIconProvider } from '@nice2dev/ui';
import { NiceFaIconProvider } from '@nice2dev/icons'; // optional

// Full provider stack:
<NiceI18nProvider t={myTranslationFunction}>
  <NiceFaIconProvider>  {/* or <NiceIconProvider resolver={...}> */}
    <App />
  </NiceFaIconProvider>
</NiceI18nProvider>

// Minimal (no providers needed):
<App />
```

---

## Companion Package: @nice2dev/icons

**[@nice2dev/icons](../nice2dev-icons/README.md)** provides 300+ multi-color SVG icons with 4 rendering variants (solid, outline, duotone, flat), 65+ CSS animations, gradient fills, and a searchable icon picker component. Includes brand icons for NiceToDev and OmniVerk.

```bash
npm install @nice2dev/icons
```

```tsx
import { NtdHome, NtdSearch, NtdHeart } from '@nice2dev/icons';

<NtdHome size="lg" primaryColor="#3b82f6" />
<NtdSearch animation="pulse" />
<NtdHeart variant="duotone" gradient="sunset" />
```

See the [@nice2dev/icons README](../nice2dev-icons/README.md) for full documentation.

---

## License

MIT © NiceToDev
