@delightui/components 0.1.104 → 0.1.106

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 (120) hide show
  1. package/README.md +104 -1
  2. package/dist/cjs/components/molecules/Modal/DemoModal.d.ts +8 -0
  3. package/dist/cjs/components/molecules/Modal/ModalContext/ModalContext.d.ts +41 -0
  4. package/dist/cjs/components/molecules/Modal/ModalContext/ModalContext.types.d.ts +87 -0
  5. package/dist/cjs/components/molecules/Modal/ModalContext/index.d.ts +3 -0
  6. package/dist/cjs/components/molecules/Modal/ModalContext/useModal.d.ts +34 -0
  7. package/dist/cjs/components/molecules/Modal/index.d.ts +2 -0
  8. package/dist/cjs/components/molecules/Popover/Popover.presenter.d.ts +26 -0
  9. package/dist/cjs/components/molecules/Select/Option/Option.types.d.ts +6 -0
  10. package/dist/cjs/components/molecules/Select/Select.Context.d.ts +1 -1
  11. package/dist/cjs/components/molecules/Select/Select.d.ts +5 -5
  12. package/dist/cjs/components/molecules/Select/Select.presenter.d.ts +1 -0
  13. package/dist/cjs/components/molecules/Select/Select.types.d.ts +5 -0
  14. package/dist/cjs/components/molecules/Select/index.d.ts +2 -9
  15. package/dist/cjs/components/molecules/index.d.ts +2 -0
  16. package/dist/cjs/components/utils/accessibilityUtils.d.ts +41 -0
  17. package/dist/cjs/components/utils/index.d.ts +2 -0
  18. package/dist/cjs/library.css +13 -0
  19. package/dist/cjs/library.js +2 -2
  20. package/dist/cjs/library.js.map +1 -1
  21. package/dist/esm/components/molecules/Modal/DemoModal.d.ts +8 -0
  22. package/dist/esm/components/molecules/Modal/ModalContext/ModalContext.d.ts +41 -0
  23. package/dist/esm/components/molecules/Modal/ModalContext/ModalContext.types.d.ts +87 -0
  24. package/dist/esm/components/molecules/Modal/ModalContext/index.d.ts +3 -0
  25. package/dist/esm/components/molecules/Modal/ModalContext/useModal.d.ts +34 -0
  26. package/dist/esm/components/molecules/Modal/index.d.ts +2 -0
  27. package/dist/esm/components/molecules/Popover/Popover.presenter.d.ts +26 -0
  28. package/dist/esm/components/molecules/Select/Option/Option.types.d.ts +6 -0
  29. package/dist/esm/components/molecules/Select/Select.Context.d.ts +1 -1
  30. package/dist/esm/components/molecules/Select/Select.d.ts +5 -5
  31. package/dist/esm/components/molecules/Select/Select.presenter.d.ts +1 -0
  32. package/dist/esm/components/molecules/Select/Select.types.d.ts +5 -0
  33. package/dist/esm/components/molecules/Select/index.d.ts +2 -9
  34. package/dist/esm/components/molecules/index.d.ts +2 -0
  35. package/dist/esm/components/utils/accessibilityUtils.d.ts +41 -0
  36. package/dist/esm/components/utils/index.d.ts +2 -0
  37. package/dist/esm/library.css +13 -0
  38. package/dist/esm/library.js +3 -3
  39. package/dist/esm/library.js.map +1 -1
  40. package/dist/index.d.ts +156 -12
  41. package/docs/README.md +264 -0
  42. package/docs/components/atoms/ActionImage.md +119 -0
  43. package/docs/components/atoms/Button.md +197 -0
  44. package/docs/components/atoms/Checkbox.md +299 -0
  45. package/docs/components/atoms/CheckboxItem.md +314 -0
  46. package/docs/components/atoms/Chip.md +380 -0
  47. package/docs/components/atoms/CustomToggle.md +270 -0
  48. package/docs/components/atoms/Icon.md +365 -0
  49. package/docs/components/atoms/IconButton.md +407 -0
  50. package/docs/components/atoms/Image.md +448 -0
  51. package/docs/components/atoms/Input.md +430 -0
  52. package/docs/components/atoms/ListItem.md +502 -0
  53. package/docs/components/atoms/Password.md +472 -0
  54. package/docs/components/atoms/RadioButton.md +614 -0
  55. package/docs/components/atoms/RadioButtonItem.md +588 -0
  56. package/docs/components/atoms/ResponsiveComponent.md +612 -0
  57. package/docs/components/atoms/SelectListItem.md +609 -0
  58. package/docs/components/atoms/Slider.md +605 -0
  59. package/docs/components/atoms/Spinner.md +605 -0
  60. package/docs/components/atoms/Text.md +463 -0
  61. package/docs/components/atoms/TextArea.md +670 -0
  62. package/docs/components/atoms/ToastNotification.md +668 -0
  63. package/docs/components/atoms/Toggle.md +737 -0
  64. package/docs/components/atoms/ToggleButton.md +751 -0
  65. package/docs/components/atoms/Tooltip.md +391 -0
  66. package/docs/components/molecules/Accordion.md +440 -0
  67. package/docs/components/molecules/AccordionGroup.md +547 -0
  68. package/docs/components/molecules/ActionCard.md +546 -0
  69. package/docs/components/molecules/Breadcrumb.md +403 -0
  70. package/docs/components/molecules/Breadcrumbs.md +485 -0
  71. package/docs/components/molecules/ButtonGroup.md +383 -0
  72. package/docs/components/molecules/Card.md +298 -0
  73. package/docs/components/molecules/ChipInput.md +646 -0
  74. package/docs/components/molecules/ContextMenu.md +768 -0
  75. package/docs/components/molecules/CustomTimeSelector.md +116 -0
  76. package/docs/components/molecules/DatePicker.md +516 -0
  77. package/docs/components/molecules/DateTimeSelector.md +166 -0
  78. package/docs/components/molecules/FormField.md +312 -0
  79. package/docs/components/molecules/Grid.md +577 -0
  80. package/docs/components/molecules/GridItem.md +834 -0
  81. package/docs/components/molecules/GridList.md +244 -0
  82. package/docs/components/molecules/List.md +485 -0
  83. package/docs/components/molecules/Modal.md +470 -0
  84. package/docs/components/molecules/ModalFooter.md +702 -0
  85. package/docs/components/molecules/ModalHeader.md +756 -0
  86. package/docs/components/molecules/ModalProvider.md +205 -0
  87. package/docs/components/molecules/Nav.md +530 -0
  88. package/docs/components/molecules/NavItem.md +572 -0
  89. package/docs/components/molecules/NavLink.md +499 -0
  90. package/docs/components/molecules/Option.md +521 -0
  91. package/docs/components/molecules/Pagination.md +592 -0
  92. package/docs/components/molecules/PaginationNumberField.md +722 -0
  93. package/docs/components/molecules/Popover.md +516 -0
  94. package/docs/components/molecules/ProgressBar.md +624 -0
  95. package/docs/components/molecules/RadioGroup.md +831 -0
  96. package/docs/components/molecules/RepeaterList.md +185 -0
  97. package/docs/components/molecules/Select.md +402 -0
  98. package/docs/components/molecules/SortableTrigger.md +82 -0
  99. package/docs/components/molecules/useModal.md +379 -0
  100. package/docs/components/organisms/Dropzone.md +346 -0
  101. package/docs/components/organisms/DropzoneClear.md +135 -0
  102. package/docs/components/organisms/DropzoneContent.md +216 -0
  103. package/docs/components/organisms/DropzoneFilename.md +191 -0
  104. package/docs/components/organisms/DropzoneSupportedFormats.md +184 -0
  105. package/docs/components/organisms/DropzoneTrigger.md +209 -0
  106. package/docs/components/organisms/Form.md +533 -0
  107. package/docs/components/organisms/SlideOutPanel.md +662 -0
  108. package/docs/components/organisms/TabContent.md +902 -0
  109. package/docs/components/organisms/TabItem.md +1091 -0
  110. package/docs/components/organisms/Table.md +611 -0
  111. package/docs/components/organisms/TableBody.md +679 -0
  112. package/docs/components/organisms/TableCell.md +482 -0
  113. package/docs/components/organisms/TableHeader.md +513 -0
  114. package/docs/components/organisms/TableHeaderCell.md +661 -0
  115. package/docs/components/organisms/TableRow.md +715 -0
  116. package/docs/components/organisms/Tabs.md +1330 -0
  117. package/docs/components/utils/ConditionalView.md +568 -0
  118. package/docs/components/utils/RenderStateView.md +726 -0
  119. package/docs/components/utils/WrapTextNodes.md +614 -0
  120. package/package.json +3 -2
