@transferwise/components 0.0.0-experimental-6d7ebae → 0.0.0-experimental-a087360

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 (48) hide show
  1. package/build/index.esm.js +47 -59
  2. package/build/index.esm.js.map +1 -1
  3. package/build/index.js +47 -59
  4. package/build/index.js.map +1 -1
  5. package/build/main.css +1 -1
  6. package/build/styles/flowNavigation/FlowNavigation.css +1 -1
  7. package/build/styles/flowNavigation/animatedLabel/AnimatedLabel.css +1 -1
  8. package/build/styles/inputs/SelectInput.css +1 -1
  9. package/build/styles/main.css +1 -1
  10. package/build/styles/overlayHeader/OverlayHeader.css +1 -1
  11. package/build/types/common/flowHeader/FlowHeader.d.ts.map +1 -1
  12. package/build/types/flowNavigation/FlowNavigation.d.ts.map +1 -1
  13. package/build/types/flowNavigation/animatedLabel/AnimatedLabel.d.ts +1 -2
  14. package/build/types/flowNavigation/animatedLabel/AnimatedLabel.d.ts.map +1 -1
  15. package/build/types/flowNavigation/backButton/BackButton.d.ts +10 -11
  16. package/build/types/flowNavigation/backButton/BackButton.d.ts.map +1 -1
  17. package/build/types/inputs/SelectInput.d.ts +1 -2
  18. package/build/types/inputs/SelectInput.d.ts.map +1 -1
  19. package/build/types/overlayHeader/OverlayHeader.d.ts.map +1 -1
  20. package/package.json +1 -1
  21. package/src/common/flowHeader/FlowHeader.tsx +4 -22
  22. package/src/common/flowHeader/__snapshots__/FlowHeader.spec.js.snap +6 -22
  23. package/src/flowNavigation/FlowNavigation.css +1 -1
  24. package/src/flowNavigation/FlowNavigation.less +0 -9
  25. package/src/flowNavigation/FlowNavigation.spec.js +3 -3
  26. package/src/flowNavigation/FlowNavigation.story.js +22 -189
  27. package/src/flowNavigation/FlowNavigation.tsx +22 -27
  28. package/src/flowNavigation/__snapshots__/FlowNavigation.spec.js.snap +18 -26
  29. package/src/flowNavigation/animatedLabel/AnimatedLabel.css +1 -1
  30. package/src/flowNavigation/animatedLabel/AnimatedLabel.less +0 -6
  31. package/src/flowNavigation/animatedLabel/AnimatedLabel.spec.js +7 -21
  32. package/src/flowNavigation/animatedLabel/AnimatedLabel.tsx +8 -17
  33. package/src/flowNavigation/animatedLabel/__snapshots__/AnimatedLabel.spec.js.snap +4 -4
  34. package/src/flowNavigation/backButton/BackButton.js +14 -9
  35. package/src/flowNavigation/backButton/BackButton.spec.js +3 -2
  36. package/src/flowNavigation/backButton/__snapshots__/BackButton.spec.js.snap +28 -21
  37. package/src/inputs/SelectInput.css +1 -1
  38. package/src/inputs/SelectInput.less +0 -4
  39. package/src/inputs/SelectInput.spec.tsx +0 -40
  40. package/src/inputs/SelectInput.story.tsx +0 -18
  41. package/src/inputs/SelectInput.tsx +3 -14
  42. package/src/main.css +1 -1
  43. package/src/overlayHeader/OverlayHeader.css +1 -1
  44. package/src/overlayHeader/OverlayHeader.js +6 -4
  45. package/src/overlayHeader/OverlayHeader.less +0 -8
  46. package/src/overlayHeader/OverlayHeader.spec.js +1 -1
  47. package/src/overlayHeader/__snapshots__/OverlayHeader.spec.js.snap +10 -14
  48. package/src/flowNavigation/animatedLabel/AnimatedLabel.story.js +0 -22
@@ -6,23 +6,19 @@ exports[`FlowNavigation on mobile renders as expected 1`] = `
6
6
  class="np-flow-navigation d-flex align-items-center justify-content-center p-y-3 np-flow-navigation--border-bottom"
7
7
  >
8
8
  <div
9
- class="np-flow-header d-flex flex-wrap align-items-center np-flow-navigation__content p-x-3 np-flow-navigation--xs-max"
9
+ class="np-flow-header d-flex flex-wrap align-items-center justify-content-between flex__item--12 np-flow-navigation__content p-x-3 np-flow-navigation--xs-max"
10
10
  >
11
+ <div>
12
+ BackButton
13
+ </div>
11
14
  <div
12
- class="np-flow-header__left flex__item--8"
15
+ class="m-x-1"
16
+ data-testid="activeLabel-1"
13
17
  >
14
- <div>
15
- BackButton
16
- <div
17
- class="m-x-1"
18
- data-testid="activeLabel-0"
19
- >
20
- AnimatedLabel
21
- </div>
22
- </div>
18
+ AnimatedLabel
23
19
  </div>
24
20
  <div
25
- class="align-items-center d-flex np-flow-header__right justify-content-end flex__item--4 "
21
+ class="d-flex align-items-center"
26
22
  >
27
23
  <div
28
24
  class="tw-avatar tw-avatar--48 tw-avatar--initials np-text-title-body"
@@ -34,7 +30,7 @@ exports[`FlowNavigation on mobile renders as expected 1`] = `
34
30
  </div>
