@react-ui-org/react-ui 0.48.0 → 0.50.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.
- 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
|