@@ -0,0 +1,611 @@
1
+ # Table
2
+
3
+ ## Description
4
+
5
+ A comprehensive data table component that provides structure for presenting tabular data in an organized, accessible format. The Table component serves as the root container for table content and offers features like sticky headers for enhanced usability in data-heavy interfaces.
6
+
7
+ ## Aliases
8
+
9
+ - Table
10
+ - DataTable
11
+ - Grid
12
+ - TableContainer
13
+ - DataGrid
14
+
15
+ ## Props Breakdown
16
+
17
+ **Extends:** `TableHTMLAttributes<HTMLTableElement>`
18
+
19
+ | Prop | Type | Default | Required | Description |
20
+ |------|------|---------|----------|-------------|
21
+ | `stickyHeader` | `boolean` | `false` | No | Whether the table header should stick to the top when scrolling |
22
+ | `children` | `ReactNode` | - | Yes | Table content including TableHeader, TableBody, and TableRow components |
23
+
24
+ Plus all standard HTML table attributes (id, className, style, role, etc.).
25
+
26
+ ## Examples
27
+
28
+ ### Basic Data Table
29
+ ```tsx
30
+ import { Table, TableHeader, TableBody, TableRow, TableHeaderCell, TableCell, Text } from '@delightui/components';
31
+
32
+ function BasicTableExample() {
33
+ const users = [
34
+ { id: 1, name: 'John Doe', email: 'john@example.com', role: 'Admin' },
35
+ { id: 2, name: 'Jane Smith', email: 'jane@example.com', role: 'User' },
36
+ { id: 3, name: 'Bob Johnson', email: 'bob@example.com', role: 'Editor' }
37
+ ];
38
+
39
+ return (
40
+ <Table>
41
+ <TableHeader>
42
+ <TableRow>
43
+ <TableHeaderCell>Name</TableHeaderCell>
44
+ <TableHeaderCell>Email</TableHeaderCell>
45
+ <TableHeaderCell>Role</TableHeaderCell>
46
+ </TableRow>
47
+ </TableHeader>
48
+ <TableBody>
49
+ <List
50
+ data={users}
51
+ component={({ name, email, role }) => (
52
+ <TableRow>
53
+ <TableCell>{name}</TableCell>
54
+ <TableCell>{email}</TableCell>
55
+ <TableCell>{role}</TableCell>
56
+ </TableRow>
57
+ )}
58
+ keyExtractor={(user) => user.id}
59
+ />
60
+ </TableBody>
61
+ </Table>
62
+ );
63
+ }
64
+ ```
65
+
66
+ ### Sticky Header Table
67
+ ```tsx
68
+ function StickyHeaderExample() {
69
+ const products = Array.from({ length: 50 }, (_, i) => ({
70
+ id: i + 1,
71
+ name: `Product ${i + 1}`,
72
+ category: ['Electronics', 'Clothing', 'Books', 'Home'][i % 4],
73
+ price: (Math.random() * 1000).toFixed(2),
74
+ stock: Math.floor(Math.random() * 100)
75
+ }));
76
+
77
+ return (
78
+ <div className="table-container" style={{ height: '400px', overflow: 'auto' }}>
79
+ <Table stickyHeader>
80
+ <TableHeader>
81
+ <TableRow>
82
+ <TableHeaderCell>ID</TableHeaderCell>
83
+ <TableHeaderCell>Product Name</TableHeaderCell>
84
+ <TableHeaderCell>Category</TableHeaderCell>
85
+ <TableHeaderCell>Price</TableHeaderCell>
86
+ <TableHeaderCell>Stock</TableHeaderCell>
87
+ </TableRow>
88
+ </TableHeader>
89
+ <TableBody>
90
+ <List
91
+ data={products}
92
+ component={({ id, name, category, price, stock }) => (
93
+ <TableRow>
94
+ <TableCell>{id}</TableCell>
95
+ <TableCell>{name}</TableCell>
96
+ <TableCell>{category}</TableCell>
97
+ <TableCell>${price}</TableCell>
98
+ <TableCell>{stock}</TableCell>
99
+ </TableRow>
100
+ )}
101
+ keyExtractor={(product) => product.id}
102
+ />
103
+ </TableBody>
104
+ </Table>
105
+ </div>
106
+ );
107
+ }
108
+ ```
109
+
110
+ ### Sortable Table with Actions
111
+ ```tsx
112
+ import { Table, TableHeader, TableBody, TableRow, TableHeaderCell, TableCell, Button, Icon } from '@delightui/components';
113
+
114
+ function SortableTableExample() {
115
+ const [sortField, setSortField] = useState('name');
116
+ const [sortDirection, setSortDirection] = useState('asc');
117
+
118
+ const data = [
119
+ { id: 1, name: 'Alice Johnson', department: 'Engineering', salary: 95000, startDate: '2021-03-15' },
120
+ { id: 2, name: 'Bob Smith', department: 'Marketing', salary: 75000, startDate: '2020-11-20' },
121
+ { id: 3, name: 'Carol Williams', department: 'Design', salary: 85000, startDate: '2022-01-10' }
122
+ ];
123
+
124
+ const handleSort = (field) => {
125
+ if (sortField === field) {
126
+ setSortDirection(sortDirection === 'asc' ? 'desc' : 'asc');
127
+ } else {
128
+ setSortField(field);
129
+ setSortDirection('asc');
130
+ }
131
+ };
132
+
133
+ const sortedData = [...data].sort((a, b) => {
134
+ const aVal = a[sortField];
135
+ const bVal = b[sortField];
136
+ const modifier = sortDirection === 'asc' ? 1 : -1;
137
+ return aVal < bVal ? -1 * modifier : aVal > bVal ? 1 * modifier : 0;
138
+ });
139
+
140
+ return (
141
+ <Table>
142
+ <TableHeader>
143
+ <TableRow>
144
+ <TableHeaderCell
145
+ onClick={() => handleSort('name')}
146
+ className="sortable-header"
147
+ >
148
+ Name
149
+ <Icon
150
+ icon={sortField === 'name' && sortDirection === 'desc' ? 'ArrowUp' : 'ArrowDown'}
151
+ size="Small"
152
+ />
153
+ </TableHeaderCell>
154
+ <TableHeaderCell
155
+ onClick={() => handleSort('department')}
156
+ className="sortable-header"
157
+ >
158
+ Department
159
+ <Icon
160
+ icon={sortField === 'department' && sortDirection === 'desc' ? 'ArrowUp' : 'ArrowDown'}
161
+ size="Small"
162
+ />
163
+ </TableHeaderCell>
164
+ <TableHeaderCell
165
+ onClick={() => handleSort('salary')}
166
+ className="sortable-header"
167
+ >
168
+ Salary
169
+ <Icon
170
+ icon={sortField === 'salary' && sortDirection === 'desc' ? 'ArrowUp' : 'ArrowDown'}
171
+ size="Small"
172
+ />
173
+ </TableHeaderCell>
174
+ <TableHeaderCell>Actions</TableHeaderCell>
175
+ </TableRow>
176
+ </TableHeader>
177
+ <TableBody>
178
+ {sortedData.map(employee => (
179
+ <TableRow key={employee.id}>
180
+ <TableCell>{employee.name}</TableCell>
181
+ <TableCell>{employee.department}</TableCell>
182
+ <TableCell>${employee.salary.toLocaleString()}</TableCell>
183
+ <TableCell>
184
+ <div className="action-buttons">
185
+ <Button size="Small" type="Ghost">Edit</Button>
186
+ <Button size="Small" type="Ghost">Delete</Button>
187
+ </div>
188
+ </TableCell>
189
+ </TableRow>
190
+ ))}
191
+ </TableBody>
192
+ </Table>
193
+ );
194
+ }
195
+ ```
196
+
197
+ ### Table with Row Selection
198
+ ```tsx
199
+ function SelectableTableExample() {
200
+ const [selectedRows, setSelectedRows] = useState(new Set());
201
+
202
+ const tasks = [
203
+ { id: 1, title: 'Update documentation', status: 'In Progress', assignee: 'John', priority: 'High' },
204
+ { id: 2, title: 'Fix login bug', status: 'Todo', assignee: 'Jane', priority: 'Critical' },
205
+ { id: 3, title: 'Design new feature', status: 'Done', assignee: 'Bob', priority: 'Medium' }
206
+ ];
207
+
208
+ const handleSelectAll = (checked) => {
209
+ if (checked) {
210
+ setSelectedRows(new Set(tasks.map(task => task.id)));
211
+ } else {
212
+ setSelectedRows(new Set());
213
+ }
214
+ };
215
+
216
+ const handleSelectRow = (id, checked) => {
217
+ const newSelected = new Set(selectedRows);
218
+ if (checked) {
219
+ newSelected.add(id);
220
+ } else {
221
+ newSelected.delete(id);
222
+ }
223
+ setSelectedRows(newSelected);
224
+ };
225
+
226
+ return (
227
+ <div>
228
+ <div className="table-actions">
229
+ <Text>Selected: {selectedRows.size} items</Text>
230
+ {selectedRows.size > 0 && (
231
+ <Button size="Small" type="Outlined">
232
+ Delete Selected
233
+ </Button>
234
+ )}
235
+ </div>
236
+
237
+ <Table>
238
+ <TableHeader>
239
+ <TableRow>
240
+ <TableHeaderCell>
241
+ <Checkbox
242
+ checked={selectedRows.size === tasks.length}
243
+ indeterminate={selectedRows.size > 0 && selectedRows.size < tasks.length}
244
+ onChange={(e) => handleSelectAll(e.target.checked)}
245
+ />
246
+ </TableHeaderCell>
247
+ <TableHeaderCell>Task</TableHeaderCell>
248
+ <TableHeaderCell>Status</TableHeaderCell>
249
+ <TableHeaderCell>Assignee</TableHeaderCell>
250
+ <TableHeaderCell>Priority</TableHeaderCell>
251
+ </TableRow>
252
+ </TableHeader>
253
+ <TableBody>
254
+ {tasks.map(task => (
255
+ <TableRow key={task.id} className={selectedRows.has(task.id) ? 'selected-row' : ''}>
256
+ <TableCell>
257
+ <Checkbox
258
+ checked={selectedRows.has(task.id)}
259
+ onChange={(e) => handleSelectRow(task.id, e.target.checked)}
260
+ />
261
+ </TableCell>
262
+ <TableCell>{task.title}</TableCell>
263
+ <TableCell>
264
+ <Chip
265
+ style={task.status === 'Done' ? 'Success' : task.status === 'In Progress' ? 'Warning' : 'Default'}
266
+ >
267
+ {task.status}
268
+ </Chip>
269
+ </TableCell>
270
+ <TableCell>{task.assignee}</TableCell>
271
+ <TableCell>
272
+ <Chip
273
+ style={task.priority === 'Critical' ? 'Error' : task.priority === 'High' ? 'Warning' : 'Default'}
274
+ >
275
+ {task.priority}
276
+ </Chip>
277
+ </TableCell>
278
+ </TableRow>
279
+ ))}
280
+ </TableBody>
281
+ </Table>
282
+ </div>
283
+ );
284
+ }
285
+ ```
286
+
287
+ ### Expandable Rows Table
288
+ ```tsx
289
+ function ExpandableTableExample() {
290
+ const [expandedRows, setExpandedRows] = useState(new Set());
291
+
292
+ const orders = [
293
+ {
294
+ id: '001',
295
+ customer: 'John Doe',
296
+ total: 299.99,
297
+ date: '2023-10-15',
298
+ items: [
299
+ { name: 'Laptop', quantity: 1, price: 199.99 },
300
+ { name: 'Mouse', quantity: 2, price: 50.00 }
301
+ ]
302
+ },
303
+ {
304
+ id: '002',
305
+ customer: 'Jane Smith',
306
+ total: 159.97,
307
+ date: '2023-10-14',
308
+ items: [
309
+ { name: 'Keyboard', quantity: 1, price: 79.99 },
310
+ { name: 'Monitor Stand', quantity: 1, price: 79.98 }
311
+ ]
312
+ }
313
+ ];
314
+
315
+ const toggleRow = (id) => {
316
+ const newExpanded = new Set(expandedRows);
317
+ if (newExpanded.has(id)) {
318
+ newExpanded.delete(id);
319
+ } else {
320
+ newExpanded.add(id);
321
+ }
322
+ setExpandedRows(newExpanded);
323
+ };
324
+
325
+ return (
326
+ <Table>
327
+ <TableHeader>
328
+ <TableRow>
329
+ <TableHeaderCell></TableHeaderCell>
330
+ <TableHeaderCell>Order ID</TableHeaderCell>
331
+ <TableHeaderCell>Customer</TableHeaderCell>
332
+ <TableHeaderCell>Date</TableHeaderCell>
333
+ <TableHeaderCell>Total</TableHeaderCell>
334
+ </TableRow>
335
+ </TableHeader>
336
+ <TableBody>
337
+ {orders.map(order => (
338
+ <React.Fragment key={order.id}>
339
+ <TableRow>
340
+ <TableCell>
341
+ <Button
342
+ size="Small"
343
+ type="Ghost"
344
+ onClick={() => toggleRow(order.id)}
345
+ >
346
+ <Icon
347
+ icon={expandedRows.has(order.id) ? 'ExpandLess' : 'ExpandMore'}
348
+ size="Small"
349
+ />
350
+ </Button>
351
+ </TableCell>
352
+ <TableCell>{order.id}</TableCell>
353
+ <TableCell>{order.customer}</TableCell>
354
+ <TableCell>{order.date}</TableCell>
355
+ <TableCell>${order.total}</TableCell>
356
+ </TableRow>
357
+ {expandedRows.has(order.id) && (
358
+ <TableRow className="expanded-row">
359
+ <TableCell colSpan={5}>
360
+ <div className="order-details">
361
+ <Text type="Heading6">Order Items:</Text>
362
+ <Table>
363
+ <TableHeader>
364
+ <TableRow>
365
+ <TableHeaderCell>Item</TableHeaderCell>
366
+ <TableHeaderCell>Quantity</TableHeaderCell>
367
+ <TableHeaderCell>Price</TableHeaderCell>
368
+ </TableRow>
369
+ </TableHeader>
370
+ <TableBody>
371
+ {order.items.map((item, index) => (
372
+ <TableRow key={index}>
373
+ <TableCell>{item.name}</TableCell>
374
+ <TableCell>{item.quantity}</TableCell>
375
+ <TableCell>${item.price}</TableCell>
376
+ </TableRow>
377
+ ))}
378
+ </TableBody>
379
+ </Table>
380
+ </div>
381
+ </TableCell>
382
+ </TableRow>
383
+ )}
384
+ </React.Fragment>
385
+ ))}
386
+ </TableBody>
387
+ </Table>
388
+ );
389
+ }
390
+ ```
391
+
392
+ ### Responsive Table
393
+ ```tsx
394
+ function ResponsiveTableExample() {
395
+ const transactions = [
396
+ { id: 'TX001', type: 'Purchase', amount: -99.99, merchant: 'Amazon', date: '2023-10-15', category: 'Shopping' },
397
+ { id: 'TX002', type: 'Deposit', amount: 2500.00, merchant: 'Direct Deposit', date: '2023-10-14', category: 'Income' },
398
+ { id: 'TX003', type: 'Purchase', amount: -45.67, merchant: 'Gas Station', date: '2023-10-13', category: 'Transport' }
399
+ ];
400
+
401
+ return (
402
+ <div className="responsive-table-wrapper">
403
+ <Table className="responsive-table">
404
+ <TableHeader>
405
+ <TableRow>
406
+ <TableHeaderCell>Transaction</TableHeaderCell>
407
+ <TableHeaderCell className="hide-mobile">Type</TableHeaderCell>
408
+ <TableHeaderCell>Amount</TableHeaderCell>
409
+ <TableHeaderCell className="hide-mobile">Merchant</TableHeaderCell>
410
+ <TableHeaderCell className="hide-tablet">Date</TableHeaderCell>
411
+ <TableHeaderCell className="hide-mobile">Category</TableHeaderCell>
412
+ </TableRow>
413
+ </TableHeader>
414
+ <TableBody>
415
+ {transactions.map(transaction => (
416
+ <TableRow key={transaction.id}>
417
+ <TableCell>
418
+ <div className="transaction-info">
419
+ <Text type="BodyMedium">{transaction.id}</Text>
420
+ <Text type="BodySmall" className="show-mobile">
421
+ {transaction.type} • {transaction.merchant}
422
+ </Text>
423
+ </div>
424
+ </TableCell>
425
+ <TableCell className="hide-mobile">{transaction.type}</TableCell>
426
+ <TableCell>
427
+ <Text
428
+ type="BodyMedium"
429
+ className={transaction.amount > 0 ? 'positive-amount' : 'negative-amount'}
430
+ >
431
+ ${Math.abs(transaction.amount).toFixed(2)}
432
+ </Text>
433
+ </TableCell>
434
+ <TableCell className="hide-mobile">{transaction.merchant}</TableCell>
435
+ <TableCell className="hide-tablet">{transaction.date}</TableCell>
436
+ <TableCell className="hide-mobile">
437
+ <Chip size="Small">{transaction.category}</Chip>
438
+ </TableCell>
439
+ </TableRow>
440
+ ))}
441
+ </TableBody>
442
+ </Table>
443
+ </div>
444
+ );
445
+ }
446
+ ```
447
+
448
+ ### Table with Pagination
449
+ ```tsx
450
+ function PaginatedTableExample() {
451
+ const [currentPage, setCurrentPage] = useState(1);
452
+ const [pageSize] = useState(5);
453
+
454
+ const allData = Array.from({ length: 50 }, (_, i) => ({
455
+ id: i + 1,
456
+ name: `User ${i + 1}`,
457
+ email: `user${i + 1}@example.com`,
458
+ status: ['Active', 'Inactive', 'Pending'][i % 3],
459
+ lastLogin: new Date(Date.now() - Math.random() * 30 * 24 * 60 * 60 * 1000).toLocaleDateString()
460
+ }));
461
+
462
+ const totalPages = Math.ceil(allData.length / pageSize);
463
+ const startIndex = (currentPage - 1) * pageSize;
464
+ const currentData = allData.slice(startIndex, startIndex + pageSize);
465
+
466
+ return (
467
+ <div>
468
+ <Table>
469
+ <TableHeader>
470
+ <TableRow>
471
+ <TableHeaderCell>ID</TableHeaderCell>
472
+ <TableHeaderCell>Name</TableHeaderCell>
473
+ <TableHeaderCell>Email</TableHeaderCell>
474
+ <TableHeaderCell>Status</TableHeaderCell>
475
+ <TableHeaderCell>Last Login</TableHeaderCell>
476
+ </TableRow>
477
+ </TableHeader>
478
+ <TableBody>
479
+ {currentData.map(user => (
480
+ <TableRow key={user.id}>
481
+ <TableCell>{user.id}</TableCell>
482
+ <TableCell>{user.name}</TableCell>
483
+ <TableCell>{user.email}</TableCell>
484
+ <TableCell>
485
+ <Chip
486
+ style={user.status === 'Active' ? 'Success' : user.status === 'Inactive' ? 'Error' : 'Warning'}
487
+ >
488
+ {user.status}
489
+ </Chip>
490
+ </TableCell>
491
+ <TableCell>{user.lastLogin}</TableCell>
492
+ </TableRow>
493
+ ))}
494
+ </TableBody>
495
+ </Table>
496
+
497
+ <div className="table-pagination">
498
+ <Pagination
499
+ currentPage={currentPage}
500
+ totalPages={totalPages}
501
+ onPageChange={setCurrentPage}
502
+ />
503
+ <Text type="BodySmall">
504
+ Showing {startIndex + 1}-{Math.min(startIndex + pageSize, allData.length)} of {allData.length} results
505
+ </Text>
506
+ </div>
507
+ </div>
508
+ );
509
+ }
510
+ ```
511
+
512
+ ### Loading State Table
513
+ ```tsx
514
+ function LoadingTableExample() {
515
+ const [isLoading, setIsLoading] = useState(true);
516
+ const [data, setData] = useState([]);
517
+
518
+ useEffect(() => {
519
+ // Simulate API call
520
+ setTimeout(() => {
521
+ setData([
522
+ { id: 1, name: 'John Doe', role: 'Admin', lastActive: '2 hours ago' },
523
+ { id: 2, name: 'Jane Smith', role: 'User', lastActive: '1 day ago' },
524
+ { id: 3, name: 'Bob Johnson', role: 'Editor', lastActive: '3 days ago' }
525
+ ]);
526
+ setIsLoading(false);
527
+ }, 2000);
528
+ }, []);
529
+
530
+ return (
531
+ <Table>
532
+ <TableHeader>
533
+ <TableRow>
534
+ <TableHeaderCell>Name</TableHeaderCell>
535
+ <TableHeaderCell>Role</TableHeaderCell>
536
+ <TableHeaderCell>Last Active</TableHeaderCell>
537
+ <TableHeaderCell>Actions</TableHeaderCell>
538
+ </TableRow>
539
+ </TableHeader>
540
+ <TableBody>
541
+ {isLoading ? (
542
+ Array.from({ length: 3 }).map((_, index) => (
543
+ <TableRow key={index}>
544
+ <TableCell>
545
+ <div className="skeleton-loader skeleton-text"></div>
546
+ </TableCell>
547
+ <TableCell>
548
+ <div className="skeleton-loader skeleton-text-small"></div>
549
+ </TableCell>
550
+ <TableCell>
551
+ <div className="skeleton-loader skeleton-text-small"></div>
552
+ </TableCell>
553
+ <TableCell>
554
+ <div className="skeleton-loader skeleton-button"></div>
555
+ </TableCell>
556
+ </TableRow>
557
+ ))
558
+ ) : (
559
+ data.map(user => (
560
+ <TableRow key={user.id}>
561
+ <TableCell>{user.name}</TableCell>
562
+ <TableCell>{user.role}</TableCell>
563
+ <TableCell>{user.lastActive}</TableCell>
564
+ <TableCell>
565
+ <Button size="Small" type="Ghost">View</Button>
566
+ </TableCell>
567
+ </TableRow>
568
+ ))
569
+ )}
570
+ </TableBody>
571
+ </Table>
572
+ );
573
+ }
574
+ ```
575
+
576
+ ### Empty State Table
577
+ ```tsx
578
+ function EmptyStateTableExample() {
579
+ const [hasData] = useState(false);
580
+
581
+ return (
582
+ <Table>
583
+ <TableHeader>
584
+ <TableRow>
585
+ <TableHeaderCell>Product Name</TableHeaderCell>
586
+ <TableHeaderCell>Category</TableHeaderCell>
587
+ <TableHeaderCell>Price</TableHeaderCell>
588
+ <TableHeaderCell>Stock</TableHeaderCell>
589
+ <TableHeaderCell>Actions</TableHeaderCell>
590
+ </TableRow>
591
+ </TableHeader>
592
+ <TableBody>
593
+ {!hasData ? (
594
+ <TableRow>
595
+ <TableCell colSpan={5} className="empty-state-cell">
596
+ <div className="empty-state">
597
+ <Icon icon="Inventory" size="Large" className="empty-state-icon" />
598
+ <Text type="Heading5">No products found</Text>
599
+ <Text type="BodySmall">
600
+ Start by adding your first product to the inventory.
601
+ </Text>
602
+ <Button>Add Product</Button>
603
+ </div>
604
+ </TableCell>
605
+ </TableRow>
606
+ ) : null}
607
+ </TableBody>
608
+ </Table>
609
+ );
610
+ }
611
+ ```