@utilitywarehouse/hearth-react 0.28.6 → 0.29.0

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 (104) hide show
  1. package/README.md +34 -20
  2. package/SKILL.md +355 -0
  3. package/dist/{chunk-O7RBVBMN.cjs → chunk-LWHIBSW2.cjs} +2 -2
  4. package/dist/{chunk-O7RBVBMN.cjs.map → chunk-LWHIBSW2.cjs.map} +1 -1
  5. package/dist/{chunk-JRVYOIXR.js → chunk-MIVYZGEV.js} +2 -2
  6. package/dist/components/CardAccordion/CardAccordion.context.d.ts.map +1 -1
  7. package/dist/components/Combobox/Combobox.cjs +1 -1
  8. package/dist/components/Combobox/Combobox.js +1 -1
  9. package/dist/components/ExpandableCard/ExpandableCard.cjs +1 -1
  10. package/dist/components/ExpandableCard/ExpandableCard.js +1 -1
  11. package/dist/helpers/get-classname-styles.d.ts.map +1 -1
  12. package/dist/helpers/logger.d.ts.map +1 -1
  13. package/dist/helpers/merge-ids.d.ts.map +1 -1
  14. package/dist/hooks/use-ids.d.ts.map +1 -1
  15. package/dist/index.cjs +1 -1
  16. package/dist/index.cjs.map +1 -1
  17. package/dist/index.js +1 -1
  18. package/package.json +18 -12
  19. package/public/llms/components/accordion.md +321 -0
  20. package/public/llms/components/alert.md +217 -0
  21. package/public/llms/components/avatar.md +112 -0
  22. package/public/llms/components/badge.md +158 -0
  23. package/public/llms/components/body-text.md +200 -0
  24. package/public/llms/components/box.md +148 -0
  25. package/public/llms/components/breadcrumbs.md +97 -0
  26. package/public/llms/components/button.md +595 -0
  27. package/public/llms/components/card-accordion.md +277 -0
  28. package/public/llms/components/card.md +985 -0
  29. package/public/llms/components/checkbox-group.md +193 -0
  30. package/public/llms/components/checkbox-tile.md +116 -0
  31. package/public/llms/components/checkbox.md +108 -0
  32. package/public/llms/components/combobox.md +360 -0
  33. package/public/llms/components/container.md +162 -0
  34. package/public/llms/components/currency-input.md +85 -0
  35. package/public/llms/components/date-input.md +90 -0
  36. package/public/llms/components/date-picker.md +159 -0
  37. package/public/llms/components/description-list.md +149 -0
  38. package/public/llms/components/detail-text.md +89 -0
  39. package/public/llms/components/divider.md +88 -0
  40. package/public/llms/components/em.md +43 -0
  41. package/public/llms/components/expandable-card.md +231 -0
  42. package/public/llms/components/flex.md +197 -0
  43. package/public/llms/components/grid.md +244 -0
  44. package/public/llms/components/heading.md +65 -0
  45. package/public/llms/components/helper-text.md +27 -0
  46. package/public/llms/components/highlight-banner.md +94 -0
  47. package/public/llms/components/icon-button.md +516 -0
  48. package/public/llms/components/icon-container.md +247 -0
  49. package/public/llms/components/inline-link.md +190 -0
  50. package/public/llms/components/label.md +28 -0
  51. package/public/llms/components/link.md +236 -0
  52. package/public/llms/components/list.md +715 -0
  53. package/public/llms/components/menu.md +270 -0
  54. package/public/llms/components/modal.md +328 -0
  55. package/public/llms/components/pagination.md +138 -0
  56. package/public/llms/components/password-input.md +93 -0
  57. package/public/llms/components/progress-bar.md +139 -0
  58. package/public/llms/components/progress-stepper.md +147 -0
  59. package/public/llms/components/radio-group.md +487 -0
  60. package/public/llms/components/search-input.md +132 -0
  61. package/public/llms/components/section-header.md +82 -0
  62. package/public/llms/components/select.md +148 -0
  63. package/public/llms/components/skeleton.md +282 -0
  64. package/public/llms/components/spinner.md +59 -0
  65. package/public/llms/components/strong.md +49 -0
  66. package/public/llms/components/switch.md +106 -0
  67. package/public/llms/components/table.md +230 -0
  68. package/public/llms/components/tabs.md +320 -0
  69. package/public/llms/components/text-area.md +141 -0
  70. package/public/llms/components/text-input.md +228 -0
  71. package/public/llms/components/toast.md +323 -0
  72. package/public/llms/components/toggle-button-card.md +513 -0
  73. package/public/llms/components/tooltip.md +188 -0
  74. package/public/llms/components/unstyled-icon-button.md +175 -0
  75. package/public/llms/components/validation-text.md +29 -0
  76. package/public/llms/components/verification-input.md +96 -0
  77. package/public/llms/docs/changelog.md +1430 -0
  78. package/public/llms/docs/common-props/align-self.md +90 -0
  79. package/public/llms/docs/common-props/border.md +308 -0
  80. package/public/llms/docs/common-props/colour.md +221 -0
  81. package/public/llms/docs/common-props/flex-items.md +91 -0
  82. package/public/llms/docs/common-props/gap.md +111 -0
  83. package/public/llms/docs/common-props/grid-items.md +96 -0
  84. package/public/llms/docs/common-props/margin.md +105 -0
  85. package/public/llms/docs/common-props/opacity.md +100 -0
  86. package/public/llms/docs/common-props/order.md +90 -0
  87. package/public/llms/docs/common-props/overflow.md +89 -0
  88. package/public/llms/docs/common-props/padding.md +102 -0
  89. package/public/llms/docs/common-props/position.md +92 -0
  90. package/public/llms/docs/common-props/size.md +93 -0
  91. package/public/llms/docs/common-props/spacing.md +97 -0
  92. package/public/llms/docs/common-props/text.md +35 -0
  93. package/public/llms/docs/common-props/z-index.md +88 -0
  94. package/public/llms/docs/design-tokens.md +72 -0
  95. package/public/llms/docs/getting-started.md +117 -0
  96. package/public/llms/docs/layout.md +135 -0
  97. package/public/llms/docs/migrating.md +302 -0
  98. package/public/llms/docs/responsive-design/breakpoints.md +119 -0
  99. package/public/llms/docs/responsive-design/media-queries.md +89 -0
  100. package/public/llms/docs/responsive-design/responsive-props.md +37 -0
  101. package/public/llms.txt +97 -0
  102. package/scripts/init-ai.js +142 -0
  103. package/styles.css +2 -2
  104. /package/dist/{chunk-JRVYOIXR.js.map → chunk-MIVYZGEV.js.map} +0 -0
