@kaizen/components 1.67.22 → 1.68.1

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 (54) hide show
  1. package/codemods/README.md +16 -1
  2. package/codemods/upgradeIconV1/getNewIconPropsFromOldIconName.ts +9 -9
  3. package/dist/cjs/__actions__/Button/v3/Button.cjs +43 -8
  4. package/dist/cjs/__actions__/Button/v3/Button.module.css.cjs +21 -0
  5. package/dist/cjs/__actions__/Button/v3/subcomponents/ButtonContent/ButtonContent.cjs +37 -0
  6. package/dist/cjs/__actions__/Button/v3/subcomponents/ButtonContent/ButtonContent.module.css.cjs +9 -0
  7. package/dist/cjs/__actions__/Button/v3/subcomponents/PendingContent/PendingContent.cjs +35 -0
  8. package/dist/cjs/__actions__/Button/v3/subcomponents/PendingContent/PendingContent.module.css.cjs +8 -0
  9. package/dist/cjs/__overlays__/Tooltip/v3/Tooltip.cjs +2 -2
  10. package/dist/esm/__actions__/Button/v3/Button.mjs +44 -9
  11. package/dist/esm/__actions__/Button/v3/Button.module.css.mjs +19 -0
  12. package/dist/esm/__actions__/Button/v3/subcomponents/ButtonContent/ButtonContent.mjs +28 -0
  13. package/dist/esm/__actions__/Button/v3/subcomponents/ButtonContent/ButtonContent.module.css.mjs +7 -0
  14. package/dist/esm/__actions__/Button/v3/subcomponents/PendingContent/PendingContent.mjs +26 -0
  15. package/dist/esm/__actions__/Button/v3/subcomponents/PendingContent/PendingContent.module.css.mjs +6 -0
  16. package/dist/esm/__overlays__/Tooltip/v3/Tooltip.mjs +1 -1
  17. package/dist/styles.css +276 -91
  18. package/dist/types/__actions__/Button/v3/Button.d.ts +17 -4
  19. package/dist/types/__actions__/Button/v3/index.d.ts +1 -0
  20. package/dist/types/__actions__/Button/v3/subcomponents/ButtonContent/ButtonContent.d.ts +11 -0
  21. package/dist/types/__actions__/Button/v3/subcomponents/ButtonContent/index.d.ts +1 -0
  22. package/dist/types/__actions__/Button/v3/subcomponents/PendingContent/PendingContent.d.ts +5 -0
  23. package/dist/types/__actions__/Button/v3/subcomponents/PendingContent/index.d.ts +1 -0
  24. package/dist/types/__actions__/Button/v3/subcomponents/index.d.ts +2 -0
  25. package/dist/types/__actions__/Button/v3/types.d.ts +21 -0
  26. package/package.json +1 -1
  27. package/src/__actions__/Button/v3/Button.module.css +235 -0
  28. package/src/__actions__/Button/v3/Button.tsx +92 -29
  29. package/src/__actions__/Button/v3/_docs/Button--api-specification.mdx +150 -0
  30. package/src/__actions__/Button/v3/_docs/Button--usage-guidelines.mdx +30 -0
  31. package/src/__actions__/Button/v3/_docs/Button.docs.stories.tsx +112 -50
  32. package/src/__actions__/Button/v3/_docs/Button.spec.stories.tsx +80 -120
  33. package/src/__actions__/Button/v3/_docs/Button.stickersheet.stories.tsx +183 -81
  34. package/src/__actions__/Button/v3/index.ts +1 -0
  35. package/src/__actions__/Button/v3/subcomponents/ButtonContent/ButtonContent.module.css +19 -0
  36. package/src/__actions__/Button/v3/subcomponents/ButtonContent/ButtonContent.tsx +40 -0
  37. package/src/__actions__/Button/v3/subcomponents/ButtonContent/index.ts +1 -0
  38. package/src/__actions__/Button/v3/subcomponents/PendingContent/PendingContent.module.css +16 -0
  39. package/src/__actions__/Button/v3/subcomponents/PendingContent/PendingContent.tsx +28 -0
  40. package/src/__actions__/Button/v3/subcomponents/PendingContent/index.ts +1 -0
  41. package/src/__actions__/Button/v3/subcomponents/index.ts +2 -0
  42. package/src/__actions__/Button/v3/types.ts +25 -0
  43. package/src/__actions__/Menu/v3/_docs/Menu.docs.stories.tsx +54 -18
  44. package/src/__actions__/Menu/v3/_docs/Menu.spec.stories.tsx +30 -10
  45. package/src/__actions__/Menu/v3/_docs/Menu.stories.tsx +12 -4
  46. package/src/__future__/Icon/_docs/Icon.docs.stories.tsx +7 -7
  47. package/src/__overlays__/Tooltip/v3/Tooltip.tsx +1 -1
  48. package/src/__overlays__/Tooltip/v3/_docs/Tooltip.spec.stories.tsx +2 -0
  49. package/dist/cjs/__actions__/Button/v3/Button.module.scss.cjs +0 -9
  50. package/dist/esm/__actions__/Button/v3/Button.module.scss.mjs +0 -7
  51. package/src/__actions__/Button/v3/Button.module.scss +0 -104
  52. package/src/__actions__/Button/v3/_docs/ApiSpecification.mdx +0 -173
  53. package/src/__actions__/Button/v3/_docs/Button.mdx +0 -41
  54. package/src/__actions__/Button/v3/_docs/Button.stories.tsx +0 -98
