@transferwise/components 0.0.0-experimental-94710bd → 0.0.0-experimental-d7e8cfa
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.
- package/build/ExpressiveMoneyInput/CurrencySelector/CurrencySelector.js +5 -3
- package/build/ExpressiveMoneyInput/CurrencySelector/CurrencySelector.js.map +1 -1
- package/build/ExpressiveMoneyInput/CurrencySelector/CurrencySelector.mjs +5 -3
- package/build/ExpressiveMoneyInput/CurrencySelector/CurrencySelector.mjs.map +1 -1
- package/build/Inputs/SelectInput/TriggerButton/SelectInputTriggerButton.js.map +1 -1
- package/build/Inputs/SelectInput/TriggerButton/SelectInputTriggerButton.mjs.map +1 -1
- package/build/Typeahead/Typeahead.js +53 -27
- package/build/Typeahead/Typeahead.js.map +1 -1
- package/build/Typeahead/Typeahead.messages.js +3 -0
- package/build/Typeahead/Typeahead.messages.js.map +1 -1
- package/build/Typeahead/Typeahead.messages.mjs +3 -0
- package/build/Typeahead/Typeahead.messages.mjs.map +1 -1
- package/build/Typeahead/Typeahead.mjs +53 -27
- package/build/Typeahead/Typeahead.mjs.map +1 -1
- package/build/Typeahead/TypeaheadInput/TypeaheadInput.js +2 -2
- package/build/Typeahead/TypeaheadInput/TypeaheadInput.js.map +1 -1
- package/build/Typeahead/TypeaheadInput/TypeaheadInput.mjs +2 -2
- package/build/Typeahead/TypeaheadInput/TypeaheadInput.mjs.map +1 -1
- package/build/Typeahead/TypeaheadOption/TypeaheadOption.js +3 -1
- package/build/Typeahead/TypeaheadOption/TypeaheadOption.js.map +1 -1
- package/build/Typeahead/TypeaheadOption/TypeaheadOption.mjs +3 -1
- package/build/Typeahead/TypeaheadOption/TypeaheadOption.mjs.map +1 -1
- package/build/i18n/en.json +1 -0
- package/build/i18n/en.json.js +1 -0
- package/build/i18n/en.json.js.map +1 -1
- package/build/i18n/en.json.mjs +1 -0
- package/build/i18n/en.json.mjs.map +1 -1
- package/build/main.css +10 -0
- package/build/styles/Typeahead/Typeahead.css +4 -0
- package/build/styles/Typeahead/TypeaheadOption/TypeaheadOption.css +5 -0
- package/build/styles/main.css +10 -0
- package/build/types/ExpressiveMoneyInput/CurrencySelector/CurrencySelector.d.ts +4 -6
- package/build/types/ExpressiveMoneyInput/CurrencySelector/CurrencySelector.d.ts.map +1 -1
- package/build/types/Inputs/SelectInput/TriggerButton/SelectInputTriggerButton.d.ts +1 -1
- package/build/types/Inputs/SelectInput/TriggerButton/SelectInputTriggerButton.d.ts.map +1 -1
- package/build/types/Typeahead/Typeahead.d.ts.map +1 -1
- package/build/types/Typeahead/Typeahead.messages.d.ts +5 -0
- package/build/types/Typeahead/Typeahead.messages.d.ts.map +1 -1
- package/build/types/Typeahead/TypeaheadInput/TypeaheadInput.d.ts.map +1 -1
- package/build/types/Typeahead/TypeaheadOption/TypeaheadOption.d.ts +1 -0
- package/build/types/Typeahead/TypeaheadOption/TypeaheadOption.d.ts.map +1 -1
- package/build/types/test-utils/index.d.ts +2 -0
- package/build/types/test-utils/index.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/ExpressiveMoneyInput/CurrencySelector/CurrencySelector.tsx +13 -12
- package/src/Inputs/SelectInput/SelectInput.test.tsx +0 -37
- package/src/Inputs/SelectInput/TriggerButton/SelectInputTriggerButton.tsx +1 -1
- package/src/Typeahead/Typeahead.css +4 -0
- package/src/Typeahead/Typeahead.less +2 -0
- package/src/Typeahead/Typeahead.messages.ts +5 -0
- package/src/Typeahead/Typeahead.test.tsx +80 -3
- package/src/Typeahead/Typeahead.tsx +50 -27
- package/src/Typeahead/TypeaheadInput/TypeaheadInput.tsx +2 -6
- package/src/Typeahead/TypeaheadOption/TypeaheadOption.css +5 -0
- package/src/Typeahead/TypeaheadOption/TypeaheadOption.less +9 -0
- package/src/Typeahead/TypeaheadOption/TypeaheadOption.tsx +4 -2
- package/src/main.css +10 -0
package/build/styles/main.css
CHANGED
|
@@ -34122,6 +34122,10 @@ html:not([dir="rtl"]) .np-navigation-option {
|
|
|
34122
34122
|
.typeahead .dropdown-menu {
|
|
34123
34123
|
max-width: 100%;
|
|
34124
34124
|
width: 100%;
|
|
34125
|
+
scroll-padding-top: 8px;
|
|
34126
|
+
scroll-padding-top: var(--size-8);
|
|
34127
|
+
scroll-padding-bottom: 8px;
|
|
34128
|
+
scroll-padding-bottom: var(--size-8);
|
|
34125
34129
|
}
|
|
34126
34130
|
|
|
34127
34131
|
.np-theme-personal--forest-green .typeahead .dropdown-menu,
|
|
@@ -34348,6 +34352,12 @@ html:not([dir="rtl"]) .np-navigation-option {
|
|
|
34348
34352
|
border-radius: var(--radius-small);
|
|
34349
34353
|
}
|
|
34350
34354
|
|
|
34355
|
+
.dropdown-menu > li.typeahead__option:not(.active):not(.selected) > .dropdown-item:not([disabled]):not(.disabled):hover,
|
|
34356
|
+
.dropdown-menu > li.typeahead__option:not(.active):not(.selected) > .dropdown-item:not([disabled]):not(.disabled):focus,
|
|
34357
|
+
.dropdown-menu > li.typeahead__option:not(.active):not(.selected) > .dropdown-item:not([disabled]):not(.disabled):active {
|
|
34358
|
+
box-shadow: none;
|
|
34359
|
+
}
|
|
34360
|
+
|
|
34351
34361
|
.tw-droppable-lg {
|
|
34352
34362
|
min-height: 346px;
|
|
34353
34363
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { AvatarLayoutProps } from '../../AvatarLayout';
|
|
2
|
-
import type { NewButtonProps } from '../../Button';
|
|
3
2
|
import type { CurrencyType, ExpressiveMoneyInputProps } from '../ExpressiveMoneyInput';
|
|
3
|
+
import { type ButtonHTMLAttributes } from 'react';
|
|
4
4
|
export interface CurrencyOption {
|
|
5
5
|
label?: string;
|
|
6
6
|
code: string;
|
|
@@ -23,10 +23,8 @@ export type CurrencySelectorProps = {
|
|
|
23
23
|
resultCount: number;
|
|
24
24
|
}) => void;
|
|
25
25
|
} & Pick<ExpressiveMoneyInputProps, 'currency'>;
|
|
26
|
-
type ButtonInputProps = Omit<Extract<NewButtonProps, {
|
|
27
|
-
as?: 'button';
|
|
28
|
-
}>, 'v2' | 'size' | 'priority' | 'className' | 'href' | 'target'>;
|
|
29
26
|
export declare const CurrencySelector: ({ id, currency, options, labelId, onChange, addons, onOpen, onSearchChange, }: CurrencySelectorProps) => import("react").JSX.Element;
|
|
30
|
-
export declare const ButtonInput: import("react").ForwardRefExoticComponent<
|
|
31
|
-
|
|
27
|
+
export declare const ButtonInput: import("react").ForwardRefExoticComponent<ButtonHTMLAttributes<HTMLButtonElement> & {
|
|
28
|
+
children?: import("react").ReactNode | undefined;
|
|
29
|
+
} & import("react").RefAttributes<HTMLButtonElement | null>>;
|
|
32
30
|
//# sourceMappingURL=CurrencySelector.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CurrencySelector.d.ts","sourceRoot":"","sources":["../../../../src/ExpressiveMoneyInput/CurrencySelector/CurrencySelector.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;
|
|
1
|
+
{"version":3,"file":"CurrencySelector.d.ts","sourceRoot":"","sources":["../../../../src/ExpressiveMoneyInput/CurrencySelector/CurrencySelector.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AAO5D,OAAO,KAAK,EAAE,YAAY,EAAE,yBAAyB,EAAE,MAAM,yBAAyB,CAAC;AAGvF,OAAO,EACL,KAAK,oBAAoB,EAK1B,MAAM,OAAO,CAAC;AAOf,MAAM,WAAW,cAAc;IAC7B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,EAAE,GAAG,SAAS,CAAC;CAChC;AAED,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,cAAc,EAAE,CAAC;CAC9B;AAED,MAAM,MAAM,eAAe,GAAG,eAAe,EAAE,CAAC;AAEhD,MAAM,MAAM,qBAAqB,GAAG;IAClC,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,eAAe,CAAC;IAC1B,QAAQ,CAAC,EAAE,CAAC,QAAQ,EAAE,YAAY,KAAK,IAAI,CAAC;IAC5C,MAAM,CAAC,EAAE,MAAM,IAAI,CAAC;IACpB,MAAM,CAAC,EAAE,iBAAiB,CAAC,SAAS,CAAC,CAAC;IACtC,cAAc,CAAC,EAAE,CAAC,OAAO,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,MAAM,CAAA;KAAE,KAAK,IAAI,CAAC;CAC5E,GAAG,IAAI,CAAC,yBAAyB,EAAE,UAAU,CAAC,CAAC;AAEhD,eAAO,MAAM,gBAAgB,GAAI,+EAS9B,qBAAqB,gCAgGvB,CAAC;AAEF,eAAO,MAAM,WAAW;;4DAgBtB,CAAC"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Merge } from '../../../utils';
|
|
2
|
-
export type SelectInputTriggerButtonElementType = React.
|
|
2
|
+
export type SelectInputTriggerButtonElementType = 'button' | React.ComponentType;
|
|
3
3
|
export type SelectInputTriggerButtonProps<T extends SelectInputTriggerButtonElementType = 'button'> = Merge<React.ComponentPropsWithoutRef<T>, {
|
|
4
4
|
as?: T;
|
|
5
5
|
}>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SelectInputTriggerButton.d.ts","sourceRoot":"","sources":["../../../../../src/Inputs/SelectInput/TriggerButton/SelectInputTriggerButton.tsx"],"names":[],"mappings":"AAIA,OAAO,EAAE,KAAK,EAAE,MAAM,gBAAgB,CAAC;AAGvC,MAAM,MAAM,mCAAmC,GAAG,KAAK,CAAC,
|
|
1
|
+
{"version":3,"file":"SelectInputTriggerButton.d.ts","sourceRoot":"","sources":["../../../../../src/Inputs/SelectInput/TriggerButton/SelectInputTriggerButton.tsx"],"names":[],"mappings":"AAIA,OAAO,EAAE,KAAK,EAAE,MAAM,gBAAgB,CAAC;AAGvC,MAAM,MAAM,mCAAmC,GAAG,QAAQ,GAAG,KAAK,CAAC,aAAa,CAAC;AAEjF,MAAM,MAAM,6BAA6B,CACvC,CAAC,SAAS,mCAAmC,GAAG,QAAQ,IACtD,KAAK,CAAC,KAAK,CAAC,wBAAwB,CAAC,CAAC,CAAC,EAAE;IAAE,EAAE,CAAC,EAAE,CAAC,CAAA;CAAE,CAAC,CAAC;AAEzD;;;;GAIG;AACH,wBAAgB,wBAAwB,CAAC,CAAC,SAAS,mCAAmC,GAAG,QAAQ,EAAE,EACjG,EAAkB,EAClB,GAAG,SAAS,EACb,EAAE,6BAA6B,CAAC,CAAC,CAAC,+BAclC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Typeahead.d.ts","sourceRoot":"","sources":["../../../src/Typeahead/Typeahead.tsx"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,EAAa,SAAS,EAAE,MAAM,OAAO,CAAC;AACpD,OAAO,EAAc,KAAK,qBAAqB,EAAE,MAAM,sBAAsB,CAAC;AAG9E,OAAO,EAEL,SAAS,EACT,UAAU,EACV,SAAS,EAIV,MAAM,WAAW,CAAC;AACnB,OAAO,EAAgB,iBAAiB,EAAE,MAAM,WAAW,CAAC;AAU5D,MAAM,MAAM,eAAe,CAAC,CAAC,GAAG,MAAM,IAAI;IACxC,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,CAAC,CAAC;IACV,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B,iBAAiB,CAAC,EAAE,OAAO,CAAC;CAC7B,CAAC;AAEF,MAAM,WAAW,cAAc,CAAC,CAAC,CAAE,SAAQ,OAAO,CAAC,qBAAqB,CAAC;IACvE,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,SAAS,CAAC;IAClB;;;OAGG;IACH,KAAK,CAAC,EAAE;QACN,OAAO,EAAE,iBAAiB,CAAC,UAAU,CAAC,CAAC;QACvC,IAAI,CAAC,EACD,iBAAiB,CAAC,WAAW,CAAC,GAC9B,GAAG,SAAS,CAAC,KAAK,EAAE,GACpB,GAAG,SAAS,CAAC,IAAI,EAAE,GACnB,GAAG,SAAS,CAAC,OAAO,EAAE,CAAC;KAC5B,CAAC;IACF,qBAAqB;IACrB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,oBAAoB;IACpB,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,qBAAqB;IACrB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,kBAAkB;IAClB,cAAc,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACnC,oBAAoB;IACpB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,MAAM,CAAC,EAAE,SAAS,CAAC;IACnB,kBAAkB;IAClB,YAAY,CAAC,EAAE,SAAS,eAAe,CAAC,CAAC,CAAC,EAAE,CAAC;IAC7C,8BAA8B;IAC9B,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,iBAAiB;IACjB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,qBAAqB;IACrB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,OAAO,EAAE,SAAS,eAAe,CAAC,CAAC,CAAC,EAAE,CAAC;IACvC,mBAAmB;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,oBAAoB;IACpB,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,oBAAoB;IACpB,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,oBAAoB;IACpB,IAAI,CAAC,EAAE,UAAU,GAAG,SAAS,CAAC;IAC9B,MAAM,CAAC,EAAE,MAAM,IAAI,CAAC;IACpB,QAAQ,EAAE,CAAC,OAAO,EAAE,eAAe,CAAC,CAAC,CAAC,EAAE,KAAK,IAAI,CAAC;IAClD,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACxC,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACnC,YAAY,CAAC,EAAE,CAAC,IAAI,EAAE,eAAe,CAAC,CAAC,CAAC,KAAK,OAAO,CAAC;CACtD;
|
|
1
|
+
{"version":3,"file":"Typeahead.d.ts","sourceRoot":"","sources":["../../../src/Typeahead/Typeahead.tsx"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,EAAa,SAAS,EAAE,MAAM,OAAO,CAAC;AACpD,OAAO,EAAc,KAAK,qBAAqB,EAAE,MAAM,sBAAsB,CAAC;AAG9E,OAAO,EAEL,SAAS,EACT,UAAU,EACV,SAAS,EAIV,MAAM,WAAW,CAAC;AACnB,OAAO,EAAgB,iBAAiB,EAAE,MAAM,WAAW,CAAC;AAU5D,MAAM,MAAM,eAAe,CAAC,CAAC,GAAG,MAAM,IAAI;IACxC,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,CAAC,CAAC;IACV,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B,iBAAiB,CAAC,EAAE,OAAO,CAAC;CAC7B,CAAC;AAEF,MAAM,WAAW,cAAc,CAAC,CAAC,CAAE,SAAQ,OAAO,CAAC,qBAAqB,CAAC;IACvE,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,SAAS,CAAC;IAClB;;;OAGG;IACH,KAAK,CAAC,EAAE;QACN,OAAO,EAAE,iBAAiB,CAAC,UAAU,CAAC,CAAC;QACvC,IAAI,CAAC,EACD,iBAAiB,CAAC,WAAW,CAAC,GAC9B,GAAG,SAAS,CAAC,KAAK,EAAE,GACpB,GAAG,SAAS,CAAC,IAAI,EAAE,GACnB,GAAG,SAAS,CAAC,OAAO,EAAE,CAAC;KAC5B,CAAC;IACF,qBAAqB;IACrB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,oBAAoB;IACpB,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,qBAAqB;IACrB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,kBAAkB;IAClB,cAAc,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACnC,oBAAoB;IACpB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,MAAM,CAAC,EAAE,SAAS,CAAC;IACnB,kBAAkB;IAClB,YAAY,CAAC,EAAE,SAAS,eAAe,CAAC,CAAC,CAAC,EAAE,CAAC;IAC7C,8BAA8B;IAC9B,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,iBAAiB;IACjB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,qBAAqB;IACrB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,OAAO,EAAE,SAAS,eAAe,CAAC,CAAC,CAAC,EAAE,CAAC;IACvC,mBAAmB;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,oBAAoB;IACpB,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,oBAAoB;IACpB,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,oBAAoB;IACpB,IAAI,CAAC,EAAE,UAAU,GAAG,SAAS,CAAC;IAC9B,MAAM,CAAC,EAAE,MAAM,IAAI,CAAC;IACpB,QAAQ,EAAE,CAAC,OAAO,EAAE,eAAe,CAAC,CAAC,CAAC,EAAE,KAAK,IAAI,CAAC;IAClD,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACxC,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACnC,YAAY,CAAC,EAAE,CAAC,IAAI,EAAE,eAAe,CAAC,CAAC,CAAC,KAAK,OAAO,CAAC;CACtD;wBA6gBoF,CAAC,CAAC,EACrF,KAAK,EAAE,cAAc,CAAC,CAAC,CAAC,KACrB,KAAK,CAAC,YAAY;AAFvB,wBAEwB"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Typeahead.messages.d.ts","sourceRoot":"","sources":["../../../src/Typeahead/Typeahead.messages.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"Typeahead.messages.d.ts","sourceRoot":"","sources":["../../../src/Typeahead/Typeahead.messages.ts"],"names":[],"mappings":";;;;;;;;;;;;AAEA,wBAWG"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TypeaheadInput.d.ts","sourceRoot":"","sources":["../../../../src/Typeahead/TypeaheadInput/TypeaheadInput.tsx"],"names":[],"mappings":"AAIA,OAAO,EAAE,SAAS,EAAa,SAAS,EAAE,MAAM,OAAO,CAAC;AAGxD,OAAO,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAI/D,MAAM,MAAM,mBAAmB,CAAC,CAAC,IAAI;IACnC,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,SAAS,eAAe,CAAC,CAAC,CAAC,EAAE,CAAC;IACxC,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,YAAY,EAAE,MAAM,CAAC;IACrB,QAAQ,EAAE,KAAK,CAAC,kBAAkB,CAAC,gBAAgB,CAAC,CAAC;IACrD,SAAS,EAAE,KAAK,CAAC,oBAAoB,CAAC,gBAAgB,CAAC,CAAC;IACxD,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,OAAO,EAAE,KAAK,CAAC,qBAAqB,CAAC,gBAAgB,CAAC,CAAC;IACvD,UAAU,EAAE,CAAC,IAAI,EAAE,eAAe,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,MAAM,KAAK,SAAS,CAAC;IACnE,oBAAoB,CAAC,EAAE,MAAM,CAAC;CAC/B,GAAG,IAAI,CAAC,cAAc,CAAC,CAAC,CAAC,EAAE,IAAI,GAAG,MAAM,GAAG,WAAW,GAAG,UAAU,GAAG,aAAa,GAAG,WAAW,CAAC,CAAC;AAEpG,KAAK,mBAAmB,GAAG;IACzB,UAAU,EAAE,MAAM,CAAC;IACnB,0BAA0B,EAAE,MAAM,GAAG,IAAI,CAAC;CAC3C,CAAC;AAEF,MAAM,CAAC,OAAO,OAAO,cAAc,CAAC,CAAC,CAAE,SAAQ,SAAS,CACtD,mBAAmB,CAAC,CAAC,CAAC,EACtB,mBAAmB,CACpB;IACC,QAAQ,8CAAiC;IACzC,QAAQ,4CAA+B;gBAE3B,KAAK,EAAE,mBAAmB,CAAC,CAAC,CAAC;IAQzC,iBAAiB;IAUjB,kBAAkB,CAAC,aAAa,EAAE,mBAAmB,CAAC,CAAC,CAAC;IAMxD,gBAAgB,aAMd;IAEF,WAAW,
|
|
1
|
+
{"version":3,"file":"TypeaheadInput.d.ts","sourceRoot":"","sources":["../../../../src/Typeahead/TypeaheadInput/TypeaheadInput.tsx"],"names":[],"mappings":"AAIA,OAAO,EAAE,SAAS,EAAa,SAAS,EAAE,MAAM,OAAO,CAAC;AAGxD,OAAO,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAI/D,MAAM,MAAM,mBAAmB,CAAC,CAAC,IAAI;IACnC,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,SAAS,eAAe,CAAC,CAAC,CAAC,EAAE,CAAC;IACxC,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,YAAY,EAAE,MAAM,CAAC;IACrB,QAAQ,EAAE,KAAK,CAAC,kBAAkB,CAAC,gBAAgB,CAAC,CAAC;IACrD,SAAS,EAAE,KAAK,CAAC,oBAAoB,CAAC,gBAAgB,CAAC,CAAC;IACxD,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,OAAO,EAAE,KAAK,CAAC,qBAAqB,CAAC,gBAAgB,CAAC,CAAC;IACvD,UAAU,EAAE,CAAC,IAAI,EAAE,eAAe,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,MAAM,KAAK,SAAS,CAAC;IACnE,oBAAoB,CAAC,EAAE,MAAM,CAAC;CAC/B,GAAG,IAAI,CAAC,cAAc,CAAC,CAAC,CAAC,EAAE,IAAI,GAAG,MAAM,GAAG,WAAW,GAAG,UAAU,GAAG,aAAa,GAAG,WAAW,CAAC,CAAC;AAEpG,KAAK,mBAAmB,GAAG;IACzB,UAAU,EAAE,MAAM,CAAC;IACnB,0BAA0B,EAAE,MAAM,GAAG,IAAI,CAAC;CAC3C,CAAC;AAEF,MAAM,CAAC,OAAO,OAAO,cAAc,CAAC,CAAC,CAAE,SAAQ,SAAS,CACtD,mBAAmB,CAAC,CAAC,CAAC,EACtB,mBAAmB,CACpB;IACC,QAAQ,8CAAiC;IACzC,QAAQ,4CAA+B;gBAE3B,KAAK,EAAE,mBAAmB,CAAC,CAAC,CAAC;IAQzC,iBAAiB;IAUjB,kBAAkB,CAAC,aAAa,EAAE,mBAAmB,CAAC,CAAC,CAAC;IAMxD,gBAAgB,aAMd;IAEF,WAAW,oCA4CT;IAEF,MAAM;CAyBP"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TypeaheadOption.d.ts","sourceRoot":"","sources":["../../../../src/Typeahead/TypeaheadOption/TypeaheadOption.tsx"],"names":[],"mappings":"AAGA,OAAO,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAG/C,MAAM,MAAM,oBAAoB,CAAC,CAAC,IAAI;IACpC,MAAM,EAAE,eAAe,CAAC,CAAC,CAAC,CAAC;IAC3B,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,OAAO,CAAC,EAAE,KAAK,CAAC,iBAAiB,CAAC;IAClC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,EAAE,CAAC,EAAE,MAAM,CAAC;CACb,CAAC;AAEF,QAAA,MAAM,MAAM,
|
|
1
|
+
{"version":3,"file":"TypeaheadOption.d.ts","sourceRoot":"","sources":["../../../../src/Typeahead/TypeaheadOption/TypeaheadOption.tsx"],"names":[],"mappings":"AAGA,OAAO,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAG/C,MAAM,MAAM,oBAAoB,CAAC,CAAC,IAAI;IACpC,MAAM,EAAE,eAAe,CAAC,CAAC,CAAC,CAAC;IAC3B,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,OAAO,CAAC,EAAE,KAAK,CAAC,iBAAiB,CAAC;IAClC,YAAY,CAAC,EAAE,KAAK,CAAC,iBAAiB,CAAC;IACvC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,EAAE,CAAC,EAAE,MAAM,CAAC;CACb,CAAC;AAEF,QAAA,MAAM,MAAM,qHA4BV,CAAC;AAEH,eAAe,MAAM,CAAC"}
|
|
@@ -56,6 +56,7 @@ declare function customRender(ui: ReactElement, { locale, messages, ...renderOpt
|
|
|
56
56
|
"neptune.Table.loaded": string;
|
|
57
57
|
"neptune.Table.loading": string;
|
|
58
58
|
"neptune.Table.refreshPage": string;
|
|
59
|
+
"neptune.Typeahead.suggestionsLabel": string;
|
|
59
60
|
"neptune.Upload.csButtonText": string;
|
|
60
61
|
"neptune.Upload.csFailureText": string;
|
|
61
62
|
"neptune.Upload.csSuccessText": string;
|
|
@@ -144,6 +145,7 @@ declare function customRenderHook(callback: () => unknown, { locale, messages }?
|
|
|
144
145
|
"neptune.Table.loaded": string;
|
|
145
146
|
"neptune.Table.loading": string;
|
|
146
147
|
"neptune.Table.refreshPage": string;
|
|
148
|
+
"neptune.Typeahead.suggestionsLabel": string;
|
|
147
149
|
"neptune.Upload.csButtonText": string;
|
|
148
150
|
"neptune.Upload.csFailureText": string;
|
|
149
151
|
"neptune.Upload.csSuccessText": string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/test-utils/index.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAM,MAAM,OAAO,CAAC;AACzC,OAAO,EAAE,MAAM,EAAc,MAAM,wBAAwB,CAAC;AAC5D,OAAO,EAAE,SAAS,EAAE,MAAM,6BAA6B,CAAC;AAMxD;;;;GAIG;AACH,iBAAS,YAAY,CACnB,EAAE,EAAE,YAAY,EAChB,EAAE,MAAuB,EAAE,QAAa,EAAE,GAAG,aAAa,EAAE
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/test-utils/index.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAM,MAAM,OAAO,CAAC;AACzC,OAAO,EAAE,MAAM,EAAc,MAAM,wBAAwB,CAAC;AAC5D,OAAO,EAAE,SAAS,EAAE,MAAM,6BAA6B,CAAC;AAMxD;;;;GAIG;AACH,iBAAS,YAAY,CACnB,EAAE,EAAE,YAAY,EAChB,EAAE,MAAuB,EAAE,QAAa,EAAE,GAAG,aAAa,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAAK,GAChE,UAAU,CAAC,OAAO,MAAM,CAAC,CAK3B;AAED;;;GAGG;AACH,iBAAS,gBAAgB,CACvB,QAAQ,EAAE,MAAM,OAAO,EACvB,EAAE,MAAuB,EAAE,QAAa,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAAK,uEAKhD;AAED,cAAc,wBAAwB,CAAC;AACvC,cAAc,aAAa,CAAC;AAC5B,cAAc,eAAe,CAAC;AAC9B,OAAO,EAAE,YAAY,IAAI,MAAM,EAAE,gBAAgB,IAAI,UAAU,EAAE,SAAS,EAAE,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import type { AvatarLayoutProps } from '../../AvatarLayout';
|
|
2
2
|
import Button from '../../Button';
|
|
3
|
-
import type { NewButtonProps } from '../../Button';
|
|
4
3
|
import {
|
|
5
4
|
SelectInput,
|
|
6
5
|
SelectInputOptionContent,
|
|
@@ -9,7 +8,13 @@ import {
|
|
|
9
8
|
import type { CurrencyType, ExpressiveMoneyInputProps } from '../ExpressiveMoneyInput';
|
|
10
9
|
import { ChevronDown } from '@transferwise/icons';
|
|
11
10
|
import { Flag } from '@wise/art';
|
|
12
|
-
import {
|
|
11
|
+
import {
|
|
12
|
+
type ButtonHTMLAttributes,
|
|
13
|
+
forwardRef,
|
|
14
|
+
type MouseEventHandler,
|
|
15
|
+
useMemo,
|
|
16
|
+
useState,
|
|
17
|
+
} from 'react';
|
|
13
18
|
import { useIntl } from 'react-intl';
|
|
14
19
|
|
|
15
20
|
import messages from '../ExpressiveMoneyInput.messages';
|
|
@@ -39,11 +44,6 @@ export type CurrencySelectorProps = {
|
|
|
39
44
|
onSearchChange?: (payload: { query: string; resultCount: number }) => void;
|
|
40
45
|
} & Pick<ExpressiveMoneyInputProps, 'currency'>;
|
|
41
46
|
|
|
42
|
-
type ButtonInputProps = Omit<
|
|
43
|
-
Extract<NewButtonProps, { as?: 'button' }>,
|
|
44
|
-
'v2' | 'size' | 'priority' | 'className' | 'href' | 'target'
|
|
45
|
-
>;
|
|
46
|
-
|
|
47
47
|
export const CurrencySelector = ({
|
|
48
48
|
id,
|
|
49
49
|
currency,
|
|
@@ -109,6 +109,7 @@ export const CurrencySelector = ({
|
|
|
109
109
|
renderTrigger={() => (
|
|
110
110
|
<SelectInputTriggerButton
|
|
111
111
|
as={ButtonInput}
|
|
112
|
+
// @ts-expect-error new (v2) ButtonProps
|
|
112
113
|
addonStart={{
|
|
113
114
|
type: 'avatar',
|
|
114
115
|
value: [
|
|
@@ -121,11 +122,11 @@ export const CurrencySelector = ({
|
|
|
121
122
|
}),
|
|
122
123
|
},
|
|
123
124
|
]
|
|
124
|
-
.filter(
|
|
125
|
+
.filter(Boolean)
|
|
125
126
|
.filter((avatar) => !(avatar && Object.keys(avatar).length === 0)),
|
|
126
127
|
}}
|
|
127
128
|
addonEnd={disabled ? undefined : { type: 'icon', value: <ChevronDown /> }}
|
|
128
|
-
onClick={handleTriggerClick}
|
|
129
|
+
onClick={(event) => handleTriggerClick(event)}
|
|
129
130
|
>
|
|
130
131
|
<>
|
|
131
132
|
<span aria-hidden>{formatCurrencyCode(currency)}</span>
|
|
@@ -150,9 +151,9 @@ export const CurrencySelector = ({
|
|
|
150
151
|
);
|
|
151
152
|
};
|
|
152
153
|
|
|
153
|
-
export const ButtonInput = forwardRef
|
|
154
|
-
{ children, ...rest }
|
|
155
|
-
ref
|
|
154
|
+
export const ButtonInput = forwardRef(function ButtonInput(
|
|
155
|
+
{ children, ...rest }: React.PropsWithChildren<ButtonHTMLAttributes<HTMLButtonElement>>,
|
|
156
|
+
ref: React.ForwardedRef<HTMLButtonElement | null>,
|
|
156
157
|
) {
|
|
157
158
|
return (
|
|
158
159
|
<Button
|
|
@@ -7,12 +7,9 @@ import { render, mockMatchMedia, mockResizeObserver } from '../../test-utils';
|
|
|
7
7
|
import {
|
|
8
8
|
SelectInput,
|
|
9
9
|
SelectInputOptionContent,
|
|
10
|
-
SelectInputTriggerButton,
|
|
11
10
|
type SelectInputOptionItem,
|
|
12
11
|
type SelectInputProps,
|
|
13
12
|
} from '.';
|
|
14
|
-
import Button from '../../Button';
|
|
15
|
-
import type { ButtonProps as ResolverButtonProps } from '../../Button/Button.resolver';
|
|
16
13
|
import Field from '../../Field';
|
|
17
14
|
|
|
18
15
|
mockMatchMedia();
|
|
@@ -340,40 +337,6 @@ describe('SelectInput', () => {
|
|
|
340
337
|
expect(screen.getByLabelText(/Currency/)).toHaveAttribute('aria-haspopup');
|
|
341
338
|
});
|
|
342
339
|
|
|
343
|
-
it('renders addonStart and addonEnd when using trigger as Button', () => {
|
|
344
|
-
type V2ButtonProps = Extract<ResolverButtonProps, { v2: true }>;
|
|
345
|
-
|
|
346
|
-
render(
|
|
347
|
-
<SelectInput
|
|
348
|
-
items={[{ type: 'option', value: 'USD' }]}
|
|
349
|
-
renderTrigger={({ content, className, size }) => {
|
|
350
|
-
const triggerButtonProps: V2ButtonProps = {
|
|
351
|
-
v2: true,
|
|
352
|
-
size,
|
|
353
|
-
className,
|
|
354
|
-
addonStart: {
|
|
355
|
-
type: 'icon',
|
|
356
|
-
value: <span data-testid="select-trigger-addon-start">Start</span>,
|
|
357
|
-
},
|
|
358
|
-
addonEnd: {
|
|
359
|
-
type: 'icon',
|
|
360
|
-
value: <span data-testid="select-trigger-addon-end">End</span>,
|
|
361
|
-
},
|
|
362
|
-
};
|
|
363
|
-
|
|
364
|
-
return (
|
|
365
|
-
<SelectInputTriggerButton as={Button} {...triggerButtonProps}>
|
|
366
|
-
{content}
|
|
367
|
-
</SelectInputTriggerButton>
|
|
368
|
-
);
|
|
369
|
-
}}
|
|
370
|
-
/>,
|
|
371
|
-
);
|
|
372
|
-
|
|
373
|
-
expect(screen.getByTestId('select-trigger-addon-start')).toBeInTheDocument();
|
|
374
|
-
expect(screen.getByTestId('select-trigger-addon-end')).toBeInTheDocument();
|
|
375
|
-
});
|
|
376
|
-
|
|
377
340
|
it('deduplicates search results across groups using compareValues as key', async () => {
|
|
378
341
|
interface Currency {
|
|
379
342
|
code: string;
|
|
@@ -5,7 +5,7 @@ import { PolymorphicWithOverrides } from '../../../common/PolymorphicWithOverrid
|
|
|
5
5
|
import { Merge } from '../../../utils';
|
|
6
6
|
import { SelectInputTriggerButtonPropsContext } from '../SelectInput.contexts';
|
|
7
7
|
|
|
8
|
-
export type SelectInputTriggerButtonElementType = React.
|
|
8
|
+
export type SelectInputTriggerButtonElementType = 'button' | React.ComponentType;
|
|
9
9
|
|
|
10
10
|
export type SelectInputTriggerButtonProps<
|
|
11
11
|
T extends SelectInputTriggerButtonElementType = 'button',
|
|
@@ -7,6 +7,10 @@
|
|
|
7
7
|
.typeahead .dropdown-menu {
|
|
8
8
|
max-width: 100%;
|
|
9
9
|
width: 100%;
|
|
10
|
+
scroll-padding-top: 8px;
|
|
11
|
+
scroll-padding-top: var(--size-8);
|
|
12
|
+
scroll-padding-bottom: 8px;
|
|
13
|
+
scroll-padding-bottom: var(--size-8);
|
|
10
14
|
}
|
|
11
15
|
.np-theme-personal--forest-green .typeahead .dropdown-menu,
|
|
12
16
|
.np-theme-personal--bright-green .typeahead .dropdown-menu,
|
|
@@ -6,4 +6,9 @@ export default defineMessages({
|
|
|
6
6
|
defaultMessage: 'Clear',
|
|
7
7
|
description: 'Description of clear button',
|
|
8
8
|
},
|
|
9
|
+
suggestionsLabel: {
|
|
10
|
+
id: 'neptune.Typeahead.suggestionsLabel',
|
|
11
|
+
defaultMessage: 'Suggestions',
|
|
12
|
+
description: 'Accessible label for the list of typeahead suggestions',
|
|
13
|
+
},
|
|
9
14
|
});
|
|
@@ -1,11 +1,18 @@
|
|
|
1
1
|
import Field from '../Field';
|
|
2
|
-
import { mockMatchMedia, render, screen, fireEvent } from '../test-utils';
|
|
2
|
+
import { mockMatchMedia, render, screen, fireEvent, userEvent } from '../test-utils';
|
|
3
3
|
import { wait } from '../test-utils/wait';
|
|
4
4
|
import Typeahead from './Typeahead';
|
|
5
5
|
|
|
6
6
|
mockMatchMedia();
|
|
7
7
|
|
|
8
|
+
const scrollIntoView = jest.fn();
|
|
9
|
+
|
|
8
10
|
describe('Typeahead', () => {
|
|
11
|
+
beforeEach(() => {
|
|
12
|
+
HTMLElement.prototype.scrollIntoView = scrollIntoView;
|
|
13
|
+
scrollIntoView.mockClear();
|
|
14
|
+
});
|
|
15
|
+
|
|
9
16
|
it('supports `Field` for labeling', () => {
|
|
10
17
|
render(
|
|
11
18
|
<Field id="test" label="Tags">
|
|
@@ -22,7 +29,7 @@ describe('Typeahead', () => {
|
|
|
22
29
|
<Typeahead id="test" name="test" options={[]} onChange={() => {}} />
|
|
23
30
|
</Field>,
|
|
24
31
|
);
|
|
25
|
-
expect(screen.queryByRole('
|
|
32
|
+
expect(screen.queryByRole('listbox')).not.toBeInTheDocument();
|
|
26
33
|
});
|
|
27
34
|
it('does render a dropdown when only a footer is provided', () => {
|
|
28
35
|
render(
|
|
@@ -30,7 +37,7 @@ describe('Typeahead', () => {
|
|
|
30
37
|
<Typeahead id="test" name="test" options={[]} footer={<p>hello</p>} onChange={() => {}} />
|
|
31
38
|
</Field>,
|
|
32
39
|
);
|
|
33
|
-
expect(screen.getByRole('
|
|
40
|
+
expect(screen.getByRole('listbox')).toBeInTheDocument();
|
|
34
41
|
});
|
|
35
42
|
});
|
|
36
43
|
|
|
@@ -74,6 +81,76 @@ describe('Typeahead', () => {
|
|
|
74
81
|
expect(onChange).toHaveBeenCalled();
|
|
75
82
|
});
|
|
76
83
|
|
|
84
|
+
it('scrolls options into view when navigating with arrow keys', async () => {
|
|
85
|
+
render(
|
|
86
|
+
<Typeahead
|
|
87
|
+
id="test"
|
|
88
|
+
name="test"
|
|
89
|
+
options={[{ label: 'Option 1' }, { label: 'Option 2' }]}
|
|
90
|
+
minQueryLength={0}
|
|
91
|
+
onChange={() => {}}
|
|
92
|
+
/>,
|
|
93
|
+
);
|
|
94
|
+
const input = screen.getByRole('combobox');
|
|
95
|
+
|
|
96
|
+
await userEvent.click(input);
|
|
97
|
+
await userEvent.keyboard('{ArrowDown}{ArrowDown}');
|
|
98
|
+
|
|
99
|
+
expect(input).toHaveFocus();
|
|
100
|
+
expect(scrollIntoView).toHaveBeenCalledTimes(2);
|
|
101
|
+
expect(scrollIntoView).toHaveBeenNthCalledWith(1, { block: 'nearest' });
|
|
102
|
+
expect(scrollIntoView).toHaveBeenNthCalledWith(2, { block: 'nearest' });
|
|
103
|
+
expect(scrollIntoView.mock.contexts[0]).toBe(screen.getByText('Option 1').closest('li'));
|
|
104
|
+
expect(scrollIntoView.mock.contexts[1]).toBe(screen.getByText('Option 2').closest('li'));
|
|
105
|
+
});
|
|
106
|
+
|
|
107
|
+
it('uses one Tab stop for the suggestions', async () => {
|
|
108
|
+
render(
|
|
109
|
+
<>
|
|
110
|
+
<Typeahead
|
|
111
|
+
id="test"
|
|
112
|
+
name="test"
|
|
113
|
+
options={[{ label: 'Option 1' }, { label: 'Option 2' }]}
|
|
114
|
+
minQueryLength={0}
|
|
115
|
+
onChange={() => {}}
|
|
116
|
+
/>
|
|
117
|
+
<button type="button">Next control</button>
|
|
118
|
+
</>,
|
|
119
|
+
);
|
|
120
|
+
|
|
121
|
+
const input = screen.getByRole('combobox');
|
|
122
|
+
await userEvent.click(input);
|
|
123
|
+
await userEvent.tab();
|
|
124
|
+
|
|
125
|
+
expect(screen.getByRole('listbox')).toHaveFocus();
|
|
126
|
+
await userEvent.keyboard('{ArrowDown}');
|
|
127
|
+
expect(screen.getByRole('option', { name: 'Option 1' })).toHaveClass(
|
|
128
|
+
'tw-dropdown-item--focused',
|
|
129
|
+
);
|
|
130
|
+
expect(screen.getByRole('listbox')).toHaveFocus();
|
|
131
|
+
await userEvent.tab();
|
|
132
|
+
expect(screen.getByRole('button', { name: 'Next control' })).toHaveFocus();
|
|
133
|
+
});
|
|
134
|
+
|
|
135
|
+
it('uses the active option style when hovering a suggestion', async () => {
|
|
136
|
+
render(
|
|
137
|
+
<Typeahead
|
|
138
|
+
id="test"
|
|
139
|
+
name="test"
|
|
140
|
+
options={[{ label: 'Option 1' }, { label: 'Option 2' }]}
|
|
141
|
+
minQueryLength={0}
|
|
142
|
+
onChange={() => {}}
|
|
143
|
+
/>,
|
|
144
|
+
);
|
|
145
|
+
|
|
146
|
+
await userEvent.click(screen.getByRole('combobox'));
|
|
147
|
+
await userEvent.hover(screen.getByRole('option', { name: 'Option 2' }));
|
|
148
|
+
|
|
149
|
+
expect(screen.getByRole('option', { name: 'Option 2' })).toHaveClass(
|
|
150
|
+
'tw-dropdown-item--focused',
|
|
151
|
+
);
|
|
152
|
+
});
|
|
153
|
+
|
|
77
154
|
it('shows clear button when there is a value', () => {
|
|
78
155
|
render(
|
|
79
156
|
<Typeahead
|
|
@@ -216,31 +216,15 @@ class Typeahead<T> extends Component<TypeaheadPropsWithInputAttributes<T>, Typea
|
|
|
216
216
|
};
|
|
217
217
|
|
|
218
218
|
handleOnKeyDown: React.KeyboardEventHandler<HTMLInputElement> = (event) => {
|
|
219
|
-
const { showSuggestions, allowNew, multiple, chipSeparators
|
|
220
|
-
const {
|
|
219
|
+
const { showSuggestions, allowNew, multiple, chipSeparators } = this.props;
|
|
220
|
+
const { query, selected } = this.state;
|
|
221
221
|
const chipsMode = !showSuggestions && allowNew && multiple;
|
|
222
222
|
|
|
223
223
|
if (chipsMode && ['Enter', 'Tab', ...chipSeparators].includes(event.key) && query.trim()) {
|
|
224
224
|
event.preventDefault();
|
|
225
225
|
this.selectItem({ label: query });
|
|
226
|
-
} else {
|
|
226
|
+
} else if (!this.handleOptionNavigation(event)) {
|
|
227
227
|
switch (event.key) {
|
|
228
|
-
case 'ArrowDown':
|
|
229
|
-
event.preventDefault();
|
|
230
|
-
this.moveFocusedOption(1);
|
|
231
|
-
break;
|
|
232
|
-
case 'ArrowUp':
|
|
233
|
-
event.preventDefault();
|
|
234
|
-
this.moveFocusedOption(-1);
|
|
235
|
-
break;
|
|
236
|
-
case 'Enter':
|
|
237
|
-
event.preventDefault();
|
|
238
|
-
if (keyboardFocusedOptionIndex != null && options[keyboardFocusedOptionIndex]) {
|
|
239
|
-
this.selectItem(options[keyboardFocusedOptionIndex]);
|
|
240
|
-
} else if (allowNew && query.trim()) {
|
|
241
|
-
this.selectItem({ label: query });
|
|
242
|
-
}
|
|
243
|
-
break;
|
|
244
228
|
case 'Backspace':
|
|
245
229
|
if (multiple && !query && selected.length > 0) {
|
|
246
230
|
this.updateSelectedValue(selected.slice(0, -1));
|
|
@@ -251,6 +235,36 @@ class Typeahead<T> extends Component<TypeaheadPropsWithInputAttributes<T>, Typea
|
|
|
251
235
|
}
|
|
252
236
|
}
|
|
253
237
|
};
|
|
238
|
+
|
|
239
|
+
handleOptionListKeyDown: React.KeyboardEventHandler<HTMLUListElement> = (event) => {
|
|
240
|
+
this.handleOptionNavigation(event);
|
|
241
|
+
};
|
|
242
|
+
|
|
243
|
+
handleOptionNavigation(event: React.KeyboardEvent<HTMLElement>) {
|
|
244
|
+
const { allowNew, options } = this.props;
|
|
245
|
+
const { keyboardFocusedOptionIndex, query } = this.state;
|
|
246
|
+
|
|
247
|
+
switch (event.key) {
|
|
248
|
+
case 'ArrowDown':
|
|
249
|
+
event.preventDefault();
|
|
250
|
+
this.moveFocusedOption(1);
|
|
251
|
+
return true;
|
|
252
|
+
case 'ArrowUp':
|
|
253
|
+
event.preventDefault();
|
|
254
|
+
this.moveFocusedOption(-1);
|
|
255
|
+
return true;
|
|
256
|
+
case 'Enter':
|
|
257
|
+
event.preventDefault();
|
|
258
|
+
if (keyboardFocusedOptionIndex != null && options[keyboardFocusedOptionIndex]) {
|
|
259
|
+
this.selectItem(options[keyboardFocusedOptionIndex]);
|
|
260
|
+
} else if (allowNew && query.trim()) {
|
|
261
|
+
this.selectItem({ label: query });
|
|
262
|
+
}
|
|
263
|
+
return true;
|
|
264
|
+
default:
|
|
265
|
+
return false;
|
|
266
|
+
}
|
|
267
|
+
}
|
|
254
268
|
moveFocusedOption(offset: number) {
|
|
255
269
|
this.setState((previousState) => {
|
|
256
270
|
const { keyboardFocusedOptionIndex } = previousState;
|
|
@@ -261,7 +275,7 @@ class Typeahead<T> extends Component<TypeaheadPropsWithInputAttributes<T>, Typea
|
|
|
261
275
|
}
|
|
262
276
|
const optionRef = this.optionRefs[index];
|
|
263
277
|
if (optionRef?.current) {
|
|
264
|
-
optionRef.current.
|
|
278
|
+
optionRef.current.scrollIntoView({ block: 'nearest' });
|
|
265
279
|
}
|
|
266
280
|
return {
|
|
267
281
|
keyboardFocusedOptionIndex: index,
|
|
@@ -269,6 +283,10 @@ class Typeahead<T> extends Component<TypeaheadPropsWithInputAttributes<T>, Typea
|
|
|
269
283
|
});
|
|
270
284
|
}
|
|
271
285
|
|
|
286
|
+
setFocusedOption = (index: number) => {
|
|
287
|
+
this.setState({ keyboardFocusedOptionIndex: index });
|
|
288
|
+
};
|
|
289
|
+
|
|
272
290
|
selectItem = (item: TypeaheadOption<T>) => {
|
|
273
291
|
const { multiple } = this.props;
|
|
274
292
|
let selected = [...this.state.selected];
|
|
@@ -423,12 +441,16 @@ class Typeahead<T> extends Component<TypeaheadPropsWithInputAttributes<T>, Typea
|
|
|
423
441
|
});
|
|
424
442
|
}
|
|
425
443
|
return (
|
|
426
|
-
<div
|
|
427
|
-
className={clsx('dropdown btn-group btn-block', { open: dropdownOpen })}
|
|
428
|
-
id={`menu-${id}`}
|
|
429
|
-
>
|
|
444
|
+
<div className={clsx('dropdown btn-group btn-block', { open: dropdownOpen })}>
|
|
430
445
|
{(!!optionsToRender.length || footer) && (
|
|
431
|
-
<ul
|
|
446
|
+
<ul
|
|
447
|
+
className="dropdown-menu"
|
|
448
|
+
id={`menu-${id}`}
|
|
449
|
+
role="listbox"
|
|
450
|
+
aria-label={this.props?.intl?.formatMessage(messages.suggestionsLabel)}
|
|
451
|
+
tabIndex={0}
|
|
452
|
+
onKeyDown={this.handleOptionListKeyDown}
|
|
453
|
+
>
|
|
432
454
|
{optionsToRender.map((option, idx) => {
|
|
433
455
|
const ref = React.createRef<HTMLLIElement>();
|
|
434
456
|
this.optionRefs[idx] = ref;
|
|
@@ -439,7 +461,8 @@ class Typeahead<T> extends Component<TypeaheadPropsWithInputAttributes<T>, Typea
|
|
|
439
461
|
query={query}
|
|
440
462
|
option={option}
|
|
441
463
|
selected={keyboardFocusedOptionIndex === idx}
|
|
442
|
-
id={
|
|
464
|
+
id={`${id}-${idx}`}
|
|
465
|
+
onMouseEnter={() => this.setFocusedOption(idx)}
|
|
443
466
|
onClick={(event) => {
|
|
444
467
|
this.onOptionSelected(event, option);
|
|
445
468
|
}}
|
|
@@ -554,7 +577,7 @@ class Typeahead<T> extends Component<TypeaheadPropsWithInputAttributes<T>, Typea
|
|
|
554
577
|
autoComplete={inputAutoComplete}
|
|
555
578
|
ariaActivedescendant={
|
|
556
579
|
keyboardFocusedOptionIndex !== null && options[keyboardFocusedOptionIndex]
|
|
557
|
-
? `option-${
|
|
580
|
+
? `option-${id}-${keyboardFocusedOptionIndex}`
|
|
558
581
|
: undefined
|
|
559
582
|
}
|
|
560
583
|
onChange={this.handleOnChange}
|
|
@@ -82,7 +82,7 @@ export default class TypeaheadInput<T> extends Component<
|
|
|
82
82
|
onFocus,
|
|
83
83
|
onPaste,
|
|
84
84
|
autoComplete,
|
|
85
|
-
ariaActivedescendant,
|
|
85
|
+
ariaActivedescendant,
|
|
86
86
|
} = this.props;
|
|
87
87
|
const { inputWidth } = this.state;
|
|
88
88
|
|
|
@@ -93,11 +93,7 @@ export default class TypeaheadInput<T> extends Component<
|
|
|
93
93
|
className={clsx(multiple && 'typeahead__input')}
|
|
94
94
|
name={name}
|
|
95
95
|
id={`input-${typeaheadId}`}
|
|
96
|
-
aria-activedescendant={
|
|
97
|
-
ariaActivedescendant
|
|
98
|
-
? `menu-${typeaheadId} ${ariaActivedescendant}`
|
|
99
|
-
: `menu-${typeaheadId}`
|
|
100
|
-
}
|
|
96
|
+
aria-activedescendant={ariaActivedescendant}
|
|
101
97
|
autoFocus={autoFocus}
|
|
102
98
|
placeholder={hasPlaceholder ? placeholder : ''}
|
|
103
99
|
aria-autocomplete="list"
|
|
@@ -7,3 +7,8 @@
|
|
|
7
7
|
border-radius: 10px;
|
|
8
8
|
border-radius: var(--radius-small);
|
|
9
9
|
}
|
|
10
|
+
.dropdown-menu > li.typeahead__option:not(.active):not(.selected) > .dropdown-item:not([disabled]):not(.disabled):hover,
|
|
11
|
+
.dropdown-menu > li.typeahead__option:not(.active):not(.selected) > .dropdown-item:not([disabled]):not(.disabled):focus,
|
|
12
|
+
.dropdown-menu > li.typeahead__option:not(.active):not(.selected) > .dropdown-item:not([disabled]):not(.disabled):active {
|
|
13
|
+
box-shadow: none;
|
|
14
|
+
}
|
|
@@ -8,12 +8,13 @@ export type TypeaheadOptionProps<T> = {
|
|
|
8
8
|
option: TypeaheadOption<T>;
|
|
9
9
|
selected?: boolean;
|
|
10
10
|
onClick?: React.MouseEventHandler;
|
|
11
|
+
onMouseEnter?: React.MouseEventHandler;
|
|
11
12
|
query?: string;
|
|
12
13
|
id?: string;
|
|
13
14
|
};
|
|
14
15
|
|
|
15
16
|
const Option = forwardRef<HTMLLIElement, TypeaheadOptionProps<any>>((props, ref) => {
|
|
16
|
-
const { option, selected = false, onClick = () => {}, query = '', id } = props;
|
|
17
|
+
const { option, selected = false, onClick = () => {}, onMouseEnter, query = '', id } = props;
|
|
17
18
|
const { label, note, secondary } = option;
|
|
18
19
|
|
|
19
20
|
return (
|
|
@@ -25,8 +26,9 @@ const Option = forwardRef<HTMLLIElement, TypeaheadOptionProps<any>>((props, ref)
|
|
|
25
26
|
className={clsx('typeahead__option tw-dropdown-item clickable', {
|
|
26
27
|
'tw-dropdown-item--focused': selected,
|
|
27
28
|
})}
|
|
29
|
+
onMouseEnter={onMouseEnter}
|
|
28
30
|
>
|
|
29
|
-
<a className="dropdown-item" href="#" tabIndex={
|
|
31
|
+
<a className="dropdown-item" href="#" tabIndex={-1} onClick={onClick}>
|
|
30
32
|
<Highlight value={label} query={query} />
|
|
31
33
|
{note && <span className="np-text-body-default m-l-1">{note}</span>}
|
|
32
34
|
{secondary && (
|