35
31
  </div>
36
32
  <span
37
- class="separator"
33
+ class="m-x-1"
38
34
  />
39
35
  <button
40
36
  aria-label="Close"
@@ -122,20 +118,16 @@ exports[`FlowNavigation renders as expected 1`] = `
122
118
  class="np-flow-navigation d-flex align-items-center justify-content-center p-y-3 np-flow-navigation--border-bottom"
123
119
  >
124
120
  <div
125
- class="np-flow-header d-flex flex-wrap align-items-center np-flow-navigation__content p-x-3 np-flow-navigation--sm np-flow-navigation--lg"
121
+ class="np-flow-header d-flex flex-wrap align-items-center justify-content-between flex__item--12 np-flow-navigation__content p-x-3 np-flow-navigation--sm np-flow-navigation--lg"
126
122
  >
123
+ <img
124
+ alt="logo"
125
+ height="24"
126
+ src="logo.svg"
127
+ width="138"
128
+ />
127
129
  <div
128
- class="np-flow-header__left"
129
- >
130
- <img
131
- alt="logo"
132
- height="24"
133
- src="logo.svg"
134
- width="138"
135
- />
136
- </div>
137
- <div
138
- class="align-items-center d-flex np-flow-header__right justify-content-end order-2"
130
+ class="d-flex align-items-center order-2"
139
131
  >
140
132
  <div
141
133
  class="tw-avatar tw-avatar--48 tw-avatar--initials np-text-title-body"
@@ -147,7 +139,7 @@ exports[`FlowNavigation renders as expected 1`] = `
147
139
  </div>
148
140
  </div>
149
141
  <span
150
- class="separator"
142
+ class="m-x-1"
151
143
  />
152
144
  <button
153
145
  aria-label="Close"
@@ -1 +1 @@
1
- .np-animated-label{height:24px;overflow:hidden;padding-top:1px;position:relative}.np-animated-label>*{height:0;opacity:0;position:absolute;transform:translateX(-8px);transition:all .3s ease-in}.np-animated-label--in{height:auto;opacity:1;position:relative;top:auto;transform:translateX(0);transition:all .3s ease-in .3s}.np-animated-label--out{position:relative;top:-24px;transform:translateX(8px)}
1
+ .np-animated-label{height:24px;overflow:hidden;padding-top:1px;position:relative}.np-animated-label>*{height:0;opacity:0;position:absolute;transform:translateX(-8px);transition:all .3s ease-in}.np-animated-label--in{height:auto;opacity:1;position:relative;top:auto;transform:translateX(0);transition:all .3s ease-in .3s}
@@ -28,10 +28,4 @@
28
28
  transform: translateX(0);
29
29
  transition: all @transition-duration ease-in @transition-duration;
30
30
  }
31
-
32
- &--out {
33
- position: relative;
34
- top: -@label-height;
35
- transform: translateX(@slide-length);
36
- }
37
31
  }
@@ -14,12 +14,6 @@ describe('AnimatedLabel', () => {
14
14
  expect(container).toMatchSnapshot();
15
15
  });
16
16
 
