@react-ui-org/react-ui 0.57.0 → 0.58.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 (80) hide show
  1. package/.nvmrc +1 -1
  2. package/dist/react-ui.css +14 -14
  3. package/dist/react-ui.development.css +225 -14
  4. package/dist/react-ui.development.js +102 -62
  5. package/dist/react-ui.js +1 -1
  6. package/package.json +12 -1
  7. package/src/components/Alert/Alert.jsx +3 -5
  8. package/src/components/Alert/Alert.module.scss +3 -3
  9. package/src/components/Alert/README.md +22 -10
  10. package/src/components/Badge/Badge.jsx +1 -1
  11. package/src/components/Button/Button.jsx +1 -1
  12. package/src/components/ButtonGroup/ButtonGroup.jsx +1 -1
  13. package/src/components/Card/Card.jsx +1 -1
  14. package/src/components/Card/Card.module.scss +6 -5
  15. package/src/components/Card/CardBody.jsx +1 -1
  16. package/src/components/Card/CardFooter.jsx +1 -1
  17. package/src/components/Card/README.md +22 -0
  18. package/src/components/CheckboxField/CheckboxField.jsx +9 -3
  19. package/src/components/CheckboxField/README.md +110 -5
  20. package/src/components/FileInputField/FileInputField.jsx +1 -1
  21. package/src/components/FormLayout/FormLayout.jsx +1 -1
  22. package/src/components/FormLayout/FormLayoutCustomField.jsx +1 -1
  23. package/src/components/Grid/Grid.jsx +1 -1
  24. package/src/components/Grid/GridSpan.jsx +1 -1
  25. package/src/components/InputGroup/InputGroup.jsx +2 -2
  26. package/src/components/InputGroup/InputGroup.module.scss +9 -5
  27. package/src/components/Modal/Modal.jsx +1 -1
  28. package/src/components/Modal/ModalBody.jsx +1 -1
  29. package/src/components/Modal/ModalCloseButton.jsx +3 -5
  30. package/src/components/Modal/ModalContent.jsx +1 -1
  31. package/src/components/Modal/ModalFooter.jsx +1 -1
  32. package/src/components/Modal/ModalHeader.jsx +1 -1
  33. package/src/components/Modal/ModalTitle.jsx +1 -1
  34. package/src/components/Modal/README.md +18 -18
  35. package/src/components/Paper/Paper.jsx +1 -1
  36. package/src/components/Popover/Popover.jsx +58 -13
  37. package/src/components/Popover/Popover.module.scss +37 -9
  38. package/src/components/Popover/PopoverWrapper.jsx +1 -1
  39. package/src/components/Popover/README.md +60 -3
  40. package/src/components/Popover/_helpers/cleanPlacementStyle.js +20 -0
  41. package/src/components/Radio/README.md +103 -0
  42. package/src/components/Radio/Radio.jsx +9 -3
  43. package/src/components/Radio/Radio.module.scss +4 -0
  44. package/src/components/ScrollView/ScrollView.jsx +3 -5
  45. package/src/components/SelectField/README.md +103 -0
  46. package/src/components/SelectField/SelectField.jsx +9 -3
  47. package/src/components/Table/Table.jsx +1 -1
  48. package/src/components/Tabs/Tabs.jsx +1 -1
  49. package/src/components/Tabs/TabsItem.jsx +1 -1
  50. package/src/components/Text/Text.jsx +1 -1
  51. package/src/components/TextArea/TextArea.jsx +1 -1
  52. package/src/components/TextField/README.md +14 -2
  53. package/src/components/TextField/TextField.jsx +1 -1
  54. package/src/components/TextLink/README.md +10 -3
  55. package/src/components/TextLink/TextLink.jsx +1 -1
  56. package/src/components/TextLink/_theme.scss +3 -3
  57. package/src/components/Toggle/README.md +83 -1
  58. package/src/components/Toggle/Toggle.jsx +9 -3
  59. package/src/components/Toolbar/Toolbar.jsx +1 -1
  60. package/src/components/Toolbar/ToolbarGroup.jsx +1 -1
  61. package/src/components/Toolbar/ToolbarItem.jsx +1 -1
  62. package/src/components/_helpers/resolveContextOrProp.js +6 -3
  63. package/src/index.js +3 -2
  64. package/src/providers/globalProps/GlobalPropsContext.jsx +5 -0
  65. package/src/providers/globalProps/GlobalPropsProvider.jsx +33 -0
  66. package/src/providers/globalProps/index.js +3 -0
  67. package/src/{provider → providers/globalProps}/withGlobalProps.jsx +16 -16
  68. package/src/providers/translations/TranslationsContext.jsx +6 -0
  69. package/src/providers/translations/TranslationsProvider.jsx +33 -0
  70. package/src/providers/translations/index.js +2 -0
  71. package/src/styles/elements/_links.scss +7 -2
  72. package/src/styles/theme/_form-fields.scss +19 -0
  73. package/src/styles/theme/_links.scss +4 -3
  74. package/src/styles/tools/_collections.scss +79 -5
  75. package/src/styles/tools/form-fields/_foundation.scss +6 -4
  76. package/src/styles/tools/form-fields/_variants.scss +5 -1
  77. package/src/theme.scss +2 -1
  78. package/src/provider/RUIContext.jsx +0 -9
  79. package/src/provider/RUIProvider.jsx +0 -42
  80. package/src/provider/index.js +0 -3
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@react-ui-org/react-ui",
3
3
  "description": "React UI is a themeable UI library for React apps.",
