jattac.libs.web.responsive-table 0.0.26 → 0.1.1

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
@@ -1,196 +1,270 @@
1
- # ResponsiveTable
2
-
3
- ResponsiveTable is a React component designed to create responsive tables that adapt seamlessly to both desktop and mobile screens. It simplifies the process of building tables with dynamic layouts and custom behaviors.
4
-
5
- ## Installation
6
-
7
- To install ResponsiveTable, use npm:
8
-
9
- ```bash
10
- npm install jattac.libs.web.responsive-table
11
- ```
12
-
13
- ## Why Use ResponsiveTable?
14
-
15
- - **Mobile-Friendly**: Automatically adjusts to look great on small screens.
16
- - **Customizable**: Define how each column looks and behaves.
17
- - **Dynamic**: Supports flexible column setups, even changing them based on the data.
18
- - **Easy to Use**: Simple API for quick integration into your React project.
19
-
20
- ## How to Use It
21
-
22
- Here’s a quick example:
23
-
24
- ```jsx
25
- import ResponsiveTable from 'jattac.libs.web.responsive-table';
26
-
27
- const columns = [
28
- {
29
- displayLabel: 'Name',
30
- dataKey: 'name',
31
- cellRenderer: (row) => row.name,
32
- },
33
- {
34
- displayLabel: 'Age',
35
- dataKey: 'age',
36
- cellRenderer: (row) => row.age,
37
- },
38
- ];
39
-
40
- const data = [
41
- { name: 'Alice', age: 25 },
42
- { name: 'Bob', age: 30 },
43
- ];
44
-
45
- <ResponsiveTable columnDefinitions={columns} data={data} />;
46
- ```
47
-
48
- ### Explanation
49
-
50
- - **`columnDefinitions`**: Defines the columns of the table. Each column has a label (`displayLabel`), a key to match the data (`dataKey`), and a function to render the cell (`cellRenderer`).
51
- - **`data`**: The rows of the table, where each object represents a row.
52
-
53
- ## Key Features
54
-
55
- ### 1. Mobile and Desktop Layouts
56
-
57
- - On small screens, the table switches to a card-style layout for better readability.
58
-
59
- ### 2. Custom Columns
60
-
61
- - Customize how each column looks and behaves. For example, you can add clickable headers or custom styles.
62
-
63
- ### 3. Dynamic Columns
64
-
65
- - Columns can be defined dynamically based on the data or external conditions. This allows you to create tables that adapt to different datasets or user preferences.
66
-
67
- #### Example 1: Conditional Columns
68
-
69
- You can show or hide columns based on a condition:
70
-
71
- ```jsx
72
- const isAdmin = true; // Example condition
73
-
74
- const columns = [
75
- {
76
- displayLabel: 'Name',
77
- dataKey: 'name',
78
- cellRenderer: (row) => row.name,
79
- },
80
- isAdmin && {
81
- displayLabel: 'Actions',
82
- dataKey: 'actions',
83
- cellRenderer: (row) => <button onClick={() => alert(row.name)}>Edit</button>,
84
- },
85
- ].filter(Boolean); // Remove undefined columns
86
-
87
- const data = [{ name: 'Alice' }, { name: 'Bob' }];
88
-
89
- <ResponsiveTable columnDefinitions={columns} data={data} />;
90
- ```
91
-
92
- #### Example 2: Dynamic Column Labels
93
-
94
- You can change column labels dynamically based on user preferences or locale:
95
-
96
- ```jsx
97
- const userLocale = 'fr'; // Example locale
98
-
99
- const columnLabels = {
100
- en: { name: 'Name', age: 'Age' },
101
- fr: { name: 'Nom', age: 'Âge' },
102
- };
103
-
104
- const columns = [
105
- {
106
- displayLabel: columnLabels[userLocale].name,
107
- dataKey: 'name',
108
- cellRenderer: (row) => row.name,
109
- },
110
- {
111
- displayLabel: columnLabels[userLocale].age,
112
- dataKey: 'age',
113
- cellRenderer: (row) => row.age,
114
- },
115
- ];
116
-
117
- const data = [
118
- { name: 'Alice', age: 25 },
119
- { name: 'Bob', age: 30 },
120
- ];
121
-
122
- <ResponsiveTable columnDefinitions={columns} data={data} />;
123
- ```
124
-
125
- #### Example 3: Columns Based on Data
126
-
127
- You can generate columns dynamically based on the dataset:
128
-
129
- ```jsx
130
- const data = [
131
- { name: 'Alice', age: 25, city: 'New York' },
132
- { name: 'Bob', age: 30, city: 'Los Angeles' },
133
- ];
134
-
135
- const columns = Object.keys(data[0]).map((key) => ({
136
- displayLabel: key.charAt(0).toUpperCase() + key.slice(1), // Capitalize key
137
- dataKey: key,
138
- cellRenderer: (row) => row[key],
139
- }));
140
-
141
- <ResponsiveTable columnDefinitions={columns} data={data} />;
142
- ```
143
-
144
- #### Example 4: Adding Columns Dynamically Using a Function
145
-
146
- You can define columns dynamically by using a function that takes the row data and optionally the row index. This is useful for creating columns based on specific row properties or conditions.
147
-
148
- ```jsx
149
- const columns = [
150
- {
151
- displayLabel: 'Name',
152
- dataKey: 'name',
153
- cellRenderer: (row) => row.name,
154
- },
155
- {
156
- displayLabel: 'Dynamic Column',
157
- dataKey: 'dynamic',
158
- cellRenderer: (row, rowIndex) => {
159
- if (rowIndex % 2 === 0) {
160
- return `Even Row: ${row.name}`;
161
- } else {
162
- return `Odd Row: ${row.name}`;
163
- }
164
- },
165
- },
166
- ];
167
-
168
- const data = [
169
- { name: 'Alice', age: 25 },
170
- { name: 'Bob', age: 30 },
171
- { name: 'Charlie', age: 35 },
172
- ];
173
-
174
- <ResponsiveTable columnDefinitions={columns} data={data} />;
175
- ```
176
-
177
- ### Explanation
178
-
179
- - **Dynamic Column Logic**: The `cellRenderer` function for the dynamic column checks the row index and displays different content for even and odd rows.
180
- - **Flexibility**: This approach allows you to create highly customized columns based on row-specific data or conditions.
181
-
182
- ### 4. No Data? No Problem!
183
-
184
- - If there’s no data to display, you can show a custom message or graphic.
185
-
186
- ## Why It’s Designed This Way
187
-
188
- - **Flexibility**: Works for both simple and complex data tables.
189
- - **User-Friendly**: Automatically adapts to different screen sizes.
190
- - **Customizable**: Lets you control how your data is displayed.
191
-
192
- ## Advantages
193
-
194
- - Saves time: No need to build responsive tables from scratch.
195
- - Easy to maintain: Clear and simple API.
196
- - Works out of the box: Handles common table features like empty states and dynamic layouts.
1
+ # ResponsiveTable: A Modern and Flexible React Table Component
2
+
3
+ ResponsiveTable is a powerful, lightweight, and fully responsive React component for creating beautiful and functional tables. It’s designed to look great on any device, adapting from a traditional table layout on desktops to a clean, card-based view on mobile screens.
4
+
5
+ ## Features
6
+
7
+ - **Mobile-First Design**: Automatically switches to a card layout on smaller screens for optimal readability.
8
+ - **Highly Customizable**: Tailor the look and feel of columns, headers, and footers.
9
+ - **Dynamic Data Handling**: Define columns and footers based on your data or application state.
10
+ - **Delightful Animations**: Includes an optional skeleton loader and staggered row entrance animations.
11
+ - **Interactive Elements**: Easily add click handlers for rows and headers.
12
+ - **Performant**: Built with performance in mind, including debounced resize handling.
13
+ - **Easy to Use**: A simple and intuitive API for quick integration.
14
+
15
+ ## Installation
16
+
17
+ To get started, install the package from npm:
18
+
19
+ ```bash
20
+ npm install jattac.libs.web.responsive-table
21
+ ```
22
+
23
+ ## Getting Started
24
+
25
+ Here’s a basic example to get you up and running in minutes.
26
+
27
+ ```jsx
28
+ import React from 'react';
29
+ import ResponsiveTable from 'jattac.libs.web.responsive-table';
30
+
31
+ const GettingStarted = () => {
32
+ const columns = [
33
+ { displayLabel: 'Name', dataKey: 'name', cellRenderer: (row) => row.name },
34
+ { displayLabel: 'Age', dataKey: 'age', cellRenderer: (row) => row.age },
35
+ { displayLabel: 'City', dataKey: 'city', cellRenderer: (row) => row.city },
36
+ ];
37
+
38
+ const data = [
39
+ { name: 'Alice', age: 32, city: 'New York' },
40
+ { name: 'Bob', age: 28, city: 'Los Angeles' },
41
+ { name: 'Charlie', age: 45, city: 'Chicago' },
42
+ ];
43
+
44
+ return <ResponsiveTable columnDefinitions={columns} data={data} />;
45
+ };
46
+
47
+ export default GettingStarted;
48
+ ```
49
+
50
+ This will render a table that automatically adapts to the screen size. On a desktop, it will look like a standard table, and on mobile, it will switch to a card-based layout.
51
+
52
+ ---
53
+
54
+ ## Comprehensive Examples
55
+
56
+ ### Example 1: Loading State and Animations
57
+
58
+ You can provide a seamless user experience by showing a skeleton loader while your data is being fetched, and then animating the rows in when the data is ready.
59
+
60
+ ```jsx
61
+ import React, { useState, useEffect } from 'react';
62
+ import ResponsiveTable from 'jattac.libs.web.responsive-table';
63
+
64
+ const AnimatedTable = () => {
65
+ const [data, setData] = useState([]);
66
+ const [isLoading, setIsLoading] = useState(true);
67
+
68
+ const columns = [
69
+ { displayLabel: 'User', cellRenderer: (row) => row.name },
70
+ { displayLabel: 'Email', cellRenderer: (row) => row.email },
71
+ ];
72
+
73
+ useEffect(() => {
74
+ // Simulate a network request
75
+ setTimeout(() => {
76
+ setData([
77
+ { name: 'Grace', email: 'grace@example.com' },
78
+ { name: 'Henry', email: 'henry@example.com' },
79
+ ]);
80
+ setIsLoading(false);
81
+ }, 2000);
82
+ }, []);
83
+
84
+ return <ResponsiveTable columnDefinitions={columns} data={data} isLoading={isLoading} animateOnLoad={true} />;
85
+ };
86
+ ```
87
+
88
+ ### Example 2: Adding a Clickable Row Action
89
+
90
+ You can make rows clickable to perform actions, such as navigating to a details page or opening a modal.
91
+
92
+ ```jsx
93
+ import React from 'react';
94
+ import ResponsiveTable from 'jattac.libs.web.responsive-table';
95
+
96
+ const ClickableRows = () => {
97
+ const columns = [
98
+ { displayLabel: 'Product', cellRenderer: (row) => row.product },
99
+ { displayLabel: 'Price', cellRenderer: (row) => `$${row.price.toFixed(2)}` },
100
+ ];
101
+
102
+ const data = [
103
+ { id: 1, product: 'Laptop', price: 1200 },
104
+ { id: 2, product: 'Keyboard', price: 75 },
105
+ ];
106
+
107
+ const handleRowClick = (item) => {
108
+ alert(`You clicked on product ID: ${item.id}`);
109
+ };
110
+
111
+ return <ResponsiveTable columnDefinitions={columns} data={data} onRowClick={handleRowClick} />;
112
+ };
113
+ ```
114
+
115
+ ### Example 3: Custom Cell Rendering
116
+
117
+ You can render any React component inside a cell, allowing for rich content like buttons, links, or status badges.
118
+
119
+ ```jsx
120
+ import React from 'react';
121
+ import ResponsiveTable from 'jattac.libs.web.responsive-table';
122
+
123
+ const CustomCells = () => {
124
+ const columns = [
125
+ { displayLabel: 'User', cellRenderer: (row) => <strong>{row.user}</strong> },
126
+ {
127
+ displayLabel: 'Status',
128
+ cellRenderer: (row) => (
129
+ <span
130
+ style={{
131
+ color: row.status === 'Active' ? 'green' : 'red',
132
+ fontWeight: 'bold',
133
+ }}
134
+ >
135
+ {row.status}
136
+ </span>
137
+ ),
138
+ },
139
+ {
140
+ displayLabel: 'Action',
141
+ cellRenderer: (row) => <button onClick={() => alert(`Editing ${row.user}`)}>Edit</button>,
142
+ },
143
+ ];
144
+
145
+ const data = [
146
+ { user: 'Eve', status: 'Active' },
147
+ { user: 'Frank', status: 'Inactive' },
148
+ ];
149
+
150
+ return <ResponsiveTable columnDefinitions={columns} data={data} />;
151
+ };
152
+ ```
153
+
154
+ ### Example 4: Dynamic and Conditional Columns
155
+
156
+ Columns can be generated dynamically based on your data or application state. This is useful for creating flexible tables that adapt to different datasets.
157
+
158
+ ```jsx
159
+ import React from 'react';
160
+ import ResponsiveTable from 'jattac.libs.web.responsive-table';
161
+
162
+ const DynamicColumns = ({ isAdmin }) => {
163
+ // Base columns for all users
164
+ const columns = [
165
+ { displayLabel: 'File Name', cellRenderer: (row) => row.fileName },
166
+ { displayLabel: 'Size', cellRenderer: (row) => `${row.size} KB` },
167
+ ];
168
+
169
+ // Add an admin-only column conditionally
170
+ if (isAdmin) {
171
+ columns.push({
172
+ displayLabel: 'Admin Actions',
173
+ cellRenderer: (row) => <button onClick={() => alert(`Deleting ${row.fileName}`)}>Delete</button>,
174
+ });
175
+ }
176
+
177
+ const data = [
178
+ { fileName: 'document.pdf', size: 1024 },
179
+ { fileName: 'image.jpg', size: 512 },
180
+ ];
181
+
182
+ return <ResponsiveTable columnDefinitions={columns} data={data} />;
183
+ };
184
+ ```
185
+
186
+ ### Example 5: Adding a Table Footer for Summaries
187
+
188
+ You can add a footer to display summary information, such as totals or averages. The footer is also responsive and will appear correctly in both desktop and mobile views.
189
+
190
+ ```jsx
191
+ import React from 'react';
192
+ import ResponsiveTable from 'jattac.libs.web.responsive-table';
193
+
194
+ const TableWithFooter = () => {
195
+ const columns = [
196
+ { displayLabel: 'Item', cellRenderer: (row) => row.item },
197
+ { displayLabel: 'Quantity', cellRenderer: (row) => row.quantity },
198
+ { displayLabel: 'Price', cellRenderer: (row) => `$${row.price.toFixed(2)}` },
199
+ ];
200
+
201
+ const data = [
202
+ { item: 'Apples', quantity: 10, price: 1.5 },
203
+ { item: 'Oranges', quantity: 5, price: 2.0 },
204
+ { item: 'Bananas', quantity: 15, price: 0.5 },
205
+ ];
206
+
207
+ const total = data.reduce((sum, row) => sum + row.quantity * row.price, 0);
208
+
209
+ const footerRows = [
210
+ {
211
+ columns: [
212
+ {
213
+ colSpan: 2,
214
+ cellRenderer: () => <strong>Total:</strong>,
215
+ },
216
+ {
217
+ colSpan: 1,
218
+ cellRenderer: () => <strong>${total.toFixed(2)}</strong>,
219
+ },
220
+ ],
221
+ },
222
+ ];
223
+
224
+ return <ResponsiveTable columnDefinitions={columns} data={data} footerRows={footerRows} />;
225
+ };
226
+ ```
227
+
228
+ ---
229
+
230
+ ## API Reference
231
+
232
+ ### `ResponsiveTable` Props
233
+
234
+ | Prop | Type | Required | Description |
235
+ | ------------------- | ------------------------------------ | -------- | ----------------------------------------------------------------------------------- |
236
+ | `columnDefinitions` | `IResponsiveTableColumnDefinition[]` | Yes | An array of objects defining the table columns. |
237
+ | `data` | `TData[]` | Yes | An array of data objects to populate the table rows. |
238
+ | `isLoading` | `boolean` | No | If `true`, displays a skeleton loader. Defaults to `false`. |
239
+ | `animateOnLoad` | `boolean` | No | If `true`, animates the rows with a staggered entrance effect. Defaults to `false`. |
240
+ | `footerRows` | `IFooterRowDefinition[]` | No | An array of objects defining the table footer. |
241
+ | `onRowClick` | `(item: TData) => void` | No | A callback function that is triggered when a row is clicked. |
242
+ | `noDataComponent` | `ReactNode` | No | A custom component to display when there is no data. |
243
+ | `maxHeight` | `string` | No | Sets a maximum height for the table body, making it scrollable. |
244
+ | `mobileBreakpoint` | `number` | No | The pixel width at which the table switches to the mobile view. Defaults to `600`. |
245
+
246
+ ### `IResponsiveTableColumnDefinition`
247
+
248
+ | Property | Type | Required | Description |
249
+ | --------------- | --------------------------- | -------- | ------------------------------------------------------------------------------ |
250
+ | `displayLabel` | `string` | Yes | The label displayed in the table header. |
251
+ | `cellRenderer` | `(row: TData) => ReactNode` | Yes | A function that returns the content to be rendered in the cell. |
252
+ | `dataKey` | `string` | No | A key to match the column to a property in the data object (optional). |
253
+ | `interactivity` | `object` | No | An object to define header interactivity (`onHeaderClick`, `id`, `className`). |
254
+
255
+ ### `IFooterRowDefinition`
256
+
257
+ | Property | Type | Required | Description |
258
+ | --------- | --------------------------- | -------- | -------------------------------------------------- |
259
+ | `columns` | `IFooterColumnDefinition[]` | Yes | An array of column definitions for the footer row. |
260
+
261
+ ### `IFooterColumnDefinition`
262
+
263
+ | Property | Type | Required | Description |
264
+ | -------------- | ----------------- | -------- | -------------------------------------------------------- |
265
+ | `colSpan` | `number` | Yes | The number of columns the footer cell should span. |
266
+ | `cellRenderer` | `() => ReactNode` | Yes | A function that returns the content for the footer cell. |
267
+
268
+ ## License
269
+
270
+ This project is licensed under the MIT License.
@@ -0,0 +1,5 @@
1
+ import { ReactNode } from 'react';
2
+ export default interface IFooterColumnDefinition {
3
+ colSpan: number;
4
+ cellRenderer: () => ReactNode;
5
+ }
@@ -0,0 +1,4 @@
1
+ import IFooterColumnDefinition from './IFooterColumnDefinition';
2
+ export default interface IFooterRowDefinition {
3
+ columns: IFooterColumnDefinition[];
4
+ }
@@ -1,5 +1,6 @@
1
1
  import React, { Component, ReactNode } from 'react';
