@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.
Files changed (77) hide show
  1. package/dist/Button/Button.d.ts +0 -1
  2. package/dist/DataGrid/datagrid.interfaces.d.ts +1 -0
  3. package/dist/Form/Checkbox/Checkbox.d.ts +1 -1
  4. package/dist/Form/FormHelperText/FormHelperText.d.ts +1 -1
  5. package/dist/Form/FormSelectorWrapper/FormSelectorWrapper.d.ts +1 -1
  6. package/dist/Form/Input/Input.d.ts +2 -2
  7. package/dist/Form/Radio/Radio.d.ts +1 -1
  8. package/dist/Form/Select/Select.d.ts +1 -1
  9. package/dist/Form/Textarea/Textarea.d.ts +1 -6
  10. package/dist/Form/Toggle/Toggle.d.ts +1 -1
  11. package/dist/Form/Wrapper/CheckboxWrapper/CheckboxWrapper.d.ts +1 -1
  12. package/dist/Form/Wrapper/InputWrapper/InputWrapper.d.ts +1 -1
  13. package/dist/Form/Wrapper/RadioWrapper/RadioWrapper.d.ts +1 -1
  14. package/dist/Form/Wrapper/SelectWrapper/SelectWrapper.d.ts +1 -1
  15. package/dist/Form/Wrapper/TextareaWrapper/TextareaWrapper.d.ts +1 -1
  16. package/dist/Form/form.interfaces.d.ts +1 -0
  17. package/dist/Link/Link.d.ts +1 -2
  18. package/dist/Notifications/Banner/Banner.d.ts +11 -0
  19. package/dist/Tabs/TabButton.d.ts +0 -1
  20. package/dist/_BaseStyling_/BaseStyling.d.ts +2 -0
  21. package/dist/hooks/useDetermineStatusIcon.d.ts +3 -0
  22. package/dist/index.d.ts +1 -0
  23. package/dist/react-lib-components.cjs.development.js +416 -318
  24. package/dist/react-lib-components.cjs.development.js.map +1 -1
  25. package/dist/react-lib-components.cjs.production.min.js +1 -1
  26. package/dist/react-lib-components.cjs.production.min.js.map +1 -1
  27. package/dist/react-lib-components.esm.js +416 -319
  28. package/dist/react-lib-components.esm.js.map +1 -1
  29. package/package.json +11 -11
  30. package/src/Button/BaseButton.module.scss +2 -2
  31. package/src/Button/Button.module.scss +4 -5
  32. package/src/Button/Button.tsx +0 -1
  33. package/src/Button/IconButton.module.scss +4 -5
  34. package/src/DataGrid/DataGrid.tsx +3 -2
  35. package/src/DataGrid/DataGridActions/DataGridActions.tsx +16 -9
  36. package/src/DataGrid/DataGridBody/DataGridCell.module.scss +2 -2
  37. package/src/DataGrid/DataGridHeader/DataGridHeader.test.tsx +8 -3
  38. package/src/DataGrid/DataGridHeader/DataGridHeader.tsx +3 -1
  39. package/src/DataGrid/datagrid.interfaces.ts +1 -0
  40. package/src/Form/Input/Input.module.scss +36 -25
  41. package/src/Form/Input/Input.test.tsx +10 -0
  42. package/src/Form/Input/Input.tsx +7 -5
  43. package/src/Form/Select/Select.module.scss +9 -6
  44. package/src/Form/Select/Select.test.tsx +11 -0
  45. package/src/Form/Select/Select.tsx +5 -9
  46. package/src/Form/Select/SelectService.ts +2 -2
  47. package/src/Form/Textarea/Textarea.module.scss +21 -13
  48. package/src/Form/Textarea/Textarea.test.tsx +8 -0
  49. package/src/Form/Textarea/Textarea.tsx +6 -12
  50. package/src/Form/Toggle/Toggle.module.scss +3 -3
  51. package/src/Form/Wrapper/InputWrapper/InputWrapper.module.scss +7 -3
  52. package/src/Form/Wrapper/InputWrapper/InputWrapper.tsx +2 -0
  53. package/src/Form/Wrapper/SelectWrapper/SelectWrapper.tsx +12 -1
  54. package/src/Form/Wrapper/TextareaWrapper/TextareaWrapper.module.scss +15 -14
  55. package/src/Form/Wrapper/TextareaWrapper/TextareaWrapper.tsx +2 -1
  56. package/src/Form/Wrapper/Wrapper/Wrapper.module.scss +2 -2
  57. package/src/Form/form.interfaces.ts +1 -0
  58. package/src/Link/Link.module.scss +5 -5
  59. package/src/Link/Link.tsx +14 -13
  60. package/src/Notifications/Banner/Banner.module.scss +76 -0
  61. package/src/Notifications/Banner/Banner.test.tsx +84 -0
  62. package/src/Notifications/Banner/Banner.tsx +78 -0
  63. package/src/Notifications/BaseModal/BaseModal.module.scss +2 -2
  64. package/src/Notifications/Snackbar/SnackbarContainer/SnackbarContainer.module.scss +2 -2
  65. package/src/Notifications/Snackbar/SnackbarItem/SnackbarItem.module.scss +4 -4
  66. package/src/Notifications/Snackbar/SnackbarItem/SnackbarItem.tsx +3 -2
  67. package/src/Popover/Popover.module.scss +2 -2
  68. package/src/Skeleton/Skeleton.module.scss +2 -2
  69. package/src/Tabs/TabButton.tsx +1 -2
  70. package/src/Tabs/Tabs.module.scss +2 -2
  71. package/src/Tabs/Tabs.tsx +13 -10
  72. package/src/Tiles/Tile.module.scss +4 -4
  73. package/src/Tooltip/Tooltip.module.scss +3 -3
  74. package/src/_BaseStyling_/BaseStyling.tsx +4 -0
  75. package/src/hooks/useDetermineStatusIcon.test.ts +28 -0
  76. package/src/hooks/useDetermineStatusIcon.tsx +35 -0
  77. package/src/index.ts +1 -0