@@ -0,0 +1,228 @@
1
+ # TextInput
2
+
3
+ `TextInput` is an interactive field that allows users to enter text and data.
4
+
5
+ ```tsx
6
+ <TextInput {...args} />
7
+ ```
8
+
9
+ - [Alternatives](#alternatives)
10
+ - [Label](#label)
11
+ - [Required](#required)
12
+ - [Disabled and Read-only](#disabled-and-read-only)
13
+ - [Validation](#validation)
14
+ - [Prefix and Suffix](#prefix-and-suffix)
15
+ - [Grouping inputs](#grouping-inputs)
16
+ - [API](#api)
17
+
18
+ ## Alternatives
19
+
20
+ - PasswordInput - For entering
21
+ passwords
22
+ - SearchInput - For search
23
+ - CurrencyInput - For money
24
+ - VerificationInput - For one-time
25
+ passwords
26
+ - DateInput - For entering dates
27
+
28
+ ## Label
29
+
30
+ A label is required, this should be clear and descriptive to guide the user.
31
+
32
+ The `hideLabel` prop will visually hide the label but keep it available for screen readers.
33
+
34
+ ## Required
35
+
36
+ In it's default state the `TextInput` is optional, and is indicated as such
37
+ with the `(optional)` text following the label.
38
+
39
+ When using online forms, most users assume all fields are required by default,
40
+ so the `TextInput` draws attention to when it is optional. Please make sure
41
+ that when the input field is required for successful completion of the form,
42
+ that you apply the `required` prop and appropriate validation is included.
43
+
44
+ You may also need to set the `novalidate` attribute to prevent the browser from
45
+ displaying its own validation errors.
46
+
47
+ ## Disabled and Read-only
48
+
49
+ Read-only inputs cannot be edited, but remain focusable, and should only be
50
+ used when presenting already submitted information. They differ from
51
+ disabled inputs, as there may be actions a user can take to activate a disabled
52
+ input, but read-only fields should stay undeditable in the same view.
53
+
54
+ ```tsx
55
+ <Flex direction="column" gap="400">
56
+ <TextInput {...args} label="Disabled" disabled helperText="Please do something before this" />
57
+ <TextInput
58
+ {...args}
59
+ label="Read only"
60
+ readOnly
61
+ value="Uneditable previously provided information"
62
+ />
63
+ </Flex>
64
+ ```
65
+
66
+ ## Validation
67
+
68
+ The input `validationStatus` can be set to either `"valid"` or `"invalid"` to
69
+ indicate the status. This status must be accompanied by the `validationText` to
70
+ explain the reason for the status.
71
+
72
+ ```tsx
73
+ <Flex direction="column" gap="400">
74
+ <TextInput
75
+ {...args}
76
+ label="Email"
77
+ type="email"
78
+ defaultValue="rphoenix@uw.co.uk"
79
+ validationStatus="valid"
80
+ validationText="Valid email address"
81
+ required
82
+ />
83
+ <TextInput
84
+ {...args}
85
+ label="Email"
86
+ type="email"
87
+ defaultValue="rphoenix@geemail."
88
+ validationStatus="invalid"
89
+ validationText="Please enter a valid email address"
90
+ required
91
+ />
92
+ </Flex>
93
+ ```
94
+
95
+ You can set the `validationText` according to what the `validationStatus` is:
96
+
97
+ ```tsx
98
+ const validationStatus = isValid ? "valid" : isInvalid ? "invalid" : undefined
99
+ const validationText = isValid ? "Your input is valid" : isInvalid ? "Your input is invalid" : undefined
100
+
101
+ [...]
102
+
103
+ <TextInput
104
+ label="Name"
105
+ required
106
+ validationStatus={validationStatus}
107
+ validationText={validationText}
108
+ />
109
+ ```
110
+
111
+ Be aware that you probably want to set `noValidate` on your form to prevent
112
+ the browser from displaying its own validation messages.
113
+
114
+ ```tsx
115
+ <form noValidate>
116
+ <TextInput
117
+ label="Name"
118
+ required
119
+ validationStatus="invalid"
120
+ validationText="Please enter your name"
121
+ />
122
+ </form>
123
+ ```
124
+
125
+ ## Prefix and Suffix
126
+
127
+ To include a prefix or suffix in the `TextInput` you need to wrap the content
128
+ in the `InputSlot` component. You can then set the `placement` prop on the
129
+ `InputSlot` component to display it as either a `prefix` or a `suffix`.
130
+
131
+ ```tsx
132
+ <Flex direction="column" gap="400">
133
+ <TextInput {...args}>
134
+ <InputSlot placement="prefix">
135
+ <BodyText size="md" weight="semibold">
136
+ £
137
+ </BodyText>
138
+ </InputSlot>
139
+ </TextInput>
140
+ <TextInput {...args}>
141
+ <InputSlot placement="suffix">
142
+ <BodyText size="md" weight="semibold">
143
+ kWh
144
+ </BodyText>
145
+ </InputSlot>
146
+ </TextInput>
147
+ </Flex>
148
+ ```
149
+
150
+ You can do the same with icons.
151
+
152
+ ```tsx
153
+ <TextInput {...args}>
154
+ <InputSlot placement="prefix">
155
+ <EmailMediumIcon />
156
+ </InputSlot>
157
+ </TextInput>
158
+ ```
159
+
160
+ ## Grouping inputs
161
+
162
+ When grouping inputs you should
163
+ [use the `fieldset` and `legend` elements](https://accessibility.blog.gov.uk/2016/07/22/using-the-fieldset-and-legend-elements/).
164
+ This will ensure the group title is properly associated with child input
165
+ elements. Make sure you place the `legend` element as the first child of the
166
+ `fieldset` otherwise the relationship is broken. If this is not possible, you
167
+ can use `aria-label` or `aria-labelledby` to create the relationship.
168
+
169
+ If you are also including supporting text, then this should be associated with
170
+ each individual input, rather than with the grouping fieldset.
171
+
172
+ Please take the time to test what you build with a screen reader.
173
+
174
+ ```tsx
175
+ <Flex asChild direction="column">
176
+ <fieldset>
177
+ <legend>
178
+ <Heading as="h3" size="lg" marginBottom="200">
179
+ Grouping Inputs
180
+ </Heading>
181
+ </legend>
182
+ <BodyText size="md" marginBottom="250" id="supporting-info">
183
+ Supporting information
184
+ </BodyText>
185
+ <Card variant="subtle" direction="column" gap="250">
186
+ <TextInput label="First name" required aria-describedby="supporting-info" />
187
+ <TextInput label="Last name" required aria-describedby="supporting-info" />
188
+ <TextInput
189
+ label="Email"
190
+ helperText="this is the helper text"
191
+ aria-describedby="supporting-info"
192
+ >
193
+ <InputSlot placement="prefix">
194
+ <EmailMediumIcon />
195
+ </InputSlot>
196
+ </TextInput>
197
+ </Card>
198
+ </fieldset>
199
+ </Flex>
200
+ ```
201
+
202
+ ## API
203
+
204
+ This component is based on the `input` element and supports the following common props:
205
+
206
+ - Margin
207
+
208
+ | Prop | Type | Default | Description |
209
+ | ------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------- | --------------------------------------------------------------------------- |
210
+ | `label` | `string` | — | The label for the form field, describing its purpose. |
211
+ | `defaultValue` | `string \| number` | — | The initial value of the input when rendered. |
212
+ | `type` | `"number" \| "search" \| "text" \| "email" \| "password" \| "tel" \| "url"` | — | |
213
+ | `value` | `string \| number` | — | The controlled value of the input. Must be used with an `onChange` handler. |
214
+ | `labelId` | `string` | — | |
215
+ | `helperTextId` | `string` | — | |
216
+ | `validationTextId` | `string` | — | |
217
+ | `hideLabel` | `boolean` | — | Visually hide the label. |
218
+ | `labelVariant` | `"body" \| "heading"` | — | Change the label variant |
219
+ | `helperText` | `string` | — | Optional helper text to provide additional context or instructions. |
220
+ | `validationText` | `string` | — | Text to display when the `validationStatus` is set. |
221
+ | `validationStatus` | `"valid" \| "invalid"` | — | Indicates the validation status. |
222
+ | `margin` | `Responsive<"auto" \| "0" \| "25" \| "50" \| "75" \| "100" \| "150" \| "175" \| "200" \| "250" \| "300" \| "350" \| "400" \| "500" \| "600" \| "700" \| "800" \| "900" \| "1000" \| `var(--h-${string})`>` | — | |
223
+ | `marginTop` | `Responsive<"auto" \| "0" \| "25" \| "50" \| "75" \| "100" \| "150" \| "175" \| "200" \| "250" \| "300" \| "350" \| "400" \| "500" \| "600" \| "700" \| "800" \| "900" \| "1000" \| `var(--h-${string})`>` | — | |
224
+ | `marginRight` | `Responsive<"auto" \| "0" \| "25" \| "50" \| "75" \| "100" \| "150" \| "175" \| "200" \| "250" \| "300" \| "350" \| "400" \| "500" \| "600" \| "700" \| "800" \| "900" \| "1000" \| `var(--h-${string})`>` | — | |
225
+ | `marginBottom` | `Responsive<"auto" \| "0" \| "25" \| "50" \| "75" \| "100" \| "150" \| "175" \| "200" \| "250" \| "300" \| "350" \| "400" \| "500" \| "600" \| "700" \| "800" \| "900" \| "1000" \| `var(--h-${string})`>` | — | |
226
+ | `marginLeft` | `Responsive<"auto" \| "0" \| "25" \| "50" \| "75" \| "100" \| "150" \| "175" \| "200" \| "250" \| "300" \| "350" \| "400" \| "500" \| "600" \| "700" \| "800" \| "900" \| "1000" \| `var(--h-${string})`>` | — | |
227
+ | `marginX` | `Responsive<"auto" \| "0" \| "25" \| "50" \| "75" \| "100" \| "150" \| "175" \| "200" \| "250" \| "300" \| "350" \| "400" \| "500" \| "600" \| "700" \| "800" \| "900" \| "1000" \| `var(--h-${string})`>` | — | |
228
+ | `marginY` | `Responsive<"auto" \| "0" \| "25" \| "50" \| "75" \| "100" \| "150" \| "175" \| "200" \| "250" \| "300" \| "350" \| "400" \| "500" \| "600" \| "700" \| "800" \| "900" \| "1000" \| `var(--h-${string})`>` | — | |
@@ -0,0 +1,323 @@
1
+ # Toast
2
+
3
+ A `Toast` is a brief, non-intrusive message that appears temporarily to provide feedback on an action or notify users of important information. Toasts automatically dismiss after a set duration or can be dismissed manually.
4
+
5
+ - [Usage](#usage)
6
+ - [Icon](#icon)
7
+ - [Dismiss toast](#dismiss-toast)
8
+ - [Actions](#actions)
9
+ - [Custom duration](#custom-duration)
10
+ - [Accessibility](#accessibility)
11
+ - [Sensitivity](#sensitivity)
12
+ - [Keyboard interactions](#keyboard-interactions)
13
+ - [Duplicate toasts](#duplicate-toasts)
14
+ - [API](#api)
15
+
16
+ ```tsx
17
+ <div>
18
+ <Button
19
+ onClick={() => {
20
+ setOpen(false);
21
+ window.clearTimeout(timerRef.current);
22
+ timerRef.current = window.setTimeout(() => {
23
+ setOpen(true);
24
+ }, 100);
25
+ }}
26
+ >
27
+ Show Toast
28
+ </Button>
29
+ <Toast open={open} onOpenChange={setOpen} icon={<TickCircleMediumIcon />} {...args}>
30
+ <ToastActionLink href="#" altText="Visit #">
31
+ Link
32
+ </ToastActionLink>
33
+ </Toast>
34
+ </div>
35
+ ```
36
+
37
+ ## Usage
38
+
39
+ When using toasts you must first wrap your usage in a provider. It usually
40
+ makes sense to do this at the root of the application.
41
+
42
+ ```tsx
43
+ import { ToastProvider } from '@utilitywarehouse/hearth-react';
44
+
45
+ [...]
46
+
47
+ <ToastProvider>
48
+ {children}
49
+ </ToastProvider>
50
+ ```
51
+
52
+ You can then render your toast:
53
+
54
+ ```tsx
55
+ <Toast description="Toast description" />
56
+ ```
57
+
58
+ ## Icon
59
+
60
+ Include an icon using the `icon` prop:
61
+
62
+ ```tsx
63
+ import { Toast } from '@utilitywarehouse/hearth-react';
64
+ import { TickCircleMediumIcon } from '@utilitywarehouse/hearth-react-icons';
65
+
66
+ [...]
67
+
68
+ <Toast
69
+ description='With icon'
70
+ icon={<TickCircleMediumIcon />}
71
+ />
72
+ ```
73
+
74
+ ## Dismiss toast
75
+
76
+ A dismiss button can be included.
77
+
78
+ ```tsx
79
+ <Toast description="Show dismiss button" showDismissButton />
80
+ ```
81
+
82
+ Users can also swipe down on any toast to dismiss it immediately.
83
+
84
+ ## Actions
85
+
86
+ You can include an `action` using the `ToastActionLink` or `ToastActionButton`
87
+ components as children. Only use one per toast.
88
+
89
+ The action should be safe to ignore so that users are not expected to complete
90
+ tasks with unexpected side effects as a result of a time limit. You can direct
91
+ the user to a permanent place in your application where they can action it. Use
92
+ foreground type to announce immediately and increase the duration to give the
93
+ user ample time.
94
+
95
+ When obtaining a user response is necessary, consider using an `Alert` instead.
96
+
97
+ ```tsx
98
+ <Toast
99
+ type="foreground"
100
+ duration={10000}
101
+ description="You can change your details anytime"
102
+ >
103
+ <ToastActionLink
104
+ href="/account-settings"
105
+ altText="Visit account settings to change your details"
106
+ >
107
+ Account settings
108
+ </ToastActionLink>
109
+ </Toast>
110
+
111
+ [...]
112
+
113
+ <Toast
114
+ type="foreground"
115
+ duration={10000}
116
+ description="Settings updated"
117
+ >
118
+ <ToastActionButton altText="Go to settings to undo">Undo</ToastActionButton>
119
+ </Toast>
120
+ ```
121
+
122
+ ```tsx
123
+ <div>
124
+ <Flex gap="400">
125
+ <Button
126
+ onClick={() => {
127
+ setOpenLinkActionToast(false);
128
+ window.clearTimeout(linkActionTimerRef.current);
129
+ linkActionTimerRef.current = window.setTimeout(() => {
130
+ setOpenLinkActionToast(true);
131
+ }, 100);
132
+ }}
133
+ >
134
+ Show Link Action Toast
135
+ </Button>
136
+ <Button
137
+ onClick={() => {
138
+ setOpenButtonActionToast(false);
139
+ window.clearTimeout(buttonActionTimerRef.current);
140
+ buttonActionTimerRef.current = window.setTimeout(() => {
141
+ setOpenButtonActionToast(true);
142
+ }, 100);
143
+ }}
144
+ >
145
+ Show Button Action Toast
146
+ </Button>
147
+ </Flex>
148
+ <Toast
149
+ type="foreground"
150
+ duration={10000}
151
+ description="You can change your details anytime"
152
+ open={openLinkActionToast}
153
+ onOpenChange={setOpenLinkActionToast}
154
+ >
155
+ <ToastActionLink
156
+ href="/account-settings"
157
+ altText="Visit account settings to change your details"
158
+ >
159
+ Account settings
160
+ </ToastActionLink>
161
+ </Toast>
162
+ <Toast
163
+ type="foreground"
164
+ duration={10000}
165
+ description="Settings updated"
166
+ open={openButtonActionToast}
167
+ onOpenChange={setOpenButtonActionToast}
168
+ >
169
+ <ToastActionButton altText="Go to settings to undo">Undo</ToastActionButton>
170
+ </Toast>
171
+ </div>
172
+ ```
173
+
174
+ ## Custom duration
175
+
176
+ The default duration of 5 seconds is set on the `ToastProvider`, you
177
+ can override this on the provider, or setting this on the individual toast will
178
+ override the global default.
179
+
180
+ ```tsx
181
+ <Toast duration={10000} description="Custom toast duration of 10 seconds" />
182
+ ```
183
+
184
+ ## Accessibility
185
+
186
+ Adheres to the [aria-live requirements](https://www.w3.org/TR/wai-aria/#aria-live)
187
+
188
+ ### Sensitivity
189
+
190
+ You can control the sensitivity of the toast for screen readers, using the `type` prop.
191
+
192
+ For toasts that are the result of a user action, choose `foreground`. Toasts
193
+ generated from background tasks should use `background`. The default type is
194
+ `foreground`.
195
+
196
+ Foreground toasts are announced immediately. Assistive technologies may choose
197
+ to clear previously queued messages when a foreground toast appears. Try to
198
+ avoid stacking distinct foreground toasts at the same time.
199
+
200
+ Background toasts are announced at the next graceful opportunity, for example,
201
+ when the screen reader has finished reading its current sentence. They do not
202
+ clear queued messages so overusing them can be perceived as a laggy user
203
+ experience for screen reader users when used in response to a user interaction.
204
+
205
+ ### Keyboard interactions
206
+
207
+ <Flex direction="column" gap="200" className="sb-unstyled">
208
+ <Flex>
209
+ <Box width="300px">
210
+ <BodyText as="span" weight="bold">
211
+ Key
212
+ </BodyText>
213
+ </Box>
214
+ <BodyText as="span" weight="bold">
215
+ Description
216
+ </BodyText>
217
+ </Flex>
218
+ <Divider />
219
+ {[
220
+ {
221
+ key: 'F8',
222
+ description: 'Focuses toasts viewport.',
223
+ },
224
+ {
225
+ key: 'Tab',
226
+ description: 'Moves focus to the next focusable element.',
227
+ },
228
+ {
229
+ key: 'Shift+Tab',
230
+ description: 'Moves focus to the previous focusable element.',
231
+ },
232
+ {
233
+ key: 'Space',
234
+ description:
235
+ 'When focus is on a Toast action component or the Toast dismiss button, closes the toast.',
236
+ },
237
+ {
238
+ key: 'Enter',
239
+ description:
240
+ 'When focus is on a Toast action component or the Toast dismiss button, closes the toast.',
241
+ },
242
+ {
243
+ key: 'Esc',
244
+ description: 'When focus is on a Toast, closes the toast.',
245
+ },
246
+ ].map((kbi, i) => (
247
+ <>
248
+ <Flex>
249
+ <Box width="300px">
250
+ <kbd>{kbi.key}</kbd>
251
+ </Box>
252
+ <BodyText as="span">{kbi.description}</BodyText>
253
+ </Flex>
254
+ {i < 5 ? <Divider /> : null}
255
+ </>
256
+ ))}
257
+ </Flex>
258
+
259
+ ## Duplicate toasts
260
+
261
+ When a toast must appear every time a user clicks a button, use state to render
262
+ multiple instances of the same toast. Toasts will stack vertically with the
263
+ newest appearing at the bottom.
264
+
265
+ ```tsx
266
+ const [savedCount, setSavedCount] = React.useState(0);
267
+
268
+ return (
269
+ <div>
270
+ <Button onClick={() => setSavedCount(count => count + 1)}>Save</Button>
271
+
272
+ {Array.from({ length: savedCount }).map((_, index) => (
273
+ <Toast key={index} description={`Saved! (${index})`} showDismissButton />
274
+ ))}
275
+ </div>
276
+ );
277
+ ```
278
+
279
+ ### ToastProvider
280
+
281
+ This component is based on [Radix UI's Toast primitive](https://www.radix-ui.com/primitives/docs/components/toast).
282
+
283
+ | Prop | Type | Default | Description |
284
+ | ---------------- | ---------- | ------- | ------------------------------------------------------------------------------------------------------------------------------------------------ |
285
+ | `viewportLabel` | `string` | — | |
286
+ | `viewportHotkey` | `string[]` | — | |
287
+ | `label` | `string` | — | An author-localized label for each toast. Used to help screen reader users associate the interruption with a toast. @defaultValue 'Notification' |
288
+ | `duration` | `number` | `5000` | Time in milliseconds that each toast should remain visible for. @defaultValue 5000 |
289
+
290
+ ### Toast
291
+
292
+ This component is based on [Radix UI's Toast primitive](https://www.radix-ui.com/primitives/docs/components/toast).
293
+
294
+ | Prop | Type | Default | Description |
295
+ | ------------------- | ---------------------------------- | ------- | ---------------------------------------------------------------------------------------------------- |
296
+ | `open` | `boolean` | — | |
297
+ | `onPause` | `(() => void)` | — | |
298
+ | `type` | `"foreground" \| "background"` | — | |
299
+ | `duration` | `number` | — | Time in milliseconds that toast should remain visible for. Overrides value given to `ToastProvider`. |
300
+ | `onEscapeKeyDown` | `((event: KeyboardEvent) => void)` | — | |
301
+ | `onResume` | `(() => void)` | — | |
302
+ | `onSwipeStart` | `((event: SwipeEvent) => void)` | — | |
303
+ | `onSwipeMove` | `((event: SwipeEvent) => void)` | — | |
304
+ | `onSwipeCancel` | `((event: SwipeEvent) => void)` | — | |
305
+ | `onSwipeEnd` | `((event: SwipeEvent) => void)` | — | |
306
+ | `defaultOpen` | `boolean` | — | |
307
+ | `onOpenChange` | `((open: boolean) => void)` | — | |
308
+ | `description` | `ReactNode` | — | |
309
+ | `icon` | `ReactNode` | — | |
310
+ | `showDismissButton` | `boolean` | — | |
311
+
312
+ ### ToastActionLink
313
+
314
+ This component is based on the `a` element and [Radix UI's Toast primitive](https://www.radix-ui.com/primitives/docs/components/toast).
315
+
316
+ | Prop | Type | Default | Description |
317
+ | --------- | --------- | ------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
318
+ | `asChild` | `boolean` | — | |
319
+ | `altText` | `string` | — | A short description for an alternate way to carry out the action. For screen reader users who will not be able to navigate to the button easily/quickly. @example <ToastAction altText="Goto account settings to upgrade">Upgrade</ToastAction> @example <ToastAction altText="Undo (Alt+U)">Undo</ToastAction> |
320
+
321
+ ### ToastActionButton
322
+
323
+ This component is based on the `button` element and [Radix UI's Toast primitive](https://www.radix-ui.com/primitives/docs/components/toast).