@react-ui-org/react-ui 0.53.0 → 0.55.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 (149) hide show
  1. package/README.md +7 -5
  2. package/dist/react-ui.css +36 -38
  3. package/dist/react-ui.development.css +10800 -0
  4. package/dist/react-ui.development.js +1568 -0
  5. package/dist/react-ui.js +1 -1
  6. package/package.json +7 -4
  7. package/src/components/Alert/Alert.jsx +1 -1
  8. package/src/components/Alert/Alert.module.scss +100 -0
  9. package/src/components/Alert/README.md +9 -7
  10. package/src/components/Badge/Badge.jsx +1 -1
  11. package/src/components/Badge/Badge.module.scss +109 -0
  12. package/src/components/Badge/README.md +9 -7
  13. package/src/components/Button/Button.jsx +1 -1
  14. package/src/components/Button/README.md +9 -7
  15. package/src/components/Button/_base.scss +117 -115
  16. package/src/components/Button/_priorities.scss +135 -133
  17. package/src/components/ButtonGroup/ButtonGroup.jsx +1 -1
  18. package/src/components/ButtonGroup/ButtonGroup.module.scss +35 -0
  19. package/src/components/ButtonGroup/README.md +10 -8
  20. package/src/components/Card/Card.jsx +1 -1
  21. package/src/components/Card/Card.module.scss +72 -0
  22. package/src/components/Card/CardBody.jsx +1 -1
  23. package/src/components/Card/CardFooter.jsx +1 -1
  24. package/src/components/Card/README.md +9 -7
  25. package/src/components/CheckboxField/CheckboxField.jsx +1 -1
  26. package/src/components/CheckboxField/CheckboxField.module.scss +63 -0
  27. package/src/components/CheckboxField/README.md +10 -8
  28. package/src/components/FileInputField/FileInputField.jsx +1 -1
  29. package/src/components/FileInputField/FileInputField.module.scss +65 -0
  30. package/src/components/FileInputField/README.md +10 -8
  31. package/src/components/FormLayout/FormLayout.jsx +1 -1
  32. package/src/components/FormLayout/{FormLayout.scss → FormLayout.module.scss} +30 -28
  33. package/src/components/FormLayout/FormLayoutCustomField.jsx +1 -1
  34. package/src/components/FormLayout/FormLayoutCustomField.module.scss +65 -0
  35. package/src/components/FormLayout/README.md +11 -9
  36. package/src/components/Grid/Grid.jsx +1 -1
  37. package/src/components/Grid/Grid.module.scss +66 -0
  38. package/src/components/Grid/GridSpan.jsx +1 -1
  39. package/src/components/Grid/README.md +11 -8
  40. package/src/components/InputGroup/InputGroup.jsx +9 -1
  41. package/src/components/InputGroup/InputGroup.module.scss +93 -0
  42. package/src/components/InputGroup/README.md +27 -10
  43. package/src/components/Modal/Modal.jsx +1 -1
  44. package/src/components/Modal/Modal.module.scss +80 -0
  45. package/src/components/Modal/ModalBody.jsx +1 -1
  46. package/src/components/Modal/ModalBody.module.scss +20 -0
  47. package/src/components/Modal/ModalCloseButton.jsx +1 -1
  48. package/src/components/Modal/ModalCloseButton.module.scss +20 -0
  49. package/src/components/Modal/ModalContent.jsx +1 -1
  50. package/src/components/Modal/ModalContent.module.scss +7 -0
  51. package/src/components/Modal/ModalFooter.jsx +1 -1
  52. package/src/components/Modal/ModalFooter.module.scss +37 -0
  53. package/src/components/Modal/ModalHeader.jsx +1 -1
  54. package/src/components/Modal/ModalHeader.module.scss +32 -0
  55. package/src/components/Modal/ModalTitle.jsx +1 -1
  56. package/src/components/Modal/ModalTitle.module.scss +12 -0
  57. package/src/components/Modal/README.md +17 -14
  58. package/src/components/Paper/Paper.jsx +1 -1
  59. package/src/components/Paper/Paper.module.scss +19 -0
  60. package/src/components/Paper/README.md +9 -7
  61. package/src/components/Popover/Popover.jsx +1 -1
  62. package/src/components/Popover/Popover.module.scss +238 -0
  63. package/src/components/Popover/PopoverWrapper.jsx +1 -2
  64. package/src/components/Popover/PopoverWrapper.module.scss +5 -0
  65. package/src/components/Popover/README.md +9 -7
  66. package/src/components/Radio/README.md +12 -10
  67. package/src/components/Radio/Radio.jsx +1 -1
  68. package/src/components/Radio/Radio.module.scss +85 -0
  69. package/src/components/ScrollView/README.md +10 -8
  70. package/src/components/ScrollView/ScrollView.jsx +1 -1
  71. package/src/components/ScrollView/ScrollView.module.scss +233 -0
  72. package/src/components/SelectField/README.md +10 -8
  73. package/src/components/SelectField/SelectField.jsx +1 -1
  74. package/src/components/SelectField/SelectField.module.scss +111 -0
  75. package/src/components/Table/README.md +10 -8
  76. package/src/components/Table/Table.jsx +1 -1
  77. package/src/components/Table/Table.module.scss +30 -0
  78. package/src/components/Table/_components/TableBodyCell/TableBodyCell.jsx +1 -1
  79. package/src/components/Table/_components/TableCell.module.scss +28 -0
  80. package/src/components/Table/_components/TableHeaderCell/TableHeaderCell.jsx +1 -1
  81. package/src/components/Tabs/README.md +16 -10
  82. package/src/components/Tabs/Tabs.jsx +1 -1
  83. package/src/components/Tabs/Tabs.module.scss +31 -0
  84. package/src/components/Tabs/TabsItem.jsx +1 -1
  85. package/src/components/Tabs/TabsItem.module.scss +119 -0
  86. package/src/components/Text/README.md +15 -9
  87. package/src/components/Text/Text.jsx +1 -1
  88. package/src/components/Text/Text.module.scss +42 -0
  89. package/src/components/TextArea/README.md +10 -8
  90. package/src/components/TextArea/TextArea.jsx +1 -1
  91. package/src/components/TextArea/TextArea.module.scss +97 -0
  92. package/src/components/TextField/README.md +13 -8
  93. package/src/components/TextField/TextField.jsx +1 -1
  94. package/src/components/TextField/TextField.module.scss +109 -0
  95. package/src/components/TextLink/README.md +10 -8
  96. package/src/components/TextLink/TextLink.jsx +1 -1
  97. package/src/components/TextLink/TextLink.module.scss +18 -0
  98. package/src/components/Toggle/README.md +10 -8
  99. package/src/components/Toggle/Toggle.jsx +1 -1
  100. package/src/components/Toggle/Toggle.module.scss +63 -0
  101. package/src/components/Toolbar/README.md +9 -7
  102. package/src/components/Toolbar/Toolbar.jsx +1 -1
  103. package/src/components/Toolbar/Toolbar.module.scss +85 -0
  104. package/src/components/Toolbar/ToolbarGroup.jsx +1 -1
  105. package/src/components/Toolbar/ToolbarItem.jsx +1 -1
  106. package/src/components/_helpers/transferProps.js +47 -7
  107. package/src/foundation.scss +22 -17
  108. package/src/helpers.scss +12 -8
  109. package/src/index.js +3 -4
  110. package/src/index.scss +7 -0
  111. package/src/layers.scss +4 -0
  112. package/src/styles/elements/_page.scss +0 -4
  113. package/src/styles/helpers/_animation.scss +2 -2
  114. package/src/styles/tools/_utilities.scss +1 -1
  115. package/src/theme.scss +1040 -1038
  116. package/CODEOWNERS +0 -23
  117. package/src/components/Alert/Alert.scss +0 -98
  118. package/src/components/Badge/Badge.scss +0 -107
  119. package/src/components/ButtonGroup/ButtonGroup.scss +0 -33
  120. package/src/components/Card/Card.scss +0 -70
  121. package/src/components/CheckboxField/CheckboxField.scss +0 -61
  122. package/src/components/FileInputField/FileInputField.scss +0 -63
  123. package/src/components/FormLayout/FormLayoutCustomField.scss +0 -63
  124. package/src/components/Grid/Grid.scss +0 -63
  125. package/src/components/InputGroup/InputGroup.scss +0 -87
  126. package/src/components/Modal/Modal.scss +0 -78
  127. package/src/components/Modal/ModalBody.scss +0 -18
  128. package/src/components/Modal/ModalCloseButton.scss +0 -18
  129. package/src/components/Modal/ModalContent.scss +0 -5
  130. package/src/components/Modal/ModalFooter.scss +0 -35
  131. package/src/components/Modal/ModalHeader.scss +0 -30
  132. package/src/components/Modal/ModalTitle.scss +0 -10
  133. package/src/components/Paper/Paper.scss +0 -17
  134. package/src/components/Popover/Popover.scss +0 -236
  135. package/src/components/Popover/PopoverWrapper.scss +0 -3
  136. package/src/components/Radio/Radio.scss +0 -83
  137. package/src/components/ScrollView/ScrollView.scss +0 -227
  138. package/src/components/SelectField/SelectField.scss +0 -109
  139. package/src/components/Table/Table.scss +0 -28
  140. package/src/components/Table/_components/TableCell.scss +0 -26
  141. package/src/components/Tabs/Tabs.scss +0 -28
  142. package/src/components/Tabs/TabsItem.scss +0 -117
  143. package/src/components/Text/Text.scss +0 -40
  144. package/src/components/TextArea/TextArea.scss +0 -95
  145. package/src/components/TextField/TextField.scss +0 -107
  146. package/src/components/TextLink/TextLink.scss +0 -16
  147. package/src/components/Toggle/Toggle.scss +0 -61
  148. package/src/components/Toolbar/Toolbar.scss +0 -83
  149. /package/src/components/Button/{Button.scss → Button.module.scss} +0 -0