@@ -0,0 +1,235 @@
1
+ .button {
2
+ /* RESET */
3
+ appearance: none;
4
+ background: transparent;
5
+ font: inherit;
6
+ margin: 0;
7
+ outline: none;
8
+ -webkit-font-smoothing: antialiased;
9
+ -moz-osx-font-smoothing: grayscale;
10
+
11
+ --button-min-x-y: var(--spacing-40);
12
+ --button-border-width: var(--border-solid-border-width);
13
+ --button-padding-y: calc(var(--spacing-8) - var(--button-border-width));
14
+ --button-padding-x: calc(var(--spacing-16) - var(--button-border-width));
15
+
16
+ background-color: var(--button-bg-color, var(--color-blue-500));
17
+ border: var(--button-border-width) solid;
18
+ border-radius: var(--border-solid-border-radius);
19
+ border-color: var(--button-border-color, var(--color-blue-500));
20
+ box-sizing: border-box;
21
+ color: var(--button-text-color, var(--color-white));
22
+ display: inline-flex;
23
+ align-items: center;
24
+ justify-content: center;
25
+ text-align: start;
26
+ font-family: var(
27
+ --button-font-family,
28
+ var(--typography-paragraph-body-font-family)
29
+ );
30
+ font-weight: var(--button-font-weight, 500);
31
+ font-size: var(--button-font-size, 1rem);
32
+ line-height: var(--button-line-height, 1.5rem);
33
+ min-height: var(--button-min-x-y);
34
+ min-width: var(--button-min-x-y);
35
+ position: relative;
36
+ padding: var(--button-padding-y) var(--button-padding-x);
37
+
38
+ &[data-hovered] {
39
+ --button-bg-color: var(--color-blue-600);
40
+ --button-border-color: var(--color-blue-600);
41
+ }
42
+
43
+ &[data-pressed] {
44
+ --button-bg-color: var(--color-blue-700);
45
+ --button-border-color: var(--color-blue-700);
46
+ }
47
+
48
+ &[data-pending] {
49
+ --button-bg-color: var(--color-blue-700);
50
+ --button-border-color: var(--color-blue-700);
51
+ }
52
+
53
+ &[data-focus-visible]::after {
54
+ content: "";
55
+ position: absolute;
56
+ background: transparent;
57
+ border-color: var(--color-blue-500);
58
+ border-radius: var(--border-focus-ring-border-radius);
59
+ border-width: var(--border-focus-ring-border-width);
60
+ border-style: var(--border-focus-ring-border-style);
61
+ inset: calc(-1 * (var(--border-focus-ring-border-width) * 2) - 1px);
62
+ }
63
+ }
64
+
65
+ .fullWidth {
66
+ width: 100%;
67
+ }
68
+
69
+ .small {
70
+ --button-font-size: 0.75rem;
71
+ --button-line-height: 1rem;
72
+ --button-min-x-y: var(--spacing-32);
73
+ --icon-size: 16;
74
+ }
75
+
76
+ .medium {
77
+ --button-padding-x: calc(var(--spacing-20) - var(--button-border-width));
78
+ --button-padding-y: calc(var(--spacing-8) - var(--button-border-width));
79
+ --button-min-x-y: var(--spacing-40);
80
+ --icon-size: 24;
81
+ }
82
+
83
+ .large {
84
+ --button-padding-x: calc(var(--spacing-24) - var(--button-border-width));
85
+ --button-padding-y: calc(var(--spacing-12) - var(--button-border-width));
86
+ --button-min-x-y: var(--spacing-48);
87
+ --icon-size: 24;
88
+ }
89
+
90
+ .smallIconButton,
91
+ .mediumIconButton {
92
+ --button-padding-x: calc(var(--spacing-8) - var(--button-border-width));
93
+ --button-padding-y: calc(var(--spacing-8) - var(--button-border-width));
94
+ }
95
+
96
+ .largeIconButton {
97
+ --button-padding-x: calc(var(--spacing-12) - var(--button-border-width));
98
+ --button-padding-y: calc(var(--spacing-12) - var(--button-border-width));
99
+ }
100
+
101
+ .secondary {
102
+ --button-bg-color: var(--color-white);
103
+ --button-border-color: var(--color-gray-500);
104
+ --button-text-color: var(--color-purple-800);
105
+
106
+ &[data-hovered] {
107
+ --button-bg-color: var(--color-gray-200);
108
+ --button-border-color: var(--color-gray-600);
109
+ }
110
+
111
+ &[data-pressed] {
112
+ --button-bg-color: var(--color-gray-300);
113
+ --button-border-color: var(--color-black);
114
+ }
115
+
116
+ &[data-pending] {
117
+ --button-bg-color: var(--color-gray-300);
118
+ --button-border-color: var(--color-black);
119
+ }
120
+ }
121
+
122
+ .tertiary {
123
+ --button-bg-color: transparent;
124
+ --button-border-color: transparent;
125
+ --button-text-color: var(--color-purple-800);
126
+
127
+ &[data-hovered] {
128
+ --button-bg-color: var(--color-gray-200);
129
+ --button-border-color: var(--color-gray-200);
130
+ }
131
+
132
+ &[data-pressed] {
133
+ --button-bg-color: var(--color-gray-300);
134
+ --button-border-color: var(--color-gray-300);
135
+ }
136
+
137
+ &[data-pending] {
138
+ --button-bg-color: var(--color-gray-300);
139
+ --button-border-color: var(--color-gray-300);
140
+ }
141
+ }
142
+
143
+ .primaryReversed,
144
+ .secondaryReversed,
145
+ .tertiaryReversed {
146
+ &[data-focus-visible]::after {
147
+ border-color: var(--color-blue-300);
148
+ }
149
+ }
150
+
151
+ .primaryReversed {
152
+ --button-bg-color: var(--color-white);
153
+ --button-border-color: var(--color-white);
154
+ --button-text-color: var(--color-purple-800);
155
+
156
+ &[data-hovered] {
157
+ --button-bg-color: var(--color-white);
158
+ --button-border-color: var(--color-white);
159
+ }
160
+
161
+ &[data-pressed] {
162
+ --button-bg-color: var(--color-white);
163
+ --button-border-color: var(--color-white);
164
+ }
165
+
166
+ &[data-pending] {
167
+ --button-bg-color: var(--color-white);
168
+ --button-border-color: var(--color-white);
169
+ }
170
+ }
171
+
172
+ .secondaryReversed {
173
+ --button-bg-color: transparent;
174
+ --button-border-color: var(--color-white);
175
+ --button-text-color: var(--color-white);
176
+
177
+ &[data-hovered] {
178
+ --button-bg-color: rgba(var(--color-white-rgb), 0.2);
179
+ --button-border-color: var(--color-white);
180
+ }
181
+
182
+ &[data-pressed] {
183
+ --button-bg-color: rgba(var(--color-white-rgb), 0.1);
184
+ --button-border-color: var(--color-white);
185
+ }
186
+
187
+ &[data-pending] {
188
+ --button-bg-color: rgba(var(--color-white-rgb), 0.1);
189
+ --button-border-color: var(--color-white);
190
+ }
191
+ }
192
+
193
+ .tertiaryReversed {
194
+ --button-bg-color: transparent;
195
+ --button-border-color: transparent;
196
+ --button-text-color: var(--color-white);
197
+
198
+ &[data-hovered] {
199
+ --button-bg-color: rgba(var(--color-white-rgb), 0.2);
200
+ --button-border-color: transparent;
201
+ }
202
+
203
+ &[data-pressed] {
204
+ --button-bg-color: rgba(var(--color-white-rgb), 0.1);
205
+ --button-border-color: transparent;
206
+ }
207
+
208
+ &[data-pending] {
209
+ --button-bg-color: rgba(var(--color-white-rgb), 0.1);
210
+ --button-border-color: transparent;
211
+ }
212
+ }
213
+
214
+ .isDisabled {
215
+ --button-bg-color: var(--color-gray-400);
216
+ --button-border-color: var(--color-gray-400);
217
+ --button-text-color: var(--color-white);
218
+
219
+ &[data-hovered] {
220
+ --button-bg-color: var(--color-gray-400);
221
+ --button-border-color: var(--color-gray-400);
222
+ }
223
+ }
224
+
225
+ .hideContentWidth {
226
+ position: absolute;
227
+ left: 50%;
228
+ top: 50%;
229
+ transform: translate(-50%, -50%);
230
+ visibility: hidden;
231
+ }
232
+
233
+ .retainContentWidth {
234
+ visibility: hidden;
235
+ }
@@ -1,44 +1,107 @@
1
- import React from "react"
1
+ import React, { forwardRef } from "react"
2
2
  import {
3
3
  Button as RACButton,
4
4
  ButtonProps as RACButtonProps,
5
5
  } from "react-aria-components"