4
- "version": "0.57.0",
4
+ "version": "0.58.0",
5
5
  "keywords": [
6
6
  "react",
7
7
  "ui",
@@ -31,6 +31,17 @@
31
31
  "engines": {
32
32
  "node": ">=20"
33
33
  },
34
+ "devEngines": {
35
+ "runtime": {
36
+ "name": "node",
37
+ "version": "22.x",
38
+ "onFail": "error"
39
+ },
40
+ "packageManager": {
41
+ "name": "npm",
42
+ "onFail": "error"
43
+ }
44
+ },
34
45
  "scripts": {
35
46
  "build": "webpack --mode=production && webpack --mode=development",
36
47
  "copy": "npm run copy:css && npm run copy:js",
@@ -1,9 +1,7 @@
1
1
  import PropTypes from 'prop-types';
2
2
  import React, { useContext } from 'react';
3
- import {
4
- RUIContext,
5
- withGlobalProps,
6
- } from '../../provider';
3
+ import { withGlobalProps } from '../../providers/globalProps';
4
+ import { TranslationsContext } from '../../providers/translations';
7
5
  import { classNames } from '../../utils/classNames';
8
6
  import { transferProps } from '../../utils/transferProps';
9
7
  import { getRootColorClassName } from '../_helpers/getRootColorClassName';
@@ -17,7 +15,7 @@ export const Alert = ({
17
15
  onClose,
18
16
  ...restProps
19
17
  }) => {
20
- const { translations } = useContext(RUIContext);
18
+ const translations = useContext(TranslationsContext);
21
19
 
22
20
  return (
23
21
  <div
@@ -25,8 +25,8 @@
25
25
  padding: theme.$padding;
26
26
  }
27
27
 
28
- .close,
29
- .icon {
28
+ .icon,
29
+ .close {
30
30
  height: settings.$min-height;
31
31
  color: var(--rui-local-foreground-color);
32
32
  }
@@ -46,7 +46,6 @@
46
46
  line-height: settings.$line-height;
47
47
  }
48
48
 
49
- .message a,
50
49
  .message strong {
51
50
  font-weight: theme.$emphasis-font-weight;
52
51
  color: var(--rui-local-foreground-color);
@@ -73,6 +72,7 @@
73
72
  $variant-name: "color",
74
73
  $variant-value: $color,
75
74
  $properties: settings.$themeable-properties,
75
+ $inherit-link-color: true,
76
76
  );
77
77
  }
78
78
  }
@@ -41,6 +41,8 @@ Success alerts confirm that an operation has been processed successfully.
41
41
  ```docoff-react-preview
42
42
  <Alert color="success">
43
43
  <strong>Success:</strong> Settings have been successfully saved.
44
+ {' '}
45
+ <TextLink href="/" label="Undo" />
44
46
  </Alert>
45
47
  ```
46
48
 
@@ -53,7 +55,7 @@ suggest an action to resolve the problem.
53
55
  <Alert color="warning">
54
56
  <strong>Warning:</strong> Your credit card is going to expire soon.
55
57
  {' '}
56
- <a href="/">Update my payment options</a>
58
+ <TextLink href="/" label="Update my payment options" />
57
59
  </Alert>
58
60
  ```
59
61
 
@@ -68,7 +70,7 @@ problem.
68
70
  <strong>Error:</strong> Cannot connect to the server. Is your internet
69
71
  connection working fine?
70
72
  {' '}
71
- <a href="/">Try again</a>
73
+ <TextLink href="/" label="Try again" />
72
74
  </Alert>
73
75
  ```
74
76
 
@@ -80,6 +82,8 @@ This kind of alert can be used to display helpful information.
80
82
  <Alert color="help">
81
83
  <strong>Help:</strong> You should choose a password you don&apos;t use
82
84
  anywhere else.
85
+ {' '}
86
+ <TextLink href="/" label="Help me choose" />
83
87
  </Alert>
84
88
  ```
85
89
 
@@ -90,6 +94,8 @@ Another common, informative alert.
90
94
  ```docoff-react-preview
91
95
  <Alert color="info">
92
96
  <strong>Info:</strong> This feature depends on user&apos;s OS preferences.
97
+ {' '}
98
+ <TextLink href="/" label="Open preferences" />
93
99
  </Alert>
94
100
  ```
95
101
 
@@ -100,6 +106,8 @@ Neutral informative alert.
100
106
  ```docoff-react-preview
101
107
  <Alert>
102
108
  <strong>Note:</strong> This feature may not be available in all regions.
109
+ {' '}
110
+ <TextLink href="/" label="Show list of regions" />
103
111
  </Alert>
104
112
  ```
105
113
 
@@ -111,6 +119,8 @@ Light alert variant.
111
119
  <docoff-placeholder dark>
112
120
  <Alert color="light">
113
121
  <strong>Light alert:</strong> Stands out on dark backgrounds.
122
+ {' '}
123
+ <TextLink href="/" label="This is a link" />
114
124
  </Alert>
115
125
  </docoff-placeholder>
116
126
  ```
@@ -122,6 +132,8 @@ Dark alert variant.
122
132
  ```docoff-react-preview
123
133
  <Alert color="dark">
124
134
  <strong>Dark alert:</strong> Stands out on light backgrounds.
135
+ {' '}
136
+ <TextLink href="/" label="This is a link" />
125
137
  </Alert>
126
138
  ```
127
139
 
@@ -190,14 +202,14 @@ helps to improve its accessibility.
190
202
 
191
203
  ### Common Theming Options
192
204
 
193
- | Custom Property | Description |
194
- |------------------------------------------------------|--------------------------------------------------------------|
195
- | `--rui-Alert__padding` | Padding between border and message |
196
- | `--rui-Alert__font-weight` | Message font weight |
197
- | `--rui-Alert__border-width` | Border width |
198
- | `--rui-Alert__border-radius` | Corner radius |
199
- | `--rui-Alert__emphasis__font-weight` | Font weight of text emphasised with `<strong>` |
200
- | `--rui-Alert__stripe__width` | Width of the border at the start of the Alert |
205
+ | Custom Property | Description |
206
+ |--------------------------------------|------------------------------------------------|
207
+ | `--rui-Alert__padding` | Padding between border and message |
208
+ | `--rui-Alert__font-weight` | Message font weight |
209
+ | `--rui-Alert__border-width` | Border width |
210
+ | `--rui-Alert__border-radius` | Corner radius |
211
+ | `--rui-Alert__emphasis__font-weight` | Font weight of text emphasised with `<strong>` |
212
+ | `--rui-Alert__stripe__width` | Width of the border at the start of the Alert |
201
213
 
202
214
  ### Theming Variants
203
215
 
@@ -1,6 +1,6 @@
1
1
  import PropTypes from 'prop-types';
2
2
  import React from 'react';
3
- import { withGlobalProps } from '../../provider';
3
+ import { withGlobalProps } from '../../providers/globalProps';
4
4
  import { classNames } from '../../utils/classNames';
5
5
  import { transferProps } from '../../utils/transferProps';
6
6
  import { getRootColorClassName } from '../_helpers/getRootColorClassName';
@@ -1,6 +1,6 @@
1
1
  import PropTypes from 'prop-types';
2
2
  import React, { useContext } from 'react';
3
- import { withGlobalProps } from '../../provider';
3
+ import { withGlobalProps } from '../../providers/globalProps';
4
4
  import { classNames } from '../../utils/classNames';
5
5
  import { transferProps } from '../../utils/transferProps';
6
6
  import { getRootColorClassName } from '../_helpers/getRootColorClassName';
@@ -2,7 +2,7 @@ import PropTypes from 'prop-types';
2
2
  import React, {
3
3
  useMemo,
4
4
  } from 'react';
5
- import { withGlobalProps } from '../../provider';
5
+ import { withGlobalProps } from '../../providers/globalProps';
6
6
  import { classNames } from '../../utils/classNames';
7
7
  import { transferProps } from '../../utils/transferProps';
8
8
  import { getRootPriorityClassName } from '../_helpers/getRootPriorityClassName';
@@ -1,6 +1,6 @@
1
1
  import PropTypes from 'prop-types';
2
2
  import React from 'react';
3
- import { withGlobalProps } from '../../provider';
3
+ import { withGlobalProps } from '../../providers/globalProps';
4
4
  import { classNames } from '../../utils/classNames';
5
5
  import { transferProps } from '../../utils/transferProps';
6
6
  import { getRootColorClassName } from '../_helpers/getRootColorClassName';
@@ -34,18 +34,19 @@
34
34
  box-shadow: theme.$raised-box-shadow;
35
35
  }
