# @mezzanine-ui/react

> React component library for Mezzanine UI — a comprehensive set of accessible, themeable components built on top of @mezzanine-ui/core, @mezzanine-ui/icons, and @mezzanine-ui/system.

## Installation

```bash
npm install @mezzanine-ui/react @mezzanine-ui/core @mezzanine-ui/icons @mezzanine-ui/system react react-dom lodash
```

Peer dependencies: `react >= 18`, `react-dom >= 18`, `lodash >= 4`

## Related Packages

| Package                  | Role                                              |
| ------------------------ | ------------------------------------------------- |
| `@mezzanine-ui/core`     | CSS styles and TypeScript type definitions        |
| `@mezzanine-ui/icons`    | SVG icon definitions (plain objects)              |
| `@mezzanine-ui/system`   | Design tokens: palette, spacing, typography, etc. |

## Import Patterns

Individual component (preferred for tree-shaking):
```ts
import Button from '@mezzanine-ui/react/Button';
import Select from '@mezzanine-ui/react/Select';
```

Named exports from the barrel (hooks, types, utilities):
```ts
import { usePagination, useCheckboxControlValue } from '@mezzanine-ui/react';
import type { ButtonProps, ButtonVariant } from '@mezzanine-ui/react';
```

Required styles — create a `main.scss` and import it at your app entry point. All component styles are loaded at once via `@include mzn-core.styles()`:
```scss
@use '~@mezzanine-ui/system' as mzn-system;
@use '~@mezzanine-ui/core' as mzn-core;

:root {
  @include mzn-system.palette-variables(light);
  @include mzn-system.common-variables(default);
}

/* Optional: dark mode */
[data-theme='dark'] {
  @include mzn-system.palette-variables(dark);
}

/* Optional: compact density */
[data-density='compact'] {
  @include mzn-system.common-variables(compact);
}

@include mzn-core.styles();
```

## Component Categories

- **General** — Button, ButtonGroup, Cropper, Icon, Layout, Separator, Typography
- **Navigation** — Breadcrumb, Drawer, Navigation (+ sub-components), PageHeader, PageFooter, Stepper, Tab
- **Data Display** — Accordion, Badge, Cards (BaseCard, FourThumbnailCard, SingleThumbnailCard, QuickActionCard), Description, Empty, Pagination, Table, Tag, Tooltip
- **Data Entry** — AutoComplete, Checkbox, DatePicker, DateRangePicker, DateTimePicker, FilterArea, FormField, Input, Radio, Select, Slider, Toggle, Textarea, TimePicker, Upload, Cascader
- **Feedback** — InlineMessage, Message, Modal, NotificationCenter, Progress, ResultState, Skeleton, Spin
- **Others** — AlertBanner, Anchor, Backdrop, FloatingButton
- **Utility** — Calendar, Dropdown, Popper, Portal, TimePanel, Transition animations (Collapse, Fade, Rotate, Scale, Slide, Translate)

## Key Design Patterns

**Polymorphic `component` prop** — most components accept a `component` prop to override the rendered HTML element or pass a router link component:
```tsx
<Button component="a" href="/page">Link Button</Button>
```

**Controlled/uncontrolled with control hooks** — pair components with their corresponding hook:
```tsx
const [value, onChange] = useCheckboxControlValue({ defaultValue: [] });
<CheckboxGroup value={value} onChange={onChange} options={options} />
```

Available control hooks: `useAutoCompleteValueControl`, `useCheckboxControlValue`, `useInputControlValue`, `useInputWithClearControlValue`, `useRadioControlValue`, `useSelectValueControl`, `useSwitchControlValue`, `useCustomControlValue`.

**Portal-based overlays** — Modal, Drawer, and Tooltip render outside the component tree via `Portal`. Use the `container` prop to target a specific DOM node.

**Calendar adapter pattern** — Calendar components require wrapping the app with a date-adapter provider. Import from the library-specific entry point to avoid bundling unused date libraries:
```tsx
// Day.js (recommended)
import { CalendarConfigProviderDayjs, CalendarLocale } from '@mezzanine-ui/react/dayjs';
<CalendarConfigProviderDayjs locale={CalendarLocale.ZH_TW}>{children}</CalendarConfigProviderDayjs>

// Moment.js
import { CalendarConfigProviderMoment, CalendarLocale } from '@mezzanine-ui/react/moment';

// Luxon
import { CalendarConfigProviderLuxon, CalendarLocale } from '@mezzanine-ui/react/luxon';
```

**forwardRef** — all components forward their ref to the underlying DOM element.

## Common Pitfalls for AI Assistants

**Typography `variant` is not h1–h6.** The prop is named `variant` but its type is `TypographySemanticType` — a design-system semantic scale, not HTML heading levels. Valid values are `h1`, `h2`, `h3` (no h4/h5/h6), then `body`, `body-highlight`, `body-mono`, `caption`, `caption-highlight`, `annotation`, `annotation-highlight`, `button`, `input`, `label-primary`, `label-secondary`, and a few others. Never use `h4`, `h5`, or `h6`.
```tsx
<Typography variant="h1">Title</Typography>      // ✅
<Typography variant="body">Body text</Typography> // ✅
<Typography variant="h5">Subtitle</Typography>    // ❌ h5 does not exist
```

**Button icons use `icon` + `iconType`, not `prefix`/`suffix` JSX.** Pass an icon definition object (from `@mezzanine-ui/icons`) to the `icon` prop and set position via `iconType`: `"leading"` | `"trailing"` | `"icon-only"`. Do not wrap `<Icon />` in `prefix` or `suffix` props — those props do not exist on Button.
```tsx
import { PlusIcon } from '@mezzanine-ui/icons';
<Button icon={PlusIcon} iconType="leading">新增</Button>   // ✅
<Button prefix={<Icon icon={PlusIcon} />}>新增</Button>    // ❌ prefix does not exist
```

**`TextField` is a low-level layout container, not a full form field.** It renders the border/background/affix shell around an `<input>` but does not include a label, hint text, or error message. For a complete labeled form field, use `FormField` (which wraps `TextField` + `Input` + label + validation message).
```tsx
// Full labeled form field:
<FormField label="Email" required errorMessage={error}>
  <TextField><Input placeholder="you@example.com" /></TextField>
</FormField>
```

## Further Reference

- Full component index with descriptions: `packages/react/COMPONENTS.md`
- Complete prop types and JSDoc: `*.d.ts` files in the published package (or `packages/react/src/<ComponentName>/index.tsx`)
- GitHub: https://github.com/Mezzanine-UI/mezzanine
