@react-ui-org/react-ui 0.48.0 → 0.49.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 (99) hide show
  1. package/dist/lib.development.js +160 -64
  2. package/dist/lib.js +1 -1
  3. package/package.json +1 -1
  4. package/src/lib/components/Alert/Alert.jsx +3 -0
  5. package/src/lib/components/Alert/Alert.scss +10 -10
  6. package/src/lib/components/Alert/README.mdx +14 -0
  7. package/src/lib/components/Badge/Badge.jsx +4 -8
  8. package/src/lib/components/Badge/Badge.scss +21 -21
  9. package/src/lib/components/Badge/README.mdx +14 -0
  10. package/src/lib/components/Button/Button.jsx +2 -13
  11. package/src/lib/components/Button/README.mdx +17 -5
  12. package/src/lib/components/Button/_base.scss +20 -20
  13. package/src/lib/components/Button/_priorities.scss +35 -35
  14. package/src/lib/components/Button/helpers/getRootLabelVisibilityClassName.js +7 -7
  15. package/src/lib/components/Button/helpers/getRootPriorityClassName.js +3 -3
  16. package/src/lib/components/ButtonGroup/ButtonGroup.jsx +0 -7
  17. package/src/lib/components/ButtonGroup/README.mdx +14 -0
  18. package/src/lib/components/Card/Card.jsx +6 -10
  19. package/src/lib/components/Card/Card.scss +13 -13
  20. package/src/lib/components/Card/CardBody.jsx +6 -10
  21. package/src/lib/components/Card/CardFooter.jsx +6 -7
  22. package/src/lib/components/Card/README.mdx +14 -0
  23. package/src/lib/components/CheckboxField/CheckboxField.jsx +1 -27
  24. package/src/lib/components/CheckboxField/README.mdx +17 -5
  25. package/src/lib/components/FileInputField/FileInputField.jsx +2 -11
  26. package/src/lib/components/FileInputField/FileInputField.scss +3 -3
  27. package/src/lib/components/FileInputField/README.mdx +29 -27
  28. package/src/lib/components/FormLayout/FormLayout.jsx +5 -9
  29. package/src/lib/components/FormLayout/FormLayout.scss +3 -3
  30. package/src/lib/components/FormLayout/FormLayoutCustomField.jsx +4 -1
  31. package/src/lib/components/FormLayout/FormLayoutCustomField.scss +8 -8
  32. package/src/lib/components/FormLayout/README.mdx +13 -0
  33. package/src/lib/components/Grid/Grid.jsx +0 -7
  34. package/src/lib/components/Grid/GridSpan.jsx +0 -7
  35. package/src/lib/components/Grid/README.mdx +14 -0
  36. package/src/lib/components/Modal/Modal.jsx +6 -10
  37. package/src/lib/components/Modal/ModalBody.jsx +3 -7
  38. package/src/lib/components/Modal/ModalCloseButton.jsx +0 -16
  39. package/src/lib/components/Modal/ModalContent.jsx +3 -7
  40. package/src/lib/components/Modal/ModalFooter.jsx +3 -7
  41. package/src/lib/components/Modal/ModalFooter.scss +5 -5
  42. package/src/lib/components/Modal/ModalHeader.jsx +3 -7
  43. package/src/lib/components/Modal/ModalHeader.scss +5 -5
  44. package/src/lib/components/Modal/ModalTitle.jsx +6 -7
  45. package/src/lib/components/Modal/README.mdx +25 -0
  46. package/src/lib/components/Modal/_helpers/getJustifyClassName.js +5 -5
  47. package/src/lib/components/Paper/Paper.jsx +5 -9
  48. package/src/lib/components/Paper/Paper.scss +2 -2
  49. package/src/lib/components/Paper/README.mdx +14 -0
  50. package/src/lib/components/Popover/Popover.jsx +0 -16
  51. package/src/lib/components/Popover/PopoverWrapper.jsx +0 -7
  52. package/src/lib/components/Popover/README.mdx +19 -0
  53. package/src/lib/components/Radio/README.mdx +12 -5
  54. package/src/lib/components/Radio/Radio.jsx +2 -2
  55. package/src/lib/components/Radio/Radio.scss +3 -3
  56. package/src/lib/components/ScrollView/README.mdx +19 -0
  57. package/src/lib/components/ScrollView/ScrollView.jsx +11 -4
  58. package/src/lib/components/SelectField/README.mdx +17 -5
  59. package/src/lib/components/SelectField/SelectField.jsx +3 -22
  60. package/src/lib/components/SelectField/SelectField.scss +8 -8
  61. package/src/lib/components/Table/README.mdx +21 -7
  62. package/src/lib/components/Table/Table.jsx +43 -101
  63. package/src/lib/components/Table/Table.scss +0 -24
  64. package/src/lib/components/Table/_components/TableBodyCell/TableBodyCell.jsx +46 -0
  65. package/src/lib/components/Table/_components/TableBodyCell/index.js +1 -0
  66. package/src/lib/components/Table/_components/TableCell.scss +25 -0
  67. package/src/lib/components/Table/_components/TableHeaderCell/TableHeaderCell.jsx +71 -0
  68. package/src/lib/components/Table/_components/TableHeaderCell/index.js +1 -0
  69. package/src/lib/components/Tabs/README.mdx +16 -0
  70. package/src/lib/components/Tabs/Tabs.jsx +6 -1
  71. package/src/lib/components/Tabs/TabsItem.jsx +3 -0
  72. package/src/lib/components/Text/README.mdx +16 -0
  73. package/src/lib/components/Text/Text.jsx +3 -7
  74. package/src/lib/components/Text/Text.scss +6 -6
  75. package/src/lib/components/Text/_helpers/getRootClampClassName.js +2 -2
  76. package/src/lib/components/Text/_helpers/getRootHyphensClassName.js +2 -2
  77. package/src/lib/components/Text/_helpers/getRootWordWrappingClassName.js +2 -2
  78. package/src/lib/components/TextArea/README.mdx +33 -30
  79. package/src/lib/components/TextArea/TextArea.jsx +3 -43
  80. package/src/lib/components/TextArea/TextArea.scss +8 -8
  81. package/src/lib/components/TextField/README.mdx +53 -51
  82. package/src/lib/components/TextField/TextField.jsx +3 -29
  83. package/src/lib/components/TextField/TextField.scss +9 -9
  84. package/src/lib/components/TextLink/README.mdx +12 -5
  85. package/src/lib/components/TextLink/TextLink.jsx +0 -10
  86. package/src/lib/components/Toggle/README.mdx +17 -5
  87. package/src/lib/components/Toggle/Toggle.jsx +1 -27
  88. package/src/lib/components/Toolbar/README.mdx +13 -0
  89. package/src/lib/components/Toolbar/Toolbar.jsx +9 -43
  90. package/src/lib/components/Toolbar/Toolbar.scss +24 -12
  91. package/src/lib/components/Toolbar/ToolbarGroup.jsx +7 -26
  92. package/src/lib/components/Toolbar/ToolbarItem.jsx +3 -7
  93. package/src/lib/components/Toolbar/_helpers/getAlignClassName.js +19 -0
  94. package/src/lib/components/Toolbar/_helpers/getJustifyClassName.js +16 -0
  95. package/src/lib/components/_helpers/getRootColorClassName.js +10 -10
  96. package/src/lib/components/_helpers/getRootSizeClassName.js +3 -3
  97. package/src/lib/styles/tools/form-fields/_box-field-layout.scss +15 -15
  98. package/src/lib/styles/tools/form-fields/_inline-field-elements.scss +1 -1
  99. package/src/lib/styles/tools/form-fields/_inline-field-layout.scss +9 -9
