@conduction/components 2.2.17 → 2.2.19

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 (33) hide show
  1. package/README.md +6 -0
  2. package/lib/components/Pagination/Pagination.module.css +1 -1
  3. package/lib/components/card/richContentCard/RichContentCard.js +7 -7
  4. package/lib/components/card/richContentCard/RichContentCard.module.css +93 -103
  5. package/lib/components/formFields/select/select.js +28 -64
  6. package/lib/components/formFields/select/select.module.css +5 -0
  7. package/lib/components/horizontalOverflowWrapper/HorizontalOverflowWrapper.d.ts +10 -0
  8. package/lib/components/horizontalOverflowWrapper/HorizontalOverflowWrapper.js +36 -0
  9. package/lib/components/horizontalOverflowWrapper/HorizontalOverflowWrapper.module.css +41 -0
  10. package/lib/components/tabs/Tabs.js +8 -2
  11. package/lib/components/topNav/primaryTopNav/PrimaryTopNav.d.ts +9 -7
  12. package/lib/components/topNav/primaryTopNav/PrimaryTopNav.js +12 -23
  13. package/lib/components/topNav/primaryTopNav/PrimaryTopNav.module.css +10 -5
  14. package/lib/index.d.ts +2 -2
  15. package/lib/index.js +2 -2
  16. package/package.json +1 -1
  17. package/src/components/Pagination/Pagination.module.css +1 -1
  18. package/src/components/formFields/select/select.module.css +5 -0
  19. package/src/components/formFields/select/select.tsx +28 -64
  20. package/src/components/horizontalOverflowWrapper/HorizontalOverflowWrapper.module.css +41 -0
  21. package/src/components/horizontalOverflowWrapper/HorizontalOverflowWrapper.tsx +80 -0
  22. package/src/components/tabs/Tabs.tsx +10 -2
  23. package/src/components/topNav/primaryTopNav/PrimaryTopNav.module.css +10 -5
  24. package/src/components/topNav/primaryTopNav/PrimaryTopNav.tsx +29 -45
  25. package/src/index.ts +2 -2
  26. package/tsconfig.json +5 -16
  27. package/lib/components/tableWrapper/TableWrapper.d.ts +0 -4
  28. package/lib/components/tableWrapper/TableWrapper.js +0 -30
  29. package/lib/components/tableWrapper/TableWrapper.module.css +0 -67
  30. package/lib/components/temp/Temp.d.ts +0 -5
  31. package/lib/components/temp/Temp.js +0 -14
  32. package/src/components/tableWrapper/TableWrapper.module.css +0 -67
  33. package/src/components/tableWrapper/TableWrapper.tsx +0 -56
package/README.md CHANGED
@@ -4,6 +4,12 @@
4
4
 
5
5
  - **Version 2.2 (breaking changes from 2.1.x)**
6
6
 
7
+ - 2.2.19: Refactored primary top nav to simplify sub-items.
8
+ - 2.2.18:
9
+ - Refactored select role attribute.
10
+ - Fixed Pagination-button border-radius.
11
+ - Added colors for Focus and Selected options in Select forms.
12
+ - Add HorizontalOverflowWrapper component and refactor Tabs Component overflow scroll.
7
13
  - 2.2.17: Refactor Pagination to include aria labels and make aria label required on texarea, input and select components.
8
14
  - 2.2.15/2.2.16: Added more NLDS options to Pagination.
9
15
  - 2.2.13/2.2.14:
@@ -150,7 +150,7 @@
150
150
  border-width: var(--conduction-pagination-navigation-button-border-width, var(--utrecht-button-border-width)) !important;
151
151
  border-style: var(--conduction-pagination-navigation-button-border-style, var(--utrecht-button-border-style)) !important;
152
152
  border-color: var(--conduction-pagination-navigation-button-border-color, var(--utrecht-button-border-color)) !important;
153
- border-radius: var(--conduction-pagination-navigation-button-border-radius, var(--utrecht-button-border-radius));
153
+ border-radius: var(--conduction-pagination-navigation-button-border-radius, var(--utrecht-button-border-radius)) !important;
154
154
  padding-inline-start: var(--conduction-pagination-navigation-button-padding-inline-start) !important;
155
155
  padding-inline-end: var(--conduction-pagination-navigation-button-padding-inline-end) !important;
156
156
  padding-block-start: var(--conduction-pagination-navigation-button-padding-block-start) !important;
@@ -1,16 +1,16 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import * as styles from "./RichContentCard.module.css";
3
- import { Link } from "@utrecht/component-library-react/dist/css-module";
2
+ import { Divider } from "@gemeente-denhaag/divider";
3
+ import { Link } from "@gemeente-denhaag/link";
4
4
  import { navigate } from "gatsby";
5
+ import * as styles from "./RichContentCard.module.css";
6
+ import { ExternalLinkIcon, ArrowRightIcon } from "@gemeente-denhaag/icons";
5
7
  import { Tag } from "../../tag/Tag";
