@transferwise/components 0.0.0-experimental-b26a3c1 → 0.0.0-experimental-31fcf10

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.
@@ -42,11 +42,9 @@ const Button = /*#__PURE__*/React.forwardRef(({
42
42
  disabled = false,
43
43
  priority = 'primary',
44
44
  sentiment = 'default',
45
- // iconStart: IconStart,
46
- // iconEnd: IconEnd,
47
- // avatars,
48
- addonStart,
49
- addonEnd,
45
+ iconStart: IconStart,
46
+ iconEnd: IconEnd,
47
+ avatars,
50
48
  // @ts-expect-error NewButtonProps has `type` prop
51
49
  type = 'button',
52
50
  loading = false,
@@ -78,19 +76,17 @@ const Button = /*#__PURE__*/React.forwardRef(({
78
76
  className: "wds-Button-label",
79
77
  "aria-hidden": loading,
80
78
  children: size === 'lg' ? children : /*#__PURE__*/jsxRuntime.jsxs(jsxRuntime.Fragment, {
81
- children: [size === 'md' && addonStart?.type === 'avatar' && addonStart.value && /*#__PURE__*/jsxRuntime.jsx("span", {
79
+ children: [size === 'md' && avatars && /*#__PURE__*/jsxRuntime.jsx("span", {
82
80
  className: "wds-Button-avatars",
83
81
  children: /*#__PURE__*/jsxRuntime.jsx(AvatarLayout, {
84
82
  orientation: "horizontal",
85
- avatars: addonStart?.value,
83
+ avatars: avatars,
86
84
  size: 24
87
85
  })
88
- }), addonStart?.type === 'icon' && addonStart.value && /*#__PURE__*/jsxRuntime.jsx("span", {
89
- className: "wds-Button-icon wds-Button-icon--start",
90
- children: addonStart.value
91
- }), children, addonEnd?.value && /*#__PURE__*/jsxRuntime.jsx("span", {
92
- className: "wds-Button-icon wds-Button-icon--end",
93
- children: addonEnd.value
86
+ }), !avatars && IconStart && /*#__PURE__*/jsxRuntime.jsx(IconStart, {
87
+ className: "wds-Button-icon wds-Button-icon--start"
88
+ }), children, IconEnd && /*#__PURE__*/jsxRuntime.jsx(IconEnd, {
89
+ className: "wds-Button-icon wds-Button-icon--end"
94
90
  })]
95
91
  })
96
92
  })]
@@ -1 +1 @@
1
- {"version":3,"file":"Button.js","sources":["../../src/button/Button.tsx"],"sourcesContent":["/* eslint-disable react/display-name */\n/* eslint-disable @typescript-eslint/no-unsafe-assignment */\nimport { ComponentType, forwardRef, isValidElement, ReactElement, ReactNode } from 'react';\nimport {\n AnchorElementProps,\n ButtonReferenceType,\n ButtonProps as NewButtonProps,\n} from './Button.types';\nimport { PrimitiveAnchor, PrimitiveButton } from '../primitives';\nimport AvatarLayout from '../avatarLayout';\nimport ProcessIndicator from '../processIndicator';\nimport { clsx } from 'clsx';\nimport { Typography } from '../common';\nimport Body from '../body';\n\nconst Button = forwardRef<ButtonReferenceType, NewButtonProps>(\n (\n {\n as = 'button',\n children,\n className,\n size = 'lg',\n href,\n disabled = false,\n priority = 'primary',\n sentiment = 'default',\n // iconStart: IconStart,\n // iconEnd: IconEnd,\n // avatars,\n addonStart,\n addonEnd,\n // @ts-expect-error NewButtonProps has `type` prop\n type = 'button',\n loading = false,\n block = false,\n v2,\n ...props\n },\n ref,\n ) => {\n const classNames = clsx(\n 'wds-Button',\n {\n [`wds-Button--block`]: block,\n [`wds-Button--disabled`]: disabled,\n [`wds-Button--loading`]: loading,\n },\n `wds-Button--${{ sm: 'small', md: 'medium', lg: 'large' }[size]}`,\n `wds-Button--${priority}`,\n `wds-Button--${sentiment}`,\n className,\n );\n\n const contentClassNames = clsx('wds-Button-content', {\n [`wds-Button-content--loading`]: loading,\n });\n\n const content = (\n <Body\n as=\"span\"\n type={size === 'sm' ? Typography.BODY_DEFAULT_BOLD : Typography.BODY_LARGE_BOLD}\n className={contentClassNames}\n >\n {loading && (\n <ProcessIndicator\n size={size === 'sm' ? 'xxs' : 'xs'}\n className=\"wds-Button-loader\"\n data-testid=\"button-loader-indicator\"\n />\n )}\n <span className=\"wds-Button-label\" aria-hidden={loading}>\n {size === 'lg' ? (\n children\n ) : (\n <>\n {size === 'md' && addonStart?.type === 'avatar' && addonStart.value && (\n <span className=\"wds-Button-avatars\">\n <AvatarLayout orientation=\"horizontal\" avatars={addonStart?.value} size={24} />\n </span>\n )}\n\n {addonStart?.type === 'icon' && addonStart.value && (\n <span className=\"wds-Button-icon wds-Button-icon--start\">{addonStart.value}</span>\n )}\n\n {children}\n\n {addonEnd?.value && (\n <span className=\"wds-Button-icon wds-Button-icon--end\">{addonEnd.value}</span>\n )}\n </>\n )}\n </span>\n </Body>\n );\n\n if (href || as === 'a') {\n return (\n <PrimitiveAnchor\n ref={ref as React.Ref<HTMLAnchorElement>}\n {...(props as any)}\n href={href}\n className={classNames}\n disabled={disabled || loading}\n aria-busy={loading || undefined}\n >\n {content}\n </PrimitiveAnchor>\n );\n }\n\n return (\n <PrimitiveButton\n ref={ref as React.Ref<HTMLButtonElement>}\n {...(props as any)}\n className={classNames}\n disabled={disabled}\n loading={loading}\n type={type}\n >\n {content}\n </PrimitiveButton>\n );\n },\n);\n\nexport default Button;\n"],"names":["Button","forwardRef","as","children","className","size","href","disabled","priority","sentiment","addonStart","addonEnd","type","loading","block","v2","props","ref","classNames","clsx","sm","md","lg","contentClassNames","content","_jsxs","Body","Typography","BODY_DEFAULT_BOLD","BODY_LARGE_BOLD","_jsx","ProcessIndicator","_Fragment","value","AvatarLayout","orientation","avatars","PrimitiveAnchor","undefined","PrimitiveButton"],"mappings":"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"}
1
+ {"version":3,"file":"Button.js","sources":["../../src/button/Button.tsx"],"sourcesContent":["/* eslint-disable react/display-name */\n/* eslint-disable @typescript-eslint/no-unsafe-assignment */\nimport { forwardRef } from 'react';\nimport {\n AnchorElementProps,\n ButtonReferenceType,\n ButtonProps as NewButtonProps,\n} from './Button.types';\nimport { PrimitiveAnchor, PrimitiveButton } from '../primitives';\nimport AvatarLayout from '../avatarLayout';\nimport ProcessIndicator from '../processIndicator';\nimport { clsx } from 'clsx';\nimport { Typography } from '../common';\nimport Body from '../body';\n\nconst Button = forwardRef<ButtonReferenceType, NewButtonProps>(\n (\n {\n as = 'button',\n children,\n className,\n size = 'lg',\n href,\n disabled = false,\n priority = 'primary',\n sentiment = 'default',\n iconStart: IconStart,\n iconEnd: IconEnd,\n avatars,\n // @ts-expect-error NewButtonProps has `type` prop\n type = 'button',\n loading = false,\n block = false,\n v2,\n ...props\n },\n ref,\n ) => {\n const classNames = clsx(\n 'wds-Button',\n {\n [`wds-Button--block`]: block,\n [`wds-Button--disabled`]: disabled,\n [`wds-Button--loading`]: loading,\n },\n `wds-Button--${{ sm: 'small', md: 'medium', lg: 'large' }[size]}`,\n `wds-Button--${priority}`,\n `wds-Button--${sentiment}`,\n className,\n );\n\n const contentClassNames = clsx('wds-Button-content', {\n [`wds-Button-content--loading`]: loading,\n });\n\n const content = (\n <Body\n as=\"span\"\n type={size === 'sm' ? Typography.BODY_DEFAULT_BOLD : Typography.BODY_LARGE_BOLD}\n className={contentClassNames}\n >\n {loading && (\n <ProcessIndicator\n size={size === 'sm' ? 'xxs' : 'xs'}\n className=\"wds-Button-loader\"\n data-testid=\"button-loader-indicator\"\n />\n )}\n <span className=\"wds-Button-label\" aria-hidden={loading}>\n {size === 'lg' ? (\n children\n ) : (\n <>\n {size === 'md' && avatars && (\n <span className=\"wds-Button-avatars\">\n <AvatarLayout orientation=\"horizontal\" avatars={avatars} size={24} />\n </span>\n )}\n {!avatars && IconStart && (\n <IconStart className=\"wds-Button-icon wds-Button-icon--start\" />\n )}\n {children}\n {IconEnd && <IconEnd className=\"wds-Button-icon wds-Button-icon--end\" />}\n </>\n )}\n </span>\n </Body>\n );\n\n if (href || as === 'a') {\n return (\n <PrimitiveAnchor\n ref={ref as React.Ref<HTMLAnchorElement>}\n {...(props as any)}\n href={href}\n className={classNames}\n disabled={disabled || loading}\n aria-busy={loading || undefined}\n >\n {content}\n </PrimitiveAnchor>\n );\n }\n\n return (\n <PrimitiveButton\n ref={ref as React.Ref<HTMLButtonElement>}\n {...(props as any)}\n className={classNames}\n disabled={disabled}\n loading={loading}\n type={type}\n >\n {content}\n </PrimitiveButton>\n );\n },\n);\n\nexport default Button;\n"],"names":["Button","forwardRef","as","children","className","size","href","disabled","priority","sentiment","iconStart","IconStart","iconEnd","IconEnd","avatars","type","loading","block","v2","props","ref","classNames","clsx","sm","md","lg","contentClassNames","content","_jsxs","Body","Typography","BODY_DEFAULT_BOLD","BODY_LARGE_BOLD","_jsx","ProcessIndicator","_Fragment","AvatarLayout","orientation","PrimitiveAnchor","undefined","PrimitiveButton"],"mappings":"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"}
@@ -40,11 +40,9 @@ const Button = /*#__PURE__*/forwardRef(({
40
40
  disabled = false,
41
41
  priority = 'primary',
42
42
  sentiment = 'default',
43
- // iconStart: IconStart,
44
- // iconEnd: IconEnd,
45
- // avatars,
46
- addonStart,
47
- addonEnd,
43
+ iconStart: IconStart,
44
+ iconEnd: IconEnd,
45
+ avatars,
48
46
  // @ts-expect-error NewButtonProps has `type` prop
49
47
  type = 'button',
50
48
  loading = false,
@@ -76,19 +74,17 @@ const Button = /*#__PURE__*/forwardRef(({
76
74
  className: "wds-Button-label",
77
75
  "aria-hidden": loading,
78
76
  children: size === 'lg' ? children : /*#__PURE__*/jsxs(Fragment, {
79
- children: [size === 'md' && addonStart?.type === 'avatar' && addonStart.value && /*#__PURE__*/jsx("span", {
77
+ children: [size === 'md' && avatars && /*#__PURE__*/jsx("span", {
80
78
  className: "wds-Button-avatars",
81
79
  children: /*#__PURE__*/jsx(AvatarLayout, {
82
80
  orientation: "horizontal",
83
- avatars: addonStart?.value,
81
+ avatars: avatars,
84
82
  size: 24
85
83
  })
86
- }), addonStart?.type === 'icon' && addonStart.value && /*#__PURE__*/jsx("span", {
87
- className: "wds-Button-icon wds-Button-icon--start",
88
- children: addonStart.value
89
- }), children, addonEnd?.value && /*#__PURE__*/jsx("span", {
90
- className: "wds-Button-icon wds-Button-icon--end",
91
- children: addonEnd.value
84
+ }), !avatars && IconStart && /*#__PURE__*/jsx(IconStart, {
85
+ className: "wds-Button-icon wds-Button-icon--start"
86
+ }), children, IconEnd && /*#__PURE__*/jsx(IconEnd, {
87
+ className: "wds-Button-icon wds-Button-icon--end"
92
88
  })]
93
89
  })
94
90
  })]
@@ -1 +1 @@
1
- {"version":3,"file":"Button.mjs","sources":["../../src/button/Button.tsx"],"sourcesContent":["/* eslint-disable react/display-name */\n/* eslint-disable @typescript-eslint/no-unsafe-assignment */\nimport { ComponentType, forwardRef, isValidElement, ReactElement, ReactNode } from 'react';\nimport {\n AnchorElementProps,\n ButtonReferenceType,\n ButtonProps as NewButtonProps,\n} from './Button.types';\nimport { PrimitiveAnchor, PrimitiveButton } from '../primitives';\nimport AvatarLayout from '../avatarLayout';\nimport ProcessIndicator from '../processIndicator';\nimport { clsx } from 'clsx';\nimport { Typography } from '../common';\nimport Body from '../body';\n\nconst Button = forwardRef<ButtonReferenceType, NewButtonProps>(\n (\n {\n as = 'button',\n children,\n className,\n size = 'lg',\n href,\n disabled = false,\n priority = 'primary',\n sentiment = 'default',\n // iconStart: IconStart,\n // iconEnd: IconEnd,\n // avatars,\n addonStart,\n addonEnd,\n // @ts-expect-error NewButtonProps has `type` prop\n type = 'button',\n loading = false,\n block = false,\n v2,\n ...props\n },\n ref,\n ) => {\n const classNames = clsx(\n 'wds-Button',\n {\n [`wds-Button--block`]: block,\n [`wds-Button--disabled`]: disabled,\n [`wds-Button--loading`]: loading,\n },\n `wds-Button--${{ sm: 'small', md: 'medium', lg: 'large' }[size]}`,\n `wds-Button--${priority}`,\n `wds-Button--${sentiment}`,\n className,\n );\n\n const contentClassNames = clsx('wds-Button-content', {\n [`wds-Button-content--loading`]: loading,\n });\n\n const content = (\n <Body\n as=\"span\"\n type={size === 'sm' ? Typography.BODY_DEFAULT_BOLD : Typography.BODY_LARGE_BOLD}\n className={contentClassNames}\n >\n {loading && (\n <ProcessIndicator\n size={size === 'sm' ? 'xxs' : 'xs'}\n className=\"wds-Button-loader\"\n data-testid=\"button-loader-indicator\"\n />\n )}\n <span className=\"wds-Button-label\" aria-hidden={loading}>\n {size === 'lg' ? (\n children\n ) : (\n <>\n {size === 'md' && addonStart?.type === 'avatar' && addonStart.value && (\n <span className=\"wds-Button-avatars\">\n <AvatarLayout orientation=\"horizontal\" avatars={addonStart?.value} size={24} />\n </span>\n )}\n\n {addonStart?.type === 'icon' && addonStart.value && (\n <span className=\"wds-Button-icon wds-Button-icon--start\">{addonStart.value}</span>\n )}\n\n {children}\n\n {addonEnd?.value && (\n <span className=\"wds-Button-icon wds-Button-icon--end\">{addonEnd.value}</span>\n )}\n </>\n )}\n </span>\n </Body>\n );\n\n if (href || as === 'a') {\n return (\n <PrimitiveAnchor\n ref={ref as React.Ref<HTMLAnchorElement>}\n {...(props as any)}\n href={href}\n className={classNames}\n disabled={disabled || loading}\n aria-busy={loading || undefined}\n >\n {content}\n </PrimitiveAnchor>\n );\n }\n\n return (\n <PrimitiveButton\n ref={ref as React.Ref<HTMLButtonElement>}\n {...(props as any)}\n className={classNames}\n disabled={disabled}\n loading={loading}\n type={type}\n >\n {content}\n </PrimitiveButton>\n );\n },\n);\n\nexport default Button;\n"],"names":["Button","forwardRef","as","children","className","size","href","disabled","priority","sentiment","addonStart","addonEnd","type","loading","block","v2","props","ref","classNames","clsx","sm","md","lg","contentClassNames","content","_jsxs","Body","Typography","BODY_DEFAULT_BOLD","BODY_LARGE_BOLD","_jsx","ProcessIndicator","_Fragment","value","AvatarLayout","orientation","avatars","PrimitiveAnchor","undefined","PrimitiveButton"],"mappings":"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"}
1
+ {"version":3,"file":"Button.mjs","sources":["../../src/button/Button.tsx"],"sourcesContent":["/* eslint-disable react/display-name */\n/* eslint-disable @typescript-eslint/no-unsafe-assignment */\nimport { forwardRef } from 'react';\nimport {\n AnchorElementProps,\n ButtonReferenceType,\n ButtonProps as NewButtonProps,\n} from './Button.types';\nimport { PrimitiveAnchor, PrimitiveButton } from '../primitives';\nimport AvatarLayout from '../avatarLayout';\nimport ProcessIndicator from '../processIndicator';\nimport { clsx } from 'clsx';\nimport { Typography } from '../common';\nimport Body from '../body';\n\nconst Button = forwardRef<ButtonReferenceType, NewButtonProps>(\n (\n {\n as = 'button',\n children,\n className,\n size = 'lg',\n href,\n disabled = false,\n priority = 'primary',\n sentiment = 'default',\n iconStart: IconStart,\n iconEnd: IconEnd,\n avatars,\n // @ts-expect-error NewButtonProps has `type` prop\n type = 'button',\n loading = false,\n block = false,\n v2,\n ...props\n },\n ref,\n ) => {\n const classNames = clsx(\n 'wds-Button',\n {\n [`wds-Button--block`]: block,\n [`wds-Button--disabled`]: disabled,\n [`wds-Button--loading`]: loading,\n },\n `wds-Button--${{ sm: 'small', md: 'medium', lg: 'large' }[size]}`,\n `wds-Button--${priority}`,\n `wds-Button--${sentiment}`,\n className,\n );\n\n const contentClassNames = clsx('wds-Button-content', {\n [`wds-Button-content--loading`]: loading,\n });\n\n const content = (\n <Body\n as=\"span\"\n type={size === 'sm' ? Typography.BODY_DEFAULT_BOLD : Typography.BODY_LARGE_BOLD}\n className={contentClassNames}\n >\n {loading && (\n <ProcessIndicator\n size={size === 'sm' ? 'xxs' : 'xs'}\n className=\"wds-Button-loader\"\n data-testid=\"button-loader-indicator\"\n />\n )}\n <span className=\"wds-Button-label\" aria-hidden={loading}>\n {size === 'lg' ? (\n children\n ) : (\n <>\n {size === 'md' && avatars && (\n <span className=\"wds-Button-avatars\">\n <AvatarLayout orientation=\"horizontal\" avatars={avatars} size={24} />\n </span>\n )}\n {!avatars && IconStart && (\n <IconStart className=\"wds-Button-icon wds-Button-icon--start\" />\n )}\n {children}\n {IconEnd && <IconEnd className=\"wds-Button-icon wds-Button-icon--end\" />}\n </>\n )}\n </span>\n </Body>\n );\n\n if (href || as === 'a') {\n return (\n <PrimitiveAnchor\n ref={ref as React.Ref<HTMLAnchorElement>}\n {...(props as any)}\n href={href}\n className={classNames}\n disabled={disabled || loading}\n aria-busy={loading || undefined}\n >\n {content}\n </PrimitiveAnchor>\n );\n }\n\n return (\n <PrimitiveButton\n ref={ref as React.Ref<HTMLButtonElement>}\n {...(props as any)}\n className={classNames}\n disabled={disabled}\n loading={loading}\n type={type}\n >\n {content}\n </PrimitiveButton>\n );\n },\n);\n\nexport default Button;\n"],"names":["Button","forwardRef","as","children","className","size","href","disabled","priority","sentiment","iconStart","IconStart","iconEnd","IconEnd","avatars","type","loading","block","v2","props","ref","classNames","clsx","sm","md","lg","contentClassNames","content","_jsxs","Body","Typography","BODY_DEFAULT_BOLD","BODY_LARGE_BOLD","_jsx","ProcessIndicator","_Fragment","AvatarLayout","orientation","PrimitiveAnchor","undefined","PrimitiveButton"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"Button.d.ts","sourceRoot":"","sources":["../../../src/button/Button.tsx"],"names":[],"mappings":"AAGA,OAAO,EAEL,mBAAmB,EACnB,WAAW,IAAI,cAAc,EAC9B,MAAM,gBAAgB,CAAC;AAQxB,QAAA,MAAM,MAAM,gHA6GX,CAAC;AAEF,eAAe,MAAM,CAAC"}
1
+ {"version":3,"file":"Button.d.ts","sourceRoot":"","sources":["../../../src/button/Button.tsx"],"names":[],"mappings":"AAGA,OAAO,EAEL,mBAAmB,EACnB,WAAW,IAAI,cAAc,EAC9B,MAAM,gBAAgB,CAAC;AAQxB,QAAA,MAAM,MAAM,gHAsGX,CAAC;AAEF,eAAe,MAAM,CAAC"}
@@ -4,16 +4,6 @@ export type ButtonSentiment = 'default' | 'negative';
4
4
  export type ButtonPriority = 'primary' | 'secondary' | 'tertiary' | 'minimal';
5
5
  export type ButtonSize = 'sm' | 'md' | 'lg';
6
6
  export type ButtonReferenceType = HTMLButtonElement | HTMLAnchorElement;
7
- type ButtonAddonIcon = {
8
- type: 'icon';
9
- value: ReactNode;
10
- };
11
- type ButtonAddonAvatar = {
12
- type: 'avatar';
13
- value: AvatarLayoutProps['avatars'];
14
- };
15
- type ButtonAddonStart = ButtonAddonIcon | ButtonAddonAvatar;
16
- type ButtonAddonEnd = ButtonAddonIcon;
17
7
  /**
18
8
  * Common properties for the Button component.
19
9
  */
@@ -52,15 +42,16 @@ export interface CommonProps {
52
42
  * @default default
53
43
  */
54
44
  sentiment?: ButtonSentiment;
55
- /** Accessory to be displayed before the label */
56
- addonStart?: ButtonAddonStart;
57
- /** Accessory to be displayed after the label */
58
- addonEnd?: ButtonAddonEnd;
45
+ /** Icon to be displayed on the left side of the button */
46
+ iconStart?: React.ElementType;
47
+ /** Icon to be displayed on the right side of the button */
48
+ iconEnd?: React.ElementType;
49
+ /** Media to be displayed on the left side of the button */
50
+ avatars?: AvatarLayoutProps['avatars'];
59
51
  /** Content to be displayed inside the button */
60
52
  children?: ReactNode;
61
53
  }
62
54
  export type ButtonElementProps = Omit<ButtonHTMLAttributes<HTMLButtonElement>, 'disabled' | 'className'> & CommonProps;
63
55
  export type AnchorElementProps = Omit<AnchorHTMLAttributes<HTMLAnchorElement>, 'type' | 'disabled' | 'href' | 'className'> & CommonProps;
64
56
  export type ButtonProps = ButtonElementProps | AnchorElementProps;
65
- export {};
66
57
  //# sourceMappingURL=Button.types.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"Button.types.d.ts","sourceRoot":"","sources":["../../../src/button/Button.types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,oBAAoB,EAAE,SAAS,EAAgB,MAAM,OAAO,CAAC;AAC5F,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AAEzD,MAAM,MAAM,eAAe,GAAG,SAAS,GAAG,UAAU,CAAC;AACrD,MAAM,MAAM,cAAc,GAAG,SAAS,GAAG,WAAW,GAAG,UAAU,GAAG,SAAS,CAAC;AAC9E,MAAM,MAAM,UAAU,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC;AAC5C,MAAM,MAAM,mBAAmB,GAAG,iBAAiB,GAAG,iBAAiB,CAAC;AACxE,KAAK,eAAe,GAAG;IACrB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,SAAS,CAAC;CAClB,CAAC;AACF,KAAK,iBAAiB,GAAG;IACvB,IAAI,EAAE,QAAQ,CAAC;IACf,KAAK,EAAE,iBAAiB,CAAC,SAAS,CAAC,CAAC;CACrC,CAAC;AACF,KAAK,gBAAgB,GAAG,eAAe,GAAG,iBAAiB,CAAC;AAC5D,KAAK,cAAc,GAAG,eAAe,CAAC;AAEtC;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,EAAE,EAAE,IAAI,CAAC;IAET;;;QAGI;IACJ,EAAE,CAAC,EAAE,QAAQ,GAAG,GAAG,CAAC;IAEpB,sDAAsD;IACtD,SAAS,CAAC,EAAE,MAAM,CAAC;IAEnB;;QAEI;IACJ,QAAQ,CAAC,EAAE,OAAO,CAAC;IAEnB,IAAI,CAAC,EAAE,MAAM,CAAC;IAEd;;SAEK;IACL,OAAO,CAAC,EAAE,OAAO,CAAC;IAElB,wEAAwE;IACxE,KAAK,CAAC,EAAE,OAAO,CAAC;IAEhB;;;SAGK;IACL,IAAI,CAAC,EAAE,UAAU,CAAC;IAElB;;;OAGG;IACH,QAAQ,CAAC,EAAE,cAAc,CAAC;IAE1B;;;OAGG;IACH,SAAS,CAAC,EAAE,eAAe,CAAC;IAE5B,iDAAiD;IACjD,UAAU,CAAC,EAAE,gBAAgB,CAAC;IAE9B,gDAAgD;IAChD,QAAQ,CAAC,EAAE,cAAc,CAAC;IAE1B,gDAAgD;IAChD,QAAQ,CAAC,EAAE,SAAS,CAAC;CACtB;AAED,MAAM,MAAM,kBAAkB,GAAG,IAAI,CACnC,oBAAoB,CAAC,iBAAiB,CAAC,EACvC,UAAU,GAAG,WAAW,CACzB,GACC,WAAW,CAAC;AACd,MAAM,MAAM,kBAAkB,GAAG,IAAI,CACnC,oBAAoB,CAAC,iBAAiB,CAAC,EACvC,MAAM,GAAG,UAAU,GAAG,MAAM,GAAG,WAAW,CAC3C,GACC,WAAW,CAAC;AAEd,MAAM,MAAM,WAAW,GAAG,kBAAkB,GAAG,kBAAkB,CAAC"}
1
+ {"version":3,"file":"Button.types.d.ts","sourceRoot":"","sources":["../../../src/button/Button.types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,oBAAoB,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAE9E,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AAEzD,MAAM,MAAM,eAAe,GAAG,SAAS,GAAG,UAAU,CAAC;AACrD,MAAM,MAAM,cAAc,GAAG,SAAS,GAAG,WAAW,GAAG,UAAU,GAAG,SAAS,CAAC;AAC9E,MAAM,MAAM,UAAU,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC;AAC5C,MAAM,MAAM,mBAAmB,GAAG,iBAAiB,GAAG,iBAAiB,CAAC;AAExE;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,EAAE,EAAE,IAAI,CAAC;IAET;;;QAGI;IACJ,EAAE,CAAC,EAAE,QAAQ,GAAG,GAAG,CAAC;IAEpB,sDAAsD;IACtD,SAAS,CAAC,EAAE,MAAM,CAAC;IAEnB;;QAEI;IACJ,QAAQ,CAAC,EAAE,OAAO,CAAC;IAEnB,IAAI,CAAC,EAAE,MAAM,CAAC;IAEd;;SAEK;IACL,OAAO,CAAC,EAAE,OAAO,CAAC;IAElB,wEAAwE;IACxE,KAAK,CAAC,EAAE,OAAO,CAAC;IAEhB;;;SAGK;IACL,IAAI,CAAC,EAAE,UAAU,CAAC;IAElB;;;OAGG;IACH,QAAQ,CAAC,EAAE,cAAc,CAAC;IAE1B;;;OAGG;IACH,SAAS,CAAC,EAAE,eAAe,CAAC;IAE5B,0DAA0D;IAC1D,SAAS,CAAC,EAAE,KAAK,CAAC,WAAW,CAAC;IAE9B,2DAA2D;IAC3D,OAAO,CAAC,EAAE,KAAK,CAAC,WAAW,CAAC;IAE5B,2DAA2D;IAC3D,OAAO,CAAC,EAAE,iBAAiB,CAAC,SAAS,CAAC,CAAC;IAEvC,gDAAgD;IAChD,QAAQ,CAAC,EAAE,SAAS,CAAC;CACtB;AAED,MAAM,MAAM,kBAAkB,GAAG,IAAI,CACnC,oBAAoB,CAAC,iBAAiB,CAAC,EACvC,UAAU,GAAG,WAAW,CACzB,GACC,WAAW,CAAC;AACd,MAAM,MAAM,kBAAkB,GAAG,IAAI,CACnC,oBAAoB,CAAC,iBAAiB,CAAC,EACvC,MAAM,GAAG,UAAU,GAAG,MAAM,GAAG,WAAW,CAC3C,GACC,WAAW,CAAC;AAEd,MAAM,MAAM,WAAW,GAAG,kBAAkB,GAAG,kBAAkB,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@transferwise/components",
3
- "version": "0.0.0-experimental-b26a3c1",
3
+ "version": "0.0.0-experimental-31fcf10",
4
4
  "description": "Neptune React components",
5
5
  "license": "Apache-2.0",
6
6
  "repository": {
@@ -92,12 +92,12 @@
92
92
  "rollup-preserve-directives": "^1.1.1",
93
93
  "storybook": "^8.2.2",
94
94
  "@transferwise/less-config": "3.1.0",
95
- "@transferwise/neptune-css": "0.0.0-experimental-b26a3c1",
95
+ "@transferwise/neptune-css": "0.0.0-experimental-31fcf10",
96
96
  "@wise/components-theming": "1.6.1"
97
97
  },
98
98
  "peerDependencies": {
99
99
  "@transferwise/icons": "^3.13.1",
100
- "@transferwise/neptune-css": "0.0.0-experimental-b26a3c1",
100
+ "@transferwise/neptune-css": "0.0.0-experimental-31fcf10",
101
101
  "@wise/art": "^2.16",
102
102
  "@wise/components-theming": "^1.0.0",
103
103
  "react": ">=18",
@@ -0,0 +1,103 @@
1
+ import { Meta, Canvas, Source } from '@storybook/blocks';
2
+ import { NavigationOption } from '..';
3
+ import { Bulb } from '@transferwise/icons';
4
+ import * as stories from './Button.story';
5
+
6
+ <Meta title="Actions/Button/Accessibility" />
7
+
8
+ # Accessibility
9
+
10
+ Given the `Button` is a widely used and highly sensitive component, there are some instances where care is required to ensure inclusive and accessible experience.
11
+
12
+ <NavigationOption
13
+ media={<Bulb size={24} />}
14
+ title="Design guidance"
15
+ content="Before you start, familiarise yourself with the dedicated accessibility documentation."
16
+ href="https://wise.design/components/button#accessibility"
17
+ />
18
+
19
+ <br />
20
+ <br />
21
+
22
+ ## Anchors
23
+
24
+ While it's technically possible to make the `Button` component render as a link by using `as="a"` on its own, and there are use cases for it, this will not result in a semantic HTML anchor. For that to happen, you should set `href` instead – it will automatically render the component as a semantic anchor.
25
+
26
+ <Source dark code={`
27
+ // ⚠️ use with care
28
+ <Button v2 as="a">Inaccessible anchor</Button>
29
+
30
+ // ✅ semantic link
31
+
32
+ <Button v2 href="https://wise.com">
33
+ Accessible anchor
34
+ </Button>
35
+ <Button v2 href="https://wise.com" as="a">
36
+ Accessible anchor
37
+ </Button>
38
+ `}/>
39
+
40
+ It's also worth noting that HTML links without a valid `href` are not recognised by RTL via `getByRole('link')`.
41
+
42
+ **Additional resources:**
43
+
44
+ 1. [Deque: Anchors must only be used as links with valid URLs or URL fragments](https://dequeuniversity.com/rules/axe-devtools/4.2/href-no-hash)
45
+ 2. [whatwg HTML standard: 4.6.2 Links created by a and area elements](https://html.spec.whatwg.org/multipage/links.html#links-created-by-a-and-area-elements)
46
+
47
+ <br />
48
+
49
+ ## Disabled anchors
50
+
51
+ Technically, there's no such thing as disabled HTML anchor and the `disabled` attribute is not recognised on the `<a />`. While the code shown below works in all major screen readers, should be overall considered a last resort and design teams should be encouraged to use it sporadically and consider alternative flows instead.
52
+
53
+ <Source
54
+ dark
55
+ code={`
56
+ // ⚠️ use with care
57
+ <Button v2 href="https://wise.com" disabled>Emulated disabled anchor</Button>
58
+ `}
59
+ />
60
+
61
+ We're emulating this behaviour by applying a combination of the following:
62
+
63
+ 1. removing `href` attribute to strip out the link's semantics.
64
+ 2. adding `role="link"` to make it recognisable and discoverable by the assistive tech.
65
+ 3. setting `aria-disabled="true"` to inform assistive tech of the component state.
66
+
67
+ **Additional resources:**
68
+
69
+ 1. [Scott O'Hara: Disabling a link](https://www.scottohara.me/blog/2021/05/28/disabled-links.html)
70
+ 2. [CSS-Tricks: How to Disable Links](https://css-tricks.com/how-to-disable-links/)
71
+
72
+ <br />
73
+
74
+ ## Loading state
75
+
76
+ While it might be tempting to use the native, HTML `disabled` attribute for the `loading` state, it would result in a component that is completely invisible to the assistive tech – not focusable and not parsable – entirely inaccessible experience for users relying on such tools.
77
+
78
+ Instead, we're relying on ARIA attributes and roles to ensure the `Button` is focusable, correctly announced as "busy" and offering visual cue different to the disabled state.
79
+
80
+ <Source dark code={`
81
+ // ❌ do not use
82
+ <Button v2 loading disabled>Invisible</Button>
83
+
84
+ // ✅ semantic loading button
85
+
86
+ <Button v2 loading>
87
+ Proper loading state
88
+ </Button>
89
+ `}/>
90
+
91
+ `Button` instances rendered as HTML anchors, follow the strategy described in the [Disabled anchors](#disabled-anchors) section above.
92
+
93
+ <br />
94
+
95
+ ## Working with addons (accessories)
96
+
97
+ One of the core requirements of accessible experience is that all users have equal access to the same content, no matter how they interact with our products.
98
+
99
+ This becomes troublesome for more complex instances of the `Button` such as those with contentful icons or avatars, e.g. those referring to particular currencies, people or action types.
100
+
101
+ Exposing separate ARIA labels for such addons would likely become problematic due to syntactic differences between different languages and so instead we recommend using simple `aria-label` attribute to describe given components complete content. Please note, that screen readers will use that text over the visible label
102
+
103
+ <Canvas of={stories.AccessibilityAddons} />
@@ -1,6 +1,6 @@
1
1
  import { Meta, StoryObj } from '@storybook/react';
2
2
  import { fn } from '@storybook/test';
3
- import { Freeze, ArrowRight, ChevronRight } from '@transferwise/icons';
3
+ import { Freeze, ArrowRight, ArrowLeft, ChevronRight, ChevronLeft } from '@transferwise/icons';
4
4
  import { Flag } from '@wise/art';
5
5
  import Button from './Button.resolver';
6
6
  import type { ButtonProps, ButtonPriority } from './Button.types';
@@ -39,8 +39,9 @@ const withComponentGrid =
39
39
  */
40
40
  const hideControls = (args: string[]) => {
41
41
  const hidden = [
42
- 'addonStart',
43
- 'addonEnd',
42
+ 'avatars',
43
+ 'iconStart',
44
+ 'iconEnd',
44
45
  'onClick',
45
46
  'onBlur',
46
47
  'onFocus',
@@ -53,88 +54,84 @@ const hideControls = (args: string[]) => {
53
54
  return Object.fromEntries(hidden.map((item) => [item, { table: { disable: true } }]));
54
55
  };
55
56
 
57
+ /**
58
+ * SB code generation is often not ideal, rendering confusing source.
59
+ * This helper makes icon values more understandable for the stories below.
60
+ */
61
+ const augmentIconProps = ({ start = 'Freeze', end = 'ArrowRight' } = {}) => ({
62
+ docs: {
63
+ source: {
64
+ transform(value: string): string {
65
+ return value
66
+ .replace(/iconStart=.*?\}+/g, `iconStart={${start}}`)
67
+ .replace(/iconEnd=.*?\}+/g, `iconEnd={${end}}`);
68
+ },
69
+ },
70
+ },
71
+ });
72
+
56
73
  /**
57
74
  * Convenience controls for previewing rich markup,
58
75
  * not otherwise possible via Storybook
59
76
  */
60
77
  type PreviewStoryArgs = Parameters<typeof Button>[0] & {
61
- previewAddonStart: boolean | ButtonProps['addonStart'];
62
- previewAddonEnd: boolean | ButtonProps['addonEnd'];
78
+ previewAvatars: boolean | ButtonProps['avatars'];
79
+ previewIconStart: boolean | ButtonProps['iconStart'];
80
+ previewIconEnd: boolean | ButtonProps['iconEnd'];
63
81
  };
64
82
  const previewArgTypes = {
65
- previewAddonStart: {
66
- control: 'select',
67
- options: [
68
- 'undefined',
69
- 'icon',
70
- 'avatar: flag',
71
- 'avatar: initials',
72
- 'avatar: icon',
73
- 'avatar: image',
74
- 'avatar: double',
75
- ],
76
- name: 'Preview with `addonStart`',
83
+ previewIconStart: {
84
+ control: 'boolean',
85
+ name: 'Show with `iconStart`',
77
86
  mapping: {
78
- undefined,
79
- icon: {
80
- type: 'icon',
81
- value: <Freeze />,
82
- },
83
- 'avatar: flag': {
84
- type: 'avatar',
85
- value: [{ asset: <Flag code="pl" /> }],
86
- },
87
- 'avatar: initials': {
88
- type: 'avatar',
89
- value: [{ profileName: 'Jay Jay' }],
90
- },
91
- 'avatar: icon': {
92
- type: 'avatar',
93
- value: [{ asset: <Freeze /> }],
94
- },
95
- 'avatar: image': {
96
- type: 'avatar',
97
- value: [{ imgSrc: '../avatar-square-dude.webp' }],
98
- },
99
- 'avatar: double': {
100
- type: 'avatar',
101
- value: [{ asset: <Flag code="gb" /> }, { imgSrc: '../avatar-square-dude.webp' }],
102
- },
87
+ true: Freeze,
103
88
  },
104
89
  table: {
105
90
  category: 'Preview options',
106
- type: {
107
- summary: undefined,
108
- },
109
91
  },
110
92
  },
111
- previewAddonEnd: {
93
+ previewIconEnd: {
112
94
  control: 'boolean',
113
- name: 'Preview with `addonEnd`',
95
+ name: 'Show with `iconEnd`',
114
96
  mapping: {
115
- true: { type: 'icon', value: <ArrowRight /> },
97
+ true: ArrowRight,
98
+ },
99
+ table: {
100
+ category: 'Preview options',
101
+ },
102
+ },
103
+ previewAvatars: {
104
+ control: 'select',
105
+ options: ['undefined', 'flag', 'initials', 'icon', 'image', 'double'],
106
+ name: 'Show with Avatar',
107
+ mapping: {
108
+ undefined,
109
+ flag: [{ asset: <Flag code="pl" /> }],
110
+ initials: [{ profileName: 'Jay Jay' }],
111
+ icon: [{ asset: <Freeze /> }],
112
+ image: [{ imgSrc: '../avatar-square-dude.webp' }],
113
+ double: [{ asset: <Flag code="gb" /> }, { imgSrc: '../avatar-square-dude.webp' }],
116
114
  },
117
115
  table: {
118
116
  category: 'Preview options',
119
- type: {
120
- summary: undefined,
121
- },
122
117
  },
123
118
  },
124
119
  } as const;
125
120
 
126
121
  const getPropsForPreview = (args: PreviewStoryArgs) => {
127
- const { previewAddonStart, previewAddonEnd, ...props } = args as {
128
- previewAddonStart: ButtonProps['addonStart'];
129
- previewAddonEnd: ButtonProps['addonEnd'];
122
+ const { previewAvatars, previewIconStart, previewIconEnd, ...props } = args as {
123
+ previewAvatars: ButtonProps['avatars'];
124
+ previewIconStart: ButtonProps['iconStart'];
125
+ previewIconEnd: ButtonProps['iconEnd'];
130
126
  props: typeof Button;
131
127
  };
132
128
 
133
129
  return [
134
130
  props,
135
131
  {
136
- addonStart: previewAddonStart,
137
- addonEnd: previewAddonEnd,
132
+ avatars: previewAvatars,
133
+ iconStart: previewIconStart,
134
+ iconEnd: previewIconEnd,
138
135
  },
139
136
  ];
140
137
  };
@@ -209,10 +206,13 @@ const meta: Meta<typeof Button> = {
209
206
  },
210
207
  description: 'If set, the component will render as an HTML anchor.',
211
208
  },
212
- addonStart: {
209
+ iconStart: {
210
+ control: 'object',
211
+ },
212
+ iconEnd: {
213
213
  control: 'object',
214
214
  },
215
- addonEnd: {
215
+ avatars: {
216
216
  control: 'object',
217
217
  },
218
218
  type: {
@@ -237,8 +237,9 @@ const meta: Meta<typeof Button> = {
237
237
  href: undefined,
238
238
  as: undefined,
239
239
  type: undefined,
240
- addonStart: undefined,
241
- addonEnd: undefined,
240
+ iconStart: undefined,
241
+ iconEnd: undefined,
242
+ avatars: undefined,
242
243
  className: undefined,
243
244
  onClick: fn(),
244
245
  children: 'Button text',
@@ -263,8 +264,9 @@ export const Playground: StoryObj<PreviewStoryArgs> = {
263
264
  onKeyDown: fn(),
264
265
  onMouseEnter: fn(),
265
266
  onMouseLeave: fn(),
266
- previewAddonStart: false,
267
- previewAddonEnd: false,
267
+ previewIconStart: false,
268
+ previewIconEnd: false,
269
+ previewAvatars: false,
268
270
  },
269
271
  argTypes: {
270
272
  onClick: { table: { disable: true } },
@@ -309,10 +311,12 @@ export const Sentiment: StoryObj<PreviewStoryArgs> = {
309
311
  ...previewArgTypes,
310
312
  },
311
313
  args: {
312
- previewAddonStart: false,
313
- previewAddonEnd: false,
314
+ previewIconStart: false,
315
+ previewIconEnd: false,
316
+ previewAvatars: false,
314
317
  },
315
318
  decorators: [withComponentGrid('30rem')],
319
+ parameters: augmentIconProps(),
316
320
  };
317
321
 
318
322
  /**
@@ -346,8 +350,9 @@ export const Priority: StoryObj<PreviewStoryArgs> = {
346
350
  ...previewArgTypes,
347
351
  },
348
352
  args: {
349
- previewAddonStart: false,
350
- previewAddonEnd: false,
353
+ previewIconStart: false,
354
+ previewIconEnd: false,
355
+ previewAvatars: false,
351
356
  },
352
357
  decorators: [withComponentGrid()],
353
358
  };
@@ -379,8 +384,9 @@ export const Size: StoryObj<PreviewStoryArgs> = {
379
384
  ...previewArgTypes,
380
385
  },
381
386
  args: {
382
- previewAddonStart: false,
383
- previewAddonEnd: false,
387
+ previewIconStart: false,
388
+ previewIconEnd: false,
389
+ previewAvatars: false,
384
390
  },
385
391
  decorators: [withComponentGrid()],
386
392
  };
@@ -405,8 +411,9 @@ export const AsAnchor: StoryObj<PreviewStoryArgs> = {
405
411
  args: {
406
412
  as: 'a',
407
413
  href: 'https://wise.com',
408
- previewAddonStart: false,
409
- previewAddonEnd: false,
414
+ previewIconStart: false,
415
+ previewIconEnd: false,
416
+ previewAvatars: false,
410
417
  onClick: undefined,
411
418
  },
412
419
  };
@@ -427,8 +434,9 @@ export const Disabled: StoryObj<PreviewStoryArgs> = {
427
434
  },
428
435
  args: {
429
436
  disabled: true,
430
- previewAddonStart: false,
431
- previewAddonEnd: false,
437
+ previewIconStart: false,
438
+ previewIconEnd: false,
439
+ previewAvatars: false,
432
440
  },
433
441
  };
434
442
 
@@ -448,8 +456,9 @@ export const Loading: StoryObj<PreviewStoryArgs> = {
448
456
  },
449
457
  args: {
450
458
  loading: true,
451
- previewAddonStart: false,
452
- previewAddonEnd: false,
459
+ previewIconStart: false,
460
+ previewIconEnd: false,
461
+ previewAvatars: false,
453
462
  },
454
463
  };
455
464
 
@@ -472,8 +481,9 @@ export const DisplayBlock: StoryObj<PreviewStoryArgs> = {
472
481
  },
473
482
  args: {
474
483
  block: true,
475
- previewAddonStart: false,
476
- previewAddonEnd: false,
484
+ previewIconStart: false,
485
+ previewIconEnd: false,
486
+ previewAvatars: false,
477
487
  },
478
488
  };
479
489
 
@@ -487,20 +497,15 @@ export const WithIcons: StoryObj<PreviewStoryArgs> = {
487
497
 
488
498
  return (
489
499
  <>
490
- <Button {...props} v2 addonStart={{ type: 'icon', value: <Freeze /> }}>
500
+ <Button {...props} iconStart={Freeze}>
491
501
  With start icon
492
502
  </Button>
493
503
 
494
- <Button {...props} v2 addonEnd={{ type: 'icon', value: <ArrowRight /> }}>
504
+ <Button {...props} iconEnd={ArrowRight}>
495
505
  With end icon
496
506
  </Button>
497
507
 
498
- <Button
499
- {...props}
500
- v2
501
- addonStart={{ type: 'icon', value: <Freeze /> }}
502
- addonEnd={{ type: 'icon', value: <ArrowRight /> }}
503
- >
508
+ <Button {...props} iconStart={Freeze} iconEnd={ArrowRight}>
504
509
  With both icons
505
510
  </Button>
506
511
  </>
@@ -512,27 +517,7 @@ export const WithIcons: StoryObj<PreviewStoryArgs> = {
512
517
  args: {
513
518
  size: 'md',
514
519
  },
515
- parameters: {
516
- docs: {
517
- source: {
518
- code: `
519
- <>
520
- <Button v2 size="md" addonStart={{ type: 'icon', value: <Freeze /> }}>
521
- With start icon
522
- </Button>
523
-
524
- <Button v2 size="md" addonEnd={{ type: 'icon', value: <ArrowRight /> }}>
525
- With end icon
526
- </Button>
527
-
528
- <Button v2 size="md" addonStart={{ type: 'icon', value: <Freeze /> }} addonEnd={{ type: 'icon', value: <ArrowRight /> }}>
529
- With both icons
530
- </Button>
531
- </>
532
- `,
533
- },
534
- },
535
- },
520
+ parameters: augmentIconProps(),
536
521
  decorators: [withComponentGrid()],
537
522
  };
538
523
 
@@ -546,30 +531,19 @@ export const WithAvatars: StoryObj<PreviewStoryArgs> = {
546
531
 
547
532
  return (
548
533
  <>
549
- <Button {...props} v2 addonStart={{ type: 'avatar', value: [{ asset: <Freeze /> }] }}>
534
+ <Button {...props} avatars={[{ asset: <Freeze /> }]}>
550
535
  With single avatar
551
536
  </Button>
552
537
 
553
- <Button
554
- {...props}
555
- v2
556
- addonStart={{
557
- type: 'avatar',
558
- value: [{ asset: <Flag code="br" /> }, { asset: <Flag code="jp" /> }],
559
- }}
560
- >
538
+ <Button {...props} avatars={[{ asset: <Flag code="br" /> }, { asset: <Flag code="jp" /> }]}>
561
539
  With double avatar
562
540
  </Button>
563
541
 
564
- <Button {...props} v2 addonStart={{ type: 'avatar', value: [{ profileName: 'John Doe' }] }}>
542
+ <Button {...props} avatars={[{ profileName: 'John Doe' }]}>
565
543
  With initials
566
544
  </Button>
567
545
 
568
- <Button
569
- {...props}
570
- v2
571
- addonStart={{ type: 'avatar', value: [{ imgSrc: '../avatar-square-dude.webp' }] }}
572
- >
546
+ <Button {...props} avatars={[{ imgSrc: '../avatar-square-dude.webp' }]}>
573
547
  With an image
574
548
  </Button>
575
549
  </>
@@ -578,53 +552,26 @@ export const WithAvatars: StoryObj<PreviewStoryArgs> = {
578
552
  argTypes: hideControls(['href', 'target', 'priority', 'sentiment', 'as', 'disabled', 'children']),
579
553
  args: {
580
554
  size: 'md',
555
+ avatars: [],
581
556
  },
582
557
  parameters: {
583
558
  docs: {
584
559
  source: {
585
560
  code: `
586
561
  <>
587
- <Button
588
- v2
589
- size="md"
590
- addonStart={{
591
- type: 'avatar',
592
- value: [{ asset: <Freeze /> }]
593
- }}
594
- >
562
+ <Button v2 size="md" avatars={[{ asset: <Freeze /> }]}>
595
563
  With single avatar
596
564
  </Button>
597
-
598
- <Button
599
- v2
600
- size="md"
601
- addonStart={{
602
- type: 'avatar',
603
- value: [{ asset: <Flag code="br" /> }, { asset: <Flag code="jp" /> }]
604
- }}
605
- >
565
+
566
+ <Button v2 size="md" avatars={[{ asset: <Flag code="br" /> }, { asset: <Flag code="jp" /> }]}>
606
567
  With double avatar
607
568
  </Button>
608
-
609
- <Button
610
- v2
611
- size="md"
612
- addonStart={{
613
- type: 'avatar',
614
- value: [{ profileName: 'John Doe' }]
615
- }}
616
- >
569
+
570
+ <Button v2 size="md" avatars={[{ profileName: 'John Doe' }]}>
617
571
  With initials
618
572
  </Button>
619
-
620
- <Button
621
- v2
622
- size="md"
623
- addonStart={{
624
- type: 'avatar',
625
- value: [{ imgSrc: '../avatar-square-dude.webp' }]
626
- }}
627
- >
573
+
574
+ <Button v2 size="md" avatars={[{ imgSrc: '../avatar-square-dude.webp' }]}>
628
575
  With image Avatar
629
576
  </Button>
630
577
  </>
@@ -635,6 +582,20 @@ export const WithAvatars: StoryObj<PreviewStoryArgs> = {
635
582
  decorators: [withComponentGrid()],
636
583
  };
637
584
 
585
+ /**
586
+ * Avatar will always take precedence over `iconStart`
587
+ */
588
+ export const WithAvatarAndIcon: Story = {
589
+ args: {
590
+ size: 'md',
591
+ iconStart: Freeze,
592
+ avatars: [{ profileName: 'John Doe' }],
593
+ iconEnd: ArrowRight,
594
+ },
595
+ argTypes: hideControls(['href', 'target', 'as', 'children']),
596
+ parameters: augmentIconProps(),
597
+ };
598
+
638
599
  const buttonPriorities = ['primary', 'secondary', 'tertiary', 'minimal'] as const;
639
600
  const buttonSizes = ['sm', 'md', 'lg'] as const;
640
601
 
@@ -659,8 +620,9 @@ export const AllVariants = storyConfig(
659
620
  v2
660
621
  priority={priority as ButtonPriority}
661
622
  size={size}
662
- addonStart={{ type: 'avatar', value: [{ asset: <Freeze /> }] }}
663
- addonEnd={{ type: 'icon', value: <ArrowRight /> }}
623
+ iconStart={ArrowLeft}
624
+ iconEnd={ArrowRight}
625
+ avatars={[{ asset: <Freeze /> }]}
664
626
  block
665
627
  href="https://wise.com"
666
628
  target="_blank"
@@ -672,11 +634,9 @@ export const AllVariants = storyConfig(
672
634
  v2
673
635
  priority={priority as ButtonPriority}
674
636
  size={size}
675
- addonStart={{
676
- type: 'avatar',
677
- value: [{ asset: <Freeze /> }, { asset: <Freeze /> }],
678
- }}
679
- addonEnd={{ type: 'icon', value: <ArrowRight /> }}
637
+ iconStart={ArrowLeft}
638
+ iconEnd={ArrowRight}
639
+ avatars={[{ asset: <Freeze /> }, { asset: <Freeze /> }]}
680
640
  block
681
641
  disabled
682
642
  >
@@ -686,8 +646,9 @@ export const AllVariants = storyConfig(
686
646
  v2
687
647
  priority={priority as ButtonPriority}
688
648
  size={size}
689
- addonStart={{ type: 'avatar', value: [{ asset: <Freeze /> }] }}
690
- addonEnd={{ type: 'icon', value: <ArrowRight /> }}
649
+ iconStart={ArrowLeft}
650
+ iconEnd={ArrowRight}
651
+ avatars={[{ asset: <Freeze /> }]}
691
652
  block
692
653
  loading
693
654
  >
@@ -707,8 +668,9 @@ export const AllVariants = storyConfig(
707
668
  sentiment="negative"
708
669
  priority={priority as ButtonPriority}
709
670
  size={size}
710
- addonEnd={{ type: 'icon', value: <ChevronRight /> }}
711
- addonStart={{ type: 'avatar', value: [{ asset: <Freeze /> }] }}
671
+ iconStart={ChevronLeft}
672
+ iconEnd={ChevronRight}
673
+ avatars={[{ asset: <Freeze /> }]}
712
674
  block
713
675
  href="https://wise.com"
714
676
  target="_blank"
@@ -721,8 +683,9 @@ export const AllVariants = storyConfig(
721
683
  sentiment="negative"
722
684
  priority={priority as ButtonPriority}
723
685
  size={size}
724
- addonEnd={{ type: 'icon', value: <ChevronRight /> }}
725
- addonStart={{ type: 'avatar', value: [{ asset: <Freeze /> }] }}
686
+ iconStart={ChevronLeft}
687
+ iconEnd={ChevronRight}
688
+ avatars={[{ asset: <Freeze /> }]}
726
689
  block
727
690
  disabled
728
691
  >
@@ -733,8 +696,9 @@ export const AllVariants = storyConfig(
733
696
  sentiment="negative"
734
697
  priority={priority as ButtonPriority}
735
698
  size={size}
736
- addonEnd={{ type: 'icon', value: <ChevronRight /> }}
737
- addonStart={{ type: 'avatar', value: [{ asset: <Freeze /> }] }}
699
+ iconStart={ChevronLeft}
700
+ iconEnd={ChevronRight}
701
+ avatars={[{ asset: <Freeze /> }]}
738
702
  block
739
703
  loading
740
704
  >
@@ -748,3 +712,14 @@ export const AllVariants = storyConfig(
748
712
  },
749
713
  { variants: ['default', 'dark', 'bright-green', 'forest-green', 'rtl'] },
750
714
  );
715
+
716
+ export const AccessibilityAddons: Story = {
717
+ args: {
718
+ v2: true,
719
+ avatars: [{ asset: <Flag code="br" /> }, { asset: <Flag code="jp" /> }],
720
+ 'aria-label': 'Convert Real to Yen',
721
+ children: 'Convert',
722
+ size: 'md',
723
+ },
724
+ tags: ['docs-only'],
725
+ };
@@ -1,6 +1,6 @@
1
1
  /* eslint-disable react/display-name */
2
2
  /* eslint-disable @typescript-eslint/no-unsafe-assignment */
3
- import { ComponentType, forwardRef, isValidElement, ReactElement, ReactNode } from 'react';
3
+ import { forwardRef } from 'react';
4
4
  import {
5
5
  AnchorElementProps,
6
6
  ButtonReferenceType,
@@ -24,11 +24,9 @@ const Button = forwardRef<ButtonReferenceType, NewButtonProps>(
24
24
  disabled = false,
25
25
  priority = 'primary',
26
26
  sentiment = 'default',
27
- // iconStart: IconStart,
28
- // iconEnd: IconEnd,
29
- // avatars,
30
- addonStart,
31
- addonEnd,
27
+ iconStart: IconStart,
28
+ iconEnd: IconEnd,
29
+ avatars,
32
30
  // @ts-expect-error NewButtonProps has `type` prop
33
31
  type = 'button',
34
32
  loading = false,
@@ -73,21 +71,16 @@ const Button = forwardRef<ButtonReferenceType, NewButtonProps>(
73
71
  children
74
72
  ) : (
75
73
  <>
76
- {size === 'md' && addonStart?.type === 'avatar' && addonStart.value && (
74
+ {size === 'md' && avatars && (
77
75
  <span className="wds-Button-avatars">
78
- <AvatarLayout orientation="horizontal" avatars={addonStart?.value} size={24} />
76
+ <AvatarLayout orientation="horizontal" avatars={avatars} size={24} />
79
77
  </span>
80
78
  )}
81
-
82
- {addonStart?.type === 'icon' && addonStart.value && (
83
- <span className="wds-Button-icon wds-Button-icon--start">{addonStart.value}</span>
79
+ {!avatars && IconStart && (
80
+ <IconStart className="wds-Button-icon wds-Button-icon--start" />
84
81
  )}
85
-
86
82
  {children}
87
-
88
- {addonEnd?.value && (
89
- <span className="wds-Button-icon wds-Button-icon--end">{addonEnd.value}</span>
90
- )}
83
+ {IconEnd && <IconEnd className="wds-Button-icon wds-Button-icon--end" />}
91
84
  </>
92
85
  )}
93
86
  </span>
@@ -1,20 +1,11 @@
1
- import { AnchorHTMLAttributes, ButtonHTMLAttributes, ReactNode, ReactElement } from 'react';
1
+ import { AnchorHTMLAttributes, ButtonHTMLAttributes, ReactNode } from 'react';
2
+ import type { PrimitiveButtonProps, PrimitiveAnchorProps } from '../primitives';
2
3
  import type { AvatarLayoutProps } from '../avatarLayout';
3
4
 
4
5
  export type ButtonSentiment = 'default' | 'negative';
5
6
  export type ButtonPriority = 'primary' | 'secondary' | 'tertiary' | 'minimal';
6
7
  export type ButtonSize = 'sm' | 'md' | 'lg';
7
8
  export type ButtonReferenceType = HTMLButtonElement | HTMLAnchorElement;
8
- type ButtonAddonIcon = {
9
- type: 'icon';
10
- value: ReactNode;
11
- };
12
- type ButtonAddonAvatar = {
13
- type: 'avatar';
14
- value: AvatarLayoutProps['avatars'];
15
- };
16
- type ButtonAddonStart = ButtonAddonIcon | ButtonAddonAvatar;
17
- type ButtonAddonEnd = ButtonAddonIcon;
18
9
 
19
10
  /**
20
11
  * Common properties for the Button component.
@@ -64,11 +55,14 @@ export interface CommonProps {
64
55
  */
65
56
  sentiment?: ButtonSentiment;
66
57
 
67
- /** Accessory to be displayed before the label */
68
- addonStart?: ButtonAddonStart;
58
+ /** Icon to be displayed on the left side of the button */
59
+ iconStart?: React.ElementType;
69
60
 
70
- /** Accessory to be displayed after the label */
71
- addonEnd?: ButtonAddonEnd;
61
+ /** Icon to be displayed on the right side of the button */
62
+ iconEnd?: React.ElementType;
63
+
64
+ /** Media to be displayed on the left side of the button */
65
+ avatars?: AvatarLayoutProps['avatars'];
72
66
 
73
67
  /** Content to be displayed inside the button */
74
68
  children?: ReactNode;
@@ -61,12 +61,17 @@ const meta: Meta<typeof Button> = {
61
61
  disable: true,
62
62
  },
63
63
  },
64
- addonStart: {
64
+ iconStart: {
65
65
  table: {
66
66
  disable: true,
67
67
  },
68
68
  },
69
- addonEnd: {
69
+ iconEnd: {
70
+ table: {
71
+ disable: true,
72
+ },
73
+ },
74
+ avatars: {
70
75
  table: {
71
76
  disable: true,
72
77
  },