jattac.libs.web.responsive-table 0.0.25 → 0.1.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.
package/README.md CHANGED
@@ -1,196 +1,297 @@
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
+ ![ResponsiveTable Demo](https://example.com/demo.gif) <!-- Replace with an actual demo GIF -->
6
+
7
+ ## Features
8
+
9
+ - **Mobile-First Design**: Automatically switches to a card layout on smaller screens for optimal readability.
10
+ - **Highly Customizable**: Tailor the look and feel of columns, headers, and footers.
11
+ - **Dynamic Data Handling**: Define columns and footers based on your data or application state.
12
+ - **Delightful Animations**: Includes an optional skeleton loader and staggered row entrance animations.
13
+ - **Interactive Elements**: Easily add click handlers for rows and headers.
14
+ - **Performant**: Built with performance in mind, including debounced resize handling.
15
+ - **Easy to Use**: A simple and intuitive API for quick integration.
16
+
17
+ ## Installation
18
+
19
+ To get started, install the package from npm:
20
+
21
+ ```bash
22
+ npm install jattac.libs.web.responsive-table
23
+ ```
24
+
25
+ ## Getting Started
26
+
27
+ Here’s a basic example to get you up and running in minutes.
28
+
29
+ ```jsx
30
+ import React from 'react';
31
+ import ResponsiveTable from 'jattac.libs.web.responsive-table';
32
+
33
+ const GettingStarted = () => {
34
+ const columns = [
35
+ { displayLabel: 'Name', dataKey: 'name', cellRenderer: (row) => row.name },
36
+ { displayLabel: 'Age', dataKey: 'age', cellRenderer: (row) => row.age },
37
+ { displayLabel: 'City', dataKey: 'city', cellRenderer: (row) => row.city },
38
+ ];
39
+
40
+ const data = [
41
+ { name: 'Alice', age: 32, city: 'New York' },
42
+ { name: 'Bob', age: 28, city: 'Los Angeles' },
43
+ { name: 'Charlie', age: 45, city: 'Chicago' },
44
+ ];
45
+
46
+ return <ResponsiveTable columnDefinitions={columns} data={data} />;
47
+ };
48
+
49
+ export default GettingStarted;
50
+ ```
51
+
52
+ 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.
53
+
54
+ ---
55
+
56
+ ## Comprehensive Examples
57
+
58
+ ### Example 1: Loading State and Animations
59
+
60
+ 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.
61
+
62
+ ```jsx
63
+ import React, { useState, useEffect } from 'react';
64
+ import ResponsiveTable from 'jattac.libs.web.responsive-table';
65
+
66
+ const AnimatedTable = () => {
67
+ const [data, setData] = useState([]);
68
+ const [isLoading, setIsLoading] = useState(true);
69
+
70
+ const columns = [
71
+ { displayLabel: 'User', cellRenderer: (row) => row.name },
72
+ { displayLabel: 'Email', cellRenderer: (row) => row.email },
73
+ ];
74
+
75
+ useEffect(() => {
76
+ // Simulate a network request
77
+ setTimeout(() => {
78
+ setData([
79
+ { name: 'Grace', email: 'grace@example.com' },
80
+ { name: 'Henry', email: 'henry@example.com' },
81
+ ]);
82
+ setIsLoading(false);
83
+ }, 2000);
84
+ }, []);
85
+
86
+ return (
87
+ <ResponsiveTable
88
+ columnDefinitions={columns}
89
+ data={data}
90
+ isLoading={isLoading}
91
+ animateOnLoad={true}
92
+ />
93
+ );
94
+ };
95
+ ```
96
+
97
+ ### Example 2: Adding a Clickable Row Action
98
+
99
+ You can make rows clickable to perform actions, such as navigating to a details page or opening a modal.
100
+
101
+ ```jsx
102
+ import React from 'react';
103
+ import ResponsiveTable from 'jattac.libs.web.responsive-table';
104
+
105
+ const ClickableRows = () => {
106
+ const columns = [
107
+ { displayLabel: 'Product', cellRenderer: (row) => row.product },
108
+ { displayLabel: 'Price', cellRenderer: (row) => `$${row.price.toFixed(2)}` },
109
+ ];
110
+
111
+ const data = [
112
+ { id: 1, product: 'Laptop', price: 1200 },
113
+ { id: 2, product: 'Keyboard', price: 75 },
114
+ ];
115
+
116
+ const handleRowClick = (item) => {
117
+ alert(`You clicked on product ID: ${item.id}`);
118
+ };
119
+
120
+ return (
121
+ <ResponsiveTable
122
+ columnDefinitions={columns}
123
+ data={data}
124
+ onRowClick={handleRowClick}
125
+ />
126
+ );
127
+ };
128
+ ```
129
+
130
+ ### Example 3: Custom Cell Rendering
131
+
132
+ You can render any React component inside a cell, allowing for rich content like buttons, links, or status badges.
133
+
134
+ ```jsx
135
+ import React from 'react';
136
+ import ResponsiveTable from 'jattac.libs.web.responsive-table';
137
+
138
+ const CustomCells = () => {
139
+ const columns = [
140
+ { displayLabel: 'User', cellRenderer: (row) => <strong>{row.user}</strong> },
141
+ {
142
+ displayLabel: 'Status',
143
+ cellRenderer: (row) => (
144
+ <span
145
+ style={{
146
+ color: row.status === 'Active' ? 'green' : 'red',
147
+ fontWeight: 'bold',
148
+ }}
149
+ >
150
+ {row.status}
151
+ </span>
152
+ ),
153
+ },
154
+ {
155
+ displayLabel: 'Action',
156
+ cellRenderer: (row) => (
157
+ <button onClick={() => alert(`Editing ${row.user}`)}>Edit</button>
158
+ ),
159
+ },
160
+ ];
161
+
162
+ const data = [
163
+ { user: 'Eve', status: 'Active' },
164
+ { user: 'Frank', status: 'Inactive' },
165
+ ];
166
+
167
+ return <ResponsiveTable columnDefinitions={columns} data={data} />;
168
+ };
169
+ ```
170
+
171
+ ### Example 4: Dynamic and Conditional Columns
172
+
173
+ Columns can be generated dynamically based on your data or application state. This is useful for creating flexible tables that adapt to different datasets.
174
+
175
+ ```jsx
176
+ import React from 'react';
177
+ import ResponsiveTable from 'jattac.libs.web.responsive-table';
178
+
179
+ const DynamicColumns = ({ isAdmin }) => {
180
+ // Base columns for all users
181
+ const columns = [
182
+ { displayLabel: 'File Name', cellRenderer: (row) => row.fileName },
183
+ { displayLabel: 'Size', cellRenderer: (row) => `${row.size} KB` },
184
+ ];
185
+
186
+ // Add an admin-only column conditionally
187
+ if (isAdmin) {
188
+ columns.push({
189
+ displayLabel: 'Admin Actions',
190
+ cellRenderer: (row) => (
191
+ <button onClick={() => alert(`Deleting ${row.fileName}`)}>
192
+ Delete
193
+ </button>
194
+ ),
195
+ });
196
+ }
197
+
198
+ const data = [
199
+ { fileName: 'document.pdf', size: 1024 },
200
+ { fileName: 'image.jpg', size: 512 },
201
+ ];
202
+
203
+ return <ResponsiveTable columnDefinitions={columns} data={data} />;
204
+ };
205
+ ```
206
+
207
+ ### Example 5: Adding a Table Footer for Summaries
208
+
209
+ 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.
210
+
211
+ ```jsx
212
+ import React from 'react';
213
+ import ResponsiveTable from 'jattac.libs.web.responsive-table';
214
+
215
+ const TableWithFooter = () => {
216
+ const columns = [
217
+ { displayLabel: 'Item', cellRenderer: (row) => row.item },
218
+ { displayLabel: 'Quantity', cellRenderer: (row) => row.quantity },
219
+ { displayLabel: 'Price', cellRenderer: (row) => `$${row.price.toFixed(2)}` },
220
+ ];
221
+
222
+ const data = [
223
+ { item: 'Apples', quantity: 10, price: 1.5 },
224
+ { item: 'Oranges', quantity: 5, price: 2.0 },
225
+ { item: 'Bananas', quantity: 15, price: 0.5 },
226
+ ];
227
+
228
+ const total = data.reduce((sum, row) => sum + row.quantity * row.price, 0);
229
+
230
+ const footerRows = [
231
+ {
232
+ columns: [
233
+ {
234
+ colSpan: 2,
235
+ cellRenderer: () => <strong>Total:</strong>,
236
+ },
237
+ {
238
+ colSpan: 1,
239
+ cellRenderer: () => <strong>${total.toFixed(2)}</strong>,
240
+ },
241
+ ],
242
+ },
243
+ ];
244
+
245
+ return (
246
+ <ResponsiveTable
247
+ columnDefinitions={columns}
248
+ data={data}
249
+ footerRows={footerRows}
250
+ />
251
+ );
252
+ };
253
+ ```
254
+
255
+ ---
256
+
257
+ ## API Reference
258
+
259
+ ### `ResponsiveTable` Props
260
+
261
+ | Prop | Type | Required | Description |
262
+ | ------------------- | ---------------------------------------- | -------- | ------------------------------------------------------------------------------------------------------- |
263
+ | `columnDefinitions` | `IResponsiveTableColumnDefinition[]` | Yes | An array of objects defining the table columns. |
264
+ | `data` | `TData[]` | Yes | An array of data objects to populate the table rows. |
265
+ | `isLoading` | `boolean` | No | If `true`, displays a skeleton loader. Defaults to `false`. |
266
+ | `animateOnLoad` | `boolean` | No | If `true`, animates the rows with a staggered entrance effect. Defaults to `false`. |
267
+ | `footerRows` | `IFooterRowDefinition[]` | No | An array of objects defining the table footer. |
268
+ | `onRowClick` | `(item: TData) => void` | No | A callback function that is triggered when a row is clicked. |
269
+ | `noDataComponent` | `ReactNode` | No | A custom component to display when there is no data. |
270
+ | `maxHeight` | `string` | No | Sets a maximum height for the table body, making it scrollable. |
271
+ | `mobileBreakpoint` | `number` | No | The pixel width at which the table switches to the mobile view. Defaults to `600`. |
272
+
273
+ ### `IResponsiveTableColumnDefinition`
274
+
275
+ | Property | Type | Required | Description |
276
+ | -------------- | ------------------------- | -------- | ------------------------------------------------------------------------ |
277
+ | `displayLabel` | `string` | Yes | The label displayed in the table header. |
278
+ | `cellRenderer` | `(row: TData) => ReactNode` | Yes | A function that returns the content to be rendered in the cell. |
279
+ | `dataKey` | `string` | No | A key to match the column to a property in the data object (optional). |
280
+ | `interactivity`| `object` | No | An object to define header interactivity (`onHeaderClick`, `id`, `className`). |
281
+
282
+ ### `IFooterRowDefinition`
283
+
284
+ | Property | Type | Required | Description |
285
+ | -------- | ---------------------------- | -------- | ----------------------------------------- |
286
+ | `columns` | `IFooterColumnDefinition[]` | Yes | An array of column definitions for the footer row. |
287
+
288
+ ### `IFooterColumnDefinition`
289
+
290
+ | Property | Type | Required | Description |
291
+ | -------------- | ------------------- | -------- | ----------------------------------------------------- |
292
+ | `colSpan` | `number` | Yes | The number of columns the footer cell should span. |
293
+ | `cellRenderer` | `() => ReactNode` | Yes | A function that returns the content for the footer cell. |
294
+
295
+ ## License
296
+
297
+ 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,18 +1,26 @@
1
1
  import React, { Component, ReactNode } from 'react';
2
2
  import IResponsiveTableColumnDefinition from '../Data/IResponsiveTableColumnDefinition';
3
- type ColumnDefinition<TData> = IResponsiveTableColumnDefinition<TData> | ((data: TData, rowIndex?: number) => IResponsiveTableColumnDefinition<TData>);
3
+ import IFooterRowDefinition from '../Data/IFooterRowDefinition';
4
+ export type ColumnDefinition<TData> = IResponsiveTableColumnDefinition<TData> | ((data: TData, rowIndex?: number) => IResponsiveTableColumnDefinition<TData>);
4
5
  interface IProps<TData> {
5
6
  columnDefinitions: ColumnDefinition<TData>[];
6
7
  data: 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;
package/dist/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import IResponsiveTableColumnDefinition from "./Data/IResponsiveTableColumnDefinition";
2
- import ResponsiveTable from "./UI/ResponsiveTable";
3
- export { IResponsiveTableColumnDefinition };
1
+ import IResponsiveTableColumnDefinition from './Data/IResponsiveTableColumnDefinition';
2
+ import ResponsiveTable, { ColumnDefinition } from './UI/ResponsiveTable';
3
+ export { IResponsiveTableColumnDefinition, ColumnDefinition };
4
4
  export default ResponsiveTable;