6
- import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
7
- import { faArrowRight, faExternalLink } from "@fortawesome/free-solid-svg-icons";
8
8
  export const RichContentCard = ({ link, labelsWithIcon, tags, contentLinks, linkIsExternal, }) => {
9
- return (_jsxs("div", { className: styles.container, children: [_jsx("div", { className: styles.linkContainer, onClick: () => navigate(link.href), children: _jsxs(Link, { className: styles.link, children: [_jsx(FontAwesomeIcon, { icon: linkIsExternal ? faExternalLink : faArrowRight }), link.label] }) }), _jsx("div", { className: styles.labelsWithIcon, children: labelsWithIcon.map(({ label, icon }, idx) => (_jsx(LabelWithIcon, { ...{ label, icon } }, idx))) }), _jsx("div", { className: styles.tags, children: tags.map((tag, idx) => (_jsx(Tag, { label: tag }, idx))) }), contentLinks && (_jsxs("div", { className: styles.contentLinks, children: [_jsx("hr", { className: styles.divider }), contentLinks.map(({ title, subTitle, href }, idx) => (_jsx(ContentLink, { ...{ title, subTitle, href } }, idx)))] }))] }));
9
+ return (_jsxs("div", { className: styles.container, children: [_jsx("div", { className: styles.link, onClick: () => navigate(link.href), children: _jsx(Link, { icon: linkIsExternal ? _jsx(ExternalLinkIcon, {}) : _jsx(ArrowRightIcon, {}), iconAlign: "start", children: link.label }) }), _jsx("div", { className: styles.labelsWithIcon, children: labelsWithIcon.map(({ label, icon }, idx) => (_jsx(LabelWithIcon, { ...{ label, icon } }, idx))) }), _jsx("div", { className: styles.tags, children: tags.map((tag, idx) => (_jsx(Tag, { label: tag }, idx))) }), contentLinks && (_jsxs("div", { className: styles.contentLinks, children: [_jsx(Divider, {}), contentLinks.map(({ title, subTitle, href }, idx) => (_jsx(ContentLink, { ...{ title, subTitle, href } }, idx)))] }))] }));
10
10
  };
11
11
  const LabelWithIcon = ({ label, icon }) => {
12
12
  return (_jsxs("div", { className: styles.labelWithIcon, children: [_jsx("span", { className: styles.labelWithIcon_icon, children: icon }), _jsx("span", { className: styles.labelWithIcon_label, children: label })] }));
13
13
  };
