@transferwise/components 0.0.0-experimental-11c630d → 0.0.0-experimental-50dbef7
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/common/card/Card.js.map +1 -1
- package/build/common/card/Card.mjs.map +1 -1
- package/build/field/Field.js +1 -1
- package/build/field/Field.js.map +1 -1
- package/build/field/Field.mjs +1 -1
- package/build/field/Field.mjs.map +1 -1
- package/build/index.js +1 -2
- package/build/index.js.map +1 -1
- package/build/index.mjs +1 -1
- package/build/moneyInput/MoneyInput.js +3 -8
- package/build/moneyInput/MoneyInput.js.map +1 -1
- package/build/moneyInput/MoneyInput.mjs +3 -8
- package/build/moneyInput/MoneyInput.mjs.map +1 -1
- package/build/promoCard/PromoCardGroup.js.map +1 -1
- package/build/promoCard/PromoCardGroup.mjs.map +1 -1
- package/build/promoCard/PromoCardIndicator.js.map +1 -1
- package/build/promoCard/PromoCardIndicator.mjs.map +1 -1
- package/build/sticky/Sticky.js.map +1 -1
- package/build/sticky/Sticky.mjs.map +1 -1
- package/build/types/common/card/Card.d.ts +1 -1
- package/build/types/index.d.ts +0 -4
- package/build/types/index.d.ts.map +1 -1
- package/build/types/moneyInput/MoneyInput.d.ts +3 -7
- package/build/types/moneyInput/MoneyInput.d.ts.map +1 -1
- package/build/types/promoCard/PromoCardIndicator.d.ts +1 -1
- package/build/types/sticky/Sticky.d.ts +1 -1
- package/build/types/uploadInput/uploadItem/UploadItem.d.ts +1 -1
- package/build/types/uploadInput/uploadItem/UploadItem.d.ts.map +1 -1
- package/build/uploadInput/uploadItem/UploadItem.js.map +1 -1
- package/build/uploadInput/uploadItem/UploadItem.mjs.map +1 -1
- package/package.json +3 -3
- package/src/common/card/Card.tsx +1 -1
- package/src/field/Field.spec.tsx +1 -1
- package/src/field/Field.story.tsx +19 -8
- package/src/field/Field.tsx +1 -1
- package/src/index.ts +2 -5
- package/src/moneyInput/MoneyInput.spec.js +6 -19
- package/src/moneyInput/MoneyInput.story.tsx +9 -7
- package/src/moneyInput/MoneyInput.tsx +5 -8
- package/src/promoCard/PromoCardGroup.tsx +1 -1
- package/src/promoCard/PromoCardIndicator.tsx +1 -1
- package/src/sticky/Sticky.tsx +1 -1
- package/src/uploadInput/uploadItem/UploadItem.tsx +1 -1
- package/build/types/withId/index.d.ts +0 -3
- package/build/types/withId/index.d.ts.map +0 -1
- package/build/types/withId/story/source.d.ts +0 -2
- package/build/types/withId/story/source.d.ts.map +0 -1
- package/build/types/withId/withId.d.ts +0 -17
- package/build/types/withId/withId.d.ts.map +0 -1
- package/build/withId/withId.js +0 -19
- package/build/withId/withId.js.map +0 -1
- package/build/withId/withId.mjs +0 -17
- package/build/withId/withId.mjs.map +0 -1
- package/src/withId/index.ts +0 -2
- package/src/withId/story/source.tsx +0 -22
- package/src/withId/withId.docs.mdx +0 -24
- package/src/withId/withId.spec.tsx +0 -26
- package/src/withId/withId.story.tsx +0 -38
- package/src/withId/withId.tsx +0 -29
package/src/common/card/Card.tsx
CHANGED
|
@@ -42,7 +42,7 @@ export interface CardProps {
|
|
|
42
42
|
* @param {boolean} isSmall - Whether the card is small or not.
|
|
43
43
|
* @param {(event_: MouseEvent<HTMLButtonElement>) => void} onDismiss - Optional function to call when the card is dismissed.
|
|
44
44
|
* @param {string} testId - Optional ID to add to the card container for testing purposes.
|
|
45
|
-
* @returns {JSX.Element} - The card component.
|
|
45
|
+
* @returns {React.JSX.Element} - The card component.
|
|
46
46
|
* @example
|
|
47
47
|
* <Card>
|
|
48
48
|
* <p>Hello World!</p>
|
package/src/field/Field.spec.tsx
CHANGED
|
@@ -73,7 +73,7 @@ describe('Field', () => {
|
|
|
73
73
|
|
|
74
74
|
it('should show or hide (Optional) suffix depending on required prop', () => {
|
|
75
75
|
render(
|
|
76
|
-
<Field label="Phone number" description="This is help text">
|
|
76
|
+
<Field label="Phone number" required={false} description="This is help text">
|
|
77
77
|
<Input />
|
|
78
78
|
</Field>,
|
|
79
79
|
);
|
|
@@ -21,16 +21,21 @@ export const Basic = () => {
|
|
|
21
21
|
return (
|
|
22
22
|
<div className="row">
|
|
23
23
|
<div className="col-md-8 col-md-offset-2">
|
|
24
|
-
<Field label="Required Text Input"
|
|
24
|
+
<Field label="Required Text Input">
|
|
25
25
|
<Input value={value} onChange={({ target }) => setValue(target.value)} />
|
|
26
26
|
</Field>
|
|
27
|
-
<Field label="Text Input">
|
|
27
|
+
<Field label="Text Input" required={false}>
|
|
28
28
|
<Input value={value} onChange={({ target }) => setValue(target.value)} />
|
|
29
29
|
</Field>
|
|
30
|
-
<Field
|
|
30
|
+
<Field
|
|
31
|
+
label="Text Input with Description"
|
|
32
|
+
required={false}
|
|
33
|
+
description="This a field Description"
|
|
34
|
+
>
|
|
31
35
|
<Input value={value} onChange={({ target }) => setValue(target.value)} />
|
|
32
36
|
</Field>
|
|
33
37
|
<Field
|
|
38
|
+
required={false}
|
|
34
39
|
label="Text Input with Validation Error"
|
|
35
40
|
description="This a field Description"
|
|
36
41
|
sentiment={Sentiment.NEGATIVE}
|
|
@@ -39,27 +44,32 @@ export const Basic = () => {
|
|
|
39
44
|
<Input value={value} onChange={({ target }) => setValue(target.value)} />
|
|
40
45
|
</Field>
|
|
41
46
|
|
|
42
|
-
<Field label="Date Of Birth">
|
|
47
|
+
<Field label="Date Of Birth" required={false}>
|
|
43
48
|
<DateInput onChange={fn} />
|
|
44
49
|
</Field>
|
|
45
50
|
|
|
46
|
-
<Field label="Date Of Birth with Description" description={lorem10}>
|
|
51
|
+
<Field label="Date Of Birth with Description" required={false} description={lorem10}>
|
|
47
52
|
<DateInput onChange={fn} />
|
|
48
53
|
</Field>
|
|
49
54
|
|
|
50
|
-
<Field label="Search business">
|
|
55
|
+
<Field label="Search business" required={false}>
|
|
51
56
|
<SearchInput />
|
|
52
57
|
</Field>
|
|
53
58
|
|
|
54
|
-
<Field label="Textarea">
|
|
59
|
+
<Field label="Textarea" required={false}>
|
|
55
60
|
<TextArea />
|
|
56
61
|
</Field>
|
|
57
62
|
|
|
58
|
-
<Field
|
|
63
|
+
<Field
|
|
64
|
+
label="Textarea with Description"
|
|
65
|
+
required={false}
|
|
66
|
+
description="This a TextArea Description"
|
|
67
|
+
>
|
|
59
68
|
<TextArea />
|
|
60
69
|
</Field>
|
|
61
70
|
|
|
62
71
|
<Field
|
|
72
|
+
required={false}
|
|
63
73
|
label="Textarea with Validation Error"
|
|
64
74
|
description="This a TextArea Description"
|
|
65
75
|
message={lorem10}
|
|
@@ -69,6 +79,7 @@ export const Basic = () => {
|
|
|
69
79
|
</Field>
|
|
70
80
|
|
|
71
81
|
<Field
|
|
82
|
+
required={false}
|
|
72
83
|
label={
|
|
73
84
|
<>
|
|
74
85
|
Label with Suffix <Info content={lorem40} />
|
package/src/field/Field.tsx
CHANGED
package/src/index.ts
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { shallow } from 'enzyme';
|
|
2
|
-
import { render, screen } from '@testing-library/react';
|
|
3
2
|
|
|
4
3
|
import { MoneyInput, Title, Input, SelectInput } from '..';
|
|
5
4
|
import { mockMatchMedia, mockResizeObserver } from '../test-utils';
|
|
@@ -88,9 +87,7 @@ describe('Money Input', () => {
|
|
|
88
87
|
onAmountChange: jest.fn(),
|
|
89
88
|
onCurrencyChange: jest.fn(),
|
|
90
89
|
};
|
|
91
|
-
component = shallow(<MoneyInput {...props} />)
|
|
92
|
-
.dive()
|
|
93
|
-
.dive();
|
|
90
|
+
component = shallow(<MoneyInput {...props} />).dive();
|
|
94
91
|
jest.clearAllMocks();
|
|
95
92
|
});
|
|
96
93
|
|
|
@@ -210,10 +207,10 @@ describe('Money Input', () => {
|
|
|
210
207
|
]);
|
|
211
208
|
});
|
|
212
209
|
|
|
213
|
-
it('renders Select component with
|
|
210
|
+
it('renders Select component with undefined id when id is not provided', () => {
|
|
214
211
|
const select = component.find('SelectInput');
|
|
215
212
|
|
|
216
|
-
expect(select.prop('id')).
|
|
213
|
+
expect(select.prop('id')).toBeUndefined();
|
|
217
214
|
});
|
|
218
215
|
|
|
219
216
|
it('shows the currently active currency as active and hides its note', () => {
|
|
@@ -573,7 +570,9 @@ describe('Money Input', () => {
|
|
|
573
570
|
);
|
|
574
571
|
|
|
575
572
|
it('passes the id given to the input element', () => {
|
|
573
|
+
expect(amountInput().prop('id')).toBeUndefined();
|
|
576
574
|
component.setProps({ id: 'some-id' });
|
|
575
|
+
|
|
577
576
|
expect(amountInput().prop('id')).toBe('some-id');
|
|
578
577
|
});
|
|
579
578
|
|
|
@@ -805,9 +804,7 @@ describe('Money Input', () => {
|
|
|
805
804
|
}}
|
|
806
805
|
{...props}
|
|
807
806
|
/>,
|
|
808
|
-
)
|
|
809
|
-
.dive()
|
|
810
|
-
.dive();
|
|
807
|
+
).dive();
|
|
811
808
|
});
|
|
812
809
|
|
|
813
810
|
it('renders Select component with expected props', () => {
|
|
@@ -818,14 +815,4 @@ describe('Money Input', () => {
|
|
|
818
815
|
});
|
|
819
816
|
});
|
|
820
817
|
});
|
|
821
|
-
|
|
822
|
-
describe('withId', () => {
|
|
823
|
-
it('should guarantee id and connect the input with the selected currency', () => {
|
|
824
|
-
render(<MoneyInput {...props} />);
|
|
825
|
-
const input = screen.getByRole('textbox');
|
|
826
|
-
const button = screen.getByRole('combobox');
|
|
827
|
-
expect(input.getAttribute('id')).toBeTruthy();
|
|
828
|
-
expect(input).toHaveAttribute('aria-describedby', button.getAttribute('id'));
|
|
829
|
-
});
|
|
830
|
-
});
|
|
831
818
|
});
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Meta, StoryObj } from '@storybook/react';
|
|
2
|
-
import { within, userEvent } from '@storybook/test';
|
|
2
|
+
import { expect, within, userEvent } from '@storybook/test';
|
|
3
3
|
import { Lock } from '@transferwise/icons';
|
|
4
4
|
import { useState } from 'react';
|
|
5
5
|
|
|
@@ -9,13 +9,14 @@ import { Field } from '../field/Field';
|
|
|
9
9
|
export default {
|
|
10
10
|
component: MoneyInput,
|
|
11
11
|
title: 'Forms/MoneyInput',
|
|
12
|
-
render:
|
|
12
|
+
render: (args) => {
|
|
13
|
+
// eslint-disable-next-line react-hooks/rules-of-hooks
|
|
13
14
|
const [selectedCurrency, setSelectedCurrency] = useState(args.selectedCurrency);
|
|
14
15
|
|
|
15
16
|
const handleOnCurrencyChange = (value: CurrencyOptionItem) => setSelectedCurrency(value);
|
|
16
17
|
|
|
17
18
|
return (
|
|
18
|
-
<Field label="Editable money input label" required>
|
|
19
|
+
<Field id={args.id} label="Editable money input label" required>
|
|
19
20
|
<MoneyInput
|
|
20
21
|
{...args}
|
|
21
22
|
selectedCurrency={selectedCurrency}
|
|
@@ -25,6 +26,7 @@ export default {
|
|
|
25
26
|
);
|
|
26
27
|
},
|
|
27
28
|
args: {
|
|
29
|
+
id: 'money-input',
|
|
28
30
|
amount: 1000,
|
|
29
31
|
onAmountChange: () => {},
|
|
30
32
|
onCurrencyChange: () => {},
|
|
@@ -59,28 +61,28 @@ const exampleCurrency = {
|
|
|
59
61
|
hkd: {
|
|
60
62
|
value: 'HKD',
|
|
61
63
|
label: 'HKD',
|
|
62
|
-
note: 'Hong Kong
|
|
64
|
+
note: 'Hong Kong',
|
|
63
65
|
currency: 'hkd',
|
|
64
66
|
searchable: 'Hong Kong, Saudi Arabia',
|
|
65
67
|
},
|
|
66
68
|
aud: {
|
|
67
69
|
value: 'AUD',
|
|
68
70
|
label: 'AUD',
|
|
69
|
-
note: '
|
|
71
|
+
note: 'Australia',
|
|
70
72
|
currency: 'aud',
|
|
71
73
|
searchable: 'Kenguru',
|
|
72
74
|
},
|
|
73
75
|
cny: {
|
|
74
76
|
value: 'CNY',
|
|
75
77
|
label: 'CNY',
|
|
76
|
-
note: '
|
|
78
|
+
note: 'China',
|
|
77
79
|
currency: 'cny',
|
|
78
80
|
searchable: 'China',
|
|
79
81
|
},
|
|
80
82
|
jpy: {
|
|
81
83
|
value: 'JPY',
|
|
82
84
|
label: 'JPY',
|
|
83
|
-
note: '
|
|
85
|
+
note: 'Japan',
|
|
84
86
|
currency: 'jpy',
|
|
85
87
|
searchable: 'Japan',
|
|
86
88
|
},
|
|
@@ -4,7 +4,8 @@ import { clsx } from 'clsx';
|
|
|
4
4
|
import { Component } from 'react';
|
|
5
5
|
import { injectIntl, WrappedComponentProps } from 'react-intl';
|
|
6
6
|
|
|
7
|
-
import { Typography
|
|
7
|
+
import { Typography } from '../common';
|
|
8
|
+
import { Size, SizeLarge, SizeMedium, SizeSmall } from '../common/propsValues/size';
|
|
8
9
|
import { withInputAttributes, WithInputAttributesProps } from '../inputs/contexts';
|
|
9
10
|
import { Input } from '../inputs/Input';
|
|
10
11
|
import {
|
|
@@ -18,7 +19,6 @@ import Title from '../title';
|
|
|
18
19
|
|
|
19
20
|
import messages from './MoneyInput.messages';
|
|
20
21
|
import { formatAmount, parseAmount } from './currencyFormatting';
|
|
21
|
-
import withId from '../withId';
|
|
22
22
|
|
|
23
23
|
export interface CurrencyOptionItem {
|
|
24
24
|
header?: never;
|
|
@@ -288,6 +288,7 @@ class MoneyInput extends Component<MoneyInputPropsWithInputAttributes, MoneyInpu
|
|
|
288
288
|
selectProps,
|
|
289
289
|
} = this.props;
|
|
290
290
|
const ariaLabelledBy = ariaLabelledByProp ?? inputAttributes?.['aria-labelledby'];
|
|
291
|
+
|
|
291
292
|
const selectOptions = this.getSelectOptions();
|
|
292
293
|
|
|
293
294
|
const hasSingleCurrency = () => {
|
|
@@ -313,9 +314,8 @@ class MoneyInput extends Component<MoneyInputPropsWithInputAttributes, MoneyInpu
|
|
|
313
314
|
};
|
|
314
315
|
|
|
315
316
|
const isFixedCurrency = (!this.state.searchQuery && hasSingleCurrency()) || !onCurrencyChange;
|
|
316
|
-
const disabled = !this.props.onAmountChange;
|
|
317
|
-
const currencyCurrencyElementId = `${amountInputId}currentCurrency:`;
|
|
318
317
|
|
|
318
|
+
const disabled = !this.props.onAmountChange;
|
|
319
319
|
return (
|
|
320
320
|
<div
|
|
321
321
|
role="group"
|
|
@@ -338,7 +338,6 @@ class MoneyInput extends Component<MoneyInputPropsWithInputAttributes, MoneyInpu
|
|
|
338
338
|
locale: this.state.locale,
|
|
339
339
|
})}
|
|
340
340
|
autoComplete="off"
|
|
341
|
-
aria-describedby={currencyCurrencyElementId}
|
|
342
341
|
onKeyDown={this.handleKeyDown}
|
|
343
342
|
onChange={this.onAmountChange}
|
|
344
343
|
onFocus={this.onAmountFocus}
|
|
@@ -364,7 +363,6 @@ class MoneyInput extends Component<MoneyInputPropsWithInputAttributes, MoneyInpu
|
|
|
364
363
|
this.style('tw-money-input__fixed-currency'),
|
|
365
364
|
disabled ? this.style('disabled') : '',
|
|
366
365
|
)}
|
|
367
|
-
id={currencyCurrencyElementId}
|
|
368
366
|
>
|
|
369
367
|
{(size === 'lg' || size === 'md') && (
|
|
370
368
|
<span className={clsx(this.style('money-input-currency-flag'), this.style('m-r-2'))}>
|
|
@@ -387,7 +385,6 @@ class MoneyInput extends Component<MoneyInputPropsWithInputAttributes, MoneyInpu
|
|
|
387
385
|
)}
|
|
388
386
|
>
|
|
389
387
|
<SelectInput
|
|
390
|
-
id={currencyCurrencyElementId}
|
|
391
388
|
items={selectOptions}
|
|
392
389
|
value={selectedCurrency}
|
|
393
390
|
compareValues="currency"
|
|
@@ -491,4 +488,4 @@ function sortOptionsLabelsToFirst(options: readonly CurrencyOptionItem[], query:
|
|
|
491
488
|
});
|
|
492
489
|
}
|
|
493
490
|
|
|
494
|
-
export default injectIntl(
|
|
491
|
+
export default injectIntl(withInputAttributes(MoneyInput, { nonLabelable: true }));
|
|
@@ -56,7 +56,7 @@ export interface PromoCardGroupProps {
|
|
|
56
56
|
* @param {string} label - Optional label to display above the group.
|
|
57
57
|
* @param {Function} onChange - Optional function to call when the group value changes.
|
|
58
58
|
* @param {string} testId - Optional ID to add to the group container for testing purposes.
|
|
59
|
-
* @returns {JSX.Element} - The PromoCardGroup component.
|
|
59
|
+
* @returns {React.JSX.Element} - The PromoCardGroup component.
|
|
60
60
|
*/
|
|
61
61
|
const PromoCardGroup: FunctionComponent<PromoCardGroupProps> = ({
|
|
62
62
|
children,
|
|
@@ -38,7 +38,7 @@ export type PromoCardIndicatorProps = {
|
|
|
38
38
|
* @param {string | ReactElement} icon - Optional icon to display in the indicator.
|
|
39
39
|
* @param {string} testid - Optional ID to add to the indicator container for testing purposes.
|
|
40
40
|
* @param {ReactNode} children - Optional children to display inside the indicator.
|
|
41
|
-
* @returns {JSX.Element} - The PromoCardIndicator component.
|
|
41
|
+
* @returns {React.JSX.Element} - The PromoCardIndicator component.
|
|
42
42
|
* @example
|
|
43
43
|
* <PromoCardIndicator label="Download" icon="download" />
|
|
44
44
|
*/
|
package/src/sticky/Sticky.tsx
CHANGED
|
@@ -29,7 +29,7 @@ export interface StickyProps {
|
|
|
29
29
|
* @param {boolean} open - Determines if the Sticky component is open or closed.
|
|
30
30
|
* @param {('top'|'bottom')} position - Specifies the position.
|
|
31
31
|
* @param {string} testId - ID used for testing.
|
|
32
|
-
* @returns {JSX.Element} The `SlidingPanel` component with applied props.
|
|
32
|
+
* @returns {React.JSX.Element} The `SlidingPanel` component with applied props.
|
|
33
33
|
* @example
|
|
34
34
|
* <Button onClick={() => setOpen(!open)}>Open Sticky</Button>
|
|
35
35
|
* <Sticky open={open} position={'bottom'}>
|
|
@@ -11,7 +11,7 @@ import { UploadedFile, UploadError } from '../types';
|
|
|
11
11
|
import MESSAGES from './UploadItem.messages';
|
|
12
12
|
import { UploadItemLink } from './UploadItemLink';
|
|
13
13
|
|
|
14
|
-
export type UploadItemProps = JSX.IntrinsicAttributes & {
|
|
14
|
+
export type UploadItemProps = React.JSX.IntrinsicAttributes & {
|
|
15
15
|
file: UploadedFile;
|
|
16
16
|
/**
|
|
17
17
|
* Is this Item part of a multiple- or single-file UploadInput
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/withId/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,UAAU,CAAC;AACnC,YAAY,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC"}
|
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
export declare const withIdSource = "\nimport { withId, Button } from '@transferwise/components';\n\ntype DescribedButtonProps = {\n id?: string;\n}\n\nconst DescribedButton: DescribedButtonProps = ({id}) => (\n <>\n <Button aria-describedby={id}>\n Continue \n </Button>\n\n <p id={id} className=\"text-xs-center m-t-2\">\n Enter an amount in either GBP or PLN.<br />\n This paragraph has id of `{id}`\n </p>\n </>\n);\n\nexport default withId(DescribedButton);\n";
|
|
2
|
-
//# sourceMappingURL=source.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"source.d.ts","sourceRoot":"","sources":["../../../../src/withId/story/source.tsx"],"names":[],"mappings":"AAAA,eAAO,MAAM,YAAY,8cAqBxB,CAAC"}
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
import { ComponentType } from 'react';
|
|
2
|
-
type ChildProps<Props> = Props & {
|
|
3
|
-
id?: string;
|
|
4
|
-
};
|
|
5
|
-
export type WithIdProps<Props> = Props & {
|
|
6
|
-
id: string;
|
|
7
|
-
};
|
|
8
|
-
/**
|
|
9
|
-
* @internal
|
|
10
|
-
* @param {ReactNode} WrappedComponent
|
|
11
|
-
*/
|
|
12
|
-
export default function withId<Props extends object>(WrappedComponent: ComponentType<WithIdProps<Props>>): {
|
|
13
|
-
(props: ChildProps<Props>): import("react").JSX.Element;
|
|
14
|
-
displayName: string;
|
|
15
|
-
};
|
|
16
|
-
export {};
|
|
17
|
-
//# sourceMappingURL=withId.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"withId.d.ts","sourceRoot":"","sources":["../../../src/withId/withId.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAS,aAAa,EAAE,MAAM,OAAO,CAAC;AAG7C,KAAK,UAAU,CAAC,KAAK,IAAI,KAAK,GAAG;IAC/B,EAAE,CAAC,EAAE,MAAM,CAAC;CACb,CAAC;AAEF,MAAM,MAAM,WAAW,CAAC,KAAK,IAAI,KAAK,GAAG;IACvC,EAAE,EAAE,MAAM,CAAC;CACZ,CAAC;AAGF;;;GAGG;AACH,MAAM,CAAC,OAAO,UAAU,MAAM,CAAC,KAAK,SAAS,MAAM,EACjD,gBAAgB,EAAE,aAAa,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC;YAEnB,UAAU,CAAC,KAAK,CAAC;;EASlD"}
|
package/build/withId/withId.js
DELETED
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
var React = require('react');
|
|
4
|
-
var jsxRuntime = require('react/jsx-runtime');
|
|
5
|
-
|
|
6
|
-
function withId(WrappedComponent) {
|
|
7
|
-
function WithIdComponent(props) {
|
|
8
|
-
const id = React.useId();
|
|
9
|
-
return /*#__PURE__*/jsxRuntime.jsx(WrappedComponent, {
|
|
10
|
-
...props,
|
|
11
|
-
id: props.id || id
|
|
12
|
-
});
|
|
13
|
-
}
|
|
14
|
-
WithIdComponent.displayName = `withId(${WrappedComponent.displayName || WrappedComponent.name || 'Component'})`;
|
|
15
|
-
return WithIdComponent;
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
module.exports = withId;
|
|
19
|
-
//# sourceMappingURL=withId.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"withId.js","sources":["../../src/withId/withId.tsx"],"sourcesContent":["import { useId, ComponentType } from 'react';\n\n\ntype ChildProps<Props> = Props & {\n id?: string;\n};\n\nexport type WithIdProps<Props> = Props & {\n id: string;\n};\n\n\n/**\n * @internal\n * @param {ReactNode} WrappedComponent\n */\nexport default function withId<Props extends object>(\n WrappedComponent: ComponentType<WithIdProps<Props>>\n) {\n function WithIdComponent(props: ChildProps<Props>) {\n const id = useId();\n\n return <WrappedComponent {...props} id={props.id || id} />;\n }\n\n WithIdComponent.displayName = `withId(${WrappedComponent.displayName || WrappedComponent.name || 'Component'})`;\n\n return WithIdComponent;\n}\n"],"names":["withId","WrappedComponent","WithIdComponent","props","id","useId","_jsx","displayName","name"],"mappings":";;;;;AAgBwB,SAAAA,MAAMA,CAC5BC,gBAAmD,EAAA;EAEnD,SAASC,eAAeA,CAACC,KAAwB,EAAA;AAC/C,IAAA,MAAMC,EAAE,GAAGC,WAAK,EAAE,CAAA;IAElB,oBAAOC,cAAA,CAACL,gBAAgB,EAAA;AAAA,MAAA,GAAKE,KAAK;AAAEC,MAAAA,EAAE,EAAED,KAAK,CAACC,EAAE,IAAIA,EAAAA;AAAG,MAAG,CAAA;AAC5D,GAAA;AAEAF,EAAAA,eAAe,CAACK,WAAW,GAAG,CAAA,OAAA,EAAUN,gBAAgB,CAACM,WAAW,IAAIN,gBAAgB,CAACO,IAAI,IAAI,WAAW,CAAG,CAAA,CAAA,CAAA;AAE/G,EAAA,OAAON,eAAe,CAAA;AACxB;;;;"}
|
package/build/withId/withId.mjs
DELETED
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
import { useId } from 'react';
|
|
2
|
-
import { jsx } from 'react/jsx-runtime';
|
|
3
|
-
|
|
4
|
-
function withId(WrappedComponent) {
|
|
5
|
-
function WithIdComponent(props) {
|
|
6
|
-
const id = useId();
|
|
7
|
-
return /*#__PURE__*/jsx(WrappedComponent, {
|
|
8
|
-
...props,
|
|
9
|
-
id: props.id || id
|
|
10
|
-
});
|
|
11
|
-
}
|
|
12
|
-
WithIdComponent.displayName = `withId(${WrappedComponent.displayName || WrappedComponent.name || 'Component'})`;
|
|
13
|
-
return WithIdComponent;
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
export { withId as default };
|
|
17
|
-
//# sourceMappingURL=withId.mjs.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"withId.mjs","sources":["../../src/withId/withId.tsx"],"sourcesContent":["import { useId, ComponentType } from 'react';\n\n\ntype ChildProps<Props> = Props & {\n id?: string;\n};\n\nexport type WithIdProps<Props> = Props & {\n id: string;\n};\n\n\n/**\n * @internal\n * @param {ReactNode} WrappedComponent\n */\nexport default function withId<Props extends object>(\n WrappedComponent: ComponentType<WithIdProps<Props>>\n) {\n function WithIdComponent(props: ChildProps<Props>) {\n const id = useId();\n\n return <WrappedComponent {...props} id={props.id || id} />;\n }\n\n WithIdComponent.displayName = `withId(${WrappedComponent.displayName || WrappedComponent.name || 'Component'})`;\n\n return WithIdComponent;\n}\n"],"names":["withId","WrappedComponent","WithIdComponent","props","id","useId","_jsx","displayName","name"],"mappings":";;;AAgBwB,SAAAA,MAAMA,CAC5BC,gBAAmD,EAAA;EAEnD,SAASC,eAAeA,CAACC,KAAwB,EAAA;AAC/C,IAAA,MAAMC,EAAE,GAAGC,KAAK,EAAE,CAAA;IAElB,oBAAOC,GAAA,CAACL,gBAAgB,EAAA;AAAA,MAAA,GAAKE,KAAK;AAAEC,MAAAA,EAAE,EAAED,KAAK,CAACC,EAAE,IAAIA,EAAAA;AAAG,MAAG,CAAA;AAC5D,GAAA;AAEAF,EAAAA,eAAe,CAACK,WAAW,GAAG,CAAA,OAAA,EAAUN,gBAAgB,CAACM,WAAW,IAAIN,gBAAgB,CAACO,IAAI,IAAI,WAAW,CAAG,CAAA,CAAA,CAAA;AAE/G,EAAA,OAAON,eAAe,CAAA;AACxB;;;;"}
|
package/src/withId/index.ts
DELETED
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
export const withIdSource = `
|
|
2
|
-
import { withId, Button } from '@transferwise/components';
|
|
3
|
-
|
|
4
|
-
type DescribedButtonProps = {
|
|
5
|
-
id?: string;
|
|
6
|
-
}
|
|
7
|
-
|
|
8
|
-
const DescribedButton: DescribedButtonProps = ({id}) => (
|
|
9
|
-
<>
|
|
10
|
-
<Button aria-describedby={id}>
|
|
11
|
-
Continue
|
|
12
|
-
</Button>
|
|
13
|
-
|
|
14
|
-
<p id={id} className="text-xs-center m-t-2">
|
|
15
|
-
Enter an amount in either GBP or PLN.<br />
|
|
16
|
-
This paragraph has id of \`{id}\`
|
|
17
|
-
</p>
|
|
18
|
-
</>
|
|
19
|
-
);
|
|
20
|
-
|
|
21
|
-
export default withId(DescribedButton);
|
|
22
|
-
`;
|
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
import { Meta, Canvas, Source } from '@storybook/blocks';
|
|
2
|
-
import { WithoutId, WithCustomId } from './withId.story';
|
|
3
|
-
import { withIdSource } from './story/source';
|
|
4
|
-
|
|
5
|
-
<Meta title="HoCs/withId" />
|
|
6
|
-
|
|
7
|
-
# withId
|
|
8
|
-
|
|
9
|
-
This Higher Order Component injects an SSR-friendly `id` prop to any given component. It's especially useful for class-based components where you need to connect a number of elements via aria attributes, yet `useId` hook is unavailable.
|
|
10
|
-
|
|
11
|
-
> **Please note:** this component will be eventually deprecated as we move away from the class components to function components, so use with care.
|
|
12
|
-
|
|
13
|
-
## Usage
|
|
14
|
-
Given a dummy `DescribedButtonProps` component, when wrapped in the `widthId` HoC…
|
|
15
|
-
|
|
16
|
-
<Source code={withIdSource} dark />
|
|
17
|
-
|
|
18
|
-
…it will be automatically provided with a generated `id` prop…
|
|
19
|
-
|
|
20
|
-
<Canvas of={WithoutId} language="tsx" />
|
|
21
|
-
|
|
22
|
-
…but it will also respect a custom `id`, if provided.
|
|
23
|
-
|
|
24
|
-
<Canvas of={WithCustomId} language="tsx" />
|
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
import { render, screen } from '@testing-library/react';
|
|
2
|
-
import withId from '.';
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
describe('withId', () => {
|
|
6
|
-
type ButtonProps = {
|
|
7
|
-
id?: string;
|
|
8
|
-
}
|
|
9
|
-
const Button = withId<ButtonProps>(
|
|
10
|
-
(props) => <button id={props.id} type="button">click me</button>
|
|
11
|
-
);
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
it('should provide id', () => {
|
|
15
|
-
render(<Button />);
|
|
16
|
-
expect(
|
|
17
|
-
screen.getByRole('button').getAttribute('id')
|
|
18
|
-
).toBeTruthy();
|
|
19
|
-
});
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
it('should respect existing id', () => {
|
|
23
|
-
render(<Button id="myId" />);
|
|
24
|
-
expect(screen.getByRole('button')).toHaveAttribute('id', 'myId');
|
|
25
|
-
});
|
|
26
|
-
});
|
|
@@ -1,38 +0,0 @@
|
|
|
1
|
-
import { Meta, StoryObj } from '@storybook/react';
|
|
2
|
-
import { Button, withId } from '..';
|
|
3
|
-
|
|
4
|
-
type Story = StoryObj<typeof withId>;
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
type ButtonProps = {
|
|
9
|
-
id?: string;
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
const DescribedButton = withId<ButtonProps>(
|
|
13
|
-
({ id }) => <>
|
|
14
|
-
<Button aria-describedby={id}>
|
|
15
|
-
Continue
|
|
16
|
-
</Button>
|
|
17
|
-
|
|
18
|
-
<p id={id} className="text-xs-center m-t-2">
|
|
19
|
-
Enter an amount in either GBP or PLN<br />
|
|
20
|
-
This paragraph has id of <code>{id}</code>
|
|
21
|
-
</p>
|
|
22
|
-
</>
|
|
23
|
-
);
|
|
24
|
-
DescribedButton.displayName = 'DescribedButton';
|
|
25
|
-
|
|
26
|
-
export default {
|
|
27
|
-
component: DescribedButton
|
|
28
|
-
} satisfies Meta<typeof withId>;
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
export const WithoutId: Story = {};
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
export const WithCustomId: Story = {
|
|
35
|
-
args: {
|
|
36
|
-
id: 'myId',
|
|
37
|
-
},
|
|
38
|
-
};
|
package/src/withId/withId.tsx
DELETED
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
import { useId, ComponentType } from 'react';
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
type ChildProps<Props> = Props & {
|
|
5
|
-
id?: string;
|
|
6
|
-
};
|
|
7
|
-
|
|
8
|
-
export type WithIdProps<Props> = Props & {
|
|
9
|
-
id: string;
|
|
10
|
-
};
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
/**
|
|
14
|
-
* @internal
|
|
15
|
-
* @param {ReactNode} WrappedComponent
|
|
16
|
-
*/
|
|
17
|
-
export default function withId<Props extends object>(
|
|
18
|
-
WrappedComponent: ComponentType<WithIdProps<Props>>
|
|
19
|
-
) {
|
|
20
|
-
function WithIdComponent(props: ChildProps<Props>) {
|
|
21
|
-
const id = useId();
|
|
22
|
-
|
|
23
|
-
return <WrappedComponent {...props} id={props.id || id} />;
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
WithIdComponent.displayName = `withId(${WrappedComponent.displayName || WrappedComponent.name || 'Component'})`;
|
|
27
|
-
|
|
28
|
-
return WithIdComponent;
|
|
29
|
-
}
|