6
6
  import { useReversedColors } from "~components/__utilities__/v3"
7
7
  import { mergeClassNames } from "~components/utils/mergeClassNames"
8
- import styles from "./Button.module.scss"
8
+ import { ButtonContent, PendingContent } from "./subcomponents"
9
+ import { ButtonSizes, ButtonVariants, PendingButtonProps } from "./types"
10
+ import styles from "./Button.module.css"
9
11
 
10
- export type ButtonVariants = "default"
11
-
12
- export type ButtonProps = RACButtonProps & {
12
+ type ButtonBaseProps = Omit<RACButtonProps, "children"> & {
13
+ /** Used as the label for the button. */
14
+ children: RACButtonProps["children"]
15
+ /** Visually hides the Button's child content used as the label and the `pendingLabel`. Use for icon-only `Button`. @default "false" */
16
+ hasHiddenLabel?: boolean
13
17
  /** The visual style of the button.
14
18
  * @default "default" */
15
19
  variant?: ButtonVariants
16
20
  /** The visual size of the button. `medium` was formerly `regular`
17
21
  * @default "medium" */
18
- size?: "small" | "medium"
22
+ size?: ButtonSizes
23
+ /** Renders an icon at the `iconPosition` provided. To the size scales with the button, we recommend using the `Icon` component from `"@kaizen/components/future"` */
24
+ icon?: JSX.Element
25
+ /** Controls the position of the Icon passed in as props. @default "start" */
26
+ iconPosition?: "start" | "end"
27
+ /** Controls if the button inherits width from its parent. @default "false" */
28
+ isFullWidth?: boolean
19
29
  }
20
30
 
21
- export const Button = ({
22
- variant = "default",
23
- className,
24
- size = "medium",
25
- children,
26
- ...otherProps
27
- }: ButtonProps): JSX.Element => {
28
- const isReversed = useReversedColors()
31
+ export type ButtonProps = ButtonBaseProps & PendingButtonProps
29
32
 
30
- return (
31
- <RACButton
32
- className={mergeClassNames(
33
- styles.button,
34
- styles[variant],
35
- styles[size],
36
- isReversed && styles.reversed,
37
- className
38
- )}
39
- {...otherProps}
40
- >
41
- {children}
42
- </RACButton>
43
- )
44
- }
33
+ export const Button = forwardRef(
34
+ (
35
+ {
36
+ variant = "primary",
37
+ size = "medium",
38
+ className,
39
+ children,
40
+ isDisabled,
41
+ isFullWidth = false,
42
+ icon,
43
+ iconPosition,
44
+ hasHiddenLabel = false,
45
+ isPending,
46
+ hasHiddenPendingLabel: propsHasHiddenPendingLabel = false,
47
+ pendingLabel,
48
+ ...restProps
49
+ }: ButtonProps,
50
+ ref: React.ForwardedRef<HTMLButtonElement>
51
+ ) => {
52
+ const isReversed = useReversedColors()
53
+ const pendingProps: PendingButtonProps = isPending
54
+ ? {
55
+ isPending,
56
+ hasHiddenPendingLabel: hasHiddenLabel || propsHasHiddenPendingLabel,
57
+ pendingLabel,
58
+ }
59
+ : {}
60
+ const buttonContentClass = isPending
61
+ ? !hasHiddenLabel && propsHasHiddenPendingLabel
62
+ ? styles.retainContentWidth
63
+ : styles.hideContentWidth
64
+ : undefined
65
+
66
+ return (
67
+ <RACButton
68
+ ref={ref}
69
+ className={mergeClassNames(
70
+ styles.button,
71
+ styles[size],
72
+ hasHiddenLabel && styles[`${size}IconButton`],
73
+ isDisabled && styles.isDisabled,
74
+ isReversed ? styles[`${variant}Reversed`] : styles[variant],
75
+ isFullWidth && styles.fullWidth,
76
+ className
77
+ )}
78
+ isDisabled={isDisabled}
79
+ isPending={isPending}
80
+ {...restProps}
81
+ >
82
+ {racStateProps => {
83
+ const childIsFunction = typeof children === "function"
84
+
85
+ return (
86
+ <>
87
+ <ButtonContent
88
+ size={size}
89
+ icon={icon}
90
+ iconPosition={iconPosition}
91
+ hasHiddenLabel={hasHiddenLabel}
92
+ className={buttonContentClass}
93
+ >
94
+ {childIsFunction ? children(racStateProps) : children}
95
+ </ButtonContent>
96
+ <span aria-live="polite">
97
+ {pendingProps.isPending && (
98
+ <PendingContent {...pendingProps} size={size} />
99
+ )}
100
+ </span>
101
+ </>
102
+ )
103
+ }}
104
+ </RACButton>
105
+ )
106
+ }
107
+ )
@@ -0,0 +1,150 @@
1
+ import { Canvas, Meta, Controls, ArgTypes, DocsStory } from "@storybook/blocks"
2
+ import { ResourceLinks, KAIOInstallation } from "~storybook/components"
3
+ import * as exampleStories from "./Button.docs.stories"
4
+ import * as specStories from "./Button.spec.stories"
5
+
6
+ <Meta title="Actions/Button/Button (v3)/API Specification" />
7
+
8
+ # Button API Specification (v3)
9
+
10
+ Updated Nov 19, 2024
11
+
12
+ <ResourceLinks
13
+ sourceCode="https://github.com/cultureamp/kaizen-design-system/tree/main/packages/components/src/__actions__/Button/v3"
14
+ figma="https://www.figma.com/design/eZKEE5kXbEMY3lx84oz8iN/branch/sPhYSlgPScLOAOYfAbkaI5/%F0%9F%92%9C-Heart-UI-Kit?node-id=1929-17364&node-type=canvas&m=dev"
15
+ designGuidelines="/?path=/docs/actions-button-button-v3-usage-guidelines--docs"
16
+ />
17
+
18
+ <KAIOInstallation exportNames={["Button" ]} family="actions" version="3" />
19
+
20
+ ## Overview
21
+
22
+ `Button` allows users to perform an action. If the component needs to navigate somewhere and can be opened in a new tab, use a [link instead](#buttons-and-links).
23
+
24
+ The following example and table showcases the essential props that enable the core functionality of `Button`. For the remaining suite of API options refer to [this section](#additional-api-options).
25
+
26
+ <Canvas of={exampleStories.Playground} />
27
+
28
+ <Controls of={exampleStories.Playground} className="mb-64" include={["children", "hasHiddenLabel", "className", "size", "variant", "onPress", "icon", "iconPosition", "isFullWidth", "isDisabled", "isPending","pendingLabel", "hasHiddenPendingLabel" ]} />
29
+
30
+ ## Buttons and links
31
+
32
+ The `Button` component does not support the `href` property or have any inbuilt routing support. This component is intended as a semantic button and should only be used to perform actions on a page. We advise against passing in an `anchor` tag as a child of the `Button` as this can lead to accessibility issues.
33
+
34
+ A `LinkButton` component will be provided in the future to handle routing and navigation use cases. In the meantime, we recommend staying on [Button V1](/docs/actions-button-button-v1--docs) if an `href` is needed.
35
+
36
+ ## API
37
+
38
+ This is built on top of [React Aria's Button component](https://react-spectrum.adobe.com/react-aria/Button.html#props) and seeks to provide a flexible API with convenient abstractions that handles variants, sizes, pending states and icons.
39
+
40
+ ### Variants
41
+
42
+ `Button` supports the following variants: `primary`, `secondary` and `tertiary`. If the `variant` prop is not specified, the default will be `primary`.
43
+
44
+ <Canvas of={exampleStories.ButtonVariants} />
45
+
46
+ Reversed variants are handled via the `ReversedColors` Provider - read more on this in the [reversed colors section](#reversed-colors).
47
+
48
+ <DocsStory of={exampleStories.ButtonVariantsReversed} expanded={false} />
49
+
50
+ To enable the reversed theme, you will need to wrap the component or application in the `ReversedColors` provider, ie:
51
+
52
+ ```tsx
53
+ import { Button } from "@kaizen/components/v3/actions"
54
+ import { ReversedColors } from "@kaizen/components/v3/utilities"
55
+ // application code
56
+
57
+ return (
58
+ <ReversedColors isReversed={true}>
59
+ <Button {...buttonProps} />
60
+ </ReversedColors>
61
+ )
62
+ ```
63
+
64
+ ### Sizes
65
+
66
+ Button supports the following sizes: `small`, `medium` and `large`. If the `size` prop is not specified, the default will be `medium`.
67
+
68
+ <Canvas of={exampleStories.ButtonSizes} />
69
+
70
+ ### `onPress` vs `onClick`
71
+
72
+ One key change to the `Button`&apos;s API is the shift from `onClick` to React Aria's implementation of `onPress`. This approach has been adopted as it provides better support for consistent touch events across device types, such mobile, desktop and tablet. You can read more about the development and reason behind this pattern [here](https://react-spectrum.adobe.com/blog/building-a-button-part-1.html#touch-interactions).
73
+
74
+ Functionally this does not change the way we pass actions into `Button`. Consumers can safely replace `onClick` with `onPress` without any additional changes, ie:
75
+
76
+ ```tsx
77
+ <Button label="Submit" onClick={e => sumbit(e)}/>
78
+ ```
79
+
80
+ Can safely be replaced with the following:
81
+
82
+ ```tsx
83
+ <Button onPress={e => submit(e)}>
84
+ Submit
85
+ </Button>
86
+ ```
87
+
88
+ ### Button content and children
89
+
90
+ Labels and any button content can be passed into the `Button` as `children`. Content wrapped by the `Button` will be spaced evenly relative to the `size` prop.
91
+
92
+ ```tsx
93
+ <Button variant="secondary" onPress={e => submit(e)}>
94
+ Label
95
+ </Button>
96
+ ```
97
+
98
+ While in most cases, `children` will be a `ReactNode`, `Button` also accepts a render function with React Aria's `ButtonRenderProps`. This allows for more advanced styling and rendering options by hooking into React Aria's internal button state. You can read more about this [here](https://react-spectrum.adobe.com/react-aria/Button.html#styling).
99
+
100
+ ### Icons and positioning
101
+
102
+ The `icon` property abstracts the need to handle positioning and sizing logic for icons within the `Button`. When paired with the [Icon component](/docs/illustrations-icon-icon-future-api-specification--docs), this will scale the icon to the `Button`'s `size` prop.
103
+
104
+ <Canvas of={exampleStories.ButtonWithIconStart} />
105
+
106
+ Set the position of the icon using the `iconPosition` prop. This will ensure content is flipped in `RTL` layouts. Note that icons will need the [shouldMirrorInRTL](/docs/illustrations-icon-icon-future-api-specification--docs#mirror-in-rtl) prop set to `true` when mirroring is required.
107
+
108
+ <Canvas of={exampleStories.ButtonWithIconEnd} />
109
+
110
+
111
+ ### Icon-only `Button` and `hasHiddenLabel`
112
+
113
+ To achieve an icon-only `Button` (previously: `IconButton`) use the `icon` prop and set `hasHiddenLabel` to `true`. This will visually hide the button's `children` and `pendingLabel`, while still announcing the content to screen readers.
114
+
115
+ <Canvas of={exampleStories.IconButton} className="mb-32" />
116
+
117
+ This pattern ensures that the `Button`'s accessible name is determined by its children, which helps to announce relevant content to the screen readers, as with the [pending state](#pending-state). You can learn more about this [accessible pattern here](https://cultureamp.atlassian.net/wiki/spaces/PA/pages/3833331831/Accessible+button+and+link+labels).
118
+
119
+ ### Pending state
120
+
121
+ `isPending` and `pendingLabel` are used to indicate that an interaction is in progress. This will disable the `Button`'s press events while rendering a loading spinner and `pendingLabel`.
122
+
123
+ <Canvas of={specStories.PendingButton} />
124
+
125
+ This can be paired with the `hasHiddenPendingLabel` prop to visually hide the `pendingLabel` and maintain the content width. This is ideal for avoid layout shifts when space is a commodity.
126
+
127
+ The `pendingLabel` should be short and declarative as this will be announced to a screen reader regardless of its visibility.
128
+
129
+ <Canvas of={specStories.PendingButtonWithHiddenPendingLabel} />
130
+
131
+ As mentioned in the [previous section](#icon-only-button-and-hashiddenlabel), an icon-only `Button` uses `hasHiddenLabel` to visually hide both the `pendingLabel` and child content, so `hasHiddenPendingLabel` is not needed.
132
+
133
+ <Canvas of={specStories.PendingIconButton} />
134
+
135
+
136
+ ### Full width Buttons
137
+
138
+ If a button is statically the full width of a container you can use the `isFullWidth` property.
139
+
140
+ <Canvas of={exampleStories.ButtonFullWidth} />
141
+
142
+ For resizing on smaller screens, consider using the `className` prop to leverage CSS media or container queries, ie: `<Button className="w-full md:w-[initial]">Label</Button>`.
143
+
144
+ ## Additional API options
145
+
146
+ The following table is a collection of additional React Aria and native HTML props that are exposed from the React Aria API. These are not required for the implementation of `Button` but can be used to extend its functionality. Refer back to the [overview section](#overview) for the core props that enable most use cases.
147
+
148
+ You can learn more about React Aria's Button API and advance configuration options [here](https://react-spectrum.adobe.com/react-aria/Button.html#props).
149
+
150
+ <ArgTypes of={exampleStories.Playground} exclude={["children", "hasHiddenLabel", "className", "size", "variant", "onPress", "icon", "iconPosition", "isFullWidth", "isDisabled", "isPending", "pendingLabel", "hasHiddenPendingLabel" ]} />
@@ -0,0 +1,30 @@
1
+ import { Canvas, Meta, Controls } from "@storybook/blocks"
2
+ import { ResourceLinks, Installation } from "~storybook/components"
3
+ import * as Button from "./Button.docs.stories"
4
+
5
+ <Meta title="Actions/Button/Button (v3)/Usage Guidelines" />
6
+
7
+ # Button (v3)
8
+
9
+ Updated July 12, 2024
10
+
11
+ <ResourceLinks
12
+ sourceCode="https://github.com/cultureamp/kaizen-design-system/tree/main/packages/components/src/__actions__/Button/v3"
13
+ figma="https://www.figma.com/design/eZKEE5kXbEMY3lx84oz8iN/branch/sPhYSlgPScLOAOYfAbkaI5/%F0%9F%92%9C-Heart-UI-Kit?node-id=1929-17364&node-type=canvas&m=dev"
14
+ apiSpecification="/?path=/docs/actions-button-button-v3-api-specification--docs"
15
+ />
16
+
17
+ <Installation
18
+ installCommand="pnpm add @kaizen/components"
19
+ importStatement='import { Button } from "@kaizen/components/v3/actions"'
20
+ />
21
+
22
+ ## Overview
23
+
24
+ Buttons allow users to perform an action. They have multiple styles for various needs, and are ideal for calling attention to where a user needs to do something in order to move forward in a flow.
25
+
26
+ <Canvas of={Button.Playground} />
27
+
28
+ <Controls of={Button.Playground} include={["children", "variant", "size", "isDisabled", "icon", "iconPosition"]} className="mb-64" />
29
+
30
+