36
36
 
37
+ .isRootDisabled {
38
+ background-color: theme.$disabled-background-color;
39
+ opacity: theme.$disabled-opacity;
40
+ }
41
+
37
42
  @each $color in settings.$colors {
38
43
  @include collections.generate-class(
39
44
  $prefix: "rui-",
40
45
  $component-name: "Card",
41
46
  $variant-name: "color",
42
47
  $variant-value: $color,
48
+ $inherit-link-color: true,
43
49
  $properties: settings.$themeable-properties,
44
50
  );
45
51
  }
46
-
47
- .isRootDisabled {
48
- background-color: theme.$disabled-background-color;
49
- opacity: theme.$disabled-opacity;
50
- }
51
52
  }
@@ -1,6 +1,6 @@
1
1
  import PropTypes from 'prop-types';
2
2
  import React from 'react';
3
- import { withGlobalProps } from '../../provider';
3
+ import { withGlobalProps } from '../../providers/globalProps';
4
4
  import { transferProps } from '../../utils/transferProps';
5
5
  import styles from './Card.module.scss';
6
6
 
@@ -1,7 +1,7 @@
1
1
  import PropTypes from 'prop-types';
2
2
  import React from 'react';
3
- import { withGlobalProps } from '../../provider';
4
3
  import { transferProps } from '../../utils/transferProps';
