@mantis-core/ui 0.1.3 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (134) hide show
  1. package/COMPONENTS.md +15 -142
  2. package/PRIMEREACT_MAPPING.md +6 -0
  3. package/README.md +56 -72
  4. package/dist/components/Forms/AsyncSelect.d.ts +20 -0
  5. package/dist/components/Forms/AsyncSelect.d.ts.map +1 -0
  6. package/dist/components/Forms/AsyncSelect.js +77 -0
  7. package/dist/components/Forms/AsyncSelect.js.map +1 -0
  8. package/dist/components/Forms/CurrencyInput.d.ts +12 -0
  9. package/dist/components/Forms/CurrencyInput.d.ts.map +1 -0
  10. package/dist/components/Forms/CurrencyInput.js +9 -0
  11. package/dist/components/Forms/CurrencyInput.js.map +1 -0
  12. package/dist/components/Forms/DateRangeInput.d.ts +10 -0
  13. package/dist/components/Forms/DateRangeInput.d.ts.map +1 -0
  14. package/dist/components/Forms/DateRangeInput.js +13 -0
  15. package/dist/components/Forms/DateRangeInput.js.map +1 -0
  16. package/dist/components/Forms/DirtyFormGuard.d.ts +5 -0
  17. package/dist/components/Forms/DirtyFormGuard.d.ts.map +1 -0
  18. package/dist/components/Forms/DirtyFormGuard.js +8 -0
  19. package/dist/components/Forms/DirtyFormGuard.js.map +1 -0
  20. package/dist/components/Forms/FileDropzone.d.ts +29 -0
  21. package/dist/components/Forms/FileDropzone.d.ts.map +1 -0
  22. package/dist/components/Forms/FileDropzone.js +137 -0
  23. package/dist/components/Forms/FileDropzone.js.map +1 -0
  24. package/dist/components/Forms/FormActionsBar.d.ts +26 -0
  25. package/dist/components/Forms/FormActionsBar.d.ts.map +1 -0
  26. package/dist/components/Forms/FormActionsBar.js +16 -0
  27. package/dist/components/Forms/FormActionsBar.js.map +1 -0
  28. package/dist/components/Forms/FormWizard.d.ts +17 -0
  29. package/dist/components/Forms/FormWizard.d.ts.map +1 -0
  30. package/dist/components/Forms/FormWizard.js +63 -0
  31. package/dist/components/Forms/FormWizard.js.map +1 -0
  32. package/dist/components/Forms/PhoneInput.d.ts +11 -0
  33. package/dist/components/Forms/PhoneInput.d.ts.map +1 -0
  34. package/dist/components/Forms/PhoneInput.js +9 -0
  35. package/dist/components/Forms/PhoneInput.js.map +1 -0
  36. package/dist/components/Forms/RadioGroup.d.ts +15 -0
  37. package/dist/components/Forms/RadioGroup.d.ts.map +1 -0
  38. package/dist/components/Forms/RadioGroup.js +9 -0
  39. package/dist/components/Forms/RadioGroup.js.map +1 -0
  40. package/dist/components/Forms/RangeSlider.d.ts +13 -0
  41. package/dist/components/Forms/RangeSlider.d.ts.map +1 -0
  42. package/dist/components/Forms/RangeSlider.js +9 -0
  43. package/dist/components/Forms/RangeSlider.js.map +1 -0
  44. package/dist/components/Forms/SearchInput.d.ts +14 -0
  45. package/dist/components/Forms/SearchInput.d.ts.map +1 -0
  46. package/dist/components/Forms/SearchInput.js +34 -0
  47. package/dist/components/Forms/SearchInput.js.map +1 -0
  48. package/dist/components/Forms/useDirtyFormGuard.d.ts +12 -0
  49. package/dist/components/Forms/useDirtyFormGuard.d.ts.map +1 -0
  50. package/dist/components/Forms/useDirtyFormGuard.js +36 -0
  51. package/dist/components/Forms/useDirtyFormGuard.js.map +1 -0
  52. package/dist/components/pages/AdminPageHeader.d.ts.map +1 -1
  53. package/dist/components/pages/AdminPageHeader.js +2 -9
  54. package/dist/components/pages/AdminPageHeader.js.map +1 -1
  55. package/dist/components/pages/app-shell/AppShell.d.ts +5 -0
  56. package/dist/components/pages/app-shell/AppShell.d.ts.map +1 -0
  57. package/dist/components/pages/app-shell/AppShell.js +36 -0
  58. package/dist/components/pages/app-shell/AppShell.js.map +1 -0
  59. package/dist/components/pages/app-shell/Breadcrumbs.d.ts +8 -0
  60. package/dist/components/pages/app-shell/Breadcrumbs.d.ts.map +1 -0
  61. package/dist/components/pages/app-shell/Breadcrumbs.js +17 -0
  62. package/dist/components/pages/app-shell/Breadcrumbs.js.map +1 -0
  63. package/dist/components/pages/app-shell/index.d.ts +4 -0
  64. package/dist/components/pages/app-shell/index.d.ts.map +1 -0
  65. package/dist/components/pages/app-shell/index.js +3 -0
  66. package/dist/components/pages/app-shell/index.js.map +1 -0
  67. package/dist/components/pages/app-shell/types.d.ts +20 -0
  68. package/dist/components/pages/app-shell/types.d.ts.map +1 -0
  69. package/dist/components/pages/app-shell/types.js +2 -0
  70. package/dist/components/pages/app-shell/types.js.map +1 -0
  71. package/dist/components/ui/ConfirmDialog.d.ts +19 -0
  72. package/dist/components/ui/ConfirmDialog.d.ts.map +1 -0
  73. package/dist/components/ui/ConfirmDialog.js +20 -0
  74. package/dist/components/ui/ConfirmDialog.js.map +1 -0
  75. package/dist/components/ui/DataState.d.ts +20 -0
  76. package/dist/components/ui/DataState.d.ts.map +1 -0
  77. package/dist/components/ui/DataState.js +30 -0
  78. package/dist/components/ui/DataState.js.map +1 -0
  79. package/dist/components/ui/StatusBadge.d.ts +12 -0
  80. package/dist/components/ui/StatusBadge.d.ts.map +1 -0
  81. package/dist/components/ui/StatusBadge.js +19 -0
  82. package/dist/components/ui/StatusBadge.js.map +1 -0
  83. package/dist/index.d.ts +16 -0
  84. package/dist/index.d.ts.map +1 -1
  85. package/dist/index.js +8 -0
  86. package/dist/index.js.map +1 -1
  87. package/docs/README.md +72 -0
  88. package/docs/components/action-column.md +17 -0
  89. package/docs/components/admin-page-header.md +21 -0
  90. package/docs/components/admin-page-layout.md +29 -0
  91. package/docs/components/async-select.md +26 -0
  92. package/docs/components/button.md +25 -0
  93. package/docs/components/ckeditor-input.md +24 -0
  94. package/docs/components/confirm-dialog.md +21 -0
  95. package/docs/components/data-state.md +19 -0
  96. package/docs/components/date-input.md +22 -0
  97. package/docs/components/dirty-form-guard.md +31 -0
  98. package/docs/components/drop-down.md +28 -0
  99. package/docs/components/error-message.md +13 -0
  100. package/docs/components/file-dropzone.md +25 -0
  101. package/docs/components/filter-pannel.md +23 -0
  102. package/docs/components/form-actions-bar.md +22 -0
  103. package/docs/components/form-field-render.md +20 -0
  104. package/docs/components/form-section.md +15 -0
  105. package/docs/components/hidden-field.md +19 -0
  106. package/docs/components/index-column.md +13 -0
  107. package/docs/components/loading.md +21 -0
  108. package/docs/components/map-picker-client.md +22 -0
  109. package/docs/components/map-picker-osm.md +18 -0
  110. package/docs/components/map-picker.md +21 -0
  111. package/docs/components/menu-button.md +22 -0
  112. package/docs/components/multi-select-filter.md +20 -0
  113. package/docs/components/multi-select.md +23 -0
  114. package/docs/components/number-input.md +20 -0
  115. package/docs/components/page-title.md +13 -0
  116. package/docs/components/paginated-table.md +35 -0
  117. package/docs/components/pagination.md +27 -0
  118. package/docs/components/render-field.md +24 -0
  119. package/docs/components/rich-text-preview.md +18 -0
  120. package/docs/components/select.md +28 -0
  121. package/docs/components/status-badge.md +14 -0
  122. package/docs/components/switch.md +27 -0
  123. package/docs/components/table-filter-field.md +21 -0
  124. package/docs/components/table-toolbar.md +19 -0
  125. package/docs/components/text-area.md +20 -0
  126. package/docs/components/text-input.md +23 -0
  127. package/docs/components/time-picker.md +22 -0
  128. package/docs/components/toggle-inline-button.md +22 -0
  129. package/docs/components/toggle.md +21 -0
  130. package/docs/components/upload-files-preview.md +26 -0
  131. package/docs/contracts/controller-props.md +28 -0
  132. package/docs/contracts/dependency-map.md +57 -0
  133. package/docs/contracts/style-imports.md +27 -0
  134. package/package.json +6 -4
