@react-ui-org/react-ui 0.48.0 → 0.49.0

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