4
+ import { withGlobalProps } from '../../providers/globalProps';
5
5
  import { isChildrenEmpty } from '../_helpers/isChildrenEmpty';
6
6
  import styles from './Card.module.scss';
7
7
 
@@ -154,6 +154,8 @@ To cover all possible needs of your project, Card is available in colors from
154
154
  <Card color="success">
155
155
  <CardBody>
156
156
  Hello! I&apos;m success variant of card.
157
+ {' '}
158
+ <TextLink href="/" label="This is a link" />
157
159
  </CardBody>
158
160
  <CardFooter>
159
161
  <Button label="Read more" priority="outline" color="success" />
@@ -162,6 +164,8 @@ To cover all possible needs of your project, Card is available in colors from
162
164
  <Card color="warning">
163
165
  <CardBody>
164
166
  Hello! I&apos;m warning variant of card.
167
+ {' '}
168
+ <TextLink href="/" label="This is a link" />
165
169
  </CardBody>
166
170
  <CardFooter>
167
171
  <Button label="Read more" priority="outline" color="warning" />
@@ -170,6 +174,8 @@ To cover all possible needs of your project, Card is available in colors from
170
174
  <Card color="danger">
171
175
  <CardBody>
172
176
  Hello! I&apos;m danger variant of card.
177
+ {' '}
178
+ <TextLink href="/" label="This is a link" />
173
179
  </CardBody>
