@transferwise/components 0.0.0-experimental-6fb3b67 → 0.0.0-experimental-4658255

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.
@@ -3524,13 +3524,6 @@ html:not([dir="rtl"]) .np-flow-navigation--sm .np-flow-navigation__stepper {
3524
3524
  padding-inline-start: 8px;
3525
3525
  padding-inline-start: var(--size-8);
3526
3526
  }
3527
- .wds-select-input-scroll-freeze {
3528
- scroll-behavior: unset !important;
3529
- height: 100vh;
3530
- }
3531
- .wds-select-input-scroll-freeze body {
3532
- height: 100vh;
3533
- }
3534
3527
  .np-bottom-sheet-v2-container {
3535
3528
  position: relative;
3536
3529
  z-index: 1060;
@@ -3544,8 +3537,6 @@ html:not([dir="rtl"]) .np-flow-navigation--sm .np-flow-navigation__stepper {
3544
3537
  transition-property: opacity;
3545
3538
  transition-timing-function: ease-out;
3546
3539
  transition-duration: 300ms;
3547
- will-change: transform;
3548
- min-height: 100vh;
3549
3540
  }
3550
3541
  .np-bottom-sheet-v2-backdrop--closed {
3551
3542
  opacity: 0;
@@ -3553,7 +3544,7 @@ html:not([dir="rtl"]) .np-flow-navigation--sm .np-flow-navigation__stepper {
3553
3544
  .np-bottom-sheet-v2 {
3554
3545
  position: fixed;
3555
3546
  inset: 0px;
3556
- bottom: env(safe-area-inset-bottom, 0);
3547
+ bottom: env(keyboard-inset-height, 0px);
3557
3548
  margin-left: 8px;
3558
3549
  margin-left: var(--size-8);
3559
3550
  margin-right: 8px;
@@ -3563,19 +3554,18 @@ html:not([dir="rtl"]) .np-flow-navigation--sm .np-flow-navigation__stepper {
3563
3554
  display: flex;
3564
3555
  flex-direction: column;
3565
3556
  justify-content: flex-end;
3566
- height: calc(100vh - 64px - 40px);
3567
- height: calc(100vh - var(--size-64) - 40px);
3568
3557
  }
3569
3558
  .np-bottom-sheet-v2-content {
3570
3559
  display: flex;
3571
3560
  flex-direction: column;
3572
3561
  overflow: auto;
3573
- border-radius: 32px;
3574
- border-radius: var(--size-32);
3562
+ border-top-left-radius: 32px;
3563
+ /* TODO: Tokenize */
3564
+ border-top-right-radius: 32px;
3565
+ /* TODO: Tokenize */
3575
3566
  background-color: #ffffff;
3576
3567
  background-color: var(--color-background-elevated);
3577
3568
  box-shadow: 0 0 40px rgba(69, 71, 69, 0.2);
3578
- will-change: transform;
3579
3569
  }
3580
3570
  .np-bottom-sheet-v2-content:focus {
3581
3571
  outline: none;
@@ -32,6 +32,25 @@ export interface SelectInputProps<T = string, M extends boolean = false> {
32
32
  multiple?: M;
33
33
  placeholder?: string;
34
34
  items: readonly SelectInputItem<NonNullable<T>>[];
35
+ /**
36
+ * Enables browser autocomplete integration through the search input.
37
+ * Accepts standard HTML autocomplete values (e.g., "country-name", "address-level1").
38
+ *
39
+ * Requires `filterable={true}` to enable the search input.
40
+ *
41
+ * @example
42
+ * <SelectInput
43
+ * name="country"
44
+ * autocomplete="country-name"
45
+ * filterable={true}
46
+ * items={[{
47
+ * type: 'option',
48
+ * value: 'GB',
49
+ * filterMatchers: ['United Kingdom', 'UK']
50
+ * }]}
51
+ * />
52
+ */
53
+ autocomplete?: string;
35
54
  defaultValue?: M extends true ? readonly T[] : T;
36
55
  value?: M extends true ? readonly T[] : T;
37
56
  compareValues?: (keyof NonNullable<T> & string) | ((a: T | undefined, b: T | undefined) => boolean);
@@ -67,7 +86,7 @@ export interface SelectInputProps<T = string, M extends boolean = false> {
67
86
  onClose?: () => void;
68
87
  onClear?: () => void;
69
88
  }
70
- export declare function SelectInput<T = string, M extends boolean = false>({ id: idProp, parentId, name, multiple, placeholder, items, defaultValue, value: controlledValue, compareValues, renderValue, renderFooter, renderTrigger, filterable, filterPlaceholder, disabled, size, className, UNSAFE_triggerButtonProps, triggerRef: externalTriggerRef, onFilterChange, onChange, onOpen, onClose, onClear, }: SelectInputProps<T, M>): import("react").JSX.Element;
89
+ export declare function SelectInput<T = string, M extends boolean = false>({ id: idProp, parentId, name, multiple, placeholder, autocomplete, items, defaultValue, value: controlledValue, compareValues, renderValue, renderFooter, renderTrigger, filterable, filterPlaceholder, disabled, size, className, UNSAFE_triggerButtonProps, triggerRef: externalTriggerRef, onFilterChange, onChange, onOpen, onClose, onClear, }: SelectInputProps<T, M>): import("react").JSX.Element;
71
90
  type SelectInputTriggerButtonElementType = 'button' | React.ComponentType;
72
91
  export type SelectInputTriggerButtonProps<T extends SelectInputTriggerButtonElementType = 'button'> = Merge<React.ComponentPropsWithoutRef<T>, {
73
92
  as?: T;
@@ -1 +1 @@
1
- {"version":3,"file":"SelectInput.d.ts","sourceRoot":"","sources":["../../../src/inputs/SelectInput.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"SelectInput.d.ts","sourceRoot":"","sources":["../../../src/inputs/SelectInput.tsx"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"_BottomSheet.d.ts","sourceRoot":"","sources":["../../../src/inputs/_BottomSheet.tsx"],"names":[],"mappings":"AAkBA,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,OAAO,CAAC;IACd,aAAa,CAAC,EAAE,CAAC,IAAI,EAAE;QACrB,GAAG,EAAE,KAAK,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC;QAChC,mBAAmB,EAAE,CAAC,mBAAmB,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC,OAAO,CAAC,KAAK;YACvE,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;SACxB,CAAC;KACH,KAAK,KAAK,CAAC,SAAS,CAAC;IACtB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,eAAe,CAAC,EAAE,KAAK,CAAC,gBAAgB,CAAC,WAAW,GAAG,IAAI,CAAC,CAAC;IAC7D,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC3B,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB,UAAU,CAAC,EAAE,MAAM,IAAI,CAAC;CACzB;AAeD,wBAAgB,WAAW,CAAC,EAC1B,IAAI,EACJ,aAAa,EACb,KAAK,EACL,eAAe,EACf,OAAc,EACd,QAAQ,EACR,OAAO,EACP,UAAU,GACX,EAAE,gBAAgB,+BAiGlB"}
1
+ {"version":3,"file":"_BottomSheet.d.ts","sourceRoot":"","sources":["../../../src/inputs/_BottomSheet.tsx"],"names":[],"mappings":"AAmBA,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,OAAO,CAAC;IACd,aAAa,CAAC,EAAE,CAAC,IAAI,EAAE;QACrB,GAAG,EAAE,KAAK,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC;QAChC,mBAAmB,EAAE,CAAC,mBAAmB,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC,OAAO,CAAC,KAAK;YACvE,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;SACxB,CAAC;KACH,KAAK,KAAK,CAAC,SAAS,CAAC;IACtB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,eAAe,CAAC,EAAE,KAAK,CAAC,gBAAgB,CAAC,WAAW,GAAG,IAAI,CAAC,CAAC;IAC7D,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC3B,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB,UAAU,CAAC,EAAE,MAAM,IAAI,CAAC;CACzB;AAED,wBAAgB,WAAW,CAAC,EAC1B,IAAI,EACJ,aAAa,EACb,KAAK,EACL,eAAe,EACf,OAAc,EACd,QAAQ,EACR,OAAO,EACP,UAAU,GACX,EAAE,gBAAgB,+BA6FlB"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@transferwise/components",
3
- "version": "0.0.0-experimental-6fb3b67",
3
+ "version": "0.0.0-experimental-4658255",
4
4
  "description": "Neptune React components",
5
5
  "license": "Apache-2.0",
6
6
  "repository": {
@@ -83,8 +83,8 @@
83
83
  "storybook": "^9.1.3",
84
84
  "storybook-addon-tag-badges": "^2.0.2",
85
85
  "storybook-addon-test-codegen": "^2.0.1",
86
- "@transferwise/neptune-css": "14.25.0",
87
86
  "@transferwise/less-config": "3.1.2",
87
+ "@transferwise/neptune-css": "14.25.0",
88
88
  "@wise/components-theming": "1.7.0",
89
89
  "@wise/wds-configs": "0.0.0"
90
90
  },
@@ -102,8 +102,8 @@
102
102
  "@floating-ui/react": "^0.27.16",
103
103
  "@headlessui/react": "^1.7.19",
104
104
  "@popperjs/core": "^2.11.8",
105
- "@react-aria/focus": "^3.21.1",
106
- "@react-aria/overlays": "^3.29.1",
105
+ "@react-aria/focus": "^3.21.0",
106
+ "@react-aria/overlays": "^3.28.0",
107
107
  "@react-spring/web": "~10.0.1",
108
108
  "@transferwise/formatting": "^2.13.4",
109
109
  "@transferwise/neptune-validation": "^3.3.1",
@@ -1,10 +1,3 @@
1
- .wds-select-input-scroll-freeze {
2
- scroll-behavior: unset !important;
3
- height: 100vh;
4
- }
5
- .wds-select-input-scroll-freeze body {
6
- height: 100vh;
7
- }
8
1
  .np-bottom-sheet-v2-container {
9
2
  position: relative;
10
3
  z-index: 1060;
@@ -18,8 +11,6 @@
18
11
  transition-property: opacity;
19
12
  transition-timing-function: ease-out;
20
13
  transition-duration: 300ms;
21
- will-change: transform;
22
- min-height: 100vh;
23
14
  }
24
15
  .np-bottom-sheet-v2-backdrop--closed {
25
16
  opacity: 0;
@@ -27,7 +18,7 @@
27
18
  .np-bottom-sheet-v2 {
28
19
  position: fixed;
29
20
  inset: 0px;
30
- bottom: env(safe-area-inset-bottom, 0);
21
+ bottom: env(keyboard-inset-height, 0px);
31
22
  margin-left: 8px;
32
23
  margin-left: var(--size-8);
33
24
  margin-right: 8px;
@@ -37,19 +28,18 @@
37
28
  display: flex;
38
29
  flex-direction: column;
39
30
  justify-content: flex-end;
40
- height: calc(100vh - 64px - 40px);
41
- height: calc(100vh - var(--size-64) - 40px);
42
31
  }
43
32
  .np-bottom-sheet-v2-content {
44
33
  display: flex;
45
34
  flex-direction: column;
46
35
  overflow: auto;
47
- border-radius: 32px;
48
- border-radius: var(--size-32);
36
+ border-top-left-radius: 32px;
37
+ /* TODO: Tokenize */
38
+ border-top-right-radius: 32px;
39
+ /* TODO: Tokenize */
49
40
  background-color: #ffffff;
50
41
  background-color: var(--color-background-elevated);
51
42
  box-shadow: 0 0 40px rgba(69, 71, 69, 0.2);
52
- will-change: transform;
53
43
  }
54
44
  .np-bottom-sheet-v2-content:focus {
55
45
  outline: none;
@@ -3,21 +3,13 @@ import { userEvent } from '@testing-library/user-event';
3
3
 
4
4
  import { render, mockMatchMedia, mockResizeObserver } from '../test-utils';
5
5
 
6
- import { useScreenSize } from '../common/hooks/useScreenSize';
7
6
  import { SelectInput, type SelectInputOptionItem, type SelectInputProps } from './SelectInput';
8
7
  import { Field } from '../field/Field';
9
8
 
10
9
  mockMatchMedia();
11
10
  mockResizeObserver();
12
- jest.mock('../common/hooks/useScreenSize');
13
11
 
14
12
  describe('SelectInput', () => {
15
- beforeEach(() => {
16
- (useScreenSize as jest.Mock).mockReturnValue(true);
17
- });
18
-
19
- afterEach(jest.clearAllMocks);
20
-
21
13
  it('renders placeholder', () => {
22
14
  render(
23
15
  <SelectInput
@@ -317,29 +309,4 @@ describe('SelectInput', () => {
317
309
  expect(listBox).not.toHaveAttribute('aria-labelledby');
318
310
  });
319
311
  });
320
-
321
- describe('smooth scroll reset', () => {
322
- const options: SelectInputOptionItem[] = [
323
- { type: 'option', value: 'Banana' },
324
- { type: 'option', value: 'Orange' },
325
- { type: 'option', value: 'Olive' },
326
- ];
327
-
328
- beforeEach(() => {
329
- (useScreenSize as jest.Mock).mockReturnValue(false);
330
- });
331
-
332
- afterEach(jest.clearAllMocks);
333
-
334
- it('toggles scroll-resetting class', async () => {
335
- render(<SelectInput items={options} />);
336
- expect(document.documentElement).not.toHaveClass('wds-select-input-scroll-freeze');
337
-
338
- await userEvent.click(screen.getByRole('combobox'));
339
- expect(document.documentElement).toHaveClass('wds-select-input-scroll-freeze');
340
-
341
- await userEvent.click(document.documentElement);
342
- expect(document.documentElement).not.toHaveClass('wds-select-input-scroll-freeze');
343
- });
344
- });
345
312
  });
@@ -516,3 +516,97 @@ export const WithinModal: Story<Currency> = {
516
516
  },
517
517
  ],
518
518
  };
519
+
520
+ interface Country {
521
+ code: string;
522
+ name: string;
523
+ }
524
+
525
+ const countries: Country[] = [
526
+ { code: 'US', name: 'United States' },
527
+ { code: 'GB', name: 'United Kingdom' },
528
+ { code: 'CA', name: 'Canada' },
529
+ { code: 'AU', name: 'Australia' },
530
+ { code: 'DE', name: 'Germany' },
531
+ { code: 'FR', name: 'France' },
532
+ { code: 'JP', name: 'Japan' },
533
+ { code: 'BR', name: 'Brazil' },
534
+ { code: 'IN', name: 'India' },
535
+ { code: 'CN', name: 'China' },
536
+ { code: 'IT', name: 'Italy' },
537
+ { code: 'ES', name: 'Spain' },
538
+ { code: 'NL', name: 'Netherlands' },
539
+ { code: 'CH', name: 'Switzerland' },
540
+ { code: 'SE', name: 'Sweden' },
541
+ ];
542
+
543
+ function countryOption(country: Country) {
544
+ return {
545
+ type: 'option',
546
+ value: country.code,
547
+ filterMatchers: [country.code, country.name],
548
+ } satisfies SelectInputItem;
549
+ }
550
+
551
+ export const WithAutocomplete: Story<string> = {
552
+ args: {
553
+ name: 'country',
554
+ autocomplete: 'country-name',
555
+ placeholder: 'Select your country',
556
+ items: countries.map(countryOption),
557
+ renderValue: (countryCode, withinTrigger) => {
558
+ const country = countries.find((c) => c.code === countryCode);
559
+ return (
560
+ <SelectInputOptionContent
561
+ title={withinTrigger ? countryCode : country?.name || countryCode}
562
+ note={withinTrigger ? undefined : countryCode}
563
+ icon={<Flag code={countryCode} intrinsicSize={24} />}
564
+ />
565
+ );
566
+ },
567
+ filterable: true,
568
+ filterPlaceholder: 'Type a country name',
569
+ size: 'lg',
570
+ },
571
+ render: function Render({ onChange, onClear, ...args }) {
572
+ const [selectedCountry, setSelectedCountry] = useState<string | undefined>(undefined);
573
+
574
+ return (
575
+ <div>
576
+ <form
577
+ method="post"
578
+ onSubmit={(e) => {
579
+ e.preventDefault();
580
+ console.log(
581
+ `Form submitted with country: ${selectedCountry}. This saves data for browser autocomplete!`,
582
+ );
583
+ }}
584
+ >
585
+ <div>
586
+ <label htmlFor="country-select" className="block text-sm font-medium mb-2">
587
+ Country Selection with Autocomplete:
588
+ </label>
589
+ <SelectInput
590
+ {...args}
591
+ id="country-select"
592
+ value={selectedCountry}
593
+ onChange={(country) => {
594
+ setSelectedCountry(country);
595
+ onChange?.(country);
596
+ console.log('Country selected via SelectInput:', country);
597
+ }}
598
+ onClear={() => {
599
+ setSelectedCountry(undefined);
600
+ onClear?.();
601
+ }}
602
+ />
603
+ </div>
604
+
605
+ <Button type="submit" v2 className="m-t-2" data-testid="submit-btn">
606
+ Submit Form
607
+ </Button>
608
+ </form>
609
+ </div>
610
+ );
611
+ },
612
+ };
@@ -155,6 +155,25 @@ export interface SelectInputProps<T = string, M extends boolean = false> {
155
155
  multiple?: M;
156
156
  placeholder?: string;
157
157
  items: readonly SelectInputItem<NonNullable<T>>[];
158
+ /**
159
+ * Enables browser autocomplete integration through the search input.
160
+ * Accepts standard HTML autocomplete values (e.g., "country-name", "address-level1").
161
+ *
162
+ * Requires `filterable={true}` to enable the search input.
163
+ *
164
+ * @example
165
+ * <SelectInput
166
+ * name="country"
167
+ * autocomplete="country-name"
168
+ * filterable={true}
169
+ * items={[{
170
+ * type: 'option',
171
+ * value: 'GB',
172
+ * filterMatchers: ['United Kingdom', 'UK']
173
+ * }]}
174
+ * />
175
+ */
176
+ autocomplete?: string;
158
177
  defaultValue?: M extends true ? readonly T[] : T;
159
178
  value?: M extends true ? readonly T[] : T;
160
179
  compareValues?:
@@ -257,6 +276,7 @@ export function SelectInput<T = string, M extends boolean = false>({
257
276
  name,
258
277
  multiple,
259
278
  placeholder,
279
+ autocomplete,
260
280
  items,
261
281
  defaultValue,
262
282
  value: controlledValue,
@@ -457,7 +477,15 @@ export function SelectInput<T = string, M extends boolean = false>({
457
477
  searchInputRef={searchInputRef}
458
478
  listboxRef={listboxRef}
459
479
  filterQuery={deferredFilterQuery}
480
+ autocomplete={autocomplete}
481
+ name={name}
460
482
  onFilterChange={setFilterQuery}
483
+ onAutocompleteSelect={(matchedValue) => {
484
+ onChange?.(matchedValue as M extends true ? T[] : T);
485
+ if (!multiple) {
486
+ setOpen(false);
487
+ }
488
+ }}
461
489
  {...getListBoxLabelProps()}
462
490
  />
463
491
  </OptionsOverlay>
@@ -565,6 +593,9 @@ interface SelectInputOptionsProps<T = string>
565
593
  onFilterChange: (query: string) => void;
566
594
  listBoxLabel?: string;
567
595
  listBoxLabelledBy?: string;
596
+ autocomplete?: string;
597
+ name?: string;
598
+ onAutocompleteSelect?: (value: T) => void;
568
599
  }
569
600
 
570
601
  function SelectInputOptions<T = string>({
@@ -581,6 +612,9 @@ function SelectInputOptions<T = string>({
581
612
  onFilterChange,
582
613
  listBoxLabel,
583
614
  listBoxLabelledBy,
615
+ autocomplete,
616
+ name,
617
+ onAutocompleteSelect,
584
618
  }: SelectInputOptionsProps<T>) {
585
619
  const intl = useIntl();
586
620
  const virtualiserHandlerRef = useRef<VirtualizerHandle>(null);
@@ -664,6 +698,35 @@ function SelectInputOptions<T = string>({
664
698
  );
665
699
  };
666
700
 
701
+ const findMatchingItem = (autocompleteValue: string): T | null => {
702
+ const flatOptions = items
703
+ .flatMap((item) =>
704
+ item.type === 'group' ? item.options : item.type === 'option' ? [item] : [],
705
+ )
706
+ .filter(
707
+ (item): item is SelectInputOptionItem<NonNullable<T>> =>
708
+ item.type === 'option' && item.value != null,
709
+ );
710
+
711
+ const exactMatch = flatOptions.find(
712
+ (option) =>
713
+ String(option.value) === autocompleteValue ||
714
+ option.filterMatchers?.some((matcher) => matcher === autocompleteValue),
715
+ );
716
+
717
+ if (exactMatch) {
718
+ return exactMatch.value;
719
+ }
720
+
721
+ const fuzzyMatch = flatOptions.find((option) =>
722
+ option.filterMatchers?.some((matcher) =>
723
+ matcher.toLowerCase().includes(autocompleteValue.toLowerCase()),
724
+ ),
725
+ );
726
+
727
+ return fuzzyMatch ? fuzzyMatch.value : null;
728
+ };
729
+
667
730
  return (
668
731
  <ListboxBase.Options
669
732
  as={SelectInputOptionsContainer}
@@ -684,6 +747,8 @@ function SelectInputOptions<T = string>({
684
747
  <SearchInput
685
748
  ref={searchInputRef}
686
749
  id={id}
750
+ name={name}
751
+ autoComplete={autocomplete}
687
752
  role="combobox"
688
753
  shape="rectangle"
689
754
  placeholder={filterPlaceholder}
@@ -703,8 +768,26 @@ function SelectInputOptions<T = string>({
703
768
  onChange={(event) => {
704
769
  // Free up resources and ensure not to go out of bounds when the
705
770
  // resulting item count is less than before
771
+ const inputValue = event.currentTarget.value;
772
+
773
+ // Free up resources and ensure not to go out of bounds
706
774
  setMountedIndexes([]);
707
- onFilterChange(event.currentTarget.value);
775
+ onFilterChange(inputValue);
776
+ }}
777
+ onInput={(event) => {
778
+ const inputValue = event.currentTarget.value;
779
+ const inputElement = event.currentTarget;
780
+
781
+ if (autocomplete && onAutocompleteSelect && inputValue) {
782
+ setTimeout(() => {
783
+ if (inputElement.value === inputValue && inputValue.length > 2) {
784
+ const matchedValue = findMatchingItem(inputValue);
785
+ if (matchedValue !== null) {
786
+ onAutocompleteSelect(matchedValue);
787
+ }
788
+ }
789
+ }, 50);
790
+ }
708
791
  }}
709
792
  />
710
793
  </div>
@@ -1,12 +1,3 @@
1
- .wds-select-input-scroll-freeze {
2
- scroll-behavior: unset !important;
3
- height: 100vh;
4
-
5
- body{
6
- height: 100vh;
7
- }
8
- }
9
-
10
1
  .np-bottom-sheet-v2-container {
11
2
  position: relative;
12
3
  z-index: 1060;
@@ -20,8 +11,6 @@
20
11
  transition-property: opacity;
21
12
  transition-timing-function: ease-out;
22
13
  transition-duration: 300ms;
23
- will-change: transform;
24
- min-height: 100vh;
25
14
 
26
15
  &--closed {
27
16
  opacity: 0;
@@ -31,24 +20,23 @@
31
20
  .np-bottom-sheet-v2 {
32
21
  position: fixed;
33
22
  inset: 0px;
34
- bottom: env(safe-area-inset-bottom, 0);
23
+ bottom: env(keyboard-inset-height, 0px);
35
24
  margin-left: var(--size-8);
36
25
  margin-right: var(--size-8);
37
26
  margin-top: var(--size-64);
38
27
  display: flex;
39
28
  flex-direction: column;
40
29
  justify-content: flex-end;
41
- height: calc(100vh - var(--size-64) - 40px);
42
30
  }
43
31
 
44
32
  .np-bottom-sheet-v2-content {
45
33
  display: flex;
46
34
  flex-direction: column;
47
35
  overflow: auto;
48
- border-radius: var(--size-32);
36
+ border-top-left-radius: 32px; /* TODO: Tokenize */
37
+ border-top-right-radius: 32px; /* TODO: Tokenize */
49
38
  background-color: var(--color-background-elevated);
50
39
  box-shadow: 0 0 40px rgb(69 71 69 / 0.2);
51
- will-change: transform;
52
40
 
53
41
  &:focus {
54
42
  outline: none;
@@ -10,11 +10,12 @@ import { Transition } from '@headlessui/react';
10
10
  import { FocusScope } from '@react-aria/focus';
11
11
  import { ThemeProvider, useTheme } from '@wise/components-theming';
12
12
  import { clsx } from 'clsx';
13
- import { Fragment, useEffect, useState } from 'react';
13
+ import { Fragment, useState } from 'react';
14
14
 
15
- import { CloseButton , Size } from '../common';
15
+ import { CloseButton } from '../common/closeButton';
16
16
  import { useVirtualKeyboard } from '../common/hooks/useVirtualKeyboard';
17
17
  import { PreventScroll } from '../common/preventScroll/PreventScroll';
18
+ import { Size } from '../common/propsValues/size';
18
19
 
19
20
  export interface BottomSheetProps {
20
21
  open: boolean;
@@ -32,19 +33,6 @@ export interface BottomSheetProps {
32
33
  onCloseEnd?: () => void;
33
34
  }
34
35
 
35
- /**
36
- * App pages set scroll-behavior to 'smooth' which causes mobile Safari to
37
- * slow-scroll and glitch. This function temporarily disables that behaviour
38
- * while the BottomSheet is open. It complements <PreventScroll />.
39
- */
40
- const freezeScroll = (shouldFreeze = true) => {
41
- if (shouldFreeze) {
42
- document.documentElement.classList.add('wds-select-input-scroll-freeze');
43
- } else {
44
- document.documentElement.classList.remove('wds-select-input-scroll-freeze');
45
- }
46
- };
47
-
48
36
  export function BottomSheet({
49
37
  open,
50
38
  renderTrigger,
@@ -66,10 +54,6 @@ export function BottomSheet({
66
54
  },
67
55
  });
68
56
 
69
- useEffect(() => {
70
- freezeScroll(open);
71
- }, [open]);
72
-
73
57
  const dismiss = useDismiss(context);
74
58
  const role = useRole(context);
75
59
  const { getReferenceProps, getFloatingProps } = useInteractions([dismiss, role]);
package/src/main.css CHANGED
@@ -3524,13 +3524,6 @@ html:not([dir="rtl"]) .np-flow-navigation--sm .np-flow-navigation__stepper {
3524
3524
  padding-inline-start: 8px;
3525
3525
  padding-inline-start: var(--size-8);
3526
3526
  }
3527
- .wds-select-input-scroll-freeze {
3528
- scroll-behavior: unset !important;
3529
- height: 100vh;
3530
- }
3531
- .wds-select-input-scroll-freeze body {
3532
- height: 100vh;
3533
- }
3534
3527
  .np-bottom-sheet-v2-container {
3535
3528
  position: relative;
3536
3529
  z-index: 1060;
@@ -3544,8 +3537,6 @@ html:not([dir="rtl"]) .np-flow-navigation--sm .np-flow-navigation__stepper {
3544
3537
  transition-property: opacity;
3545
3538
  transition-timing-function: ease-out;
3546
3539
  transition-duration: 300ms;
3547
- will-change: transform;
3548
- min-height: 100vh;
3549
3540
  }
3550
3541
  .np-bottom-sheet-v2-backdrop--closed {
3551
3542
  opacity: 0;
@@ -3553,7 +3544,7 @@ html:not([dir="rtl"]) .np-flow-navigation--sm .np-flow-navigation__stepper {
3553
3544
  .np-bottom-sheet-v2 {
3554
3545
  position: fixed;
3555
3546
  inset: 0px;
3556
- bottom: env(safe-area-inset-bottom, 0);
3547
+ bottom: env(keyboard-inset-height, 0px);
3557
3548
  margin-left: 8px;
3558
3549
  margin-left: var(--size-8);
3559
3550
  margin-right: 8px;
@@ -3563,19 +3554,18 @@ html:not([dir="rtl"]) .np-flow-navigation--sm .np-flow-navigation__stepper {
3563
3554
  display: flex;
3564
3555
  flex-direction: column;
3565
3556
  justify-content: flex-end;
3566
- height: calc(100vh - 64px - 40px);
3567
- height: calc(100vh - var(--size-64) - 40px);
3568
3557
  }
3569
3558
  .np-bottom-sheet-v2-content {
3570
3559
  display: flex;
3571
3560
  flex-direction: column;
3572
3561
  overflow: auto;
3573
- border-radius: 32px;
3574
- border-radius: var(--size-32);
3562
+ border-top-left-radius: 32px;
3563
+ /* TODO: Tokenize */
3564
+ border-top-right-radius: 32px;
3565
+ /* TODO: Tokenize */
3575
3566
  background-color: #ffffff;
3576
3567
  background-color: var(--color-background-elevated);
3577
3568
  box-shadow: 0 0 40px rgba(69, 71, 69, 0.2);
3578
- will-change: transform;
3579
3569
  }
3580
3570
  .np-bottom-sheet-v2-content:focus {
3581
3571
  outline: none;