@@ -156,10 +156,10 @@ It's possible to disable the whole input.
156
156
  ## Forwarding HTML Attributes
157
157
 
158
158
  In addition to the options below in the [component's API](#api) section, you
159
- can specify [React synthetic events] or you can **add whatever HTML attribute
160
- you like.** All attributes that don't interfere with the API are forwarded to
161
- the native HTML `<input>`. This enables making the component interactive and
162
- helps to improve its accessibility.
159
+ can specify **any HTML attribute you like.** All attributes that don't interfere
160
+ with the API of the React component are forwarded to the root `<input>` HTML
161
+ element. This enables making the component interactive and helps to improve
162
+ its accessibility.
163
163
 
164
164
  ```docoff-react-preview
165
165
  <FileInputField
@@ -173,8 +173,10 @@ helps to improve its accessibility.
173
173
  />
174
174
  ```
175
175
 
176
- 👉 Refer to the MDN reference for the full list of supported attributes of the
177
- [file] input type.
176
+ 👉 For the full list of supported attributes refer to:
177
+
178
+ - [`<input type="file" />` HTML element attributes][file-attributes]{:target="_blank"}
179
+ - [React common props]{:target="_blank"}
178
180
 
179
181
  ## Forwarding ref
180
182
 
@@ -189,6 +191,6 @@ If you provide [ref], it is forwarded to the native HTML `<input>` element.
189
191
  Head to [Forms Theming](/docs/customize/theming/forms) to see shared form theming
190
192
  options.
191
193
 
192
- [React synthetic events]: https://reactjs.org/docs/events.html
193
- [file]: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/file#additional_attributes
194
+ [React common props]: https://react.dev/reference/react-dom/components/common#common-props
195
+ [file-attributes]: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/file#additional_attributes
194
196
  [ref]: https://reactjs.org/docs/refs-and-the-dom.html
@@ -5,7 +5,7 @@ import { transferProps } from '../_helpers/transferProps';
5
5
  import { classNames } from '../../utils/classNames';
6
6
  import { isChildrenEmpty } from '../_helpers/isChildrenEmpty';
7
7
  import { FormLayoutContext } from './FormLayoutContext';
8
- import styles from './FormLayout.scss';
8
+ import styles from './FormLayout.module.scss';
9
9
 
10
10
  const PREDEFINED_LABEL_WIDTH_VALUES = ['auto', 'default', 'limited'];
11
11
 
@@ -18,41 +18,43 @@
18
18
  @use "../../styles/tools/spacing";
19
19
  @use "theme";
20
20
 
21
- .root {
22
- --rui-local-field-width: 1fr;
21
+ @layer components.form-layout {
22
+ .root {
23
+ --rui-local-field-width: 1fr;
23
24
 
24
- @include spacing.bottom(layouts);
25
- }
25
+ @include spacing.bottom(layouts);
26
+ }
26
27
 
27
- .isRootFieldLayoutVertical,
28
- .isRootFieldLayoutHorizontal {
29
- display: grid;
30
- grid-template-columns: var(--rui-local-field-width);
31
- grid-row-gap: theme.$row-gap;
32
- }
28
+ .isRootFieldLayoutVertical,
29
+ .isRootFieldLayoutHorizontal {
30
+ display: grid;
31
+ grid-template-columns: var(--rui-local-field-width);
32
+ grid-row-gap: theme.$row-gap;
33
+ }
33
34
 
34
- .isRootFieldLayoutHorizontal {
35
- @include breakpoint.up(forms.$horizontal-breakpoint) {
36
- grid-template-columns: var(--rui-local-label-width) var(--rui-local-field-width); // 1.
35
+ .isRootFieldLayoutHorizontal {
36
+ @include breakpoint.up(forms.$horizontal-breakpoint) {
37
+ grid-template-columns: var(--rui-local-label-width) var(--rui-local-field-width); // 1.
38
+ }
37
39
  }
38
- }
39
40
 
40
- .hasRootLabelWidthDefault {
41
- --rui-local-label-width: #{theme.$horizontal-label-width}; // 1., 2.
42
- }
41
+ .hasRootLabelWidthDefault {
42
+ --rui-local-label-width: #{theme.$horizontal-label-width}; // 1., 2.
43
+ }
43
44
 
44
- .hasRootLabelWidthAuto {
45
- --rui-local-label-width: #{theme.$horizontal-label-width-auto}; // 4.
46
- }
45
+ .hasRootLabelWidthAuto {
46
+ --rui-local-label-width: #{theme.$horizontal-label-width-auto}; // 4.
47
+ }
47
48
 
48
- .hasRootLabelWidthLimited {
49
- --rui-local-label-width: #{theme.$horizontal-label-width-limited}; // 4.
50
- }
49
+ .hasRootLabelWidthLimited {
50
+ --rui-local-label-width: #{theme.$horizontal-label-width-limited}; // 4.
51
+ }
51
52
 
52
- .hasRootLabelWidthCustom {
53
- --rui-local-label-width: var(--rui-custom-label-width); // 3.
54
- }
53
+ .hasRootLabelWidthCustom {
54
+ --rui-local-label-width: var(--rui-custom-label-width); // 3.
55
+ }
55
56
 
56
- .isRootAutoWidth {
57
- --rui-local-field-width: min-content;
57
+ .isRootAutoWidth {
58
+ --rui-local-field-width: min-content;
59
+ }
58
60
  }
@@ -7,7 +7,7 @@ import { getRootSizeClassName } from '../_helpers/getRootSizeClassName';
7
7
  import { getRootValidationStateClassName } from '../_helpers/getRootValidationStateClassName';
8
8
  import { isChildrenEmpty } from '../_helpers/isChildrenEmpty';
9
9
  import { FormLayoutContext } from './FormLayoutContext';
10
- import styles from './FormLayoutCustomField.scss';
10
+ import styles from './FormLayoutCustomField.module.scss';
11
11
 
12
12
  const renderLabel = (id, label, labelForId) => {
13
13
  if (labelForId && label) {
@@ -0,0 +1,65 @@
1
+ @use "../../styles/tools/form-fields/foundation";
2
+ @use "../../styles/tools/form-fields/box-field-layout";
3
+ @use "../../styles/tools/form-fields/box-field-sizes";
4
+ @use "../../styles/tools/form-fields/variants";
5
+
6
+ @layer components.form-layout {
7
+ // Foundation
8
+ .root {
9
+ @include box-field-layout.in-form-layout();
10
+ @include variants.visual(custom);
11
+ }
12
+
13
+ .label {
14
+ @include foundation.label();
15
+ }
16
+
17
+ .isRootRequired .label {
18
+ @include foundation.label-required();
19
+ }
20
+
21
+ // States
22
+ .isRootStateInvalid {
23
+ @include variants.validation(invalid);
24
+ }
25
+
26
+ .isRootStateValid {
27
+ @include variants.validation(valid);
28
+ }
29
+
30
+ .isRootStateWarning {
31
+ @include variants.validation(warning);
32
+ }
33
+
34
+ // Layouts
35
+ .isRootLayoutVertical,
36
+ .isRootLayoutHorizontal {
37
+ @include box-field-layout.vertical();
38
+ }
39
+
40
+ .isRootLayoutHorizontal {
41
+ @include box-field-layout.horizontal();
42
+ }
43
+
44
+ .isRootLayoutVertical .field,
45
+ .isRootLayoutHorizontal .field {
46
+ width: auto;
47
+ }
48
+
49
+ .isRootFullWidth .field {
50
+ justify-self: stretch;
51
+ }
52
+
53
+ // Sizes
54
+ .isRootSizeSmall {
55
+ @include box-field-sizes.size(small);
56
+ }
57
+
58
+ .isRootSizeMedium {
59
+ @include box-field-sizes.size(medium);
60
+ }
61
+
62
+ .isRootSizeLarge {
63
+ @include box-field-sizes.size(large);
64
+ }
65
+ }
@@ -416,13 +416,15 @@ React.createElement(() => {
416
416
  ## Forwarding HTML Attributes
417
417
 
418
418
  In addition to the options below in the [component's API](#api) section, you
419
- can specify [React synthetic events] or **any HTML attribute you like.** All
420
- attributes that don't interfere with the API are forwarded to the root `<div>`
421
- HTML element. This enables making the component interactive and helps to improve
419
+ can specify **any HTML attribute you like.** All attributes that don't interfere
420
+ with the API of the React component are forwarded to the root `<div>` HTML
421
+ element. This enables making the component interactive and helps to improve
422
422
  its accessibility.
423
423
 
424
- 👉 Refer to the MDN reference for the full list of supported attributes of the
425
- [div] element.
424
+ 👉 For the full list of supported attributes refer to:
425
+
426
+ - [`<div>` HTML element attributes][div-attributes]{:target="_blank"}
427
+ - [React common props]{:target="_blank"}
426
428
 
427
429
  ## API
428
430
 
@@ -453,10 +455,10 @@ FormLayoutCustomField can be styled using a small subset of
453
455
  | `--rui-FormField--custom--default__surrounding-text-color` | Custom field label color in default state |
454
456
  | `--rui-FormField--custom--disabled__surrounding-text-color` | Custom field label color in disabled-like state |
455
457
 
456
- [grid]: https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Grid_Layout
457
- [subgrid]: https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Grid_Layout/Subgrid
458
+ [div-attributes]: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/div#attributes
458
459
  [fragments]: https://reactjs.org/docs/fragments.html
460
+ [grid]: https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Grid_Layout
461
+ [React common props]: https://react.dev/reference/react-dom/components/common#common-props
459
462
  [rui-232]: https://github.com/react-ui-org/react-ui/issues/232
460
463
  [rui-265]: https://github.com/react-ui-org/react-ui/issues/265
461
- [React synthetic events]: https://reactjs.org/docs/events.html
462
- [div]: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/div#attributes
464
+ [subgrid]: https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Grid_Layout/Subgrid
@@ -4,7 +4,7 @@ import { withGlobalProps } from '../../provider';
4
4
  import { isChildrenEmpty } from '../_helpers/isChildrenEmpty';
5
5
  import { transferProps } from '../_helpers/transferProps';
6
6
  import { generateResponsiveCustomProperties } from './_helpers/generateResponsiveCustomProperties';
7
- import styles from './Grid.scss';
7
+ import styles from './Grid.module.scss';
8
8
 
9
9
  const SPACING_VALUES = [0, 1, 2, 3, 4, 5, 6, 7];
10
10
 
@@ -0,0 +1,66 @@
1
+ // 1. Read value of `--rui-local-<PROPERTY>-<BREAKPOINT>` that might have been defined by
2
+ // JavaScript and assign it to `--rui-local-<PROPERTY>` used in 2.
3
+ //
4
+ // Fallback cascade containing fallbacks for all previous breakpoints recursively is included
5
+ // using CSS custom property fallback mechanism like this:
6
+ //
7
+ // Fallback for `xs` breakpoint: `<INITIAL FALLBACK>`
8
+ // Fallback for `sm` breakpoint: `var(--rui-local-<PROPERTY>-xs, <INITIAL FALLBACK>)`
9
+ // Fallback for `md` breakpoint: `var(--rui-local-<PROPERTY>-sm, var(--rui-local-<PROPERTY>-xs, <INIT. FALLBACK>))`
10
+ //
11
+ // … etc, up to the largest breakpoint.
12
+ //
13
+ // A media query is then created for each breakpoint (with exception of `xs` which doesn't need a
14
+ // media query) and a corresponding responsive custom property variant is assigned to
15
+ // `--rui-local-<PROPERTY>` that is used later in CSS, see 2.
16
+ //
17
+ // Example for `sm` breakpoint:
18
+ //
19
+ // `--rui-local-<PROPERTY>: var(--rui-local-<PROPERTY>-sm, var(--rui-local-<PROPERTY>-xs, <INITIAL FALLBACK>))`
20
+ //
21
+ // 2. Apply custom property value that is defined within current breakpoint, see 1.
22
+
23
+ @use "sass:map";
24
+ @use "../../styles/tools/spacing";
25
+ @use "settings";
26
+ @use "tools";
27
+
28
+ @layer components.grid {
29
+ .root {
30
+ @include tools.assign-responsive-custom-properties(settings.$grid-responsive-properties); // 1.
31
+ @include spacing.bottom(layouts);
32
+
33
+ display: grid;
34
+ grid-template-columns: var(--rui-local-columns); // 2.
35
+ grid-template-rows: var(--rui-local-rows); // 2.
36
+ grid-auto-flow: var(--rui-local-auto-flow); // 2.
37
+ grid-gap: var(--rui-local-row-gap) var(--rui-local-column-gap); // 2.
38
+ align-content: var(--rui-local-align-content); // 2.
39
+ align-items: var(--rui-local-align-items); // 2.
40
+ justify-content: var(--rui-local-justify-content); // 2.
41
+ justify-items: var(--rui-local-justify-items); // 2.
42
+ }
43
+
44
+ // stylelint-disable-next-line selector-max-universal -- Reset any previously added margins.
45
+ .root > * {
46
+ margin-block: 0;
47
+ }
48
+
49
+ .span {
50
+ @include tools.assign-responsive-custom-properties(settings.$grid-span-responsive-properties); // 1.
51
+
52
+ grid-column: span var(--rui-local-column-span); // 2.
53
+ grid-row: span var(--rui-local-row-span); // 2.
54
+ }
55
+
56
+ // stylelint-disable selector-no-qualifying-type
57
+ dl.root,
58
+ ol.root,
59
+ ul.root {
60
+ padding-left: 0;
61
+ margin-left: 0;
62
+ list-style: none;
63
+ }
64
+
65
+ // stylelint-enable selector-no-qualifying-type
66
+ }
@@ -4,7 +4,7 @@ import { withGlobalProps } from '../../provider';
4
4
  import { isChildrenEmpty } from '../_helpers/isChildrenEmpty';
5
5
  import { transferProps } from '../_helpers/transferProps';
6
6
  import { generateResponsiveCustomProperties } from './_helpers/generateResponsiveCustomProperties';
7
- import styles from './Grid.scss';
7
+ import styles from './Grid.module.scss';
8
8
 
9
9
  export const GridSpan = ({
10
10
  children,
@@ -248,13 +248,16 @@ property. Check [MDN][grid-auto-flow] to fully understand available options.
248
248
  ## Forwarding HTML Attributes
249
249
 
250
250
  In addition to the options below in the [component's API](#api) section, you
251
- can specify [React synthetic events] or **any HTML attribute you like.** All
252
- attributes that don't interfere with the API are forwarded to the HTML element
253
- of your choice provided by `tag`, which is `<div>` by default. It enables making
254
- the component interactive and helps to improve its accessibility.
251
+ can specify **any HTML attribute you like.** All attributes that don't interfere
252
+ with the API of the React component are forwarded to the root HTML element
253
+ of your choice provided by `tag`, which is `<div>` by default. This enables
254
+ making the component interactive and helps to improve its accessibility.
255
255
 
256
- 👉 Refer to the MDN reference for the full list of supported attributes of the
257
- [div] element or [any other][all-html-elements] element of your choice.
256
+ 👉 For the full list of supported attributes refer to:
257
+
258
+ - [`<div>` HTML element attributes][div-attributes]{:target="_blank"}
259
+ - [any other HTML element][all-html-elements]{:target="_blank"}
260
+ - [React common props]{:target="_blank"}
258
261
 
259
262
  ## API
260
263
 
@@ -276,6 +279,6 @@ Wrapper for content that should span multiple rows or columns.
276
279
  [justify-items]: https://developer.mozilla.org/en-US/docs/Web/CSS/justify-items
277
280
  [repeat]: https://developer.mozilla.org/en-US/docs/Web/CSS/repeat
278
281
  [minmax]: https://developer.mozilla.org/en-US/docs/Web/CSS/minmax
279
- [React synthetic events]: https://reactjs.org/docs/events.html
280
- [div]: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/div#attributes
282
+ [React common props]: https://react.dev/reference/react-dom/components/common#common-props
283
+ [div-attributes]: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/div#attributes
281
284
  [all-html-elements]: https://developer.mozilla.org/en-US/docs/Web/HTML/Element
@@ -13,7 +13,7 @@ import { resolveContextOrProp } from '../_helpers/resolveContextOrProp';
13
13
  import { transferProps } from '../_helpers/transferProps';
14
14
  import { FormLayoutContext } from '../FormLayout';
15
15
  import { InputGroupContext } from './InputGroupContext';
16
- import styles from './InputGroup.scss';
16
+ import styles from './InputGroup.module.scss';
17
17
 
18
18
  export const InputGroup = ({
19
19
  children,
@@ -22,6 +22,7 @@ export const InputGroup = ({
22
22
  isLabelVisible,
23
23
  label,
24
24
  layout,
25
+ required,
25
26
  size,
26
27
  validationTexts,
27
28
  ...restProps
@@ -57,6 +58,7 @@ export const InputGroup = ({
57
58
  ? styles.isRootLayoutHorizontal
58
59
  : styles.isRootLayoutVertical,
59
60
  disabled && styles.isRootDisabled,
61
+ required && styles.isRootRequired,
60
62
  getRootSizeClassName(size, styles),
61
63
  getRootValidationStateClassName(validationState, styles),
62
64
  )}
@@ -112,6 +114,7 @@ InputGroup.defaultProps = {
112
114
  id: undefined,
113
115
  isLabelVisible: true,
114
116
  layout: 'vertical',
117
+ required: false,
115
118
  size: 'medium',
116
119
  validationTexts: null,
117
120
  };
@@ -156,6 +159,11 @@ InputGroup.propTypes = {
156
159
  * as the value is inherited in such case.
157
160
  */
158
161
  layout: PropTypes.oneOf(['horizontal', 'vertical']),
162
+ /**
163
+ * If `true`, the `InputGroup`'s label appears as required. Underlying `<fieldset>`
164
+ * element does not take `required` attribute so there is no functional effect.
165
+ */
166
+ required: PropTypes.bool,
159
167
  /**
160
168
  * Size of the `children` elements.
161
169
  */
@@ -0,0 +1,93 @@
1
+ // 1. The class name is intentionally singular because it's targeted by other mixins too.
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.
5
+ // https://developer.mozilla.org/en-US/docs/Web/HTML/Element/fieldset#styling_with_css
6
+
7
+ @use "../../styles/tools/form-fields/box-field-elements";
8
+ @use "../../styles/tools/form-fields/box-field-layout";
9
+ @use "../../styles/tools/form-fields/box-field-sizes";
10
+ @use "../../styles/tools/form-fields/foundation";
11
+ @use "../../styles/tools/form-fields/variants";
12
+ @use "../../styles/tools/accessibility";
13
+ @use "../../styles/tools/reset";
14
+ @use "theme";
15
+
16
+ @layer components.input-group {
17
+ .root {
18
+ @include foundation.root();
19
+ @include foundation.fieldset();
20
+ }
21
+
22
+ // 4.
23
+ .legend {
24
+ @include accessibility.hide-text();
25
+ }
26
+
27
+ // 4.
28
+ .label {
29
+ @include foundation.label();
30
+ }
31
+
32
+ .inputGroup {
33
+ --rui-local-inner-border-radius: #{theme.$inner-border-radius};
34
+
35
+ display: flex; // 2.
36
+ gap: theme.$gap;
37
+ }
38
+
39
+ // 1.
40
+ .validationText {
41
+ @include reset.list();
42
+ @include foundation.help-text();
43
+ }
44
+
45
+ .isRootRequired .label {
46
+ @include foundation.label-required();
47
+ }
48
+
49
+ // States
50
+ .isRootStateInvalid {
51
+ @include variants.validation(invalid);
52
+ }
53
+
54
+ .isRootStateValid {
55
+ @include variants.validation(valid);
56
+ }
57
+
58
+ .isRootStateWarning {
59
+ @include variants.validation(warning);
60
+ }
61
+
62
+ // Layouts
63
+ .isRootLayoutVertical,
64
+ .isRootLayoutHorizontal {
65
+ @include box-field-layout.vertical();
66
+ }
67
+
68
+ .isRootLayoutVertical .field,
69
+ .isRootLayoutHorizontal .field {
70
+ max-width: none; // 3.
71
+ }
72
+
73
+ .isRootLayoutHorizontal {
74
+ @include box-field-layout.horizontal();
75
+ }
76
+
77
+ .isRootInFormLayout {
78
+ @include box-field-layout.in-form-layout($is-fieldset: true);
79
+ }
80
+
81
+ // Sizes
82
+ .isRootSizeSmall {
83
+ @include box-field-sizes.size(small, $has-input: false);
84
+ }
85
+
86
+ .isRootSizeMedium {
87
+ @include box-field-sizes.size(medium, $has-input: false);
88
+ }
89
+
90
+ .isRootSizeLarge {
91
+ @include box-field-sizes.size(large, $has-input: false);
92
+ }
93
+ }
@@ -176,9 +176,14 @@ not show any `validationText`, they only show their respective `validationState`
176
176
  Validation messages passed to input elements' `validationText` prop will be
177
177
  ignored.
178
178
 
179
+ 👉 While there is a `required` property to visually denote the whole input group
180
+ is required, there is no functional effect as there is no such HTML attribute
181
+ for the underlying `<fieldset>` element.
182
+
179
183
  ```docoff-react-preview
180
184
  <InputGroup
181
185
  label="First and last name"
186
+ required
182
187
  validationTexts={[
183
188
  "First name must be filled in.",
184
189
  "Last name must be filled in.",
@@ -187,17 +192,20 @@ ignored.
187
192
  <TextField
188
193
  label="First name"
189
194
  placeholder="Eg. John"
195
+ required
190
196
  validationState="invalid"
191
197
  />
192
198
  <TextField
193
199
  label="Last name"
194
200
  placeholder="Eg. Doe"
201
+ required
195
202
  validationState="invalid"
196
203
  />
197
204
  <Button label="Submit" />
198
205
  </InputGroup>
199
206
  <InputGroup
200
207
  label="First and last name"
208
+ required
201
209
  validationTexts={[
202
210
  "Last name should not include any digits.",
203
211
  ]}
@@ -205,26 +213,33 @@ ignored.
205
213
  <TextField
206
214
  label="First name"
207
215
  placeholder="Eg. John"
216
+ required
208
217
  value="John"
209
218
  />
210
219
  <TextField
211
220
  label="Last name"
212
221
  placeholder="Eg. Doe"
222
+ required
213
223
  validationState="warning"
214
224
  value="123Doe"
215
225
  />
216
226
  <Button label="Submit" />
217
227
  </InputGroup>
218
- <InputGroup label="First and last name">
228
+ <InputGroup
229
+ label="First and last name"
230
+ required
231
+ >
219
232
  <TextField
220
233
  label="First name"
221
234
  placeholder="Eg. John"
235
+ required
222
236
  validationState="valid"
223
237
  value="John"
224
238
  />
225
239
  <TextField
226
240
  label="Last name"
227
241
  placeholder="Eg. Doe"
242
+ required
228
243
  validationState="valid"
229
244
  value="Doe"
230
245
  />
@@ -235,13 +250,15 @@ ignored.
235
250
  ## Forwarding HTML Attributes
236
251
 
237
252
  In addition to the options below in the [component's API](#api) section, you
238
- can specify [React synthetic events] or **any HTML attribute you like.** All
239
- attributes that don't interfere with the API are forwarded to the `<div>` HTML
240
- element which wraps elements to be grouped. This enables making the component
241
- interactive and helps to improve its accessibility.
253
+ can specify **any HTML attribute you like.** All attributes that don't interfere
254
+ with the API of the React component are forwarded to the root `<fieldset>` HTML
255
+ element. This enables making the component interactive and helps to improve
256
+ its accessibility.
242
257
 
243
- 👉 Refer to the MDN reference for the full list of supported attributes of the
244
- [div] element.
258
+ 👉 For the full list of supported attributes refer to:
259
+
260
+ - [`<fieldset>` HTML element attributes][fieldset-attributes]{:target="_blank"}
261
+ - [React common props]{:target="_blank"}
245
262
 
246
263
  ## API
247
264
 
@@ -254,7 +271,7 @@ interactive and helps to improve its accessibility.
254
271
  | `--rui-InputGroup__gap` | Gap between elements |
255
272
  | `--rui-InputGroup__inner-border-radius` | Inner border radius of elements |
256
273
 
257
- [fieldset]: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/fieldset
258
274
  [accessibility]: https://www.w3.org/WAI/tutorials/forms/grouping/
259
- [React synthetic events]: https://reactjs.org/docs/events.html
260
- [div]: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/div#attributes
275
+ [fieldset]: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/fieldset
276
+ [fieldset-attributes]: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/fieldset#attributes
277
+ [React common props]: https://react.dev/reference/react-dom/components/common#common-props
@@ -8,7 +8,7 @@ import { getPositionClassName } from './_helpers/getPositionClassName';
8
8
  import { getSizeClassName } from './_helpers/getSizeClassName';
9
9
  import { useModalFocus } from './_hooks/useModalFocus';
10
10
  import { useModalScrollPrevention } from './_hooks/useModalScrollPrevention';
11
- import styles from './Modal.scss';
11
+ import styles from './Modal.module.scss';
12
12
 
13
13
  const preRender = (
14
14
  children,