react-admin-crud-manager 1.2.13 → 1.2.15

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 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, file upload, rich text editor, and more
13
+ - Rich form fields including text, select, image upload, rich text editor, and more
14
14
 
15
15
  ## Installation
16
16
 
@@ -22,15 +22,13 @@ npm install react-admin-crud-manager
22
22
 
23
23
  ### 1. Use the component
24
24
 
25
- ```js
26
- import Crud from "react-admin-crud-manager";
25
+ ```
26
+ import Crud from 'react-admin-crud-manager';
27
27
 
28
28
  function App() {
29
29
  const config = {
30
- title: "Users",
31
- fetchData: async () => {
32
- /* fetch logic */
33
- },
30
+ title: 'Users',
31
+ fetchData: async () => { /* fetch logic */ },
34
32
  // ...other config options
35
33
  };
36
34
  return <Crud config={config} />;
@@ -83,26 +81,26 @@ Below is a complete reference of the public props accepted by this package (type
83
81
  | `exportCSV` | object | Export data as CSV | `{ enabled: true, fileName: "users.csv", fields: [{ label: "Name", key: "name" }, ...] }` |
84
82
  | `rowClick` | function or boolean | Callback on table row click | `(row: object, rowIndex: number) => void` or `true` (setting true will open details) |
85
83
 
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).
84
+ <br>
87
85
 
88
86
  #### Table Column Object (`table_head[]`)
89
87
 
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>` |
88
+ | Key | Type | Description | Accepted Values / Example |
89
+ | ---------------- | -------- | ------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------ |
90
+ | `key` | string | Property name in row objects | `"id"`, `"name"`, `"email"` (must exist in data objects) |
91
+ | `title` | string | Column header text | `"User ID"`, `"Full Name"`, `"Email Address"` |
92
+ | `type` | string | Column renderer type | `"plain"` (default), `"index"` (row number), `"group"` (avatar+text), `"chip"` (badge), `"date"`, `"avatar"`, `"menu_actions"` |
93
+ | `imageKey` | string | Image property for avatar/group types | `"profileImage"`, `"avatarUrl"` (path to image in data object) |
94
+ | `titleKey` | string | Title property for group/avatar types | `"name"`, `"fullName"` (property key in data object) |
95
+ | `subtitleKey` | string | Subtitle property for group/avatar types | `"email"`, `"department"` (property key in data object) |
96
+ | `onClickDetails` | boolean | Clicking cell opens view details modal | `true`, `false` (default: `false`) |
97
+ | `variant` | string | Chip styling variant | `"contained"`, `"outline"`, `"soft"` (used with `type: "chip"`) |
98
+ | `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" }]` |
99
+ | `defaultColor` | string | Default color for chips (if no match in chipOptions) | `"green"`, `"red"`, `"blue"`, `"yellow"`, `"purple"`, `"gray"`, etc. |
100
+ | `className` | string | Custom CSS class for cell content | Tailwind classes: `"font-bold text-sm text-gray-600"` |
101
+ | `format` | string | Date format pattern | `"DD MMM YYYY"`, `"YYYY-MM-DD"`, `"DD/MM/YYYY HH:mm"` (uses date-fns patterns) |
102
+ | `menuList` | array | Action menu items; array of `{ title: string, type: string, variant?: string, icon?: ReactNode }` | `[{ title: "Edit", type: "edit", icon: <EditIcon /> }, { title: "Delete", type: "delete", icon: <TrashIcon /> }]` |
103
+ | `render` | function | Custom cell renderer (overrides built-in logic) | `(row: object, rowIndex: number) => ReactNode`; e.g., `(row) => <span>{row.name.toUpperCase()}</span>` |
106
104
 
107
105
  ---
108
106
 
@@ -170,19 +168,19 @@ Used by `modalConfig.*.formFields`, `filterConfig.fields`, and `viewModal.fields
170
168
 
171
169
  #### Common Field Properties (All Types)
172
170
 
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"` |
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"` |
186
184
 
187
185
  #### Type-Specific Properties
188
186
 
@@ -263,7 +261,7 @@ Used by `modalConfig.*.formFields`, `filterConfig.fields`, and `viewModal.fields
263
261
  | ---------- | ------- | --------------------------- | ----------------------------------------------- |
264
262
  | `accept` | string | MIME type filter | `"video/*"` (default), `"video/mp4,video/webm"` |
265
263
  | `dragDrop` | boolean | Enable drag-and-drop upload | `true`, `false` (default: `false`) |
266
- | `maxSize` | number | Maximum file size in MB | `5`, `10`, `25` |
264
+ | `maxSize` | number | Maximum file size in bytes | `5242880` (5MB), `10485760` (10MB) |
267
265
 
268
266
  ##### `"audio"` Field
269
267
 
@@ -271,45 +269,7 @@ Used by `modalConfig.*.formFields`, `filterConfig.fields`, and `viewModal.fields
271
269
  | ---------- | ------- | --------------------------- | ----------------------------------------------- |
272
270
  | `accept` | string | MIME type filter | `"audio/*"` (default), `"audio/mpeg,audio/wav"` |
273
271
  | `dragDrop` | boolean | Enable drag-and-drop upload | `true`, `false` (default: `false`) |
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
- ```
272
+ | `maxSize` | number | Maximum file size in bytes | `5242880` (5MB), `10485760` (10MB) |
313
273
 
314
274
  ##### `"tinyEditor"` Field
315
275
 
@@ -754,84 +714,6 @@ const config = {
754
714
  };
755
715
  ```
756
716
 
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
-
835
717
  ### Primary Color Customization
836
718
 
837
719
  You can override the default primary color used across the UI by defining CSS variables in your global `:root`.
@@ -934,7 +816,7 @@ The following table lists all available CSS classes that can be overridden to cu
934
816
  - Works with CSS, SCSS, Tailwind (`@apply`), or CSS-in-JS.
935
817
  - No manual assignment required — classes are already applied internally.
936
818
 
937
- ### CRUD Examples
819
+ ### Examples
938
820
 
939
821
  #### Example 1: Minimal Client-Side CRUD
940
822