@react-ui-org/react-ui 0.59.3 → 0.61.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/.env.playwright +9 -0
- package/.env.playwright.dist +9 -0
- package/.eslintrc-ts +40 -0
- package/README.md +18 -1
- package/dist/react-ui.css +4 -4
- package/dist/react-ui.development.css +8 -0
- package/dist/react-ui.development.js +57 -47
- package/dist/react-ui.js +1 -1
- package/jest.config-ts.js +34 -0
- package/package.json +25 -6
- package/playwright-ct.config.ts +68 -0
- package/src/components/Alert/Alert.jsx +2 -2
- package/src/components/Button/Button.jsx +5 -5
- package/src/components/Button/README.md +1 -1
- package/src/components/ButtonGroup/ButtonGroup.jsx +2 -2
- package/src/components/Card/Card.module.scss +1 -0
- package/src/components/Card/CardFooter.jsx +2 -2
- package/src/components/Card/README.md +2 -0
- package/src/components/Card/_theme.scss +2 -0
- package/src/components/CheckboxField/CheckboxField.jsx +3 -3
- package/src/components/FileInputField/FileInputField.jsx +21 -8
- package/src/components/FileInputField/FileInputField.module.scss +4 -0
- package/src/components/FormLayout/FormLayout.jsx +2 -2
- package/src/components/FormLayout/FormLayoutCustomField.jsx +5 -5
- package/src/components/Grid/Grid.jsx +2 -2
- package/src/components/Grid/GridSpan.jsx +2 -2
- package/src/components/InputGroup/InputGroup.jsx +25 -5
- package/src/components/InputGroup/InputGroup.module.scss +2 -1
- package/src/components/InputGroup/README.md +69 -14
- package/src/components/Modal/Modal.jsx +26 -8
- package/src/components/Modal/ModalBody.jsx +2 -2
- package/src/components/Modal/ModalContent.jsx +2 -2
- package/src/components/Modal/_helpers/dialogOnClickHandler.js +6 -0
- package/src/components/Popover/Popover.jsx +5 -5
- package/src/components/Radio/Radio.jsx +3 -3
- package/src/components/ScrollView/ScrollView.jsx +42 -12
- package/src/components/ScrollView/_hooks/useScrollPositionHook.js +4 -4
- package/src/components/SelectField/SelectField.jsx +9 -6
- package/src/components/Table/Table.jsx +1 -1
- package/src/components/Table/_components/TableBodyCell/TableBodyCell.jsx +1 -1
- package/src/components/Table/_components/TableHeaderCell/TableHeaderCell.jsx +1 -1
- package/src/components/Tabs/TabsItem.jsx +3 -3
- package/src/components/Text/Text.jsx +2 -2
- package/src/components/TextArea/TextArea.jsx +3 -3
- package/src/components/TextField/TextField.jsx +11 -8
- package/src/components/Toggle/Toggle.jsx +3 -3
- package/src/components/Toolbar/Toolbar.jsx +2 -2
- package/src/components/Toolbar/ToolbarGroup.jsx +2 -2
- package/src/components/Toolbar/ToolbarItem.jsx +2 -2
- package/src/helpers/isChildrenEmpty/README.md +57 -0
- package/src/helpers/isChildrenEmpty/index.js +1 -0
- package/src/index.js +1 -0
- package/src/providers/globalProps/GlobalPropsProvider.jsx +1 -1
- package/src/providers/translations/TranslationsProvider.jsx +1 -1
- package/src/styles/settings/_breakpoints.scss +2 -0
- package/src/theme.scss +2 -0
- package/src/translations/en.js +1 -0
- package/tsconfig.json +27 -0
- /package/src/{components/_helpers → helpers/isChildrenEmpty}/isChildrenEmpty.js +0 -0
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
|
|
2
|
+
module.exports = {
|
|
3
|
+
extensionsToTreatAsEsm: [
|
|
4
|
+
'.ts',
|
|
5
|
+
'.tsx',
|
|
6
|
+
],
|
|
7
|
+
moduleFileExtensions: [
|
|
8
|
+
'js',
|
|
9
|
+
'jsx',
|
|
10
|
+
'ts',
|
|
11
|
+
'tsx',
|
|
12
|
+
],
|
|
13
|
+
moduleNameMapper: {
|
|
14
|
+
'\\.scss$': 'identity-obj-proxy',
|
|
15
|
+
'\\.svg$': '<rootDir>/tests/jest/mocks/svgrMock.jsx',
|
|
16
|
+
},
|
|
17
|
+
preset: 'ts-jest',
|
|
18
|
+
setupFiles: [
|
|
19
|
+
'<rootDir>/tests/jest/setupJest.js',
|
|
20
|
+
],
|
|
21
|
+
setupFilesAfterEnv: [
|
|
22
|
+
],
|
|
23
|
+
testEnvironment: '@happy-dom/jest-environment',
|
|
24
|
+
testMatch: [
|
|
25
|
+
'**/*.test.{ts,tsx}',
|
|
26
|
+
],
|
|
27
|
+
transform: {
|
|
28
|
+
'^.+\\.(ts|tsx)$': [
|
|
29
|
+
'ts-jest',
|
|
30
|
+
{ useESM: true },
|
|
31
|
+
],
|
|
32
|
+
},
|
|
33
|
+
verbose: true,
|
|
34
|
+
};
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@react-ui-org/react-ui",
|
|
3
3
|
"description": "React UI is a themeable UI library for React apps.",
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "0.61.0",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"react",
|
|
7
7
|
"ui",
|
|
@@ -47,17 +47,24 @@
|
|
|
47
47
|
"copy": "npm run copy:css && npm run copy:js",
|
|
48
48
|
"copy:css": "cp src/docs/_assets/generated/react-ui.css dist && cp src/docs/_assets/generated/react-ui.development.css dist",
|
|
49
49
|
"copy:js": "cp src/docs/_assets/generated/react-ui.js dist && cp src/docs/_assets/generated/react-ui.development.js dist",
|
|
50
|
-
"eslint": "eslint
|
|
51
|
-
"
|
|
50
|
+
"eslint": "npm run eslint:ts && npm run eslint:js",
|
|
51
|
+
"eslint:js": "eslint --ext js,jsx src",
|
|
52
|
+
"eslint:ts": "eslint --ext ts,tsx -c .eslintrc-ts src tests",
|
|
52
53
|
"lint": "npm run eslint && npm run markdownlint && npm run stylelint",
|
|
53
|
-
"markdownlint": "markdownlint-cli2 \"
|
|
54
|
+
"markdownlint": "markdownlint-cli2 \"README.md\" \"src/**/*.md\"",
|
|
54
55
|
"postbuild": "npm run copy",
|
|
55
|
-
"postinstall": "cp -n .env.dist .env || true",
|
|
56
|
+
"postinstall": "cp -n .env.dist .env && cp -n .env.playwright.dist .env.playwright || true",
|
|
56
57
|
"precopy": "rm -rf dist && mkdir dist",
|
|
57
58
|
"prepublishOnly": "npm run build",
|
|
58
59
|
"start": "webpack --watch --mode=development",
|
|
59
60
|
"stylelint": "stylelint \"src/**/*.{css,scss}\" \"!src/docs/_assets/generated/**\" --config stylelint.config.js",
|
|
60
|
-
"test": "npm run jest"
|
|
61
|
+
"test": "npm run test:jest",
|
|
62
|
+
"test:jest": "npm run test:jest:ts && npm run test:jest:js",
|
|
63
|
+
"test:jest:js": "jest --coverage",
|
|
64
|
+
"test:jest:ts": "jest -c jest.config-ts.js --coverage",
|
|
65
|
+
"test:playwright-ct:all": "playwright test -c playwright-ct.config.ts",
|
|
66
|
+
"test:playwright-ct:all-with-update": "playwright test -c playwright-ct.config.ts --update-snapshots",
|
|
67
|
+
"test:playwright-ct:show-report": "playwright show-report --host=0.0.0.0 --port=9323"
|
|
61
68
|
},
|
|
62
69
|
"dependencies": {
|
|
63
70
|
"normalize.css": "^8.0.1"
|
|
@@ -77,11 +84,18 @@
|
|
|
77
84
|
"@babel/preset-react": "^7.24.7",
|
|
78
85
|
"@babel/register": "^7.24.6",
|
|
79
86
|
"@happy-dom/jest-environment": "^16.6.0",
|
|
87
|
+
"@playwright/experimental-ct-react": "^1.50.1",
|
|
80
88
|
"@stylistic/stylelint-config": "^1.0.1",
|
|
81
89
|
"@svgr/webpack": "^8.1.0",
|
|
82
90
|
"@testing-library/jest-dom": "^6.6.3",
|
|
83
91
|
"@testing-library/react": "^16.1.0",
|
|
84
92
|
"@testing-library/user-event": "^14.5.2",
|
|
93
|
+
"@types/jest": "^29.5.14",
|
|
94
|
+
"@types/node": "^22.13.5",
|
|
95
|
+
"@types/react": "^19.0.10",
|
|
96
|
+
"@types/react-dom": "^19.0.4",
|
|
97
|
+
"@typescript-eslint/eslint-plugin": "^7.18.0",
|
|
98
|
+
"@typescript-eslint/parser": "^7.18.0",
|
|
85
99
|
"@visionappscz/eslint-config-visionapps": "^1.7.0",
|
|
86
100
|
"@visionappscz/stylelint-config": "^4.0.0",
|
|
87
101
|
"autoprefixer": "^10.4.19",
|
|
@@ -89,13 +103,17 @@
|
|
|
89
103
|
"babel-loader": "^9.1.3",
|
|
90
104
|
"core-js": "^3.37.1",
|
|
91
105
|
"css-loader": "^7.1.2",
|
|
106
|
+
"dotenv": "^16.4.7",
|
|
92
107
|
"eslint": "^8.57.0",
|
|
93
108
|
"eslint-config-airbnb": "^19.0.4",
|
|
109
|
+
"eslint-config-airbnb-typescript": "^18.0.0",
|
|
110
|
+
"eslint-plugin-deprecation": "^3.0.0",
|
|
94
111
|
"eslint-plugin-import": "^2.29.1",
|
|
95
112
|
"eslint-plugin-jsx-a11y": "^6.9.0",
|
|
96
113
|
"eslint-plugin-markdown": "^3.0.1",
|
|
97
114
|
"eslint-plugin-react": "^7.34.3",
|
|
98
115
|
"eslint-plugin-react-hooks": "^4.6.2",
|
|
116
|
+
"eslint-plugin-typescript-sort-keys": "^3.3.0",
|
|
99
117
|
"identity-obj-proxy": "^3.0.0",
|
|
100
118
|
"jest": "^29.7.0",
|
|
101
119
|
"markdownlint-cli2": "^0.13.0",
|
|
@@ -110,6 +128,7 @@
|
|
|
110
128
|
"stylelint": "^16.7.0",
|
|
111
129
|
"stylelint-webpack-plugin": "^5.0.1",
|
|
112
130
|
"terser-webpack-plugin": "^5.3.10",
|
|
131
|
+
"ts-jest": "^29.2.6",
|
|
113
132
|
"webpack": "^5.92.1",
|
|
114
133
|
"webpack-cli": "^5.1.4",
|
|
115
134
|
"webpack-visualizer-plugin2": "^1.1.0"
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import {
|
|
2
|
+
defineConfig,
|
|
3
|
+
devices,
|
|
4
|
+
} from '@playwright/experimental-ct-react';
|
|
5
|
+
import { parseEnvironment } from './tests/playwright/env/parseEnvironment';
|
|
6
|
+
|
|
7
|
+
const environment = parseEnvironment();
|
|
8
|
+
|
|
9
|
+
const isCI = !!process.env.CI;
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* @see https://playwright.dev/docs/test-configuration
|
|
13
|
+
*/
|
|
14
|
+
module.exports = defineConfig({
|
|
15
|
+
// Fail the build on CI if you accidentally left test.only in the source code
|
|
16
|
+
forbidOnly: isCI,
|
|
17
|
+
// Run tests in files in parallel
|
|
18
|
+
fullyParallel: true,
|
|
19
|
+
// Directory where the output generated by Playwright is stored
|
|
20
|
+
outputDir: './tests/playwright/.temp/playwright-ct-output/',
|
|
21
|
+
// Run tests for following projects
|
|
22
|
+
projects: [
|
|
23
|
+
{
|
|
24
|
+
name: 'chromium',
|
|
25
|
+
use: { ...devices['Desktop Chrome'] },
|
|
26
|
+
},
|
|
27
|
+
],
|
|
28
|
+
/* Reporter to use. See https://playwright.dev/docs/test-reporters */
|
|
29
|
+
reporter: 'html',
|
|
30
|
+
// Retry failed tests once to eliminate flakiness
|
|
31
|
+
retries: 1,
|
|
32
|
+
// Directory where the snapshots are located
|
|
33
|
+
// (must be same as testDir to save snapshots in place where tests are located)
|
|
34
|
+
snapshotDir: './src/',
|
|
35
|
+
// Directory where the tests are located
|
|
36
|
+
testDir: './src/',
|
|
37
|
+
// Pattern to search for test files
|
|
38
|
+
testMatch: '*/*.spec.{ts,tsx}',
|
|
39
|
+
// Timeout for each test
|
|
40
|
+
timeout: 10 * 1000,
|
|
41
|
+
// Do not update snapshots automatically
|
|
42
|
+
updateSnapshots: 'none',
|
|
43
|
+
// Configuration for Playwright component testing
|
|
44
|
+
use: {
|
|
45
|
+
// Directory where the cache is stored
|
|
46
|
+
ctCacheDir: './tests/playwright/.temp/playwright-ct-cache',
|
|
47
|
+
// Port to use for Playwright component endpoint
|
|
48
|
+
ctPort: environment.CT_PORT,
|
|
49
|
+
// Directory where the templates are stored
|
|
50
|
+
ctTemplateDir: './tests/playwright/templates',
|
|
51
|
+
// Launch options for Playwright
|
|
52
|
+
launchOptions: {
|
|
53
|
+
args: [
|
|
54
|
+
'--use-gl=egl',
|
|
55
|
+
// # Must be set to `new` to enable new version of Chromium Headless to obtain correct snapshots
|
|
56
|
+
'--headless=new',
|
|
57
|
+
],
|
|
58
|
+
ignoreDefaultArgs: [
|
|
59
|
+
// # Must be ignored to enable new version of Chromium Headless to obtain correct snapshots
|
|
60
|
+
'--headless',
|
|
61
|
+
],
|
|
62
|
+
},
|
|
63
|
+
// Collect trace on all retries
|
|
64
|
+
trace: 'on-all-retries',
|
|
65
|
+
},
|
|
66
|
+
// Number of workers to use
|
|
67
|
+
workers: environment.WORKERS,
|
|
68
|
+
});
|
|
@@ -101,18 +101,18 @@ export const Button = React.forwardRef((props, ref) => {
|
|
|
101
101
|
});
|
|
102
102
|
|
|
103
103
|
Button.defaultProps = {
|
|
104
|
-
afterLabel:
|
|
105
|
-
beforeLabel:
|
|
104
|
+
afterLabel: undefined,
|
|
105
|
+
beforeLabel: undefined,
|
|
106
106
|
block: false,
|
|
107
107
|
color: 'primary',
|
|
108
108
|
disabled: false,
|
|
109
|
-
endCorner:
|
|
110
|
-
feedbackIcon:
|
|
109
|
+
endCorner: undefined,
|
|
110
|
+
feedbackIcon: undefined,
|
|
111
111
|
id: undefined,
|
|
112
112
|
labelVisibility: 'xs',
|
|
113
113
|
priority: 'filled',
|
|
114
114
|
size: 'medium',
|
|
115
|
-
startCorner:
|
|
115
|
+
startCorner: undefined,
|
|
116
116
|
type: 'button',
|
|
117
117
|
};
|
|
118
118
|
|
|
@@ -28,7 +28,7 @@ See [API](#api) for all available options.
|
|
|
28
28
|
- **Don't overwhelm your UI** with too many high-emphasis actions. There should
|
|
29
29
|
always be one but chances are that having more of them is not necessary.
|
|
30
30
|
|
|
31
|
-
- Ensure the **button action is well
|
|
31
|
+
- Ensure the **button action is well recognizable** across your target audience.
|
|
32
32
|
This is especially important when using the button [with an icon only](#icon-buttons).
|
|
33
33
|
|
|
34
34
|
## Priorities
|
|
@@ -6,7 +6,7 @@ import { withGlobalProps } from '../../providers/globalProps';
|
|
|
6
6
|
import { classNames } from '../../helpers/classNames/classNames';
|
|
7
7
|
import { transferProps } from '../../helpers/transferProps';
|
|
8
8
|
import { getRootPriorityClassName } from '../_helpers/getRootPriorityClassName';
|
|
9
|
-
import { isChildrenEmpty } from '
|
|
9
|
+
import { isChildrenEmpty } from '../../helpers/isChildrenEmpty/isChildrenEmpty';
|
|
10
10
|
import styles from './ButtonGroup.module.scss';
|
|
11
11
|
import { ButtonGroupContext } from './ButtonGroupContext';
|
|
12
12
|
|
|
@@ -48,7 +48,7 @@ export const ButtonGroup = ({
|
|
|
48
48
|
|
|
49
49
|
ButtonGroup.defaultProps = {
|
|
50
50
|
block: false,
|
|
51
|
-
children:
|
|
51
|
+
children: undefined,
|
|
52
52
|
disabled: false,
|
|
53
53
|
priority: 'filled',
|
|
54
54
|
size: 'medium',
|
|
@@ -2,7 +2,7 @@ import PropTypes from 'prop-types';
|
|
|
2
2
|
import React from 'react';
|
|
3
3
|
import { transferProps } from '../../helpers/transferProps';
|
|
4
4
|
import { withGlobalProps } from '../../providers/globalProps';
|
|
5
|
-
import { isChildrenEmpty } from '
|
|
5
|
+
import { isChildrenEmpty } from '../../helpers/isChildrenEmpty/isChildrenEmpty';
|
|
6
6
|
import styles from './Card.module.scss';
|
|
7
7
|
|
|
8
8
|
export const CardFooter = ({
|
|
@@ -24,7 +24,7 @@ export const CardFooter = ({
|
|
|
24
24
|
};
|
|
25
25
|
|
|
26
26
|
CardFooter.defaultProps = {
|
|
27
|
-
children:
|
|
27
|
+
children: undefined,
|
|
28
28
|
};
|
|
29
29
|
|
|
30
30
|
CardFooter.propTypes = {
|
|
@@ -300,6 +300,8 @@ Separate your card actions with CardFooter. See
|
|
|
300
300
|
| `--rui-Card--raised__box-shadow` | Box shadow of raised card |
|
|
301
301
|
| `--rui-Card--disabled__background-color` | Card background color in disabled state |
|
|
302
302
|
| `--rui-Card--disabled__opacity` | Card opacity in disabled state |
|
|
303
|
+
| `--rui-Card--disabled__border-width` | Card border width in disabled state |
|
|
304
|
+
| `--rui-Card--disabled__border-color` | Card border color in disabled state |
|
|
303
305
|
|
|
304
306
|
### Theming Variants
|
|
305
307
|
|
|
@@ -9,3 +9,5 @@ $raised-box-shadow: var(--rui-Card--raised__box-shadow);
|
|
|
9
9
|
|
|
10
10
|
$disabled-background-color: var(--rui-Card--disabled__background-color);
|
|
11
11
|
$disabled-opacity: var(--rui-Card--disabled__opacity);
|
|
12
|
+
$disabled-border-width: var(--rui-Card--disabled__border-width);
|
|
13
|
+
$disabled-border-color: var(--rui-Card--disabled__border-color);
|
|
@@ -79,14 +79,14 @@ export const CheckboxField = React.forwardRef((props, ref) => {
|
|
|
79
79
|
|
|
80
80
|
CheckboxField.defaultProps = {
|
|
81
81
|
disabled: false,
|
|
82
|
-
helpText:
|
|
82
|
+
helpText: undefined,
|
|
83
83
|
id: undefined,
|
|
84
84
|
isLabelVisible: true,
|
|
85
85
|
labelPosition: 'after',
|
|
86
86
|
renderAsRequired: false,
|
|
87
87
|
required: false,
|
|
88
|
-
validationState:
|
|
89
|
-
validationText:
|
|
88
|
+
validationState: undefined,
|
|
89
|
+
validationText: undefined,
|
|
90
90
|
};
|
|
91
91
|
|
|
92
92
|
CheckboxField.propTypes = {
|
|
@@ -78,6 +78,7 @@ export const FileInputField = React.forwardRef((props, ref) => {
|
|
|
78
78
|
const handleFileChange = (files, event) => {
|
|
79
79
|
if (files.length === 0) {
|
|
80
80
|
setSelectedFileNames([]);
|
|
81
|
+
onFilesChanged([], event);
|
|
81
82
|
return;
|
|
82
83
|
}
|
|
83
84
|
|
|
@@ -85,6 +86,7 @@ export const FileInputField = React.forwardRef((props, ref) => {
|
|
|
85
86
|
// does not accept multiple files, no files are processed.
|
|
86
87
|
if (files.length > 1 && !multiple) {
|
|
87
88
|
setSelectedFileNames([]);
|
|
89
|
+
onFilesChanged([], event);
|
|
88
90
|
return;
|
|
89
91
|
}
|
|
90
92
|
|
|
@@ -198,15 +200,20 @@ export const FileInputField = React.forwardRef((props, ref) => {
|
|
|
198
200
|
type="button"
|
|
199
201
|
>
|
|
200
202
|
<Text lines={1}>
|
|
201
|
-
{
|
|
203
|
+
{isDragging && (
|
|
204
|
+
<span className={styles.dropFileHereText}>
|
|
205
|
+
{translations.FileInputField.dropFileHere}
|
|
206
|
+
</span>
|
|
207
|
+
)}
|
|
208
|
+
{!isDragging && !selectedFileNames.length && (
|
|
202
209
|
<>
|
|
203
210
|
<span className={styles.dropZoneLink}>{translations.FileInputField.browse}</span>
|
|
204
211
|
{' '}
|
|
205
212
|
{translations.FileInputField.drop}
|
|
206
213
|
</>
|
|
207
214
|
)}
|
|
208
|
-
{selectedFileNames.length === 1 && selectedFileNames[0]}
|
|
209
|
-
{selectedFileNames.length > 1 && (
|
|
215
|
+
{!isDragging && selectedFileNames.length === 1 && selectedFileNames[0]}
|
|
216
|
+
{!isDragging && selectedFileNames.length > 1 && (
|
|
210
217
|
<>
|
|
211
218
|
{selectedFileNames.length}
|
|
212
219
|
{' '}
|
|
@@ -216,7 +223,7 @@ export const FileInputField = React.forwardRef((props, ref) => {
|
|
|
216
223
|
</Text>
|
|
217
224
|
</button>
|
|
218
225
|
</div>
|
|
219
|
-
{helpText && (
|
|
226
|
+
{(helpText && !inputGroupContext) && (
|
|
220
227
|
<div
|
|
221
228
|
className={styles.helpText}
|
|
222
229
|
id={`${id}__helpText`}
|
|
@@ -224,7 +231,7 @@ export const FileInputField = React.forwardRef((props, ref) => {
|
|
|
224
231
|
{helpText}
|
|
225
232
|
</div>
|
|
226
233
|
)}
|
|
227
|
-
{validationText && (
|
|
234
|
+
{(validationText && !inputGroupContext) && (
|
|
228
235
|
<div
|
|
229
236
|
className={styles.validationText}
|
|
230
237
|
id={`${id}__validationText`}
|
|
@@ -240,14 +247,14 @@ export const FileInputField = React.forwardRef((props, ref) => {
|
|
|
240
247
|
FileInputField.defaultProps = {
|
|
241
248
|
disabled: false,
|
|
242
249
|
fullWidth: false,
|
|
243
|
-
helpText:
|
|
250
|
+
helpText: undefined,
|
|
244
251
|
isLabelVisible: true,
|
|
245
252
|
layout: 'vertical',
|
|
246
253
|
multiple: false,
|
|
247
254
|
required: false,
|
|
248
255
|
size: 'medium',
|
|
249
|
-
validationState:
|
|
250
|
-
validationText:
|
|
256
|
+
validationState: undefined,
|
|
257
|
+
validationText: undefined,
|
|
251
258
|
};
|
|
252
259
|
|
|
253
260
|
FileInputField.propTypes = {
|
|
@@ -261,6 +268,9 @@ FileInputField.propTypes = {
|
|
|
261
268
|
fullWidth: PropTypes.bool,
|
|
262
269
|
/**
|
|
263
270
|
* Optional help text.
|
|
271
|
+
*
|
|
272
|
+
* Help text is never rendered when the component is placed into `InputGroup`.
|
|
273
|
+
* If a help text is needed, it must be defined on the `InputGroup` component instead.
|
|
264
274
|
*/
|
|
265
275
|
helpText: PropTypes.node,
|
|
266
276
|
/**
|
|
@@ -314,6 +324,9 @@ FileInputField.propTypes = {
|
|
|
314
324
|
validationState: PropTypes.oneOf(['invalid', 'valid', 'warning']),
|
|
315
325
|
/**
|
|
316
326
|
* Validation message to be displayed.
|
|
327
|
+
*
|
|
328
|
+
* Validation text is never rendered when the component is placed into `InputGroup`.
|
|
329
|
+
* If a validation text is needed, it must be defined on the `InputGroup` component instead.
|
|
317
330
|
*/
|
|
318
331
|
validationText: PropTypes.node,
|
|
319
332
|
};
|
|
@@ -3,7 +3,7 @@ import React, { useMemo } from 'react';
|
|
|
3
3
|
import { withGlobalProps } from '../../providers/globalProps';
|
|
4
4
|
import { classNames } from '../../helpers/classNames/classNames';
|
|
5
5
|
import { transferProps } from '../../helpers/transferProps';
|
|
6
|
-
import { isChildrenEmpty } from '
|
|
6
|
+
import { isChildrenEmpty } from '../../helpers/isChildrenEmpty/isChildrenEmpty';
|
|
7
7
|
import { FormLayoutContext } from './FormLayoutContext';
|
|
8
8
|
import styles from './FormLayout.module.scss';
|
|
9
9
|
|
|
@@ -68,7 +68,7 @@ export const FormLayout = ({
|
|
|
68
68
|
|
|
69
69
|
FormLayout.defaultProps = {
|
|
70
70
|
autoWidth: false,
|
|
71
|
-
children:
|
|
71
|
+
children: undefined,
|
|
72
72
|
fieldLayout: 'vertical',
|
|
73
73
|
labelWidth: 'default',
|
|
74
74
|
};
|
|
@@ -5,7 +5,7 @@ import { classNames } from '../../helpers/classNames/classNames';
|
|
|
5
5
|
import { transferProps } from '../../helpers/transferProps';
|
|
6
6
|
import { getRootSizeClassName } from '../_helpers/getRootSizeClassName';
|
|
7
7
|
import { getRootValidationStateClassName } from '../_helpers/getRootValidationStateClassName';
|
|
8
|
-
import { isChildrenEmpty } from '
|
|
8
|
+
import { isChildrenEmpty } from '../../helpers/isChildrenEmpty/isChildrenEmpty';
|
|
9
9
|
import { FormLayoutContext } from './FormLayoutContext';
|
|
10
10
|
import styles from './FormLayoutCustomField.module.scss';
|
|
11
11
|
|
|
@@ -80,15 +80,15 @@ export const FormLayoutCustomField = ({
|
|
|
80
80
|
};
|
|
81
81
|
|
|
82
82
|
FormLayoutCustomField.defaultProps = {
|
|
83
|
-
children:
|
|
83
|
+
children: undefined,
|
|
84
84
|
disabled: false,
|
|
85
85
|
fullWidth: false,
|
|
86
86
|
id: undefined,
|
|
87
|
-
innerFieldSize:
|
|
88
|
-
label:
|
|
87
|
+
innerFieldSize: undefined,
|
|
88
|
+
label: undefined,
|
|
89
89
|
labelForId: undefined,
|
|
90
90
|
required: false,
|
|
91
|
-
validationState:
|
|
91
|
+
validationState: undefined,
|
|
92
92
|
};
|
|
93
93
|
|
|
94
94
|
FormLayoutCustomField.propTypes = {
|
|
@@ -2,7 +2,7 @@ import PropTypes from 'prop-types';
|
|
|
2
2
|
import React from 'react';
|
|
3
3
|
import { withGlobalProps } from '../../providers/globalProps';
|
|
4
4
|
import { transferProps } from '../../helpers/transferProps';
|
|
5
|
-
import { isChildrenEmpty } from '
|
|
5
|
+
import { isChildrenEmpty } from '../../helpers/isChildrenEmpty/isChildrenEmpty';
|
|
6
6
|
import { generateResponsiveCustomProperties } from './_helpers/generateResponsiveCustomProperties';
|
|
7
7
|
import styles from './Grid.module.scss';
|
|
8
8
|
|
|
@@ -54,7 +54,7 @@ Grid.defaultProps = {
|
|
|
54
54
|
alignContent: undefined,
|
|
55
55
|
alignItems: undefined,
|
|
56
56
|
autoFlow: undefined,
|
|
57
|
-
children:
|
|
57
|
+
children: undefined,
|
|
58
58
|
columnGap: 4,
|
|
59
59
|
columns: '1fr',
|
|
60
60
|
justifyContent: undefined,
|
|
@@ -2,7 +2,7 @@ import PropTypes from 'prop-types';
|
|
|
2
2
|
import React from 'react';
|
|
3
3
|
import { withGlobalProps } from '../../providers/globalProps';
|
|
4
4
|
import { transferProps } from '../../helpers/transferProps';
|
|
5
|
-
import { isChildrenEmpty } from '
|
|
5
|
+
import { isChildrenEmpty } from '../../helpers/isChildrenEmpty/isChildrenEmpty';
|
|
6
6
|
import { generateResponsiveCustomProperties } from './_helpers/generateResponsiveCustomProperties';
|
|
7
7
|
import styles from './Grid.module.scss';
|
|
8
8
|
|
|
@@ -35,7 +35,7 @@ export const GridSpan = ({
|
|
|
35
35
|
/* eslint-disable sort-keys */
|
|
36
36
|
|
|
37
37
|
GridSpan.defaultProps = {
|
|
38
|
-
children:
|
|
38
|
+
children: undefined,
|
|
39
39
|
columns: 1,
|
|
40
40
|
rows: 1,
|
|
41
41
|
tag: 'div',
|
|
@@ -8,7 +8,7 @@ import { classNames } from '../../helpers/classNames/classNames';
|
|
|
8
8
|
import { transferProps } from '../../helpers/transferProps';
|
|
9
9
|
import { getRootSizeClassName } from '../_helpers/getRootSizeClassName';
|
|
10
10
|
import { getRootValidationStateClassName } from '../_helpers/getRootValidationStateClassName';
|
|
11
|
-
import { isChildrenEmpty } from '
|
|
11
|
+
import { isChildrenEmpty } from '../../helpers/isChildrenEmpty/isChildrenEmpty';
|
|
12
12
|
import { resolveContextOrProp } from '../_helpers/resolveContextOrProp';
|
|
13
13
|
import { FormLayoutContext } from '../FormLayout';
|
|
14
14
|
import { Text } from '../Text';
|
|
@@ -18,6 +18,7 @@ import styles from './InputGroup.module.scss';
|
|
|
18
18
|
export const InputGroup = ({
|
|
19
19
|
children,
|
|
20
20
|
disabled,
|
|
21
|
+
helpTexts,
|
|
21
22
|
id,
|
|
22
23
|
isLabelVisible,
|
|
23
24
|
label,
|
|
@@ -89,7 +90,21 @@ export const InputGroup = ({
|
|
|
89
90
|
{children}
|
|
90
91
|
</InputGroupContext.Provider>
|
|
91
92
|
</div>
|
|
92
|
-
{
|
|
93
|
+
{helpTexts && helpTexts.length > 0 && (
|
|
94
|
+
<ul
|
|
95
|
+
className={styles.helpText}
|
|
96
|
+
id={id && `${id}__helpTexts`}
|
|
97
|
+
>
|
|
98
|
+
{helpTexts.map((helpText) => (
|
|
99
|
+
<li key={helpText}>
|
|
100
|
+
<Text blockLevel>
|
|
101
|
+
{helpText}
|
|
102
|
+
</Text>
|
|
103
|
+
</li>
|
|
104
|
+
))}
|
|
105
|
+
</ul>
|
|
106
|
+
)}
|
|
107
|
+
{validationTexts && validationTexts.length > 0 && (
|
|
93
108
|
<ul
|
|
94
109
|
className={styles.validationText}
|
|
95
110
|
id={id && `${id}__validationTexts`}
|
|
@@ -109,14 +124,15 @@ export const InputGroup = ({
|
|
|
109
124
|
};
|
|
110
125
|
|
|
111
126
|
InputGroup.defaultProps = {
|
|
112
|
-
children:
|
|
127
|
+
children: undefined,
|
|
113
128
|
disabled: false,
|
|
129
|
+
helpTexts: undefined,
|
|
114
130
|
id: undefined,
|
|
115
131
|
isLabelVisible: true,
|
|
116
132
|
layout: 'vertical',
|
|
117
133
|
required: false,
|
|
118
134
|
size: 'medium',
|
|
119
|
-
validationTexts:
|
|
135
|
+
validationTexts: undefined,
|
|
120
136
|
};
|
|
121
137
|
|
|
122
138
|
InputGroup.propTypes = {
|
|
@@ -133,6 +149,10 @@ InputGroup.propTypes = {
|
|
|
133
149
|
* If `true`, the whole input group with all nested inputs and buttons will be disabled.
|
|
134
150
|
*/
|
|
135
151
|
disabled: PropTypes.bool,
|
|
152
|
+
/**
|
|
153
|
+
* An array of help texts to be displayed.
|
|
154
|
+
*/
|
|
155
|
+
helpTexts: PropTypes.arrayOf(PropTypes.node),
|
|
136
156
|
/**
|
|
137
157
|
* ID of the root HTML element.
|
|
138
158
|
*
|
|
@@ -171,7 +191,7 @@ InputGroup.propTypes = {
|
|
|
171
191
|
/**
|
|
172
192
|
* An array of validation messages to be displayed.
|
|
173
193
|
*/
|
|
174
|
-
validationTexts: PropTypes.node,
|
|
194
|
+
validationTexts: PropTypes.arrayOf(PropTypes.node),
|
|
175
195
|
};
|
|
176
196
|
|
|
177
197
|
export const InputGroupWithGlobalProps = withGlobalProps(InputGroup, 'InputGroup');
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
// 1. The class
|
|
1
|
+
// 1. The class names are intentionally singular because they are also targeted by other mixins.
|
|
2
2
|
// 2. Use a block-level display mode to prevent extra white space below grouped inputs in Safari.
|
|
3
3
|
// 3. Let wide input groups honor the minimum input width and overflow horizontally without wrapping and distorting
|
|
4
4
|
// the inputs.
|
|
@@ -39,6 +39,7 @@
|
|
|
39
39
|
}
|
|
40
40
|
|
|
41
41
|
// 1.
|
|
42
|
+
.helpText,
|
|
42
43
|
.validationText {
|
|
43
44
|
@include reset.list();
|
|
44
45
|
@include foundation.help-text();
|