174
180
  <CardFooter>
175
181
  <Button label="Read more" priority="outline" color="danger" />
@@ -178,6 +184,8 @@ To cover all possible needs of your project, Card is available in colors from
178
184
  <Card color="help">
179
185
  <CardBody>
180
186
  Hello! I&apos;m help variant of card.
187
+ {' '}
188
+ <TextLink href="/" label="This is a link" />
181
189
  </CardBody>
182
190
  <CardFooter>
183
191
  <Button label="Read more" priority="outline" color="help" />
@@ -186,6 +194,8 @@ To cover all possible needs of your project, Card is available in colors from
186
194
  <Card color="info">
187
195
  <CardBody>
188
196
  Hello! I&apos;m info variant of card.
197
+ {' '}
198
+ <TextLink href="/" label="This is a link" />
189
199
  </CardBody>
190
200
  <CardFooter>
191
201
  <Button label="Read more" priority="outline" color="info" />
@@ -194,6 +204,8 @@ To cover all possible needs of your project, Card is available in colors from
194
204
  <Card color="note">
195
205
  <CardBody>
196
206
  Hello! I&apos;m note variant of card.
207
+ {' '}
208
+ <TextLink href="/" label="This is a link" />
197
209
  </CardBody>
198
210
  <CardFooter>
199
211
  <Button label="Read more" priority="outline" color="note" />
@@ -202,6 +214,8 @@ To cover all possible needs of your project, Card is available in colors from
202
214
  <Card>
203
215
  <CardBody>
204
216
  Hello! I&apos;m light (default) variant of card.
217
+ {' '}
218
+ <TextLink href="/" label="This is a link" />
205
219
  </CardBody>
206
220
  <CardFooter>
207
221
  <Button label="Read more" priority="outline" color="dark" />
@@ -210,6 +224,8 @@ To cover all possible needs of your project, Card is available in colors from
210
224
  <Card color="dark">
211
225
  <CardBody>
212
226
  Hello! I&apos;m dark variant of card.
227
+ {' '}
228
+ <TextLink href="/" label="This is a link" />
213
229
  </CardBody>
214
230
  <CardFooter>
215
231
  <Button label="Read more" priority="outline" color="light" />
@@ -228,6 +244,8 @@ its interactive elements to disallow user's interaction.
228
244
  <Card disabled>
229
245
  <CardBody>
230
246
  Hello! I&apos;m a disabled card.
247
+ {' '}
248
+ <TextLink href="/" label="This is a link" />
231
249
  </CardBody>
232
250
  <CardFooter>
233
251
  <Button label="Read more" priority="outline" disabled />
@@ -236,6 +254,8 @@ its interactive elements to disallow user's interaction.
236
254
  <Card disabled raised>
237
255
  <CardBody>
238
256
  Hello! I&apos;m a disabled raised card.
257
+ {' '}
258
+ <TextLink href="/" label="This is a link" />
239
259
  </CardBody>
240
260
  <CardFooter>
241
261
  <Button label="Read more" priority="outline" disabled />
@@ -244,6 +264,8 @@ its interactive elements to disallow user's interaction.
244
264
  <Card color="success" disabled>
245
265
  <CardBody>
246
266
  Hello! I&apos;m a disabled success variant of card.
267
+ {' '}
268
+ <TextLink href="/" label="This is a link" />
247
269
  </CardBody>
248
270
  <CardFooter>
249
271
  <Button label="Read more" priority="outline" color="success" disabled />
@@ -1,6 +1,6 @@
1
1
  import PropTypes from 'prop-types';
2
2
  import React, { useContext } from 'react';
3
- import { withGlobalProps } from '../../provider';
3
+ import { withGlobalProps } from '../../providers/globalProps';
4
4
  import { classNames } from '../../utils/classNames';
5
5
  import { transferProps } from '../../utils/transferProps';
6
6
  import { getRootValidationStateClassName } from '../_helpers/getRootValidationStateClassName';