2
2
  import IResponsiveTableColumnDefinition from '../Data/IResponsiveTableColumnDefinition';
3
+ import IFooterRowDefinition from '../Data/IFooterRowDefinition';
3
4
  export type ColumnDefinition<TData> = IResponsiveTableColumnDefinition<TData> | ((data: TData, rowIndex?: number) => IResponsiveTableColumnDefinition<TData>);
4
5
  interface IProps<TData> {
5
6
  columnDefinitions: ColumnDefinition<TData>[];
@@ -7,12 +8,19 @@ interface IProps<TData> {
7
8
  noDataComponent?: ReactNode;
8
9
  maxHeight?: string;
9
10
  onRowClick?: (item: TData) => void;
11
+ footerRows?: IFooterRowDefinition[];
12
+ mobileBreakpoint?: number;
13
+ isLoading?: boolean;
14
+ animateOnLoad?: boolean;
10
15
  }
11
16
  interface IState {
12
17
  isMobile: boolean;
13
18
  }
14
19
  declare class ResponsiveTable<TData> extends Component<IProps<TData>, IState> {
20
+ private debouncedResize;
15
21
  constructor(props: IProps<TData>);
22
+ private get mobileBreakpoint();
23
+ private debounce;
16
24
  private get data();
17
25
  private get noDataSvg();
18
26
  private get hasData();
@@ -26,6 +34,9 @@ declare class ResponsiveTable<TData> extends Component<IProps<TData>, IState> {
26
34
  private getClickableHeaderClassName;
27
35
  private get rowClickFunction();
28
36
  private get rowClickStyle();
37
+ private get tableFooter();
38
+ private get mobileFooter();
39
+ private get skeletonView();
29
40
  private get mobileView();
30
41
  private get largeScreenView();
31
42
  render(): React.ReactNode;