@onewelcome/react-lib-components 1.5.0 → 1.6.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/Button/Button.d.ts +0 -1
- package/dist/DataGrid/datagrid.interfaces.d.ts +1 -0
- package/dist/Form/Checkbox/Checkbox.d.ts +1 -1
- package/dist/Form/FormHelperText/FormHelperText.d.ts +1 -1
- package/dist/Form/FormSelectorWrapper/FormSelectorWrapper.d.ts +1 -1
- package/dist/Form/Input/Input.d.ts +2 -2
- package/dist/Form/Radio/Radio.d.ts +1 -1
- package/dist/Form/Select/Select.d.ts +1 -1
- package/dist/Form/Textarea/Textarea.d.ts +1 -6
- package/dist/Form/Toggle/Toggle.d.ts +1 -1
- package/dist/Form/Wrapper/CheckboxWrapper/CheckboxWrapper.d.ts +1 -1
- package/dist/Form/Wrapper/InputWrapper/InputWrapper.d.ts +1 -1
- package/dist/Form/Wrapper/RadioWrapper/RadioWrapper.d.ts +1 -1
- package/dist/Form/Wrapper/SelectWrapper/SelectWrapper.d.ts +1 -1
- package/dist/Form/Wrapper/TextareaWrapper/TextareaWrapper.d.ts +1 -1
- package/dist/Form/form.interfaces.d.ts +1 -0
- package/dist/Link/Link.d.ts +1 -2
- package/dist/Notifications/Banner/Banner.d.ts +11 -0
- package/dist/Tabs/TabButton.d.ts +0 -1
- package/dist/_BaseStyling_/BaseStyling.d.ts +2 -0
- package/dist/hooks/useDetermineStatusIcon.d.ts +3 -0
- package/dist/index.d.ts +1 -0
- package/dist/react-lib-components.cjs.development.js +416 -318
- package/dist/react-lib-components.cjs.development.js.map +1 -1
- package/dist/react-lib-components.cjs.production.min.js +1 -1
- package/dist/react-lib-components.cjs.production.min.js.map +1 -1
- package/dist/react-lib-components.esm.js +416 -319
- package/dist/react-lib-components.esm.js.map +1 -1
- package/package.json +11 -11
- package/src/Button/BaseButton.module.scss +2 -2
- package/src/Button/Button.module.scss +4 -5
- package/src/Button/Button.tsx +0 -1
- package/src/Button/IconButton.module.scss +4 -5
- package/src/DataGrid/DataGrid.tsx +3 -2
- package/src/DataGrid/DataGridActions/DataGridActions.tsx +16 -9
- package/src/DataGrid/DataGridBody/DataGridCell.module.scss +2 -2
- package/src/DataGrid/DataGridHeader/DataGridHeader.test.tsx +8 -3
- package/src/DataGrid/DataGridHeader/DataGridHeader.tsx +3 -1
- package/src/DataGrid/datagrid.interfaces.ts +1 -0
- package/src/Form/Input/Input.module.scss +36 -25
- package/src/Form/Input/Input.test.tsx +10 -0
- package/src/Form/Input/Input.tsx +7 -5
- package/src/Form/Select/Select.module.scss +9 -6
- package/src/Form/Select/Select.test.tsx +11 -0
- package/src/Form/Select/Select.tsx +5 -9
- package/src/Form/Select/SelectService.ts +2 -2
- package/src/Form/Textarea/Textarea.module.scss +21 -13
- package/src/Form/Textarea/Textarea.test.tsx +8 -0
- package/src/Form/Textarea/Textarea.tsx +6 -12
- package/src/Form/Toggle/Toggle.module.scss +3 -3
- package/src/Form/Wrapper/InputWrapper/InputWrapper.module.scss +7 -3
- package/src/Form/Wrapper/InputWrapper/InputWrapper.tsx +2 -0
- package/src/Form/Wrapper/SelectWrapper/SelectWrapper.tsx +12 -1
- package/src/Form/Wrapper/TextareaWrapper/TextareaWrapper.module.scss +15 -14
- package/src/Form/Wrapper/TextareaWrapper/TextareaWrapper.tsx +2 -1
- package/src/Form/Wrapper/Wrapper/Wrapper.module.scss +2 -2
- package/src/Form/form.interfaces.ts +1 -0
- package/src/Link/Link.module.scss +5 -5
- package/src/Link/Link.tsx +14 -13
- package/src/Notifications/Banner/Banner.module.scss +76 -0
- package/src/Notifications/Banner/Banner.test.tsx +84 -0
- package/src/Notifications/Banner/Banner.tsx +78 -0
- package/src/Notifications/BaseModal/BaseModal.module.scss +2 -2
- package/src/Notifications/Snackbar/SnackbarContainer/SnackbarContainer.module.scss +2 -2
- package/src/Notifications/Snackbar/SnackbarItem/SnackbarItem.module.scss +4 -4
- package/src/Notifications/Snackbar/SnackbarItem/SnackbarItem.tsx +3 -2
- package/src/Popover/Popover.module.scss +2 -2
- package/src/Skeleton/Skeleton.module.scss +2 -2
- package/src/Tabs/TabButton.tsx +1 -2
- package/src/Tabs/Tabs.module.scss +2 -2
- package/src/Tabs/Tabs.tsx +13 -10
- package/src/Tiles/Tile.module.scss +4 -4
- package/src/Tooltip/Tooltip.module.scss +3 -3
- package/src/_BaseStyling_/BaseStyling.tsx +4 -0
- package/src/hooks/useDetermineStatusIcon.test.ts +28 -0
- package/src/hooks/useDetermineStatusIcon.tsx +35 -0
- package/src/index.ts +1 -0
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"homepage": "http://onewelcome.github.io/react-lib-components",
|
|
3
3
|
"name": "@onewelcome/react-lib-components",
|
|
4
|
-
"version": "1.
|
|
4
|
+
"version": "1.6.0",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"author": "OneWelcome B.V.",
|
|
7
7
|
"main": "dist/index.js",
|
|
@@ -55,7 +55,7 @@
|
|
|
55
55
|
"@babel/core": "^7.20.12",
|
|
56
56
|
"@mdx-js/react": "^1.6.22",
|
|
57
57
|
"@onewelcome/eslint-config-shared-codestyle": "^9.0.3",
|
|
58
|
-
"@size-limit/preset-small-lib": "^
|
|
58
|
+
"@size-limit/preset-small-lib": "^8.1.2",
|
|
59
59
|
"@storybook/addon-a11y": "^6.5.15",
|
|
60
60
|
"@storybook/addon-docs": "^6.5.15",
|
|
61
61
|
"@storybook/addon-essentials": "^6.5.15",
|
|
@@ -66,24 +66,24 @@
|
|
|
66
66
|
"@storybook/preset-scss": "^1.0.3",
|
|
67
67
|
"@storybook/react": "^6.5.15",
|
|
68
68
|
"@storybook/theming": "^6.5.15",
|
|
69
|
-
"@testing-library/dom": "^8.
|
|
69
|
+
"@testing-library/dom": "^8.20.0",
|
|
70
70
|
"@testing-library/jest-dom": "^5.16.5",
|
|
71
71
|
"@testing-library/react": "^12.1.5",
|
|
72
72
|
"@testing-library/react-hooks": "^8.0.1",
|
|
73
73
|
"@testing-library/user-event": "^13.5.0",
|
|
74
74
|
"@tsconfig/create-react-app": "^1.0.3",
|
|
75
|
-
"@tsconfig/recommended": "^1.0.
|
|
75
|
+
"@tsconfig/recommended": "^1.0.2",
|
|
76
76
|
"@types/color-convert": "^2.0.0",
|
|
77
77
|
"@types/mdx": "^2.0.3",
|
|
78
78
|
"@types/react": "^17.0.52",
|
|
79
79
|
"@types/react-dom": "^17.0.18",
|
|
80
80
|
"@types/react-router": "^5.1.20",
|
|
81
81
|
"@types/react-router-dom": "^5.3.3",
|
|
82
|
-
"@typescript-eslint/eslint-plugin": "^5.
|
|
83
|
-
"@typescript-eslint/parser": "^5.
|
|
84
|
-
"babel-loader": "^9.1.
|
|
82
|
+
"@typescript-eslint/eslint-plugin": "^5.49.0",
|
|
83
|
+
"@typescript-eslint/parser": "^5.49.0",
|
|
84
|
+
"babel-loader": "^9.1.2",
|
|
85
85
|
"dts-cli": "^1.6.3",
|
|
86
|
-
"eslint": "^8.
|
|
86
|
+
"eslint": "^8.32.0",
|
|
87
87
|
"eslint-config-prettier": "^8.6.0",
|
|
88
88
|
"eslint-plugin-cypress": "^2.12.1",
|
|
89
89
|
"eslint-plugin-jest": "^27.2.1",
|
|
@@ -95,16 +95,16 @@
|
|
|
95
95
|
"jest-junit": "^15.0.0",
|
|
96
96
|
"lint-staged": "^13.1.0",
|
|
97
97
|
"npm-run-all": "^4.1.5",
|
|
98
|
-
"prettier": "^2.8.
|
|
98
|
+
"prettier": "^2.8.3",
|
|
99
99
|
"react": "^17.0.2",
|
|
100
100
|
"react-dom": "^17.0.2",
|
|
101
101
|
"react-is": "^18.2.0",
|
|
102
102
|
"react-router": "^6.6.2",
|
|
103
|
-
"react-router-dom": "^6.
|
|
103
|
+
"react-router-dom": "^6.7.0",
|
|
104
104
|
"rollup-plugin-cleanup": "^3.2.1",
|
|
105
105
|
"rollup-plugin-styles": "^4.0.0",
|
|
106
106
|
"sass": "^1.57.1",
|
|
107
|
-
"size-limit": "^
|
|
107
|
+
"size-limit": "^8.1.1",
|
|
108
108
|
"tslib": "^2.4.1",
|
|
109
109
|
"typescript": "^4.9.4"
|
|
110
110
|
}
|
|
@@ -14,19 +14,18 @@
|
|
|
14
14
|
* limitations under the License.
|
|
15
15
|
*/
|
|
16
16
|
|
|
17
|
-
@
|
|
18
|
-
@import "../mixins.module.scss";
|
|
17
|
+
@use "../mixins.module.scss";
|
|
19
18
|
|
|
20
19
|
.fill {
|
|
21
|
-
@include button("fill");
|
|
20
|
+
@include mixins.button("fill");
|
|
22
21
|
}
|
|
23
22
|
|
|
24
23
|
.outline {
|
|
25
|
-
@include button("outline");
|
|
24
|
+
@include mixins.button("outline");
|
|
26
25
|
}
|
|
27
26
|
|
|
28
27
|
.text {
|
|
29
|
-
@include button("text");
|
|
28
|
+
@include mixins.button("text");
|
|
30
29
|
}
|
|
31
30
|
|
|
32
31
|
.has-icon {
|
package/src/Button/Button.tsx
CHANGED
|
@@ -14,8 +14,7 @@
|
|
|
14
14
|
* limitations under the License.
|
|
15
15
|
*/
|
|
16
16
|
|
|
17
|
-
@
|
|
18
|
-
@import "../mixins.module.scss";
|
|
17
|
+
@use "../mixins.module.scss";
|
|
19
18
|
|
|
20
19
|
.icon-button {
|
|
21
20
|
border: var(--button-border-width) var(--button-border-style) transparent;
|
|
@@ -57,14 +56,14 @@
|
|
|
57
56
|
}
|
|
58
57
|
|
|
59
58
|
&.fill {
|
|
60
|
-
@include button("fill", "icon");
|
|
59
|
+
@include mixins.button("fill", "icon");
|
|
61
60
|
}
|
|
62
61
|
|
|
63
62
|
&.text {
|
|
64
|
-
@include button("text", "icon");
|
|
63
|
+
@include mixins.button("text", "icon");
|
|
65
64
|
}
|
|
66
65
|
|
|
67
66
|
&.outline {
|
|
68
|
-
@include button("outline", "icon");
|
|
67
|
+
@include mixins.button("outline", "icon");
|
|
69
68
|
}
|
|
70
69
|
}
|
|
@@ -144,14 +144,15 @@ const DataGridInner = <T extends {}>(
|
|
|
144
144
|
spacing={styleWithSpacing}
|
|
145
145
|
/>
|
|
146
146
|
<DataGridBody
|
|
147
|
-
children={children}
|
|
148
147
|
data={data}
|
|
149
148
|
headers={internalHeaders}
|
|
150
149
|
isLoading={isLoading}
|
|
151
150
|
disableContextMenuColumn={disableContextMenuColumn}
|
|
152
151
|
emptyLabel={emptyLabel}
|
|
153
152
|
spacing={styleWithSpacing}
|
|
154
|
-
|
|
153
|
+
>
|
|
154
|
+
{children}
|
|
155
|
+
</DataGridBody>
|
|
155
156
|
</table>
|
|
156
157
|
</div>
|
|
157
158
|
{paginationProps && !isLoading && (
|
|
@@ -52,6 +52,7 @@ const DataGridActionsComponent: ForwardRefRenderFunction<HTMLDivElement, Props>
|
|
|
52
52
|
searchIconBtnProps = {},
|
|
53
53
|
headers,
|
|
54
54
|
onColumnToggled,
|
|
55
|
+
children,
|
|
55
56
|
...rest
|
|
56
57
|
}: Props,
|
|
57
58
|
ref
|
|
@@ -59,6 +60,9 @@ const DataGridActionsComponent: ForwardRefRenderFunction<HTMLDivElement, Props>
|
|
|
59
60
|
const isHidden = !(enableAddBtn || enableColumnsBtn || enableSearchBtn);
|
|
60
61
|
const [showColsPopover, setShowColsPopover] = useState(false);
|
|
61
62
|
const showColumnBtn = useRef<HTMLButtonElement>(null);
|
|
63
|
+
const { children: addBtnChildren, ...restAddBtnProps } = addBtnProps;
|
|
64
|
+
const { children: columnsBtnChildren, ...restColumnsBtnProps } = columnsBtnProps;
|
|
65
|
+
const { children: searchBtnChildren, ...restSearchBtnProps } = searchBtnProps;
|
|
62
66
|
|
|
63
67
|
return isHidden ? null : (
|
|
64
68
|
<div {...rest} ref={ref} className={`${classes["actions"]} ${className ?? ""}`}>
|
|
@@ -70,9 +74,10 @@ const DataGridActionsComponent: ForwardRefRenderFunction<HTMLDivElement, Props>
|
|
|
70
74
|
title="Add item"
|
|
71
75
|
type="button"
|
|
72
76
|
variant="outline"
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
77
|
+
{...restAddBtnProps}
|
|
78
|
+
>
|
|
79
|
+
{addBtnChildren ?? "Add item"}
|
|
80
|
+
</Button>
|
|
76
81
|
)}
|
|
77
82
|
</div>
|
|
78
83
|
<div className={classes["right-actions"]}>
|
|
@@ -82,12 +87,13 @@ const DataGridActionsComponent: ForwardRefRenderFunction<HTMLDivElement, Props>
|
|
|
82
87
|
startIcon={<Icon icon={Icons.Change} />}
|
|
83
88
|
title="Show/hide columns"
|
|
84
89
|
variant="text"
|
|
85
|
-
|
|
86
|
-
{...columnsBtnProps}
|
|
90
|
+
{...restColumnsBtnProps}
|
|
87
91
|
className={`${classes["desktop"]} ${columnsBtnProps?.className ?? ""}`}
|
|
88
92
|
ref={showColumnBtn}
|
|
89
93
|
onClick={() => setShowColsPopover(true)}
|
|
90
|
-
|
|
94
|
+
>
|
|
95
|
+
{columnsBtnChildren ?? "Columns"}
|
|
96
|
+
</Button>
|
|
91
97
|
<IconButton
|
|
92
98
|
title="Show/hide columns"
|
|
93
99
|
{...columnsBtnProps}
|
|
@@ -112,10 +118,11 @@ const DataGridActionsComponent: ForwardRefRenderFunction<HTMLDivElement, Props>
|
|
|
112
118
|
startIcon={<Icon icon={Icons.TableSearch} />}
|
|
113
119
|
title="Search"
|
|
114
120
|
variant="text"
|
|
115
|
-
|
|
116
|
-
{...searchBtnProps}
|
|
121
|
+
{...restSearchBtnProps}
|
|
117
122
|
className={`${classes["desktop"]} ${searchBtnProps?.className ?? ""}`}
|
|
118
|
-
|
|
123
|
+
>
|
|
124
|
+
{searchBtnChildren ?? "Search"}
|
|
125
|
+
</Button>
|
|
119
126
|
<IconButton
|
|
120
127
|
title="Search"
|
|
121
128
|
{...searchIconBtnProps}
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
* limitations under the License.
|
|
15
15
|
*/
|
|
16
16
|
|
|
17
|
-
@
|
|
17
|
+
@use "../../mixins.module.scss";
|
|
18
18
|
|
|
19
19
|
.cell {
|
|
20
20
|
min-height: 3.5rem;
|
|
@@ -29,7 +29,7 @@
|
|
|
29
29
|
}
|
|
30
30
|
|
|
31
31
|
.loading {
|
|
32
|
-
@include skeletonLoading();
|
|
32
|
+
@include mixins.skeletonLoading();
|
|
33
33
|
border-radius: 0.5rem;
|
|
34
34
|
height: 1.25rem;
|
|
35
35
|
margin: 0.625rem 0;
|
|
@@ -21,8 +21,8 @@ import userEvent from "@testing-library/user-event";
|
|
|
21
21
|
|
|
22
22
|
const defaultParams: Props = {
|
|
23
23
|
headers: [
|
|
24
|
-
{ name: "firstName", headline: "First name" },
|
|
25
|
-
{ name: "lastName", headline: "Last name" }
|
|
24
|
+
{ name: "firstName", headline: "First name", align: "center" },
|
|
25
|
+
{ name: "lastName", headline: "Last name", align: "right" }
|
|
26
26
|
]
|
|
27
27
|
};
|
|
28
28
|
|
|
@@ -36,7 +36,6 @@ const createDataGridHeader = (params?: (defaultParams: Props) => Props) => {
|
|
|
36
36
|
container
|
|
37
37
|
});
|
|
38
38
|
const dataGridHeader = queries.getByTestId("dataGridHeader");
|
|
39
|
-
|
|
40
39
|
return {
|
|
41
40
|
...queries,
|
|
42
41
|
dataGridHeader
|
|
@@ -51,6 +50,12 @@ describe("DataGridHeader should render", () => {
|
|
|
51
50
|
expect(getAllByRole("columnheader")).toHaveLength(2);
|
|
52
51
|
expect(getByRole("cell")).toBeDefined(); //context-menu empty cell
|
|
53
52
|
|
|
53
|
+
const headerCells = dataGridHeader.querySelectorAll("th");
|
|
54
|
+
|
|
55
|
+
expect(headerCells).toHaveLength(2);
|
|
56
|
+
expect(headerCells[0]).toHaveStyle({ textAlign: "center" });
|
|
57
|
+
expect(headerCells[1]).toHaveStyle({ textAlign: "right" });
|
|
58
|
+
|
|
54
59
|
expect(dataGridHeader.querySelectorAll("[data-icon]")).toHaveLength(0);
|
|
55
60
|
});
|
|
56
61
|
|
|
@@ -77,7 +77,9 @@ const DataGridHeaderComponent: ForwardRefRenderFunction<HTMLTableSectionElement,
|
|
|
77
77
|
return null;
|
|
78
78
|
}
|
|
79
79
|
|
|
80
|
-
let headerStyle: React.CSSProperties = {
|
|
80
|
+
let headerStyle: React.CSSProperties = {
|
|
81
|
+
textAlign: header.align || "left"
|
|
82
|
+
};
|
|
81
83
|
|
|
82
84
|
if (index === 0) {
|
|
83
85
|
headerStyle.paddingLeft = spacing?.paddingLeft;
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
* limitations under the License.
|
|
15
15
|
*/
|
|
16
16
|
|
|
17
|
-
@
|
|
17
|
+
@use "../../mixins.module.scss";
|
|
18
18
|
|
|
19
19
|
.input-wrapper {
|
|
20
20
|
position: relative;
|
|
@@ -25,7 +25,7 @@
|
|
|
25
25
|
border-radius: var(--input-border-radius);
|
|
26
26
|
background-color: var(--input-background-color);
|
|
27
27
|
padding: 0 1.25rem;
|
|
28
|
-
@include transition(all, 0.2s, ease-in-out);
|
|
28
|
+
@include mixins.transition(all, 0.2s, ease-in-out);
|
|
29
29
|
|
|
30
30
|
// General autofill styles
|
|
31
31
|
input:-webkit-autofill,
|
|
@@ -64,7 +64,33 @@
|
|
|
64
64
|
}
|
|
65
65
|
}
|
|
66
66
|
|
|
67
|
-
@include outlineStates;
|
|
67
|
+
@include mixins.outlineStates;
|
|
68
|
+
|
|
69
|
+
[data-icon-status="success"],
|
|
70
|
+
[data-icon-status="error"] {
|
|
71
|
+
height: 100%;
|
|
72
|
+
width: 1.25rem;
|
|
73
|
+
box-sizing: border-box;
|
|
74
|
+
padding-top: calc(1rem - (1.25rem - 1rem));
|
|
75
|
+
font-size: 1.25rem;
|
|
76
|
+
display: flex;
|
|
77
|
+
align-items: center;
|
|
78
|
+
justify-content: center;
|
|
79
|
+
z-index: 2;
|
|
80
|
+
|
|
81
|
+
&:before {
|
|
82
|
+
height: 1.25rem;
|
|
83
|
+
width: 1.25rem;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
[data-icon-status="success"] {
|
|
88
|
+
color: var(--success);
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
[data-icon-status="error"] {
|
|
92
|
+
color: var(--error);
|
|
93
|
+
}
|
|
68
94
|
}
|
|
69
95
|
|
|
70
96
|
.input {
|
|
@@ -76,7 +102,7 @@
|
|
|
76
102
|
box-sizing: border-box;
|
|
77
103
|
border: 0;
|
|
78
104
|
border-radius: var(--input-border-radius);
|
|
79
|
-
@include transition(all, 0.2s, ease-in-out);
|
|
105
|
+
@include mixins.transition(all, 0.2s, ease-in-out);
|
|
80
106
|
background-color: transparent;
|
|
81
107
|
z-index: 1;
|
|
82
108
|
|
|
@@ -93,41 +119,26 @@
|
|
|
93
119
|
width: auto;
|
|
94
120
|
}
|
|
95
121
|
|
|
96
|
-
@include browserOutlineDisabled;
|
|
122
|
+
@include mixins.browserOutlineDisabled;
|
|
97
123
|
}
|
|
98
124
|
|
|
99
|
-
@include outline;
|
|
125
|
+
@include mixins.outline;
|
|
100
126
|
|
|
101
127
|
.error input {
|
|
102
128
|
color: var(--error);
|
|
103
|
-
padding-right:
|
|
129
|
+
padding-right: 1.25rem;
|
|
104
130
|
|
|
105
131
|
&.remove-extra-indent {
|
|
106
132
|
padding-right: 0;
|
|
107
133
|
}
|
|
108
134
|
}
|
|
109
|
-
|
|
110
|
-
.
|
|
111
|
-
color: var(--error);
|
|
112
|
-
position: absolute;
|
|
113
|
-
height: 100%;
|
|
114
|
-
width: 1.25rem;
|
|
115
|
-
right: 1.25rem;
|
|
116
|
-
top: 0;
|
|
117
|
-
font-size: 1.125rem;
|
|
118
|
-
display: flex;
|
|
119
|
-
align-items: center;
|
|
120
|
-
justify-content: center;
|
|
121
|
-
z-index: 2;
|
|
122
|
-
|
|
123
|
-
&:before {
|
|
124
|
-
height: 1.3125rem;
|
|
125
|
-
}
|
|
135
|
+
.success input {
|
|
136
|
+
padding-right: 1.25rem;
|
|
126
137
|
}
|
|
127
138
|
|
|
128
139
|
.input-wrapper [data-prefix],
|
|
129
140
|
.input-wrapper [data-suffix] {
|
|
130
|
-
@include transition(all, 0.2s, ease-in-out);
|
|
141
|
+
@include mixins.transition(all, 0.2s, ease-in-out);
|
|
131
142
|
display: block;
|
|
132
143
|
z-index: 1;
|
|
133
144
|
}
|
|
@@ -234,4 +234,14 @@ describe("It should render prefix and suffix ", () => {
|
|
|
234
234
|
expect(input.querySelector("icon-warning")).toBeDefined();
|
|
235
235
|
expect(getByText(suffix)).toBeDefined();
|
|
236
236
|
});
|
|
237
|
+
|
|
238
|
+
it("success icon should be visible", () => {
|
|
239
|
+
const { input } = createInput(defaultParams => ({
|
|
240
|
+
...defaultParams,
|
|
241
|
+
success: true
|
|
242
|
+
}));
|
|
243
|
+
const icon = input.querySelector(".icon-checkmark-circle-breakout");
|
|
244
|
+
expect(input.querySelector(".success")).toBeDefined();
|
|
245
|
+
expect(icon).toBeDefined();
|
|
246
|
+
});
|
|
237
247
|
});
|
package/src/Form/Input/Input.tsx
CHANGED
|
@@ -24,8 +24,8 @@ import React, {
|
|
|
24
24
|
} from "react";
|
|
25
25
|
import classes from "./Input.module.scss";
|
|
26
26
|
import readyclasses from "../../readyclasses.module.scss";
|
|
27
|
-
import { Icon, Icons } from "../../Icon/Icon";
|
|
28
27
|
import { FormElement } from "../form.interfaces";
|
|
28
|
+
import { useDetermineStatusIcon } from "../../hooks/useDetermineStatusIcon";
|
|
29
29
|
|
|
30
30
|
export const dateTypes = ["date", "time", "datetime-local"] as const;
|
|
31
31
|
|
|
@@ -39,7 +39,7 @@ export type Type =
|
|
|
39
39
|
| "tel"
|
|
40
40
|
| "url"
|
|
41
41
|
| "hidden"
|
|
42
|
-
| typeof dateTypes[number];
|
|
42
|
+
| (typeof dateTypes)[number];
|
|
43
43
|
|
|
44
44
|
export interface Props extends ComponentPropsWithRef<"input">, FormElement {
|
|
45
45
|
wrapperProps?: ComponentPropsWithRef<"div">;
|
|
@@ -52,6 +52,7 @@ export interface Props extends ComponentPropsWithRef<"input">, FormElement {
|
|
|
52
52
|
const InputComponent: ForwardRefRenderFunction<HTMLInputElement, Props> = (
|
|
53
53
|
{
|
|
54
54
|
error = false,
|
|
55
|
+
success = false,
|
|
55
56
|
className,
|
|
56
57
|
name,
|
|
57
58
|
style,
|
|
@@ -69,7 +70,6 @@ const InputComponent: ForwardRefRenderFunction<HTMLInputElement, Props> = (
|
|
|
69
70
|
) => {
|
|
70
71
|
const [focus, setFocus] = useState(false);
|
|
71
72
|
const inputWrapperRef = useRef<HTMLDivElement>(null);
|
|
72
|
-
const errorIconRef = useRef<HTMLDivElement>(null);
|
|
73
73
|
const suffixRef = useRef<HTMLDivElement>(null);
|
|
74
74
|
|
|
75
75
|
useEffect(() => {
|
|
@@ -84,7 +84,6 @@ const InputComponent: ForwardRefRenderFunction<HTMLInputElement, Props> = (
|
|
|
84
84
|
inputClassNames.push(classes["shrink-width-for-date-icon"]);
|
|
85
85
|
className && inputClassNames.push(className);
|
|
86
86
|
|
|
87
|
-
const iconClassNames = [classes["warning"]];
|
|
88
87
|
const wrapperClasses = [classes["input-wrapper"]];
|
|
89
88
|
const outlineClasses = [classes["outline"]];
|
|
90
89
|
|
|
@@ -95,6 +94,9 @@ const InputComponent: ForwardRefRenderFunction<HTMLInputElement, Props> = (
|
|
|
95
94
|
disabled && wrapperClasses.push(classes["disabled"]) && outlineClasses.push(classes["disabled"]);
|
|
96
95
|
error && wrapperClasses.push(classes["error"]) && outlineClasses.push(classes["error"]);
|
|
97
96
|
focus && wrapperClasses.push(classes["focus"]) && outlineClasses.push(classes["focus"]);
|
|
97
|
+
success && wrapperClasses.push(classes["success"]);
|
|
98
|
+
|
|
99
|
+
const icon = useDetermineStatusIcon({ success, error });
|
|
98
100
|
|
|
99
101
|
return (
|
|
100
102
|
<div
|
|
@@ -126,12 +128,12 @@ const InputComponent: ForwardRefRenderFunction<HTMLInputElement, Props> = (
|
|
|
126
128
|
className={inputClassNames.join(" ")}
|
|
127
129
|
spellCheck={rest.spellCheck || false}
|
|
128
130
|
/>
|
|
131
|
+
{icon}
|
|
129
132
|
{suffix && (
|
|
130
133
|
<div ref={suffixRef} data-suffix className={classes["suffix"]}>
|
|
131
134
|
<span>{suffix}</span>
|
|
132
135
|
</div>
|
|
133
136
|
)}
|
|
134
|
-
{error && <Icon ref={errorIconRef} className={iconClassNames.join(" ")} icon={Icons.Error} />}
|
|
135
137
|
<span className={outlineClasses.join(" ")}></span>
|
|
136
138
|
</div>
|
|
137
139
|
);
|
|
@@ -14,15 +14,14 @@
|
|
|
14
14
|
* limitations under the License.
|
|
15
15
|
*/
|
|
16
16
|
|
|
17
|
-
@
|
|
18
|
-
@import "../../mixins.module.scss";
|
|
17
|
+
@use "../../mixins.module.scss";
|
|
19
18
|
|
|
20
19
|
$listItemHeight: 2.125rem;
|
|
21
20
|
|
|
22
21
|
.select {
|
|
23
22
|
position: relative;
|
|
24
23
|
box-sizing: border-box;
|
|
25
|
-
@include transition(all, 0.2s, ease-in-out);
|
|
24
|
+
@include mixins.transition(all, 0.2s, ease-in-out);
|
|
26
25
|
border: 0;
|
|
27
26
|
border-radius: var(--input-border-radius);
|
|
28
27
|
background-color: var(--input-background-color);
|
|
@@ -57,7 +56,6 @@ $listItemHeight: 2.125rem;
|
|
|
57
56
|
position: relative;
|
|
58
57
|
width: 100%;
|
|
59
58
|
min-height: calc(4rem - (2 * var(--input-border-width)));
|
|
60
|
-
border: 0;
|
|
61
59
|
padding: 0 1.25rem;
|
|
62
60
|
background-color: transparent;
|
|
63
61
|
border-color: var(--light-grey-border);
|
|
@@ -66,7 +64,7 @@ $listItemHeight: 2.125rem;
|
|
|
66
64
|
border-radius: var(--input-border-radius);
|
|
67
65
|
font-size: var(--font-size);
|
|
68
66
|
cursor: pointer;
|
|
69
|
-
@include transition(all, 0.2s, ease-in-out);
|
|
67
|
+
@include mixins.transition(all, 0.2s, ease-in-out);
|
|
70
68
|
|
|
71
69
|
&:focus {
|
|
72
70
|
outline: 0;
|
|
@@ -173,7 +171,12 @@ $listItemHeight: 2.125rem;
|
|
|
173
171
|
display: flex;
|
|
174
172
|
align-items: center;
|
|
175
173
|
|
|
176
|
-
|
|
174
|
+
[data-icon-status="success"] {
|
|
175
|
+
color: var(--success);
|
|
176
|
+
font-size: 1.25rem;
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
[data-icon-status="error"] {
|
|
177
180
|
color: var(--error);
|
|
178
181
|
font-size: 1.25rem;
|
|
179
182
|
}
|
|
@@ -119,6 +119,17 @@ describe("Select should render", () => {
|
|
|
119
119
|
expect(button).toHaveAttribute("aria-invalid", "true");
|
|
120
120
|
expect(select.querySelector("[data-clear]")).not.toBeInTheDocument();
|
|
121
121
|
});
|
|
122
|
+
|
|
123
|
+
it("should have a success icon when success state", () => {
|
|
124
|
+
const { button } = createSelect(defaultParams => ({
|
|
125
|
+
...defaultParams,
|
|
126
|
+
success: true
|
|
127
|
+
}));
|
|
128
|
+
|
|
129
|
+
const icon = button.querySelector("[class*='icon-checkmark-circle-breakout']");
|
|
130
|
+
expect(button).toHaveClass("success");
|
|
131
|
+
expect(icon).toBeDefined();
|
|
132
|
+
});
|
|
122
133
|
});
|
|
123
134
|
|
|
124
135
|
describe("ref should work", () => {
|
|
@@ -33,6 +33,7 @@ import { useBodyClick } from "../../hooks/useBodyClick";
|
|
|
33
33
|
import readyclasses from "../../readyclasses.module.scss";
|
|
34
34
|
import { filterProps } from "../../util/helper";
|
|
35
35
|
import { useArrowNavigation, useSelectPositionList } from "./SelectService";
|
|
36
|
+
import { useDetermineStatusIcon } from "../../hooks/useDetermineStatusIcon";
|
|
36
37
|
|
|
37
38
|
type PartialInputProps = Partial<InputProps>;
|
|
38
39
|
|
|
@@ -67,6 +68,7 @@ const SelectComponent: ForwardRefRenderFunction<HTMLSelectElement, Props> = (
|
|
|
67
68
|
selectButtonProps,
|
|
68
69
|
className,
|
|
69
70
|
error = false,
|
|
71
|
+
success = false,
|
|
70
72
|
value,
|
|
71
73
|
clearLabel = "Clear selection",
|
|
72
74
|
onChange,
|
|
@@ -90,7 +92,6 @@ const SelectComponent: ForwardRefRenderFunction<HTMLSelectElement, Props> = (
|
|
|
90
92
|
const nativeSelect = (ref as React.RefObject<HTMLSelectElement>) || createRef();
|
|
91
93
|
const searchInputRef = useRef<HTMLInputElement>(null);
|
|
92
94
|
const customSelectButtonRef = useRef<HTMLButtonElement>(null);
|
|
93
|
-
|
|
94
95
|
const { onArrowNavigation } = useArrowNavigation({
|
|
95
96
|
expanded,
|
|
96
97
|
setExpanded,
|
|
@@ -183,13 +184,7 @@ const SelectComponent: ForwardRefRenderFunction<HTMLSelectElement, Props> = (
|
|
|
183
184
|
setFilter(event.currentTarget.value);
|
|
184
185
|
};
|
|
185
186
|
|
|
186
|
-
const
|
|
187
|
-
if (error) {
|
|
188
|
-
return <Icon className={classes["warning"]} icon={Icons.Warning} />;
|
|
189
|
-
}
|
|
190
|
-
|
|
191
|
-
return null;
|
|
192
|
-
};
|
|
187
|
+
const icon = useDetermineStatusIcon({ success, error });
|
|
193
188
|
|
|
194
189
|
const nativeOnChangeHandler = (event: React.ChangeEvent<HTMLSelectElement>) => {
|
|
195
190
|
onChange && onChange(event);
|
|
@@ -214,6 +209,7 @@ const SelectComponent: ForwardRefRenderFunction<HTMLSelectElement, Props> = (
|
|
|
214
209
|
error && additionalClasses.push(classes.error);
|
|
215
210
|
disabled && additionalClasses.push(classes.disabled);
|
|
216
211
|
className && additionalClasses.push(className);
|
|
212
|
+
success && additionalClasses.push(classes.success);
|
|
217
213
|
|
|
218
214
|
/** The native select is purely for external form libraries. We use it to emit an onChange with native select event object so they know exactly what's happening. */
|
|
219
215
|
return (
|
|
@@ -262,7 +258,7 @@ const SelectComponent: ForwardRefRenderFunction<HTMLSelectElement, Props> = (
|
|
|
262
258
|
{value?.length > 0 && <span data-display-inner>{display}</span>}
|
|
263
259
|
</div>
|
|
264
260
|
<div className={classes["status"]}>
|
|
265
|
-
{
|
|
261
|
+
{icon}
|
|
266
262
|
<Icon className={classes["triangle-down"]} icon={Icons.TriangleDown} />
|
|
267
263
|
</div>
|
|
268
264
|
</button>
|
|
@@ -174,7 +174,7 @@ export const useSelectPositionList = ({
|
|
|
174
174
|
|
|
175
175
|
const calculateOptionListMaxHeight = (position: Position) => {
|
|
176
176
|
// Calculate max height if there's more space below the select
|
|
177
|
-
const listHeight = optionListReference.current
|
|
177
|
+
const listHeight = optionListReference.current?.getBoundingClientRect().height;
|
|
178
178
|
const transformOrigin = position.top !== "initial" ? "top" : "bottom";
|
|
179
179
|
|
|
180
180
|
const availableSpace =
|
|
@@ -184,7 +184,7 @@ export const useSelectPositionList = ({
|
|
|
184
184
|
16
|
|
185
185
|
: containerReference.current!.getBoundingClientRect()[transformOrigin] - 16;
|
|
186
186
|
|
|
187
|
-
if (availableSpace < listHeight) {
|
|
187
|
+
if (listHeight && availableSpace < listHeight) {
|
|
188
188
|
setOptionsListMaxHeight(`${availableSpace}px`);
|
|
189
189
|
setOpacity(100);
|
|
190
190
|
return;
|