@react-ui-org/react-ui 0.50.2 → 0.52.0
Sign up to get free protection for your applications and to get access to all the features.
- package/dist/lib.development.js +157 -49
- package/dist/lib.js +1 -1
- package/package.json +1 -1
- package/src/lib/components/Alert/Alert.jsx +1 -3
- package/src/lib/components/Alert/Alert.scss +1 -9
- package/src/lib/components/Alert/README.mdx +0 -20
- package/src/lib/components/Alert/_settings.scss +1 -1
- package/src/lib/components/Alert/_theme.scss +0 -10
- package/src/lib/components/Badge/Badge.jsx +1 -3
- package/src/lib/components/Badge/Badge.scss +25 -44
- package/src/lib/components/Badge/README.mdx +6 -14
- package/src/lib/components/Button/Button.jsx +20 -10
- package/src/lib/components/Button/README.mdx +8 -3
- package/src/lib/components/Button/_base.scss +21 -12
- package/src/lib/components/Button/_priorities.scss +13 -18
- package/src/lib/components/Button/_settings.scss +1 -1
- package/src/lib/components/Button/_theme.scss +0 -10
- package/src/lib/components/ButtonGroup/ButtonGroup.jsx +5 -3
- package/src/lib/components/ButtonGroup/ButtonGroup.scss +26 -1
- package/src/lib/components/ButtonGroup/README.mdx +85 -59
- package/src/lib/components/ButtonGroup/_theme.scss +13 -0
- package/src/lib/components/Card/Card.jsx +1 -3
- package/src/lib/components/Card/Card.scss +0 -9
- package/src/lib/components/Card/README.mdx +0 -16
- package/src/lib/components/Card/_theme.scss +0 -10
- package/src/lib/components/FormLayout/README.mdx +22 -8
- package/src/lib/components/Grid/_helpers/generateResponsiveCustomProperties.js +1 -1
- package/src/lib/components/InputGroup/InputGroup.jsx +170 -0
- package/src/lib/components/InputGroup/InputGroup.scss +92 -0
- package/src/lib/components/InputGroup/InputGroupContext.js +3 -0
- package/src/lib/components/InputGroup/README.mdx +278 -0
- package/src/lib/components/InputGroup/_theme.scss +2 -0
- package/src/lib/components/InputGroup/index.js +2 -0
- package/src/lib/components/Modal/Modal.jsx +58 -97
- package/src/lib/components/Modal/ModalCloseButton.scss +2 -2
- package/src/lib/components/Modal/README.mdx +392 -128
- package/src/lib/components/Modal/_helpers/getPositionClassName.js +7 -0
- package/src/lib/components/Modal/_helpers/getSizeClassName.js +19 -0
- package/src/lib/components/Modal/_hooks/useModalFocus.js +126 -0
- package/src/lib/components/Modal/_hooks/useModalScrollPrevention.js +35 -0
- package/src/lib/components/Modal/_settings.scss +2 -2
- package/src/lib/components/Popover/README.mdx +7 -4
- package/src/lib/components/Radio/README.mdx +9 -1
- package/src/lib/components/Radio/Radio.jsx +39 -31
- package/src/lib/components/Radio/Radio.scss +11 -1
- package/src/lib/components/ScrollView/README.mdx +2 -2
- package/src/lib/components/SelectField/SelectField.jsx +21 -8
- package/src/lib/components/SelectField/SelectField.scss +5 -0
- package/src/lib/components/Table/_components/TableCell.scss +6 -5
- package/src/lib/components/Table/_components/TableHeaderCell/TableHeaderCell.jsx +8 -5
- package/src/lib/components/Table/_settings.scss +5 -6
- package/src/lib/components/Text/README.mdx +14 -8
- package/src/lib/components/TextField/TextField.jsx +21 -8
- package/src/lib/components/TextField/TextField.scss +5 -0
- package/src/lib/components/TextLink/README.mdx +8 -6
- package/src/lib/components/TextLink/TextLink.scss +5 -0
- package/src/lib/components/TextLink/_theme.scss +2 -0
- package/src/lib/components/Toolbar/README.mdx +19 -11
- package/src/lib/components/_helpers/getRootColorClassName.js +4 -0
- package/src/lib/index.js +1 -0
- package/src/lib/styles/elements/_code.scss +1 -3
- package/src/lib/styles/elements/_page.scss +1 -0
- package/src/lib/styles/elements/_rulers.scss +1 -3
- package/src/lib/styles/elements/_small.scss +1 -1
- package/src/lib/styles/settings/_form-fields.scss +1 -1
- package/src/lib/styles/settings/_utilities.scss +46 -14
- package/src/lib/styles/theme/_accessibility.scss +4 -4
- package/src/lib/styles/theme/_borders.scss +3 -2
- package/src/lib/styles/theme/_code.scss +2 -2
- package/src/lib/styles/theme/_links.scss +6 -4
- package/src/lib/styles/theme/_lists.scss +1 -1
- package/src/lib/styles/theme/_page.scss +2 -2
- package/src/lib/styles/theme/_spacing.scss +11 -11
- package/src/lib/styles/theme/_typography.scss +19 -18
- package/src/lib/styles/theme-constants/_colors.scss +23 -23
- package/src/lib/styles/tools/_spacing.scss +1 -1
- package/src/lib/styles/tools/form-fields/_box-field-elements.scss +19 -2
- package/src/lib/styles/tools/form-fields/_box-field-sizes.scss +11 -8
- package/src/lib/styles/tools/form-fields/_foundation.scss +7 -0
- package/src/lib/theme.scss +650 -567
- package/src/lib/styles/theme/_colors.scss +0 -65
- /package/src/lib/components/{Button/helpers → _helpers}/getRootPriorityClassName.js +0 -0
@@ -43,6 +43,13 @@ See [API](#api) for all available options.
|
|
43
43
|
- Use button group to group **related actions** that a user can take. Buttons
|
44
44
|
should not be grouped just to save space on the screen.
|
45
45
|
|
46
|
+
- **Mixing multiple button priorities** and some other properties within a
|
47
|
+
button group is [not allowed](#shared-properties). The priority can only be
|
48
|
+
set for all buttons in the group at once.
|
49
|
+
|
50
|
+
- In most use cases, **secondary action color** is probably the best option for
|
51
|
+
buttons in a group as it works good with the colors of the selected state.
|
52
|
+
|
46
53
|
- Use **short labels or icons** so the buttons can fit small screens.
|
47
54
|
|
48
55
|
- For toggling between on/off states, use rather the
|
@@ -52,17 +59,28 @@ See [API](#api) for all available options.
|
|
52
59
|
the [SelectField](/components/select-field) or
|
53
60
|
[Radio](/components/radio) components.
|
54
61
|
|
62
|
+
- In the background, ButtonGroup uses the [`fieldset`][fieldset] element. Not
|
63
|
+
only it improves the [accessibility] of the group, it also allows you to make
|
64
|
+
use of its built-in features like disabling all nested inputs or pairing the
|
65
|
+
group with a form outside. Consult [the MDN docs][fieldset] to learn more.
|
66
|
+
|
55
67
|
- Be careful with using `startCorner` and `endCorner` options for grouped
|
56
68
|
buttons. Overflowing elements may cause undesired interaction problems.
|
57
69
|
|
58
70
|
### Shared Properties
|
59
71
|
|
60
72
|
You can set the following properties directly on ButtonGroup to be shared for
|
61
|
-
all buttons inside the group:
|
73
|
+
all buttons inside the group:
|
74
|
+
|
75
|
+
- `size`,
|
76
|
+
- `priority`,
|
77
|
+
- `disabled` state,
|
78
|
+
- and `block` width.
|
79
|
+
|
62
80
|
These properties are then passed over to individual buttons. At the same time,
|
63
|
-
they **cannot be overridden** on the buttons' level. While
|
64
|
-
from the design point of view it's undesirable to group
|
65
|
-
different types or sizes.
|
81
|
+
they **cannot be overridden** on the buttons' level. While (in theory)
|
82
|
+
technically possible, from the design point of view it's undesirable to group
|
83
|
+
buttons of totally different types or sizes.
|
66
84
|
|
67
85
|
## Priorities
|
68
86
|
|
@@ -73,6 +91,9 @@ priorities of the [Button](/components/button) component:
|
|
73
91
|
2. outline
|
74
92
|
3. flat
|
75
93
|
|
94
|
+
👉 To avoid undesired combinations, the visual priority of the button group
|
95
|
+
**cannot be overridden** on the Button level.
|
96
|
+
|
76
97
|
### Filled
|
77
98
|
|
78
99
|
The default, high-emphasis priority should be used for primary actions of your
|
@@ -80,9 +101,9 @@ app.
|
|
80
101
|
|
81
102
|
<Playground>
|
82
103
|
<ButtonGroup>
|
83
|
-
<Button label="Week" />
|
84
|
-
<Button label="Month" />
|
85
|
-
<Button label="Year" />
|
104
|
+
<Button color="secondary" label="Week" />
|
105
|
+
<Button color="secondary" label="Month" />
|
106
|
+
<Button color="secondary" label="Year" />
|
86
107
|
</ButtonGroup>
|
87
108
|
</Playground>
|
88
109
|
|
@@ -93,9 +114,9 @@ in your app.
|
|
93
114
|
|
94
115
|
<Playground>
|
95
116
|
<ButtonGroup priority="outline">
|
96
|
-
<Button label="Week" />
|
97
|
-
<Button label="Month" />
|
98
|
-
<Button label="Year" />
|
117
|
+
<Button color="secondary" label="Week" />
|
118
|
+
<Button color="secondary" label="Month" />
|
119
|
+
<Button color="secondary" label="Year" />
|
99
120
|
</ButtonGroup>
|
100
121
|
</Playground>
|
101
122
|
|
@@ -106,9 +127,9 @@ the content.
|
|
106
127
|
|
107
128
|
<Playground>
|
108
129
|
<ButtonGroup priority="flat">
|
109
|
-
<Button label="Week" />
|
110
|
-
<Button label="Month" />
|
111
|
-
<Button label="Year" />
|
130
|
+
<Button color="secondary" label="Week" />
|
131
|
+
<Button color="secondary" label="Month" />
|
132
|
+
<Button color="secondary" label="Year" />
|
112
133
|
</ButtonGroup>
|
113
134
|
</Playground>
|
114
135
|
|
@@ -119,19 +140,19 @@ medium, and large.
|
|
119
140
|
|
120
141
|
<Playground>
|
121
142
|
<ButtonGroup size="small">
|
122
|
-
<Button label="Week" />
|
123
|
-
<Button label="Month" />
|
124
|
-
<Button label="Year" />
|
143
|
+
<Button color="secondary" label="Week" />
|
144
|
+
<Button color="secondary" label="Month" />
|
145
|
+
<Button color="secondary" label="Year" />
|
125
146
|
</ButtonGroup>
|
126
147
|
<ButtonGroup>
|
127
|
-
<Button label="Week" />
|
128
|
-
<Button label="Month" />
|
129
|
-
<Button label="Year" />
|
148
|
+
<Button color="secondary" label="Week" />
|
149
|
+
<Button color="secondary" label="Month" />
|
150
|
+
<Button color="secondary" label="Year" />
|
130
151
|
</ButtonGroup>
|
131
152
|
<ButtonGroup size="large">
|
132
|
-
<Button label="Week" />
|
133
|
-
<Button label="Month" />
|
134
|
-
<Button label="Year" />
|
153
|
+
<Button color="secondary" label="Week" />
|
154
|
+
<Button color="secondary" label="Month" />
|
155
|
+
<Button color="secondary" label="Year" />
|
135
156
|
</ButtonGroup>
|
136
157
|
</Playground>
|
137
158
|
|
@@ -139,9 +160,9 @@ Block button groups span the full width of a parent:
|
|
139
160
|
|
140
161
|
<Playground>
|
141
162
|
<ButtonGroup block>
|
142
|
-
<Button label="Week" />
|
143
|
-
<Button label="Month" />
|
144
|
-
<Button label="Year" />
|
163
|
+
<Button color="secondary" label="Week" />
|
164
|
+
<Button color="secondary" label="Month" />
|
165
|
+
<Button color="secondary" label="Year" />
|
145
166
|
</ButtonGroup>
|
146
167
|
</Playground>
|
147
168
|
|
@@ -153,19 +174,19 @@ Disables all buttons inside the group.
|
|
153
174
|
|
154
175
|
<Playground>
|
155
176
|
<ButtonGroup disabled>
|
156
|
-
<Button label="Week" />
|
157
|
-
<Button label="Month" />
|
158
|
-
<Button label="Year" />
|
177
|
+
<Button color="secondary" label="Week" />
|
178
|
+
<Button color="secondary" label="Month" />
|
179
|
+
<Button color="secondary" label="Year" />
|
159
180
|
</ButtonGroup>
|
160
181
|
<ButtonGroup priority="outline" disabled>
|
161
|
-
<Button label="Week" />
|
162
|
-
<Button label="Month" />
|
163
|
-
<Button label="Year" />
|
182
|
+
<Button color="secondary" label="Week" />
|
183
|
+
<Button color="secondary" label="Month" />
|
184
|
+
<Button color="secondary" label="Year" />
|
164
185
|
</ButtonGroup>
|
165
186
|
<ButtonGroup priority="flat" disabled>
|
166
|
-
<Button label="Week" />
|
167
|
-
<Button label="Month" />
|
168
|
-
<Button label="Year" />
|
187
|
+
<Button color="secondary" label="Week" />
|
188
|
+
<Button color="secondary" label="Month" />
|
189
|
+
<Button color="secondary" label="Year" />
|
169
190
|
</ButtonGroup>
|
170
191
|
</Playground>
|
171
192
|
|
@@ -176,42 +197,42 @@ state of individual buttons can be indicated by showing an icon.
|
|
176
197
|
|
177
198
|
<Playground>
|
178
199
|
<ButtonGroup>
|
179
|
-
<Button
|
180
|
-
<Button label="Month" />
|
181
|
-
<Button label="Year" />
|
200
|
+
<Button color="success" label="Week" feedbackIcon={<Icon icon="success" />} />
|
201
|
+
<Button color="secondary" label="Month" />
|
202
|
+
<Button color="secondary" label="Year" />
|
182
203
|
</ButtonGroup>
|
183
204
|
<ButtonGroup priority="outline">
|
184
|
-
<Button
|
185
|
-
<Button label="Month" />
|
186
|
-
<Button label="Year" />
|
205
|
+
<Button color="success" label="Week" feedbackIcon={<Icon icon="success" />} />
|
206
|
+
<Button color="secondary" label="Month" />
|
207
|
+
<Button color="secondary" label="Year" />
|
187
208
|
</ButtonGroup>
|
188
209
|
<ButtonGroup priority="flat">
|
189
|
-
<Button
|
190
|
-
<Button label="Month" />
|
191
|
-
<Button label="Year" />
|
210
|
+
<Button color="success" label="Week" feedbackIcon={<Icon icon="success" />} />
|
211
|
+
<Button color="secondary" label="Month" />
|
212
|
+
<Button color="secondary" label="Year" />
|
192
213
|
</ButtonGroup>
|
193
214
|
</Playground>
|
194
215
|
|
195
|
-
###
|
216
|
+
### Selected State
|
196
217
|
|
197
|
-
To highlight the selected option,
|
198
|
-
|
218
|
+
To highlight the selected option, just apply the selected color variant for
|
219
|
+
the desired item.
|
199
220
|
|
200
221
|
<Playground>
|
201
222
|
<ButtonGroup>
|
202
|
-
<Button color="
|
203
|
-
<Button label="Month" />
|
204
|
-
<Button label="Year" />
|
223
|
+
<Button color="selected" label="Week" />
|
224
|
+
<Button color="secondary" label="Month" />
|
225
|
+
<Button color="secondary" label="Year" />
|
205
226
|
</ButtonGroup>
|
206
227
|
<ButtonGroup priority="outline">
|
207
|
-
<Button color="
|
208
|
-
<Button label="Month" />
|
209
|
-
<Button label="Year" />
|
228
|
+
<Button color="selected" label="Week" />
|
229
|
+
<Button color="secondary" label="Month" />
|
230
|
+
<Button color="secondary" label="Year" />
|
210
231
|
</ButtonGroup>
|
211
232
|
<ButtonGroup priority="flat">
|
212
|
-
<Button color="
|
213
|
-
<Button label="Month" />
|
214
|
-
<Button label="Year" />
|
233
|
+
<Button color="selected" label="Week" />
|
234
|
+
<Button color="secondary" label="Month" />
|
235
|
+
<Button color="secondary" label="Year" />
|
215
236
|
</ButtonGroup>
|
216
237
|
</Playground>
|
217
238
|
|
@@ -224,9 +245,9 @@ and communicating the state of individual options.
|
|
224
245
|
<>
|
225
246
|
<span id="period-label">Period:</span>
|
226
247
|
<ButtonGroup aria-labelledby="period-label">
|
227
|
-
<Button label="Week" aria-pressed
|
228
|
-
<Button label="Month" aria-pressed={false} />
|
229
|
-
<Button label="Year" aria-pressed={false} />
|
248
|
+
<Button color="selected" label="Week" aria-pressed />
|
249
|
+
<Button color="secondary" label="Month" aria-pressed={false} />
|
250
|
+
<Button color="secondary" label="Year" aria-pressed={false} />
|
230
251
|
</ButtonGroup>
|
231
252
|
</>
|
232
253
|
</Playground>
|
@@ -250,13 +271,18 @@ its accessibility.
|
|
250
271
|
|
251
272
|
| Custom Property | Description |
|
252
273
|
|--------------------------------------------------------------------|------------------------------------------------|
|
274
|
+
| `--rui-ButtonGroup__inner-border-radius` | Inner border radius of buttons |
|
253
275
|
| `--rui-ButtonGroup--filled__gap` | Gap between `filled` buttons |
|
254
276
|
| `--rui-ButtonGroup--filled__separator__width` | Separator width for `filled` buttons |
|
255
277
|
| `--rui-ButtonGroup--filled__separator__color` | Separator color for `filled` buttons |
|
278
|
+
| `--rui-ButtonGroup--outline__gap` | Gap between `outline` buttons |
|
279
|
+
| `--rui-ButtonGroup--outline__separator__width` | Separator width for `outline` buttons |
|
280
|
+
| `--rui-ButtonGroup--outline__separator__color` | Separator color for `outline` buttons |
|
256
281
|
| `--rui-ButtonGroup--flat__gap` | Gap between `flat` buttons |
|
257
282
|
| `--rui-ButtonGroup--flat__separator__width` | Separator width for `flat` buttons |
|
258
283
|
| `--rui-ButtonGroup--flat__separator__color` | Separator color for `flat` buttons |
|
259
|
-
| `--rui-ButtonGroup--outline__gap` | Gap between `outline` buttons |
|
260
284
|
|
285
|
+
[fieldset]: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/fieldset
|
286
|
+
[accessibility]: https://www.w3.org/WAI/tutorials/forms/grouping/
|
261
287
|
[React synthetic events]: https://reactjs.org/docs/events.html
|
262
288
|
[div]: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/div#attributes
|
@@ -0,0 +1,13 @@
|
|
1
|
+
$inner-border-radius: var(--rui-ButtonGroup__inner-border-radius);
|
2
|
+
|
3
|
+
$filled-gap: var(--rui-ButtonGroup--filled__gap);
|
4
|
+
$filled-separator-width: var(--rui-ButtonGroup--filled__separator__width);
|
5
|
+
$filled-separator-color: var(--rui-ButtonGroup--filled__separator__color);
|
6
|
+
|
7
|
+
$outline-gap: var(--rui-ButtonGroup--outline__gap);
|
8
|
+
$outline-separator-width: var(--rui-ButtonGroup--outline__separator__width);
|
9
|
+
$outline-separator-color: var(--rui-ButtonGroup--outline__separator__color);
|
10
|
+
|
11
|
+
$flat-gap: var(--rui-ButtonGroup--flat__gap);
|
12
|
+
$flat-separator-width: var(--rui-ButtonGroup--flat__separator__width);
|
13
|
+
$flat-separator-color: var(--rui-ButtonGroup--flat__separator__color);
|
@@ -46,9 +46,7 @@ Card.propTypes = {
|
|
46
46
|
/**
|
47
47
|
* [Color variant](/foundation/colors#component-colors) to clarify importance and meaning of the card.
|
48
48
|
*/
|
49
|
-
color: PropTypes.oneOf(
|
50
|
-
['primary', 'secondary', 'success', 'warning', 'danger', 'help', 'info', 'note', 'light', 'dark'],
|
51
|
-
),
|
49
|
+
color: PropTypes.oneOf(['success', 'warning', 'danger', 'help', 'info', 'note', 'light', 'dark']),
|
52
50
|
/**
|
53
51
|
* Make the card more compact.
|
54
52
|
*/
|
@@ -1,6 +1,5 @@
|
|
1
1
|
// 1. Retain equal card widths in flex and grid layouts independently on their content.
|
2
2
|
|
3
|
-
@use "../../styles/theme/colors";
|
4
3
|
@use "theme";
|
5
4
|
@use "tools";
|
6
5
|
|
@@ -33,14 +32,6 @@
|
|
33
32
|
box-shadow: theme.$raised-box-shadow;
|
34
33
|
}
|
35
34
|
|
36
|
-
.isRootColorPrimary {
|
37
|
-
@include tools.color(primary);
|
38
|
-
}
|
39
|
-
|
40
|
-
.isRootColorSecondary {
|
41
|
-
@include tools.color(secondary);
|
42
|
-
}
|
43
|
-
|
44
35
|
.isRootColorSuccess {
|
45
36
|
@include tools.color(success);
|
46
37
|
}
|
@@ -164,22 +164,6 @@ Card supports all
|
|
164
164
|
of your app.
|
165
165
|
|
166
166
|
<Playground>
|
167
|
-
<Card color="primary">
|
168
|
-
<CardBody>
|
169
|
-
Hello! I'm primary variant of card.
|
170
|
-
</CardBody>
|
171
|
-
<CardFooter>
|
172
|
-
<Button label="Read more" priority="outline" />
|
173
|
-
</CardFooter>
|
174
|
-
</Card>
|
175
|
-
<Card color="secondary">
|
176
|
-
<CardBody>
|
177
|
-
Hello! I'm secondary variant of card.
|
178
|
-
</CardBody>
|
179
|
-
<CardFooter>
|
180
|
-
<Button label="Read more" priority="outline" color="secondary" />
|
181
|
-
</CardFooter>
|
182
|
-
</Card>
|
183
167
|
<Card color="success">
|
184
168
|
<CardBody>
|
185
169
|
Hello! I'm success variant of card.
|
@@ -9,16 +9,6 @@ $disabled-background-color: var(--rui-Card--disabled__background-color);
|
|
9
9
|
$disabled-opacity: var(--rui-Card--disabled__opacity);
|
10
10
|
|
11
11
|
$colors: (
|
12
|
-
primary: (
|
13
|
-
color: var(--rui-Card--primary__color),
|
14
|
-
border-color: var(--rui-Card--primary__border-color),
|
15
|
-
background-color: var(--rui-Card--primary__background-color),
|
16
|
-
),
|
17
|
-
secondary: (
|
18
|
-
color: var(--rui-Card--secondary__color),
|
19
|
-
border-color: var(--rui-Card--secondary__border-color),
|
20
|
-
background-color: var(--rui-Card--secondary__background-color),
|
21
|
-
),
|
22
12
|
success: (
|
23
13
|
color: var(--rui-Card--success__color),
|
24
14
|
border-color: var(--rui-Card--success__border-color),
|
@@ -27,6 +27,7 @@ import {
|
|
27
27
|
ToolbarItem,
|
28
28
|
FormLayout,
|
29
29
|
FormLayoutCustomField,
|
30
|
+
InputGroup,
|
30
31
|
} from '../..'
|
31
32
|
|
32
33
|
## Basic Usage
|
@@ -144,24 +145,31 @@ with CSS custom properties.
|
|
144
145
|
<span id="label-width-options-label">Label width:</span>
|
145
146
|
</ToolbarItem>
|
146
147
|
<ToolbarItem>
|
147
|
-
<ButtonGroup
|
148
|
+
<ButtonGroup
|
149
|
+
aria-labelledby="label-width-options-label"
|
150
|
+
priority="outline"
|
151
|
+
>
|
148
152
|
<Button
|
149
|
-
|
153
|
+
aria-pressed={labelWidth === 'default'}
|
154
|
+
color={labelWidth === 'default' ? 'selected' : 'secondary'}
|
150
155
|
label="default"
|
151
156
|
onClick={() => setLabelWidth('default')}
|
152
157
|
/>
|
153
158
|
<Button
|
154
|
-
|
159
|
+
aria-pressed={labelWidth === 'auto'}
|
160
|
+
color={labelWidth === 'auto' ? 'selected' : 'secondary'}
|
155
161
|
label="auto"
|
156
162
|
onClick={() => setLabelWidth('auto')}
|
157
163
|
/>
|
158
164
|
<Button
|
159
|
-
|
165
|
+
aria-pressed={labelWidth === 'limited'}
|
166
|
+
color={labelWidth === 'limited' ? 'selected' : 'secondary'}
|
160
167
|
label="limited"
|
161
168
|
onClick={() => setLabelWidth('limited')}
|
162
169
|
/>
|
163
170
|
<Button
|
164
|
-
|
171
|
+
aria-pressed={labelWidth === 'custom'}
|
172
|
+
color={labelWidth === 'custom' ? 'selected' : 'secondary'}
|
165
173
|
label="custom"
|
166
174
|
onClick={() => setLabelWidth('custom')}
|
167
175
|
/>
|
@@ -351,14 +359,16 @@ This is a demo of all components supported by FormLayout.
|
|
351
359
|
<div>
|
352
360
|
<Toolbar>
|
353
361
|
<ToolbarItem>
|
354
|
-
<ButtonGroup>
|
362
|
+
<ButtonGroup priority="outline">
|
355
363
|
<Button
|
356
|
-
|
364
|
+
aria-pressed={fieldLayout === 'vertical'}
|
365
|
+
color={fieldLayout === 'vertical' ? 'selected' : 'secondary'}
|
357
366
|
label="Vertical layout"
|
358
367
|
onClick={() => setFieldLayout('vertical')}
|
359
368
|
/>
|
360
369
|
<Button
|
361
|
-
|
370
|
+
aria-pressed={fieldLayout === 'horizontal'}
|
371
|
+
color={fieldLayout === 'horizontal' ? 'selected' : 'secondary'}
|
362
372
|
label="Horizontal layout"
|
363
373
|
onClick={() => setFieldLayout('horizontal')}
|
364
374
|
/>
|
@@ -432,6 +442,10 @@ This is a demo of all components supported by FormLayout.
|
|
432
442
|
options={options}
|
433
443
|
value={fruit}
|
434
444
|
/>
|
445
|
+
<InputGroup label="Promo code">
|
446
|
+
<TextField label="Code" />
|
447
|
+
<Button label="Apply" color="secondary" priority="outline" />
|
448
|
+
</InputGroup>
|
435
449
|
</FormLayout>
|
436
450
|
</div>
|
437
451
|
)
|
@@ -0,0 +1,170 @@
|
|
1
|
+
import PropTypes from 'prop-types';
|
2
|
+
import React, { useContext } from 'react';
|
3
|
+
import { Text } from '../Text';
|
4
|
+
import { withGlobalProps } from '../../provider';
|
5
|
+
import { classNames } from '../../utils/classNames';
|
6
|
+
import { getRootSizeClassName } from '../_helpers/getRootSizeClassName';
|
7
|
+
import { getRootValidationStateClassName } from '../_helpers/getRootValidationStateClassName';
|
8
|
+
import { isChildrenEmpty } from '../_helpers/isChildrenEmpty';
|
9
|
+
import { resolveContextOrProp } from '../_helpers/resolveContextOrProp';
|
10
|
+
import { transferProps } from '../_helpers/transferProps';
|
11
|
+
import { FormLayoutContext } from '../FormLayout';
|
12
|
+
import { InputGroupContext } from './InputGroupContext';
|
13
|
+
import styles from './InputGroup.scss';
|
14
|
+
|
15
|
+
export const InputGroup = ({
|
16
|
+
children,
|
17
|
+
disabled,
|
18
|
+
id,
|
19
|
+
isLabelVisible,
|
20
|
+
label,
|
21
|
+
layout,
|
22
|
+
size,
|
23
|
+
validationTexts,
|
24
|
+
...restProps
|
25
|
+
}) => {
|
26
|
+
const formLayoutContext = useContext(FormLayoutContext);
|
27
|
+
|
28
|
+
if (isChildrenEmpty(children)) {
|
29
|
+
return null;
|
30
|
+
}
|
31
|
+
|
32
|
+
const validationState = children.reduce(
|
33
|
+
(state, child) => {
|
34
|
+
if (state === 'invalid' || (state === 'warning' && child.props.validationState === 'valid')) {
|
35
|
+
return state;
|
36
|
+
}
|
37
|
+
return child.props.validationState ?? state;
|
38
|
+
},
|
39
|
+
null,
|
40
|
+
);
|
41
|
+
|
42
|
+
return (
|
43
|
+
<fieldset
|
44
|
+
{...transferProps(restProps)}
|
45
|
+
id={id}
|
46
|
+
className={classNames(
|
47
|
+
styles.root,
|
48
|
+
formLayoutContext && styles.isRootInFormLayout,
|
49
|
+
resolveContextOrProp(formLayoutContext && formLayoutContext.layout, layout) === 'horizontal'
|
50
|
+
? styles.isRootLayoutHorizontal
|
51
|
+
: styles.isRootLayoutVertical,
|
52
|
+
disabled && styles.isRootDisabled,
|
53
|
+
getRootSizeClassName(size, styles),
|
54
|
+
getRootValidationStateClassName(validationState, styles),
|
55
|
+
)}
|
56
|
+
disabled={disabled}
|
57
|
+
>
|
58
|
+
<legend
|
59
|
+
className={styles.legend}
|
60
|
+
id={id && `${id}__label`}
|
61
|
+
>
|
62
|
+
{label}
|
63
|
+
</legend>
|
64
|
+
<div
|
65
|
+
aria-hidden
|
66
|
+
className={classNames(
|
67
|
+
styles.label,
|
68
|
+
!isLabelVisible && styles.isLabelHidden,
|
69
|
+
)}
|
70
|
+
id={id && `${id}__displayLabel`}
|
71
|
+
>
|
72
|
+
{label}
|
73
|
+
</div>
|
74
|
+
<div className={styles.field}>
|
75
|
+
<div
|
76
|
+
className={styles.inputGroup}
|
77
|
+
id={id && `${id}__group`}
|
78
|
+
>
|
79
|
+
<InputGroupContext.Provider
|
80
|
+
value={{
|
81
|
+
disabled,
|
82
|
+
layout,
|
83
|
+
size,
|
84
|
+
}}
|
85
|
+
>
|
86
|
+
{children}
|
87
|
+
</InputGroupContext.Provider>
|
88
|
+
</div>
|
89
|
+
{validationTexts && (
|
90
|
+
<ul
|
91
|
+
className={styles.validationText}
|
92
|
+
id={id && `${id}__validationTexts`}
|
93
|
+
>
|
94
|
+
{validationTexts.map((validationText) => (
|
95
|
+
<li key={validationText}>
|
96
|
+
<Text blockLevel>
|
97
|
+
{validationText}
|
98
|
+
</Text>
|
99
|
+
</li>
|
100
|
+
))}
|
101
|
+
</ul>
|
102
|
+
)}
|
103
|
+
</div>
|
104
|
+
</fieldset>
|
105
|
+
);
|
106
|
+
};
|
107
|
+
|
108
|
+
InputGroup.defaultProps = {
|
109
|
+
children: null,
|
110
|
+
disabled: false,
|
111
|
+
id: undefined,
|
112
|
+
isLabelVisible: true,
|
113
|
+
layout: 'vertical',
|
114
|
+
size: 'medium',
|
115
|
+
validationTexts: null,
|
116
|
+
};
|
117
|
+
|
118
|
+
InputGroup.propTypes = {
|
119
|
+
/**
|
120
|
+
* Supported elements to be grouped:
|
121
|
+
* * `Button`
|
122
|
+
* * `SelectField`
|
123
|
+
* * `TextField`
|
124
|
+
*
|
125
|
+
* If none are provided nothing is rendered.
|
126
|
+
*/
|
127
|
+
children: PropTypes.node,
|
128
|
+
/**
|
129
|
+
* If `true`, the whole input group with all nested inputs and buttons will be disabled.
|
130
|
+
*/
|
131
|
+
disabled: PropTypes.bool,
|
132
|
+
/**
|
133
|
+
* ID of the root HTML element.
|
134
|
+
*
|
135
|
+
* Also serves as base for ids of nested elements:
|
136
|
+
* * `<ID>__label`
|
137
|
+
* * `<ID>__displayLabel`
|
138
|
+
* * `<ID>__group`
|
139
|
+
* * `<ID>__validationTexts`
|
140
|
+
*/
|
141
|
+
id: PropTypes.string,
|
142
|
+
/**
|
143
|
+
* If `false`, the label will be visually hidden (but remains accessible by assistive
|
144
|
+
* technologies).
|
145
|
+
*/
|
146
|
+
isLabelVisible: PropTypes.bool,
|
147
|
+
/**
|
148
|
+
* Input group label.
|
149
|
+
*/
|
150
|
+
label: PropTypes.string.isRequired,
|
151
|
+
/**
|
152
|
+
* Layout of the group.
|
153
|
+
*
|
154
|
+
* Ignored if the component is rendered within `FormLayout` component
|
155
|
+
* as the value is inherited in such case.
|
156
|
+
*/
|
157
|
+
layout: PropTypes.oneOf(['horizontal', 'vertical']),
|
158
|
+
/**
|
159
|
+
* Size of the `children` elements.
|
160
|
+
*/
|
161
|
+
size: PropTypes.oneOf(['small', 'medium', 'large']),
|
162
|
+
/**
|
163
|
+
* An array of validation messages to be displayed.
|
164
|
+
*/
|
165
|
+
validationTexts: PropTypes.node,
|
166
|
+
};
|
167
|
+
|
168
|
+
export const InputGroupWithGlobalProps = withGlobalProps(InputGroup, 'InputGroup');
|
169
|
+
|
170
|
+
export default InputGroupWithGlobalProps;
|