@@ -0,0 +1,24 @@
1
+ # CKEditorInput
2
+
3
+ - Export: `CKEditorInput`
4
+ - Extra exports: `CKEditorInputProps`, `CKEditorContentMetrics`
5
+ - Import: `import { CKEditorInput } from "@mantis-core/ui";`
6
+ - Base library: `@ckeditor/ckeditor5-react` + `ckeditor5`
7
+ - Base typing: explicit `CKEditorInputProps`
8
+ - Form contract: [`ControllerProps`](../contracts/controller-props.md)
9
+ - Required styles: `@mantis-core/styles/scss/ckeditor.scss`
10
+
11
+ ## Example
12
+
13
+ ```tsx
14
+ <CKEditorInput
15
+ controller={{ name: "body", control: form.control }}
16
+ minHeight="20rem"
17
+ showStats
18
+ onMetricsChange={(metrics) => console.log(metrics.words)}
19
+ />
20
+ ```
21
+
22
+ ## Notes
23
+
24
+ - This wrapper adds metrics, presets, and optional non-empty HTML validation on top of CKEditor.
@@ -0,0 +1,21 @@
1
+ # ConfirmDialog
2
+
3
+ - Export: `ConfirmDialog`
4
+ - Extra exports: `ConfirmDialogProps`, `ConfirmDialogSeverity`
5
+ - Import: `import { ConfirmDialog } from "@mantis-core/ui";`
6
+ - Base library: `primereact/dialog`
7
+ - Base typing: explicit `ConfirmDialogProps`
8
+ - Required styles: `@mantis-core/styles/scss/confirm-dialog.scss`
9
+
10
+ ## Example
11
+
12
+ ```tsx
13
+ <ConfirmDialog
14
+ visible={open}
15
+ title="Delete listing"
16
+ message="This action cannot be undone."
17
+ confirmSeverity="danger"
18
+ onConfirm={handleDelete}
19
+ onCancel={() => setOpen(false)}
20
+ />
21
+ ```
@@ -0,0 +1,19 @@
1
+ # DataState
2
+
3
+ - Export: `DataState`
4
+ - Extra exports: `DataStateProps`, `DataStateStatus`
5
+ - Import: `import { DataState } from "@mantis-core/ui";`
6
+ - Base library: custom state wrapper + `Button`
7
+ - Base typing: explicit `DataStateProps`
8
+ - Required styles: `@mantis-core/styles/scss/data-state.scss`
9
+
10
+ ## Example
11
+
12
+ ```tsx
13
+ <DataState
14
+ status={query.isError ? "error" : query.isLoading ? "loading" : rows.length === 0 ? "empty" : "ready"}
15
+ onRetry={() => query.refetch()}
16
+ >
17
+ <PaginatedTable value={rows}>{/* columns */}</PaginatedTable>
18
+ </DataState>
19
+ ```
@@ -0,0 +1,22 @@
1
+ # DateInput
2
+
3
+ - Export: `DateInput`
4
+ - Extra exports: `DateInputProps`
5
+ - Import: `import { DateInput } from "@mantis-core/ui";`
6
+ - Base library: `primereact/calendar`
7
+ - Base typing: `Omit<CalendarProps, "name" | "defaultValue"> & { controller: ControllerProps; block?: boolean }`
8
+ - Form contract: [`ControllerProps`](../contracts/controller-props.md)
9
+ - Required styles:
10
+ - `@mantis-core/styles/scss/inputs.scss`
11
+ - `@mantis-core/styles/scss/date-picker.scss`
12
+
13
+ ## Example
14
+
15
+ ```tsx
16
+ <DateInput
17
+ controller={{ name: "publishAt", control: form.control }}
18
+ block
19
+ showIcon
20
+ dateFormat="yy-mm-dd"
21
+ />
22
+ ```
@@ -0,0 +1,31 @@
1
+ # DirtyFormGuard and useDirtyFormGuard
2
+
3
+ - Exports: `DirtyFormGuard`, `useDirtyFormGuard`
4
+ - Extra exports: `DirtyFormGuardProps`, `UseDirtyFormGuardOptions`, `UseDirtyFormGuardResult`
5
+ - Base library: browser `beforeunload` + `window.confirm`
6
+ - Required styles: none
7
+
8
+ ## Component example
9
+
10
+ ```tsx
11
+ <DirtyFormGuard
12
+ isDirty={form.formState.isDirty}
13
+ message="You have unsaved changes."
14
+ />
15
+ ```
16
+
17
+ ## Hook example
18
+
19
+ ```tsx
20
+ const guard = useDirtyFormGuard({
21
+ isDirty: form.formState.isDirty,
22
+ message: "Leave without saving?",
23
+ });
24
+
25
+ void guard.confirmIfDirty(async () => router.push("/admin"));
26
+ ```
27
+
28
+ ## Notes
29
+
30
+ - Use the component for declarative page guards.
31
+ - Use the hook when you need to wrap specific navigation or destructive actions.
@@ -0,0 +1,28 @@
1
+ # DropDown
2
+
3
+ - Export: `DropDown`
4
+ - Extra exports: `DropDownProps`
5
+ - Import: `import { DropDown } from "@mantis-core/ui";`
6
+ - Base library: `primereact/dropdown`
7
+ - Base typing: `Omit<DropdownProps, "name" | "defaultValue"> & { controller: ControllerProps; block?: boolean }`
8
+ - Form contract: [`ControllerProps`](../contracts/controller-props.md)
9
+ - Required styles: `@mantis-core/styles/scss/inputs.scss`
10
+
11
+ ## Example
12
+
13
+ ```tsx
14
+ <DropDown
15
+ controller={{ name: "status", control: form.control }}
16
+ block
17
+ options={[
18
+ { label: "Draft", value: "draft" },
19
+ { label: "Published", value: "published" },
20
+ ]}
21
+ optionLabel="label"
22
+ optionValue="value"
23
+ />
24
+ ```
25
+
26
+ ## Notes
27
+
28
+ - This is the PrimeReact dropdown wrapper, not the `react-select` wrapper.
@@ -0,0 +1,13 @@
1
+ # ErrorMessage
2
+
3
+ - Export: `ErrorMessage`
4
+ - Import: `import { ErrorMessage } from "@mantis-core/ui";`
5
+ - Base library: `@hookform/error-message`
6
+ - Base typing: wrapper export around hook-form error rendering
7
+ - Required styles: none
8
+
9
+ ## Example
10
+
11
+ ```tsx
12
+ <ErrorMessage errors={form.formState.errors} name="title" />
13
+ ```
@@ -0,0 +1,25 @@
1
+ # FileDropzone
2
+
3
+ - Export: `FileDropzone`
4
+ - Extra exports: `FileDropzoneProps`, `FileDropzoneRejectedFile`, `FileDropzoneRejectCode`
5
+ - Import: `import { FileDropzone } from "@mantis-core/ui";`
6
+ - Base library: custom drag-and-drop file input
7
+ - Base typing: explicit `FileDropzoneProps`
8
+ - Required styles: `@mantis-core/styles/scss/file-dropzone.scss`
9
+
10
+ ## Example
11
+
12
+ ```tsx
13
+ <FileDropzone
14
+ controller={{ name: "attachments", control: form.control, defaultValue: [] }}
15
+ accept={["image/*", ".pdf"]}
16
+ maxFiles={5}
17
+ maxSizeBytes={5 * 1024 * 1024}
18
+ label="Attachments"
19
+ />
20
+ ```
21
+
22
+ ## Notes
23
+
24
+ - Supports both `react-hook-form` mode and plain controlled mode with `value` and `onChange`.
25
+ - Rejections are normalized into `FileDropzoneRejectedFile`.
@@ -0,0 +1,23 @@
1
+ # FilterPannel
2
+
3
+ - Export: `FilterPannel`
4
+ - Import: `import { FilterPannel } from "@mantis-core/ui";`
5
+ - Base library: `primereact/sidebar` + `react-hook-form`
6
+ - Base typing: `PropsWithChildren<{ onApplyFilter: (data: T) => Promise<void> }>`
7
+ - Required styles: none
8
+
9
+ ## Example
10
+
11
+ ```tsx
12
+ <FilterPannel<{ status: string | null; city: string | null }>
13
+ onApplyFilter={async (filters) => setFilters(filters)}
14
+ >
15
+ <DropDown controller={{ name: "status" }} options={statusOptions} />
16
+ <DropDown controller={{ name: "city" }} options={cityOptions} />
17
+ </FilterPannel>
18
+ ```
19
+
20
+ ## Notes
21
+
22
+ - The component creates its own `FormProvider`.
23
+ - Empty values are normalized to `null` before `onApplyFilter`.
@@ -0,0 +1,22 @@
1
+ # FormActionsBar
2
+
3
+ - Export: `FormActionsBar`
4
+ - Import: `import { FormActionsBar } from "@mantis-core/ui";`
5
+ - Base library: custom layout + `Button`
6
+ - Base typing: explicit `FormActionsBarProps`
7
+ - Required styles: `@mantis-core/styles/scss/form-actions.scss`
8
+
9
+ ## Example
10
+
11
+ ```tsx
12
+ <FormActionsBar
13
+ align="between"
14
+ sticky
15
+ leftSlot={<span>Unsaved changes</span>}
16
+ primaryLabel="Save"
17
+ primaryType="submit"
18
+ secondaryLabel="Cancel"
19
+ secondaryOutlined
20
+ onSecondaryClick={() => router.back()}
21
+ />
22
+ ```
@@ -0,0 +1,20 @@
1
+ # FormFieldRender
2
+
3
+ - Export: `FormFieldRender`
4
+ - Extra exports: `FormFieldRenderProps`
5
+ - Import: `import { FormFieldRender } from "@mantis-core/ui";`
6
+ - Base library: custom label and error wrapper
7
+ - Base typing: `{ name: string; label: string | ReactElement; labelProps?; containerClassName?; render: ({ name }) => ReactElement | ReactNode }`
8
+ - Required styles: none
9
+
10
+ ## Example
11
+
12
+ ```tsx
13
+ <FormFieldRender
14
+ name="email"
15
+ label="Email"
16
+ render={({ name }) => (
17
+ <TextInput controller={{ name, control: form.control }} block />
18
+ )}
19
+ />
20
+ ```
@@ -0,0 +1,15 @@
1
+ # FormSection
2
+
3
+ - Export: `FormSection`
4
+ - Import: `import { FormSection } from "@mantis-core/ui";`
5
+ - Base library: custom card section
6
+ - Base typing: `{ title: string; description?: string; icon?: ReactNode; children: ReactNode; className?: string }`
7
+ - Required styles: none
8
+
9
+ ## Example
10
+
11
+ ```tsx
12
+ <FormSection title="Publishing" description="Visibility and timing controls">
13
+ <Switch name="published" control={form.control} />
14
+ </FormSection>
15
+ ```
@@ -0,0 +1,19 @@
1
+ # HiddenField
2
+
3
+ - Export: `HiddenField`
4
+ - Extra exports: `HiddenFieldProps`
5
+ - Import: `import { HiddenField } from "@mantis-core/ui";`
6
+ - Base library: `react-hook-form`
7
+ - Base typing: `ControllerProps & { hidden?: boolean }`
8
+ - Form contract: [`ControllerProps`](../contracts/controller-props.md)
9
+ - Required styles: none
10
+
11
+ ## Example
12
+
13
+ ```tsx
14
+ <HiddenField
15
+ name="tenantId"
16
+ control={form.control}
17
+ defaultValue={tenantId}
18
+ />
19
+ ```
@@ -0,0 +1,13 @@
1
+ # IndexColumn
2
+
3
+ - Export: `IndexColumn`
4
+ - Import: `import { IndexColumn } from "@mantis-core/ui";`
5
+ - Base library: `primereact/column`
6
+ - Base typing: `(props?: ColumnProps) => JSX.Element`
7
+ - Required styles: none beyond table context
8
+
9
+ ## Example
10
+
11
+ ```tsx
12
+ <IndexColumn style={{ width: "4rem" }} />
13
+ ```
@@ -0,0 +1,21 @@
1
+ # Loading
2
+
3
+ - Export: `Loading`
4
+ - Extra exports: `LoadingWrapperProps`
5
+ - Import: `import { Loading } from "@mantis-core/ui";`
6
+ - Base library: custom full-screen overlay
7
+ - Base typing: `PropsWithChildren<{ loading?: boolean; texto?: string; className?: string }>`
8
+ - Required styles: none
9
+
10
+ ## Example
11
+
12
+ ```tsx
13
+ <Loading loading={isSubmitting} texto="Saving changes...">
14
+ <FormScreen />
15
+ </Loading>
16
+ ```
17
+
18
+ ## Notes
19
+
20
+ - When `loading` is `false`, it returns `children` unchanged.
21
+ - This is a page overlay, not an inline spinner primitive.
@@ -0,0 +1,22 @@
1
+ # MapPickerClient
2
+
3
+ - Export: `MapPickerClient`
4
+ - Extra exports: `MapPickerClientProps`
5
+ - Import: `import { MapPickerClient } from "@mantis-core/ui";`
6
+ - Base library: `react-leaflet` + `leaflet`
7
+ - Base typing: `{ onLocationSelect: (lat: number, lng: number) => void; initialLat?: number | null; initialLng?: number | null }`
8
+ - Required styles: Leaflet CSS is imported by the component
9
+
10
+ ## Example
11
+
12
+ ```tsx
13
+ <MapPickerClient
14
+ initialLat={-2.9}
15
+ initialLng={-79.0}
16
+ onLocationSelect={(lat, lng) => console.log(lat, lng)}
17
+ />
18
+ ```
19
+
20
+ ## Notes
21
+
22
+ - Marker assets are expected under `/leaflet/*`.
@@ -0,0 +1,18 @@
1
+ # MapPickerOSM
2
+
3
+ - Export: `MapPickerOSM`
4
+ - Extra exports: `MapPickerOSMProps`, `LatLng`
5
+ - Import: `import { MapPickerOSM } from "@mantis-core/ui";`
6
+ - Base library: Leaflet loaded from CDN
7
+ - Base typing: `{ initialPosition?: LatLng; zoom?: number; height?: string; onChange?: (pos: LatLng) => void; onSave?: (pos: LatLng) => void }`
8
+ - Required styles: no `@mantis-core/styles` partial; Leaflet CSS is injected from CDN
9
+
10
+ ## Example
11
+
12
+ ```tsx
13
+ <MapPickerOSM
14
+ initialPosition={{ lat: -12.0464, lng: -77.0428 }}
15
+ onChange={(pos) => console.log(pos)}
16
+ onSave={(pos) => saveCoordinates(pos)}
17
+ />
18
+ ```
@@ -0,0 +1,21 @@
1
+ # MapPicker
2
+
3
+ - Export: `MapPicker`
4
+ - Extra exports: `MapPickerProps`
5
+ - Import: `import { MapPicker } from "@mantis-core/ui";`
6
+ - Base library: `next/dynamic` wrapper over `MapPickerClient`
7
+ - Base typing: `{ onLocationSelect: (lat: number, lng: number) => void; initialLat?: number | null; initialLng?: number | null }`
8
+ - Required styles: Leaflet CSS comes from the client implementation
9
+
10
+ ## Example
11
+
12
+ ```tsx
13
+ <MapPicker
14
+ initialLat={-2.9}
15
+ initialLng={-79.0}
16
+ onLocationSelect={(lat, lng) => {
17
+ form.setValue("lat", lat);
18
+ form.setValue("lng", lng);
19
+ }}
20
+ />
21
+ ```
@@ -0,0 +1,22 @@
1
+ # MenuButton
2
+
3
+ - Export: `MenuButton`
4
+ - Extra exports: `MenuButtonProps`, `ActionMenuItem`
5
+ - Import: `import { MenuButton } from "@mantis-core/ui";`
6
+ - Base library: `primereact/tieredmenu`
7
+ - Base typing:
8
+ - `ActionMenuItem extends MenuItem { route?: string; items?: ActionMenuItem[] | ActionMenuItem[][] }`
9
+ - `MenuButtonProps = { label?: string; icon?: string; items?: ActionMenuItem[] }`
10
+ - Required styles: [`buttons.scss`](../../../../packages/mantis-core-styles/docs/styles/buttons.md) indirectly through `Button`
11
+
12
+ ## Example
13
+
14
+ ```tsx
15
+ <MenuButton
16
+ label="Actions"
17
+ items={[
18
+ { label: "Edit", icon: "pi pi-pencil", route: "/admin/listings/1" },
19
+ { label: "Delete", icon: "pi pi-trash", command: () => setOpen(true) },
20
+ ]}
21
+ />
22
+ ```
@@ -0,0 +1,20 @@
1
+ # MultiSelectFilter
2
+
3
+ - Export: `MultiSelectFilter`
4
+ - Import: `import { MultiSelectFilter } from "@mantis-core/ui";`
5
+ - Base library: `primereact/multiselect`
6
+ - Base typing: `Omit<MultiSelectProps, "value" | "onChange"> & { filterProps: ColumnFilterElementTemplateOptions }`
7
+ - Required styles: `@mantis-core/styles/scss/inputs.scss`
8
+
9
+ ## Example
10
+
11
+ ```tsx
12
+ filterElement={(filterProps) => (
13
+ <MultiSelectFilter
14
+ filterProps={filterProps}
15
+ options={statusOptions}
16
+ optionLabel="label"
17
+ optionValue="value"
18
+ />
19
+ )}
20
+ ```
@@ -0,0 +1,23 @@
1
+ # MultiSelect
2
+
3
+ - Export: `MultiSelect`
4
+ - Import: `import { MultiSelect } from "@mantis-core/ui";`
5
+ - Base library: `primereact/multiselect`
6
+ - Base typing: `Omit<PrimeMultiSelectProps, "name" | "defaultValue"> & { controller: ControllerProps; block?: boolean }`
7
+ - Form contract: [`ControllerProps`](../contracts/controller-props.md)
8
+ - Required styles: `@mantis-core/styles/scss/inputs.scss`
9
+
10
+ ## Example
11
+
12
+ ```tsx
13
+ <MultiSelect
14
+ controller={{ name: "tags", control: form.control }}
15
+ block
16
+ options={[
17
+ { label: "Featured", value: "featured" },
18
+ { label: "Luxury", value: "luxury" },
19
+ ]}
20
+ optionLabel="label"
21
+ optionValue="value"
22
+ />
23
+ ```
@@ -0,0 +1,20 @@
1
+ # NumberInput
2
+
3
+ - Export: `NumberInput`
4
+ - Extra exports: `NumberInputProps`
5
+ - Import: `import { NumberInput } from "@mantis-core/ui";`
6
+ - Base library: `primereact/inputnumber`
7
+ - Base typing: `Omit<InputNumberProps, "name" | "defaultValue"> & { controller: ControllerProps; block?: boolean }`
8
+ - Form contract: [`ControllerProps`](../contracts/controller-props.md)
9
+ - Required styles: `@mantis-core/styles/scss/inputs.scss`
10
+
11
+ ## Example
12
+
13
+ ```tsx
14
+ <NumberInput
15
+ controller={{ name: "price", control: form.control }}
16
+ block
17
+ mode="currency"
18
+ currency="USD"
19
+ />
20
+ ```
@@ -0,0 +1,13 @@
1
+ # PageTitle
2
+
3
+ - Export: `PageTitle`
4
+ - Import: `import { PageTitle } from "@mantis-core/ui";`
5
+ - Base library: custom typographic wrapper
6
+ - Base typing: `PropsWithChildren`
7
+ - Required styles: none
8
+
9
+ ## Example
10
+
11
+ ```tsx
12
+ <PageTitle>Inventory Overview</PageTitle>
13
+ ```
@@ -0,0 +1,35 @@
1
+ # PaginatedTable
2
+
3
+ - Export: `PaginatedTable`
4
+ - Extra exports: `PaginatedTableProps`
5
+ - Import: `import { PaginatedTable } from "@mantis-core/ui";`
6
+ - Base library: `primereact/datatable` + `primereact/column`
7
+ - Base typing: `DataTableBaseProps<TValue> & { showIndexColumn?; showActionColumn?; useMantisCoreStyles?; indexColumnProps?; actionColumnProps?; actionColumnItems? }`
8
+ - Required styles: `@mantis-core/styles/scss/table.scss`
9
+
10
+ ## Example
11
+
12
+ ```tsx
13
+ import { Column } from "primereact/column";
14
+
15
+ <PaginatedTable
16
+ value={rows}
17
+ totalRecords={total}
18
+ lazy
19
+ first={first}
20
+ rows={pageSize}
21
+ onPage={onPage}
22
+ showActionColumn
23
+ actionColumnItems={(row) => [
24
+ { label: "Edit", icon: "pi pi-pencil", route: `/admin/listings/${row.id}` },
25
+ ]}
26
+ >
27
+ <Column field="name" header="Name" sortable />
28
+ <Column field="status" header="Status" />
29
+ </PaginatedTable>
30
+ ```
31
+
32
+ ## Notes
33
+
34
+ - It sets Mantis defaults for pagination, stripes, gridlines, sorting, empty state, and responsive layout.
35
+ - Set `useMantisCoreStyles={false}` only if you want plain PrimeReact styling.
@@ -0,0 +1,27 @@
1
+ # Pagination, PaginationInfo, and PageSizeSelector
2
+
3
+ - Exports: `Pagination`, `PaginationInfo`, `PageSizeSelector`
4
+ - Extra exports: `PaginationProps`, `PaginationInfoProps`, `PageSizeSelectorProps`
5
+ - Import: `import { Pagination, PaginationInfo, PageSizeSelector } from "@mantis-core/ui";`
6
+ - Base library: custom pagination UI using `@mantis-core/utils`
7
+ - Required styles: none
8
+
9
+ ## Example
10
+
11
+ ```tsx
12
+ <Pagination
13
+ currentPage={page}
14
+ totalPages={totalPages}
15
+ onPageChange={setPage}
16
+ maxVisible={5}
17
+ />
18
+
19
+ <PaginationInfo currentPage={page} pageSize={pageSize} totalCount={total} />
20
+
21
+ <PageSizeSelector pageSize={pageSize} onPageSizeChange={setPageSize} />
22
+ ```
23
+
24
+ ## Notes
25
+
26
+ - This is not PrimeReact `Paginator`.
27
+ - `paginator.scss` styles PrimeReact paginator markup, not these exports.
@@ -0,0 +1,24 @@
1
+ # RenderField
2
+
3
+ - Export: `RenderField`
4
+ - Extra exports: `RenderFieldProps`
5
+ - Import: `import { RenderField } from "@mantis-core/ui";`
6
+ - Base library: `react-hook-form` `Controller`
7
+ - Base typing: `{ name: string; defaultValue?: any; control?: Control; render: (props: RenderProps) => ReactElement; rules?: RegisterOptions }`
8
+ - Required styles: none
9
+
10
+ ## Example
11
+
12
+ ```tsx
13
+ <RenderField
14
+ name="featured"
15
+ control={form.control}
16
+ render={({ field }) => (
17
+ <input
18
+ type="checkbox"
19
+ checked={!!field.value}
20
+ onChange={(e) => field.onChange(e.target.checked)}
21
+ />
22
+ )}
23
+ />
24
+ ```
@@ -0,0 +1,18 @@
1
+ # RichTextPreview
2
+
3
+ - Export: `RichTextPreview`
4
+ - Extra exports: `RichTextPreviewProps`
5
+ - Import: `import { RichTextPreview } from "@mantis-core/ui";`
6
+ - Base library: sanitized HTML renderer via `@mantis-core/utils`
7
+ - Base typing: `{ html?: string | null; className?: string; sanitize?: boolean; size?: "sm" | "md" | "lg"; emptyFallback?: ReactNode }`
8
+ - Required styles: `@mantis-core/styles/scss/rich-text-preview.scss`
9
+
10
+ ## Example
11
+
12
+ ```tsx
13
+ <RichTextPreview
14
+ html={post.bodyHtml}
15
+ size="lg"
16
+ emptyFallback={<p>No content yet.</p>}
17
+ />
18
+ ```
@@ -0,0 +1,28 @@
1
+ # Select
2
+
3
+ - Export: `Select`
4
+ - Import: `import { Select } from "@mantis-core/ui";`
5
+ - Base library: `react-select` or `react-select/creatable`
6
+ - Base typing: `Omit<ReactSelectProps, "name" | "defaultValue"> & { controller: ControllerProps; block?: boolean; variant?: ButtonVariant; isCreatable?: boolean; onCreateOption?; formatCreateLabel? }`
7
+ - Form contract: [`ControllerProps`](../contracts/controller-props.md)
8
+ - Required styles: `@mantis-core/styles/scss/select.scss`
9
+
10
+ ## Example
11
+
12
+ ```tsx
13
+ <Select
14
+ controller={{ name: "agent", control: form.control }}
15
+ block
16
+ variant="secondary"
17
+ options={[
18
+ { label: "Alice", value: "alice" },
19
+ { label: "Bob", value: "bob" },
20
+ ]}
21
+ isClearable
22
+ />
23
+ ```
24
+
25
+ ## Notes
26
+
27
+ - This is not PrimeReact.
28
+ - Keep `classNamePrefix="react-select"` behavior so the shared SCSS continues to match.
@@ -0,0 +1,14 @@
1
+ # StatusBadge
2
+
3
+ - Export: `StatusBadge`
4
+ - Extra exports: `StatusBadgeProps`, `StatusBadgeTone`, `StatusBadgeSize`
5
+ - Import: `import { StatusBadge } from "@mantis-core/ui";`
6
+ - Base library: custom span primitive
7
+ - Base typing: `Omit<HTMLAttributes<HTMLSpanElement>, "children"> & { label?: ReactNode; tone?: "success" | "muted" | "warning" | "info" | "danger"; size?: "sm" | "md"; block?: boolean; children?: ReactNode }`
8
+ - Required styles: `@mantis-core/styles/scss/status-badge.scss`
9
+
10
+ ## Example
11
+
12
+ ```tsx
13
+ <StatusBadge tone="success" size="sm" label="Published" />
14
+ ```