@@ -1,6 +1,7 @@
1
1
  import PropTypes from 'prop-types';
2
2
  import React, { useContext } from 'react';
3
3
  import { withGlobalProps } from '../../provider';
4
+ import { transferProps } from '../_helpers/transferProps';
4
5
  import { classNames } from '../../utils/classNames';
5
6
  import { getRootSizeClassName } from '../_helpers/getRootSizeClassName';
6
7
  import { getRootValidationStateClassName } from '../_helpers/getRootValidationStateClassName';
@@ -45,6 +46,7 @@ export const FormLayoutCustomField = ({
45
46
  labelForId,
46
47
  required,
47
48
  validationState,
49
+ ...restProps
48
50
  }) => {
49
51
  const context = useContext(FormLayoutContext);
50
52
 
@@ -54,11 +56,12 @@ export const FormLayoutCustomField = ({
54
56
 
55
57
  return (
56
58
  <div
59
+ {...transferProps(restProps)}
57
60
  id={id}
58
61
  className={classNames(
59
62
  styles.root,
60
63
  fullWidth && styles.isRootFullWidth,
61
- context && context.layout === 'horizontal' ? styles.rootLayoutHorizontal : styles.rootLayoutVertical,
64
+ context && context.layout === 'horizontal' ? styles.isRootLayoutHorizontal : styles.isRootLayoutVertical,
62
65
  disabled && styles.isRootDisabled,
63
66
  required && styles.isRootRequired,
64
67
  getRootSizeClassName(innerFieldSize, styles),
@@ -31,17 +31,17 @@
31
31
  }
32
32
 
33
33
  // Layouts
34
- .rootLayoutVertical,
35
- .rootLayoutHorizontal {
34
+ .isRootLayoutVertical,
35
+ .isRootLayoutHorizontal {
36
36
  @include box-field-layout.vertical();
37
37
  }
38
38
 
39
- .rootLayoutHorizontal {
39
+ .isRootLayoutHorizontal {
40
40
  @include box-field-layout.horizontal();
41
41
  }
42
42
 
43
- .rootLayoutVertical .field,
44
- .rootLayoutHorizontal .field {
43
+ .isRootLayoutVertical .field,
44
+ .isRootLayoutHorizontal .field {
45
45
  width: auto;
46
46
  }
47
47
 
@@ -50,14 +50,14 @@
50
50
  }
51
51
 
52
52
  // Sizes
53
- .rootSizeSmall {
53
+ .isRootSizeSmall {
54
54
  @include box-field-sizes.size(small);
55
55
  }
56
56
 
57
- .rootSizeMedium {
57
+ .isRootSizeMedium {
58
58
  @include box-field-sizes.size(medium);
59
59
  }
60
60
 
61
- .rootSizeLarge {
61
+ .isRootSizeLarge {
62
62
  @include box-field-sizes.size(large);
63
63
  }
@@ -438,6 +438,17 @@ This is a demo of all components supported by FormLayout.
438
438
  }}
439
439
  </Playground>
440
440
 
441
+ ## Forwarding HTML Attributes
442
+
443
+ In addition to the options below in the [component's API](#api) section, you
444
+ can specify [React synthetic events] or **any HTML attribute you like.** All
445
+ attributes that don't interfere with the API are forwarded to the root `<div>`
446
+ HTML element. This enables making the component interactive and helps to improve
447
+ its accessibility.
448
+
449
+ 👉 Refer to the MDN reference for the full list of supported attributes of the
450
+ [div] element.
451
+
441
452
  ## API
442
453
 
443
454
  <Props table of={FormLayout} />
@@ -472,3 +483,5 @@ FormLayoutCustomField can be styled using a small subset of
472
483
  [fragments]: https://reactjs.org/docs/fragments.html
473
484
  [rui-232]: https://github.com/react-ui-org/react-ui/issues/232
474
485
  [rui-265]: https://github.com/react-ui-org/react-ui/issues/265
486
+ [React synthetic events]: https://reactjs.org/docs/events.html
487
+ [div]: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/div#attributes
@@ -15,7 +15,6 @@ export const Grid = ({
15
15
  children,
16
16
  columnGap,
17
17
  columns,
18
- id,
19
18
  justifyContent,
20
19
  justifyItems,
21
20
  rowGap,
@@ -30,7 +29,6 @@ export const Grid = ({
30
29
  return (
31
30
  <Tag
32
31
  {...transferProps(restProps)}
33
- id={id}
34
32
  className={styles.root}
35
33
  style={{
36
34
  ...generateResponsiveCustomProperties(columns, 'columns'),
@@ -59,7 +57,6 @@ Grid.defaultProps = {
59
57
  children: null,
60
58
  columnGap: 4,
61
59
  columns: '1fr',
62
- id: undefined,
63
60
  justifyContent: undefined,
64
61
  justifyItems: undefined,
65
62
  rowGap: 4,
@@ -152,10 +149,6 @@ Grid.propTypes = {
152
149
  x3l: PropTypes.string,
153
150
  }),
154
151
  ]),
155
- /**
156
- * ID of the root HTML element.
157
- */
158
- id: PropTypes.string,
159
152
  /**
160
153
  * Content justification. Accepts any valid value of `justify-content` CSS property.
161
154
  * See [MDN](https://developer.mozilla.org/en-US/docs/Web/CSS/justify-content) for more.
@@ -9,7 +9,6 @@ import styles from './Grid.scss';
9
9
  export const GridSpan = ({
10
10
  children,
11
11
  columns,
12
- id,
13
12
  rows,
14
13
  tag: Tag,
15
14
  ...restProps
@@ -21,7 +20,6 @@ export const GridSpan = ({
21
20
  return (
22
21
  <Tag
23
22
  {...transferProps(restProps)}
24
- id={id}
25
23
  className={styles.span}
26
24
  style={{
27
25
  ...generateResponsiveCustomProperties(columns, 'column-span'),
@@ -39,7 +37,6 @@ export const GridSpan = ({
39
37
  GridSpan.defaultProps = {
40
38
  children: null,
41
39
  columns: 1,
42
- id: undefined,
43
40
  rows: 1,
44
41
  tag: 'div',
45
42
  };
@@ -64,10 +61,6 @@ GridSpan.propTypes = {
64
61
  x3l: PropTypes.number,
65
62
  }),
66
63
  ]),
67
- /**
68
- * ID of the root HTML element.
69
- */
70
- id: PropTypes.string,
71
64
  /**
72
65
  * Number of rows to span.
73
66
  */
@@ -263,6 +263,17 @@ with responsive columns and rows.
263
263
  👉 `autoFlow` (used in the example above) implements the `grid-auto-flow` CSS
264
264
  property. Check [MDN][grid-auto-flow] to fully understand available options.
265
265
 
266
+ ## Forwarding HTML Attributes
267
+
268
+ In addition to the options below in the [component's API](#api) section, you
269
+ can specify [React synthetic events] or **any HTML attribute you like.** All
270
+ attributes that don't interfere with the API are forwarded to the HTML element
271
+ of your choice provided by `tag`, which is `<div>` by default. It enables making
272
+ the component interactive and helps to improve its accessibility.
273
+
274
+ 👉 Refer to the MDN reference for the full list of supported attributes of the
275
+ [div] element or [any other][all-html-elements] element of your choice.
276
+
266
277
  ## API
267
278
 
268
279
  <Props table of={Grid} />
@@ -283,3 +294,6 @@ Wrapper for content that should span multiple rows or columns.
283
294
  [justify-items]: https://developer.mozilla.org/en-US/docs/Web/CSS/justify-items
284
295
  [repeat]: https://developer.mozilla.org/en-US/docs/Web/CSS/repeat
285
296
  [minmax]: https://developer.mozilla.org/en-US/docs/Web/CSS/minmax
297
+ [React synthetic events]: https://reactjs.org/docs/events.html
298
+ [div]: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/div#attributes
299
+ [all-html-elements]: https://developer.mozilla.org/en-US/docs/Web/HTML/Element
@@ -5,15 +5,16 @@ import React, {
5
5
  } from 'react';
6
6
  import { createPortal } from 'react-dom';
7
7
  import { withGlobalProps } from '../../provider';
8
+ import { transferProps } from '../_helpers/transferProps';
8
9
  import { classNames } from '../../utils/classNames';
9
10
  import styles from './Modal.scss';
10
11
 
11
12
  const preRender = (
12
13
  children,
13
14
  childrenWrapperRef,
14
- id,
15
15
  closeButtonRef,
16
16
  position,
17
+ restProps,
17
18
  size,
18
19
  ) => {
19
20
  const sizeClass = (modalSize) => {
@@ -47,7 +48,6 @@ const preRender = (
47
48
  return (
48
49
  <div
49
50
  className={styles.backdrop}
50
- id={id}
51
51
  onClick={() => {
52
52
  if (closeButtonRef?.current != null) {
53
53
  closeButtonRef.current.click();
@@ -56,6 +56,7 @@ const preRender = (
56
56
  role="presentation"
57
57
  >
58
58
  <div
59
+ {...transferProps(restProps)}
59
60
  className={classNames(
60
61
  styles.root,
61
62
  sizeClass(size),
@@ -77,11 +78,11 @@ export const Modal = ({
77
78
  autoFocus,
78
79
  children,
79
80
  closeButtonRef,
80
- id,
81
81
  portalId,
82
82
  position,
83
83
  primaryButtonRef,
84
84
  size,
85
+ ...restProps
85
86
  }) => {
86
87
  const childrenWrapperRef = useRef();
87
88
 
@@ -130,9 +131,9 @@ export const Modal = ({
130
131
  return preRender(
131
132
  children,
132
133
  childrenWrapperRef,
133
- id,
134
134
  closeButtonRef,
135
135
  position,
136
+ restProps,
136
137
  size,
137
138
  );
138
139
  }
@@ -141,9 +142,9 @@ export const Modal = ({
141
142
  preRender(
142
143
  children,
143
144
  childrenWrapperRef,
144
- id,
145
145
  closeButtonRef,
146
146
  position,
147
+ restProps,
147
148
  size,
148
149
  ),
149
150
  document.getElementById(portalId),
@@ -154,7 +155,6 @@ Modal.defaultProps = {
154
155
  autoFocus: true,
155
156
  children: null,
156
157
  closeButtonRef: null,
157
- id: undefined,
158
158
  portalId: null,
159
159
  position: 'center',
160
160
  primaryButtonRef: null,
@@ -184,10 +184,6 @@ Modal.propTypes = {
184
184
  // eslint-disable-next-line react/forbid-prop-types
185
185
  current: PropTypes.any,
186
186
  }),
187
- /**
188
- * ID of the root HTML element.
189
- */
190
- id: PropTypes.string,
191
187
  /**
192
188
  * If set, modal is rendered in the React Portal with that ID.
193
189
  */
@@ -1,6 +1,7 @@
1
1
  import PropTypes from 'prop-types';
2
2
  import React from 'react';
3
3
  import { withGlobalProps } from '../../provider';
4
+ import { transferProps } from '../_helpers/transferProps';
4
5
  import { classNames } from '../../utils/classNames';
5
6
  import { isChildrenEmpty } from '../_helpers/isChildrenEmpty';
6
7
  import { getScrollingClassName } from './_helpers/getScrollingClassName';
@@ -8,8 +9,8 @@ import styles from './ModalBody.scss';
8
9
 
9
10
  export const ModalBody = ({
10
11
  children,
11
- id,
12
12
  scrolling,
13
+ ...restProps
13
14
  }) => {
14
15
  if (isChildrenEmpty(children)) {
15
16
  return null;
@@ -17,11 +18,11 @@ export const ModalBody = ({
17
18
 
18
19
  return (
19
20
  <div
21
+ {...transferProps(restProps)}
20
22
  className={classNames(
21
23
  styles.root,
22
24
  getScrollingClassName(scrolling, styles),
23
25
  )}
24
- id={id}
25
26
  >
26
27
  {children}
27
28
  </div>
@@ -30,7 +31,6 @@ export const ModalBody = ({
30
31
 
31
32
  ModalBody.defaultProps = {
32
33
  children: null,
33
- id: undefined,
34
34
  scrolling: 'auto',
35
35
  };
36
36
 
@@ -45,10 +45,6 @@ ModalBody.propTypes = {
45
45
  * At most one nested element is allowed. If none are provided nothing is rendered.
46
46
  */
47
47
  children: PropTypes.node,
48
- /**
49
- * ID of the root HTML element.
50
- */
51
- id: PropTypes.string,
52
48
  /**
53
49
  * Scrolling mode:
54
50
  *
@@ -10,7 +10,6 @@ import styles from './ModalCloseButton.scss';
10
10
  export const ModalCloseButton = React.forwardRef((props, ref) => {
11
11
  const {
12
12
  disabled,
13
- id,
14
13
  ...restProps
15
14
  } = props;
16
15
 
@@ -22,7 +21,6 @@ export const ModalCloseButton = React.forwardRef((props, ref) => {
22
21
  type="button"
23
22
  className={styles.root}
24
23
  disabled={disabled}
25
- id={id}
26
24
  ref={ref}
27
25
  title={translations.ModalCloseButton.close}
28
26
  >
@@ -33,8 +31,6 @@ export const ModalCloseButton = React.forwardRef((props, ref) => {
33
31
 
34
32
  ModalCloseButton.defaultProps = {
35
33
  disabled: false,
36
- id: undefined,
37
- ref: undefined,
38
34
  };
39
35
 
40
36
  ModalCloseButton.propTypes = {
@@ -42,18 +38,6 @@ ModalCloseButton.propTypes = {
42
38
  * If `true`, close button will be disabled.
43
39
  */
44
40
  disabled: PropTypes.bool,
45
- /**
46
- * ID of the root HTML element.
47
- */
48
- id: PropTypes.string,
49
- /**
50
- * Reference forwarded to the `button` element.
51
- */
52
- ref: PropTypes.oneOfType([
53
- PropTypes.func,
54
- // eslint-disable-next-line react/forbid-prop-types
55
- PropTypes.shape({ current: PropTypes.any }),
56
- ]),
57
41
  };
58
42
 
59
43
  export const ModalCloseButtonWithGlobalProps = withGlobalProps(ModalCloseButton, 'ModalCloseButton');
@@ -2,11 +2,12 @@ import PropTypes from 'prop-types';
2
2
  import React from 'react';
3
3
  import { withGlobalProps } from '../../provider';
4
4
  import { isChildrenEmpty } from '../_helpers/isChildrenEmpty';
5
+ import { transferProps } from '../_helpers/transferProps';
5
6
  import styles from './ModalContent.scss';
6
7
 
7
8
  export const ModalContent = ({
8
9
  children,
9
- id,
10
+ ...restProps
10
11
  }) => {
11
12
  if (isChildrenEmpty(children)) {
12
13
  return null;
@@ -14,8 +15,8 @@ export const ModalContent = ({
14
15
 
15
16
  return (
16
17
  <div
18
+ {...transferProps(restProps)}
17
19
  className={styles.root}
18
- id={id}
19
20
  >
20
21
  {children}
21
22
  </div>
@@ -24,7 +25,6 @@ export const ModalContent = ({
24
25
 
25
26
  ModalContent.defaultProps = {
26
27
  children: null,
27
- id: undefined,
28
28
  };
29
29
 
30
30
  ModalContent.propTypes = {
@@ -32,10 +32,6 @@ ModalContent.propTypes = {
32
32
  * Content of the modal.
33
33
  */
34
34
  children: PropTypes.node,
35
- /**
36
- * ID of the root HTML element.
37
- */
38
- id: PropTypes.string,
39
35
  };
40
36
 
41
37
  export const ModalContentWithGlobalProps = withGlobalProps(ModalContent, 'ModalContent');
@@ -1,28 +1,28 @@
1
1
  import PropTypes from 'prop-types';
2
2
  import React from 'react';
3
3
  import { withGlobalProps } from '../../provider';
4
+ import { transferProps } from '../_helpers/transferProps';
4
5
  import { classNames } from '../../utils/classNames';
5
6
  import { getJustifyClassName } from './_helpers/getJustifyClassName';
6
7
  import styles from './ModalFooter.scss';
7
8
 
8
9
  export const ModalFooter = ({
9
10
  children,
10
- id,
11
11
  justify,
12
+ ...restProps
12
13
  }) => (
13
14
  <div
15
+ {...transferProps(restProps)}
14
16
  className={classNames(
15
17
  styles.root,
16
18
  getJustifyClassName(justify, styles),
17
19
  )}
18
- id={id}
19
20
  >
20
21
  {children}
21
22
  </div>
22
23
  );
23
24
 
24
25
  ModalFooter.defaultProps = {
25
- id: undefined,
26
26
  justify: 'center',
27
27
  };
28
28
 
@@ -31,10 +31,6 @@ ModalFooter.propTypes = {
31
31
  * Content of the footer (preferably nested `Button` elements).
32
32
  */
33
33
  children: PropTypes.node.isRequired,
34
- /**
35
- * ID of the root HTML element.
36
- */
37
- id: PropTypes.string,
38
34
  /**
39
35
  * Horizontal alignment (distribution) of individual buttons.
40
36
  */
@@ -14,22 +14,22 @@
14
14
  background: theme.$footer-background;
15
15
  }
16
16
 
17
- .isJustifiedToStart {
17
+ .isRootJustifiedToStart {
18
18
  justify-content: flex-start;
19
19
  }
20
20
 
21
- .isJustifiedToCenter {
21
+ .isRootJustifiedToCenter {
22
22
  justify-content: center;
23
23
  }
24
24
 
25
- .isJustifiedToEnd {
25
+ .isRootJustifiedToEnd {
26
26
  justify-content: flex-end;
27
27
  }
28
28
 
29
- .isJustifiedToSpaceBetween {
29
+ .isRootJustifiedToSpaceBetween {
30
30
  justify-content: space-between;
31
31
  }
32
32
 
33
- .isJustifiedToStretch {
33
+ .isRootJustifiedToStretch {
34
34
  display: block;
35
35
  }
@@ -3,28 +3,28 @@ import React from 'react';
3
3
  import {
4
4
  withGlobalProps,
5
5
  } from '../../provider';
6
+ import { transferProps } from '../_helpers/transferProps';
6
7
  import { classNames } from '../../utils/classNames';
7
8
  import { getJustifyClassName } from './_helpers/getJustifyClassName';
8
9
  import styles from './ModalHeader.scss';
9
10
 
10
11
  export const ModalHeader = ({
11
12
  children,
12
- id,
13
13
  justify,
14
+ ...restProps
14
15
  }) => (
15
16
  <div
17
+ {...transferProps(restProps)}
16
18
  className={classNames(
17
19
  styles.root,
18
20
  getJustifyClassName(justify, styles),
19
21
  )}
20
- id={id}
21
22
  >
22
23
  {children}
23
24
  </div>
24
25
  );
25
26
 
26
27
  ModalHeader.defaultProps = {
27
- id: undefined,
28
28
  justify: 'space-between',
29
29
  };
30
30
 
@@ -33,10 +33,6 @@ ModalHeader.propTypes = {
33
33
  * Content of the header (preferably ModalTitle and ModalCloseButton).
34
34
  */
35
35
  children: PropTypes.node.isRequired,
36
- /**
37
- * ID of the root HTML element.
38
- */
39
- id: PropTypes.string,
40
36
  /**
41
37
  * Horizontal alignment (distribution) of individual buttons.
42
38
  */
@@ -9,22 +9,22 @@
9
9
  border-bottom: theme.$separator-width solid theme.$separator-color;
10
10
  }
11
11
 
12
- .isJustifiedToStart {
12
+ .isRootJustifiedToStart {
13
13
  justify-content: flex-start;
14
14
  }
15
15
 
16
- .isJustifiedToCenter {
16
+ .isRootJustifiedToCenter {
17
17
  justify-content: center;
18
18
  }
19
19
 
20
- .isJustifiedToEnd {
20
+ .isRootJustifiedToEnd {
21
21
  justify-content: flex-end;
22
22
  }
23
23
 
24
- .isJustifiedToSpaceBetween {
24
+ .isRootJustifiedToSpaceBetween {
25
25
  justify-content: space-between;
26
26
  }
27
27
 
28
- .isJustifiedToStretch {
28
+ .isRootJustifiedToStretch {
29
29
  display: block;
30
30
  }
@@ -3,24 +3,27 @@ import React from 'react';
3
3
  import {
4
4
  withGlobalProps,
5
5
  } from '../../provider';
6
+ import { transferProps } from '../_helpers/transferProps';
6
7
  import styles from './ModalTitle.scss';
7
8
 
8
9
  export const ModalTitle = ({
9
10
  children,
10
- id,
11
11
  level,
12
+ ...restProps
12
13
  }) => {
13
14
  const HeadingTag = `h${level}`;
14
15
 
15
16
  return (
16
- <HeadingTag className={styles.root} id={id}>
17
+ <HeadingTag
18
+ {...transferProps(restProps)}
19
+ className={styles.root}
20
+ >
17
21
  {children}
18
22
  </HeadingTag>
19
23
  );
20
24
  };
21
25
 
22
26
  ModalTitle.defaultProps = {
23
- id: undefined,
24
27
  level: 2,
25
28
  };
26
29
 
@@ -29,10 +32,6 @@ ModalTitle.propTypes = {
29
32
  * Content of the header (preferably ModalTitle and ModalCloseButton).
30
33
  */
31
34
  children: PropTypes.node.isRequired,
32
- /**
33
- * ID of the root HTML element.
34
- */
35
- id: PropTypes.string,
36
35
  /**
37
36
  * Optional heading level. Preferably `1` or `2` should be used, see
38
37
  * [W3C recommendation](https://github.com/w3c/aria-practices/issues/551#issuecomment-365134527).
@@ -1017,6 +1017,26 @@ opened.
1017
1017
 
1018
1018
  <!-- markdownlint-disable MD024 -->
1019
1019
 
1020
+ ## Forwarding HTML Attributes
1021
+
1022
+ In addition to the options below in the [component's API](#api) section, you
1023
+ can specify [React synthetic events] or **any HTML attribute you like.** All
1024
+ attributes that don't interfere with the API are forwarded to the:
1025
+
1026
+ - `<div>` HTML element in case of the `Modal` component. This `<div>` is not the
1027
+ root, but its first child which represents the modal window.
1028
+ - root `<div>` HTML element in case of `ModalHeader`, `ModalBody`, `ModalContent`
1029
+ and `ModalFooter` components.
1030
+ - heading HTML element, which level can be specified through `level` option, in
1031
+ case of the `ModalTitle` component.
1032
+ - native HTML `<button>` in case of the `ModalCloseButton` component.
1033
+
1034
+ This enables making the component interactive and helps to improve its
1035
+ accessibility.
1036
+
1037
+ 👉 Refer to the MDN reference for the full list of supported attributes of the
1038
+ [div], [heading] and [button] element.
1039
+
1020
1040
  ## API
1021
1041
 
1022
1042
  <Props table of={Modal} />
@@ -1068,3 +1088,8 @@ opened.
1068
1088
  | `--rui-Modal--large__width` | Width of large modal |
1069
1089
  | `--rui-Modal--fullscreen__width` | Width of fullscreen modal |
1070
1090
  | `--rui-Modal--fullscreen__height` | Height of fullscreen modal |
1091
+
1092
+ [React synthetic events]: https://reactjs.org/docs/events.html
1093
+ [div]: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/div#attributes
1094
+ [heading]: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/Heading_Elements#attributes
1095
+ [button]: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/button#attributes
@@ -1,19 +1,19 @@
1
1
  export const getJustifyClassName = (value, styles) => {
2
2
  if (value === 'start') {
3
- return styles.isJustifiedToStart;
3
+ return styles.isRootJustifiedToStart;
4
4
  }
5
5
 
6
6
  if (value === 'center') {
7
- return styles.isJustifiedToCenter;
7
+ return styles.isRootJustifiedToCenter;
8
8
  }
9
9
 
10
10
  if (value === 'end') {
11
- return styles.isJustifiedToEnd;
11
+ return styles.isRootJustifiedToEnd;
12
12
  }
13
13
 
14
14
  if (value === 'space-between') {
15
- return styles.isJustifiedToSpaceBetween;
15
+ return styles.isRootJustifiedToSpaceBetween;
16
16
  }
17
17
 
18
- return styles.isJustifiedToStretch;
18
+ return styles.isRootJustifiedToStretch;
19
19
  };