react-admin-crud-manager 1.2.9 → 1.2.11
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.
- package/README.md +159 -40
- package/dist/index.cjs.js +1000 -22
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.es.js +10700 -3254
- package/dist/index.es.js.map +1 -1
- package/dist/types/OptionalSnackbarProvider.d.ts +1 -1
- package/dist/types/components/Form/components/FilePicker.d.ts +19 -0
- package/dist/types/components/Form/components/FreeEditor.d.ts +14 -0
- package/dist/types/components/Form/components/RenderFields.d.ts +1 -0
- package/dist/types/types/crudtypes.d.ts +45 -0
- package/package.json +2 -1
package/README.md
CHANGED
|
@@ -10,7 +10,7 @@ A reusable React CRUD admin template with modular components for rapid admin das
|
|
|
10
10
|
- Tailwind CSS for styling
|
|
11
11
|
- Server-side and client-side data handling
|
|
12
12
|
- Sorting, filtering, searching, and pagination support
|
|
13
|
-
- Rich form fields including text, select, image upload, rich text editor, and more
|
|
13
|
+
- Rich form fields including text, select, image upload, file upload, rich text editor, and more
|
|
14
14
|
|
|
15
15
|
## Installation
|
|
16
16
|
|
|
@@ -22,13 +22,15 @@ npm install react-admin-crud-manager
|
|
|
22
22
|
|
|
23
23
|
### 1. Use the component
|
|
24
24
|
|
|
25
|
-
```
|
|
26
|
-
import Crud from
|
|
25
|
+
```js
|
|
26
|
+
import Crud from "react-admin-crud-manager";
|
|
27
27
|
|
|
28
28
|
function App() {
|
|
29
29
|
const config = {
|
|
30
|
-
title:
|
|
31
|
-
fetchData: async () => {
|
|
30
|
+
title: "Users",
|
|
31
|
+
fetchData: async () => {
|
|
32
|
+
/* fetch logic */
|
|
33
|
+
},
|
|
32
34
|
// ...other config options
|
|
33
35
|
};
|
|
34
36
|
return <Crud config={config} />;
|
|
@@ -81,26 +83,26 @@ Below is a complete reference of the public props accepted by this package (type
|
|
|
81
83
|
| `exportCSV` | object | Export data as CSV | `{ enabled: true, fileName: "users.csv", fields: [{ label: "Name", key: "name" }, ...] }` |
|
|
82
84
|
| `rowClick` | function or boolean | Callback on table row click | `(row: object, rowIndex: number) => void` or `true` (setting true will open details) |
|
|
83
85
|
|
|
84
|
-
|
|
86
|
+
`customButtons` can also be passed in `tableConfig` to render extra header toolbar buttons with custom click handlers. See [Custom Toolbar Buttons (Header)](#12-custom-toolbar-buttons-header).
|
|
85
87
|
|
|
86
88
|
#### Table Column Object (`table_head[]`)
|
|
87
89
|
|
|
88
|
-
| Key | Type | Description
|
|
89
|
-
| ---------------- | -------- |
|
|
90
|
-
| `key` | string | Property name in row objects
|
|
91
|
-
| `title` | string | Column header text
|
|
92
|
-
| `type` | string | Column renderer type
|
|
93
|
-
| `imageKey` | string | Image property for avatar/group types
|
|
94
|
-
| `titleKey` | string | Title property for group/avatar types
|
|
95
|
-
| `subtitleKey` | string | Subtitle property for group/avatar types
|
|
96
|
-
| `onClickDetails` | boolean | Clicking cell opens view details modal
|
|
97
|
-
| `variant` | string | Chip styling variant
|
|
98
|
-
| `chipOptions` | array | Map values to chip labels and colors; array of `{ value: string\|number\|boolean, label: string, color?: string }`
|
|
99
|
-
| `defaultColor` | string | Default color for chips (if no match in chipOptions)
|
|
100
|
-
| `className` | string | Custom CSS class for cell content
|
|
101
|
-
| `format` | string | Date format pattern
|
|
102
|
-
| `menuList` | array | Action menu items; array of `{ title: string, type: string, variant?: string, icon?: ReactNode }`
|
|
103
|
-
| `render` | function | Custom cell renderer (overrides built-in logic)
|
|
90
|
+
| Key | Type | Description | Accepted Values / Example |
|
|
91
|
+
| ---------------- | -------- | --------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------- |
|
|
92
|
+
| `key` | string | Property name in row objects | `"id"`, `"name"`, `"email"` (must exist in data objects) |
|
|
93
|
+
| `title` | string | Column header text | `"User ID"`, `"Full Name"`, `"Email Address"` |
|
|
94
|
+
| `type` | string | Column renderer type | `"plain"` (default), `"index"` (row number), `"group"` (avatar+text), `"chip"` (badge), `"date"`, `"avatar"`, `"menu_actions"` |
|
|
95
|
+
| `imageKey` | string | Image property for avatar/group types | `"profileImage"`, `"avatarUrl"` (path to image in data object) |
|
|
96
|
+
| `titleKey` | string | Title property for group/avatar types | `"name"`, `"fullName"` (property key in data object) |
|
|
97
|
+
| `subtitleKey` | string | Subtitle property for group/avatar types | `"email"`, `"department"` (property key in data object) |
|
|
98
|
+
| `onClickDetails` | boolean | Clicking cell opens view details modal | `true`, `false` (default: `false`) |
|
|
99
|
+
| `variant` | string | Chip styling variant | `"contained"`, `"outline"`, `"soft"` (used with `type: "chip"`) |
|
|
100
|
+
| `chipOptions` | array | Map values to chip labels and colors; array of `{ value: string\|number\|boolean, label: string, color?: string }` | `[{ value: "active", label: "Active", color: "green" }, { value: "inactive", label: "Inactive", color: "red" }]` |
|
|
101
|
+
| `defaultColor` | string | Default color for chips (if no match in chipOptions) | `"green"`, `"red"`, `"blue"`, `"yellow"`, `"purple"`, `"gray"`, etc. |
|
|
102
|
+
| `className` | string | Custom CSS class for cell content | Tailwind classes: `"font-bold text-sm text-gray-600"` |
|
|
103
|
+
| `format` | string | Date format pattern | `"DD MMM YYYY"`, `"YYYY-MM-DD"`, `"DD/MM/YYYY HH:mm"` (uses date-fns patterns) |
|
|
104
|
+
| `menuList` | array | Action menu items; array of `{ title: string, type: string, variant?: string, icon?: ReactNode, onClick?: Function }` | `[{ title: "Edit", type: "edit", icon: <EditIcon /> }, { title: "Open", type: "custom", onClick: (event, row) => setShowModal(true) }]` |
|
|
105
|
+
| `render` | function | Custom cell renderer (overrides built-in logic) | `(row: object, rowIndex: number) => ReactNode`; e.g., `(row) => <span>{row.name.toUpperCase()}</span>` |
|
|
104
106
|
|
|
105
107
|
---
|
|
106
108
|
|
|
@@ -168,19 +170,19 @@ Used by `modalConfig.*.formFields`, `filterConfig.fields`, and `viewModal.fields
|
|
|
168
170
|
|
|
169
171
|
#### Common Field Properties (All Types)
|
|
170
172
|
|
|
171
|
-
| Key | Type | Required | Description | Accepted Values / Example
|
|
172
|
-
| ------------------ | -------- | -------- | ------------------------------------------- |
|
|
173
|
-
| `key` | string | Yes | Property name/identifier for form data | `"username"`, `"email"`, `"birth_date"`
|
|
174
|
-
| `label` | string | No | Human-readable label for the field | `"User Name"`, `"Email Address"`, `"Date of Birth"`
|
|
175
|
-
| `type` | string | Yes | Field type determining the input/renderer | `"text"`, `"number"`, `"email"`, `"password"`, `"select"`, `"checkbox"`, `"radio"`, `"switch"`, `"phone"`, `"textarea"`, `"image"`, `"video"`, `"audio"`, `"tinyEditor"`, `"group"` |
|
|
176
|
-
| `required` | boolean | No | Field must have a value for form submission | `true`, `false` (default: `false`)
|
|
177
|
-
| `minLength` | number | No | Minimum character length (for text fields) | `5`, `10`, `50`
|
|
178
|
-
| `placeholder` | string | No | Placeholder text shown in empty field | `"Enter your name"`, `"user@example.com"`
|
|
179
|
-
| `disabled` | boolean | No | Field is disabled and read-only | `true`, `false` (default: `false`)
|
|
180
|
-
| `parentClass` | string | No | Custom CSS classes for field wrapper (grid) | Tailwind classes: `"col-span-6"`, `"col-span-12"`
|
|
181
|
-
| `renderCondition` | function | No | Show field based on form data | `(formData: Record<string, any>) => boolean`; e.g., `(data) => data.userType === 'admin'`
|
|
182
|
-
| `customValidation` | function | No | Custom validation logic | `(value: any) => boolean \| string`; return `false` for invalid, error message string, or `true` for valid
|
|
183
|
-
| `className` | string | No | Custom CSS class for input element | Tailwind classes: `"bg-gray-100 rounded-lg"`
|
|
173
|
+
| Key | Type | Required | Description | Accepted Values / Example |
|
|
174
|
+
| ------------------ | -------- | -------- | ------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
175
|
+
| `key` | string | Yes | Property name/identifier for form data | `"username"`, `"email"`, `"birth_date"` |
|
|
176
|
+
| `label` | string | No | Human-readable label for the field | `"User Name"`, `"Email Address"`, `"Date of Birth"` |
|
|
177
|
+
| `type` | string | Yes | Field type determining the input/renderer | `"text"`, `"number"`, `"email"`, `"password"`, `"select"`, `"checkbox"`, `"radio"`, `"switch"`, `"phone"`, `"textarea"`, `"image"`, `"video"`, `"audio"`, `"file"`, `"tinyEditor"`, `"group"` |
|
|
178
|
+
| `required` | boolean | No | Field must have a value for form submission | `true`, `false` (default: `false`) |
|
|
179
|
+
| `minLength` | number | No | Minimum character length (for text fields) | `5`, `10`, `50` |
|
|
180
|
+
| `placeholder` | string | No | Placeholder text shown in empty field | `"Enter your name"`, `"user@example.com"` |
|
|
181
|
+
| `disabled` | boolean | No | Field is disabled and read-only | `true`, `false` (default: `false`) |
|
|
182
|
+
| `parentClass` | string | No | Custom CSS classes for field wrapper (grid) | Tailwind classes: `"col-span-6"`, `"col-span-12"` |
|
|
183
|
+
| `renderCondition` | function | No | Show field based on form data | `(formData: Record<string, any>) => boolean`; e.g., `(data) => data.userType === 'admin'` |
|
|
184
|
+
| `customValidation` | function | No | Custom validation logic | `(value: any) => boolean \| string`; return `false` for invalid, error message string, or `true` for valid |
|
|
185
|
+
| `className` | string | No | Custom CSS class for input element | Tailwind classes: `"bg-gray-100 rounded-lg"` |
|
|
184
186
|
|
|
185
187
|
#### Type-Specific Properties
|
|
186
188
|
|
|
@@ -261,7 +263,7 @@ Used by `modalConfig.*.formFields`, `filterConfig.fields`, and `viewModal.fields
|
|
|
261
263
|
| ---------- | ------- | --------------------------- | ----------------------------------------------- |
|
|
262
264
|
| `accept` | string | MIME type filter | `"video/*"` (default), `"video/mp4,video/webm"` |
|
|
263
265
|
| `dragDrop` | boolean | Enable drag-and-drop upload | `true`, `false` (default: `false`) |
|
|
264
|
-
| `maxSize` | number | Maximum file size in
|
|
266
|
+
| `maxSize` | number | Maximum file size in MB | `5`, `10`, `25` |
|
|
265
267
|
|
|
266
268
|
##### `"audio"` Field
|
|
267
269
|
|
|
@@ -269,7 +271,45 @@ Used by `modalConfig.*.formFields`, `filterConfig.fields`, and `viewModal.fields
|
|
|
269
271
|
| ---------- | ------- | --------------------------- | ----------------------------------------------- |
|
|
270
272
|
| `accept` | string | MIME type filter | `"audio/*"` (default), `"audio/mpeg,audio/wav"` |
|
|
271
273
|
| `dragDrop` | boolean | Enable drag-and-drop upload | `true`, `false` (default: `false`) |
|
|
272
|
-
| `maxSize` | number | Maximum file size in
|
|
274
|
+
| `maxSize` | number | Maximum file size in MB | `5`, `10`, `25` |
|
|
275
|
+
|
|
276
|
+
##### `"file"` Field
|
|
277
|
+
|
|
278
|
+
Upload any file type in add/edit forms, with client-side type restriction and file icon preview.
|
|
279
|
+
|
|
280
|
+
| Property | Type | Description | Accepted Values / Example |
|
|
281
|
+
| ---------- | ------- | ------------------------------------------------ | ------------------------------------------------------------------------ |
|
|
282
|
+
| `accept` | string | Allowed file types (same as native input accept) | `"*/*"` (default), `".pdf,.doc,.docx"`, `"application/pdf"`, `"image/*"` |
|
|
283
|
+
| `dragDrop` | boolean | Enable drag-and-drop upload | `true`, `false` (default: `false`) |
|
|
284
|
+
| `maxSize` | number | Maximum file size in MB | `5`, `10`, `25` |
|
|
285
|
+
|
|
286
|
+
Behavior:
|
|
287
|
+
|
|
288
|
+
- Validates selected/dropped file using `accept`
|
|
289
|
+
- Shows file icon automatically based on extension (pdf/doc/xls/ppt/zip/txt/json, etc.)
|
|
290
|
+
- Shows selected file name and allows replacing/removing the file
|
|
291
|
+
|
|
292
|
+
Example:
|
|
293
|
+
|
|
294
|
+
```js
|
|
295
|
+
const formFields = [
|
|
296
|
+
{
|
|
297
|
+
key: "attachment",
|
|
298
|
+
label: "Attachment",
|
|
299
|
+
type: "file",
|
|
300
|
+
accept: ".pdf,.doc,.docx",
|
|
301
|
+
maxSize: 10, // MB
|
|
302
|
+
dragDrop: true,
|
|
303
|
+
required: true,
|
|
304
|
+
},
|
|
305
|
+
{
|
|
306
|
+
key: "contractFile",
|
|
307
|
+
label: "Contract",
|
|
308
|
+
type: "file",
|
|
309
|
+
accept: "application/pdf",
|
|
310
|
+
},
|
|
311
|
+
];
|
|
312
|
+
```
|
|
273
313
|
|
|
274
314
|
##### `"tinyEditor"` Field
|
|
275
315
|
|
|
@@ -714,13 +754,91 @@ const config = {
|
|
|
714
754
|
};
|
|
715
755
|
```
|
|
716
756
|
|
|
757
|
+
### 12. Custom Toolbar Buttons (Header)
|
|
758
|
+
|
|
759
|
+
Add custom buttons in the table header area (same area as Add / Search / Filter / Sort / Export), with your own click handlers.
|
|
760
|
+
|
|
761
|
+
```js
|
|
762
|
+
import { Upload, RefreshCw } from "lucide-react";
|
|
763
|
+
|
|
764
|
+
const config = {
|
|
765
|
+
tableConfig: {
|
|
766
|
+
table_head: [...],
|
|
767
|
+
search: { enabled: true },
|
|
768
|
+
filter: { enabled: true },
|
|
769
|
+
sort: { enabled: true },
|
|
770
|
+
customButtons: [
|
|
771
|
+
{
|
|
772
|
+
key: "import",
|
|
773
|
+
label: "Import",
|
|
774
|
+
icon: <Upload className="w-4 h-4" />,
|
|
775
|
+
color: "primary",
|
|
776
|
+
variant: "contained",
|
|
777
|
+
onClick: (event, ctx) => {
|
|
778
|
+
// ctx has: data, filteredData, sortedData, paginatedData,
|
|
779
|
+
// searchTerm, appliedFilters, currentPage, pageSize, totalRecords
|
|
780
|
+
console.log("Import clicked", ctx.totalRecords);
|
|
781
|
+
},
|
|
782
|
+
},
|
|
783
|
+
{
|
|
784
|
+
key: "refresh",
|
|
785
|
+
label: "Refresh",
|
|
786
|
+
icon: <RefreshCw className="w-4 h-4" />,
|
|
787
|
+
variant: "outlined",
|
|
788
|
+
onClick: async () => {
|
|
789
|
+
// your custom logic
|
|
790
|
+
},
|
|
791
|
+
},
|
|
792
|
+
],
|
|
793
|
+
customMenuItems: [
|
|
794
|
+
{
|
|
795
|
+
key: "bulk-actions",
|
|
796
|
+
label: "Bulk Action",
|
|
797
|
+
onClick: (event, ctx) => {
|
|
798
|
+
console.log("bulk action", ctx.filteredData.length);
|
|
799
|
+
},
|
|
800
|
+
},
|
|
801
|
+
{
|
|
802
|
+
key: "archive-all",
|
|
803
|
+
label: "Archive Filtered",
|
|
804
|
+
onClick: async (event, ctx) => {
|
|
805
|
+
// run async logic using current filtered records
|
|
806
|
+
},
|
|
807
|
+
},
|
|
808
|
+
],
|
|
809
|
+
},
|
|
810
|
+
};
|
|
811
|
+
```
|
|
812
|
+
|
|
813
|
+
Supported button properties:
|
|
814
|
+
|
|
815
|
+
- `key` (optional): unique key
|
|
816
|
+
- `label` (required): button text
|
|
817
|
+
- `icon` (optional): React node shown before label
|
|
818
|
+
- `variant` (optional): `contained`, `outlined`, `text`
|
|
819
|
+
- `color` (optional): `primary`, `success`, `error`, `default`
|
|
820
|
+
- `className` (optional): custom Tailwind/class string
|
|
821
|
+
- `disabled` (optional): disable button
|
|
822
|
+
- `show` (optional): set `false` to hide a button
|
|
823
|
+
- `onClick` (optional): `(event, context) => void | Promise<void>`
|
|
824
|
+
|
|
825
|
+
`customMenuItems` opens in a 3-dot menu button in the same header toolbar. Supported fields:
|
|
826
|
+
|
|
827
|
+
- `key` (optional): unique key
|
|
828
|
+
- `label` (required): menu item text
|
|
829
|
+
- `icon` (optional): React node before label
|
|
830
|
+
- `className` (optional): custom class string
|
|
831
|
+
- `disabled` (optional): disable item
|
|
832
|
+
- `show` (optional): set `false` to hide item
|
|
833
|
+
- `onClick` (optional): `(event, context) => void | Promise<void>`
|
|
834
|
+
|
|
717
835
|
### Primary Color Customization
|
|
718
836
|
|
|
719
837
|
You can override the default primary color used across the UI by defining CSS variables in your global `:root`.
|
|
720
838
|
|
|
721
839
|
Simply add the following variables to your main CSS file (e.g., `root.css`, `global.css`):
|
|
722
840
|
|
|
723
|
-
|
|
841
|
+
```css
|
|
724
842
|
:root {
|
|
725
843
|
--primary-50: #eff6ff;
|
|
726
844
|
--primary-100: #dbeafe;
|
|
@@ -733,7 +851,8 @@ Simply add the following variables to your main CSS file (e.g., `root.css`, `glo
|
|
|
733
851
|
--primary-800: #1e40af;
|
|
734
852
|
--primary-900: #1e3a8a;
|
|
735
853
|
}
|
|
736
|
-
|
|
854
|
+
```
|
|
855
|
+
|
|
737
856
|
### CSS Class Customization
|
|
738
857
|
|
|
739
858
|
The following table lists all available CSS classes that can be overridden to customize the UI.
|
|
@@ -880,7 +999,7 @@ function App() {
|
|
|
880
999
|
}
|
|
881
1000
|
|
|
882
1001
|
export default App;
|
|
883
|
-
|
|
1002
|
+
```
|
|
884
1003
|
|
|
885
1004
|
#### Example 2: Server-Side CRUD with Advanced Features
|
|
886
1005
|
|