@@ -14,14 +14,30 @@
14
14
  * limitations under the License.
15
15
  */
16
16
 
17
- @import "../../mixins.module.scss";
17
+ @use "../../mixins.module.scss";
18
18
 
19
19
  .textarea-wrapper {
20
20
  position: relative;
21
21
  box-sizing: border-box;
22
22
  width: 100%;
23
+ [data-icon-status="success"],
24
+ [data-icon-status="error"] {
25
+ position: absolute;
26
+ right: 1.25rem;
27
+ z-index: 1;
28
+ top: 0.85rem;
29
+ font-size: 1.25rem;
30
+ }
31
+
32
+ [data-icon-status="success"] {
33
+ color: var(--success);
34
+ }
35
+
36
+ [data-icon-status="error"] {
37
+ color: var(--error);
38
+ }
23
39
 
24
- @include outlineStates;
40
+ @include mixins.outlineStates();
25
41
  }
26
42
 
27
43
  .textarea {
@@ -29,7 +45,7 @@
29
45
  box-sizing: border-box;
30
46
  border: 0;
31
47
  border-radius: var(--input-border-radius);
32
- @include transition(all, 0.2s, ease-in-out);
48
+ @include mixins.transition(all, 0.2s, ease-in-out);
33
49
  font-family: var(--font-family);
34
50
  font-size: var(--font-size);
35
51
  color: var(--greyed-out);
@@ -42,20 +58,12 @@
42
58
  cursor: not-allowed;
43
59
  }
44
60
 
45
- @include browserOutlineDisabled;
61
+ @include mixins.browserOutlineDisabled();
46
62
  }
47
63
 
48
- @include outline;
64
+ @include mixins.outline();
49
65
 
50
66
  .error {
51
67
  border-color: var(--error);
52
68
  color: var(--error);
53
69
  }
54
-
55
- .warning {
56
- color: var(--error);
57
- position: absolute;
58
- right: 1.25rem;
59
- top: 0.75rem;
60
- font-size: 1.25rem;
61
- }
@@ -116,3 +116,11 @@ describe("Error status", () => {
116
116
  expect(textarea.nextElementSibling).toHaveClass("icon-error-circle");
117
117
  });
118
118
  });
119
+
120
+ describe("Success status", () => {
121
+ it("success icon should be visible", () => {
122
+ const { textarea } = createTextarea({ success: true });
123
+ const icon = textarea.parentElement?.querySelector(".icon-checkmark-circle-breakout");
124
+ expect(icon).toBeDefined();
125
+ });
126
+ });
@@ -15,25 +15,22 @@
15
15
  */
16
16
 
17
17
  import React, { ForwardRefRenderFunction, ComponentPropsWithRef, useState } from "react";
