---
title: Components
tags: [design-system, components, ui]
created: 2026-05-23
---

# Components

Inventory of reusable components in `frontend/src/components/`. Each component lives in its own folder (`index.ts` + `<name>.tsx` + `classes.ts` + `types.ts`).

> [!info]
> Pattern: components are reusable **and free of business logic**. Page-specific composition lives in `frontend/src/sections/`. Hooks that fetch data live in `frontend/src/hooks/`.

---

## 1. Form components (`components/hook-form/`)

RHF + MUI wrappers. Used inside a `<FormProvider {...methods}>` context. All accept `name`, plus the MUI props of the underlying component.

| Component | Wraps | Notes |
|---|---|---|
| `RHFTextField` | `TextField` | The workhorse text input |
| `RHFSelect` | `Select` + `MenuItem` | Pass `children={<MenuItem value="..."/>...}` |
| `RHFAutocomplete` | `Autocomplete` | Async-loader friendly; pass `options` |
| `RHFCheckbox` | `Checkbox` + `FormControlLabel` | Single boolean |
| `RHFMultiCheckbox` | grid of checkboxes | Returns `string[]` |
| `RHFRadioGroup` | `RadioGroup` | Returns selected value |
| `RHFSwitch` | `Switch` + label | Boolean toggle |
| `RHFEditor` | TipTap wrapper | HTML output |
| `RHFUpload` | `components/upload` Dropzone | Single or multiple |
| `RHFDatePicker` | `@mui/x-date-pickers DatePicker` | Locale-aware |
| `RHFDateTimePicker` | `DateTimePicker` | — |
| `RHFTimePicker` | `TimePicker` | — |
| `RHFPhoneInput` | `react-phone-number-input` | E.164 output |
| `RHFCountrySelect` | `components/country-select` | ISO-2 output |
| `RHFNumberInput` | `components/number-input` | Locale-formatted, accepts min/max/step |
| `RHFRating` | `Rating` | 0–5 |
| `RHFSlider` | `Slider` | Single or range |

> [!tip]
> Form-level errors render automatically via `formState.errors[name]` — pass `helperText={errors.name?.message}` is **not needed**; the wrapper handles it.

---

## 2. Data display

| Component | Purpose |
|---|---|
| `custom-data-grid/` | MUI DataGrid Pro wrapper — sets density, locale, custom toolbar, RTL support |
| `table/` | Lower-level table utilities (head, pagination, no-data row, skeleton) |
| `chart/` | ApexCharts wrapper with theme-synced palette |
| `markdown/` | `react-markdown` + `remark-gfm` for chat/evidence rendering |
| `lightbox/` | Image gallery (gallery / dispute evidence) |
| `image/` | Next `Image` wrapper with fallback skeleton + error state |
| `file-thumbnail/` | Renders icon by MIME type for non-image files |
| `flag-icon/` | Country flag SVG (used in phone input, locale switcher) |
| `iconify/` | Iconify SVG wrapper — `<Iconify icon="solar:user-bold" />` |
| `svg-color/` | Renders SVG with `color` prop (mask-image trick) |

---

## 3. Navigation

| Component | Purpose |
|---|---|
| `nav-section/` | Sidebar nav with role-filtering, group headers, mini variant |
| `nav-basic/` | Simple horizontal nav for marketing pages |
| `custom-breadcrumbs/` | Page header breadcrumbs + action slot |
| `progress-bar/` | NProgress integration for route transitions |

The sidebar reads from a configuration array — see `src/layouts/dashboard/config-nav-dashboard.ts` (or similar) — where each entry can specify `roles: ['admin']` to hide from other users.

---

## 4. Feedback

| Component | Purpose |
|---|---|
| `snackbar/` | Notistack wrapper — `enqueueSnackbar('Done', { variant: 'success' })` |
| `loading-screen/` | Full-screen splash for boot or guarded routes |
| `empty-content/` | "No results" placeholder with illustration |
| `search-not-found/` | Variant of empty-content for failed searches |
| `email-verification-banner/` | Persistent top banner when email unverified |

---

## 5. Overlays & dialogs

| Component | Purpose |
|---|---|
| `custom-dialog/` | Modal dialog with title/content/actions slots |
| `custom-popover/` | Click-or-hover popover (used for menus, tooltips, info) |

