@utilitywarehouse/hearth-react 0.28.7 → 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.
- package/README.md +34 -20
- package/SKILL.md +355 -0
- package/dist/{chunk-TLCA3FQZ.js → chunk-ABES5BZY.js} +2 -2
- package/dist/{chunk-OHPQ5IRM.cjs → chunk-Y2CHQFKQ.cjs} +2 -2
- package/dist/{chunk-OHPQ5IRM.cjs.map → chunk-Y2CHQFKQ.cjs.map} +1 -1
- package/dist/components/CardAccordion/CardAccordion.context.d.ts.map +1 -1
- package/dist/components/ExpandableCard/ExpandableCard.cjs +1 -1
- package/dist/components/ExpandableCard/ExpandableCard.js +1 -1
- package/dist/components/ProgressBar/ProgressBar.cjs +1 -1
- package/dist/components/ProgressBar/ProgressBar.js +1 -1
- package/dist/helpers/get-classname-styles.d.ts.map +1 -1
- package/dist/helpers/logger.d.ts.map +1 -1
- package/dist/helpers/merge-ids.d.ts.map +1 -1
- package/dist/hooks/use-ids.d.ts.map +1 -1
- package/dist/index.cjs +1 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +1 -1
- package/package.json +14 -10
- package/public/llms/components/accordion.md +321 -0
- package/public/llms/components/alert.md +217 -0
- package/public/llms/components/avatar.md +112 -0
- package/public/llms/components/badge.md +158 -0
- package/public/llms/components/body-text.md +200 -0
- package/public/llms/components/box.md +148 -0
- package/public/llms/components/breadcrumbs.md +97 -0
- package/public/llms/components/button.md +595 -0
- package/public/llms/components/card-accordion.md +277 -0
- package/public/llms/components/card.md +985 -0
- package/public/llms/components/checkbox-group.md +193 -0
- package/public/llms/components/checkbox-tile.md +116 -0
- package/public/llms/components/checkbox.md +108 -0
- package/public/llms/components/combobox.md +360 -0
- package/public/llms/components/container.md +162 -0
- package/public/llms/components/currency-input.md +85 -0
- package/public/llms/components/date-input.md +90 -0
- package/public/llms/components/date-picker.md +159 -0
- package/public/llms/components/description-list.md +149 -0
- package/public/llms/components/detail-text.md +89 -0
- package/public/llms/components/divider.md +88 -0
- package/public/llms/components/em.md +43 -0
- package/public/llms/components/expandable-card.md +231 -0
- package/public/llms/components/flex.md +197 -0
- package/public/llms/components/grid.md +244 -0
- package/public/llms/components/heading.md +65 -0
- package/public/llms/components/helper-text.md +27 -0
- package/public/llms/components/highlight-banner.md +94 -0
- package/public/llms/components/icon-button.md +516 -0
- package/public/llms/components/icon-container.md +247 -0
- package/public/llms/components/inline-link.md +190 -0
- package/public/llms/components/label.md +28 -0
- package/public/llms/components/link.md +236 -0
- package/public/llms/components/list.md +715 -0
- package/public/llms/components/menu.md +270 -0
- package/public/llms/components/modal.md +328 -0
- package/public/llms/components/pagination.md +138 -0
- package/public/llms/components/password-input.md +93 -0
- package/public/llms/components/progress-bar.md +139 -0
- package/public/llms/components/progress-stepper.md +147 -0
- package/public/llms/components/radio-group.md +487 -0
- package/public/llms/components/search-input.md +132 -0
- package/public/llms/components/section-header.md +82 -0
- package/public/llms/components/select.md +148 -0
- package/public/llms/components/skeleton.md +282 -0
- package/public/llms/components/spinner.md +59 -0
- package/public/llms/components/strong.md +49 -0
- package/public/llms/components/switch.md +106 -0
- package/public/llms/components/table.md +230 -0
- package/public/llms/components/tabs.md +320 -0
- package/public/llms/components/text-area.md +141 -0
- package/public/llms/components/text-input.md +228 -0
- package/public/llms/components/toast.md +323 -0
- package/public/llms/components/toggle-button-card.md +513 -0
- package/public/llms/components/tooltip.md +188 -0
- package/public/llms/components/unstyled-icon-button.md +175 -0
- package/public/llms/components/validation-text.md +29 -0
- package/public/llms/components/verification-input.md +96 -0
- package/public/llms/docs/changelog.md +1430 -0
- package/public/llms/docs/common-props/align-self.md +90 -0
- package/public/llms/docs/common-props/border.md +308 -0
- package/public/llms/docs/common-props/colour.md +221 -0
- package/public/llms/docs/common-props/flex-items.md +91 -0
- package/public/llms/docs/common-props/gap.md +111 -0
- package/public/llms/docs/common-props/grid-items.md +96 -0
- package/public/llms/docs/common-props/margin.md +105 -0
- package/public/llms/docs/common-props/opacity.md +100 -0
- package/public/llms/docs/common-props/order.md +90 -0
- package/public/llms/docs/common-props/overflow.md +89 -0
- package/public/llms/docs/common-props/padding.md +102 -0
- package/public/llms/docs/common-props/position.md +92 -0
- package/public/llms/docs/common-props/size.md +93 -0
- package/public/llms/docs/common-props/spacing.md +97 -0
- package/public/llms/docs/common-props/text.md +35 -0
- package/public/llms/docs/common-props/z-index.md +88 -0
- package/public/llms/docs/design-tokens.md +72 -0
- package/public/llms/docs/getting-started.md +117 -0
- package/public/llms/docs/layout.md +135 -0
- package/public/llms/docs/migrating.md +302 -0
- package/public/llms/docs/responsive-design/breakpoints.md +119 -0
- package/public/llms/docs/responsive-design/media-queries.md +89 -0
- package/public/llms/docs/responsive-design/responsive-props.md +37 -0
- package/public/llms.txt +97 -0
- package/scripts/init-ai.js +142 -0
- package/styles.css +1 -1
- /package/dist/{chunk-TLCA3FQZ.js.map → chunk-ABES5BZY.js.map} +0 -0
|
@@ -0,0 +1,487 @@
|
|
|
1
|
+
# RadioGroup
|
|
2
|
+
|
|
3
|
+
`RadioGroup` provides an accessible way to group and control a set of `Radio`, `RadioTile` or `RadioCard` components, allowing the user to select one option from a set. The `RadioGroup` is responsible for handling the value, helper text, validation status and text, as well as determining the presentation and selection of the items in the list. Follows the [WAI-ARIA Radio Group Pattern](https://www.w3.org/WAI/ARIA/apg/patterns/radio/) for radio groups not contained in a toolbar.
|
|
4
|
+
|
|
5
|
+
```tsx
|
|
6
|
+
<Flex direction="column" gap="400">
|
|
7
|
+
<Flex direction="row" gap="200">
|
|
8
|
+
<RadioGroup {...args}>
|
|
9
|
+
<RadioTile value="england" label="England" />
|
|
10
|
+
<RadioTile value="wales" label="Wales" />
|
|
11
|
+
<RadioTile value="scotland" label="Scotland" />
|
|
12
|
+
<RadioTile value="northern-ireland" label="Northern Ireland" />
|
|
13
|
+
</RadioGroup>
|
|
14
|
+
<RadioGroup {...args}>
|
|
15
|
+
<Radio value="england" label="England" />
|
|
16
|
+
<Radio value="wales" label="Wales" />
|
|
17
|
+
<Radio value="scotland" label="Scotland" />
|
|
18
|
+
<Radio value="northern-ireland" label="Northern Ireland" />
|
|
19
|
+
</RadioGroup>
|
|
20
|
+
</Flex>
|
|
21
|
+
<RadioGroup
|
|
22
|
+
{...args}
|
|
23
|
+
label="Do you like living here?"
|
|
24
|
+
name="do-you-like-living-here"
|
|
25
|
+
direction="row"
|
|
26
|
+
>
|
|
27
|
+
<RadioTile value="y" label="Yes" image={<ThumbsUpSmallIcon />} />
|
|
28
|
+
<RadioTile value="n" label="No" image={<ThumbsDownSmallIcon />} />
|
|
29
|
+
</RadioGroup>
|
|
30
|
+
</Flex>
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
- [Alternatives](#alternatives)
|
|
34
|
+
- [Usage](#usage)
|
|
35
|
+
- [Accessibility](#accessibility)
|
|
36
|
+
- [Keyboard interactions](#keyboard-interactions)
|
|
37
|
+
- [Custom label](#custom-label)
|
|
38
|
+
- [Helper text](#helper-text)
|
|
39
|
+
- [Validation](#validation)
|
|
40
|
+
- [Content width](#content-width)
|
|
41
|
+
- [Grid layout](#grid-layout)
|
|
42
|
+
- [RadioTile layout](#radiotile-layout)
|
|
43
|
+
- [Controlled](#controlled)
|
|
44
|
+
- [Radio & RadioTile Image](#radio--radiotile-image)
|
|
45
|
+
- [RadioCard](#radiocard)
|
|
46
|
+
- [API](#api)
|
|
47
|
+
|
|
48
|
+
## Alternatives
|
|
49
|
+
|
|
50
|
+
- `CheckboxGroup`: For multi-select.
|
|
51
|
+
|
|
52
|
+
## Usage
|
|
53
|
+
|
|
54
|
+
`RadioGroup` is intended for use with the `RadioTile`, `RadioCard` and `Radio` components.
|
|
55
|
+
|
|
56
|
+
- `RadioTile` is the most common radio button used within the `RadioGroup`, and offers a simple way to present grouped options.
|
|
57
|
+
- `RadioCard` is for instances when you have options that are either the main focus of your UI or would benefit from additional explanation.
|
|
58
|
+
- `Radio` will not often be used, as `RadioTile` is preferred.
|
|
59
|
+
|
|
60
|
+
## Accessibility
|
|
61
|
+
|
|
62
|
+
The necessary aria props, such as `aria-labelledby`, `aria-describedby` and
|
|
63
|
+
`aria-errormessage` are handled internally, however when it is necessary for
|
|
64
|
+
the `RadioGroup` to be labelled by another element or even not to have a visual
|
|
65
|
+
label, either `aria-label` or `aria-labelledby` can be provided.
|
|
66
|
+
|
|
67
|
+
The `Radio` and `RadioTile` are, by default, appropriately labelled when using
|
|
68
|
+
the `label` props, if you do not provide a label, you must specify an
|
|
69
|
+
`aria-label` or `aria-labelledby` for accessibility.
|
|
70
|
+
|
|
71
|
+
## Keyboard interactions
|
|
72
|
+
|
|
73
|
+
<Flex direction="column" gap="200" className="sb-unstyled">
|
|
74
|
+
<Flex>
|
|
75
|
+
<Box width="300px">
|
|
76
|
+
<BodyText as="span" weight="bold">
|
|
77
|
+
Key
|
|
78
|
+
</BodyText>
|
|
79
|
+
</Box>
|
|
80
|
+
<BodyText as="span" weight="bold">
|
|
81
|
+
Description
|
|
82
|
+
</BodyText>
|
|
83
|
+
</Flex>
|
|
84
|
+
<Divider />
|
|
85
|
+
{[
|
|
86
|
+
{
|
|
87
|
+
key: 'Tab',
|
|
88
|
+
description:
|
|
89
|
+
'Moves focus to either the checked radio item or the first radio item in the group.',
|
|
90
|
+
},
|
|
91
|
+
{
|
|
92
|
+
key: 'Shift+Tab',
|
|
93
|
+
description:
|
|
94
|
+
'Moves focus to either the checked radio item or the last radio item in the group.',
|
|
95
|
+
},
|
|
96
|
+
{
|
|
97
|
+
key: 'Space',
|
|
98
|
+
description: 'When focus is on an unchecked radio item, checks it.',
|
|
99
|
+
},
|
|
100
|
+
{
|
|
101
|
+
key: 'Arrow Down / Arrow Right',
|
|
102
|
+
description: 'Moves focus and checks the next radio item in the group.',
|
|
103
|
+
},
|
|
104
|
+
{
|
|
105
|
+
key: 'Arrow Up / Arrow Left',
|
|
106
|
+
description: 'Moves focus and checks the previous radio item in the group.',
|
|
107
|
+
},
|
|
108
|
+
].map((kbi, i) => (
|
|
109
|
+
<>
|
|
110
|
+
<Flex>
|
|
111
|
+
<Box width="300px">
|
|
112
|
+
<kbd>{kbi.key}</kbd>
|
|
113
|
+
</Box>
|
|
114
|
+
<BodyText as="span">{kbi.description}</BodyText>
|
|
115
|
+
</Flex>
|
|
116
|
+
{i < 4 ? <Divider /> : null}
|
|
117
|
+
</>
|
|
118
|
+
))}
|
|
119
|
+
</Flex>
|
|
120
|
+
|
|
121
|
+
## Custom label
|
|
122
|
+
|
|
123
|
+
You can set a custom label either by passing in a component to the label prop,
|
|
124
|
+
or by properly labelling the `RadioGroup` with the relevant text element.
|
|
125
|
+
|
|
126
|
+
```tsx
|
|
127
|
+
<Flex gap="600" direction="column">
|
|
128
|
+
<RadioGroup
|
|
129
|
+
{...args}
|
|
130
|
+
label={<Heading as="h2">Where do you live?</Heading>}
|
|
131
|
+
name="where-do-you-live"
|
|
132
|
+
>
|
|
133
|
+
<RadioTile value="england" label="England" />
|
|
134
|
+
<RadioTile value="wales" label="Wales" />
|
|
135
|
+
<RadioTile value="scotland" label="Scotland" />
|
|
136
|
+
<RadioTile value="northern-ireland" label="Northern Ireland" />
|
|
137
|
+
</RadioGroup>
|
|
138
|
+
|
|
139
|
+
<Flex direction="column" gap="100">
|
|
140
|
+
<Heading as="h2" id="where-do-you-live">
|
|
141
|
+
Where do you live?
|
|
142
|
+
</Heading>
|
|
143
|
+
<RadioGroup {...args} aria-labelledby="where-do-you-live">
|
|
144
|
+
<RadioTile value="england" label="England" />
|
|
145
|
+
<RadioTile value="wales" label="Wales" />
|
|
146
|
+
<RadioTile value="scotland" label="Scotland" />
|
|
147
|
+
<RadioTile value="northern-ireland" label="Northern Ireland" />
|
|
148
|
+
</RadioGroup>
|
|
149
|
+
</Flex>
|
|
150
|
+
</Flex>
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
## Helper text
|
|
154
|
+
|
|
155
|
+
`RadioGroup` can display a secondary message as a helper text. If displayed then
|
|
156
|
+
child radio items will not be display their own helper text.
|
|
157
|
+
|
|
158
|
+
## Validation
|
|
159
|
+
|
|
160
|
+
In general, radio buttons should have a value selected by default. If this is
|
|
161
|
+
not the case, you can display an error if no value is selected when the form is
|
|
162
|
+
submitted.
|
|
163
|
+
|
|
164
|
+
```tsx
|
|
165
|
+
<RadioGroup
|
|
166
|
+
{...args}
|
|
167
|
+
value={selected}
|
|
168
|
+
onValueChange={setSelected}
|
|
169
|
+
validationStatus={selected ? undefined : 'invalid'}
|
|
170
|
+
>
|
|
171
|
+
<RadioTile value="1" label="Bear" />
|
|
172
|
+
<RadioTile value="2" label="Koala" />
|
|
173
|
+
<RadioTile value="3" label="Wolf" />
|
|
174
|
+
<RadioTile value="4" label="Horse" />
|
|
175
|
+
</RadioGroup>
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
By default, the validation text is placed above the radio items. Use `validationPlacement="bottom"` to display it below instead.
|
|
179
|
+
|
|
180
|
+
```tsx
|
|
181
|
+
<Flex direction="column" gap="400">
|
|
182
|
+
<RadioGroup
|
|
183
|
+
label="Validation top (default)"
|
|
184
|
+
validationStatus="invalid"
|
|
185
|
+
validationText="Please select an option"
|
|
186
|
+
validationPlacement="top"
|
|
187
|
+
name="validation-placement-top"
|
|
188
|
+
contentWidth="fit-content"
|
|
189
|
+
>
|
|
190
|
+
<RadioTile value="1" label="Bear" />
|
|
191
|
+
<RadioTile value="2" label="Koala" />
|
|
192
|
+
<RadioTile value="3" label="Wolf" />
|
|
193
|
+
</RadioGroup>
|
|
194
|
+
<RadioGroup
|
|
195
|
+
label="Validation bottom"
|
|
196
|
+
validationStatus="invalid"
|
|
197
|
+
validationText="Please select an option"
|
|
198
|
+
validationPlacement="bottom"
|
|
199
|
+
name="validation-placement-bottom"
|
|
200
|
+
contentWidth="fit-content"
|
|
201
|
+
>
|
|
202
|
+
<RadioTile value="1" label="Bear" />
|
|
203
|
+
<RadioTile value="2" label="Koala" />
|
|
204
|
+
<RadioTile value="3" label="Wolf" />
|
|
205
|
+
</RadioGroup>
|
|
206
|
+
</Flex>
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
## Content width
|
|
210
|
+
|
|
211
|
+
The width of the `RadioGroup` should be set by the parent layout, however it is
|
|
212
|
+
possible to independently set the width of the children using `contentWidth`
|
|
213
|
+
prop.
|
|
214
|
+
|
|
215
|
+
By default it will set the width of the children to fit their content, however
|
|
216
|
+
you can set it to a specific width, or to `100%` to take up the full width of
|
|
217
|
+
the `RadioGroup`.
|
|
218
|
+
|
|
219
|
+
This is a responsive property, so you are able to set different widths for
|
|
220
|
+
different breakpoints.
|
|
221
|
+
|
|
222
|
+
## Grid layout
|
|
223
|
+
|
|
224
|
+
You can compose the `RadioGroup` with the `Grid` component if you need to
|
|
225
|
+
present a specific grid layout.
|
|
226
|
+
|
|
227
|
+
```tsx
|
|
228
|
+
<RadioGroup {...args}>
|
|
229
|
+
<Grid columns="3" gap="150">
|
|
230
|
+
<RadioTile value="1" label="One" />
|
|
231
|
+
<RadioTile value="2" label="Two" />
|
|
232
|
+
<RadioTile value="3" label="Three" />
|
|
233
|
+
<RadioTile value="4" label="Four" />
|
|
234
|
+
<RadioTile value="5" label="Five" />
|
|
235
|
+
<RadioTile value="6" label="Six" />
|
|
236
|
+
</Grid>
|
|
237
|
+
</RadioGroup>
|
|
238
|
+
```
|
|
239
|
+
|
|
240
|
+
## RadioTile layout
|
|
241
|
+
|
|
242
|
+
`RadioTile` components will, by default, fit their content. However they have
|
|
243
|
+
access to all flex item props, so you can set them to grow and fill the
|
|
244
|
+
available space, or to have a specific width.
|
|
245
|
+
|
|
246
|
+
```tsx
|
|
247
|
+
<RadioGroup direction="row" label="Numbers">
|
|
248
|
+
<RadioTile value="1" label="One" flex="1" />
|
|
249
|
+
<RadioTile value="2" label="Two" flex="1" />
|
|
250
|
+
</RadioGroup>
|
|
251
|
+
```
|
|
252
|
+
|
|
253
|
+
## Controlled
|
|
254
|
+
|
|
255
|
+
A controlled value can be provided using the value prop, which accepts a value
|
|
256
|
+
corresponding with the value prop of each `Radio`. The onChange event is fired
|
|
257
|
+
when the user selects a `Radio`.
|
|
258
|
+
|
|
259
|
+
```
|
|
260
|
+
const options = ['Bear', 'Koala', 'Wolf', 'Horse'];
|
|
261
|
+
const [selected, setSelected] = useState(options[0]);
|
|
262
|
+
|
|
263
|
+
[...]
|
|
264
|
+
|
|
265
|
+
<RadioGroup
|
|
266
|
+
{...args}
|
|
267
|
+
value={selected}
|
|
268
|
+
onValueChange={setSelected}
|
|
269
|
+
helperText={`Your favourite animal is a ${selected}`}
|
|
270
|
+
>
|
|
271
|
+
{options.map(animal => (
|
|
272
|
+
<RadioTile key={animal} value={animal} label={animal} />
|
|
273
|
+
))}
|
|
274
|
+
</RadioGroup>
|
|
275
|
+
```
|
|
276
|
+
|
|
277
|
+
```tsx
|
|
278
|
+
<RadioGroup
|
|
279
|
+
{...args}
|
|
280
|
+
value={selected}
|
|
281
|
+
onValueChange={setSelected}
|
|
282
|
+
helperText={`Your favourite animal is a ${selected}`}
|
|
283
|
+
>
|
|
284
|
+
{options.map(animal => (
|
|
285
|
+
<RadioTile key={animal} value={animal} label={animal} />
|
|
286
|
+
))}
|
|
287
|
+
</RadioGroup>
|
|
288
|
+
```
|
|
289
|
+
|
|
290
|
+
## Radio & RadioTile Image
|
|
291
|
+
|
|
292
|
+
The `Radio` & `RadioTile` components can display an icon or image between the indicator and label.
|
|
293
|
+
|
|
294
|
+
```tsx
|
|
295
|
+
<Radio value="2" label="Two" helperText="The number two" image={<CashbackCardMediumIcon />} />
|
|
296
|
+
```
|
|
297
|
+
|
|
298
|
+
```tsx
|
|
299
|
+
<RadioGroup label="How would you like to pay?">
|
|
300
|
+
<RadioTile
|
|
301
|
+
value="mastercard"
|
|
302
|
+
label="Mastercard"
|
|
303
|
+
helperText=""
|
|
304
|
+
image={<img src={mastercard} width={40} height={24} alt="" />}
|
|
305
|
+
/>
|
|
306
|
+
<RadioTile
|
|
307
|
+
value="visa"
|
|
308
|
+
label="Visa"
|
|
309
|
+
helperText=""
|
|
310
|
+
image={<img src={visa} width={40} height={24} alt="" />}
|
|
311
|
+
/>
|
|
312
|
+
<RadioTile value="cash" label="Cash" image={<MoneyMediumIcon />} />
|
|
313
|
+
</RadioGroup>
|
|
314
|
+
```
|
|
315
|
+
|
|
316
|
+
**If you are using an `img` element, remember to include a null alt tag
|
|
317
|
+
(`alt=""` ) so the image is ignored by assistive technologies.**
|
|
318
|
+
|
|
319
|
+
```tsx
|
|
320
|
+
<RadioTile
|
|
321
|
+
value="2"
|
|
322
|
+
label="Two"
|
|
323
|
+
helperText="The number two"
|
|
324
|
+
image={<img src="https://help.uw.co.uk/images/iPhone.svg" width={25} alt="" />}
|
|
325
|
+
/>
|
|
326
|
+
```
|
|
327
|
+
|
|
328
|
+
## RadioCard
|
|
329
|
+
|
|
330
|
+
You can use the `RadioCard` component to present additional content in a more
|
|
331
|
+
card-like visual style. Unlike `RadioTile`, this component will accept
|
|
332
|
+
children.
|
|
333
|
+
|
|
334
|
+
```tsx
|
|
335
|
+
<RadioCard value="1" label="Debit card payment">
|
|
336
|
+
<Flex asChild gap="100" direction="column">
|
|
337
|
+
<ul role="list">
|
|
338
|
+
<li>• Unlimited free top-ups</li>
|
|
339
|
+
<li>• Instant withdrawals</li>
|
|
340
|
+
<li>• Extra layer of security</li>
|
|
341
|
+
</ul>
|
|
342
|
+
</Flex>
|
|
343
|
+
</RadioCard>
|
|
344
|
+
```
|
|
345
|
+
|
|
346
|
+
```tsx
|
|
347
|
+
<Flex>
|
|
348
|
+
<RadioGroup
|
|
349
|
+
defaultValue="1"
|
|
350
|
+
direction="column"
|
|
351
|
+
contentWidth="350px"
|
|
352
|
+
label={<Heading>Payment options</Heading>}
|
|
353
|
+
>
|
|
354
|
+
<Flex direction="column">
|
|
355
|
+
<Flex right="24px" position="relative" justifyContent="end">
|
|
356
|
+
<Badge flatBase colorScheme="positive" variant="emphasis" size="sm">
|
|
357
|
+
Recommended
|
|
358
|
+
</Badge>
|
|
359
|
+
</Flex>
|
|
360
|
+
|
|
361
|
+
<RadioCard value="1" label="Debit card payment" image={<CashbackCardMediumIcon />}>
|
|
362
|
+
<Flex asChild gap="100" direction="column">
|
|
363
|
+
<ul role="list">
|
|
364
|
+
<Box asChild marginLeft="100">
|
|
365
|
+
<li>• Unlimited free top-ups</li>
|
|
366
|
+
</Box>
|
|
367
|
+
<Box asChild marginLeft="100">
|
|
368
|
+
<li>• Instant withdrawals</li>
|
|
369
|
+
</Box>
|
|
370
|
+
<Box asChild marginLeft="100">
|
|
371
|
+
<li>• Extra layer of security</li>
|
|
372
|
+
</Box>
|
|
373
|
+
</ul>
|
|
374
|
+
</Flex>
|
|
375
|
+
</RadioCard>
|
|
376
|
+
</Flex>
|
|
377
|
+
|
|
378
|
+
<RadioCard value="2" label="Instant bank transfer" image={<BankMediumIcon />}>
|
|
379
|
+
<Flex asChild gap="100" direction="column">
|
|
380
|
+
<ul role="list">
|
|
381
|
+
<Box asChild marginLeft="100">
|
|
382
|
+
<li>• 5 free top-ups per month</li>
|
|
383
|
+
</Box>
|
|
384
|
+
<Box asChild marginLeft="100">
|
|
385
|
+
<li>• £0.35 per additional top-up</li>
|
|
386
|
+
</Box>
|
|
387
|
+
</ul>
|
|
388
|
+
</Flex>
|
|
389
|
+
</RadioCard>
|
|
390
|
+
</RadioGroup>
|
|
391
|
+
</Flex>
|
|
392
|
+
```
|
|
393
|
+
|
|
394
|
+
## API
|
|
395
|
+
|
|
396
|
+
This component is based on the `fieldset` element and supports the following common props:
|
|
397
|
+
|
|
398
|
+
- Margin
|
|
399
|
+
|
|
400
|
+
| Prop | Type | Default | Description |
|
|
401
|
+
| --------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
402
|
+
| `label` | `ReactNode` | — | The label for the formfield group. This should contain the question being answered by the formfield group. If you don't include a label you need to ensure you use the `aria-label` or `aria-labelledby` prop to properly associate a label with the formfield group. |
|
|
403
|
+
| `defaultValue` | `string` | — | |
|
|
404
|
+
| `asChild` | `boolean` | — | |
|
|
405
|
+
| `name` | `string` | — | |
|
|
406
|
+
| `required` | `boolean` | — | |
|
|
407
|
+
| `disabled` | `boolean` | — | |
|
|
408
|
+
| `loop` | `boolean` | — | |
|
|
409
|
+
| `value` | `string \| null` | — | |
|
|
410
|
+
| `onValueChange` | `((value: string) => void)` | — | |
|
|
411
|
+
| `labelVariant` | `"body" \| "heading"` | — | Set the label variant |
|
|
412
|
+
| `helperText` | `ReactNode` | — | Helper text for the formfield group. Provides a hint such as specific requirements for what to choose. When displayed, child components should not display their own `helperText`. |
|
|
413
|
+
| `validationText` | `ReactNode` | — | |
|
|
414
|
+
| `validationStatus` | `"valid" \| "invalid"` | — | |
|
|
415
|
+
| `validationPlacement` | `"top" \| "bottom"` | — | |
|
|
416
|
+
| `margin` | `Responsive<"0" \| "auto" \| `var(--h-${string})` \| "25" \| "50" \| "75" \| "100" \| "150" \| "175" \| "200" \| "250" \| "300" \| "350" \| "400" \| "500" \| "600" \| "700" \| "800" \| "900" \| "1000">` | — | |
|
|
417
|
+
| `marginTop` | `Responsive<"0" \| "auto" \| `var(--h-${string})` \| "25" \| "50" \| "75" \| "100" \| "150" \| "175" \| "200" \| "250" \| "300" \| "350" \| "400" \| "500" \| "600" \| "700" \| "800" \| "900" \| "1000">` | — | |
|
|
418
|
+
| `marginRight` | `Responsive<"0" \| "auto" \| `var(--h-${string})` \| "25" \| "50" \| "75" \| "100" \| "150" \| "175" \| "200" \| "250" \| "300" \| "350" \| "400" \| "500" \| "600" \| "700" \| "800" \| "900" \| "1000">` | — | |
|
|
419
|
+
| `marginBottom` | `Responsive<"0" \| "auto" \| `var(--h-${string})` \| "25" \| "50" \| "75" \| "100" \| "150" \| "175" \| "200" \| "250" \| "300" \| "350" \| "400" \| "500" \| "600" \| "700" \| "800" \| "900" \| "1000">` | — | |
|
|
420
|
+
| `marginLeft` | `Responsive<"0" \| "auto" \| `var(--h-${string})` \| "25" \| "50" \| "75" \| "100" \| "150" \| "175" \| "200" \| "250" \| "300" \| "350" \| "400" \| "500" \| "600" \| "700" \| "800" \| "900" \| "1000">` | — | |
|
|
421
|
+
| `marginX` | `Responsive<"0" \| "auto" \| `var(--h-${string})` \| "25" \| "50" \| "75" \| "100" \| "150" \| "175" \| "200" \| "250" \| "300" \| "350" \| "400" \| "500" \| "600" \| "700" \| "800" \| "900" \| "1000">` | — | |
|
|
422
|
+
| `marginY` | `Responsive<"0" \| "auto" \| `var(--h-${string})` \| "25" \| "50" \| "75" \| "100" \| "150" \| "175" \| "200" \| "250" \| "300" \| "350" \| "400" \| "500" \| "600" \| "700" \| "800" \| "900" \| "1000">` | — | |
|
|
423
|
+
| `direction` | `Responsive<"row" \| "column" \| "row-reverse" \| "column-reverse">` | `column` | |
|
|
424
|
+
| `contentWidth` | `Responsive<string>` | — | Set the container width of the RadioGroup children, independent to the width of the parent RadioGroup. |
|
|
425
|
+
|
|
426
|
+
### Radio API
|
|
427
|
+
|
|
428
|
+
This component is based on the `button` element and supports the following common props:
|
|
429
|
+
|
|
430
|
+
- Margin
|
|
431
|
+
|
|
432
|
+
| Prop | Type | Default | Description |
|
|
433
|
+
| ----------------- | ------------------------- | ------- | ----------------------------------------------------------------------------------------------------------------------------------------- |
|
|
434
|
+
| `label` | `ReactNode` | — | The label for the Radio. If not using please properly associate the Radio with a label using the `aria-label` or `aria-labelledby` props. |
|
|
435
|
+
| `image` | `ReactNode` | — | Optional image to show between the radio indicator and label. |
|
|
436
|
+
| `value` | `string` | — | |
|
|
437
|
+
| `asChild` | `boolean` | — | |
|
|
438
|
+
| `checked` | `boolean` | — | |
|
|
439
|
+
| `required` | `boolean` | — | |
|
|
440
|
+
| `labelFontWeight` | `"regular" \| "semibold"` | — | |
|
|
441
|
+
| `helperText` | `ReactNode` | — | Helper text for the Radio. Will not display if the radio group has `helperText` set. |
|
|
442
|
+
|
|
443
|
+
### RadioTile API
|
|
444
|
+
|
|
445
|
+
This component is based on the `button` element and supports the following common props:
|
|
446
|
+
|
|
447
|
+
- Margin
|
|
448
|
+
- Flex item
|
|
449
|
+
|
|
450
|
+
| Prop | Type | Default | Description |
|
|
451
|
+
| ----------------- | ------------------------- | ------- | ------------------------------------------------------------------------------------ |
|
|
452
|
+
| `label` | `ReactNode` | — | |
|
|
453
|
+
| `image` | `ReactNode` | — | Optional image to show between the radio indicator and label. |
|
|
454
|
+
| `value` | `string` | — | |
|
|
455
|
+
| `asChild` | `boolean` | — | |
|
|
456
|
+
| `checked` | `boolean` | — | |
|
|
457
|
+
| `required` | `boolean` | — | |
|
|
458
|
+
| `labelFontWeight` | `"regular" \| "semibold"` | — | |
|
|
459
|
+
| `helperText` | `ReactNode` | — | Helper text for the Radio. Will not display if the radio group has `helperText` set. |
|
|
460
|
+
| `badge` | `ReactNode` | — | |
|
|
461
|
+
| `flex` | `Responsive<string>` | — | |
|
|
462
|
+
| `flexBasis` | `Responsive<string>` | — | |
|
|
463
|
+
| `flexShrink` | `Responsive<string>` | — | |
|
|
464
|
+
| `flexGrow` | `Responsive<string>` | — | |
|
|
465
|
+
|
|
466
|
+
### RadioCard API
|
|
467
|
+
|
|
468
|
+
This component is based on the `button` element and supports the following common props:
|
|
469
|
+
|
|
470
|
+
- Margin
|
|
471
|
+
|
|
472
|
+
| Prop | Type | Default | Description |
|
|
473
|
+
| ----------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------- | ----------------------------------------------------------------------------------------------------------------------------------------- |
|
|
474
|
+
| `label` | `ReactNode` | — | The label for the Radio. If not using please properly associate the Radio with a label using the `aria-label` or `aria-labelledby` props. |
|
|
475
|
+
| `image` | `ReactNode` | — | Optional image to show between the radio indicator and label. |
|
|
476
|
+
| `value` | `string` | — | |
|
|
477
|
+
| `asChild` | `boolean` | — | |
|
|
478
|
+
| `checked` | `boolean` | — | |
|
|
479
|
+
| `required` | `boolean` | — | |
|
|
480
|
+
| `labelFontWeight` | `"regular" \| "semibold"` | — | |
|
|
481
|
+
| `margin` | `Responsive<"0" \| "auto" \| "25" \| "50" \| "75" \| "100" \| "150" \| "175" \| "200" \| "250" \| "300" \| "350" \| "400" \| "500" \| "600" \| "700" \| "800" \| "900" \| "1000" \| `var(--h-${string})`>` | — | |
|
|
482
|
+
| `marginTop` | `Responsive<"0" \| "auto" \| "25" \| "50" \| "75" \| "100" \| "150" \| "175" \| "200" \| "250" \| "300" \| "350" \| "400" \| "500" \| "600" \| "700" \| "800" \| "900" \| "1000" \| `var(--h-${string})`>` | — | |
|
|
483
|
+
| `marginRight` | `Responsive<"0" \| "auto" \| "25" \| "50" \| "75" \| "100" \| "150" \| "175" \| "200" \| "250" \| "300" \| "350" \| "400" \| "500" \| "600" \| "700" \| "800" \| "900" \| "1000" \| `var(--h-${string})`>` | — | |
|
|
484
|
+
| `marginBottom` | `Responsive<"0" \| "auto" \| "25" \| "50" \| "75" \| "100" \| "150" \| "175" \| "200" \| "250" \| "300" \| "350" \| "400" \| "500" \| "600" \| "700" \| "800" \| "900" \| "1000" \| `var(--h-${string})`>` | — | |
|
|
485
|
+
| `marginLeft` | `Responsive<"0" \| "auto" \| "25" \| "50" \| "75" \| "100" \| "150" \| "175" \| "200" \| "250" \| "300" \| "350" \| "400" \| "500" \| "600" \| "700" \| "800" \| "900" \| "1000" \| `var(--h-${string})`>` | — | |
|
|
486
|
+
| `marginX` | `Responsive<"0" \| "auto" \| "25" \| "50" \| "75" \| "100" \| "150" \| "175" \| "200" \| "250" \| "300" \| "350" \| "400" \| "500" \| "600" \| "700" \| "800" \| "900" \| "1000" \| `var(--h-${string})`>` | — | |
|
|
487
|
+
| `marginY` | `Responsive<"0" \| "auto" \| "25" \| "50" \| "75" \| "100" \| "150" \| "175" \| "200" \| "250" \| "300" \| "350" \| "400" \| "500" \| "600" \| "700" \| "800" \| "900" \| "1000" \| `var(--h-${string})`>` | — | |
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
# SearchInput
|
|
2
|
+
|
|
3
|
+
`SearchInput` allows users to enter a specific keyword or phrase and obtain results related to the context in which it is placed.
|
|
4
|
+
|
|
5
|
+
- [Alternatives](#alternatives)
|
|
6
|
+
- [Accessibility](#accessibility)
|
|
7
|
+
- [Label](#label)
|
|
8
|
+
- [Clear](#clear)
|
|
9
|
+
- [Loading](#loading)
|
|
10
|
+
- [Usage with a button](#usage-with-a-button)
|
|
11
|
+
- [API](#api)
|
|
12
|
+
|
|
13
|
+
```tsx
|
|
14
|
+
<SearchInput
|
|
15
|
+
value={value}
|
|
16
|
+
onChange={(event: ChangeEvent<HTMLInputElement>) => setValue(event.target.value)}
|
|
17
|
+
onClear={() => setValue('')}
|
|
18
|
+
id="search-input-playground"
|
|
19
|
+
{...args}
|
|
20
|
+
/>
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
## Alternatives
|
|
24
|
+
|
|
25
|
+
- TextInput - For text
|
|
26
|
+
- PasswordInput - For passwords
|
|
27
|
+
- CurrencyInput - For money
|
|
28
|
+
|
|
29
|
+
## Accessibility
|
|
30
|
+
|
|
31
|
+
Wrap `SearchInput` in a container element with `role="search"` to increase
|
|
32
|
+
their discoverability to assistive technologies. This parent element should
|
|
33
|
+
encompass all of the elements that together form the search feature.
|
|
34
|
+
|
|
35
|
+
Be aware though that too many landmark roles such as this can create
|
|
36
|
+
unnecessary 'noise' for screen reader users, and should be used sparingly on a
|
|
37
|
+
page.
|
|
38
|
+
|
|
39
|
+
You can learn more about this at the [the MDN docs](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Reference/Roles/search_role).
|
|
40
|
+
|
|
41
|
+
```tsx
|
|
42
|
+
<form role="search">
|
|
43
|
+
<SearchInput />
|
|
44
|
+
</form>
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
## Label
|
|
48
|
+
|
|
49
|
+
A label is required. By default it will be visually hidden, but still available
|
|
50
|
+
to screen readers. You can change this by setting `hideLabel` to `false`.
|
|
51
|
+
|
|
52
|
+
## Clear
|
|
53
|
+
|
|
54
|
+
You can pass a function to the `onClear` prop to clear the input. When there is
|
|
55
|
+
a value the `clear` button will be present, and clicking it will call the
|
|
56
|
+
`onClear` function. This should be used only to clear the value of the input.
|
|
57
|
+
|
|
58
|
+
## Loading
|
|
59
|
+
|
|
60
|
+
You can set the `SearchInput` into a loading state, where it will disable the
|
|
61
|
+
input and display a loading spinner.
|
|
62
|
+
|
|
63
|
+
```tsx
|
|
64
|
+
<SearchInput
|
|
65
|
+
{...args}
|
|
66
|
+
value={value}
|
|
67
|
+
onChange={(event: ChangeEvent<HTMLInputElement>) => setValue(event.target.value)}
|
|
68
|
+
onClear={() => setValue('')}
|
|
69
|
+
loading
|
|
70
|
+
/>
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
## Usage with a button
|
|
74
|
+
|
|
75
|
+
On desktop, and tablet the `SearchInput` must be followed by a button which triggers the
|
|
76
|
+
containing form's search action. Results should be shown after the user
|
|
77
|
+
triggers the search action.
|
|
78
|
+
|
|
79
|
+
On mobile, no button is required, as the search can be triggered by
|
|
80
|
+
tapping on the search button on the keyboard or dynamically while typing. On
|
|
81
|
+
older mobile browsers, the enter key may not explicitly display the word
|
|
82
|
+
_Search_ but will still trigger the containing form's search action. Results
|
|
83
|
+
should be shown dynamically as the user types or after tapping on the search
|
|
84
|
+
button on the keyboard.
|
|
85
|
+
|
|
86
|
+
You can achieve this UI using responsive props.
|
|
87
|
+
|
|
88
|
+
```tsx
|
|
89
|
+
<Flex asChild gap="50" width={{ mobile: '100%', tablet: '500px' }}>
|
|
90
|
+
<form role="search" action={search}>
|
|
91
|
+
<SearchInput
|
|
92
|
+
label="Search"
|
|
93
|
+
value={value}
|
|
94
|
+
placeholder="What do you need help with?"
|
|
95
|
+
onChange={(event: React.ChangeEvent<HTMLInputElement>) => setValue(event.target.value)}
|
|
96
|
+
onClear={() => setValue('')}
|
|
97
|
+
/>
|
|
98
|
+
<Box display={{ mobile: 'none', tablet: 'block' }}>
|
|
99
|
+
<Button variant="solid" colorScheme="yellow">
|
|
100
|
+
Search
|
|
101
|
+
</Button>
|
|
102
|
+
</Box>
|
|
103
|
+
</form>
|
|
104
|
+
</Flex>
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
## API
|
|
108
|
+
|
|
109
|
+
This component is based on the `TextInput` component and supports the following common props:
|
|
110
|
+
|
|
111
|
+
- Margin
|
|
112
|
+
|
|
113
|
+
| Prop | Type | Default | Description |
|
|
114
|
+
| ------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------- | --------------------------------------------------------------------------- |
|
|
115
|
+
| `label` | `string` | — | The label for the form field, describing its purpose. |
|
|
116
|
+
| `defaultValue` | `string \| number` | — | The initial value of the input when rendered. |
|
|
117
|
+
| `value` | `string \| number` | — | The controlled value of the input. Must be used with an `onChange` handler. |
|
|
118
|
+
| `labelId` | `string` | — | |
|
|
119
|
+
| `helperTextId` | `string` | — | |
|
|
120
|
+
| `validationTextId` | `string` | — | |
|
|
121
|
+
| `hideLabel` | `boolean` | `true` | Visually hide the label. |
|
|
122
|
+
| `labelVariant` | `"body" \| "heading"` | — | Change the label variant |
|
|
123
|
+
| `helperText` | `string` | — | Optional helper text to provide additional context or instructions. |
|
|
124
|
+
| `margin` | `Responsive<"auto" \| "0" \| "25" \| "50" \| "75" \| "100" \| "150" \| "175" \| "200" \| "250" \| "300" \| "350" \| "400" \| "500" \| "600" \| "700" \| "800" \| "900" \| "1000" \| `var(--h-${string})`>` | — | |
|
|
125
|
+
| `marginTop` | `Responsive<"auto" \| "0" \| "25" \| "50" \| "75" \| "100" \| "150" \| "175" \| "200" \| "250" \| "300" \| "350" \| "400" \| "500" \| "600" \| "700" \| "800" \| "900" \| "1000" \| `var(--h-${string})`>` | — | |
|
|
126
|
+
| `marginRight` | `Responsive<"auto" \| "0" \| "25" \| "50" \| "75" \| "100" \| "150" \| "175" \| "200" \| "250" \| "300" \| "350" \| "400" \| "500" \| "600" \| "700" \| "800" \| "900" \| "1000" \| `var(--h-${string})`>` | — | |
|
|
127
|
+
| `marginBottom` | `Responsive<"auto" \| "0" \| "25" \| "50" \| "75" \| "100" \| "150" \| "175" \| "200" \| "250" \| "300" \| "350" \| "400" \| "500" \| "600" \| "700" \| "800" \| "900" \| "1000" \| `var(--h-${string})`>` | — | |
|
|
128
|
+
| `marginLeft` | `Responsive<"auto" \| "0" \| "25" \| "50" \| "75" \| "100" \| "150" \| "175" \| "200" \| "250" \| "300" \| "350" \| "400" \| "500" \| "600" \| "700" \| "800" \| "900" \| "1000" \| `var(--h-${string})`>` | — | |
|
|
129
|
+
| `marginX` | `Responsive<"auto" \| "0" \| "25" \| "50" \| "75" \| "100" \| "150" \| "175" \| "200" \| "250" \| "300" \| "350" \| "400" \| "500" \| "600" \| "700" \| "800" \| "900" \| "1000" \| `var(--h-${string})`>` | — | |
|
|
130
|
+
| `marginY` | `Responsive<"auto" \| "0" \| "25" \| "50" \| "75" \| "100" \| "150" \| "175" \| "200" \| "250" \| "300" \| "350" \| "400" \| "500" \| "600" \| "700" \| "800" \| "900" \| "1000" \| `var(--h-${string})`>` | — | |
|
|
131
|
+
| `onClear` | `(() => void)` | — | |
|
|
132
|
+
| `loading` | `boolean` | — | |
|