18
- import { Icon, Props as IconProps, Icons } from "../../Icon/Icon";
19
18
  import classes from "./Textarea.module.scss";
20
19
  import { FormElement } from "../form.interfaces";
21
-
22
- interface IconPropsPartial extends Omit<Partial<IconProps>, "ref"> {}
20
+ import { useDetermineStatusIcon } from "../../hooks/useDetermineStatusIcon";
23
21
 
24
22
  export interface Props extends ComponentPropsWithRef<"textarea">, FormElement {
25
23
  wrapperProps?: ComponentPropsWithRef<"div">;
26
- errorProps?: IconPropsPartial;
27
24
  }
28
25
 
29
26
  const TextareaComponent: ForwardRefRenderFunction<HTMLTextAreaElement, Props> = (
30
27
  {
31
28
  error = false,
29
+ success = false,
32
30
  disabled = false,
33
31
  className,
34
32
  rows = 4,
35
33
  wrapperProps,
36
- errorProps,
37
34
  onFocus,
38
35
  onBlur,
39
36
  ...rest
@@ -49,6 +46,9 @@ const TextareaComponent: ForwardRefRenderFunction<HTMLTextAreaElement, Props> =
49
46
  disabled && wrapperClasses.push(classes["disabled"]) && outlineClasses.push(classes["disabled"]);
50
47
  error && wrapperClasses.push(classes["error"]) && outlineClasses.push(classes["error"]);
51
48
  focus && wrapperClasses.push(classes["focus"]) && outlineClasses.push(classes["focus"]);
49
+ success && wrapperClasses.push("success");
50
+
51
+ const icon = useDetermineStatusIcon({ success, error });
52
52
 
53
53
  return (
54
54
  <div {...wrapperProps} className={wrapperClasses.join(" ")}>
@@ -67,13 +67,7 @@ const TextareaComponent: ForwardRefRenderFunction<HTMLTextAreaElement, Props> =
67
67
  onBlur && onBlur(event);
68
68
  }}
69
69
  />
70
- {error && (
71
- <Icon
72
- {...errorProps}
73
- className={`${classes["warning"]} ${errorProps?.className ?? ""}`}
74
- icon={Icons.Error}
75
- />
76
- )}
70
+ {icon}
77
71
  <span className={outlineClasses.join(" ")}></span>
78
72
  </div>
79
73
  );
@@ -14,7 +14,7 @@
14
14
  * limitations under the License.
15
15
  */
16
16
 
17
- @import "../../mixins.module.scss";
17
+ @use "../../mixins.module.scss";
18
18
 
19
19
  $borderRadius: 2.5rem;
20
20
 
@@ -31,7 +31,7 @@ $borderRadius: 2.5rem;
31
31
  background-color: var(--default);
32
32
  border-radius: $borderRadius;
33
33
  position: relative;
34
- @include transition(background-color, 0.2s, ease-in-out);
34
+ @include mixins.transition(background-color, 0.2s, ease-in-out);
35
35
  display: block;
36
36
  pointer-events: none;
37
37
 
@@ -46,7 +46,7 @@ $borderRadius: 2.5rem;
46
46
  top: 50%;
47
47
  transform: translateY(-50%) translateX(0);
48
48
  left: 0.125rem;
49
- @include transition(transform, 0.2s, ease-in-out);
49
+ @include mixins.transition(transform, 0.2s, ease-in-out);
50
50
  }
51
51
 
