@transferwise/components 46.17.1 → 46.17.3
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/index.esm.js +16 -15
- package/build/index.esm.js.map +1 -1
- package/build/index.js +15 -14
- package/build/index.js.map +1 -1
- package/build/types/accordion/Accordion.d.ts +1 -1
- package/build/types/accordion/Accordion.d.ts.map +1 -1
- package/build/types/chips/Chips.d.ts +2 -2
- package/build/types/chips/Chips.d.ts.map +1 -1
- package/build/types/dateInput/DateInput.d.ts +2 -2
- package/build/types/dateInput/DateInput.d.ts.map +1 -1
- package/build/types/dateLookup/getFocusableTime/getFocusableTime.d.ts +1 -1
- package/build/types/dateLookup/getFocusableTime/getFocusableTime.d.ts.map +1 -1
- package/build/types/decision/Decision.d.ts +1 -1
- package/build/types/decision/Decision.d.ts.map +1 -1
- package/build/types/flowNavigation/FlowNavigation.d.ts +1 -1
- package/build/types/flowNavigation/FlowNavigation.d.ts.map +1 -1
- package/build/types/flowNavigation/animatedLabel/AnimatedLabel.d.ts +1 -1
- package/build/types/flowNavigation/animatedLabel/AnimatedLabel.d.ts.map +1 -1
- package/build/types/instructionsList/InstructionsList.d.ts +4 -4
- package/build/types/instructionsList/InstructionsList.d.ts.map +1 -1
- package/build/types/markdown/Markdown.d.ts +2 -2
- package/build/types/markdown/Markdown.d.ts.map +1 -1
- package/build/types/phoneNumberInput/PhoneNumberInput.d.ts +1 -1
- package/build/types/phoneNumberInput/PhoneNumberInput.d.ts.map +1 -1
- package/build/types/phoneNumberInput/utils/excludeCountries/excludeCountries.d.ts +1 -1
- package/build/types/phoneNumberInput/utils/excludeCountries/excludeCountries.d.ts.map +1 -1
- package/build/types/phoneNumberInput/utils/groupCountriesByPrefix/groupCountriesByPrefix.d.ts +1 -1
- package/build/types/phoneNumberInput/utils/groupCountriesByPrefix/groupCountriesByPrefix.d.ts.map +1 -1
- package/build/types/phoneNumberInput/utils/longestMatchingPrefix/index.d.ts +1 -1
- package/build/types/phoneNumberInput/utils/longestMatchingPrefix/index.d.ts.map +1 -1
- package/build/types/phoneNumberInput/utils/sortArrayByProperty/sortArrayByProperty.d.ts +1 -1
- package/build/types/phoneNumberInput/utils/sortArrayByProperty/sortArrayByProperty.d.ts.map +1 -1
- package/build/types/radioGroup/RadioGroup.d.ts +1 -1
- package/build/types/radioGroup/RadioGroup.d.ts.map +1 -1
- package/build/types/segmentedControl/SegmentedControl.d.ts +3 -3
- package/build/types/segmentedControl/SegmentedControl.d.ts.map +1 -1
- package/build/types/slidingPanel/SlidingPanel.d.ts.map +1 -1
- package/build/types/stepper/Stepper.d.ts +1 -1
- package/build/types/stepper/Stepper.d.ts.map +1 -1
- package/build/types/typeahead/Typeahead.d.ts +5 -5
- package/build/types/typeahead/Typeahead.d.ts.map +1 -1
- package/build/types/typeahead/typeaheadInput/TypeaheadInput.d.ts +1 -1
- package/build/types/typeahead/typeaheadInput/TypeaheadInput.d.ts.map +1 -1
- package/build/types/uploadInput/UploadInput.d.ts +1 -1
- package/build/types/uploadInput/UploadInput.d.ts.map +1 -1
- package/build/types/uploadInput/uploadButton/UploadButton.d.ts +1 -1
- package/build/types/uploadInput/uploadButton/UploadButton.d.ts.map +1 -1
- package/build/types/uploadInput/uploadButton/getAllowedFileTypes.d.ts +1 -1
- package/build/types/uploadInput/uploadButton/getAllowedFileTypes.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/accordion/Accordion.tsx +1 -1
- package/src/chips/Chips.story.tsx +2 -2
- package/src/chips/Chips.tsx +2 -2
- package/src/dateInput/DateInput.tsx +2 -2
- package/src/dateLookup/dateTrigger/DateTrigger.js +1 -1
- package/src/dateLookup/dateTrigger/DateTrigger.spec.js +11 -3
- package/src/dateLookup/getFocusableTime/getFocusableTime.tsx +1 -1
- package/src/decision/Decision.tsx +1 -1
- package/src/flowNavigation/FlowNavigation.tsx +1 -1
- package/src/flowNavigation/__snapshots__/FlowNavigation.spec.js.snap +6 -0
- package/src/flowNavigation/animatedLabel/AnimatedLabel.tsx +1 -1
- package/src/instructionsList/InstructionsList.tsx +4 -4
- package/src/markdown/Markdown.tsx +3 -3
- package/src/moneyInput/MoneyInput.tsx +3 -3
- package/src/phoneNumberInput/PhoneNumberInput.tsx +1 -1
- package/src/phoneNumberInput/utils/excludeCountries/excludeCountries.ts +5 -2
- package/src/phoneNumberInput/utils/groupCountriesByPrefix/groupCountriesByPrefix.ts +1 -1
- package/src/phoneNumberInput/utils/longestMatchingPrefix/index.ts +1 -1
- package/src/phoneNumberInput/utils/sortArrayByProperty/sortArrayByProperty.ts +1 -1
- package/src/promoCard/PromoCardGroup.tsx +1 -1
- package/src/radioGroup/RadioGroup.tsx +1 -1
- package/src/segmentedControl/SegmentedControl.tsx +3 -3
- package/src/slidingPanel/SlidingPanel.js +1 -0
- package/src/stepper/Stepper.spec.js +16 -0
- package/src/stepper/Stepper.tsx +2 -1
- package/src/typeahead/Typeahead.tsx +6 -6
- package/src/typeahead/typeaheadInput/TypeaheadInput.tsx +1 -1
- package/src/uploadInput/UploadInput.tsx +6 -6
- package/src/uploadInput/uploadButton/UploadButton.tsx +5 -7
- package/src/uploadInput/uploadButton/getAllowedFileTypes.ts +1 -1
|
@@ -75,6 +75,7 @@ exports[`FlowNavigation on mobile renders as expected 1`] = `
|
|
|
75
75
|
class="tw-stepper-steps p-t-1 m-b-0"
|
|
76
76
|
>
|
|
77
77
|
<li
|
|
78
|
+
aria-current="false"
|
|
78
79
|
class="hidden-xs tw-stepper__step np-text-body-default"
|
|
79
80
|
style="left: 0%;"
|
|
80
81
|
>
|
|
@@ -85,6 +86,7 @@ exports[`FlowNavigation on mobile renders as expected 1`] = `
|
|
|
85
86
|
</span>
|
|
86
87
|
</li>
|
|
87
88
|
<li
|
|
89
|
+
aria-current="step"
|
|
88
90
|
class="hidden-xs tw-stepper__step np-text-body-default-bold tw-stepper__step--active"
|
|
89
91
|
style="left: 50%;"
|
|
90
92
|
>
|
|
@@ -95,6 +97,7 @@ exports[`FlowNavigation on mobile renders as expected 1`] = `
|
|
|
95
97
|
</span>
|
|
96
98
|
</li>
|
|
97
99
|
<li
|
|
100
|
+
aria-current="false"
|
|
98
101
|
class="hidden-xs tw-stepper__step np-text-body-default"
|
|
99
102
|
style="left: 100%;"
|
|
100
103
|
>
|
|
@@ -188,6 +191,7 @@ exports[`FlowNavigation renders as expected 1`] = `
|
|
|
188
191
|
class="tw-stepper-steps p-t-1 m-b-0"
|
|
189
192
|
>
|
|
190
193
|
<li
|
|
194
|
+
aria-current="step"
|
|
191
195
|
class="hidden-xs tw-stepper__step np-text-body-default-bold tw-stepper__step--active"
|
|
192
196
|
style="left: 0%;"
|
|
193
197
|
>
|
|
@@ -198,6 +202,7 @@ exports[`FlowNavigation renders as expected 1`] = `
|
|
|
198
202
|
</span>
|
|
199
203
|
</li>
|
|
200
204
|
<li
|
|
205
|
+
aria-current="false"
|
|
201
206
|
class="hidden-xs tw-stepper__step np-text-body-default"
|
|
202
207
|
style="left: 50%;"
|
|
203
208
|
>
|
|
@@ -208,6 +213,7 @@ exports[`FlowNavigation renders as expected 1`] = `
|
|
|
208
213
|
</span>
|
|
209
214
|
</li>
|
|
210
215
|
<li
|
|
216
|
+
aria-current="false"
|
|
211
217
|
class="hidden-xs tw-stepper__step np-text-body-default"
|
|
212
218
|
style="left: 100%;"
|
|
213
219
|
>
|
|
@@ -7,7 +7,7 @@ import { Typography } from '../../common';
|
|
|
7
7
|
export interface AnimatedLabelProps {
|
|
8
8
|
activeLabel: number;
|
|
9
9
|
className?: string;
|
|
10
|
-
labels: React.ReactNode[];
|
|
10
|
+
labels: readonly React.ReactNode[];
|
|
11
11
|
}
|
|
12
12
|
|
|
13
13
|
const AnimatedLabel = ({ activeLabel, className, labels }: AnimatedLabelProps) => {
|
|
@@ -12,13 +12,13 @@ type InstructionNode = {
|
|
|
12
12
|
export type InstructionsListProps = CommonProps &
|
|
13
13
|
(
|
|
14
14
|
| {
|
|
15
|
-
dos?: ReactNode[];
|
|
16
|
-
donts?: ReactNode[];
|
|
15
|
+
dos?: readonly ReactNode[];
|
|
16
|
+
donts?: readonly ReactNode[];
|
|
17
17
|
sort?: 'dosFirst' | 'dontsFirst';
|
|
18
18
|
}
|
|
19
19
|
| {
|
|
20
|
-
dos?: InstructionNode[];
|
|
21
|
-
donts?: InstructionNode[];
|
|
20
|
+
dos?: readonly InstructionNode[];
|
|
21
|
+
donts?: readonly InstructionNode[];
|
|
22
22
|
sort?: 'dosFirst' | 'dontsFirst';
|
|
23
23
|
}
|
|
24
24
|
);
|
|
@@ -17,12 +17,12 @@ export type MarkdownProps = {
|
|
|
17
17
|
children?: string;
|
|
18
18
|
} & (
|
|
19
19
|
| {
|
|
20
|
-
allowList?: `${MarkdownNodeType}`[];
|
|
20
|
+
allowList?: readonly `${MarkdownNodeType}`[];
|
|
21
21
|
blockList?: never;
|
|
22
22
|
}
|
|
23
23
|
| {
|
|
24
24
|
allowList?: never;
|
|
25
|
-
blockList?: `${MarkdownNodeType}`[];
|
|
25
|
+
blockList?: readonly `${MarkdownNodeType}`[];
|
|
26
26
|
}
|
|
27
27
|
);
|
|
28
28
|
|
|
@@ -61,7 +61,7 @@ export default function Markdown({
|
|
|
61
61
|
return <Element className={className} dangerouslySetInnerHTML={{ __html: createMarkup() }} />;
|
|
62
62
|
}
|
|
63
63
|
|
|
64
|
-
function stripNodes({ blockList, parsed }: { blockList: string[]; parsed: MarkdownNode }) {
|
|
64
|
+
function stripNodes({ blockList, parsed }: { blockList: readonly string[]; parsed: MarkdownNode }) {
|
|
65
65
|
if (!parsed) {
|
|
66
66
|
return parsed;
|
|
67
67
|
}
|
|
@@ -462,7 +462,7 @@ function filterCurrenciesForQuery(
|
|
|
462
462
|
return sortOptionsLabelsToFirst(filteredOptions, query);
|
|
463
463
|
}
|
|
464
464
|
|
|
465
|
-
function removeDuplicateValueOptions(options: CurrencyOptionItem[]) {
|
|
465
|
+
function removeDuplicateValueOptions(options: readonly CurrencyOptionItem[]) {
|
|
466
466
|
const uniqueValues = new Set<string>();
|
|
467
467
|
return options.filter((option) => {
|
|
468
468
|
if (!uniqueValues.has(option.value)) {
|
|
@@ -489,8 +489,8 @@ function contains(property: string | undefined, query: string) {
|
|
|
489
489
|
return property && property.toLowerCase().includes(query.toLowerCase());
|
|
490
490
|
}
|
|
491
491
|
|
|
492
|
-
function sortOptionsLabelsToFirst(options: CurrencyOptionItem[], query: string) {
|
|
493
|
-
return options.sort((first, second) => {
|
|
492
|
+
function sortOptionsLabelsToFirst(options: readonly CurrencyOptionItem[], query: string) {
|
|
493
|
+
return [...options].sort((first, second) => {
|
|
494
494
|
const firstContains = contains(first.label, query);
|
|
495
495
|
const secondContains = contains(second.label, query);
|
|
496
496
|
|
|
@@ -34,7 +34,7 @@ export interface PhoneNumberInputProps {
|
|
|
34
34
|
placeholder?: string;
|
|
35
35
|
selectProps?: Partial<SelectInputProps<string | null>>;
|
|
36
36
|
/** List of iso3 codes of countries to remove from the list */
|
|
37
|
-
disabledCountries?: string[];
|
|
37
|
+
disabledCountries?: readonly string[];
|
|
38
38
|
}
|
|
39
39
|
|
|
40
40
|
const defaultSelectProps = {} satisfies PhoneNumberInputProps['selectProps'];
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { Country } from '../../data/countries';
|
|
2
2
|
|
|
3
3
|
// Reference fro localeCompare : https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/localeCompare
|
|
4
|
-
const filterCountriesByIso3 = (countries: Country[], iso3Codes: string[]) => {
|
|
4
|
+
const filterCountriesByIso3 = (countries: readonly Country[], iso3Codes: readonly string[]) => {
|
|
5
5
|
const iso3CodesSet = new Set(iso3Codes);
|
|
6
6
|
return countries.filter((country) => !iso3CodesSet.has(country.iso3));
|
|
7
7
|
};
|
|
@@ -12,7 +12,10 @@ const filterCountriesByIso3 = (countries: Country[], iso3Codes: string[]) => {
|
|
|
12
12
|
* @param countries list of country metadata objects
|
|
13
13
|
* @param disabledCountries list of iso3 country codes to remove from the list
|
|
14
14
|
*/
|
|
15
|
-
export const excludeCountries = (
|
|
15
|
+
export const excludeCountries = (
|
|
16
|
+
countries: readonly Country[],
|
|
17
|
+
disabledCountries: readonly string[],
|
|
18
|
+
) => {
|
|
16
19
|
return disabledCountries.length > 0
|
|
17
20
|
? filterCountriesByIso3(countries, disabledCountries)
|
|
18
21
|
: countries;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Country } from '../../data/countries';
|
|
2
2
|
|
|
3
|
-
export const groupCountriesByPrefix = (countries: Country[]) => {
|
|
3
|
+
export const groupCountriesByPrefix = (countries: readonly Country[]) => {
|
|
4
4
|
const countriesByPrefix = new Map<string, Country[]>();
|
|
5
5
|
countries.forEach((country) => {
|
|
6
6
|
countriesByPrefix.set(country.phone, [
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import { Country } from '../../data/countries';
|
|
2
2
|
|
|
3
|
-
export const longestMatchingPrefix = (matchingCodes: Country[]) =>
|
|
3
|
+
export const longestMatchingPrefix = (matchingCodes: readonly Country[]) =>
|
|
4
4
|
matchingCodes.reduce((a, b) => (a.phone.length > b.phone.length ? a : b));
|
|
@@ -106,7 +106,7 @@ const PromoCardGroup: FunctionComponent<PromoCardGroupProps> = ({
|
|
|
106
106
|
setState(defaultChecked);
|
|
107
107
|
|
|
108
108
|
// Collect an array of types from the children PromoCard components
|
|
109
|
-
const types
|
|
109
|
+
const types =
|
|
110
110
|
React.Children.map(children, (child) => {
|
|
111
111
|
if (React.isValidElement<PromoCardProps>(child) && child.props.type) {
|
|
112
112
|
return child.props.type;
|
|
@@ -5,7 +5,7 @@ import { RadioProps } from '../radio/Radio';
|
|
|
5
5
|
|
|
6
6
|
export interface RadioGroupProps<T extends string | number = string> {
|
|
7
7
|
name: string;
|
|
8
|
-
radios: Omit<RadioProps<T>, 'name' | 'checked' | 'onChange' | 'className'>[];
|
|
8
|
+
radios: readonly Omit<RadioProps<T>, 'name' | 'checked' | 'onChange' | 'className'>[];
|
|
9
9
|
selectedValue?: T; // TODO: `NoInfer<T>` from TypeScript 5.4
|
|
10
10
|
onChange: NonNullable<RadioProps<T>['onChange']>;
|
|
11
11
|
}
|
|
@@ -9,7 +9,7 @@ type SegmentBase = { id: string; label: string; value: string };
|
|
|
9
9
|
type Segment = SegmentBase & { controls?: never };
|
|
10
10
|
type SegmentWithControls = SegmentBase & { controls: string };
|
|
11
11
|
|
|
12
|
-
export type Segments = Segment[] | SegmentWithControls[];
|
|
12
|
+
export type Segments = readonly Segment[] | readonly SegmentWithControls[];
|
|
13
13
|
|
|
14
14
|
type SegmentedControlPropsBase = {
|
|
15
15
|
name: string;
|
|
@@ -20,12 +20,12 @@ type SegmentedControlPropsBase = {
|
|
|
20
20
|
|
|
21
21
|
type SegmentedControlViewProps = {
|
|
22
22
|
mode: 'view';
|
|
23
|
-
segments: SegmentWithControls[];
|
|
23
|
+
segments: readonly SegmentWithControls[];
|
|
24
24
|
};
|
|
25
25
|
|
|
26
26
|
type SegmentedControlInputProps = {
|
|
27
27
|
mode: 'input';
|
|
28
|
-
segments: Segment[];
|
|
28
|
+
segments: readonly Segment[];
|
|
29
29
|
};
|
|
30
30
|
|
|
31
31
|
export type SegmentedControlProps = SegmentedControlPropsBase &
|
|
@@ -162,6 +162,22 @@ describe('Stepper', () => {
|
|
|
162
162
|
expect(step(1).clickable).toBe(true);
|
|
163
163
|
expect(step(2).clickable).toBe(true);
|
|
164
164
|
});
|
|
165
|
+
|
|
166
|
+
it('are aria-current=step when active', () => {
|
|
167
|
+
const stepCurrent = (index) =>
|
|
168
|
+
component.find('.tw-stepper__step').at(index).props()['aria-current'];
|
|
169
|
+
steps(4);
|
|
170
|
+
activeStep(1);
|
|
171
|
+
expect(stepCurrent(0)).toBe(false);
|
|
172
|
+
expect(stepCurrent(1)).toBe('step');
|
|
173
|
+
expect(stepCurrent(2)).toBe(false);
|
|
174
|
+
expect(stepCurrent(3)).toBe(false);
|
|
175
|
+
activeStep(2);
|
|
176
|
+
expect(stepCurrent(0)).toBe(false);
|
|
177
|
+
expect(stepCurrent(1)).toBe(false);
|
|
178
|
+
expect(stepCurrent(2)).toBe('step');
|
|
179
|
+
expect(stepCurrent(3)).toBe(false);
|
|
180
|
+
});
|
|
165
181
|
});
|
|
166
182
|
|
|
167
183
|
describe('hover labels', () => {
|
package/src/stepper/Stepper.tsx
CHANGED
|
@@ -18,7 +18,7 @@ export interface Step {
|
|
|
18
18
|
}
|
|
19
19
|
|
|
20
20
|
export interface StepperProps {
|
|
21
|
-
steps: Step[];
|
|
21
|
+
steps: readonly Step[];
|
|
22
22
|
activeStep?: number;
|
|
23
23
|
className?: string;
|
|
24
24
|
}
|
|
@@ -60,6 +60,7 @@ const Stepper = ({ steps, activeStep = 0, className }: StepperProps) => {
|
|
|
60
60
|
clickable && 'tw-stepper__step--clickable',
|
|
61
61
|
step.hoverLabel && 'tw-stepper__step--has-tooltip',
|
|
62
62
|
)}
|
|
63
|
+
aria-current={active ? 'step' : false}
|
|
63
64
|
style={
|
|
64
65
|
isRTL
|
|
65
66
|
? { right: `${index * stepPercentage * 100}%` }
|
|
@@ -43,16 +43,16 @@ export interface TypeaheadProps<T> {
|
|
|
43
43
|
allowNew?: boolean;
|
|
44
44
|
autoFillOnBlur?: boolean;
|
|
45
45
|
autoFocus?: boolean;
|
|
46
|
-
chipSeparators?: string[];
|
|
46
|
+
chipSeparators?: readonly string[];
|
|
47
47
|
clearable?: boolean;
|
|
48
48
|
footer?: ReactNode;
|
|
49
|
-
initialValue?: TypeaheadOption<T>[];
|
|
49
|
+
initialValue?: readonly TypeaheadOption<T>[];
|
|
50
50
|
inputAutoComplete?: string;
|
|
51
51
|
maxHeight?: number;
|
|
52
52
|
minQueryLength?: number;
|
|
53
53
|
placeholder?: string;
|
|
54
54
|
multiple?: boolean;
|
|
55
|
-
options: TypeaheadOption<T>[];
|
|
55
|
+
options: readonly TypeaheadOption<T>[];
|
|
56
56
|
searchDelay?: number;
|
|
57
57
|
showSuggestions?: boolean;
|
|
58
58
|
showNewEntry?: boolean;
|
|
@@ -67,7 +67,7 @@ export interface TypeaheadProps<T> {
|
|
|
67
67
|
}
|
|
68
68
|
|
|
69
69
|
type TypeaheadState<T> = {
|
|
70
|
-
selected: TypeaheadOption<T>[];
|
|
70
|
+
selected: readonly TypeaheadOption<T>[];
|
|
71
71
|
keyboardFocusedOptionIndex: number | null;
|
|
72
72
|
errorState: boolean;
|
|
73
73
|
query: string;
|
|
@@ -311,12 +311,12 @@ export default class Typeahead<T> extends Component<TypeaheadProps<T>, Typeahead
|
|
|
311
311
|
);
|
|
312
312
|
};
|
|
313
313
|
|
|
314
|
-
updateSelectedValue = (selected: TypeaheadOption<T>[]) => {
|
|
314
|
+
updateSelectedValue = (selected: readonly TypeaheadOption<T>[]) => {
|
|
315
315
|
const { onChange, validateChip } = this.props;
|
|
316
316
|
|
|
317
317
|
const errorState = selected.some((chip) => !validateChip(chip));
|
|
318
318
|
this.setState({ selected, errorState }, () => {
|
|
319
|
-
onChange(selected);
|
|
319
|
+
onChange([...selected]);
|
|
320
320
|
});
|
|
321
321
|
};
|
|
322
322
|
|
|
@@ -12,7 +12,7 @@ const DEFAULT_INPUT_MIN_WIDTH = 10;
|
|
|
12
12
|
export type TypeaheadInputProps<T> = {
|
|
13
13
|
typeaheadId: string;
|
|
14
14
|
value: string;
|
|
15
|
-
selected: TypeaheadOption<T>[];
|
|
15
|
+
selected: readonly TypeaheadOption<T>[];
|
|
16
16
|
optionsShown?: boolean;
|
|
17
17
|
autoComplete: string;
|
|
18
18
|
onChange: React.ChangeEventHandler<HTMLInputElement>;
|
|
@@ -19,7 +19,7 @@ export type UploadInputProps = {
|
|
|
19
19
|
/**
|
|
20
20
|
* List of already existing, failed or in progress files
|
|
21
21
|
*/
|
|
22
|
-
files?: UploadedFile[];
|
|
22
|
+
files?: readonly UploadedFile[];
|
|
23
23
|
|
|
24
24
|
/**
|
|
25
25
|
* The key of the file in the returned FormData object (default: file)
|
|
@@ -135,14 +135,14 @@ const UploadInput = ({
|
|
|
135
135
|
|
|
136
136
|
const PROGRESS_STATUSES = new Set([Status.PENDING, Status.PROCESSING]);
|
|
137
137
|
|
|
138
|
-
const [uploadedFiles, setUploadedFiles] = useState<UploadedFile[]>(
|
|
138
|
+
const [uploadedFiles, setUploadedFiles] = useState<readonly UploadedFile[]>(
|
|
139
139
|
multiple || files.length === 0 ? files : [files[0]],
|
|
140
140
|
);
|
|
141
141
|
|
|
142
142
|
const uploadedFilesListReference = useRef(multiple || files.length === 0 ? files : [files[0]]);
|
|
143
143
|
|
|
144
144
|
function addFileToList(recentUploadedFile: UploadedFile) {
|
|
145
|
-
function addToList(listToAddTo: UploadedFile[]) {
|
|
145
|
+
function addToList(listToAddTo: readonly UploadedFile[]) {
|
|
146
146
|
return [...listToAddTo, recentUploadedFile];
|
|
147
147
|
}
|
|
148
148
|
|
|
@@ -151,7 +151,7 @@ const UploadInput = ({
|
|
|
151
151
|
}
|
|
152
152
|
|
|
153
153
|
const removeFileFromList = (file: UploadedFile) => {
|
|
154
|
-
function filterOutFrom(listToFilterFrom: UploadedFile[]) {
|
|
154
|
+
function filterOutFrom(listToFilterFrom: readonly UploadedFile[]) {
|
|
155
155
|
return listToFilterFrom.filter(
|
|
156
156
|
(fileInList) => file !== fileInList && file.id !== fileInList.id,
|
|
157
157
|
);
|
|
@@ -162,7 +162,7 @@ const UploadInput = ({
|
|
|
162
162
|
};
|
|
163
163
|
|
|
164
164
|
const modifyFileInList = (file: UploadedFile, updates: Partial<UploadedFile>) => {
|
|
165
|
-
const updateListItem = (listToUpdate: UploadedFile[]) =>
|
|
165
|
+
const updateListItem = (listToUpdate: readonly UploadedFile[]) =>
|
|
166
166
|
listToUpdate.map((fileInList) => {
|
|
167
167
|
return fileInList === file || fileInList.id === file.id
|
|
168
168
|
? { ...file, ...updates }
|
|
@@ -295,7 +295,7 @@ const UploadInput = ({
|
|
|
295
295
|
|
|
296
296
|
useEffect(() => {
|
|
297
297
|
if (onFilesChange && mounted) {
|
|
298
|
-
onFilesChange(uploadedFiles);
|
|
298
|
+
onFilesChange([...uploadedFiles]);
|
|
299
299
|
}
|
|
300
300
|
}, [onFilesChange, uploadedFiles]); // eslint-disable-line react-hooks/exhaustive-deps
|
|
301
301
|
|
|
@@ -12,7 +12,7 @@ import MESSAGES from './UploadButton.messages';
|
|
|
12
12
|
import { DEFAULT_SIZE_LIMIT, imageFileTypes } from './defaults';
|
|
13
13
|
import getAllowedFileTypes from './getAllowedFileTypes';
|
|
14
14
|
|
|
15
|
-
type AllowedFileTypes = string | string[] | FileType[];
|
|
15
|
+
type AllowedFileTypes = string | readonly string[] | readonly FileType[];
|
|
16
16
|
export type UploadButtonProps = {
|
|
17
17
|
/**
|
|
18
18
|
* Disable the upload button if your app is not yet ready to accept uploads
|
|
@@ -144,9 +144,7 @@ const UploadButton = ({
|
|
|
144
144
|
return fileTypes;
|
|
145
145
|
}
|
|
146
146
|
|
|
147
|
-
return Array.isArray(fileTypes)
|
|
148
|
-
? getAllowedFileTypes(fileTypes).join(', ')
|
|
149
|
-
: getAllowedFileTypes([fileTypes]).join(', ');
|
|
147
|
+
return getAllowedFileTypes(Array.isArray(fileTypes) ? fileTypes : [fileTypes]).join(', ');
|
|
150
148
|
};
|
|
151
149
|
|
|
152
150
|
function getDescription() {
|
|
@@ -165,18 +163,18 @@ const UploadButton = ({
|
|
|
165
163
|
});
|
|
166
164
|
}
|
|
167
165
|
|
|
168
|
-
function getAcceptedTypes() {
|
|
166
|
+
function getAcceptedTypes(): Pick<React.ComponentPropsWithoutRef<'input'>, 'accept'> {
|
|
169
167
|
const areAllFilesAllowed = getFileTypesDescription() === '*';
|
|
170
168
|
|
|
171
169
|
if (areAllFilesAllowed) {
|
|
172
|
-
return
|
|
170
|
+
return {}; //file input by default allows all files
|
|
173
171
|
}
|
|
174
172
|
|
|
175
173
|
if (Array.isArray(fileTypes)) {
|
|
176
174
|
return { accept: fileTypes.join(',') };
|
|
177
175
|
}
|
|
178
176
|
|
|
179
|
-
return { accept: fileTypes };
|
|
177
|
+
return { accept: fileTypes as string };
|
|
180
178
|
}
|
|
181
179
|
|
|
182
180
|
function renderDescription() {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { FileType } from '../../common';
|
|
2
2
|
|
|
3
|
-
const getAllowedFileTypes = (fileTypes: FileType[] | string[]): string[] =>
|
|
3
|
+
const getAllowedFileTypes = (fileTypes: readonly FileType[] | readonly string[]): string[] =>
|
|
4
4
|
fileTypes.map((fileTypeDefinition: string) =>
|
|
5
5
|
fileTypeDefinition
|
|
6
6
|
.split(',')
|