@transferwise/components 46.70.2 → 46.70.4
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/dateLookup/DateLookup.js +1 -1
- package/build/dateLookup/DateLookup.js.map +1 -1
- package/build/dateLookup/DateLookup.mjs +1 -1
- package/build/dateLookup/DateLookup.mjs.map +1 -1
- package/build/dateLookup/dateTrigger/DateTrigger.js +2 -0
- package/build/dateLookup/dateTrigger/DateTrigger.js.map +1 -1
- package/build/dateLookup/dateTrigger/DateTrigger.mjs +2 -0
- package/build/dateLookup/dateTrigger/DateTrigger.mjs.map +1 -1
- package/build/main.css +6 -0
- package/build/styles/main.css +6 -0
- package/build/styles/upload/Upload.css +6 -0
- package/build/typeahead/Typeahead.js +1 -1
- package/build/typeahead/Typeahead.js.map +1 -1
- package/build/typeahead/Typeahead.mjs +1 -1
- package/build/typeahead/Typeahead.mjs.map +1 -1
- package/build/typeahead/typeaheadOption/TypeaheadOption.js +6 -4
- package/build/typeahead/typeaheadOption/TypeaheadOption.js.map +1 -1
- package/build/typeahead/typeaheadOption/TypeaheadOption.mjs +7 -5
- package/build/typeahead/typeaheadOption/TypeaheadOption.mjs.map +1 -1
- package/build/typeahead/util/highlight.js +8 -3
- package/build/typeahead/util/highlight.js.map +1 -1
- package/build/typeahead/util/highlight.mjs +9 -4
- package/build/typeahead/util/highlight.mjs.map +1 -1
- package/build/types/dateLookup/dateTrigger/DateTrigger.d.ts +1 -0
- package/build/types/dateLookup/dateTrigger/DateTrigger.d.ts.map +1 -1
- package/build/types/typeahead/typeaheadOption/TypeaheadOption.d.ts.map +1 -1
- package/build/types/typeahead/util/highlight.d.ts +5 -1
- package/build/types/typeahead/util/highlight.d.ts.map +1 -1
- package/build/types/upload/steps/uploadImageStep/uploadImageStep.d.ts.map +1 -1
- package/build/upload/steps/uploadImageStep/uploadImageStep.js +1 -0
- package/build/upload/steps/uploadImageStep/uploadImageStep.js.map +1 -1
- package/build/upload/steps/uploadImageStep/uploadImageStep.mjs +1 -0
- package/build/upload/steps/uploadImageStep/uploadImageStep.mjs.map +1 -1
- package/package.json +3 -3
- package/src/dateLookup/DateLookup.rtl.spec.tsx +5 -4
- package/src/dateLookup/DateLookup.story.tsx +33 -0
- package/src/dateLookup/DateLookup.testingLibrary.spec.js +1 -2
- package/src/dateLookup/DateLookup.tsx +1 -1
- package/src/dateLookup/dateTrigger/DateTrigger.tsx +3 -0
- package/src/main.css +6 -0
- package/src/typeahead/Typeahead.rtl.spec.tsx +26 -0
- package/src/typeahead/Typeahead.tsx +2 -2
- package/src/typeahead/typeaheadOption/TypeaheadOption.spec.js +5 -4
- package/src/typeahead/typeaheadOption/TypeaheadOption.tsx +7 -3
- package/src/typeahead/util/highlight.spec.js +5 -5
- package/src/typeahead/util/highlight.tsx +11 -3
- package/src/upload/Upload.css +6 -0
- package/src/upload/Upload.less +8 -0
- package/src/upload/steps/uploadImageStep/uploadImageStep.tsx +1 -0
|
@@ -11,6 +11,7 @@ import { OverlayIdContext } from '../../provider/overlay/OverlayIdProvider';
|
|
|
11
11
|
import Body from '../../body';
|
|
12
12
|
|
|
13
13
|
interface DateTriggerProps {
|
|
14
|
+
ariaLabelledBy?: string;
|
|
14
15
|
selectedDate: Date | null;
|
|
15
16
|
size: SizeSmall | SizeMedium | SizeLarge;
|
|
16
17
|
placeholder: string;
|
|
@@ -28,6 +29,7 @@ const DateTrigger: React.FC<DateTriggerProps> = ({
|
|
|
28
29
|
label,
|
|
29
30
|
monthFormat,
|
|
30
31
|
disabled,
|
|
32
|
+
ariaLabelledBy,
|
|
31
33
|
onClick,
|
|
32
34
|
onClear,
|
|
33
35
|
}) => {
|
|
@@ -41,6 +43,7 @@ const DateTrigger: React.FC<DateTriggerProps> = ({
|
|
|
41
43
|
aria-haspopup="dialog"
|
|
42
44
|
aria-expanded={overlayId != null}
|
|
43
45
|
aria-controls={overlayId}
|
|
46
|
+
aria-labelledby={ariaLabelledBy}
|
|
44
47
|
className={`btn btn-${size} btn-input np-date-trigger`}
|
|
45
48
|
disabled={disabled}
|
|
46
49
|
type="button"
|
package/src/main.css
CHANGED
|
@@ -5449,6 +5449,12 @@ html:not([dir="rtl"]) .np-navigation-option {
|
|
|
5449
5449
|
.tw-droppable-sm {
|
|
5450
5450
|
min-height: 245px;
|
|
5451
5451
|
}
|
|
5452
|
+
.tw-droppable-lg .btn:focus-visible,
|
|
5453
|
+
.tw-droppable-md .btn:focus-visible,
|
|
5454
|
+
.tw-droppable-sm .btn:focus-visible {
|
|
5455
|
+
outline: var(--ring-outline-color) solid var(--ring-outline-width);
|
|
5456
|
+
outline-offset: var(--ring-outline-offset);
|
|
5457
|
+
}
|
|
5452
5458
|
.upload-error-message {
|
|
5453
5459
|
margin-top: 24px;
|
|
5454
5460
|
margin-top: var(--padding-medium);
|
|
@@ -25,4 +25,30 @@ describe('Typeahead', () => {
|
|
|
25
25
|
);
|
|
26
26
|
expect(screen.getAllByRole('group')[0]).toHaveAccessibleName(/^Tags/);
|
|
27
27
|
});
|
|
28
|
+
|
|
29
|
+
describe('when no options are provided', () => {
|
|
30
|
+
it('does not render a dropdown when no options and no footer are provided', () => {
|
|
31
|
+
render(
|
|
32
|
+
<Field id="test" label="Tags">
|
|
33
|
+
<Typeahead id="test" name="test" options={[]} intl={intl} onChange={() => {}} />
|
|
34
|
+
</Field>,
|
|
35
|
+
);
|
|
36
|
+
expect(screen.queryByRole('menu')).not.toBeInTheDocument();
|
|
37
|
+
});
|
|
38
|
+
it('does render a dropdown when only a footer is provided', () => {
|
|
39
|
+
render(
|
|
40
|
+
<Field id="test" label="Tags">
|
|
41
|
+
<Typeahead
|
|
42
|
+
id="test"
|
|
43
|
+
name="test"
|
|
44
|
+
options={[]}
|
|
45
|
+
intl={intl}
|
|
46
|
+
footer={<p>hello</p>}
|
|
47
|
+
onChange={() => {}}
|
|
48
|
+
/>
|
|
49
|
+
</Field>,
|
|
50
|
+
);
|
|
51
|
+
expect(screen.getByRole('menu')).toBeInTheDocument();
|
|
52
|
+
});
|
|
53
|
+
});
|
|
28
54
|
});
|
|
@@ -406,7 +406,7 @@ class Typeahead<T> extends Component<TypeaheadPropsWithInputAttributes<T>, Typea
|
|
|
406
406
|
className={clsx('dropdown btn-group btn-block', { open: dropdownOpen })}
|
|
407
407
|
id={`menu-${id}`}
|
|
408
408
|
>
|
|
409
|
-
{!!optionsToRender.length && (
|
|
409
|
+
{(!!optionsToRender.length || footer) && (
|
|
410
410
|
<ul className="dropdown-menu" role="menu">
|
|
411
411
|
{optionsToRender.map((option, idx) => {
|
|
412
412
|
const ref = React.createRef<HTMLLIElement>();
|
|
@@ -423,7 +423,7 @@ class Typeahead<T> extends Component<TypeaheadPropsWithInputAttributes<T>, Typea
|
|
|
423
423
|
this.onOptionSelected(event, option);
|
|
424
424
|
}}
|
|
425
425
|
/>
|
|
426
|
-
)
|
|
426
|
+
);
|
|
427
427
|
})}
|
|
428
428
|
{footer}
|
|
429
429
|
</ul>
|
|
@@ -3,14 +3,15 @@ import { shallow } from 'enzyme';
|
|
|
3
3
|
import { fakeEvent } from '../../common/fakeEvents';
|
|
4
4
|
|
|
5
5
|
import TypeaheadOption from './TypeaheadOption';
|
|
6
|
+
import Highlight from '../util/highlight';
|
|
6
7
|
|
|
7
8
|
describe('Typeahead Option', () => {
|
|
8
9
|
let props;
|
|
9
10
|
let component;
|
|
10
11
|
|
|
11
|
-
const
|
|
12
|
+
const labelHighlight = () => component.find(Highlight);
|
|
12
13
|
const noteSpan = () => component.find('.np-text-body-default.m-l-1');
|
|
13
|
-
const
|
|
14
|
+
const secondaryTextHighlight = () => component.find('.np-text-body-default.text-ellipsis');
|
|
14
15
|
const dropdownItem = () => component.find('.dropdown-item');
|
|
15
16
|
|
|
16
17
|
beforeEach(() => {
|
|
@@ -26,7 +27,7 @@ describe('Typeahead Option', () => {
|
|
|
26
27
|
it('renders a label', () => {
|
|
27
28
|
const label = 'test';
|
|
28
29
|
component.setProps({ option: { label } });
|
|
29
|
-
expect(
|
|
30
|
+
expect(labelHighlight().dive().text()).toStrictEqual(label);
|
|
30
31
|
});
|
|
31
32
|
|
|
32
33
|
it('renders a note', () => {
|
|
@@ -40,7 +41,7 @@ describe('Typeahead Option', () => {
|
|
|
40
41
|
const label = 'test';
|
|
41
42
|
const secondary = 'test note';
|
|
42
43
|
component.setProps({ option: { label, secondary } });
|
|
43
|
-
expect(
|
|
44
|
+
expect(secondaryTextHighlight().dive().text()).toStrictEqual(secondary);
|
|
44
45
|
});
|
|
45
46
|
|
|
46
47
|
it('highlights when selected', () => {
|
|
@@ -2,7 +2,7 @@ import { clsx } from 'clsx';
|
|
|
2
2
|
import { forwardRef } from 'react';
|
|
3
3
|
|
|
4
4
|
import { TypeaheadOption } from '../Typeahead';
|
|
5
|
-
import
|
|
5
|
+
import Highlight from '../util/highlight';
|
|
6
6
|
|
|
7
7
|
export type TypeaheadOptionProps<T> = {
|
|
8
8
|
option: TypeaheadOption<T>;
|
|
@@ -27,10 +27,14 @@ const Option = forwardRef<HTMLLIElement, TypeaheadOptionProps<any>>((props, ref)
|
|
|
27
27
|
})}
|
|
28
28
|
>
|
|
29
29
|
<a className="dropdown-item" href="#" tabIndex={0} onClick={onClick}>
|
|
30
|
-
<
|
|
30
|
+
<Highlight value={label} query={query} />
|
|
31
31
|
{note && <span className="np-text-body-default m-l-1">{note}</span>}
|
|
32
32
|
{secondary && (
|
|
33
|
-
<
|
|
33
|
+
<Highlight
|
|
34
|
+
className="np-text-body-default text-ellipsis"
|
|
35
|
+
value={secondary}
|
|
36
|
+
query={query}
|
|
37
|
+
/>
|
|
34
38
|
)}
|
|
35
39
|
</a>
|
|
36
40
|
</li>
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { mount } from 'enzyme';
|
|
2
2
|
|
|
3
|
-
import
|
|
3
|
+
import Highlight from './highlight';
|
|
4
4
|
|
|
5
5
|
describe('Typeahead input', () => {
|
|
6
6
|
const highlighted = (node) => node.find('strong');
|
|
@@ -9,7 +9,7 @@ describe('Typeahead input', () => {
|
|
|
9
9
|
it('highlights part of label that matches the query', () => {
|
|
10
10
|
const query = 'test';
|
|
11
11
|
const label = `this is a ${query} label`;
|
|
12
|
-
const result = mount(
|
|
12
|
+
const result = mount(<Highlight value={label} query={query} />);
|
|
13
13
|
|
|
14
14
|
expect(highlighted(result).text()).toStrictEqual(query);
|
|
15
15
|
|
|
@@ -19,15 +19,15 @@ describe('Typeahead input', () => {
|
|
|
19
19
|
it('does not change text if query is not present in it', () => {
|
|
20
20
|
const query = 'test';
|
|
21
21
|
const label = `this is a label`;
|
|
22
|
-
const result =
|
|
22
|
+
const result = mount(<Highlight value={label} query={query} />);
|
|
23
23
|
|
|
24
|
-
expect(result).toBe(label);
|
|
24
|
+
expect(result.text()).toBe(label);
|
|
25
25
|
});
|
|
26
26
|
|
|
27
27
|
it('highlights whole label that matches the query', () => {
|
|
28
28
|
const query = 'test';
|
|
29
29
|
const label = query;
|
|
30
|
-
const result = mount(
|
|
30
|
+
const result = mount(<Highlight value={label} query={query} />);
|
|
31
31
|
|
|
32
32
|
expect(highlighted(result).text()).toStrictEqual(query);
|
|
33
33
|
});
|
|
@@ -1,14 +1,22 @@
|
|
|
1
|
-
export default function
|
|
1
|
+
export default function Highlight({
|
|
2
|
+
className,
|
|
3
|
+
value,
|
|
4
|
+
query,
|
|
5
|
+
}: {
|
|
6
|
+
className?: string;
|
|
7
|
+
value: string;
|
|
8
|
+
query: string;
|
|
9
|
+
}) {
|
|
2
10
|
if (value && query) {
|
|
3
11
|
const highlightStart = value.toUpperCase().indexOf(query.trim().toUpperCase());
|
|
4
12
|
const highlightEnd = highlightStart + query.trim().length;
|
|
5
13
|
if (highlightStart !== -1) {
|
|
6
14
|
return (
|
|
7
|
-
|
|
15
|
+
<span className={className}>
|
|
8
16
|
{value.slice(0, Math.max(0, highlightStart))}
|
|
9
17
|
<strong>{value.slice(highlightStart, highlightEnd)}</strong>
|
|
10
18
|
{value.slice(Math.max(0, highlightEnd))}
|
|
11
|
-
|
|
19
|
+
</span>
|
|
12
20
|
);
|
|
13
21
|
}
|
|
14
22
|
}
|
package/src/upload/Upload.css
CHANGED
|
@@ -13,6 +13,12 @@
|
|
|
13
13
|
.tw-droppable-sm {
|
|
14
14
|
min-height: 245px;
|
|
15
15
|
}
|
|
16
|
+
.tw-droppable-lg .btn:focus-visible,
|
|
17
|
+
.tw-droppable-md .btn:focus-visible,
|
|
18
|
+
.tw-droppable-sm .btn:focus-visible {
|
|
19
|
+
outline: var(--ring-outline-color) solid var(--ring-outline-width);
|
|
20
|
+
outline-offset: var(--ring-outline-offset);
|
|
21
|
+
}
|
|
16
22
|
.upload-error-message {
|
|
17
23
|
margin-top: 24px;
|
|
18
24
|
margin-top: var(--padding-medium);
|
package/src/upload/Upload.less
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
@import (reference) "../../node_modules/@transferwise/neptune-css/src/less/ring.less";
|
|
2
|
+
|
|
1
3
|
// This css is a quick workaround on the height of the upload container collapsing if UploadImageStep is
|
|
2
4
|
// not rendered.
|
|
3
5
|
.tw-droppable-lg {
|
|
@@ -20,6 +22,12 @@
|
|
|
20
22
|
min-height: 245px;
|
|
21
23
|
}
|
|
22
24
|
|
|
25
|
+
.tw-droppable-lg, .tw-droppable-md, .tw-droppable-sm {
|
|
26
|
+
.btn:focus-visible {
|
|
27
|
+
.ring();
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
|
|
23
31
|
.upload-error-message {
|
|
24
32
|
margin-top: var(--padding-medium);
|
|
25
33
|
border-top: 1px solid var(--color-border-neutral);
|
|
@@ -68,6 +68,7 @@ export default class UploadImageStep extends PureComponent<UploadImageStepProps>
|
|
|
68
68
|
className={`btn btn-primary btn-md ${usDisabled ? 'disabled' : ''}`}
|
|
69
69
|
role="button"
|
|
70
70
|
aria-disabled={usDisabled}
|
|
71
|
+
tabIndex={0}
|
|
71
72
|
>
|
|
72
73
|
{usButtonText ? (
|
|
73
74
|
<span>{usButtonText}</span>
|