@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
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@adobe-commerce/elsie",
3
- "version": "1.6.0-alpha7",
3
+ "version": "1.6.0-alpha77",
4
4
  "license": "SEE LICENSE IN LICENSE.md",
5
5
  "description": "Domain Package SDK",
6
6
  "engines": {
@@ -27,8 +27,8 @@
27
27
  },
28
28
  "devDependencies": {
29
29
  "@adobe-commerce/event-bus": "~1.0.1",
30
- "@adobe-commerce/fetch-graphql": "~1.2.0",
31
- "@adobe-commerce/recaptcha": "~1.0.2",
30
+ "@adobe-commerce/fetch-graphql": "1.2.3-beta2",
31
+ "@adobe-commerce/recaptcha": "1.0.3-beta2",
32
32
  "@adobe-commerce/storefront-design": "~1.0.0",
33
33
  "@dropins/build-tools": "~1.0.1",
34
34
  "preact": "~10.22.1",
@@ -58,7 +58,6 @@
58
58
  "@storybook/preact": "^8.2.3",
59
59
  "@storybook/preact-vite": "^8.2.3",
60
60
  "@storybook/preact-webpack5": "^8.2.3",
61
- "@storybook/storybook-deployer": "^2.8.16",
62
61
  "@storybook/test": "^8.2.3",
63
62
  "@storybook/test-runner": "^0.19.1",
64
63
  "@storybook/theming": "^8.2.3",
@@ -2,25 +2,29 @@
2
2
  * Copyright 2024 Adobe
3
3
  * All Rights Reserved.
4
4
  *
5
- * NOTICE: Adobe permits you to use, modify, and distribute this
6
- * file in accordance with the terms of the Adobe license agreement
7
- * accompanying it.
5
+ * NOTICE: Adobe permits you to use, modify, and distribute this
6
+ * file in accordance with the terms of the Adobe license agreement
7
+ * accompanying it.
8
8
  *******************************************************************/
9
9
 
10
10
  /* https://cssguidelin.es/#bem-like-naming */
11
11
 
12
- .dropin-icon--shape-stroke-1 {
12
+ svg.dropin-icon--shape-stroke-1,
13
+ svg.dropin-icon--shape-stroke-1 * {
13
14
  stroke-width: var(--shape-icon-stroke-1);
14
15
  }
15
16
 
16
- .dropin-icon--shape-stroke-2 {
17
+ svg.dropin-icon--shape-stroke-2,
18
+ svg.dropin-icon--shape-stroke-2 * {
17
19
  stroke-width: var(--shape-icon-stroke-2);
18
20
  }
19
21
 
20
- .dropin-icon--shape-stroke-3 {
22
+ svg.dropin-icon--shape-stroke-3,
23
+ svg.dropin-icon--shape-stroke-3 * {
21
24
  stroke-width: var(--shape-icon-stroke-3);
22
25
  }
23
26
 
24
- .dropin-icon--shape-stroke-4 {
27
+ svg.dropin-icon--shape-stroke-4,
28
+ svg.dropin-icon--shape-stroke-4 * {
25
29
  stroke-width: var(--shape-icon-stroke-4);
26
30
  }
@@ -18,52 +18,58 @@ export type IconType = keyof typeof import('@adobe-commerce/elsie/icons');
18
18
 
19
19
  const lazyIcons = {
20
20
  Add: lazy(() => import('@adobe-commerce/elsie/icons/Add.svg')),
21
+ AddressBook: lazy(() => import('@adobe-commerce/elsie/icons/AddressBook.svg')),
21
22
  Bulk: lazy(() => import('@adobe-commerce/elsie/icons/Bulk.svg')),
22
23
  Burger: lazy(() => import('@adobe-commerce/elsie/icons/Burger.svg')),
24
+ Business: lazy(() => import('@adobe-commerce/elsie/icons/Business.svg')),
25
+ Card: lazy(() => import('@adobe-commerce/elsie/icons/Card.svg')),
23
26
  Cart: lazy(() => import('@adobe-commerce/elsie/icons/Cart.svg')),
24
27
  Check: lazy(() => import('@adobe-commerce/elsie/icons/Check.svg')),
28
+ CheckWithCircle: lazy(() => import('@adobe-commerce/elsie/icons/CheckWithCircle.svg')),
25
29
  ChevronDown: lazy(() => import('@adobe-commerce/elsie/icons/ChevronDown.svg')),
26
- ChevronUp: lazy(() => import('@adobe-commerce/elsie/icons/ChevronUp.svg')),
27
30
  ChevronRight: lazy(() => import('@adobe-commerce/elsie/icons/ChevronRight.svg')),
31
+ ChevronUp: lazy(() => import('@adobe-commerce/elsie/icons/ChevronUp.svg')),
28
32
  Close: lazy(() => import('@adobe-commerce/elsie/icons/Close.svg')),
33
+ Coupon: lazy(() => import('@adobe-commerce/elsie/icons/Coupon.svg')),
34
+ Date: lazy(() => import('@adobe-commerce/elsie/icons/Date.svg')),
35
+ Delivery: lazy(() => import('@adobe-commerce/elsie/icons/Delivery.svg')),
36
+ Edit: lazy(() => import('@adobe-commerce/elsie/icons/Edit.svg')),
37
+ EmptyBox: lazy(() => import('@adobe-commerce/elsie/icons/EmptyBox.svg')),
38
+ Eye: lazy(() => import('@adobe-commerce/elsie/icons/Eye.svg')),
39
+ EyeClose: lazy(() => import('@adobe-commerce/elsie/icons/EyeClose.svg')),
40
+ Gift: lazy(() => import('@adobe-commerce/elsie/icons/Gift.svg')),
41
+ GiftCard: lazy(() => import('@adobe-commerce/elsie/icons/GiftCard.svg')),
29
42
  Heart: lazy(() => import('@adobe-commerce/elsie/icons/Heart.svg')),
43
+ HeartFilled: lazy(() => import('@adobe-commerce/elsie/icons/HeartFilled.svg')),
44
+ InfoFilled: lazy(() => import('@adobe-commerce/elsie/icons/InfoFilled.svg')),
45
+ List: lazy(() => import('@adobe-commerce/elsie/icons/List.svg')),
46
+ Locker: lazy(() => import('@adobe-commerce/elsie/icons/Locker.svg')),
30
47
  Minus: lazy(() => import('@adobe-commerce/elsie/icons/Minus.svg')),
48
+ Order: lazy(() => import('@adobe-commerce/elsie/icons/Order.svg')),
49
+ OrderError: lazy(() => import('@adobe-commerce/elsie/icons/OrderError.svg')),
50
+ OrderSuccess: lazy(() => import('@adobe-commerce/elsie/icons/OrderSuccess.svg')),
51
+ PaymentError: lazy(() => import('@adobe-commerce/elsie/icons/PaymentError.svg')),
31
52
  Placeholder: lazy(() => import('@adobe-commerce/elsie/icons/Placeholder.svg')),
32
53
  PlaceholderFilled: lazy(
33
54
  () => import('@adobe-commerce/elsie/icons/PlaceholderFilled.svg')
34
55
  ),
56
+ Purchase: lazy(() => import('@adobe-commerce/elsie/icons/Purchase.svg')),
57
+ Quote: lazy(() => import('@adobe-commerce/elsie/icons/Quote.svg')),
35
58
  Search: lazy(() => import('@adobe-commerce/elsie/icons/Search.svg')),
36
59
  SearchFilled: lazy(() => import('@adobe-commerce/elsie/icons/SearchFilled.svg')),
37
60
  Sort: lazy(() => import('@adobe-commerce/elsie/icons/Sort.svg')),
38
61
  Star: lazy(() => import('@adobe-commerce/elsie/icons/Star.svg')),
39
- View: lazy(() => import('@adobe-commerce/elsie/icons/View.svg')),
62
+ Structure: lazy(() => import('@adobe-commerce/elsie/icons/Structure.svg')),
63
+ Team: lazy(() => import('@adobe-commerce/elsie/icons/Team.svg')),
64
+ Trash: lazy(() => import('@adobe-commerce/elsie/icons/Trash.svg')),
40
65
  User: lazy(() => import('@adobe-commerce/elsie/icons/User.svg')),
41
- Warning: lazy(() => import('@adobe-commerce/elsie/icons/Warning.svg')),
42
- Locker: lazy(() => import('@adobe-commerce/elsie/icons/Locker.svg')),
66
+ View: lazy(() => import('@adobe-commerce/elsie/icons/View.svg')),
43
67
  Wallet: lazy(() => import('@adobe-commerce/elsie/icons/Wallet.svg')),
44
- Card: lazy(() => import('@adobe-commerce/elsie/icons/Card.svg')),
45
- Order: lazy(() => import('@adobe-commerce/elsie/icons/Order.svg')),
46
- Delivery: lazy(() => import('@adobe-commerce/elsie/icons/Delivery.svg')),
47
- OrderError: lazy(() => import('@adobe-commerce/elsie/icons/OrderError.svg')),
48
- OrderSuccess: lazy(() => import('@adobe-commerce/elsie/icons/OrderSuccess.svg')),
49
- PaymentError: lazy(() => import('@adobe-commerce/elsie/icons/PaymentError.svg')),
50
- CheckWithCircle: lazy(() => import('@adobe-commerce/elsie/icons/CheckWithCircle.svg')),
68
+ Warning: lazy(() => import('@adobe-commerce/elsie/icons/Warning.svg')),
69
+ WarningFilled: lazy(() => import('@adobe-commerce/elsie/icons/WarningFilled.svg')),
51
70
  WarningWithCircle: lazy(
52
71
  () => import('@adobe-commerce/elsie/icons/WarningWithCircle.svg')
53
72
  ),
54
- WarningFilled: lazy(() => import('@adobe-commerce/elsie/icons/WarningFilled.svg')),
55
- InfoFilled: lazy(() => import('@adobe-commerce/elsie/icons/InfoFilled.svg')),
56
- HeartFilled: lazy(() => import('@adobe-commerce/elsie/icons/HeartFilled.svg')),
57
- Trash: lazy(() => import('@adobe-commerce/elsie/icons/Trash.svg')),
58
- Eye: lazy(() => import('@adobe-commerce/elsie/icons/Eye.svg')),
59
- EyeClose: lazy(() => import('@adobe-commerce/elsie/icons/EyeClose.svg')),
60
- Date: lazy(() => import('@adobe-commerce/elsie/icons/Date.svg')),
61
- AddressBook: lazy(() => import('@adobe-commerce/elsie/icons/AddressBook.svg')),
62
- EmptyBox: lazy(() => import('@adobe-commerce/elsie/icons/EmptyBox.svg')),
63
- Coupon: lazy(() => import('@adobe-commerce/elsie/icons/Coupon.svg')),
64
- Gift: lazy(() => import('@adobe-commerce/elsie/icons/Gift.svg')),
65
- GiftCard: lazy(() => import('@adobe-commerce/elsie/icons/GiftCard.svg')),
66
- Edit: lazy(() => import('@adobe-commerce/elsie/icons/Edit.svg')),
67
73
  };
68
74
 
69
75
  export interface IconProps extends Omit<SVGProps<SVGSVGElement>, 'size'> {
@@ -8,7 +8,7 @@
8
8
  *******************************************************************/
9
9
 
10
10
  import type { Meta, StoryObj } from '@storybook/preact';
11
- import { expect, userEvent, within } from '@storybook/test';
11
+ import { expect, userEvent, waitFor, within } from '@storybook/test';
12
12
  import {
13
13
  MultiSelect,
14
14
  type MultiSelectProps,
@@ -430,11 +430,13 @@ export const BulkSelectionActions = {
430
430
  const selectAllButton = canvas.getByTestId('multi-select-select-all');
431
431
  await userEvent.click(selectAllButton);
432
432
 
433
- // All options should now be selected - check tags appear in the tags area
433
+ // Wait for all options to be selected - check tags appear in the tags area
434
434
  const tagsArea = canvas.getByTestId('multi-select-tags-area');
435
- await expect(tagsArea).toHaveTextContent('Option 1');
436
- await expect(tagsArea).toHaveTextContent('Option 2');
437
- await expect(tagsArea).toHaveTextContent('Option 10');
435
+ await waitFor(async () => {
436
+ await expect(tagsArea).toHaveTextContent('Option 1');
437
+ await expect(tagsArea).toHaveTextContent('Option 2');
438
+ await expect(tagsArea).toHaveTextContent('Option 10');
439
+ });
438
440
 
439
441
  // Deselect All should now be enabled
440
442
  await expect(deselectAllButton).not.toBeDisabled();
@@ -64,7 +64,8 @@
64
64
  align-items: center;
65
65
  }
66
66
 
67
- .dropin-pagination_list-item button {
67
+ .dropin-pagination_list-item button,
68
+ .dropin-pagination_list-item a {
68
69
  cursor: pointer;
69
70
  margin: 0;
70
71
  padding: 0;
@@ -72,24 +73,32 @@
72
73
  border: none;
73
74
  font: var(--type-details-caption-1-font);
74
75
  letter-spacing: var(--type-details-caption-1-letter-spacing);
76
+ text-decoration: none;
75
77
  }
76
78
 
77
- .dropin-pagination_list-item--active button {
79
+ .dropin-pagination_list-item--active button,
80
+ .dropin-pagination_list-item--active a {
78
81
  cursor: default;
79
82
  }
80
83
 
81
84
  .dropin-pagination_list-item--active button:disabled,
82
85
  .dropin-pagination_list-item--ellipsis button,
86
+ .dropin-pagination_list-item--ellipsis a,
83
87
  .dropin-pagination-arrow--backward:disabled,
84
- .dropin-pagination-arrow--forward:disabled {
88
+ .dropin-pagination-arrow--forward:disabled,
89
+ .dropin-pagination-arrow--disabled {
85
90
  cursor: default;
91
+ opacity: 0.5;
92
+ pointer-events: none;
86
93
  }
87
94
 
88
- .dropin-pagination button:not(:disabled) {
95
+ .dropin-pagination button:not(:disabled),
96
+ .dropin-pagination a:not([aria-disabled="true"]) {
89
97
  color: var(--color-neutral-800);
90
98
  }
91
99
 
92
- .dropin-pagination button {
100
+ .dropin-pagination button,
101
+ .dropin-pagination a {
93
102
  appearance: none;
94
103
  -webkit-appearance: none;
95
104
  }
@@ -2,9 +2,9 @@
2
2
  * Copyright 2024 Adobe
3
3
  * All Rights Reserved.
4
4
  *
5
- * NOTICE: Adobe permits you to use, modify, and distribute this
6
- * file in accordance with the terms of the Adobe license agreement
7
- * accompanying it.
5
+ * NOTICE: Adobe permits you to use, modify, and distribute this
6
+ * file in accordance with the terms of the Adobe license agreement
7
+ * accompanying it.
8
8
  *******************************************************************/
9
9
 
10
10
  // https://storybook.js.org/docs/7.0/preact/writing-stories/introduction
@@ -16,6 +16,8 @@ import {
16
16
  } from '@adobe-commerce/elsie/components/Pagination';
17
17
  import { expect, userEvent, within } from '@storybook/test';
18
18
  import { useState } from 'preact/hooks';
19
+ import { action } from '@storybook/addon-actions';
20
+
19
21
 
20
22
  /**
21
23
  * A component that divides large content sets into multiple pages, allowing users to navigate through the data with controls like "Next," "Previous," or page numbers, enhancing performance and usability by limiting the number of items displayed per page.
@@ -40,6 +42,10 @@ const meta: Meta<PaginationProps> = {
40
42
  description:
41
43
  'Called when the page number is changed, and it takes the resulting page number.',
42
44
  },
45
+ routePage: {
46
+ description:
47
+ 'Optional function that generates hrefs for each page. When provided, pagination will render anchor tags instead of buttons, enabling proper SEO and link behavior.',
48
+ },
43
49
  },
44
50
  };
45
51
 
@@ -115,3 +121,26 @@ export const LongPagination: Story = {
115
121
  );
116
122
  },
117
123
  };
124
+
125
+ export const WithAnchors: Story = {
126
+ name: 'As anchor tags',
127
+ render: () => {
128
+ const [currentPage, setCurrentPage] = useState(1);
129
+ const totalPages = 10;
130
+
131
+ const handlePageChange = (newPage: number, e?: Event) => {
132
+ e?.preventDefault();
133
+ setCurrentPage(newPage);
134
+ action('pageChanged')(newPage, e);
135
+ };
136
+
137
+ return (
138
+ <Pagination
139
+ totalPages={totalPages}
140
+ currentPage={currentPage}
141
+ onChange={handlePageChange}
142
+ routePage={(page) => `?page=${page}`}
143
+ />
144
+ );
145
+ },
146
+ };
@@ -2,9 +2,9 @@
2
2
  * Copyright 2024 Adobe
3
3
  * All Rights Reserved.
4
4
  *
5
- * NOTICE: Adobe permits you to use, modify, and distribute this
6
- * file in accordance with the terms of the Adobe license agreement
7
- * accompanying it.
5
+ * NOTICE: Adobe permits you to use, modify, and distribute this
6
+ * file in accordance with the terms of the Adobe license agreement
7
+ * accompanying it.
8
8
  *******************************************************************/
9
9
 
10
10
  import { FunctionComponent } from 'preact';
@@ -14,12 +14,14 @@ import { ChevronDown } from '@adobe-commerce/elsie/icons';
14
14
  import { Icon } from '@adobe-commerce/elsie/components/Icon';
15
15
  import { useText } from '@adobe-commerce/elsie/i18n';
16
16
  import '@adobe-commerce/elsie/components/Pagination/Pagination.css';
17
+ import { PaginationButton } from './PaginationButton';
17
18
 
18
19
  export interface PaginationProps {
19
20
  className?: string;
20
21
  currentPage?: number;
21
22
  totalPages?: number;
22
- onChange?: (currentPage: number) => void;
23
+ onChange?: (currentPage: number, e?: Event) => void;
24
+ routePage?: (page: number) => string;
23
25
  }
24
26
 
25
27
  export type PaginationList = {
@@ -32,6 +34,7 @@ export const Pagination: FunctionComponent<PaginationProps> = ({
32
34
  totalPages = 10,
33
35
  currentPage = 1,
34
36
  onChange,
37
+ routePage,
35
38
  className,
36
39
  ...props
37
40
  }) => {
@@ -40,22 +43,22 @@ export const Pagination: FunctionComponent<PaginationProps> = ({
40
43
  forwardButton: 'Dropin.Pagination.forwardButton.ariaLabel',
41
44
  });
42
45
 
43
- const handleForward = useCallback(() => {
46
+ const handleForward = useCallback((e?: Event) => {
44
47
  const nextPage = Math.min(currentPage + 1, totalPages);
45
48
 
46
- onChange?.(nextPage);
49
+ onChange?.(nextPage, e);
47
50
  }, [currentPage, onChange, totalPages]);
48
51
 
49
- const handleBackward = useCallback(() => {
52
+ const handleBackward = useCallback((e?: Event) => {
50
53
  const prevPage = Math.max(currentPage - 1, 1);
51
54
 
52
- onChange?.(prevPage);
55
+ onChange?.(prevPage, e);
53
56
  }, [currentPage, onChange]);
54
57
 
55
58
  const handleSetPage = useCallback(
56
- (currentPage: number | string) => {
59
+ (currentPage: number | string, e?: Event) => {
57
60
  if (isNumber(currentPage)) {
58
- onChange?.(currentPage as number);
61
+ onChange?.(currentPage as number, e);
59
62
  }
60
63
  },
61
64
  [onChange]
@@ -97,19 +100,20 @@ export const Pagination: FunctionComponent<PaginationProps> = ({
97
100
 
98
101
  return (
99
102
  <div {...props} className={classes(['dropin-pagination', className])}>
100
- <button
101
- type="button"
103
+ <PaginationButton
102
104
  data-testid="prev-button"
103
105
  aria-label={translations.backwardButton}
104
106
  disabled={currentPage === 1}
105
- onClick={handleBackward}
107
+ onClick={(e: Event) => handleBackward(e)}
108
+ href={routePage?.(currentPage) ?? undefined}
106
109
  className={classes([
107
110
  'dropin-pagination-arrow',
108
111
  'dropin-pagination-arrow--backward',
112
+ ['dropin-pagination-arrow--disabled', currentPage === 1],
109
113
  ])}
110
114
  >
111
115
  <Icon size="24" source={ChevronDown} />
112
- </button>
116
+ </PaginationButton>
113
117
  <ul className="dropin-pagination_list">
114
118
  {(paginationList as PaginationList[]).map((item, index) => (
115
119
  <li
@@ -121,29 +125,31 @@ export const Pagination: FunctionComponent<PaginationProps> = ({
121
125
  [`dropin-pagination_list-item--active`, item.isActive],
122
126
  ])}
123
127
  >
124
- <button
125
- type="button"
128
+ <PaginationButton
126
129
  data-testid={`set-page-button-${item.page}`}
127
- onClick={() => handleSetPage(item.page)}
130
+ onClick={(e: Event) => handleSetPage(item.page, e)}
131
+ href={routePage?.(item.page as number) ?? undefined}
132
+
128
133
  >
129
134
  {item.label}
130
- </button>
135
+ </PaginationButton>
131
136
  </li>
132
137
  ))}
133
138
  </ul>
134
- <button
135
- type="button"
139
+ <PaginationButton
136
140
  data-testid="next-button"
137
141
  aria-label={translations.forwardButton}
138
142
  disabled={currentPage === totalPages}
139
- onClick={handleForward}
143
+ onClick={(e: Event) => handleForward(e)}
144
+ href={routePage?.(currentPage) ?? undefined}
140
145
  className={classes([
141
146
  'dropin-pagination-arrow',
142
147
  'dropin-pagination-arrow--forward',
148
+ ['dropin-pagination-arrow--disabled', currentPage === totalPages],
143
149
  ])}
144
150
  >
145
151
  <Icon size="24" source={ChevronDown} />
146
- </button>
152
+ </PaginationButton>
147
153
  </div>
148
154
  );
149
155
  };
@@ -0,0 +1,46 @@
1
+ /********************************************************************
2
+ * Copyright 2024 Adobe
3
+ * All Rights Reserved.
4
+ *
5
+ * NOTICE: Adobe permits you to use, modify, and distribute this
6
+ * file in accordance with the terms of the Adobe license agreement
7
+ * accompanying it.
8
+ *******************************************************************/
9
+
10
+ import { FunctionComponent, JSX } from 'preact';
11
+
12
+ type BaseProps = {
13
+ href?: string;
14
+ type?: 'button';
15
+ disabled?: boolean;
16
+ };
17
+
18
+ export type PaginationButtonProps = BaseProps &
19
+ (
20
+ | Omit<JSX.HTMLAttributes<HTMLAnchorElement>, 'type'>
21
+ | Omit<JSX.HTMLAttributes<HTMLButtonElement>, 'href'>
22
+ );
23
+
24
+ export const PaginationButton: FunctionComponent<PaginationButtonProps> = (
25
+ props
26
+ ) => {
27
+ if (props.href) {
28
+
29
+ const { href, disabled, ...anchorProps } = props;
30
+ return (
31
+ <a
32
+ href={href}
33
+ aria-disabled={disabled}
34
+ {...(anchorProps as JSX.HTMLAttributes<HTMLAnchorElement>)}
35
+ />
36
+ );
37
+ }
38
+
39
+ const { type = 'button', ...buttonProps } = props;
40
+ return (
41
+ <button
42
+ type={type}
43
+ {...(buttonProps as JSX.HTMLAttributes<HTMLButtonElement>)}
44
+ />
45
+ );
46
+ };
@@ -17,6 +17,7 @@
17
17
  }
18
18
 
19
19
  .dropin-table__table {
20
+ border: var(--shape-border-width-1) solid var(--color-neutral-400);
20
21
  border-collapse: collapse;
21
22
  width: 100%;
22
23
  }
@@ -34,9 +35,8 @@
34
35
  letter-spacing: var(--type-body-1-strong-letter-spacing);
35
36
  }
36
37
 
37
- .dropin-table__header__cell,
38
- .dropin-table__body__cell {
39
- padding: var(--spacing-xsmall);
38
+ .dropin-table__header__cell {
39
+ color: var(--color-neutral-800);
40
40
  text-align: left;
41
41
  white-space: nowrap;
42
42
  }
@@ -46,15 +46,26 @@
46
46
  }
47
47
 
48
48
  .dropin-table__header__row {
49
- border-bottom: 2px solid var(--color-neutral-400);
49
+ border-bottom: var(--shape-border-width-1) solid var(--color-neutral-400);
50
+ }
51
+
52
+ .dropin-table__header__row th {
53
+ padding: var(--spacing-small) var(--spacing-medium);
54
+ }
55
+
56
+ .dropin-table__body__row:nth-child(even) {
57
+ background-color: var(--color-neutral-100);
58
+ }
59
+
60
+ .dropin-table__body__row.dropin-table__body__row--expanded {
61
+ background-color: var(--color-neutral-200);
50
62
  }
51
63
 
52
- .dropin-table__body__row {
53
- border-bottom: 1px solid var(--color-neutral-400);
64
+ .dropin-table__body__cell {
65
+ padding: var(--spacing-small) var(--spacing-medium);
54
66
  }
55
67
 
56
68
  .dropin-table__header__sort-button {
57
- margin-left: var(--spacing-xsmall);
58
69
  vertical-align: middle;
59
70
  }
60
71
 
@@ -67,10 +78,29 @@
67
78
  }
68
79
 
69
80
  .dropin-table__row-details__cell {
70
- padding: var(--spacing-small);
71
- background-color: var(--color-neutral-100);
72
- border-top: 1px solid var(--color-neutral-300);
73
- border-bottom: 1px solid var(--color-neutral-400);
81
+ padding: var(--spacing-small) var(--spacing-medium);
82
+ background-color: var(--color-neutral-200);
83
+ }
84
+
85
+ .dropin-table__row-details--expanded .dropin-table__row-details__cell > *:last-child {
86
+ margin: 0;
87
+ }
88
+
89
+ .dropin-table__row-details__cell h1,
90
+ .dropin-table__row-details__cell h2,
91
+ .dropin-table__row-details__cell h3,
92
+ .dropin-table__row-details__cell h4,
93
+ .dropin-table__row-details__cell h5,
94
+ .dropin-table__row-details__cell h6 {
95
+ font: var(--type-body-1-strong-font);
96
+ letter-spacing: var(--type-body-1-strong-letter-spacing);
97
+ margin: 0;
98
+ }
99
+
100
+ .dropin-table__row-details__cell p,
101
+ .dropin-table__row-details__cell span {
102
+ font: var(--type-body-1-default-font);
103
+ letter-spacing: var(--type-body-1-default-letter-spacing);
74
104
  }
75
105
 
76
106
  /* Container query for mobile layout */
@@ -80,20 +110,63 @@
80
110
  display: none;
81
111
  }
82
112
 
113
+ .dropin-table--mobile-layout-stacked .dropin-table__body__row {
114
+ padding: var(--spacing-medium);
115
+ display: block;
116
+ }
117
+
83
118
  .dropin-table--mobile-layout-stacked .dropin-table__body__cell {
84
119
  display: block;
120
+ font: var(--type-body-2-default-font);
121
+ letter-spacing: var(--type-body-2-default-letter-spacing);
122
+ padding: var(--spacing-xsmall) 0;
123
+ }
124
+
125
+ .dropin-table--mobile-layout-stacked .dropin-table__body__cell:first-child {
126
+ padding-top: 0;
127
+ }
128
+
129
+ .dropin-table--mobile-layout-stacked .dropin-table__body__cell:last-child {
130
+ padding-bottom: 0;
85
131
  }
86
132
 
87
133
  .dropin-table--mobile-layout-stacked .dropin-table__body__cell::before {
88
134
  content: attr(data-label);
89
- font-weight: bold;
135
+ font: var(--type-body-2-strong-font);
136
+ letter-spacing: var(--type-body-2-strong-letter-spacing);
90
137
  display: block;
91
138
  margin-bottom: var(--spacing-xxsmall);
92
139
  }
93
140
 
94
141
  .dropin-table--mobile-layout-stacked .dropin-table__row-details__cell {
95
142
  display: block;
96
- padding: var(--spacing-small);
143
+ padding: var(--spacing-medium);
144
+ }
145
+
146
+ .dropin-table--mobile-layout-stacked .dropin-table__row-details__cell > *:first-child {
147
+ border-top: var(--shape-border-width-1) solid var(--color-neutral-400);
148
+ padding-top: var(--spacing-medium);
149
+ margin-top: calc(var(--spacing-medium) * -1);
150
+ }
151
+
152
+ .dropin-table--mobile-layout-stacked .dropin-table__row-details--expanded .dropin-table__row-details__cell > *:last-child {
153
+ margin: 0;
154
+ }
155
+
156
+ .dropin-table--mobile-layout-stacked .dropin-table__row-details__cell h1,
157
+ .dropin-table--mobile-layout-stacked .dropin-table__row-details__cell h2,
158
+ .dropin-table--mobile-layout-stacked .dropin-table__row-details__cell h3,
159
+ .dropin-table--mobile-layout-stacked .dropin-table__row-details__cell h4,
160
+ .dropin-table--mobile-layout-stacked .dropin-table__row-details__cell h5,
161
+ .dropin-table--mobile-layout-stacked .dropin-table__row-details__cell h6 {
162
+ font: var(--type-body-2-strong-font);
163
+ letter-spacing: var(--type-body-2-strong-letter-spacing);
164
+ }
165
+
166
+ .dropin-table--mobile-layout-stacked .dropin-table__row-details__cell p,
167
+ .dropin-table--mobile-layout-stacked .dropin-table__row-details__cell span {
168
+ font: var(--type-body-2-default-font);
169
+ letter-spacing: var(--type-body-2-default-letter-spacing);
97
170
  }
98
171
  }
99
172