@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.
Files changed (59) hide show
  1. package/build/common/card/Card.js.map +1 -1
  2. package/build/common/card/Card.mjs.map +1 -1
  3. package/build/field/Field.js +1 -1
  4. package/build/field/Field.js.map +1 -1
  5. package/build/field/Field.mjs +1 -1
  6. package/build/field/Field.mjs.map +1 -1
  7. package/build/index.js +1 -2
  8. package/build/index.js.map +1 -1
  9. package/build/index.mjs +1 -1
  10. package/build/moneyInput/MoneyInput.js +3 -8
  11. package/build/moneyInput/MoneyInput.js.map +1 -1
  12. package/build/moneyInput/MoneyInput.mjs +3 -8
  13. package/build/moneyInput/MoneyInput.mjs.map +1 -1
  14. package/build/promoCard/PromoCardGroup.js.map +1 -1
  15. package/build/promoCard/PromoCardGroup.mjs.map +1 -1
  16. package/build/promoCard/PromoCardIndicator.js.map +1 -1
  17. package/build/promoCard/PromoCardIndicator.mjs.map +1 -1
  18. package/build/sticky/Sticky.js.map +1 -1
  19. package/build/sticky/Sticky.mjs.map +1 -1
  20. package/build/types/common/card/Card.d.ts +1 -1
  21. package/build/types/index.d.ts +0 -4
  22. package/build/types/index.d.ts.map +1 -1
  23. package/build/types/moneyInput/MoneyInput.d.ts +3 -7
  24. package/build/types/moneyInput/MoneyInput.d.ts.map +1 -1
  25. package/build/types/promoCard/PromoCardIndicator.d.ts +1 -1
  26. package/build/types/sticky/Sticky.d.ts +1 -1
  27. package/build/types/uploadInput/uploadItem/UploadItem.d.ts +1 -1
  28. package/build/types/uploadInput/uploadItem/UploadItem.d.ts.map +1 -1
  29. package/build/uploadInput/uploadItem/UploadItem.js.map +1 -1
  30. package/build/uploadInput/uploadItem/UploadItem.mjs.map +1 -1
  31. package/package.json +3 -3
  32. package/src/common/card/Card.tsx +1 -1
  33. package/src/field/Field.spec.tsx +1 -1
  34. package/src/field/Field.story.tsx +19 -8
  35. package/src/field/Field.tsx +1 -1
  36. package/src/index.ts +2 -5
  37. package/src/moneyInput/MoneyInput.spec.js +6 -19
  38. package/src/moneyInput/MoneyInput.story.tsx +9 -7
  39. package/src/moneyInput/MoneyInput.tsx +5 -8
  40. package/src/promoCard/PromoCardGroup.tsx +1 -1
  41. package/src/promoCard/PromoCardIndicator.tsx +1 -1
  42. package/src/sticky/Sticky.tsx +1 -1
  43. package/src/uploadInput/uploadItem/UploadItem.tsx +1 -1
  44. package/build/types/withId/index.d.ts +0 -3
  45. package/build/types/withId/index.d.ts.map +0 -1
  46. package/build/types/withId/story/source.d.ts +0 -2
  47. package/build/types/withId/story/source.d.ts.map +0 -1
  48. package/build/types/withId/withId.d.ts +0 -17
  49. package/build/types/withId/withId.d.ts.map +0 -1
  50. package/build/withId/withId.js +0 -19
  51. package/build/withId/withId.js.map +0 -1
  52. package/build/withId/withId.mjs +0 -17
  53. package/build/withId/withId.mjs.map +0 -1
  54. package/src/withId/index.ts +0 -2
  55. package/src/withId/story/source.tsx +0 -22
  56. package/src/withId/withId.docs.mdx +0 -24
  57. package/src/withId/withId.spec.tsx +0 -26
  58. package/src/withId/withId.story.tsx +0 -38
  59. package/src/withId/withId.tsx +0 -29
@@ -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>
@@ -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" required>
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 label="Text Input with Description" description="This a field Description">
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 label="Textarea with Description" description="This a TextArea Description">
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} />
@@ -31,7 +31,7 @@ export type FieldProps = {
31
31
  export const Field = ({
32
32
  id,
33
33
  label,
34
- required = false,
34
+ required = true,
35
35
  message: propMessage,
36
36
  hint,
37
37
  description = hint,
package/src/index.ts CHANGED
@@ -1,3 +1,5 @@
1
+ 'use client';
2
+
1
3
  /**
2
4
  * Types
3
5
  */
@@ -242,8 +244,3 @@ export {
242
244
  * Translations
243
245
  */
244
246
  export { default as translations } from './i18n';
245
-
246
- /**
247
- * HoCs
248
- */
249
- export { default as withId } from './withId';
@@ -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 generated id when id is not provided', () => {
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')).toBeTruthy();
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: function Render(args) {
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 dollar',
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: 'Australian dollar',
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: 'Chinese yuan',
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: 'Japanese yen',
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, Size, SizeLarge, SizeMedium, SizeSmall } from '../common';
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(withId(withInputAttributes(MoneyInput, { nonLabelable: true })));
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
  */
@@ -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,3 +0,0 @@
1
- export { default } from './withId';
2
- export type { WithIdProps } from './withId';
3
- //# sourceMappingURL=index.d.ts.map
@@ -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"}
@@ -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;;;;"}
@@ -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;;;;"}
@@ -1,2 +0,0 @@
1
- export { default } from './withId';
2
- export type { WithIdProps } from './withId';
@@ -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
- };
@@ -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
- }