@@ -15,6 +15,7 @@ export const CheckboxField = React.forwardRef((props, ref) => {
15
15
  isLabelVisible,
16
16
  label,
17
17
  labelPosition,
18
+ renderAsRequired,
18
19
  required,
19
20
  validationState,
20
21
  validationText,
@@ -30,7 +31,7 @@ export const CheckboxField = React.forwardRef((props, ref) => {
30
31
  context && context.layout === 'horizontal' ? styles.isRootLayoutHorizontal : styles.isRootLayoutVertical,
31
32
  labelPosition === 'before' && styles.hasRootLabelBefore,
32
33
  disabled && styles.isRootDisabled,
33
- required && styles.isRootRequired,
34
+ (renderAsRequired || required) && styles.isRootRequired,
34
35
  getRootValidationStateClassName(validationState, styles),
35
36
  )}
36
37
  htmlFor={id}
@@ -82,6 +83,7 @@ CheckboxField.defaultProps = {
82
83
  id: undefined,
83
84
  isLabelVisible: true,
84
85
  labelPosition: 'after',
86
+ renderAsRequired: false,
85
87
  required: false,
86
88
  validationState: null,
87
89
  validationText: null,
@@ -120,7 +122,11 @@ CheckboxField.propTypes = {
120
122
  */
121
123
  labelPosition: PropTypes.oneOf(['before', 'after']),
122
124
  /**
123
- * If `true`, the input will be required.
125
+ * If `true`, the input will be rendered as if it was required.
126
+ */
127
+ renderAsRequired: PropTypes.bool,
128
+ /**
129
+ * If `true`, the input will be made and rendered as required, regardless of the `renderAsRequired` prop.
124
130
  */
125
131
  required: PropTypes.bool,
126
132
  /**
@@ -18,7 +18,13 @@ React.createElement(() => {
18
18
  return (
19
19
  <CheckboxField
20
20
  checked={agree}
21
- label="I agree"
21
+ label={(
22
+ <>
23
+ I have read and agree with
24
+ {' '}
25
+ <TextLink href="#" label="terms and conditions" />
26
+ </>
27
+ )}
22
28
  onChange={() => setAgree(!agree)}
23
29
  />
24
30
  );
@@ -132,20 +138,44 @@ React.createElement(() => {
132
138
  <>
133
139
  <CheckboxField
134
140
  checked={agree}
135
- label="I have read and agree with terms and conditions"
141
+ label={(
142
+ <>
143
+ I have read and agree with
144
+ {' '}
145
+ <TextLink href="#" label="terms and conditions" />
146
+ </>
147
+ )}
136
148
  onChange={() => setAgree(!agree)}
137
149
  validationState="valid"
138
150
  />
139
151
  <CheckboxField
140
152
  checked={agree}
141
- label="I have read and agree with terms and conditions"
153
+ label={(
154
+ <>
155
+ I have read and agree with
156
+ {' '}
157
+ <TextLink href="#" label="terms and conditions" />
158
+ </>
159
+ )}
142
160
  onChange={() => setAgree(!agree)}
143
161
  validationState="warning"
144
- validationText="Please wait 10 minutes until we verify your data."
162
+ validationText={(
163
+ <>
164
+ Please wait 10 minutes until we verify your data.
165
+ {' '}
166
+ <TextLink href="#" label="Cancel" />
167
+ </>
168
+ )}
145
169
  />
146
170
  <CheckboxField
147
171
  checked={agree}
148
- label="I have read and agree with terms and conditions"
172
+ label={(
173
+ <>
174
+ I have read and agree with
175
+ {' '}
176
+ <TextLink href="#" label="terms and conditions" />
177
+ </>
178
+ )}
149
179
  onChange={() => setAgree(!agree)}
150
180
  required
151
181
  validationState="invalid"
@@ -156,6 +186,81 @@ React.createElement(() => {
156
186
  });
157
187
  ```
158
188
 
189
+ ### Required State
190
+
191
+ The required state indicates that the input is mandatory. Required fields
192
+ display an asterisk `*` after the label by default.
193
+
194
+ ```docoff-react-preview
195
+ React.createElement(() => {
196
+ const [agree, setAgree] = React.useState(true);
197
+ return (
198
+ <CheckboxField
199
+ checked={agree}
200
+ label="I agree"
201
+ onChange={() => setAgree(!agree)}
202
+ required
203
+ />
204
+ );
205
+ });
206
+ ```
207
+
208
+ #### Styling the Required State
209
+
210
+ All form fields in React UI can be
211
+ [styled](/docs/customize/theming/forms/#required-state)
212
+ to indicate the required state.
213
+
214
+ However, you may find yourself in a situation where a form field is valid in
215
+ both checked and unchecked states, for example to turn on or off a feature.
216
+ If your project uses the label color as the primary means to indicate the
217
+ required state of input fields and the usual asterisk `*` is omitted, you may
218
+ want to keep the label color consistent for both states to avoid confusion.
219
+
220
+ For this edge case, there is the `renderAsRequired` prop:
221
+
222
+ ```docoff-react-preview
223
+ React.createElement(() => {
224
+ const [optional, setOptional] = React.useState(false);
225
+ const [renderAsRequired, setRenderAsRequired] = React.useState(false);
226
+ return (
227
+ <React.Fragment>
228
+ <style>
229
+ {`
230
+ .example {
231
+ display: flex;
232
+ flex-wrap: wrap;
233
+ gap: 1rem 0.5rem;
234
+ }
235
+
236
+ .example--themed-form-fields {
237
+ --rui-FormField__label__color: var(--rui-color-text-secondary);
238
+ --rui-FormField--required__label__color: var(--rui-color-text-primary);
239
+ --rui-FormField--required__sign: '';
240
+ }
241
+ `}
242
+ </style>
243
+ <div class="example example--themed-form-fields">
244
+ <CheckboxField
245
+ checked={optional}
246
+ label="This field is optional"
247
+ onChange={() => setOptional(!optional)}
248
+ />
249
+ <CheckboxField
250
+ checked={renderAsRequired}
251
+ label="This field is optional but looks like required"
252
+ onChange={() => setRenderAsRequired(!renderAsRequired)}
253
+ renderAsRequired
254
+ />
255
+ </div>
256
+ </React.Fragment>
257
+ );
258
+ });
259
+ ```
260
+
261
+ It renders the field as if it was required, but doesn't add the `required`
262
+ attribute to the actual input.
263
+
159
264
  ### Disabled State
160
265
 
161
266
  Disabled state makes the input unavailable.
@@ -1,6 +1,6 @@
1
1
  import PropTypes from 'prop-types';
2
2
  import React, { useContext } from 'react';
3
- import { withGlobalProps } from '../../provider';
3
+ import { withGlobalProps } from '../../providers/globalProps';
4
4
  import { classNames } from '../../utils/classNames';
5
5
  import { transferProps } from '../../utils/transferProps';
6
6
  import { getRootValidationStateClassName } from '../_helpers/getRootValidationStateClassName';
@@ -1,6 +1,6 @@
1
1
  import PropTypes from 'prop-types';
2
2
  import React, { useMemo } from 'react';
3
- import { withGlobalProps } from '../../provider';
3
+ import { withGlobalProps } from '../../providers/globalProps';
4
4
  import { classNames } from '../../utils/classNames';
5
5
  import { transferProps } from '../../utils/transferProps';
6
6
  import { isChildrenEmpty } from '../_helpers/isChildrenEmpty';
@@ -1,6 +1,6 @@
1
1
  import PropTypes from 'prop-types';
2
2
  import React, { useContext } from 'react';
3
- import { withGlobalProps } from '../../provider';
3
+ import { withGlobalProps } from '../../providers/globalProps';
4
4
  import { classNames } from '../../utils/classNames';
5
5
  import { transferProps } from '../../utils/transferProps';
6
6
  import { getRootSizeClassName } from '../_helpers/getRootSizeClassName';
@@ -1,6 +1,6 @@
1
1
  import PropTypes from 'prop-types';
2
2
  import React from 'react';
3
- import { withGlobalProps } from '../../provider';
3
+ import { withGlobalProps } from '../../providers/globalProps';
4
4
  import { transferProps } from '../../utils/transferProps';
5
5
  import { isChildrenEmpty } from '../_helpers/isChildrenEmpty';
6
6
  import { generateResponsiveCustomProperties } from './_helpers/generateResponsiveCustomProperties';
@@ -1,6 +1,6 @@
1
1
  import PropTypes from 'prop-types';
2
2
  import React from 'react';
3
- import { withGlobalProps } from '../../provider';
3
+ import { withGlobalProps } from '../../providers/globalProps';
4
4
  import { transferProps } from '../../utils/transferProps';
5
5
  import { isChildrenEmpty } from '../_helpers/isChildrenEmpty';
6
6
  import { generateResponsiveCustomProperties } from './_helpers/generateResponsiveCustomProperties';
@@ -3,8 +3,7 @@ import React, {
3
3
  useContext,
4
4
  useMemo,
5
5
  } from 'react';
6
- import { Text } from '../Text';
7
- import { withGlobalProps } from '../../provider';
6
+ import { withGlobalProps } from '../../providers/globalProps';
8
7
  import { classNames } from '../../utils/classNames';
9
8
  import { transferProps } from '../../utils/transferProps';
10
9
  import { getRootSizeClassName } from '../_helpers/getRootSizeClassName';
@@ -12,6 +11,7 @@ import { getRootValidationStateClassName } from '../_helpers/getRootValidationSt
12
11
  import { isChildrenEmpty } from '../_helpers/isChildrenEmpty';
13
12
  import { resolveContextOrProp } from '../_helpers/resolveContextOrProp';
14
13
  import { FormLayoutContext } from '../FormLayout';
14
+ import { Text } from '../Text';
15
15
  import { InputGroupContext } from './InputGroupContext';
16
16
  import styles from './InputGroup.module.scss';
17
17
 
@@ -1,7 +1,9 @@
1
1
  // 1. The class name is intentionally singular because it's targeted by other mixins too.
2
2
  // 2. Use a block-level display mode to prevent extra white space below grouped inputs in Safari.
3
- // 3. Prevent individual inputs from overlapping inside narrow containers.
4
- // 4. Legends are tricky to style, let's use a `div` instead.
3
+ // 3. Let wide input groups honor the minimum input width and overflow horizontally without wrapping and distorting
4
+ // the inputs.
5
+ // 4. Prevent individual inputs from overlapping inside narrow containers.
6
+ // 5. Legends are tricky to style, let's use a `div` instead.
5
7
  // https://developer.mozilla.org/en-US/docs/Web/HTML/Element/fieldset#styling_with_css
6
8
 
7
9
  @use "../../styles/tools/form-fields/box-field-elements";
@@ -19,12 +21,12 @@
19
21
  @include foundation.fieldset();
20
22
  }
21
23
 
22
- // 4.
24
+ // 5.
23
25
  .legend {
24
26
  @include accessibility.hide-text();
25
27
  }
26
28
 
27
- // 4.
29
+ // 5.
28
30
  .label {
29
31
  @include foundation.label();
30
32
  }
@@ -63,11 +65,13 @@
63
65
  .isRootLayoutVertical,
64
66
  .isRootLayoutHorizontal {
65
67
  @include box-field-layout.vertical();
68
+
69
+ max-width: none; // 3.
66
70
  }
67
71
 
68
72
  .isRootLayoutVertical .field,
69
73
  .isRootLayoutHorizontal .field {
70
- max-width: none; // 3.
74
+ max-width: none; // 4.
71
75
  }
72
76
 
73
77
  .isRootLayoutHorizontal {
@@ -1,7 +1,7 @@
1
1
  import PropTypes from 'prop-types';
2
2
  import React, { useRef } from 'react';
3
3
  import { createPortal } from 'react-dom';
4
- import { withGlobalProps } from '../../provider';
4
+ import { withGlobalProps } from '../../providers/globalProps';
5
5
  import { classNames } from '../../utils/classNames';
6
6
  import { transferProps } from '../../utils/transferProps';
7
7
  import { getPositionClassName } from './_helpers/getPositionClassName';
@@ -1,6 +1,6 @@
1
1
  import PropTypes from 'prop-types';
2
2
  import React from 'react';
3
- import { withGlobalProps } from '../../provider';
3
+ import { withGlobalProps } from '../../providers/globalProps';
4
4
  import { classNames } from '../../utils/classNames';
5
5
  import { transferProps } from '../../utils/transferProps';
6
6
  import { isChildrenEmpty } from '../_helpers/isChildrenEmpty';