@react-ui-org/react-ui 0.47.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.
- package/dist/lib.development.js +465 -93
- 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 +18 -2
- package/src/lib/components/Alert/index.js +1 -1
- 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 +15 -1
- package/src/lib/components/Badge/index.js +1 -1
- package/src/lib/components/Button/Button.jsx +23 -34
- package/src/lib/components/Button/README.mdx +21 -7
- 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/Button/index.js +1 -1
- package/src/lib/components/ButtonGroup/ButtonGroup.jsx +2 -8
- package/src/lib/components/ButtonGroup/README.mdx +18 -2
- 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 +21 -5
- package/src/lib/components/CheckboxField/CheckboxField.jsx +17 -44
- package/src/lib/components/CheckboxField/README.mdx +18 -6
- package/src/lib/components/CheckboxField/index.js +1 -1
- package/src/lib/components/FileInputField/FileInputField.jsx +20 -29
- package/src/lib/components/FileInputField/FileInputField.scss +3 -3
- package/src/lib/components/FileInputField/README.mdx +30 -28
- package/src/lib/components/FileInputField/index.js +1 -1
- 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 +28 -13
- package/src/lib/components/Grid/Grid.jsx +31 -35
- package/src/lib/components/Grid/Grid.scss +10 -15
- package/src/lib/components/Grid/GridSpan.jsx +5 -11
- package/src/lib/components/Grid/README.mdx +48 -36
- package/src/lib/components/Grid/_helpers/generateResponsiveCustomProperties.js +11 -3
- package/src/lib/components/Grid/_settings.scss +18 -0
- package/src/lib/components/Grid/_tools.scss +5 -5
- package/src/lib/components/Modal/Modal.jsx +147 -254
- package/src/lib/components/Modal/Modal.scss +7 -55
- package/src/lib/components/Modal/ModalBody.jsx +60 -0
- package/src/lib/components/Modal/ModalBody.scss +18 -0
- package/src/lib/components/Modal/ModalCloseButton.jsx +45 -0
- package/src/lib/components/Modal/ModalCloseButton.scss +18 -0
- package/src/lib/components/Modal/ModalContent.jsx +39 -0
- package/src/lib/components/Modal/ModalContent.scss +5 -0
- package/src/lib/components/Modal/ModalFooter.jsx +42 -0
- package/src/lib/components/Modal/ModalFooter.scss +35 -0
- package/src/lib/components/Modal/ModalHeader.jsx +44 -0
- package/src/lib/components/Modal/ModalHeader.scss +30 -0
- package/src/lib/components/Modal/ModalTitle.jsx +44 -0
- package/src/lib/components/Modal/ModalTitle.scss +10 -0
- package/src/lib/components/Modal/README.mdx +865 -195
- package/src/lib/components/Modal/_helpers/getJustifyClassName.js +19 -0
- package/src/lib/components/Modal/_helpers/getScrollingClassName.js +11 -0
- package/src/lib/components/Modal/_settings.scss +1 -5
- package/src/lib/components/Modal/_theme.scss +6 -0
- package/src/lib/components/Modal/index.js +7 -1
- 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 +15 -1
- package/src/lib/components/Paper/index.js +1 -1
- package/src/lib/components/Popover/Popover.jsx +14 -30
- package/src/lib/components/Popover/Popover.scss +7 -6
- package/src/lib/components/Popover/PopoverWrapper.jsx +5 -12
- package/src/lib/components/Popover/PopoverWrapper.scss +3 -0
- package/src/lib/components/Popover/README.mdx +32 -11
- package/src/lib/components/Popover/_theme.scss +1 -1
- package/src/lib/components/Radio/README.mdx +13 -6
- package/src/lib/components/Radio/Radio.jsx +39 -29
- package/src/lib/components/Radio/Radio.scss +3 -3
- package/src/lib/components/Radio/index.js +1 -1
- package/src/lib/components/ScrollView/README.mdx +165 -84
- package/src/lib/components/ScrollView/ScrollView.jsx +115 -117
- package/src/lib/components/ScrollView/ScrollView.scss +18 -16
- package/src/lib/components/ScrollView/index.js +1 -1
- package/src/lib/components/SelectField/README.mdx +83 -7
- package/src/lib/components/SelectField/SelectField.jsx +86 -61
- package/src/lib/components/SelectField/SelectField.scss +8 -8
- package/src/lib/components/SelectField/_components/Option/Option.jsx +46 -0
- package/src/lib/components/SelectField/_components/Option/index.js +1 -0
- package/src/lib/components/SelectField/index.js +1 -1
- package/src/lib/components/Table/README.mdx +25 -9
- 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/Table/index.js +1 -1
- package/src/lib/components/Tabs/README.mdx +21 -3
- package/src/lib/components/Tabs/Tabs.jsx +6 -1
- package/src/lib/components/Tabs/TabsItem.jsx +3 -0
- package/src/lib/components/Tabs/TabsItem.scss +1 -2
- package/src/lib/components/Text/README.mdx +25 -7
- 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/Text/index.js +1 -1
- package/src/lib/components/TextArea/README.mdx +34 -31
- package/src/lib/components/TextArea/TextArea.jsx +23 -63
- package/src/lib/components/TextArea/TextArea.scss +8 -8
- package/src/lib/components/TextArea/index.js +1 -1
- package/src/lib/components/TextField/README.mdx +56 -54
- package/src/lib/components/TextField/TextField.jsx +25 -52
- package/src/lib/components/TextField/TextField.scss +9 -9
- package/src/lib/components/TextField/index.js +1 -1
- package/src/lib/components/TextLink/README.mdx +13 -6
- package/src/lib/components/TextLink/TextLink.jsx +0 -10
- package/src/lib/components/TextLink/index.js +1 -1
- package/src/lib/components/Toggle/README.mdx +18 -6
- package/src/lib/components/Toggle/Toggle.jsx +18 -44
- package/src/lib/components/Toggle/index.js +1 -1
- package/src/lib/components/Toolbar/README.mdx +21 -6
- 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/components/_helpers/transferProps.js +1 -1
- package/src/lib/index.js +24 -16
- package/src/lib/provider/withGlobalProps.jsx +20 -3
- package/src/lib/styles/tools/form-fields/_box-field-layout.scss +15 -15
- 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 +18 -26
- package/src/lib/translations/en.js +1 -1
- package/src/lib/components/Grid/_theme.scss +0 -11
- package/src/lib/components/ScrollView/_theme.scss +0 -2
- package/src/lib/components/withForwardedRef.jsx +0 -11
|
@@ -7,27 +7,27 @@ import { getRootValidationStateClassName } from '../_helpers/getRootValidationSt
|
|
|
7
7
|
import { resolveContextOrProp } from '../_helpers/resolveContextOrProp';
|
|
8
8
|
import { transferProps } from '../_helpers/transferProps';
|
|
9
9
|
import { FormLayoutContext } from '../FormLayout';
|
|
10
|
-
import
|
|
10
|
+
import { Option } from './_components/Option';
|
|
11
11
|
import styles from './SelectField.scss';
|
|
12
12
|
|
|
13
|
-
export const SelectField = ({
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
13
|
+
export const SelectField = React.forwardRef((props, ref) => {
|
|
14
|
+
const {
|
|
15
|
+
disabled,
|
|
16
|
+
fullWidth,
|
|
17
|
+
helpText,
|
|
18
|
+
id,
|
|
19
|
+
isLabelVisible,
|
|
20
|
+
label,
|
|
21
|
+
layout,
|
|
22
|
+
options,
|
|
23
|
+
required,
|
|
24
|
+
size,
|
|
25
|
+
validationState,
|
|
26
|
+
validationText,
|
|
27
|
+
variant,
|
|
28
|
+
...restProps
|
|
29
|
+
} = props;
|
|
30
|
+
|
|
31
31
|
const context = useContext(FormLayoutContext);
|
|
32
32
|
|
|
33
33
|
return (
|
|
@@ -37,13 +37,13 @@ export const SelectField = ({
|
|
|
37
37
|
fullWidth && styles.isRootFullWidth,
|
|
38
38
|
context && styles.isRootInFormLayout,
|
|
39
39
|
resolveContextOrProp(context && context.layout, layout) === 'horizontal'
|
|
40
|
-
? styles.
|
|
41
|
-
: styles.
|
|
40
|
+
? styles.isRootLayoutHorizontal
|
|
41
|
+
: styles.isRootLayoutVertical,
|
|
42
42
|
disabled && styles.isRootDisabled,
|
|
43
43
|
required && styles.isRootRequired,
|
|
44
44
|
getRootSizeClassName(size, styles),
|
|
45
45
|
getRootValidationStateClassName(validationState, styles),
|
|
46
|
-
variant === 'filled' ? styles.
|
|
46
|
+
variant === 'filled' ? styles.isRootVariantFilled : styles.isRootVariantOutline,
|
|
47
47
|
)}
|
|
48
48
|
htmlFor={id}
|
|
49
49
|
id={id && `${id}__label`}
|
|
@@ -64,21 +64,35 @@ export const SelectField = ({
|
|
|
64
64
|
className={styles.input}
|
|
65
65
|
disabled={disabled}
|
|
66
66
|
id={id}
|
|
67
|
-
ref={
|
|
67
|
+
ref={ref}
|
|
68
68
|
required={required}
|
|
69
|
-
value={value}
|
|
70
69
|
>
|
|
71
70
|
{
|
|
72
|
-
options.map((option) =>
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
71
|
+
options.map((option) => {
|
|
72
|
+
if ('options' in option) {
|
|
73
|
+
return (
|
|
74
|
+
<optgroup
|
|
75
|
+
key={option.key ?? option.label}
|
|
76
|
+
label={option.label}
|
|
77
|
+
>
|
|
78
|
+
{option.options.map((optgroupOption) => (
|
|
79
|
+
<Option
|
|
80
|
+
key={optgroupOption.key ?? optgroupOption.value}
|
|
81
|
+
{...optgroupOption}
|
|
82
|
+
{...(id && { id: `${id}__item__${optgroupOption.key ?? optgroupOption.value}` })}
|
|
83
|
+
/>
|
|
84
|
+
))}
|
|
85
|
+
</optgroup>
|
|
86
|
+
);
|
|
87
|
+
}
|
|
88
|
+
return (
|
|
89
|
+
<Option
|
|
90
|
+
key={option.key ?? option.value}
|
|
91
|
+
{...option}
|
|
92
|
+
{...(id && { id: `${id}__item__${option.key ?? option.value}` })}
|
|
93
|
+
/>
|
|
94
|
+
);
|
|
95
|
+
})
|
|
82
96
|
}
|
|
83
97
|
</select>
|
|
84
98
|
<div className={styles.caret}>
|
|
@@ -107,11 +121,10 @@ export const SelectField = ({
|
|
|
107
121
|
</div>
|
|
108
122
|
</label>
|
|
109
123
|
);
|
|
110
|
-
};
|
|
124
|
+
});
|
|
111
125
|
|
|
112
126
|
SelectField.defaultProps = {
|
|
113
127
|
disabled: false,
|
|
114
|
-
forwardedRef: undefined,
|
|
115
128
|
fullWidth: false,
|
|
116
129
|
helpText: null,
|
|
117
130
|
id: undefined,
|
|
@@ -121,7 +134,6 @@ SelectField.defaultProps = {
|
|
|
121
134
|
size: 'medium',
|
|
122
135
|
validationState: null,
|
|
123
136
|
validationText: null,
|
|
124
|
-
value: undefined,
|
|
125
137
|
variant: 'outline',
|
|
126
138
|
};
|
|
127
139
|
|
|
@@ -130,14 +142,6 @@ SelectField.propTypes = {
|
|
|
130
142
|
* If `true`, the input will be disabled.
|
|
131
143
|
*/
|
|
132
144
|
disabled: PropTypes.bool,
|
|
133
|
-
/**
|
|
134
|
-
* Reference forwarded to the `select` element.
|
|
135
|
-
*/
|
|
136
|
-
forwardedRef: PropTypes.oneOfType([
|
|
137
|
-
PropTypes.func,
|
|
138
|
-
// eslint-disable-next-line react/forbid-prop-types
|
|
139
|
-
PropTypes.shape({ current: PropTypes.any }),
|
|
140
|
-
]),
|
|
141
145
|
/**
|
|
142
146
|
* If `true`, the field will span the full width of its parent.
|
|
143
147
|
*/
|
|
@@ -157,6 +161,9 @@ SelectField.propTypes = {
|
|
|
157
161
|
*
|
|
158
162
|
* and of individual options:
|
|
159
163
|
* * `<ID>__item__<VALUE>`
|
|
164
|
+
*
|
|
165
|
+
* If `key` in the option definition object is set,
|
|
166
|
+
* then `option.key` is used instead of `option.value` in place of `<VALUE>`.
|
|
160
167
|
*/
|
|
161
168
|
id: PropTypes.string,
|
|
162
169
|
/**
|
|
@@ -177,15 +184,40 @@ SelectField.propTypes = {
|
|
|
177
184
|
layout: PropTypes.oneOf(['horizontal', 'vertical']),
|
|
178
185
|
/**
|
|
179
186
|
* Set of options to be chosen from.
|
|
187
|
+
*
|
|
188
|
+
* Either set of individual or grouped options is acceptable.
|
|
189
|
+
*
|
|
190
|
+
* For generating unique IDs the `option.value` is normally used. For cases when this is not practical or
|
|
191
|
+
* the `option.value` values are not unique the `option.key` attribute can be set manually.
|
|
192
|
+
* The same applies for the `label` value of grouped options which is supposed to be unique.
|
|
193
|
+
* To ensure uniqueness `key` attribute can be set manually.
|
|
180
194
|
*/
|
|
181
|
-
options: PropTypes.
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
195
|
+
options: PropTypes.oneOfType([
|
|
196
|
+
PropTypes.arrayOf(
|
|
197
|
+
PropTypes.shape({
|
|
198
|
+
key: PropTypes.string,
|
|
199
|
+
label: PropTypes.string.isRequired,
|
|
200
|
+
options: PropTypes.arrayOf(PropTypes.shape({
|
|
201
|
+
disabled: PropTypes.bool,
|
|
202
|
+
key: PropTypes.string,
|
|
203
|
+
label: PropTypes.string.isRequired,
|
|
204
|
+
value: PropTypes.oneOfType([
|
|
205
|
+
PropTypes.string,
|
|
206
|
+
PropTypes.number,
|
|
207
|
+
]),
|
|
208
|
+
})),
|
|
209
|
+
}),
|
|
210
|
+
),
|
|
211
|
+
PropTypes.arrayOf(PropTypes.shape({
|
|
212
|
+
disabled: PropTypes.bool,
|
|
213
|
+
key: PropTypes.string,
|
|
214
|
+
label: PropTypes.string.isRequired,
|
|
215
|
+
value: PropTypes.oneOfType([
|
|
216
|
+
PropTypes.string,
|
|
217
|
+
PropTypes.number,
|
|
218
|
+
]),
|
|
219
|
+
})),
|
|
220
|
+
]).isRequired,
|
|
189
221
|
/**
|
|
190
222
|
* If `true`, the input will be required.
|
|
191
223
|
*/
|
|
@@ -202,19 +234,12 @@ SelectField.propTypes = {
|
|
|
202
234
|
* Validation message to be displayed.
|
|
203
235
|
*/
|
|
204
236
|
validationText: PropTypes.node,
|
|
205
|
-
/**
|
|
206
|
-
* Value of the input.
|
|
207
|
-
*/
|
|
208
|
-
value: PropTypes.oneOfType([
|
|
209
|
-
PropTypes.string,
|
|
210
|
-
PropTypes.number,
|
|
211
|
-
]),
|
|
212
237
|
/**
|
|
213
238
|
* Design variant of the field, further customizable with CSS custom properties.
|
|
214
239
|
*/
|
|
215
240
|
variant: PropTypes.oneOf(['filled', 'outline']),
|
|
216
241
|
};
|
|
217
242
|
|
|
218
|
-
export const SelectFieldWithGlobalProps =
|
|
243
|
+
export const SelectFieldWithGlobalProps = withGlobalProps(SelectField, 'SelectField');
|
|
219
244
|
|
|
220
245
|
export default SelectFieldWithGlobalProps;
|
|
@@ -46,11 +46,11 @@
|
|
|
46
46
|
}
|
|
47
47
|
|
|
48
48
|
// Variants
|
|
49
|
-
.
|
|
49
|
+
.isRootVariantFilled {
|
|
50
50
|
@include variants.visual(box, $variant: filled, $has-caret: true);
|
|
51
51
|
}
|
|
52
52
|
|
|
53
|
-
.
|
|
53
|
+
.isRootVariantOutline {
|
|
54
54
|
@include variants.visual(box, $variant: outline, $has-caret: true);
|
|
55
55
|
}
|
|
56
56
|
|
|
@@ -73,12 +73,12 @@
|
|
|
73
73
|
}
|
|
74
74
|
|
|
75
75
|
// Layouts
|
|
76
|
-
.
|
|
77
|
-
.
|
|
76
|
+
.isRootLayoutVertical,
|
|
77
|
+
.isRootLayoutHorizontal {
|
|
78
78
|
@include box-field-layout.vertical();
|
|
79
79
|
}
|
|
80
80
|
|
|
81
|
-
.
|
|
81
|
+
.isRootLayoutHorizontal {
|
|
82
82
|
@include box-field-layout.horizontal();
|
|
83
83
|
}
|
|
84
84
|
|
|
@@ -91,14 +91,14 @@
|
|
|
91
91
|
}
|
|
92
92
|
|
|
93
93
|
// Sizes
|
|
94
|
-
.
|
|
94
|
+
.isRootSizeSmall {
|
|
95
95
|
@include box-field-sizes.size(small);
|
|
96
96
|
}
|
|
97
97
|
|
|
98
|
-
.
|
|
98
|
+
.isRootSizeMedium {
|
|
99
99
|
@include box-field-sizes.size(medium);
|
|
100
100
|
}
|
|
101
101
|
|
|
102
|
-
.
|
|
102
|
+
.isRootSizeLarge {
|
|
103
103
|
@include box-field-sizes.size(large);
|
|
104
104
|
}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import PropTypes from 'prop-types';
|
|
2
|
+
import React from 'react';
|
|
3
|
+
|
|
4
|
+
export const Option = ({
|
|
5
|
+
disabled,
|
|
6
|
+
id,
|
|
7
|
+
label,
|
|
8
|
+
value,
|
|
9
|
+
}) => (
|
|
10
|
+
<option
|
|
11
|
+
disabled={disabled}
|
|
12
|
+
id={id}
|
|
13
|
+
value={value}
|
|
14
|
+
>
|
|
15
|
+
{label}
|
|
16
|
+
</option>
|
|
17
|
+
);
|
|
18
|
+
|
|
19
|
+
Option.defaultProps = {
|
|
20
|
+
disabled: false,
|
|
21
|
+
id: undefined,
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
Option.propTypes = {
|
|
25
|
+
/**
|
|
26
|
+
* If `true` the option cannot be selected.
|
|
27
|
+
*/
|
|
28
|
+
disabled: PropTypes.bool,
|
|
29
|
+
/**
|
|
30
|
+
* ID of an individual option.
|
|
31
|
+
*/
|
|
32
|
+
id: PropTypes.string,
|
|
33
|
+
/**
|
|
34
|
+
* Option label.
|
|
35
|
+
*/
|
|
36
|
+
label: PropTypes.string.isRequired,
|
|
37
|
+
/**
|
|
38
|
+
* Option value.
|
|
39
|
+
*/
|
|
40
|
+
value: PropTypes.oneOfType([
|
|
41
|
+
PropTypes.string,
|
|
42
|
+
PropTypes.number,
|
|
43
|
+
]).isRequired,
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
export default Option;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default as Option } from './Option';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export { default } from './SelectField';
|
|
1
|
+
export { default as SelectField } from './SelectField';
|
|
@@ -13,8 +13,10 @@ import {
|
|
|
13
13
|
Props,
|
|
14
14
|
} from 'docz'
|
|
15
15
|
import Icon from '../../../docs/_components/Icon'
|
|
16
|
-
import
|
|
17
|
-
|
|
16
|
+
import {
|
|
17
|
+
ScrollView,
|
|
18
|
+
Table,
|
|
19
|
+
} from '../..'
|
|
18
20
|
|
|
19
21
|
## Basic Usage
|
|
20
22
|
|
|
@@ -38,7 +40,7 @@ And use it:
|
|
|
38
40
|
name: 'name',
|
|
39
41
|
},
|
|
40
42
|
{
|
|
41
|
-
format: (
|
|
43
|
+
format: (date) => date.toLocaleDateString('en-GB'),
|
|
42
44
|
label: 'Date of birth',
|
|
43
45
|
name: 'dateOfBirth',
|
|
44
46
|
},
|
|
@@ -97,21 +99,21 @@ The easiest way to make tables responsive is to wrap them with the
|
|
|
97
99
|
name: 'id',
|
|
98
100
|
},
|
|
99
101
|
{
|
|
100
|
-
format: (
|
|
101
|
-
<span style={{ whiteSpace: 'nowrap' }}>{
|
|
102
|
+
format: (name) => (
|
|
103
|
+
<span style={{ whiteSpace: 'nowrap' }}>{name}</span>
|
|
102
104
|
),
|
|
103
105
|
label: 'Name',
|
|
104
106
|
name: 'name',
|
|
105
107
|
},
|
|
106
108
|
{
|
|
107
|
-
format: (
|
|
108
|
-
<span style={{ whiteSpace: 'nowrap' }}>{
|
|
109
|
+
format: (note) => (
|
|
110
|
+
<span style={{ whiteSpace: 'nowrap' }}>{note}</span>
|
|
109
111
|
),
|
|
110
112
|
label: 'Note',
|
|
111
113
|
name: 'note',
|
|
112
114
|
},
|
|
113
115
|
{
|
|
114
|
-
format: (
|
|
116
|
+
format: (date) => date.toLocaleDateString('en-GB'),
|
|
115
117
|
label: 'Date of birth',
|
|
116
118
|
name: 'dateOfBirth',
|
|
117
119
|
},
|
|
@@ -228,7 +230,7 @@ The following is an example of custom sorting function executed on the client.
|
|
|
228
230
|
name: 'name',
|
|
229
231
|
},
|
|
230
232
|
{
|
|
231
|
-
format: (
|
|
233
|
+
format: (date) => date.toISOString(),
|
|
232
234
|
isSortable: true,
|
|
233
235
|
label: 'Date of birth',
|
|
234
236
|
name: 'dateOfBirth',
|
|
@@ -254,6 +256,20 @@ The following is an example of custom sorting function executed on the client.
|
|
|
254
256
|
}}
|
|
255
257
|
</Playground>
|
|
256
258
|
|
|
259
|
+
## Forwarding HTML Attributes
|
|
260
|
+
|
|
261
|
+
In addition to the options below in the [component's API](#api) section, you
|
|
262
|
+
can specify [React synthetic events] or **any HTML attribute you like.** All
|
|
263
|
+
attributes that don't interfere with the API are forwarded to the `<table>` HTML
|
|
264
|
+
element. This enables making the component interactive and helps to improve its
|
|
265
|
+
accessibility.
|
|
266
|
+
|
|
267
|
+
👉 Refer to the MDN reference for the full list of supported attributes of the
|
|
268
|
+
[table] element.
|
|
269
|
+
|
|
257
270
|
## API
|
|
258
271
|
|
|
259
272
|
<Props table of={Table} />
|
|
273
|
+
|
|
274
|
+
[React synthetic events]: https://reactjs.org/docs/events.html
|
|
275
|
+
[table]: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/table#attributes
|
|
@@ -1,110 +1,52 @@
|
|
|
1
1
|
import PropTypes from 'prop-types';
|
|
2
2
|
import React from 'react';
|
|
3
3
|
import { withGlobalProps } from '../../provider';
|
|
4
|
-
import
|
|
4
|
+
import { transferProps } from '../_helpers/transferProps';
|
|
5
|
+
import { TableHeaderCell } from './_components/TableHeaderCell';
|
|
6
|
+
import { TableBodyCell } from './_components/TableBodyCell';
|
|
5
7
|
import styles from './Table.scss';
|
|
6
8
|
|
|
7
|
-
export
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
labelVisibility="none"
|
|
42
|
-
onClick={() => sort.onClick(column.name, sortDirection)}
|
|
43
|
-
priority="flat"
|
|
44
|
-
{...(id && { id: `${id}__headerCell__${column.name}__sortButton` })}
|
|
9
|
+
export const Table = ({
|
|
10
|
+
columns,
|
|
11
|
+
id,
|
|
12
|
+
rows,
|
|
13
|
+
sort,
|
|
14
|
+
...restProps
|
|
15
|
+
}) => (
|
|
16
|
+
<table
|
|
17
|
+
{...transferProps(restProps)}
|
|
18
|
+
className={styles.table}
|
|
19
|
+
id={id}
|
|
20
|
+
>
|
|
21
|
+
<thead>
|
|
22
|
+
<tr className={styles.tableHeadRow}>
|
|
23
|
+
{columns.map((column) => (
|
|
24
|
+
<TableHeaderCell
|
|
25
|
+
column={column}
|
|
26
|
+
key={column.name}
|
|
27
|
+
sort={sort}
|
|
28
|
+
{...(id && { id: `${id}__headerCell__${column.name}` })}
|
|
29
|
+
/>
|
|
30
|
+
))}
|
|
31
|
+
</tr>
|
|
32
|
+
</thead>
|
|
33
|
+
<tbody>
|
|
34
|
+
{rows.map((row) => (
|
|
35
|
+
<tr key={row.id} className={styles.tableRow}>
|
|
36
|
+
{columns.map((column) => (
|
|
37
|
+
<TableBodyCell
|
|
38
|
+
format={column.format}
|
|
39
|
+
isSortingActive={sort && column.name === sort.column}
|
|
40
|
+
key={`${row.id}-${column.name}`}
|
|
41
|
+
value={row[column.name]}
|
|
42
|
+
{...(id && { id: `${id}__bodyCell__${column.name}__${row.id}` })}
|
|
45
43
|
/>
|
|
46
|
-
</div>
|
|
47
|
-
)}
|
|
48
|
-
{column.label}
|
|
49
|
-
</th>
|
|
50
|
-
);
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
renderBodyCell(column, row) {
|
|
54
|
-
const {
|
|
55
|
-
id,
|
|
56
|
-
sort,
|
|
57
|
-
} = this.props;
|
|
58
|
-
const isSortingActive = sort && column.name === sort.column;
|
|
59
|
-
|
|
60
|
-
if (column.format) {
|
|
61
|
-
return (
|
|
62
|
-
<td
|
|
63
|
-
className={isSortingActive ? styles.isTableCellSortingActive : styles.tableCell}
|
|
64
|
-
key={`${row.id}-${column.name}`}
|
|
65
|
-
{...(id && { id: `${id}__bodyCell__${column.name}__${row.id}` })}
|
|
66
|
-
>
|
|
67
|
-
{column.format(row)}
|
|
68
|
-
</td>
|
|
69
|
-
);
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
return (
|
|
73
|
-
<td
|
|
74
|
-
className={isSortingActive ? styles.isTableCellSortingActive : styles.tableCell}
|
|
75
|
-
key={`${row.id}-${column.name}`}
|
|
76
|
-
{...(id && { id: `${id}__bodyCell__${column.name}__${row.id}` })}
|
|
77
|
-
>
|
|
78
|
-
{row[column.name]}
|
|
79
|
-
</td>
|
|
80
|
-
);
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
render() {
|
|
84
|
-
const {
|
|
85
|
-
columns,
|
|
86
|
-
id,
|
|
87
|
-
rows,
|
|
88
|
-
} = this.props;
|
|
89
|
-
|
|
90
|
-
return (
|
|
91
|
-
<table id={id} className={styles.table}>
|
|
92
|
-
<thead>
|
|
93
|
-
<tr className={styles.tableHeadRow}>
|
|
94
|
-
{columns.map(this.renderHeaderCell)}
|
|
95
|
-
</tr>
|
|
96
|
-
</thead>
|
|
97
|
-
<tbody>
|
|
98
|
-
{rows.map((row) => (
|
|
99
|
-
<tr key={row.id} className={styles.tableRow}>
|
|
100
|
-
{columns.map((column) => this.renderBodyCell(column, row))}
|
|
101
|
-
</tr>
|
|
102
44
|
))}
|
|
103
|
-
</
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
45
|
+
</tr>
|
|
46
|
+
))}
|
|
47
|
+
</tbody>
|
|
48
|
+
</table>
|
|
49
|
+
);
|
|
108
50
|
|
|
109
51
|
Table.defaultProps = {
|
|
110
52
|
id: undefined,
|
|
@@ -123,7 +65,7 @@ Table.propTypes = {
|
|
|
123
65
|
name: PropTypes.string.isRequired,
|
|
124
66
|
})).isRequired,
|
|
125
67
|
/**
|
|
126
|
-
* ID of the root HTML element. It also serves as base
|
|
68
|
+
* ID of the root HTML element. It also serves as base for nested elements:
|
|
127
69
|
* * `<ID>__headerCell__<COLUMN_NAME>`
|
|
128
70
|
* * `<ID>__headerCell__<COLUMN_NAME>__sortButton`
|
|
129
71
|
* * `<ID>__bodyCell__<COLUMN_NAME>__<ROW_ID>`
|
|
@@ -26,27 +26,3 @@
|
|
|
26
26
|
background-color: settings.$head-background-color;
|
|
27
27
|
}
|
|
28
28
|
}
|
|
29
|
-
|
|
30
|
-
.tableCell,
|
|
31
|
-
.tableHeadCell,
|
|
32
|
-
.isTableCellSortingActive,
|
|
33
|
-
.isTableHeadCellSortingActive {
|
|
34
|
-
padding: settings.$cell-padding-y settings.$cell-padding-x;
|
|
35
|
-
text-align: left;
|
|
36
|
-
border-bottom: settings.$border-width solid settings.$border-color;
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
.tableHeadCell {
|
|
40
|
-
font-weight: settings.$head-font-weight;
|
|
41
|
-
border-bottom-width: 2px;
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
.isTableCellSortingActive,
|
|
45
|
-
.isTableHeadCellSortingActive {
|
|
46
|
-
background-color: settings.$sorted-background-color;
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
.sortButton {
|
|
50
|
-
display: inline-block;
|
|
51
|
-
margin-right: settings.$cell-padding-x;
|
|
52
|
-
}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import PropTypes from 'prop-types';
|
|
2
|
+
import React from 'react';
|
|
3
|
+
import styles from '../TableCell.scss';
|
|
4
|
+
|
|
5
|
+
export const TableBodyCell = ({
|
|
6
|
+
format,
|
|
7
|
+
id,
|
|
8
|
+
isSortingActive,
|
|
9
|
+
value,
|
|
10
|
+
}) => (
|
|
11
|
+
<td
|
|
12
|
+
className={isSortingActive ? styles.isTableCellSortingActive : styles.tableCell}
|
|
13
|
+
id={id}
|
|
14
|
+
>
|
|
15
|
+
{format ? format(value) : value}
|
|
16
|
+
</td>
|
|
17
|
+
);
|
|
18
|
+
|
|
19
|
+
TableBodyCell.defaultProps = {
|
|
20
|
+
format: undefined,
|
|
21
|
+
id: undefined,
|
|
22
|
+
isSortingActive: false,
|
|
23
|
+
value: null,
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
TableBodyCell.propTypes = {
|
|
27
|
+
/**
|
|
28
|
+
* Function that can be used to process the column data before displaying them.
|
|
29
|
+
*/
|
|
30
|
+
format: PropTypes.func,
|
|
31
|
+
/**
|
|
32
|
+
* ID of the HTML <td> element:
|
|
33
|
+
*/
|
|
34
|
+
id: PropTypes.string,
|
|
35
|
+
/**
|
|
36
|
+
* If `true`, cell is gray marked as sorted.
|
|
37
|
+
*/
|
|
38
|
+
isSortingActive: PropTypes.bool,
|
|
39
|
+
/**
|
|
40
|
+
* Cell value.
|
|
41
|
+
*/
|
|
42
|
+
// eslint-disable-next-line react/forbid-prop-types
|
|
43
|
+
value: PropTypes.any,
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
export default TableBodyCell;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default as TableBodyCell } from './TableBodyCell';
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
@use "../settings";
|
|
2
|
+
|
|
3
|
+
.tableCell,
|
|
4
|
+
.tableHeadCell,
|
|
5
|
+
.isTableCellSortingActive,
|
|
6
|
+
.isTableHeadCellSortingActive {
|
|
7
|
+
padding: settings.$cell-padding-y settings.$cell-padding-x;
|
|
8
|
+
text-align: left;
|
|
9
|
+
border-bottom: settings.$border-width solid settings.$border-color;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
.tableHeadCell {
|
|
13
|
+
font-weight: settings.$head-font-weight;
|
|
14
|
+
border-bottom-width: 2px;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
.isTableCellSortingActive,
|
|
18
|
+
.isTableHeadCellSortingActive {
|
|
19
|
+
background-color: settings.$sorted-background-color;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
.sortButton {
|
|
23
|
+
display: inline-block;
|
|
24
|
+
margin-right: settings.$cell-padding-x;
|
|
25
|
+
}
|