# @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, cx } from '@mezzanine-ui/react'; import type { ButtonProps, ButtonVariant } from '@mezzanine-ui/react'; ``` Sub-path imports for component groups and core types: ```ts // Navigation sub-components import { NavigationFooter, NavigationHeader, NavigationOption, NavigationIconButton, NavigationUserMenu, } from '@mezzanine-ui/react/Navigation'; // ContentHeader (deprecated — sub-path import only, not in main barrel export) // import ContentHeader from '@mezzanine-ui/react/ContentHeader'; // Form layout tokens from core (used with FormField) import { ControlFieldSlotLayout, FormFieldLayout, FormFieldLabelSpacing, } from '@mezzanine-ui/core/form'; ``` Spacing helpers in SCSS (from `@mezzanine-ui/system/spacing`): ```scss @use '@mezzanine-ui/system/spacing'; .host { padding: spacing.semantic-variable(padding, vertical, spacious) spacing.semantic-variable(padding, horizontal, comfort-fixed); row-gap: spacing.semantic-variable(gap, calm); } ``` 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.common-variables('default'); @include mzn-system.colors(); } /* Optional: light/dark palette theming */ :root { @include mzn-system.colors(light); } [data-theme='dark'] { @include mzn-system.colors(dark); } /* Optional: compact density */ [data-density='compact'] { @include mzn-system.common-variables(compact); } @include mzn-core.styles(); ``` > **Note:** The `~` prefix (e.g. `~@mezzanine-ui/core`) was required by older webpack 4 + sass-loader setups. Modern tooling (Next.js 13+, Vite) resolves node_modules without it — use bare paths as shown above. ## 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 ``` **Controlled/uncontrolled with control hooks** — pair components with their corresponding hook: ```tsx const [value, onChange] = useCheckboxControlValue({ defaultValue: [] }); ``` 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'; {children} // 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. **React Hook Form integration** — the recommended pattern is a `BaseField` wrapper that combines `FormField` with RHF's `formState.errors` for automatic error display. `ControlFieldSlotLayout.SUB` aligns the hint/error message with the input: ```tsx import { useFormContext, get } from 'react-hook-form'; import FormField from '@mezzanine-ui/react/Form/FormField'; import { ControlFieldSlotLayout, FormFieldLayout } from '@mezzanine-ui/core/form'; function BaseField({ name, label, required, disabled, children }) { const { formState } = useFormContext(); const error = get(formState.errors, name); return ( {children} ); } ``` **Message imperative API** — `Message` is a global singleton for toast notifications. Call it imperatively without rendering any JSX: ```tsx import { Message } from '@mezzanine-ui/react'; Message.success('儲存成功'); Message.warning('請確認輸入資料'); Message.error('操作失敗,請稍後再試'); ``` **Select inside Modal** — when rendering a `Select` (or `AutoComplete`) inside a `Modal` or `Drawer`, pass `dropdownZIndex` higher than the overlay (default modal z-index is ~1000): ```tsx ` 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: ``` ## Further Reference - Full component index with descriptions: `packages/react/COMPONENTS.md` - Common UI pattern examples (Layout, Form, Table, Dialog, etc.): `packages/react/PATTERNS.md` - Complete prop types and JSDoc: `*.d.ts` files in the published package (or `packages/react/src//index.tsx`) - GitHub: https://github.com/Mezzanine-UI/mezzanine