14
- const ContentLink = ({ title, subTitle }) => {
15
- return (_jsxs(Link, { className: styles.contentLink, children: [_jsxs("div", { className: styles.contentLink_content, children: [_jsx("span", { className: styles.contentLink_title, children: title }), _jsx("span", { className: styles.contentLink_subTitle, children: subTitle })] }), _jsx("div", { children: _jsx(FontAwesomeIcon, { icon: faArrowRight }) })] }));
14
+ const ContentLink = ({ title, subTitle, href }) => {
15
+ return (_jsxs(Link, { className: styles.contentLink, children: [_jsxs("div", { className: styles.contentLink_content, children: [_jsx("span", { className: styles.contentLink_title, children: title }), _jsx("span", { className: styles.contentLink_subTitle, children: subTitle })] }), _jsx("div", { children: _jsx(ArrowRightIcon, {}) })] }));
16
16
  };
@@ -1,103 +1,93 @@
1
- :root {
2
- --conduction-rich-content-card-border: 1px solid var(--skeleton-color-grey-2);
3
- }
4
-
5
- .container {
6
- display: flex;
7
- flex-direction: column;
8
- border: var(--conduction-rich-content-card-border);
9
- border-radius: var(--skeleton-border-radius-md);
10
-
11
- padding-inline-start: var(--skeleton-size-md);
12
- padding-inline-end: var(--skeleton-size-md);
13
- padding-block-start: var(--skeleton-size-md);
14
- padding-block-end: var(--skeleton-size-md);
15
- }
16
-
17
- .container > *:not(.linkContainer):not(:last-child) {
18
- margin-block-end: var(--skeleton-size-md);
19
- }
20
-
21
- .linkContainer {
22
- margin-block-end: var(--skeleton-size-xs);
23
- }
24
-
25
- .linkContainer > :first-child {
26
- display: flex;
27
- }
28
-
29
- .link > * {
30
- margin-inline-end: 8px;
31
- }
32
-
33
- .labelsWithIcon {
34
- display: flex;
35
- flex-wrap: wrap;
36
- }
37
-
38
- .labelsWithIcon > *:not(:last-child) {
39
- margin-inline-end: var(--skeleton-size-md);
40
- }
41
-
42
- .tags > *:not(:last-child) {
43
- margin-inline-end: var(--skeleton-size-md);
44
- }
45
-
46
- .contentLinks > *:not(:last-child):not(hr) {
47
- margin-block-end: var(--skeleton-size-xs);
48
- }
49
-
50
- /* Component: LabelWithIcon */
51
- .labelWithIcon {
52
- display: flex;
53
- align-items: center;
54
- color: var(--skeleton-color-grey-3);
55
- }
56
-
57
- .labelWithIcon > .labelWithIcon_icon > svg {
58
- height: var(--skeleton-size-sm);
59
- width: var(--skeleton-size-sm);
60
- margin-inline-end: var(--skeleton-size-xs);
61
- }
62
-
63
- .labelWithIcon > .labelWithIcon_label {
64
- font-size: var(--skeleton-size-sm);
65
- }
66
-
67
- /* Content Link */
68
- .contentLink {
69
- display: flex;
70
- padding-block-start: var(--skeleton-size-xs);
71
- padding-block-end: var(--skeleton-size-xs);
72
- text-decoration: none !important;
73
- }
74
-
75
- .contentLink > span {
76
- width: 100%;
77
- display: flex;
78
- justify-content: space-between;
79
- }
80
-
81
- .contentLink:hover {
82
- cursor: pointer;
83
- }
84
-
85
- .contentLink_content {
86
- display: flex;
87
- flex-direction: column;
88
- }
89
-
90
- .contentLink_title {
91
- font-size: var(--conduction-content-link-font-size);
92
- }
93
-
94
- .contentLink_subTitle {
95
- font-size: var(--conduction-content-link-font-size);
96
- color: var(--denhaag-color-grey-3);
97
- }
98
-
99
- .divider {
100
- width: 100%;
101
- opacity: 0.5;
102
- margin-block: var(--skeleton-size-lg);
103
- }
1
+ :root {
2
+ --conduction-rich-content-card-border: 1px solid var(--skeleton-color-grey-2);
3
+ }
4
+
5
+ .container {
6
+ display: flex;
7
+ flex-direction: column;
8
+ border: var(--conduction-rich-content-card-border);
9
+ border-radius: var(--skeleton-border-radius-md);
10
+
11
+ padding-inline-start: var(--skeleton-size-md);
12
+ padding-inline-end: var(--skeleton-size-md);
13
+ padding-block-start: var(--skeleton-size-md);
14
+ padding-block-end: var(--skeleton-size-md);
15
+ }
16
+
17
+ .container > *:not(.link):not(:last-child) {
18
+ margin-block-end: var(--skeleton-size-md);
19
+ }
20
+
21
+ .link {
22
+ margin-block-end: var(--skeleton-size-xs);
23
+ }
24
+
25
+ .link > :first-child {
26
+ display: flex;
27
+ }
28
+
29
+ .labelsWithIcon {
30
+ display: flex;
31
+ flex-wrap: wrap;
32
+ }
33
+
34
+ .labelsWithIcon > *:not(:last-child) {
35
+ margin-inline-end: var(--skeleton-size-md);
36
+ }
37
+
38
+ .tags > *:not(:last-child) {
39
+ margin-inline-end: var(--skeleton-size-md);
40
+ }
41
+
42
+ .contentLinks > *:not(:last-child):not(hr) {
43
+ margin-block-end: var(--skeleton-size-xs);
44
+ }
45
+
46
+ /* Component: LabelWithIcon */
47
+ .labelWithIcon {
48
+ display: flex;
49
+ align-items: center;
50
+ color: var(--skeleton-color-grey-3);
51
+ }
52
+
53
+ .labelWithIcon > .labelWithIcon_icon > svg {
54
+ height: var(--skeleton-size-sm);
55
+ width: var(--skeleton-size-sm);
56
+ margin-inline-end: var(--skeleton-size-xs);
57
+ }
58
+
59
+ .labelWithIcon > .labelWithIcon_label {
60
+ font-size: var(--skeleton-size-sm);
61
+ }
62
+
63
+ /* Content Link */
64
+ .contentLink {
65
+ display: flex;
66
+ padding-block-start: var(--skeleton-size-xs);
67
+ padding-block-end: var(--skeleton-size-xs);
68
+ text-decoration: none !important;
69
+ }
70
+
71
+ .contentLink > span {
72
+ width: 100%;
73
+ display: flex;
74
+ justify-content: space-between;
75
+ }
76
+
77
+ .contentLink:hover {
78
+ cursor: pointer;
79
+ }
80
+
81
+ .contentLink_content {
82
+ display: flex;
83
+ flex-direction: column;
84
+ }
85
+
86
+ .contentLink_title {
87
+ font-size: var(--conduction-content-link-font-size);
88
+ }
89
+
90
+ .contentLink_subTitle {
91
+ font-size: var(--conduction-content-link-font-size);
92
+ color: var(--denhaag-color-grey-3);
93
+ }
@@ -8,10 +8,23 @@ import clsx from "clsx";
8
8
  import { ErrorMessage } from "../errorMessage/ErrorMessage";
9
9
  const selectStyles = {
10
10
  menuPortal: (base) => ({ ...base, zIndex: 100 }),
11
- option: (base) => ({
11
+ option: (base, state) => ({
12
12
  ...base,
13
13
  fontFamily: `var(--conduction-input-select-list-option-font-family, ${base.fontFamily})`,
14
- backgroundColor: `var(--conduction-input-select-list-option-background-color, ${base.backgroundColor}) `,
14
+ backgroundColor: [
15
+ state.isFocused
16
+ ? `var(--conduction-input-select-list-option-focus-background-color, ${base.backgroundColor})`
17
+ : state.isSelected
18
+ ? `var(--conduction-input-select-list-option-selected-background-color, ${base.backgroundColor})`
19
+ : `var(--conduction-input-select-list-option-background-color, ${base.backgroundColor})`,
20
+ ],
21
+ color: [
22
+ state.isFocused
23
+ ? `var(--conduction-input-select-list-option-focus-color, ${base.color})`
24
+ : state.isSelected
25
+ ? `var(--conduction-input-select-list-option-selected-color, ${base.color})`
26
+ : `var(--conduction-input-select-list-option-color, ${base.color})`,
27
+ ],
15
28
  "&:hover": {
16
29
  backgroundColor: `var(--conduction-input-select-list-option-hover-background-color, ${base.backgroundColor})`,
17
30
  color: `var(--conduction-input-select-list-option-hover-color, ${base.color})`,
@@ -24,41 +37,20 @@ const selectStyles = {
24
37
  color: `var(--conduction-input-select-placeholder-color, var(--utrecht-form-input-placeholder-color, ${base.color}) )`,
25
38
  }),
26
39
  };
27
- const selectMultiStyles = {
28
- menuPortal: (base) => ({ ...base, zIndex: 100 }),
29
- option: (base) => ({
30
- ...base,
31
- fontFamily: `var(--conduction-input-select-list-option-font-family, ${base.fontFamily})`,
32
- backgroundColor: `var(--conduction-input-select-list-option-background-color, ${base.backgroundColor}) `,
33
- "&:hover": {
34
- backgroundColor: `var(--conduction-input-select-list-option-hover-background-color, ${base.backgroundColor})`,
35
- color: `var(--conduction-input-select-list-option-hover-color, ${base.color})`,
36
- fontFamily: `var(--conduction-input-select-list-option-hover-font-family, var(--conduction-input-select-list-option-font-family, ${base.fontFamily}))`,
37
- },
38
- }),
39
- placeholder: (base) => ({
40
- ...base,
41
- fontFamily: `var(--conduction-input-select-placeholder-font-family, var(--utrecht-form-input-placeholder-font-family, ${base.fontFamily}))`,
42
- color: `var(--conduction-input-select-placeholder-color, var(--utrecht-form-input-placeholder-color, ${base.color}) )`,
43
- }),
40
+ const setAttributes = () => {
41
+ const setRoleToPresentation = (selector, role) => {
42
+ document.querySelectorAll(selector).forEach((element) => {
43
+ if (element.getAttribute("role") !== "presentation")
44
+ element.setAttribute("role", role);
45
+ });
46
+ };
47
+ setRoleToPresentation('[id*="live-region"]', "presentation");
48
+ setRoleToPresentation('[class*="indicatorSeparator"]', "separator");
49
+ setRoleToPresentation('[class*="a11yText"]', "presentation");
44
50
  };
45
51
  export const SelectMultiple = ({ id, name, options, errors, control, validation, defaultValue, disabled, hideErrorMessage, menuPlacement, placeholder, ariaLabel, }) => {
46
52
  React.useEffect(() => {
47
- document.querySelectorAll('[id*="live-region"]').forEach((element) => {
48
- if (element?.role !== "presentation") {
49
- element.setAttribute("role", "presentation");
50
- }
51
- });
52
- document.querySelectorAll('[class*="indicatorSeparator"]').forEach((element) => {
53
- if (element.role !== "presentation") {
54
- element.setAttribute("role", "presentation");
55
- }
56
- });
57
- document.querySelectorAll('[class*="a11yText"]').forEach((element) => {
58
- if (element.role !== "presentation") {
59
- element.setAttribute("role", "presentation");
60
- }
61
- });
53
+ setAttributes();
62
54
  }, []);
63
55
  return (_jsx(Controller, { ...{ control, name, defaultValue }, rules: validation, render: ({ field: { onChange, value } }) => {
64
56
  return (_jsxs(_Fragment, { children: [_jsx(ReactSelect, { "aria-label": ariaLabel, inputId: id, value: value ?? "", className: clsx(styles.select, errors[name] && styles.error), isMulti: true, isDisabled: disabled, ...{ options, onChange, errors }, menuPortalTarget: document.body, menuPlacement: menuPlacement, styles: selectStyles, placeholder: disabled ? "Disabled..." : placeholder ?? "Select one or more options..." }), errors[name] && !hideErrorMessage && _jsx(ErrorMessage, { message: errors[name].message })] }));
@@ -66,21 +58,7 @@ export const SelectMultiple = ({ id, name, options, errors, control, validation,
66
58
  };
67
59
  export const SelectCreate = ({ id, name, options, errors, control, validation, defaultValue, disabled, hideErrorMessage, menuPlacement, placeholder, ariaLabel, }) => {
68
60
  React.useEffect(() => {
69
- document.querySelectorAll('[id*="live-region"]').forEach((element) => {
70
- if (element.role !== "presentation") {
71
- element.setAttribute("role", "presentation");
72
- }
73
- });
74
- document.querySelectorAll('[class*="indicatorSeparator"]').forEach((element) => {
75
- if (element.role !== "presentation") {
76
- element.setAttribute("role", "presentation");
77
- }
78
- });
79
- document.querySelectorAll('[class*="a11yText"]').forEach((element) => {
80
- if (element.role !== "presentation") {
81
- element.setAttribute("role", "presentation");
82
- }
83
- });
61
+ setAttributes();
84
62
  }, []);
85
63
  return (_jsx(Controller, { ...{ control, name, defaultValue }, rules: validation, render: ({ field: { onChange, value } }) => {
86
64
  return (_jsxs(_Fragment, { children: [_jsx(CreatableSelect, { "aria-label": ariaLabel, inputId: id, value: value ?? "", placeholder: disabled ? "Disabled..." : placeholder ?? "Select one or more options...", className: clsx(styles.select, errors[name] && styles.error), isMulti: true, isDisabled: disabled, ...{ options, onChange, errors }, menuPortalTarget: document.body, menuPlacement: menuPlacement, styles: selectStyles }), errors[name] && !hideErrorMessage && _jsx(ErrorMessage, { message: errors[name].message })] }));
@@ -88,21 +66,7 @@ export const SelectCreate = ({ id, name, options, errors, control, validation, d
88
66
  };
89
67
  export const SelectSingle = ({ id, name, options, errors, control, validation, isClearable, defaultValue, disabled, hideErrorMessage, menuPlacement, placeholder, ariaLabel, }) => {
90
68
  React.useEffect(() => {
91
- document.querySelectorAll('[id*="live-region"]').forEach((element) => {
92
- if (element.role !== "presentation") {
93
- element.setAttribute("role", "presentation");
94
- }
95
- });
96
- document.querySelectorAll('[class*="indicatorSeparator"]').forEach((element) => {
97
- if (element.role !== "presentation") {
98
- element.setAttribute("role", "presentation");
99
- }
100
- });
101
- document.querySelectorAll('[class*="a11yText"]').forEach((element) => {
102
- if (element.role !== "presentation") {
103
- element.setAttribute("role", "presentation");
104
- }
105
- });
69
+ setAttributes();
106
70
  }, []);
107
71
  return (_jsx(Controller, { ...{ control, name, defaultValue }, rules: validation, render: ({ field: { onChange, value } }) => {
108
72
  return (_jsxs(_Fragment, { children: [_jsx(ReactSelect, { "aria-label": ariaLabel, inputId: id, value: value ?? "", className: clsx(styles.select, errors[name] && styles.error), isDisabled: disabled, ...{ options, onChange, errors, isClearable }, menuPortalTarget: document.body, menuPlacement: menuPlacement, styles: selectStyles, placeholder: disabled ? "Disabled..." : placeholder ?? "Select one or more options..." }), errors[name] && !hideErrorMessage && _jsx(ErrorMessage, { message: errors[name].message })] }));
@@ -12,6 +12,11 @@
12
12
 
13
13
  --conduction-input-select-list-option-font-family: "Noto Sans", Arial, sans-serif;
14
14
  /* --conduction-input-select-list-option-background-color: unset; */
15
+ /* --conduction-input-select-list-option-color: unset; */
16
+ /* --conduction-input-select-list-option-selected--background-color: unset; */
17
+ /* --conduction-input-select-list-option-selected-color: unset; */
18
+ /* --conduction-input-select-list-option-focus-background-color: unset; */
19
+ /* --conduction-input-select-list-option-focus-color: unset; */
15
20
 
16
21
  /* --conduction-input-select-list-option-hover-background-color: unset; */
17
22
  /* --conduction-input-select-list-option-hover-color: unset; */
@@ -0,0 +1,10 @@
1
+ import * as React from "react";
2
+ interface HorizontalOverflowWrapperProps {
3
+ children: React.ReactNode;
4
+ ariaLabels: {
5
+ scrollRightButton: string;
6
+ scrollLeftButton: string;
7
+ };
8
+ }
9
+ export declare const HorizontalOverflowWrapper: React.FC<HorizontalOverflowWrapperProps>;
10
+ export {};
@@ -0,0 +1,36 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import * as React from "react";
3
+ import * as styles from "./HorizontalOverflowWrapper.module.css";
4
+ import clsx from "clsx";
5
+ import { Button } from "@utrecht/component-library-react/dist/css-module";
6
+ import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
7
+ import { faChevronLeft, faChevronRight } from "@fortawesome/free-solid-svg-icons";
8
+ export const HorizontalOverflowWrapper = ({ children, ariaLabels }) => {
9
+ const [canScrollRight, setCanScrollRight] = React.useState(false);
10
+ const [canScrollLeft, setCanScrollLeft] = React.useState(false);
11
+ const wrapperRef = React.useRef(null);
12
+ const scrollRight = () => {
13
+ wrapperRef.current?.scrollTo({
14
+ left: wrapperRef.current.scrollLeft + wrapperRef.current.clientWidth * 0.9,
15
+ behavior: "smooth",
16
+ });
17
+ };
18
+ const scrollLeft = () => {
19
+ wrapperRef.current?.scrollTo({
20
+ left: wrapperRef.current.scrollLeft - wrapperRef.current.clientWidth * 0.9,
21
+ behavior: "smooth",
22
+ });
23
+ };
24
+ React.useEffect(() => {
25
+ checkScrollDirections(); // initiate available scroll directions
26
+ window.addEventListener("resize", checkScrollDirections);
27
+ return () => window.removeEventListener("resize", checkScrollDirections);
28
+ }, []);
29
+ const checkScrollDirections = () => {
30
+ if (!wrapperRef.current)
31
+ return;
32
+ setCanScrollRight(wrapperRef.current.scrollLeft + wrapperRef.current.clientWidth < wrapperRef.current.scrollWidth);
33
+ setCanScrollLeft(wrapperRef.current.scrollLeft > 0);
34
+ };
35
+ return (_jsxs("div", { className: styles.container, children: [canScrollLeft && (_jsx(Button, { className: clsx(styles.scrollButton, styles.left), onClick: scrollLeft, appearance: "secondary-action-button", "aria-label": ariaLabels.scrollLeftButton, children: _jsx(FontAwesomeIcon, { icon: faChevronLeft }) })), canScrollRight && (_jsx(Button, { className: clsx(styles.scrollButton, styles.right), onClick: scrollRight, appearance: "secondary-action-button", "aria-label": ariaLabels.scrollRightButton, children: _jsx(FontAwesomeIcon, { icon: faChevronRight }) })), _jsx("div", { ref: wrapperRef, className: styles.wrapper, onScroll: checkScrollDirections, children: children })] }));
36
+ };
@@ -0,0 +1,41 @@
1
+ :root {
2
+ --conduction-horizontal-overflow-wrapper-background-color: unset;
3
+ --conduction-horizontal-overflow-wrapper-buttons-top: 12px;
4
+
5
+ --conduction-horizontal-overflow-wrapper-margin-inline-start: 8px;
6
+ --conduction-horizontal-overflow-wrapper-margin-inline-end: 8px;
7
+ --conduction-horizontal-overflow-wrapper-margin-block-start: 8px;
8
+ --conduction-horizontal-overflow-wrapper-margin-block-end: 8px;
9
+ }
10
+
11
+ .container {
12
+ position: relative;
13
+ background-color: var(--conduction-horizontal-overflow-wrapper-background-color);
14
+ }
15
+
16
+ .wrapper {
17
+ overflow-x: scroll;
18
+ }
19
+
20
+ .scrollButton {
21
+ position: sticky;
22
+ top: var(--conduction-horizontal-overflow-wrapper-buttons-top);
23
+
24
+ margin-inline-start: var(--conduction-horizontal-overflow-wrapper-margin-inline-start);
25
+ margin-inline-end: var(--conduction-horizontal-overflow-wrapper-margin-inline-end);
26
+ margin-block-start: var(--conduction-horizontal-overflow-wrapper-margin-block-start);
27
+ margin-block-end: var(--conduction-horizontal-overflow-wrapper-margin-block-end);
28
+ }
29
+
30
+ .scrollButton.right {
31
+ left: 100%;
32
+ }
33
+
34
+ /* Hide scrollbar */
35
+ .wrapper::-webkit-scrollbar {
36
+ display: none;
37
+ }
38
+ .wrapper {
39
+ -ms-overflow-style: none;
40
+ scrollbar-width: none;
41
+ }
@@ -21,11 +21,17 @@ export const TabList = ({ children, ...otherProps }) => {
21
21
  };
22
22
  const handleScrollRight = () => {
23
23
  if (wrapperRef.current)
24
- wrapperRef.current.scrollTo({ left: wrapperRef.current.scrollWidth, behavior: "smooth" });
24
+ wrapperRef.current.scrollTo({
25
+ left: wrapperRef.current.scrollLeft + wrapperRef.current.clientWidth * 0.9,
26
+ behavior: "smooth",
27
+ });
25
28
  };
26
29
  const handleScrollLeft = () => {
27
30
  if (wrapperRef.current)
28
- wrapperRef.current.scrollTo({ left: 0, behavior: "smooth" });
31
+ wrapperRef.current.scrollTo({
32
+ left: wrapperRef.current.scrollLeft - wrapperRef.current.clientWidth * 0.9,
33
+ behavior: "smooth",
34
+ });
29
35
  };
30
36
  React.useEffect(() => {
31
37
  if (wrapperRef.current) {
@@ -1,16 +1,18 @@
1
1
  /// <reference types="react" />
2
- interface ITopNavItem {
2
+ interface ITopNavItemBase {
3
3
  label: string;
4
4
  icon?: JSX.Element;
5
5
  current?: boolean;
6
+ }
7
+ interface ITopNavItemWithSubItems extends ITopNavItemBase {
8
+ handleClick?: never;
9
+ subItems: ITopNavItem[];
10
+ }
11
+ interface ITopNavItemWithoutSubItems extends ITopNavItemBase {
6
12
  handleClick?: () => any;
7
- subItems?: {
8
- label: string;
9
- icon?: JSX.Element;
10
- current?: boolean;
11
- handleClick?: () => any;
12
- }[];
13
+ subItems?: never;
13
14
  }
15
+ export declare type ITopNavItem = ITopNavItemWithSubItems | ITopNavItemWithoutSubItems;
14
16
  export interface TopNavProps {
15
17
  items: ITopNavItem[];
16
18
  mobileLogo?: JSX.Element;
@@ -7,28 +7,17 @@ import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
7
7
  import { faBars, faChevronRight } from "@fortawesome/free-solid-svg-icons";
8
8
  export const PrimaryTopNav = ({ items, mobileLogo, layoutClassName }) => {
9
9
  const [isOpen, setIsOpen] = React.useState(false);
10
- const [subNavIsOpen, setSubNavIsOpen] = React.useState({});
11
- const handleItemClick = (handleClick) => {
12
- if (handleClick) {
13
- handleClick();
14
- setIsOpen(false);
15
- }
16
- };
17
- const handleSubItemMenu = (idx, value) => {
18
- setSubNavIsOpen({
19
- ...subNavIsOpen,
20
- [idx]: value,
21
- });
22
- };
23
- const screenWidth = window.innerWidth;
10
+ const [isMobile, setIsMobile] = React.useState(window.innerWidth < 992);
24
11
  React.useEffect(() => {
25
- if (screenWidth > 992) {
26
- setSubNavIsOpen({});
27
- }
28
- }, [screenWidth]);
29
- return (_jsxs("div", { className: clsx(styles.container, layoutClassName && layoutClassName), children: [_jsxs("div", { className: styles.menuToggleContainer, children: [mobileLogo, _jsx("button", { className: styles.menuToggle, onClick: () => setIsOpen((o) => !o), children: _jsx(FontAwesomeIcon, { icon: faBars }) })] }), _jsx("nav", { className: clsx(styles.primary, isOpen && styles.isOpen), children: _jsx("ul", { className: styles.ul, children: items.map(({ label, icon, current, handleClick, subItems }, idx) => (_jsxs("li", { onClick: () => !subItems
30
- ? handleItemClick(handleClick)
31
- : screenWidth > 992
32
- ? handleItemClick(handleClick)
33
- : handleSubItemMenu(idx, !subNavIsOpen[idx] ?? true), className: clsx(styles.li, current && styles.current), children: [_jsxs(Link, { className: clsx(styles.link, styles.label, subItems && styles.mobileLink, current && styles.currentLink), children: [icon, label, " ", subItems && screenWidth < 992 && (_jsx(FontAwesomeIcon, { className: clsx(styles.toggleIcon, subNavIsOpen[idx] && styles.isOpen), icon: faChevronRight }))] }), subItems && (_jsx("ul", { className: clsx(styles.dropdown, subNavIsOpen[idx] && styles.isOpen), children: subItems.map(({ label, icon, current, handleClick }, idx) => (_jsx("li", { className: clsx(styles.li, current && styles.current), onClick: () => handleItemClick(handleClick), children: _jsxs(Link, { className: clsx(styles.link, styles.label, current && styles.currentLink), children: [icon, label] }) }, idx))) }))] }, idx))) }) })] }));
12
+ const handleResize = () => {
13
+ setIsMobile(window.innerWidth < 992);
14
+ };
15
+ window.addEventListener("resize", handleResize);
16
+ return () => window.removeEventListener("resize", handleResize);
17
+ }, []);
18
+ const handleSubItemClick = (handleClick) => {
19
+ setIsOpen(false);
20
+ handleClick();
21
+ };
22
+ return (_jsxs("div", { className: clsx(styles.container, layoutClassName && layoutClassName), children: [_jsxs("div", { className: styles.menuToggleContainer, children: [mobileLogo, _jsx("button", { className: styles.menuToggle, onClick: () => setIsOpen((o) => !o), children: _jsx(FontAwesomeIcon, { icon: faBars }) })] }), _jsx("nav", { className: clsx(styles.primary, isOpen && styles.isOpen), children: _jsx("ul", { className: styles.ul, children: items.map(({ label, icon, current, handleClick, subItems }, idx) => (_jsxs("li", { onClick: handleClick, className: clsx(styles.li, current && styles.current), children: [_jsxs(Link, { className: clsx(styles.link, styles.label, subItems && styles.mobileLink, current && styles.currentLink), children: [icon, label, " ", subItems && isMobile && _jsx(FontAwesomeIcon, { className: styles.toggleIcon, icon: faChevronRight })] }), subItems && (_jsx("ul", { className: styles.dropdown, children: subItems.map(({ label, icon, current, handleClick }, idx) => (_jsx("li", { className: clsx(styles.li, current && styles.current), onClick: () => handleSubItemClick(handleClick), children: _jsxs(Link, { className: clsx(styles.link, styles.label, current && styles.currentLink), children: [icon, label] }) }, idx))) }))] }, idx))) }) })] }));
34
23
  };
@@ -116,6 +116,11 @@
116
116
  }
117
117
  .primary .link {
118
118
  text-decoration: none;
119
+ text-overflow: ellipsis;
120
+ display: block;
121
+ overflow: hidden;
122
+ max-width: 100%;
123
+ white-space: wrap;
119
124
  }
120
125
 
121
126
  .primary .link:not(.currentLink) {
@@ -187,6 +192,11 @@
187
192
  margin-inline-end: var(--conduction-primary-top-nav-item-icon-margin);
188
193
  }
189
194
 
195
+ .li:hover .dropdown {
196
+ display: block;
197
+ z-index: 1;
198
+ }
199
+
190
200
  @media only screen and (min-width: 992px) {
191
201
  .container {
192
202
  width: fit-content;
@@ -215,11 +225,6 @@
215
225
  display: none;
216
226
  }
217
227
 
218
- .primary .li:hover .dropdown {
219
- display: block;
220
- z-index: 1;
221
- }
222
-
223
228
  .mobileLink {
224
229
  margin-block-end: unset;
225
230
  }
package/lib/index.d.ts CHANGED
@@ -23,5 +23,5 @@ import { CodeBlock } from "./components/codeBlock/CodeBlock";
23
23
  import { ToolTip } from "./components/toolTip/ToolTip";
24
24
  import { Pagination } from "./components/Pagination/Pagination";
25
25
  import { Tabs, TabList, Tab, TabPanel } from "./components/tabs/Tabs";
26
- import { TableWrapper } from "./components/tableWrapper/TableWrapper";
27
- export { DownloadCard, HorizontalImageCard, ImageAndDetailsCard, DetailsCard, InfoCard, Container, Breadcrumbs, InputText, InputPassword, InputEmail, InputDate, InputNumber, InputFile, Textarea, InputCheckbox, SelectMultiple, SelectSingle, ImageDivider, AuthenticatedLogo, UnauthenticatedLogo, MetaIcon, PrivateRoute, PrimaryTopNav, SecondaryTopNav, Tag, NotificationPopUp, QuoteWrapper, Pagination, BadgeCounter, CodeBlock, ToolTip, CardWrapper, CardHeader, CardHeaderTitle, CardHeaderDate, Tabs, TabList, Tab, TabPanel, TableWrapper, };
26
+ import { HorizontalOverflowWrapper } from "./components/horizontalOverflowWrapper/HorizontalOverflowWrapper";
27
+ export { DownloadCard, HorizontalImageCard, ImageAndDetailsCard, DetailsCard, InfoCard, Container, Breadcrumbs, InputText, InputPassword, InputEmail, InputDate, InputNumber, InputFile, Textarea, InputCheckbox, SelectMultiple, SelectSingle, ImageDivider, AuthenticatedLogo, UnauthenticatedLogo, MetaIcon, PrivateRoute, PrimaryTopNav, SecondaryTopNav, Tag, NotificationPopUp, QuoteWrapper, Pagination, BadgeCounter, CodeBlock, ToolTip, CardWrapper, CardHeader, CardHeaderTitle, CardHeaderDate, Tabs, TabList, Tab, TabPanel, HorizontalOverflowWrapper, };
package/lib/index.js CHANGED
@@ -16,5 +16,5 @@ import { CodeBlock } from "./components/codeBlock/CodeBlock";
16
16
  import { ToolTip } from "./components/toolTip/ToolTip";
17
17
  import { Pagination } from "./components/Pagination/Pagination";
18
18
  import { Tabs, TabList, Tab, TabPanel } from "./components/tabs/Tabs";
19
- import { TableWrapper } from "./components/tableWrapper/TableWrapper";
20
- export { DownloadCard, HorizontalImageCard, ImageAndDetailsCard, DetailsCard, InfoCard, Container, Breadcrumbs, InputText, InputPassword, InputEmail, InputDate, InputNumber, InputFile, Textarea, InputCheckbox, SelectMultiple, SelectSingle, ImageDivider, AuthenticatedLogo, UnauthenticatedLogo, MetaIcon, PrivateRoute, PrimaryTopNav, SecondaryTopNav, Tag, NotificationPopUp, QuoteWrapper, Pagination, BadgeCounter, CodeBlock, ToolTip, CardWrapper, CardHeader, CardHeaderTitle, CardHeaderDate, Tabs, TabList, Tab, TabPanel, TableWrapper, };
19
+ import { HorizontalOverflowWrapper } from "./components/horizontalOverflowWrapper/HorizontalOverflowWrapper";
20
+ export { DownloadCard, HorizontalImageCard, ImageAndDetailsCard, DetailsCard, InfoCard, Container, Breadcrumbs, InputText, InputPassword, InputEmail, InputDate, InputNumber, InputFile, Textarea, InputCheckbox, SelectMultiple, SelectSingle, ImageDivider, AuthenticatedLogo, UnauthenticatedLogo, MetaIcon, PrivateRoute, PrimaryTopNav, SecondaryTopNav, Tag, NotificationPopUp, QuoteWrapper, Pagination, BadgeCounter, CodeBlock, ToolTip, CardWrapper, CardHeader, CardHeaderTitle, CardHeaderDate, Tabs, TabList, Tab, TabPanel, HorizontalOverflowWrapper, };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@conduction/components",
3
- "version": "2.2.17",
3
+ "version": "2.2.19",
4
4
  "description": "React (Gatsby) components used within the Conduction Skeleton Application (and its implementations)",
5
5
  "main": "lib/index.js",
6
6
  "scripts": {