@adobe-commerce/elsie 1.6.0-alpha7 → 1.6.0-alpha77

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 (36) hide show
  1. package/package.json +3 -4
  2. package/src/components/Icon/Icon.css +11 -7
  3. package/src/components/Icon/Icon.tsx +30 -24
  4. package/src/components/MultiSelect/MultiSelect.stories.tsx +7 -5
  5. package/src/components/Pagination/Pagination.css +14 -5
  6. package/src/components/Pagination/Pagination.stories.tsx +32 -3
  7. package/src/components/Pagination/Pagination.tsx +28 -22
  8. package/src/components/Pagination/PaginationButton.tsx +46 -0
  9. package/src/components/Table/Table.css +86 -13
  10. package/src/components/Table/Table.stories.tsx +320 -57
  11. package/src/components/Table/Table.tsx +6 -2
  12. package/src/icons/Business.svg +6 -0
  13. package/src/icons/ChevronDown.svg +1 -1
  14. package/src/icons/ChevronUp.svg +1 -1
  15. package/src/icons/Edit.svg +3 -1
  16. package/src/icons/Eye.svg +1 -1
  17. package/src/icons/EyeClose.svg +1 -1
  18. package/src/icons/Gift.svg +1 -1
  19. package/src/icons/GiftCard.svg +1 -1
  20. package/src/icons/Heart.svg +1 -1
  21. package/src/icons/List.svg +9 -0
  22. package/src/icons/Locker.svg +2 -2
  23. package/src/icons/Minus.svg +1 -1
  24. package/src/icons/OrderError.svg +6 -6
  25. package/src/icons/OrderSuccess.svg +6 -6
  26. package/src/icons/PaymentError.svg +7 -7
  27. package/src/icons/Placeholder.svg +1 -1
  28. package/src/icons/Purchase.svg +8 -0
  29. package/src/icons/Quote.svg +10 -0
  30. package/src/icons/Sort.svg +5 -5
  31. package/src/icons/Structure.svg +10 -0
  32. package/src/icons/Team.svg +5 -0
  33. package/src/icons/Trash.svg +6 -6
  34. package/src/icons/Warning.svg +3 -3
  35. package/src/icons/index.ts +30 -24
  36. package/src/lib/aem/configs.ts +1 -1
@@ -11,6 +11,10 @@
11
11
  import type { Meta, StoryObj } from '@storybook/preact';
12
12
  import { useState } from 'preact/hooks';
13
13
  import { Table as TableComponent, TableProps } from '@adobe-commerce/elsie/components/Table';
14
+ import { ActionButton } from '@adobe-commerce/elsie/components/ActionButton';
15
+ import { ActionButtonGroup } from '@adobe-commerce/elsie/components/ActionButtonGroup';
16
+ import { Pagination } from '@adobe-commerce/elsie/components/Pagination';
17
+ import { Picker, type PickerOption } from '@adobe-commerce/elsie/components/Picker';
14
18
 