---

## 6. Inputs (raw, non-RHF)

| Component | Purpose |
|---|---|
| `number-input/` | Numeric with +/- buttons + locale format |
| `phone-input/` | Phone with country selector |
| `country-select/` | Country dropdown |
| `incrementer-button/` | Tiny `−` / `+` quantity stepper |
| `upload/` | Dropzone with progress, preview, removal |

---

## 7. User & profile

| Component | Purpose |
|---|---|
| `user-avatar/` | Hashes name → color; respects `src` if avatar uploaded |
| `user-profile-card/` | Profile summary card (name, role, level, points) |
| `notifications-drawer/` | Side drawer listing notifications, mark-as-read |

---

## 8. Media

| Component | Purpose |
|---|---|
| `video-player/` | Plyr / video.js wrapper for blog & template videos |
| `map/` | Mapbox + react-map-gl wrapper (delivery addresses) |
| `carousel/` | Embla carousel — multiple variants in `hooks/use-carousel-*` |

---

## 9. Animation

| Component | Purpose |
|---|---|
| `animate/` | Framer-motion presets (fade, slide, scale) for page transitions and lists |

---

## 10. Utility

| Component | Purpose |
|---|---|
| `scrollbar/` | SimpleBar wrapper — themed scrollbar with shadow on overflow |
| `label/` | Tag/badge — variants: filled, outlined, soft |
| `filters-result/` | Active filter chips with × to remove |
| `logo/` | App logo SVG (responsive: full mark + icon-only at small width) |
| `color-utils/` | Color manipulation helpers (alpha, darken, contrast) |

---

## 11. Settings

| Component | Purpose |
|---|---|
| `settings/` | The mounted Settings drawer + provider hooks |

---

## 12. Debug

| Component | Purpose |
|---|---|
| `debug/` | Dev-only diagnostic overlays (only rendered when `NEXT_PUBLIC_ENABLE_DEBUG=true`) |

---

## 13. Editor (`components/editor/`)

TipTap rich-text editor with this extension set:

- `StarterKit` (paragraph, headings, bold/italic, lists, blockquote, history)
- `Link` (URL parsing, target=_blank by default for external)
- `Image` (drag-drop, uploads via `components/upload`)
- `Underline`, `TextAlign`
- `CodeBlock` + `CodeBlockLowlight` (syntax highlighting via `lowlight`)
- `Placeholder`

Output: HTML string. Round-trip safe with `react-markdown` + `turndown` when Markdown storage is preferred.

Used in:
- Blog post editor (`dashboard/post/new`)
- Long-form description fields (request, template)
- Dispute evidence narrative

---

## 14. Payment-specific (`components/payment/`)

| Component | Purpose |
|---|---|
| `<TokenSelector>` | USDT / USDC / BTC / ETH chip selector |
| `<NetworkSelector>` | BSC / TRC20 / Ethereum / Polygon chip selector |
| `<QrInvoice>` | Renders the SHKeeper invoice QR + copy-address button |
| `<PaymentStatus>` | Live status pill that updates from socket events |

(Confirm names against actual exports — these are typical for this stack.)

---

## 15. Adding a new component

1. Create `src/components/<kebab-name>/` with `index.ts`, `<kebab-name>.tsx`, `classes.ts`, `types.ts`.
2. Re-export from `src/components/<kebab-name>/index.ts`: `export * from './<kebab-name>'`.
3. Place ONLY rendering + styling; do NOT call `useQuery` / `useMutation` — pass data via props.
4. Use the `sx` prop, not styled-components, unless the styling is non-trivial.
5. Cover with at least one Jest snapshot test in `__tests__/`.

---

## 16. Component vs Section vs Hook decision

| Question | Where it goes |
|---|---|
| "I want to render a chip with a delete icon." | `components/` |
| "I want a chat sidebar with conversation list + active chat + composer." | `sections/chat/` |
| "I want to subscribe to chat updates and keep the cache in sync." | `hooks/use-chat-socket.ts` |

---

## 17. Related

- [[Design System Overview]] · [[Theme Configuration]] · [[Colors]] · [[Typography]]
- [[Layouts]] · [[Internationalization & RTL]]
- [[Frontend Architecture]] — where these components live in the bigger picture
- [[Coding Standards]] — file layout & import order rules