17
- it('renders aria-label if provided', () => {
18
- render(<AnimatedLabel {...props} aria-label="hello" />);
19
- const checkbox = screen.getByLabelText('hello');
20
- expect(checkbox).toBeInTheDocument();
21
- });
22
-
23
17
  it('renders only one label with class in', () => {
24
18
  const { container } = render(<AnimatedLabel {...props} />);
25
19
  expect(screen.getByText(props.labels[0])).toHaveClass('np-animated-label--in');
@@ -28,41 +22,33 @@ describe('AnimatedLabel', () => {
28
22
 
29
23
  it('renders only one label with class out', () => {
30
24
  const { container } = render(<AnimatedLabel {...props} />);
31
- expect(screen.getByText(props.labels[1])).toHaveClass('np-animated-label--out');
32
- expect(container.querySelectorAll('.np-animated-label--out')).toHaveLength(1);
25
+ expect(screen.getByText(props.labels[1])).not.toHaveClass('np-animated-label--in');
26
+ expect(container.querySelectorAll('.np-animated-label--in')).toHaveLength(1);
33
27
  });
34
28
 
35
29
  it('when activeLabel increase it switches class accordingly', () => {
36
30
  const { rerender } = render(<AnimatedLabel {...props} />);
37
31
  expect(screen.getByText(props.labels[0])).toHaveClass('np-animated-label--in');
38
- expect(screen.getByText(props.labels[1])).toHaveClass('np-animated-label--out');
39
-
40
- expect(screen.getByText(props.labels[2])).not.toHaveClass('np-animated-label--out');
32
+ expect(screen.getByText(props.labels[1])).not.toHaveClass('np-animated-label--in');
41
33
  expect(screen.getByText(props.labels[2])).not.toHaveClass('np-animated-label--in');
42
34
 
43
35
  rerender(<AnimatedLabel {...props} activeLabel={1} />);
44
36
 
45
- expect(screen.getByText(props.labels[0])).not.toHaveClass('np-animated-label--out');
46
37
  expect(screen.getByText(props.labels[0])).not.toHaveClass('np-animated-label--in');
47
-
48
38
  expect(screen.getByText(props.labels[1])).toHaveClass('np-animated-label--in');
49
- expect(screen.getByText(props.labels[2])).toHaveClass('np-animated-label--out');
39
+ expect(screen.getByText(props.labels[2])).not.toHaveClass('np-animated-label--in');
50
40
  });
51
41
 
52
42
  it('when activeLabel decrease it switches class accordingly', () => {
53
43
  const { rerender } = render(<AnimatedLabel {...props} activeLabel={1} />);
54
- expect(screen.getByText(props.labels[1])).toHaveClass('np-animated-label--in');
55
- expect(screen.getByText(props.labels[2])).toHaveClass('np-animated-label--out');
56
-
57
- expect(screen.getByText(props.labels[0])).not.toHaveClass('np-animated-label--out');
58
44
  expect(screen.getByText(props.labels[0])).not.toHaveClass('np-animated-label--in');
45
+ expect(screen.getByText(props.labels[1])).toHaveClass('np-animated-label--in');
46
+ expect(screen.getByText(props.labels[2])).not.toHaveClass('np-animated-label--in');
59
47
 
60
48
  rerender(<AnimatedLabel {...props} activeLabel={0} />);
61
49
 
62
50
  expect(screen.getByText(props.labels[0])).toHaveClass('np-animated-label--in');
63
- expect(screen.getByText(props.labels[1])).toHaveClass('np-animated-label--out');
64
-
65
- expect(screen.getByText(props.labels[2])).not.toHaveClass('np-animated-label--out');
51
+ expect(screen.getByText(props.labels[1])).not.toHaveClass('np-animated-label--in');
66
52
  expect(screen.getByText(props.labels[2])).not.toHaveClass('np-animated-label--in');
67
53
  });
68
54
  });
@@ -1,41 +1,32 @@
1
1
  import classNames from 'classnames';
2
2
  import React from 'react';
3
3
 
4
+ import Body from '../../body';
5
+ import { Typography } from '../../common';
6
+
4
7
  export interface AnimatedLabelProps {
5
8
  activeLabel: number;
6
9
  className?: string;
7
10
  labels: React.ReactNode[];
8
- 'aria-label': string;
9
11
  }
10
12
 
11
- const AnimatedLabel = ({
12
- activeLabel,
13
- className,
14
- labels,
15
- 'aria-label': ariaLabel,
16
- }: AnimatedLabelProps) => {
17
- const numberLabels = labels.length - 1;
18
-
13
+ const AnimatedLabel = ({ activeLabel, className, labels }: AnimatedLabelProps) => {
19
14
  return (
20
- <div
21
- aria-label={ariaLabel}
22
- className={classNames('np-animated-label', 'np-text-body-large-bold', className)}
23
- >
15
+ <Body type={Typography.BODY_LARGE_BOLD} className={classNames('np-animated-label', className)}>
24
16
  {labels.map((label, index) => {
25
17
  const nextLabel = index - 1;
26
18
  return (
27
19
  <div
28
20
  key={nextLabel}
29
- className={classNames('text-xs-left', {
30
- 'np-animated-label--in': index === activeLabel,
31
- 'np-animated-label--out': nextLabel === activeLabel && nextLabel !== numberLabels,
21
+ className={classNames('text-xs-center', {
22
+ 'np-animated-label--in text-ellipsis': index === activeLabel,
32
23
  })}
33
24
  >
34
25
  {label}
35
26
  </div>
36
27
  );
37
28
  })}
38
- </div>
29
+ </Body>
39
30
  );
40
31
  };
41
32
 
@@ -3,20 +3,20 @@
3
3
  exports[`AnimatedLabel renders all labels 1`] = `
4
4
  <div>
5
5
  <div
6
- class="np-animated-label np-text-body-large-bold"
6
+ class="np-text-body-large-bold np-animated-label"
7
7
  >
8
8
  <div
9
- class="text-xs-left np-animated-label--in"
9
+ class="text-xs-center np-animated-label--in text-ellipsis"
10
10
  >
11
11
  label1
12
12
  </div>
13
13
  <div
14
- class="text-xs-left np-animated-label--out"
14
+ class="text-xs-center"
15
15
  >
16
16
  label2
17
17
  </div>
18
18
  <div
19
- class="text-xs-left"
19
+ class="text-xs-center"
20
20
  >
21
21
  label3
22
22
  </div>
@@ -2,18 +2,23 @@ import { ArrowLeft as ArrowLeftIcon } from '@transferwise/icons';
2
2
  import classNames from 'classnames';
3
3
  import PropTypes from 'prop-types';
4
4
 
5
- const BackButton = ({ label, className, onClick }) => (
6
- <button
7
- type="button"
8
- className={classNames('np-back-button', 'align-items-center', 'btn-unstyled', className)}
9
- onClick={onClick}
10
- >
11
- <ArrowLeftIcon size={24} />
12
- {label}
13
- </button>
5
+ import Avatar, { AvatarType } from '../../avatar';
6
+
7
+ const BackButton = ({ className, onClick, 'aria-label': ariaLabel }) => (
8
+ <Avatar type={AvatarType.ICON} size={40}>
9
+ <button
10
+ type="button"
11
+ aria-label={ariaLabel}
12
+ className={classNames('np-back-button', 'btn-unstyled', className)}
13
+ onClick={onClick}
14
+ >
15
+ <ArrowLeftIcon size={24} />
16
+ </button>
17
+ </Avatar>
14
18
  );
15
19
 
16
20
  BackButton.propTypes = {
21
+ 'aria-label': PropTypes.string.isRequired,
17
22
  className: PropTypes.string,
18
23
  label: PropTypes.element,
19
24
  onClick: PropTypes.func,
@@ -1,5 +1,5 @@
1
- import '@testing-library/jest-dom';
2
- import { render } from '@testing-library/react';
1
+ import { render } from '../../test-utils';
2
+ import messages from '../FlowNavigation.messages';
3
3
 
4
4
  import BackButton from '.';
5
5
 
@@ -7,6 +7,7 @@ const props = {
7
7
  label: <>label</>,
8
8
  className: 'className',
9
9
  onClick: jest.fn(),
10
+ 'aria-label': messages.back.defaultMessage,
10
11
  };
11
12
  describe('BackButton', () => {
12
13
  it(`renders as expected`, () => {
@@ -2,29 +2,36 @@
2
2
 
3
3
  exports[`BackButton renders as expected 1`] = `
4
4
  <div>
5
- <button
6
- class="np-back-button align-items-center btn-unstyled className"
7
- type="button"
5
+ <div
6
+ class="tw-avatar tw-avatar--40 tw-avatar--icon"
8
7
  >
9
- <span
10
- aria-hidden="true"
11
- class="tw-icon tw-icon-arrow-left "
12
- data-testid="arrow-left-icon"
13
- role="presentation"
8
+ <div
9
+ class="tw-avatar__content"
14
10
  >
15
- <svg
16
- fill="currentColor"
17
- focusable="false"
18
- height="24"
19
- viewBox="0 0 24 24"
20
- width="24"
11
+ <button
12
+ class="np-back-button btn-unstyled className"
13
+ type="button"
21
14
  >
22
- <path
23
- d="M22.286 11.316H4.629l7.114-7.114-1.2-1.2-8.572 8.571a.829.829 0 0 0 0 1.2l8.572 8.572 1.2-1.2-7.114-7.114h17.657v-1.715Z"
24
- />
25
- </svg>
26
- </span>
27
- label
28
- </button>
15
+ <span
16
+ aria-hidden="true"
17
+ class="tw-icon tw-icon-arrow-left "
18
+ data-testid="arrow-left-icon"
19
+ role="presentation"
20
+ >
21
+ <svg
22
+ fill="currentColor"
23
+ focusable="false"
24
+ height="24"
25
+ viewBox="0 0 24 24"
26
+ width="24"
27
+ >
28
+ <path
29
+ d="M22.286 11.316H4.629l7.114-7.114-1.2-1.2-8.572 8.571a.829.829 0 0 0 0 1.2l8.572 8.572 1.2-1.2-7.114-7.114h17.657v-1.715Z"
30
+ />
31
+ </svg>
32
+ </span>
33
+ </button>
34
+ </div>
35
+ </div>
29
36
  </div>
30
37
  `;
@@ -1 +1 @@
1
- .np-bottom-sheet-v2-container{position:relative;z-index:1060}.np-bottom-sheet-v2-backdrop-container--enter,.np-bottom-sheet-v2-backdrop-container--leave{transition-duration:.15s;transition-property:opacity;transition-timing-function:ease-out}.np-bottom-sheet-v2-backdrop-container--enter-from,.np-bottom-sheet-v2-backdrop-container--leave-to{opacity:0}.np-bottom-sheet-v2-backdrop{background-color:#37517e;background-color:var(--color-content-primary);inset:0;opacity:.4;position:fixed}.np-bottom-sheet-v2{display:flex;flex-direction:column;inset:0;justify-content:flex-end;padding-left:8px;padding-left:var(--size-8);padding-right:8px;padding-right:var(--size-8);padding-top:64px;padding-top:var(--size-64);position:fixed}.np-bottom-sheet-v2-content{max-height:100%}.np-bottom-sheet-v2-content--enter,.np-bottom-sheet-v2-content--leave{transition-duration:.3s;transition-property:transform;transition-timing-function:ease-out}@media (prefers-reduced-motion:reduce){.np-bottom-sheet-v2-content--enter,.np-bottom-sheet-v2-content--leave{transition-property:opacity}}@media (prefers-reduced-motion:no-preference){.np-bottom-sheet-v2-content--enter-from,.np-bottom-sheet-v2-content--leave-to{transform:translateY(100%)}}@media (prefers-reduced-motion:reduce){.np-bottom-sheet-v2-content--enter-from,.np-bottom-sheet-v2-content--leave-to{opacity:0}}.np-bottom-sheet-v2-content-inner-container{background-color:#fff;background-color:var(--color-background-elevated);border-top-left-radius:32px;border-top-right-radius:32px;box-shadow:0 0 40px rgba(69,71,69,.2);display:flex;flex-direction:column;height:100%}.np-bottom-sheet-v2-content-inner-container:focus{outline:none}.np-bottom-sheet-v2-header{align-self:flex-end;padding:16px;padding:var(--size-16)}.np-bottom-sheet-v2-content-inner{display:grid;grid-template-rows:repeat(1,minmax(0,1fr));overflow-y:auto;padding-top:0;row-gap:8px;row-gap:var(--size-8)}.np-bottom-sheet-v2-content-inner--has-title{grid-template-rows:auto 1fr}.np-bottom-sheet-v2-content-inner--padding-md{padding:16px;padding:var(--size-16)}.np-bottom-sheet-v2-title{color:#37517e;color:var(--color-content-primary)}.np-bottom-sheet-v2-body{color:#5d7079;color:var(--color-content-secondary)}.np-button-input{align-content:center;border-radius:10px;border-radius:var(--size-10);display:inline-grid;grid-auto-columns:minmax(0,1fr);text-align:start}.np-popover-v2-container{background-color:#fff;background-color:var(--color-background-elevated);border-radius:10px;border-radius:var(--radius-small);box-shadow:0 0 40px rgba(69,71,69,.2);display:flex;flex-direction:column;max-height:var(--max-height);min-width:20rem;width:var(--width);z-index:1060}.np-popover-v2-container:focus{outline:none}.np-popover-v2{display:grid;grid-template-rows:repeat(1,minmax(0,1fr));overflow-y:auto;row-gap:8px;row-gap:var(--size-8)}.np-popover-v2--has-title{grid-template-rows:auto 1fr}.np-popover-v2--padding-md{padding:16px;padding:var(--size-16)}.np-popover-v2-title{color:#37517e;color:var(--color-content-primary)}.np-popover-v2-content{color:#5d7079;color:var(--color-content-secondary)}.np-select-input-placeholder{color:#768e9c;color:var(--color-content-tertiary);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.np-select-input-options-container{display:flex;flex-direction:column;height:100%}.np-select-input-options-container:focus{outline:none}@media (min-width:576px){.np-select-input-options-container{max-height:28rem}}.np-select-input-options-status{align-items:center;-moz-column-gap:8px;column-gap:8px;-moz-column-gap:var(--size-8);column-gap:var(--size-8);display:flex;padding:8px 24px 0;padding:var(--size-8) var(--size-24) 0}.np-select-input-options-status-icon{color:#768e9c;color:var(--color-content-tertiary);padding:0 4px;padding:0 var(--size-4)}.np-select-input-query-container{display:flex;flex-direction:column;padding:8px;padding:var(--size-8);padding-top:0}@media (min-width:576px){.np-select-input-query-container{padding-top:8px;padding-top:var(--size-8)}}.np-select-input-listbox-container{height:var(--initial-height);overflow-y:auto;position:relative;scroll-padding-bottom:8px;scroll-padding-bottom:var(--size-8);scroll-padding-top:8px;scroll-padding-top:var(--size-8)}@media (min-width:576px){.np-select-input-listbox-container{height:auto}}.np-select-input-listbox-container--has-group{scroll-padding-top:32px;scroll-padding-top:var(--size-32)}.np-select-input-listbox{padding:8px;padding:var(--size-8)}.np-select-input-listbox:focus{outline:none}.np-select-input-separator-item{border-top-width:1px;margin:8px;margin:var(--size-8)}.np-select-input-group-item--without-needle:first-child{margin-top:-8px;margin-top:calc(var(--size-8)*-1)}.np-select-input-group-item-header{background-color:#fff;background-color:var(--color-background-elevated);color:#5d7079;color:var(--color-content-secondary);padding:8px 16px 4px;padding:var(--size-8) var(--size-16) var(--size-4);position:sticky;top:0;z-index:10}.np-select-input-option-container{align-items:center;border-radius:10px;border-radius:var(--radius-small);color:var(--color-interactive-primary);-moz-column-gap:8px;column-gap:8px;-moz-column-gap:var(--size-8);column-gap:var(--size-8);cursor:default;display:flex;padding:12px 16px;padding:var(--size-12) var(--size-16);-webkit-user-select:none;-moz-user-select:none;user-select:none}.np-select-input-option-container--active{box-shadow:inset 0 0 0 1px #c9cbce;box-shadow:inset 0 0 0 1px var(--color-interactive-secondary)}.np-select-input-option-container--disabled{opacity:.45}.np-select-input-option-check--not-selected{visibility:hidden}.np-select-input-option{flex:1}.np-select-input-option-content-container{align-items:center;color:#37517e;color:var(--color-content-primary);-moz-column-gap:8px;column-gap:8px;-moz-column-gap:var(--size-8);column-gap:var(--size-8);display:flex}.np-select-input-option-content-icon{display:flex}.np-select-input-option-content-icon--not-within-trigger{align-self:flex-start}.np-select-input-option-content-text{display:flex;flex:1;flex-direction:column;overflow:hidden}.np-select-input-option-content-text-primary{font:inherit}.np-select-input-option-content-text-secondary{color:#5d7079;color:var(--color-content-secondary)}.np-select-input-option-content-text-within-trigger{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.np-select-input-option-content-text-line-1>:not([hidden])~:not([hidden]){margin-left:8px;margin-left:var(--size-8);margin-right:8px;margin-right:var(--size-8)}.np-select-input-footer{padding:4px 24px 16px;padding:var(--size-4) var(--size-24) var(--size-16)}.np-select-input-addon-container{align-items:center;display:inline-flex;pointer-events:none}.np-select-input-addon-container,.np-select-input-addon-container>:not([hidden])~:not([hidden]){margin-inline-start:4px;margin-inline-start:var(--size-4)}.np-select-input-addon{align-items:center;background:none;border-radius:.125rem;border-width:0;display:inline-flex;height:24px;height:var(--size-24);justify-content:center;width:24px;width:var(--size-24)}.np-select-input-addon--interactive{color:#c9cbce;color:var(--color-interactive-secondary);pointer-events:auto}.np-select-input-addon--interactive:hover{color:#b5b7ba;color:var(--color-interactive-secondary-hover)}.np-select-input-addon--interactive:focus{outline:none}.np-select-input-addon--interactive:focus-visible{outline:var(--ring-outline-color) solid var(--ring-outline-width);outline-offset:var(--ring-outline-offset)}.np-select-input-addon-separator{border-inline-start:1px solid #0000001a;border-inline-start:1px solid var(--color-border-neutral);height:24px;height:var(--size-24)}
1
+ .np-bottom-sheet-v2-container{position:relative;z-index:1060}.np-bottom-sheet-v2-backdrop-container--enter,.np-bottom-sheet-v2-backdrop-container--leave{transition-duration:.15s;transition-property:opacity;transition-timing-function:ease-out}.np-bottom-sheet-v2-backdrop-container--enter-from,.np-bottom-sheet-v2-backdrop-container--leave-to{opacity:0}.np-bottom-sheet-v2-backdrop{background-color:#37517e;background-color:var(--color-content-primary);inset:0;opacity:.4;position:fixed}.np-bottom-sheet-v2{display:flex;flex-direction:column;inset:0;justify-content:flex-end;padding-left:8px;padding-left:var(--size-8);padding-right:8px;padding-right:var(--size-8);padding-top:64px;padding-top:var(--size-64);position:fixed}.np-bottom-sheet-v2-content{max-height:100%}.np-bottom-sheet-v2-content--enter,.np-bottom-sheet-v2-content--leave{transition-duration:.3s;transition-property:transform;transition-timing-function:ease-out}@media (prefers-reduced-motion:reduce){.np-bottom-sheet-v2-content--enter,.np-bottom-sheet-v2-content--leave{transition-property:opacity}}@media (prefers-reduced-motion:no-preference){.np-bottom-sheet-v2-content--enter-from,.np-bottom-sheet-v2-content--leave-to{transform:translateY(100%)}}@media (prefers-reduced-motion:reduce){.np-bottom-sheet-v2-content--enter-from,.np-bottom-sheet-v2-content--leave-to{opacity:0}}.np-bottom-sheet-v2-content-inner-container{background-color:#fff;background-color:var(--color-background-elevated);border-top-left-radius:32px;border-top-right-radius:32px;box-shadow:0 0 40px rgba(69,71,69,.2);display:flex;flex-direction:column;height:100%}.np-bottom-sheet-v2-content-inner-container:focus{outline:none}.np-bottom-sheet-v2-header{align-self:flex-end;padding:16px;padding:var(--size-16)}.np-bottom-sheet-v2-content-inner{display:grid;grid-template-rows:repeat(1,minmax(0,1fr));overflow-y:auto;padding-top:0;row-gap:8px;row-gap:var(--size-8)}.np-bottom-sheet-v2-content-inner--has-title{grid-template-rows:auto 1fr}.np-bottom-sheet-v2-content-inner--padding-md{padding:16px;padding:var(--size-16)}.np-bottom-sheet-v2-title{color:#37517e;color:var(--color-content-primary)}.np-bottom-sheet-v2-body{color:#5d7079;color:var(--color-content-secondary)}.np-button-input{align-content:center;border-radius:10px;border-radius:var(--size-10);display:inline-grid;grid-auto-columns:minmax(0,1fr);text-align:start}.np-popover-v2-container{background-color:#fff;background-color:var(--color-background-elevated);border-radius:10px;border-radius:var(--radius-small);box-shadow:0 0 40px rgba(69,71,69,.2);display:flex;flex-direction:column;max-height:var(--max-height);min-width:20rem;width:var(--width);z-index:1060}.np-popover-v2-container:focus{outline:none}.np-popover-v2{display:grid;grid-template-rows:repeat(1,minmax(0,1fr));overflow-y:auto;row-gap:8px;row-gap:var(--size-8)}.np-popover-v2--has-title{grid-template-rows:auto 1fr}.np-popover-v2--padding-md{padding:16px;padding:var(--size-16)}.np-popover-v2-title{color:#37517e;color:var(--color-content-primary)}.np-popover-v2-content{color:#5d7079;color:var(--color-content-secondary)}.np-select-input-placeholder{color:#768e9c;color:var(--color-content-tertiary);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.np-select-input-options-container{display:flex;flex-direction:column;height:100%}.np-select-input-options-container:focus{outline:none}@media (min-width:576px){.np-select-input-options-container{max-height:28rem}}.np-select-input-options-status{align-items:center;-moz-column-gap:8px;column-gap:8px;-moz-column-gap:var(--size-8);column-gap:var(--size-8);display:flex;padding:8px 24px 0;padding:var(--size-8) var(--size-24) 0}.np-select-input-options-status-icon{color:#768e9c;color:var(--color-content-tertiary);padding:0 4px;padding:0 var(--size-4)}.np-select-input-query-container{display:flex;flex-direction:column;padding:8px;padding:var(--size-8);padding-top:0}@media (min-width:576px){.np-select-input-query-container{padding-top:8px;padding-top:var(--size-8)}}.np-select-input-listbox-container{height:var(--initial-height);overflow-y:auto;position:relative;scroll-padding-bottom:8px;scroll-padding-bottom:var(--size-8);scroll-padding-top:8px;scroll-padding-top:var(--size-8)}@media (min-width:576px){.np-select-input-listbox-container{height:auto}}.np-select-input-listbox-container--has-group{scroll-padding-top:32px;scroll-padding-top:var(--size-32)}.np-select-input-listbox{padding:8px;padding:var(--size-8)}.np-select-input-listbox:focus{outline:none}.np-select-input-separator-item{border-top-width:1px;margin:8px;margin:var(--size-8)}.np-select-input-group-item--without-needle:first-child{margin-top:-8px;margin-top:calc(var(--size-8)*-1)}.np-select-input-group-item-header{background-color:#fff;background-color:var(--color-background-elevated);color:#5d7079;color:var(--color-content-secondary);padding:8px 16px 4px;padding:var(--size-8) var(--size-16) var(--size-4);position:sticky;top:0;z-index:10}.np-select-input-option-container{align-items:center;border-radius:10px;border-radius:var(--radius-small);color:var(--color-interactive-primary);-moz-column-gap:8px;column-gap:8px;-moz-column-gap:var(--size-8);column-gap:var(--size-8);cursor:default;display:flex;padding:12px 16px;padding:var(--size-12) var(--size-16);-webkit-user-select:none;-moz-user-select:none;user-select:none}.np-select-input-option-container--active{box-shadow:inset 0 0 0 1px #c9cbce;box-shadow:inset 0 0 0 1px var(--color-interactive-secondary)}.np-select-input-option-container--disabled{opacity:.45}.np-select-input-option-check--not-selected{visibility:hidden}.np-select-input-option{flex:1}.np-select-input-option-content-container{align-items:center;color:#37517e;color:var(--color-content-primary);-moz-column-gap:8px;column-gap:8px;-moz-column-gap:var(--size-8);column-gap:var(--size-8);display:flex}.np-select-input-option-content-icon{display:flex}.np-select-input-option-content-icon--not-within-trigger{align-self:flex-start}.np-select-input-option-content-text{display:flex;flex:1;flex-direction:column;overflow:hidden}.np-select-input-option-content-text-primary{font:inherit}.np-select-input-option-content-text-secondary{color:#5d7079;color:var(--color-content-secondary)}.np-select-input-option-content-text-within-trigger{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.np-select-input-option-content-text-line-1>:not([hidden])~:not([hidden]){margin-left:8px;margin-left:var(--size-8);margin-right:8px;margin-right:var(--size-8)}.np-select-input-addon-container{align-items:center;display:inline-flex;pointer-events:none}.np-select-input-addon-container,.np-select-input-addon-container>:not([hidden])~:not([hidden]){margin-inline-start:4px;margin-inline-start:var(--size-4)}.np-select-input-addon{align-items:center;background:none;border-radius:.125rem;border-width:0;display:inline-flex;height:24px;height:var(--size-24);justify-content:center;width:24px;width:var(--size-24)}.np-select-input-addon--interactive{color:#c9cbce;color:var(--color-interactive-secondary);pointer-events:auto}.np-select-input-addon--interactive:hover{color:#b5b7ba;color:var(--color-interactive-secondary-hover)}.np-select-input-addon--interactive:focus{outline:none}.np-select-input-addon--interactive:focus-visible{outline:var(--ring-outline-color) solid var(--ring-outline-width);outline-offset:var(--ring-outline-offset)}.np-select-input-addon-separator{border-inline-start:1px solid #0000001a;border-inline-start:1px solid var(--color-border-neutral);height:24px;height:var(--size-24)}
@@ -169,10 +169,6 @@
169
169
  }
170
170
  }
171
171
 
172
- .np-select-input-footer {
173
- padding: var(--size-4) var(--size-24) var(--size-16);
174
- }
175
-
176
172
  .np-select-input-addon-container {
177
173
  pointer-events: none;
178
174
  margin-inline-start: var(--size-4);
@@ -47,46 +47,6 @@ describe('SelectInput', () => {
47
47
  expect(screen.getByText('Currency')).toBeInTheDocument();
48
48
  });
49
49
 
50
- it('renders footer', async () => {
51
- render(
52
- <SelectInput
53
- items={[
54
- { type: 'option', value: 'USD' },
55
- { type: 'option', value: 'EUR' },
56
- ]}
57
- renderFooter={(normalizedQuery) =>
58
- normalizedQuery != null ? (
59
- <>Showing results for ‘{normalizedQuery}’</>
60
- ) : (
61
- <>All items shown</>
62
- )
63
- }
64
- filterable
65
- />,
66
- );
67
-
68
- // eslint-disable-next-line @typescript-eslint/require-await
69
- await act(async () => {
70
- userEvent.tab();
71
- userEvent.keyboard(specialChars.enter);
72
- });
73
-
74
- const footer = screen.getByText('All items shown');
75
- expect(footer).toBeInTheDocument();
76
-
77
- userEvent.keyboard('u');
78
- expect(footer).toHaveTextContent(/‘u’$/);
79
-
80
- userEvent.keyboard('r');
81
- expect(footer).toHaveTextContent(/‘ur’$/);
82
-
83
- userEvent.keyboard('x');
84
- expect(footer).toHaveTextContent(/‘urx’$/);
85
-
86
- userEvent.keyboard(specialChars.backspace);
87
- expect(footer).toHaveTextContent(/‘ur’$/);
88
- });
89
-
90
50
  it('shows item selected via mouse', async () => {
91
51
  render(
92
52
  <SelectInput
@@ -266,24 +266,6 @@ export const Currencies: StoryObj<{
266
266
  icon={<Flag code={currency.code} intrinsicSize={24} />}
267
267
  />
268
268
  )}
269
- renderFooter={(normalizedQuery) =>
270
- normalizedQuery != null && normalizedQuery.length === 3 ? (
271
- <>
272
- It’s not possible use {normalizedQuery.toUpperCase()} yet.{' '}
273
- <a href="#_" className="np-text-link-default">
274
- Email me when it’s available.
275
- </a>
276
- </>
277
- ) : (
278
- <>
279
- Can’t find it?{' '}
280
- <a href="#_" className="np-text-link-default">
281
- Request the currency you need,
282
- </a>{' '}
283
- and we’ll notify you once it’s available.
284
- </>
285
- )
286
- }
287
269
  filterable
288
270
  filterPlaceholder="Type a currency / country"
289
271
  size="lg"
@@ -135,7 +135,6 @@ export interface SelectInputProps<T = string> {
135
135
  | (keyof NonNullable<T> & string)
136
136
  | ((a: T | undefined, b: T | undefined) => boolean);
137
137
  renderValue?: (value: NonNullable<T>, withinTrigger: boolean) => React.ReactNode;
138
- renderFooter?: (normalizedQuery: string | null | undefined) => React.ReactNode;
139
138
  renderTrigger?: (args: {
140
139
  content: React.ReactNode;
141
140
  placeholderShown: boolean;
@@ -212,7 +211,6 @@ export function SelectInput<T = string>({
212
211
  value: controlledValue,
213
212
  compareValues,
214
213
  renderValue = wrapInFragment,
215
- renderFooter,
216
214
  renderTrigger = defaultRenderTrigger,
217
215
  filterable,
218
216
  filterPlaceholder,
@@ -298,7 +296,6 @@ export function SelectInput<T = string>({
298
296
  <SelectInputOptions
299
297
  items={items}
300
298
  renderValue={renderValue}
301
- renderFooter={renderFooter}
302
299
  filterable={filterable}
303
300
  filterPlaceholder={filterPlaceholder}
304
301
  searchInputRef={searchInputRef}
@@ -376,10 +373,7 @@ const SelectInputOptionsContainer = forwardRef(function SelectInputOptionsContai
376
373
  });
377
374
 
378
375
  interface SelectInputOptionsProps<T = string>
379
- extends Pick<
380
- SelectInputProps<T>,
381
- 'items' | 'renderValue' | 'renderFooter' | 'filterable' | 'filterPlaceholder'
382
- > {
376
+ extends Pick<SelectInputProps<T>, 'items' | 'renderValue' | 'filterable' | 'filterPlaceholder'> {
383
377
  searchInputRef: React.RefObject<HTMLInputElement>;
384
378
  listboxRef: React.RefObject<HTMLDivElement>;
385
379
  }
@@ -387,7 +381,6 @@ interface SelectInputOptionsProps<T = string>
387
381
  function SelectInputOptions<T = string>({
388
382
  items,
389
383
  renderValue = wrapInFragment,
390
- renderFooter,
391
384
  filterable = false,
392
385
  filterPlaceholder,
393
386
  searchInputRef,
@@ -458,7 +451,7 @@ function SelectInputOptions<T = string>({
458
451
  </div>
459
452
  ) : null}
460
453
 
461
- <section
454
+ <div
462
455
  ref={listboxContainerRef}
463
456
  className={classNames(
464
457
  'np-select-input-listbox-container',
@@ -491,11 +484,7 @@ function SelectInputOptions<T = string>({
491
484
  />
492
485
  ))}
493
486
  </div>
494
-
495
- {renderFooter != null ? (
496
- <footer className="np-select-input-footer">{renderFooter(needle)}</footer>
497
- ) : null}
498
- </section>
487
+ </div>
499
488
  </ListboxBase.Options>
500
489
  );
501
490
  }