@react-ui-org/react-ui 0.57.0 → 0.58.0

Sign up to get free protection for your applications and to get access to all the features.
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';