15
19
  /**
16
20
  * Use the `Table` component to render data in a structured table.
@@ -175,10 +179,10 @@ export const Table: Story = {
175
179
  { key: 'actions', label: 'Actions' },
176
180
  ],
177
181
  rowData: [
178
- { name: 'John', email: 'john@example.com', age: 20, actions: <button>Edit</button> },
179
- { name: 'Jane', email: 'jane@example.com', age: 21, actions: <button>Edit</button> },
180
- { name: 'Jim', email: 'jim@example.com', age: 22, actions: <button>Edit</button> },
181
- { name: 'Jill', email: 'jill@example.com', age: 23, actions: <button>Edit</button> },
182
+ { name: 'John', email: 'john@example.com', age: 20, actions: <ActionButton>Edit</ActionButton> },
183
+ { name: 'Jane', email: 'jane@example.com', age: 21, actions: <ActionButton>Edit</ActionButton> },
184
+ { name: 'Jim', email: 'jim@example.com', age: 22, actions: <ActionButton>Edit</ActionButton> },
185
+ { name: 'Jill', email: 'jill@example.com', age: 23, actions: <ActionButton>Edit</ActionButton> },
182
186
  ],
183
187
  },
184
188
  };
@@ -212,11 +216,11 @@ export const AllSortable: Story = {
212
216
  { key: 'actions', label: 'Actions' },
213
217
  ],
214
218
  rowData: [
215
- { name: 'John', email: 'john@example.com', age: 20, actions: <button>Edit</button> },
216
- { name: 'Jane', email: 'jane@example.com', age: 21, actions: <button>Edit</button> },
217
- { name: 'Jim', email: 'jim@example.com', age: 22, actions: <button>Edit</button> },
218
- { name: 'Jill', email: 'jill@example.com', age: 23, actions: <button>Edit</button> },
219
- { name: 'Jack', email: 'jack@example.com', age: 24, actions: <button>Edit</button> },
219
+ { name: 'John', email: 'john@example.com', age: 20, actions: <ActionButton>Edit</ActionButton> },
220
+ { name: 'Jane', email: 'jane@example.com', age: 21, actions: <ActionButton>Edit</ActionButton> },
221
+ { name: 'Jim', email: 'jim@example.com', age: 22, actions: <ActionButton>Edit</ActionButton> },
222
+ { name: 'Jill', email: 'jill@example.com', age: 23, actions: <ActionButton>Edit</ActionButton> },
223
+ { name: 'Jack', email: 'jack@example.com', age: 24, actions: <ActionButton>Edit</ActionButton> },
220
224
  ],
221
225
  },
222
226
  };
@@ -240,7 +244,7 @@ export const AllSortable: Story = {
240
244
  * { key: 'actions', label: 'Actions' }
241
245
  * ]}
242
246
  * rowData={[
243
- * { id: 1, name: 'John Doe', email: 'john@company.com', phone: '+1-555-0123', department: 'Engineering', position: 'Senior Developer', salary: '$95,000', startDate: '2022-01-15', status: 'Active', actions: <button>Edit</button> }
247
+ * { id: 1, name: 'John Doe', email: 'john@company.com', phone: '+1-555-0123', department: 'Engineering', position: 'Senior Developer', salary: '$95,000', startDate: '2022-01-15', status: 'Active', actions: <ActionButton>Edit</ActionButton> }
244
248
  * ]}
245
249
  * />
246
250
  * ```
@@ -270,7 +274,7 @@ export const WideTable: Story = {
270
274
  salary: '$95,000',
271
275
  startDate: '2022-01-15',
272
276
  status: 'Active',
273
- actions: <button>Edit</button>
277
+ actions: <ActionButton>Edit</ActionButton>
274
278
  },
275
279
  {
276
280
  id: 2,
@@ -282,7 +286,7 @@ export const WideTable: Story = {
282
286
  salary: '$78,000',
283
287
  startDate: '2021-06-20',
284
288
  status: 'Active',
285
- actions: <button>Edit</button>
289
+ actions: <ActionButton>Edit</ActionButton>
286
290
  },
287
291
  {
288
292
  id: 3,
@@ -294,7 +298,7 @@ export const WideTable: Story = {
294
298
  salary: '$110,000',
295
299
  startDate: '2020-03-10',
296
300
  status: 'Active',
297
- actions: <button>Edit</button>
301
+ actions: <ActionButton>Edit</ActionButton>
298
302
  },
299
303
  {
300
304
  id: 4,
@@ -306,7 +310,7 @@ export const WideTable: Story = {
306
310
  salary: '$65,000',
307
311
  startDate: '2023-02-28',
308
312
  status: 'Pending',
309
- actions: <button>Edit</button>
313
+ actions: <ActionButton>Edit</ActionButton>
310
314
  },
311
315
  {
312
316
  id: 5,
@@ -318,7 +322,7 @@ export const WideTable: Story = {
318
322
  salary: '$72,000',
319
323
  startDate: '2022-09-12',
320
324
  status: 'Active',
321
- actions: <button>Edit</button>
325
+ actions: <ActionButton>Edit</ActionButton>
322
326
  },
323
327
  ],
324
328
  },
@@ -341,7 +345,7 @@ export const WideTable: Story = {
341
345
  * user: <div><strong>John Doe</strong><br/>john@example.com<br/>Senior Developer</div>,
342
346
  * description: <div>Lead developer for the<br/>e-commerce platform<br/>with 5+ years experience</div>,
343
347
  * status: <span>Active</span>,
344
- * actions: <div><button>Edit</button><br/><button>Delete</button><br/><button>View</button></div>
348
+ * actions: <div><ActionButton>Edit</ActionButton><br/><ActionButton>Delete</ActionButton><br/><ActionButton>View</ActionButton></div>
345
349
  * }
346
350
  * ]}
347
351
  * />
@@ -375,11 +379,11 @@ export const ComplexCells: Story = {
375
379
  <span>Active</span>
376
380
  ),
377
381
  actions: (
378
- <div>
379
- <button>Edit</button>
380
- <button>Delete</button>
381
- <button>View</button>
382
- </div>
382
+ <ActionButtonGroup>
383
+ <ActionButton value="edit">Edit</ActionButton>
384
+ <ActionButton value="delete">Delete</ActionButton>
385
+ <ActionButton value="view">View</ActionButton>
386
+ </ActionButtonGroup>
383
387
  ),
384
388
  },
385
389
  {
@@ -401,11 +405,11 @@ export const ComplexCells: Story = {
401
405
  <span>Pending</span>
402
406
  ),
403
407
  actions: (
404
- <div>
405
- <button>Edit</button>
406
- <button>Approve</button>
407
- <button>Reject</button>
408
- </div>
408
+ <ActionButtonGroup>
409
+ <ActionButton value="edit">Edit</ActionButton>
410
+ <ActionButton value="approve">Approve</ActionButton>
411
+ <ActionButton value="reject">Reject</ActionButton>
412
+ </ActionButtonGroup>
409
413
  ),
410
414
  },
411
415
  {
@@ -427,11 +431,11 @@ export const ComplexCells: Story = {
427
431
  <span>Inactive</span>
428
432
  ),
429
433
  actions: (
430
- <div>
431
- <button>Edit</button>
432
- <button>Activate</button>
433
- <button>Archive</button>
434
- </div>
434
+ <ActionButtonGroup>
435
+ <ActionButton value="edit">Edit</ActionButton>
436
+ <ActionButton value="activate">Activate</ActionButton>
437
+ <ActionButton value="archive">Archive</ActionButton>
438
+ </ActionButtonGroup>
435
439
  ),
436
440
  },
437
441
  ],
@@ -476,10 +480,10 @@ export const StackedMobileLayout: Story = {
476
480
  { key: 'actions', label: 'Actions' },
477
481
  ],
478
482
  rowData: [
479
- { name: 'John Doe', email: 'john.doe@example.com', age: 28, status: 'Active', actions: <button>Edit</button> },
480
- { name: 'Jane Smith', email: 'jane.smith@example.com', age: 32, status: 'Inactive', actions: <button>Edit</button> },
481
- { name: 'Bob Johnson', email: 'bob.johnson@example.com', age: 45, status: 'Active', actions: <button>Edit</button> },
482
- { name: 'Alice Brown', email: 'alice.brown@example.com', age: 29, status: 'Pending', actions: <button>Edit</button> },
483
+ { name: 'John Doe', email: 'john.doe@example.com', age: 28, status: 'Active', actions: <ActionButton>Edit</ActionButton> },
484
+ { name: 'Jane Smith', email: 'jane.smith@example.com', age: 32, status: 'Inactive', actions: <ActionButton>Edit</ActionButton> },
485
+ { name: 'Bob Johnson', email: 'bob.johnson@example.com', age: 45, status: 'Active', actions: <ActionButton>Edit</ActionButton> },
486
+ { name: 'Alice Brown', email: 'alice.brown@example.com', age: 29, status: 'Pending', actions: <ActionButton>Edit</ActionButton> },
483
487
  ],
484
488
  },
485
489
  };
@@ -520,7 +524,7 @@ export const StackedMobileLayout: Story = {
520
524
  * {
521
525
  * name: 'John',
522
526
  * email: 'john@example.com',
523
- * actions: <button onClick={() => toggleRow(0)}>Toggle Details</button>,
527
+ * actions: <ActionButton onClick={() => toggleRow(0)}>Toggle Details</ActionButton>,
524
528
  * _rowDetails: <div>Additional information...</div>
525
529
  * }
526
530
  * ]}
@@ -550,22 +554,22 @@ export const RowDetails: Story = {
550
554
  email: 'john.doe@company.com',
551
555
  status: 'Active',
552
556
  actions: (
553
- <button onClick={() => toggleRow(0)}>
557
+ <ActionButton onClick={() => toggleRow(0)}>
554
558
  {expandedRows.has(0) ? 'Hide' : 'Show'}
555
- </button>
559
+ </ActionButton>
556
560
  ),
557
561
  _rowDetails: (
558
- <div>
562
+ <>
559
563
  <h3>Employee Details</h3>
560
564
  <p><strong>Department:</strong> Engineering</p>
561
565
  <p><strong>Position:</strong> Senior Developer</p>
562
566
  <p><strong>Start Date:</strong> January 15, 2022</p>
563
567
  <p><strong>Notes:</strong> Excellent performance, leads the frontend team.</p>
564
568
  <div style={{ marginTop: '12px' }}>
565
- <button style={{ marginRight: '8px' }}>Update Details</button>
566
- <button>View Full Profile</button>
569
+ <ActionButton style={{ marginRight: '8px' }}>Update Details</ActionButton>
570
+ <ActionButton>View Full Profile</ActionButton>
567
571
  </div>
568
- </div>
572
+ </>
569
573
  )
570
574
  },
571
575
  {
@@ -573,22 +577,22 @@ export const RowDetails: Story = {
573
577
  email: 'jane.smith@company.com',
574
578
  status: 'Pending',
575
579
  actions: (
576
- <button onClick={() => toggleRow(1)}>
580
+ <ActionButton onClick={() => toggleRow(1)}>
577
581
  {expandedRows.has(1) ? 'Hide' : 'Show'}
578
- </button>
582
+ </ActionButton>
579
583
  ),
580
584
  _rowDetails: (
581
- <div>
585
+ <>
582
586
  <h3>Pending Approval</h3>
583
587
  <p><strong>Department:</strong> Marketing</p>
584
588
  <p><strong>Position:</strong> Marketing Manager</p>
585
589
  <p><strong>Application Date:</strong> December 1, 2024</p>
586
590
  <p><strong>Status:</strong> Awaiting HR approval</p>
587
591
  <div style={{ marginTop: '12px' }}>
588
- <button style={{ marginRight: '8px', backgroundColor: '#22c55e', color: 'white', border: 'none', padding: '6px 12px', borderRadius: '4px' }}>Approve</button>
589
- <button style={{ backgroundColor: '#ef4444', color: 'white', border: 'none', padding: '6px 12px', borderRadius: '4px' }}>Reject</button>
592
+ <ActionButton style={{ marginRight: '8px', backgroundColor: '#22c55e', color: 'white', border: 'none', padding: '6px 12px', borderRadius: '4px' }}>Approve</ActionButton>
593
+ <ActionButton style={{ backgroundColor: '#ef4444', color: 'white', border: 'none', padding: '6px 12px', borderRadius: '4px' }}>Reject</ActionButton>
590
594
  </div>
591
- </div>
595
+ </>
592
596
  )
593
597
  },
594
598
  {
@@ -596,22 +600,22 @@ export const RowDetails: Story = {
596
600
  email: 'bob.johnson@company.com',
597
601
  status: 'Inactive',
598
602
  actions: (
599
- <button onClick={() => toggleRow(2)}>
603
+ <ActionButton onClick={() => toggleRow(2)}>
600
604
  {expandedRows.has(2) ? 'Hide' : 'Show'}
601
- </button>
605
+ </ActionButton>
602
606
  ),
603
607
  _rowDetails: (
604
- <div>
608
+ <>
605
609
  <h3>Account Information</h3>
606
610
  <p><strong>Department:</strong> Sales</p>
607
611
  <p><strong>Position:</strong> Sales Director</p>
608
612
  <p><strong>Last Active:</strong> November 20, 2024</p>
609
613
  <p><strong>Reason:</strong> On extended leave</p>
610
614
  <div style={{ marginTop: '12px' }}>
611
- <button style={{ marginRight: '8px' }}>Reactivate Account</button>
612
- <button>Contact Employee</button>
615
+ <ActionButton style={{ marginRight: '8px' }}>Reactivate Account</ActionButton>
616
+ <ActionButton>Contact Employee</ActionButton>
613
617
  </div>
614
- </div>
618
+ </>
615
619
  )
616
620
  },
617
621
  ];
@@ -704,14 +708,17 @@ export const VNodeLabels: Story = {
704
708
  <strong>👤 User Name</strong>
705
709
  </span>
706
710
  ),
711
+ ariaLabel: 'User Name',
707
712
  },
708
713
  {
709
714
  key: 'email',
710
715
  label: <span style={{ color: '#0066cc' }}>📧 Email Address</span>,
716
+ ariaLabel: 'Email Address',
711
717
  },
712
718
  {
713
719
  key: 'role',
714
720
  label: <em style={{ color: '#666' }}>Role & Department</em>,
721
+ ariaLabel: 'Role & Department',
715
722
  },
716
723
  {
717
724
  key: 'status',
@@ -727,10 +734,12 @@ export const VNodeLabels: Story = {
727
734
  📊 Status
728
735
  </span>
729
736
  ),
737
+ ariaLabel: 'Status',
730
738
  },
731
739
  {
732
740
  key: 'actions',
733
741
  label: <span>⚙️ Actions</span>,
742
+ ariaLabel: 'Actions',
734
743
  },
735
744
  ],
736
745
  rowData: [
@@ -739,23 +748,277 @@ export const VNodeLabels: Story = {
739
748
  email: 'john.doe@company.com',
740
749
  role: 'Senior Developer',
741
750
  status: 'Active',
742
- actions: <button>Edit</button>,
751
+ actions: <ActionButton>Edit</ActionButton>,
743
752
  },
744
753
  {
745
754
  name: 'Jane Smith',
746
755
  email: 'jane.smith@company.com',
747
756
  role: 'Product Manager',
748
757
  status: 'Active',
749
- actions: <button>Edit</button>,
758
+ actions: <ActionButton>Edit</ActionButton>,
750
759
  },
751
760
  {
752
761
  name: 'Bob Johnson',
753
762
  email: 'bob.johnson@company.com',
754
763
  role: 'UX Designer',
755
764
  status: 'Inactive',
756
- actions: <button>Edit</button>,
765
+ actions: <ActionButton>Edit</ActionButton>,
757
766
  },
758
767
  ],
759
768
  },
760
769
  };
761
770
 
771
+ /**
772
+ * Table with pagination to navigate through multiple pages of data.
773
+ * This demonstrates how to integrate the Pagination component with the Table component.
774
+ *
775
+ * **Features**:
776
+ * - Pagination controls below the table
777
+ * - Page state management with useState
778
+ * - Dynamic row data based on current page
779
+ * - Items per page configuration
780
+ *
781
+ * ```tsx
782
+ * const [currentPage, setCurrentPage] = useState(1);
783
+ * const itemsPerPage = 5;
784
+ * const totalItems = 50;
785
+ * const totalPages = Math.ceil(totalItems / itemsPerPage);
786
+ *
787
+ * const paginatedData = allData.slice(
788
+ * (currentPage - 1) * itemsPerPage,
789
+ * currentPage * itemsPerPage
790
+ * );
791
+ *
792
+ * <div>
793
+ * <Table
794
+ * columns={columns}
795
+ * rowData={paginatedData}
796
+ * />
797
+ * <Pagination
798
+ * currentPage={currentPage}
799
+ * totalPages={totalPages}
800
+ * onChange={setCurrentPage}
801
+ * />
802
+ * </div>
803
+ * ```
804
+ */
805
+ export const WithPagination: Story = {
806
+ render: (args) => {
807
+ const [currentPage, setCurrentPage] = useState(1);
808
+ const [pageSize, setPageSize] = useState(5);
809
+
810
+ // Page size options
811
+ const pageSizeOptions: PickerOption[] = [
812
+ { value: '5', text: '5' },
813
+ { value: '10', text: '10' },
814
+ { value: '15', text: '15' },
815
+ ];
816
+
817
+ // Generate sample data (287 items to match screenshot)
818
+ const allData = Array.from({ length: 287 }, (_, index) => ({
819
+ id: index + 1,
820
+ name: `User ${index + 1}`,
821
+ email: `user${index + 1}@example.com`,
822
+ department: ['Engineering', 'Marketing', 'Sales', 'HR', 'Finance'][index % 5],
823
+ status: ['Active', 'Inactive', 'Pending'][index % 3],
824
+ actions: <ActionButton>Edit</ActionButton>,
825
+ }));
826
+
827
+ const totalPages = Math.ceil(allData.length / pageSize);
828
+
829
+ // Calculate item range
830
+ const startItem = (currentPage - 1) * pageSize + 1;
831
+ const endItem = Math.min(currentPage * pageSize, allData.length);
832
+ const totalItems = allData.length;
833
+
834
+ // Get current page data
835
+ const paginatedData = allData.slice(
836
+ (currentPage - 1) * pageSize,
837
+ currentPage * pageSize
838
+ );
839
+
840
+ // Handle page size change
841
+ const handlePageSizeChange = (event: Event) => {
842
+ const target = event.target as HTMLSelectElement;
843
+ const newPageSize = Number(target.value);
844
+ setPageSize(newPageSize);
845
+ setCurrentPage(1); // Reset to first page when page size changes
846
+ };
847
+
848
+ return (
849
+ <div>
850
+ <TableComponent
851
+ {...args}
852
+ columns={[
853
+ { key: 'id', label: 'ID' },
854
+ { key: 'name', label: 'Name' },
855
+ { key: 'email', label: 'Email' },
856
+ { key: 'department', label: 'Department' },
857
+ { key: 'status', label: 'Status' },
858
+ { key: 'actions', label: 'Actions' },
859
+ ]}
860
+ rowData={paginatedData}
861
+ />
862
+ <div style={{ marginTop: 'var(--spacing-small)', display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
863
+ <span style={{
864
+ font: 'var(--type-body-1-default-font)',
865
+ letterSpacing: 'var(--type-body-1-default-letter-spacing)',
866
+ color: 'var(--color-neutral-800)'
867
+ }}>
868
+ Items {startItem} to {endItem} of {totalItems} total
869
+ </span>
870
+ <Pagination
871
+ currentPage={currentPage}
872
+ totalPages={totalPages}
873
+ onChange={setCurrentPage}
874
+ />
875
+ <div style={{
876
+ display: 'flex',
877
+ alignItems: 'center',
878
+ gap: 'var(--spacing-xsmall)',
879
+ font: 'var(--type-body-1-default-font)',
880
+ letterSpacing: 'var(--type-body-1-default-letter-spacing)',
881
+ color: 'var(--color-neutral-800)'
882
+ }}>
883
+ <span>Show</span>
884
+ <Picker
885
+ variant="primary"
886
+ size="medium"
887
+ value={String(pageSize)}
888
+ options={pageSizeOptions}
889
+ handleSelect={handlePageSizeChange}
890
+ aria-label="Items per page"
891
+ />
892
+ </div>
893
+ </div>
894
+ </div>
895
+ );
896
+ },
897
+ };
898
+
899
+ /**
900
+ * Table with expandable row details and stacked mobile layout.
901
+ * Combines the expandable rows feature with responsive mobile behavior using container queries.
902
+ *
903
+ * **Features**:
904
+ * - Expandable rows with toggle buttons
905
+ * - Stacked mobile layout when container width ≤ 600px
906
+ * - Row details expand in both desktop and mobile views
907
+ * - Mobile view shows labels above each cell value
908
+ *
909
+ * ```tsx
910
+ * const [expandedRows, setExpandedRows] = useState(new Set());
911
+ *
912
+ * const toggleRow = (rowIndex: number) => {
913
+ * setExpandedRows(prev => {
914
+ * const newSet = new Set(prev);
915
+ * if (newSet.has(rowIndex)) {
916
+ * newSet.delete(rowIndex);
917
+ * } else {
918
+ * newSet.add(rowIndex);
919
+ * }
920
+ * return newSet;
921
+ * });
922
+ * };
923
+ *
924
+ * <Table
925
+ * mobileLayout="stacked"
926
+ * columns={columns}
927
+ * rowData={rowDataWithDetails}
928
+ * expandedRows={expandedRows}
929
+ * />
930
+ * ```
931
+ */
932
+ export const ExpandableRowsWithMobileLayout: Story = {
933
+ render: (args) => {
934
+ const [expandedRows, setExpandedRows] = useState(new Set<number>());
935
+
936
+ const toggleRow = (rowIndex: number) => {
937
+ setExpandedRows((prev) => {
938
+ const newSet = new Set(prev);
939
+ if (newSet.has(rowIndex)) {
940
+ newSet.delete(rowIndex);
941
+ } else {
942
+ newSet.add(rowIndex);
943
+ }
944
+ return newSet;
945
+ });
946
+ };
947
+
948
+ const rowData = [
949
+ {
950
+ name: 'John Doe',
951
+ email: 'john.doe@company.com',
952
+ status: 'Active',
953
+ actions: (
954
+ <ActionButton onClick={() => toggleRow(0)}>
955
+ {expandedRows.has(0) ? 'Hide' : 'Show'}
956
+ </ActionButton>
957
+ ),
958
+ _rowDetails: (
959
+ <>
960
+ <h3>Employee Details</h3>
961
+ <p><strong>Department:</strong> Engineering</p>
962
+ <p><strong>Position:</strong> Senior Developer</p>
963
+ <p><strong>Start Date:</strong> January 15, 2022</p>
964
+ <p><strong>Notes:</strong> Excellent performance, leads the frontend team.</p>
965
+ </>
966
+ )
967
+ },
968
+ {
969
+ name: 'Jane Smith',
970
+ email: 'jane.smith@company.com',
971
+ status: 'Pending',
972
+ actions: (
973
+ <ActionButton onClick={() => toggleRow(1)}>
974
+ {expandedRows.has(1) ? 'Hide' : 'Show'}
975
+ </ActionButton>
976
+ ),
977
+ _rowDetails: (
978
+ <>
979
+ <h3>Pending Approval</h3>
980
+ <p><strong>Department:</strong> Marketing</p>
981
+ <p><strong>Position:</strong> Marketing Manager</p>
982
+ <p><strong>Application Date:</strong> December 1, 2024</p>
983
+ <p><strong>Status:</strong> Awaiting HR approval</p>
984
+ </>
985
+ )
986
+ },
987
+ {
988
+ name: 'Bob Johnson',
989
+ email: 'bob.johnson@company.com',
990
+ status: 'Inactive',
991
+ actions: (
992
+ <ActionButton onClick={() => toggleRow(2)}>
993
+ {expandedRows.has(2) ? 'Hide' : 'Show'}
994
+ </ActionButton>
995
+ ),
996
+ _rowDetails: (
997
+ <>
998
+ <h3>Account Information</h3>
999
+ <p><strong>Department:</strong> Sales</p>
1000
+ <p><strong>Position:</strong> Sales Director</p>
1001
+ <p><strong>Last Active:</strong> November 20, 2024</p>
1002
+ <p><strong>Reason:</strong> On extended leave</p>
1003
+ </>
1004
+ )
1005
+ },
1006
+ ];
1007
+
1008
+ return (
1009
+ <TableComponent
1010
+ {...args}
1011
+ mobileLayout="stacked"
1012
+ columns={[
1013
+ { key: 'name', label: 'Name', ariaLabel: 'Name' },
1014
+ { key: 'email', label: 'Email', ariaLabel: 'Email' },
1015
+ { key: 'status', label: 'Status', ariaLabel: 'Status' },
1016
+ { key: 'actions', label: 'Actions', ariaLabel: 'Actions' },
1017
+ ]}
1018
+ rowData={rowData}
1019
+ expandedRows={expandedRows}
1020
+ />
1021
+ );
1022
+ },
1023
+ };
1024
+
@@ -97,7 +97,8 @@ export const Table: FunctionComponent<TableProps> = ({
97
97
  iconSource = 'ChevronDown';
98
98
  ariaLabel = translations.sortedDescending.replace('{label}', label);
99
99
  } else {
100
- iconSource = 'Sort';
100
+ // Show chevron down when sortable but not sorted
101
+ iconSource = 'ChevronDown';
101
102
  ariaLabel = translations.sortBy.replace('{label}', label);
102
103
  }
103
104
 
@@ -138,7 +139,10 @@ export const Table: FunctionComponent<TableProps> = ({
138
139
 
139
140
  return (
140
141
  <Fragment key={rowIndex}>
141
- <tr className="dropin-table__body__row">
142
+ <tr className={classes([
143
+ 'dropin-table__body__row',
144
+ ['dropin-table__body__row--expanded', isExpanded && hasDetails],
145
+ ])}>
142
146
  {columns.map((column) => {
143
147
  const cell = row[column.key];
144
148
  const label = column.ariaLabel ?? column.label;
@@ -0,0 +1,6 @@
1
+ <svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
2
+ <path vector-effect="non-scaling-stroke" d="M2.53833 11.606V18.4906C2.53833 19.0429 2.98604 19.4906 3.53833 19.4906H20.4614C21.0137 19.4906 21.4614 19.0429 21.4614 18.4906V11.606" stroke="currentColor" stroke-width="1"/>
3
+ <path vector-effect="non-scaling-stroke" d="M13.2813 13.3799L14.5625 13.1828L17.125 12.7886L21.4021 12.1306C21.8899 12.0555 22.25 11.6358 22.25 11.1422V8.66357C22.25 8.11129 21.8023 7.66357 21.25 7.66357H2.75C2.19772 7.66357 1.75 8.11129 1.75 8.66357V11.1422C1.75 11.6358 2.11011 12.0555 2.59794 12.1306L6.875 12.7886L9.4375 13.1828L10.7188 13.3799" stroke="currentColor" stroke-width="1"/>
4
+ <rect vector-effect="non-scaling-stroke" x="8.84619" y="4.50977" width="6.30769" height="3.15385" rx="1" stroke="currentColor" stroke-width="1"/>
5
+ <rect vector-effect="non-scaling-stroke" x="10.4231" y="12.394" width="3.15385" height="2.36538" rx="1" stroke="currentColor" stroke-width="1"/>
6
+ </svg>
@@ -1,3 +1,3 @@
1
1
  <svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
2
- <path d="M7.74512 9.87701L12.0001 14.132L16.2551 9.87701" stroke="currentColor" stroke-width="1.5" stroke-linecap="square" stroke-linejoin="round"/>
2
+ <path vector-effect="non-scaling-stroke" d="M7.74512 9.87701L12.0001 14.132L16.2551 9.87701" stroke="currentColor" stroke-width="1" stroke-linecap="square" stroke-linejoin="round"/>
3
3
  </svg>
@@ -1,3 +1,3 @@
1
1
  <svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
2
- <path d="M7.74512 14.132L12.0001 9.87701L16.2551 14.132" stroke="currentColor" stroke-width="1.5" stroke-linecap="square" stroke-linejoin="round"/>
2
+ <path d="M7.74512 14.132L12.0001 9.87701L16.2551 14.132" stroke="currentColor" stroke-width="1" stroke-linecap="square" stroke-linejoin="round"/>
3
3
  </svg>
@@ -1 +1,3 @@
1
- <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-edit-2"><path d="M17 3a2.828 2.828 0 1 1 4 4L7.5 20.5 2 22l1.5-5.5L17 3z"></path></svg>
1
+ <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1" stroke-linecap="round" stroke-linejoin="round" class="feather feather-edit-2">
2
+ <path d="M17 3a2.828 2.828 0 1 1 4 4L7.5 20.5 2 22l1.5-5.5L17 3z"></path>
3
+ </svg>
package/src/icons/Eye.svg CHANGED
@@ -1,3 +1,3 @@
1
1
  <svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
2
- <path d="M11.9952 8.05896C7.85898 8.04913 4.04561 10.1916 1.96743 13.6609C4.04561 17.14 7.86907 19.2629 11.9952 19.2629C16.1314 19.2727 19.9447 17.1302 22.0229 13.6609C20.0153 10.3096 16.2827 8.05896 11.9952 8.05896ZM11.9952 8.05896V4.73709M20.5097 11.027L23.2335 9.0221M16.8174 8.88451L18.4618 6.0737M3.48067 11.027L0.756836 9.03193M7.17298 8.89434L5.52859 6.08353M14.8401 13.6609C14.8401 15.1843 13.5689 16.4226 12.0053 16.4226C10.4416 16.4226 9.17045 15.1843 9.17045 13.6609C9.17045 12.1376 10.4416 10.8993 12.0053 10.8993C13.5689 10.8993 14.8401 12.1376 14.8401 13.6609Z" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
2
+ <path d="M11.9952 8.05896C7.85898 8.04913 4.04561 10.1916 1.96743 13.6609C4.04561 17.14 7.86907 19.2629 11.9952 19.2629C16.1314 19.2727 19.9447 17.1302 22.0229 13.6609C20.0153 10.3096 16.2827 8.05896 11.9952 8.05896ZM11.9952 8.05896V4.73709M20.5097 11.027L23.2335 9.0221M16.8174 8.88451L18.4618 6.0737M3.48067 11.027L0.756836 9.03193M7.17298 8.89434L5.52859 6.08353M14.8401 13.6609C14.8401 15.1843 13.5689 16.4226 12.0053 16.4226C10.4416 16.4226 9.17045 15.1843 9.17045 13.6609C9.17045 12.1376 10.4416 10.8993 12.0053 10.8993C13.5689 10.8993 14.8401 12.1376 14.8401 13.6609Z" stroke="currentColor" stroke-width="1" stroke-linecap="round" stroke-linejoin="round"/>
3
3
  </svg>
@@ -1,3 +1,3 @@
1
1
  <svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
2
- <path d="M17.11 18.12C19.13 17.16 20.85 15.62 22.02 13.67C20.01 10.32 16.28 8.07 11.99 8.07M11.99 8.07C11.09 8.07 10.21 8.17 9.35 8.36M11.99 8.07V4.75M20.5 11.03L23.22 9.03M16.81 8.89L18.45 6.08M3.47 11.03L0.75 9.03M11.3096 10.99C11.5296 10.94 11.7596 10.91 11.9996 10.91C13.5596 10.91 14.8296 12.15 14.8296 13.67C14.8296 14.05 14.7496 14.41 14.6096 14.74M11.9999 16.43C10.4399 16.43 9.16992 15.19 9.16992 13.67C9.16992 13.37 9.21992 13.09 9.30992 12.83M6.13996 9.60001C4.43996 10.57 2.98996 11.96 1.95996 13.67C4.03996 17.15 7.85996 19.27 11.99 19.27C12.57 19.27 13.15 19.23 13.71 19.14M20.4404 22.5L4.44043 2.5" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
2
+ <path vector-effect="non-scaling-stroke" d="M17.11 18.12C19.13 17.16 20.85 15.62 22.02 13.67C20.01 10.32 16.28 8.07 11.99 8.07M11.99 8.07C11.09 8.07 10.21 8.17 9.35 8.36M11.99 8.07V4.75M20.5 11.03L23.22 9.03M16.81 8.89L18.45 6.08M3.47 11.03L0.75 9.03M11.3096 10.99C11.5296 10.94 11.7596 10.91 11.9996 10.91C13.5596 10.91 14.8296 12.15 14.8296 13.67C14.8296 14.05 14.7496 14.41 14.6096 14.74M11.9999 16.43C10.4399 16.43 9.16992 15.19 9.16992 13.67C9.16992 13.37 9.21992 13.09 9.30992 12.83M6.13996 9.60001C4.43996 10.57 2.98996 11.96 1.95996 13.67C4.03996 17.15 7.85996 19.27 11.99 19.27C12.57 19.27 13.15 19.23 13.71 19.14M20.4404 22.5L4.44043 2.5" stroke="currentColor" stroke-width="1" stroke-linecap="round" stroke-linejoin="round"/>
3
3
  </svg>
@@ -1,3 +1,3 @@
1
1
  <svg width="20" height="23" viewBox="0 0 20 23" fill="none" xmlns="http://www.w3.org/2000/svg">
2
- <path d="M10 6L10 21.5M10 6H12.25C13.4926 6 14.5 4.99264 14.5 3.75C14.5 2.50736 13.4926 1.5 12.25 1.5C11.0074 1.5 10 2.50736 10 3.75M10 6V3.75M10 6H7.75C6.50736 6 5.5 4.99264 5.5 3.75C5.5 2.50736 6.50736 1.5 7.75 1.5C8.99264 1.5 10 2.50736 10 3.75M3.25 10.75H16.75C17.9926 10.75 19 9.74264 19 8.5C19 7.25736 17.9926 6.25 16.75 6.25H3.25C2.00736 6.25 1 7.25736 1 8.5C1 9.74264 2.00736 10.75 3.25 10.75ZM4.75 21.5H15.25C16.4926 21.5 17.5 20.4926 17.5 19.25V13.25C17.5 12.0074 16.4926 11 15.25 11H4.75C3.50736 11 2.5 12.0074 2.5 13.25V19.25C2.5 20.4926 3.50736 21.5 4.75 21.5Z" stroke="currentColor" stroke-width="1.5"/>
2
+ <path vector-effect="non-scaling-stroke" d="M10 6L10 21.5M10 6H12.25C13.4926 6 14.5 4.99264 14.5 3.75C14.5 2.50736 13.4926 1.5 12.25 1.5C11.0074 1.5 10 2.50736 10 3.75M10 6V3.75M10 6H7.75C6.50736 6 5.5 4.99264 5.5 3.75C5.5 2.50736 6.50736 1.5 7.75 1.5C8.99264 1.5 10 2.50736 10 3.75M3.25 10.75H16.75C17.9926 10.75 19 9.74264 19 8.5C19 7.25736 17.9926 6.25 16.75 6.25H3.25C2.00736 6.25 1 7.25736 1 8.5C1 9.74264 2.00736 10.75 3.25 10.75ZM4.75 21.5H15.25C16.4926 21.5 17.5 20.4926 17.5 19.25V13.25C17.5 12.0074 16.4926 11 15.25 11H4.75C3.50736 11 2.5 12.0074 2.5 13.25V19.25C2.5 20.4926 3.50736 21.5 4.75 21.5Z" stroke="currentColor" stroke-width="1"/>
3
3
  </svg>
@@ -1,3 +1,3 @@
1
1
  <svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
2
- <path d="M22 12.8571V6.75774C22 6.33761 21.5848 6 21.0884 6H2.91155C2.40614 6 2 6.34511 2 6.75774V12.8571M22 12.8571H2M22 12.8571V17.0049C22 17.5468 21.5939 18 21.0884 18H2.91155C2.41516 18 2 17.5567 2 17.0049V12.8571M5.18182 16.0886L8.64545 12.8229M8.64545 12.8229L12.1087 16.0886M8.64545 12.8229C8.64545 12.8229 8.09964 10.4743 7.56328 9.96857C7.02692 9.46286 6.15419 9.46286 5.61783 9.96857C5.08146 10.4743 5.08146 11.2971 5.61783 11.8029C6.15419 12.3086 8.64545 12.8229 8.64545 12.8229ZM8.64545 12.8229C8.64545 12.8229 11.1542 12.2914 11.6905 11.7857C12.2269 11.28 12.2269 10.4571 11.6905 9.95141C11.1542 9.4457 10.2814 9.4457 9.74507 9.95141C9.2087 10.4571 8.64545 12.8229 8.64545 12.8229ZM8.64506 17.2886V6.70286" stroke="currentColor" stroke-width="1" stroke-linecap="round"/>
2
+ <path vector-effect="non-scaling-stroke" d="M22 12.8571V6.75774C22 6.33761 21.5848 6 21.0884 6H2.91155C2.40614 6 2 6.34511 2 6.75774V12.8571M22 12.8571H2M22 12.8571V17.0049C22 17.5468 21.5939 18 21.0884 18H2.91155C2.41516 18 2 17.5567 2 17.0049V12.8571M5.18182 16.0886L8.64545 12.8229M8.64545 12.8229L12.1087 16.0886M8.64545 12.8229C8.64545 12.8229 8.09964 10.4743 7.56328 9.96857C7.02692 9.46286 6.15419 9.46286 5.61783 9.96857C5.08146 10.4743 5.08146 11.2971 5.61783 11.8029C6.15419 12.3086 8.64545 12.8229 8.64545 12.8229ZM8.64545 12.8229C8.64545 12.8229 11.1542 12.2914 11.6905 11.7857C12.2269 11.28 12.2269 10.4571 11.6905 9.95141C11.1542 9.4457 10.2814 9.4457 9.74507 9.95141C9.2087 10.4571 8.64545 12.8229 8.64545 12.8229ZM8.64506 17.2886V6.70286" stroke="currentColor" stroke-width="1" stroke-linecap="round"/>
3
3
  </svg>