52
52
  &.checked {
@@ -14,9 +14,9 @@
14
14
  * limitations under the License.
15
15
  */
16
16
 
17
- @import "../../../mixins.module.scss";
17
+ @use "../../../mixins.module.scss";
18
18
 
19
- @include inputLabelPrimaryColorOnFocus("label.input-label.focus");
19
+ @include mixins.inputLabelPrimaryColorOnFocus("label.input-label.focus");
20
20
 
21
21
  input {
22
22
  &.floating-label {
@@ -30,7 +30,7 @@ input {
30
30
 
31
31
  .input-wrapper {
32
32
  [data-icon]:before {
33
- @include transition(all, 0.2s, ease-in-out);
33
+ @include mixins.transition(all, 0.2s, ease-in-out);
34
34
  transform: translateY(0px);
35
35
  font-size: 1.125rem;
36
36
  }
@@ -48,6 +48,10 @@ input {
48
48
  padding-left: 0.5rem;
49
49
  }
50
50
 
51
+ [data-suffix] {
52
+ padding-left: 1.25rem;
53
+ }
54
+
51
55
  input + [data-suffix] {
52
56
  padding-left: 0.5rem;
53
57
  }
@@ -74,6 +74,7 @@ const InputWrapperComponent: ForwardRefRenderFunction<HTMLDivElement, Props> = (
74
74
  value,
75
75
  className,
76
76
  error,
77
+ success,
77
78
  onChange,
78
79
  onBlur,
79
80
  onFocus,
@@ -164,6 +165,7 @@ const InputWrapperComponent: ForwardRefRenderFunction<HTMLDivElement, Props> = (
164
165
  inputProps?.className ?? ""
165
166
  }`}
166
167
  name={name}
168
+ success={success}
167
169
  error={error}
168
170
  id={name}
169
171
  value={value}
@@ -39,7 +39,17 @@ export interface Props
39
39
  }
40
40
 
41
41
  const SelectWrapperComponent: ForwardRefRenderFunction<HTMLDivElement, Props> = (
42
- { children, error, value, placeholder, selectProps, helperProps, onChange, ...rest }: Props,
42
+ {
43
+ children,
44
+ error,
45
+ success,
46
+ value,
47
+ placeholder,
48
+ selectProps,
49
+ helperProps,
50
+ onChange,
51
+ ...rest
52
+ }: Props,
43
53
  ref
44
54
  ) => {
45
55
  const { errorId, floatingLabelActive, helperId, labelId } = useWrapper(value, placeholder);
@@ -63,6 +73,7 @@ const SelectWrapperComponent: ForwardRefRenderFunction<HTMLDivElement, Props> =
63
73
  value={value}
64
74
  labeledBy={labelId}
65
75
  error={error}
76
+ success={success}
66
77
  describedBy={error ? errorId : helperId}
67
78
  onChange={onChange}
68
79
  placeholder={placeholder}
@@ -14,14 +14,14 @@
14
14
  * limitations under the License.
15
15
  */
16
16
 
17
- @import "../../../mixins.module.scss";
17
+ @use "../../../mixins.module.scss";
18
18
 
19
- @include inputLabelPrimaryColorOnFocus("label.textarea-label");
19
+ @include mixins.inputLabelPrimaryColorOnFocus("label.textarea-label");
20
20
 
21
21
  .textarea-wrapper {
22
22
  &:after {
23
23
  content: "";
24
- @include transition(all, 0.15s, ease-in-out);
24
+ @include mixins.transition(all, 0.15s, ease-in-out);
25
25
  display: block;
26
26
  width: calc(95%);
27
27
  height: 1.625rem;
@@ -41,17 +41,22 @@
41
41
  left: 2px;
42
42
  top: 2px;
43
43
  }
44
- }
45
44
 
46
- .textarea {
47
- padding-top: 1.625rem;
45
+ .textarea {
46
+ padding-top: 1.625rem;
47
+
48
+ &:active:not(:disabled) {
49
+ border-color: var(--color-primary);
50
+ }
48
51
 
49
- &:active:not(:disabled) {
50
- border-color: var(--color-primary);
52
+ &:focus:not(:disabled) {
53
+ outline: none;
54
+ }
51
55
  }
52
56
 
53
- &:focus:not(:disabled) {
54
- outline: none;
57
+ [data-icon-status="success"],
58
+ [data-icon-status="error"] {
59
+ top: 1.75rem;
55
60
  }
56
61
  }
57
62
 
@@ -59,7 +64,3 @@
59
64
  margin-top: 0.25rem;
60
65
  margin-left: 1.25rem;
61
66
  }
62
-
63
- .error-icon {
64
- top: 1.75rem;
65
- }
@@ -40,6 +40,7 @@ const TextareaWrapperComponent: ForwardRefRenderFunction<HTMLDivElement, Props>
40
40
  {
41
41
  name,
42
42
  error,
43
+ success,
43
44
  value,
44
45
  label,
45
46
  placeholder,
@@ -102,6 +103,7 @@ const TextareaWrapperComponent: ForwardRefRenderFunction<HTMLDivElement, Props>
102
103
  name={name}
103
104
  id={name}
104
105
  value={value}
106
+ success={success}
105
107
  onChange={onChange}
106
108
  onFocus={e => {
107
109
  onFocus && onFocus(e);
@@ -127,7 +129,6 @@ const TextareaWrapperComponent: ForwardRefRenderFunction<HTMLDivElement, Props>
127
129
  wrapperProps={{
128
130
  className: `${wrapperClasses.join(" ")} ${classes["textarea-wrapper"]}`
129
131
  }}
130
- errorProps={{ className: classes["error-icon"] }}
131
132
  />
132
133
  </Wrapper>
133
134
  );
@@ -14,7 +14,7 @@
14
14
  * limitations under the License.
15
15
  */
16
16
 
17
- @import "../../../mixins.module.scss";
17
+ @use "../../../mixins.module.scss";
18
18
 
19
19
  .floating-wrapper {
20
20
  position: relative;
@@ -27,7 +27,7 @@
27
27
  top: 1.3125rem;
28
28
  left: 1.25rem;
29
29
  transform-origin: left top;
30
- @include transition(all, 0.2s, ease-in-out);
30
+ @include mixins.transition(all, 0.2s, ease-in-out);
31
31
  pointer-events: none;
32
32
 
33
33
  &.floating-label-active {
@@ -27,5 +27,6 @@ export interface FormSelector extends FormElement {
27
27
  /** Default form elements */
28
28
  export interface FormElement {
29
29
  error?: boolean;
30
+ success?: boolean;
30
31
  [dataAttribute: DataAttributeKey]: unknown;
31
32
  }
@@ -14,7 +14,7 @@
14
14
  * limitations under the License.
15
15
  */
16
16
 
17
- @import "../mixins.module.scss";
17
+ @use "../mixins.module.scss";
18
18
 
19
19
  .link {
20
20
  font-family: var(--font-family);
@@ -64,19 +64,19 @@
64
64
  }
65
65
 
66
66
  .button {
67
- @include buttonBase("link");
67
+ @include mixins.buttonBase("link");
68
68
 
69
69
  text-decoration: none;
70
70
 
71
71
  &.fill {
72
- @include button("fill", "link");
72
+ @include mixins.button("fill", "link");
73
73
  }
74
74
 
75
75
  &.outline {
76
- @include button("outline", "link");
76
+ @include mixins.button("outline", "link");
77
77
  }
78
78
 
79
79
  &.text {
80
- @include button("text", "link");
80
+ @include mixins.button("text", "link");
81
81
  }
82
82
  }
package/src/Link/Link.tsx CHANGED
@@ -17,15 +17,13 @@
17
17
  import React, {
18
18
  ForwardRefRenderFunction,
19
19
  ComponentPropsWithRef,
20
- ForwardRefExoticComponent,
21
- ReactNode
20
+ ForwardRefExoticComponent
22
21
  } from "react";
23
22
  import classes from "./Link.module.scss";
24
23
 
25
24
  export type AnchorType = "external" | "internal" | "download";
26
25
 
27
26
  export interface Props extends ComponentPropsWithRef<"a"> {
28
- children?: ReactNode;
29
27
  color?: "primary" | "secondary" | "tertiary";
30
28
  display?: "link" | "button";
31
29
  buttonVariant?: "outline" | "text" | "fill";
@@ -69,17 +67,20 @@ const LinkComponent: ForwardRefRenderFunction<HTMLAnchorElement, Props> = (
69
67
  className && classNames.push(className);
70
68
 
71
69
  if (component) {
72
- return React.createElement(component, {
73
- ...rest,
74
- ref: ref,
75
- to: to,
76
- className: classNames.join(" "),
77
- "aria-disabled": disabled,
78
- style: {
79
- ...rest.style
70
+ return React.createElement(
71
+ component,
72
+ {
73
+ ...rest,
74
+ ref: ref,
75
+ to: to,
76
+ className: classNames.join(" "),
77
+ "aria-disabled": disabled,
78
+ style: {
79
+ ...rest.style
80
+ }
80
81
  },
81
- children: children
82
- });
82
+ children
83
+ );
83
84
  }
84
85
 
85
86
  return (
@@ -0,0 +1,76 @@
1
+ /*!
2
+ * Copyright 2022 OneWelcome B.V.
3
+ *
4
+ * Licensed under the Apache License, Version 2.0 (the "License");
5
+ * you may not use this file except in compliance with the License.
6
+ * You may obtain a copy of the License at
7
+ *
8
+ * http://www.apache.org/licenses/LICENSE-2.0
9
+ *
10
+ * Unless required by applicable law or agreed to in writing, software
11
+ * distributed under the License is distributed on an "AS IS" BASIS,
12
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ * See the License for the specific language governing permissions and
14
+ * limitations under the License.
15
+ */
16
+
17
+ .banner {
18
+ padding: 1rem 1.25rem;
19
+ background-color: var(--light);
20
+ display: flex;
21
+ border-width: 1px;
22
+ border-style: solid;
23
+ flex-grow: 0;
24
+ border-radius: var(--banner-border-radius);
25
+
26
+ .container {
27
+ display: block;
28
+ margin-left: 1rem;
29
+ flex: 1;
30
+ color: var(--default);
31
+ }
32
+
33
+ .headline {
34
+ margin-bottom: 0.25rem;
35
+ }
36
+ .content {
37
+ margin-bottom: 0;
38
+ }
39
+
40
+ .icon {
41
+ margin-top: 0.1rem;
42
+ font-size: 1.25rem;
43
+ line-height: 1.5rem;
44
+ }
45
+
46
+ &.info {
47
+ border-color: var(--info);
48
+ .icon {
49
+ color: var(--info);
50
+ }
51
+ .headline {
52
+ color: var(--info);
53
+ }
54
+ }
55
+
56
+ &.warning {
57
+ border-color: var(--error);
58
+ .icon {
59
+ color: var(--warning);
60
+ }
61
+
62
+ .headline {
63
+ color: var(--warning);
64
+ }
65
+ }
66
+ &.error {
67
+ border-color: var(--error);
68
+ .icon {
69
+ color: var(--error);
70
+ }
71
+
72
+ .headline {
73
+ color: var(--error);
74
+ }
75
+ }
76
+ }
@@ -0,0 +1,84 @@
1
+ /*
2
+ * Copyright 2022 OneWelcome B.V.
3
+ *
4
+ * Licensed under the Apache License, Version 2.0 (the "License");
5
+ * you may not use this file except in compliance with the License.
6
+ * You may obtain a copy of the License at
7
+ *
8
+ * http://www.apache.org/licenses/LICENSE-2.0
9
+ *
10
+ * Unless required by applicable law or agreed to in writing, software
11
+ * distributed under the License is distributed on an "AS IS" BASIS,
12
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ * See the License for the specific language governing permissions and
14
+ * limitations under the License.
15
+ */
16
+
17
+ import React from "react";
18
+ import { Banner, Props } from "./Banner";
19
+ import { render } from "@testing-library/react";
20
+
21
+ const defaultParams: Props = {
22
+ children: "The service will not be available between 02:00 and 03:00.",
23
+ title: "Maintenance is scheduled for next weekend",
24
+ type: "info"
25
+ };
26
+
27
+ const createBanner = (params?: (defaultParams: Props) => Props) => {
28
+ let parameters: Props = defaultParams;
29
+ if (params) {
30
+ parameters = params(defaultParams);
31
+ }
32
+ const queries = render(
33
+ <Banner {...parameters} data-testid="BannerTest">
34
+ {defaultParams.children}
35
+ </Banner>
36
+ );
37
+ const BannerComponent = queries.getByTestId("BannerTest");
38
+
39
+ return {
40
+ ...queries,
41
+ BannerComponent
42
+ };
43
+ };
44
+
45
+ describe("Banner should render", () => {
46
+ it("renders without crashing", () => {
47
+ const { BannerComponent } = createBanner();
48
+ expect(BannerComponent).toBeDefined();
49
+ const title = BannerComponent.querySelector(".headline");
50
+ const content = BannerComponent.querySelector(".content");
51
+ const icon = BannerComponent.querySelector(".icon");
52
+ expect(BannerComponent).toHaveClass("info");
53
+ expect(title).toBeDefined();
54
+ expect(title).toHaveTextContent(defaultParams.title);
55
+ expect(content).toBeDefined();
56
+ expect(content).toHaveTextContent(defaultParams.children);
57
+ expect(icon).toBeDefined();
58
+ });
59
+
60
+ it("renders ariaLabel correctly", () => {
61
+ const ariaLabel = "Information regarding your information";
62
+ const { BannerComponent } = createBanner(defaultParams => ({ ...defaultParams, ariaLabel }));
63
+ expect(BannerComponent).toBeDefined();
64
+ expect(BannerComponent).toHaveAttribute("aria-label", ariaLabel);
65
+ });
66
+
67
+ it("renders ariaLive correctly", () => {
68
+ const ariaLive = "polite";
69
+ const { BannerComponent } = createBanner(defaultParams => ({ ...defaultParams, ariaLive }));
70
+ expect(BannerComponent).toBeDefined();
71
+ expect(BannerComponent).toHaveAttribute("aria-live", ariaLive);
72
+ });
73
+
74
+ it("renders ariaRole correctly", () => {
75
+ const ariaRole = "alert";
76
+ const { BannerComponent } = createBanner(defaultParams => ({
77
+ ...defaultParams,
78
+ type: "error",
79
+ ariaRole
80
+ }));
81
+ expect(BannerComponent).toBeDefined();
82
+ expect(BannerComponent).toHaveAttribute("role", ariaRole);
83
+ });
84
+ });
@@ -0,0 +1,78 @@
1
+ /*
2
+ * Copyright 2022 OneWelcome B.V.
3
+ *
4
+ * Licensed under the Apache License, Version 2.0 (the "License");
5
+ * you may not use this file except in compliance with the License.
6
+ * You may obtain a copy of the License at
7
+ *
8
+ * http://www.apache.org/licenses/LICENSE-2.0
9
+ *
10
+ * Unless required by applicable law or agreed to in writing, software
11
+ * distributed under the License is distributed on an "AS IS" BASIS,
12
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ * See the License for the specific language governing permissions and
14
+ * limitations under the License.
15
+ */
16
+
17
+ import React, {
18
+ AriaAttributes,
19
+ AriaRole,
20
+ ComponentPropsWithRef,
21
+ ForwardRefRenderFunction
22
+ } from "react";
23
+ import { Typography } from "../../Typography/Typography";
24
+ import { Icon, Icons } from "../../Icon/Icon";
25
+ import classes from "./Banner.module.scss";
26
+
27
+ export type BannerType = "error" | "warning" | "info";
28
+ export interface Props extends ComponentPropsWithRef<"section"> {
29
+ children: string;
30
+ ariaRole?: AriaRole;
31
+ ariaLive?: AriaAttributes["aria-live"];
32
+ ariaLabel?: AriaAttributes["aria-label"];
33
+ type: BannerType;
34
+ title: string;
35
+ }
36
+
37
+ const BannerComponent: ForwardRefRenderFunction<HTMLElement, Props> = (
38
+ { children, ariaLabel, ariaRole, ariaLive, type, title, ...rest }: Props,
39
+ ref
40
+ ) => {
41
+ const getIconVariant = (type: BannerType): Icons | null => {
42
+ switch (type) {
43
+ case "info":
44
+ return Icons.InfoCircle;
45
+ case "error":
46
+ return Icons.Error;
47
+ case "warning":
48
+ return Icons.Warning;
49
+ default:
50
+ return null;
51
+ }
52
+ };
53
+
54
+ const icon = getIconVariant(type);
55
+
56
+ return (
57
+ <section
58
+ {...rest}
59
+ ref={ref}
60
+ aria-live={ariaLive}
61
+ aria-label={ariaLabel}
62
+ role={ariaRole}
63
+ className={`${classes["banner"]} ${classes[type]}`}
64
+ >
65
+ {icon && <Icon icon={icon} className={classes["icon"]} />}
66
+ <div className={classes["container"]}>
67
+ <Typography variant={"h4"} className={classes["headline"]}>
68
+ {title}
69
+ </Typography>
70
+ <Typography variant={"body"} className={classes["content"]} tag={"p"}>
71
+ {children}
72
+ </Typography>
73
+ </div>
74
+ </section>
75
+ );
76
+ };
77
+
78
+ export const Banner = React.forwardRef(BannerComponent);
@@ -14,7 +14,7 @@
14
14
  * limitations under the License.
15
15
  */
16
16
 
17
- @import "../../mixins.module.scss";
17
+ @use "../../mixins.module.scss";
18
18
 
19
19
  $zIndex: 10;
20
20
  $marginTop: 3.125rem;
@@ -41,7 +41,7 @@ $marginTop: 3.125rem;
41
41
  left: 0;
42
42
  top: 0;
43
43
  background-color: transparent;
44
- @include transition(background-color, 0.5s, ease);
44
+ @include mixins.transition(background-color, 0.5s, ease);
45
45
  }
46
46
 
47
47
  &.visible {