@react-ui-org/react-ui 0.48.0 → 0.50.0
Sign up to get free protection for your applications and to get access to all the features.
- package/dist/lib.development.js +162 -66
- package/dist/lib.js +1 -1
- package/package.json +1 -1
- package/src/lib/components/Alert/Alert.jsx +3 -0
- package/src/lib/components/Alert/Alert.scss +10 -10
- package/src/lib/components/Alert/README.mdx +14 -0
- package/src/lib/components/Badge/Badge.jsx +4 -8
- package/src/lib/components/Badge/Badge.scss +21 -21
- package/src/lib/components/Badge/README.mdx +14 -0
- package/src/lib/components/Button/Button.jsx +2 -13
- package/src/lib/components/Button/README.mdx +17 -5
- package/src/lib/components/Button/_base.scss +20 -20
- package/src/lib/components/Button/_priorities.scss +35 -35
- package/src/lib/components/Button/helpers/getRootLabelVisibilityClassName.js +7 -7
- package/src/lib/components/Button/helpers/getRootPriorityClassName.js +3 -3
- package/src/lib/components/ButtonGroup/ButtonGroup.jsx +0 -7
- package/src/lib/components/ButtonGroup/README.mdx +14 -0
- package/src/lib/components/Card/Card.jsx +6 -10
- package/src/lib/components/Card/Card.scss +13 -13
- package/src/lib/components/Card/CardBody.jsx +6 -10
- package/src/lib/components/Card/CardFooter.jsx +6 -7
- package/src/lib/components/Card/README.mdx +14 -0
- package/src/lib/components/CheckboxField/CheckboxField.jsx +1 -27
- package/src/lib/components/CheckboxField/README.mdx +17 -5
- package/src/lib/components/FileInputField/FileInputField.jsx +2 -12
- package/src/lib/components/FileInputField/FileInputField.scss +3 -7
- package/src/lib/components/FileInputField/README.mdx +29 -27
- package/src/lib/components/FormLayout/FormLayout.jsx +5 -9
- package/src/lib/components/FormLayout/FormLayout.scss +3 -3
- package/src/lib/components/FormLayout/FormLayoutCustomField.jsx +4 -1
- package/src/lib/components/FormLayout/FormLayoutCustomField.scss +8 -8
- package/src/lib/components/FormLayout/README.mdx +13 -0
- package/src/lib/components/Grid/Grid.jsx +0 -7
- package/src/lib/components/Grid/GridSpan.jsx +0 -7
- package/src/lib/components/Grid/README.mdx +14 -0
- package/src/lib/components/Modal/Modal.jsx +7 -11
- package/src/lib/components/Modal/ModalBody.jsx +3 -7
- package/src/lib/components/Modal/ModalCloseButton.jsx +0 -16
- package/src/lib/components/Modal/ModalContent.jsx +3 -7
- package/src/lib/components/Modal/ModalFooter.jsx +3 -7
- package/src/lib/components/Modal/ModalFooter.scss +5 -5
- package/src/lib/components/Modal/ModalHeader.jsx +3 -7
- package/src/lib/components/Modal/ModalHeader.scss +5 -5
- package/src/lib/components/Modal/ModalTitle.jsx +6 -7
- package/src/lib/components/Modal/README.mdx +32 -6
- package/src/lib/components/Modal/_helpers/getJustifyClassName.js +5 -5
- package/src/lib/components/Paper/Paper.jsx +5 -9
- package/src/lib/components/Paper/Paper.scss +2 -2
- package/src/lib/components/Paper/README.mdx +14 -0
- package/src/lib/components/Popover/Popover.jsx +0 -16
- package/src/lib/components/Popover/PopoverWrapper.jsx +0 -7
- package/src/lib/components/Popover/README.mdx +19 -0
- package/src/lib/components/Radio/README.mdx +12 -5
- package/src/lib/components/Radio/Radio.jsx +2 -2
- package/src/lib/components/Radio/Radio.scss +3 -3
- package/src/lib/components/ScrollView/README.mdx +19 -0
- package/src/lib/components/ScrollView/ScrollView.jsx +11 -4
- package/src/lib/components/SelectField/README.mdx +17 -5
- package/src/lib/components/SelectField/SelectField.jsx +3 -22
- package/src/lib/components/SelectField/SelectField.scss +8 -8
- package/src/lib/components/Table/README.mdx +21 -7
- package/src/lib/components/Table/Table.jsx +43 -101
- package/src/lib/components/Table/Table.scss +0 -24
- package/src/lib/components/Table/_components/TableBodyCell/TableBodyCell.jsx +46 -0
- package/src/lib/components/Table/_components/TableBodyCell/index.js +1 -0
- package/src/lib/components/Table/_components/TableCell.scss +25 -0
- package/src/lib/components/Table/_components/TableHeaderCell/TableHeaderCell.jsx +71 -0
- package/src/lib/components/Table/_components/TableHeaderCell/index.js +1 -0
- package/src/lib/components/Tabs/README.mdx +16 -0
- package/src/lib/components/Tabs/Tabs.jsx +6 -1
- package/src/lib/components/Tabs/TabsItem.jsx +3 -0
- package/src/lib/components/Text/README.mdx +16 -0
- package/src/lib/components/Text/Text.jsx +3 -7
- package/src/lib/components/Text/Text.scss +6 -6
- package/src/lib/components/Text/_helpers/getRootClampClassName.js +2 -2
- package/src/lib/components/Text/_helpers/getRootHyphensClassName.js +2 -2
- package/src/lib/components/Text/_helpers/getRootWordWrappingClassName.js +2 -2
- package/src/lib/components/TextArea/README.mdx +33 -30
- package/src/lib/components/TextArea/TextArea.jsx +3 -43
- package/src/lib/components/TextArea/TextArea.scss +8 -8
- package/src/lib/components/TextField/README.mdx +53 -51
- package/src/lib/components/TextField/TextField.jsx +3 -29
- package/src/lib/components/TextField/TextField.scss +9 -9
- package/src/lib/components/TextLink/README.mdx +12 -5
- package/src/lib/components/TextLink/TextLink.jsx +0 -10
- package/src/lib/components/Toggle/README.mdx +17 -5
- package/src/lib/components/Toggle/Toggle.jsx +1 -27
- package/src/lib/components/Toolbar/README.mdx +13 -0
- package/src/lib/components/Toolbar/Toolbar.jsx +9 -43
- package/src/lib/components/Toolbar/Toolbar.scss +24 -12
- package/src/lib/components/Toolbar/ToolbarGroup.jsx +7 -26
- package/src/lib/components/Toolbar/ToolbarItem.jsx +3 -7
- package/src/lib/components/Toolbar/_helpers/getAlignClassName.js +19 -0
- package/src/lib/components/Toolbar/_helpers/getJustifyClassName.js +16 -0
- package/src/lib/components/_helpers/getRootColorClassName.js +10 -10
- package/src/lib/components/_helpers/getRootSizeClassName.js +3 -3
- package/src/lib/styles/generic/_forms.scss +10 -6
- package/src/lib/styles/theme/_accessibility.scss +2 -0
- package/src/lib/styles/theme/_form-fields.scss +1 -0
- package/src/lib/styles/tools/_accessibility.scss +2 -0
- package/src/lib/styles/tools/form-fields/_box-field-layout.scss +15 -15
- package/src/lib/styles/tools/form-fields/_foundation.scss +2 -0
- package/src/lib/styles/tools/form-fields/_inline-field-elements.scss +1 -1
- package/src/lib/styles/tools/form-fields/_inline-field-layout.scss +9 -9
- package/src/lib/theme.scss +4 -1
@@ -24,14 +24,14 @@
|
|
24
24
|
@include spacing.bottom(layouts);
|
25
25
|
}
|
26
26
|
|
27
|
-
.
|
28
|
-
.
|
27
|
+
.isRootFieldLayoutVertical,
|
28
|
+
.isRootFieldLayoutHorizontal {
|
29
29
|
display: grid;
|
30
30
|
grid-template-columns: var(--rui-local-field-width);
|
31
31
|
grid-row-gap: theme.$row-gap;
|
32
32
|
}
|
33
33
|
|
34
|
-
.
|
34
|
+
.isRootFieldLayoutHorizontal {
|
35
35
|
@include breakpoint.up(forms.$horizontal-breakpoint) {
|
36
36
|
grid-template-columns: var(--rui-local-label-width) var(--rui-local-field-width); // 1.
|
37
37
|
}
|
@@ -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.
|
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
|
-
.
|
35
|
-
.
|
34
|
+
.isRootLayoutVertical,
|
35
|
+
.isRootLayoutHorizontal {
|
36
36
|
@include box-field-layout.vertical();
|
37
37
|
}
|
38
38
|
|
39
|
-
.
|
39
|
+
.isRootLayoutHorizontal {
|
40
40
|
@include box-field-layout.horizontal();
|
41
41
|
}
|
42
42
|
|
43
|
-
.
|
44
|
-
.
|
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
|
-
.
|
53
|
+
.isRootSizeSmall {
|
54
54
|
@include box-field-sizes.size(small);
|
55
55
|
}
|
56
56
|
|
57
|
-
.
|
57
|
+
.isRootSizeMedium {
|
58
58
|
@include box-field-sizes.size(medium);
|
59
59
|
}
|
60
60
|
|
61
|
-
.
|
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
|
|
@@ -109,7 +110,7 @@ export const Modal = ({
|
|
109
110
|
const childrenWrapperElement = childrenWrapperRef.current;
|
110
111
|
const childrenElements = childrenWrapperElement.querySelectorAll('*');
|
111
112
|
const formFieldEl = Array.from(childrenElements).find(
|
112
|
-
(element) => ['INPUT', 'TEXTAREA', 'SELECT'].includes(element.nodeName),
|
113
|
+
(element) => ['INPUT', 'TEXTAREA', 'SELECT'].includes(element.nodeName) && !element.disabled,
|
113
114
|
);
|
114
115
|
|
115
116
|
if (formFieldEl) {
|
@@ -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
|
-
|
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
|
-
.
|
17
|
+
.isRootJustifiedToStart {
|
18
18
|
justify-content: flex-start;
|
19
19
|
}
|
20
20
|
|
21
|
-
.
|
21
|
+
.isRootJustifiedToCenter {
|
22
22
|
justify-content: center;
|
23
23
|
}
|
24
24
|
|
25
|
-
.
|
25
|
+
.isRootJustifiedToEnd {
|
26
26
|
justify-content: flex-end;
|
27
27
|
}
|
28
28
|
|
29
|
-
.
|
29
|
+
.isRootJustifiedToSpaceBetween {
|
30
30
|
justify-content: space-between;
|
31
31
|
}
|
32
32
|
|
33
|
-
.
|
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
|
-
.
|
12
|
+
.isRootJustifiedToStart {
|
13
13
|
justify-content: flex-start;
|
14
14
|
}
|
15
15
|
|
16
|
-
.
|
16
|
+
.isRootJustifiedToCenter {
|
17
17
|
justify-content: center;
|
18
18
|
}
|
19
19
|
|
20
|
-
.
|
20
|
+
.isRootJustifiedToEnd {
|
21
21
|
justify-content: flex-end;
|
22
22
|
}
|
23
23
|
|
24
|
-
.
|
24
|
+
.isRootJustifiedToSpaceBetween {
|
25
25
|
justify-content: space-between;
|
26
26
|
}
|
27
27
|
|
28
|
-
.
|
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
|
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).
|
@@ -115,10 +115,10 @@ See [API](#api) for all available options.
|
|
115
115
|
- **Modal actions** should correspond to the modal purpose, too. E.g. “Delete”
|
116
116
|
tells better what happens rather than “OK”.
|
117
117
|
|
118
|
-
- Modal **automatically focuses the first form field** by default
|
119
|
-
users to confirm the modal by hitting the enter key. When no
|
120
|
-
then the primary button (in the footer) is focused. To turn
|
121
|
-
set the `autofocus` prop to `false`.
|
118
|
+
- Modal **automatically focuses the first non-disabled form field** by default
|
119
|
+
which allows users to confirm the modal by hitting the enter key. When no
|
120
|
+
field is found then the primary button (in the footer) is focused. To turn
|
121
|
+
this feature off, set the `autofocus` prop to `false`.
|
122
122
|
|
123
123
|
- **Avoid stacking** of modals. While it may technically work, the modal is just
|
124
124
|
not designed for that.
|
@@ -841,8 +841,9 @@ Autofocus is implemented to enhance the user experience by automatically
|
|
841
841
|
focussing an element within the modal.
|
842
842
|
|
843
843
|
How does it work? It tries to find `input`, `textarea`, and `select` elements
|
844
|
-
inside of Modal and moves focus
|
845
|
-
`primaryButtonRef` prop on Modal is set, then the primary button
|
844
|
+
inside of Modal and moves focus onto the first non-disabled one. If none is
|
845
|
+
found and the `primaryButtonRef` prop on Modal is set, then the primary button
|
846
|
+
is focused.
|
846
847
|
|
847
848
|
Autofocus is enabled by default, so if you want to control the focus of
|
848
849
|
elements manually, set the `autoFocus` prop on Modal to `false`.
|
@@ -1017,6 +1018,26 @@ opened.
|
|
1017
1018
|
|
1018
1019
|
<!-- markdownlint-disable MD024 -->
|
1019
1020
|
|
1021
|
+
## Forwarding HTML Attributes
|
1022
|
+
|
1023
|
+
In addition to the options below in the [component's API](#api) section, you
|
1024
|
+
can specify [React synthetic events] or **any HTML attribute you like.** All
|
1025
|
+
attributes that don't interfere with the API are forwarded to the:
|
1026
|
+
|
1027
|
+
- `<div>` HTML element in case of the `Modal` component. This `<div>` is not the
|
1028
|
+
root, but its first child which represents the modal window.
|
1029
|
+
- root `<div>` HTML element in case of `ModalHeader`, `ModalBody`, `ModalContent`
|
1030
|
+
and `ModalFooter` components.
|
1031
|
+
- heading HTML element, which level can be specified through `level` option, in
|
1032
|
+
case of the `ModalTitle` component.
|
1033
|
+
- native HTML `<button>` in case of the `ModalCloseButton` component.
|
1034
|
+
|
1035
|
+
This enables making the component interactive and helps to improve its
|
1036
|
+
accessibility.
|
1037
|
+
|
1038
|
+
👉 Refer to the MDN reference for the full list of supported attributes of the
|
1039
|
+
[div], [heading] and [button] element.
|
1040
|
+
|
1020
1041
|
## API
|
1021
1042
|
|
1022
1043
|
<Props table of={Modal} />
|
@@ -1068,3 +1089,8 @@ opened.
|
|
1068
1089
|
| `--rui-Modal--large__width` | Width of large modal |
|
1069
1090
|
| `--rui-Modal--fullscreen__width` | Width of fullscreen modal |
|
1070
1091
|
| `--rui-Modal--fullscreen__height` | Height of fullscreen modal |
|
1092
|
+
|
1093
|
+
[React synthetic events]: https://reactjs.org/docs/events.html
|
1094
|
+
[div]: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/div#attributes
|
1095
|
+
[heading]: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/Heading_Elements#attributes
|
1096
|
+
[button]: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/button#attributes
|