-
-
- {/* Component */}
-
- {/* Demostration purposes containers */}
-
+const Template = args => {
+ const { isBootstrap } = useBaseSpecificFramework();
+
+ return (
+ <>
+ {/* Bootstrap version of anchor menu depends on the header component */}
+ {isBootstrap &&
}
+
+
+
+
+ {/* Component */}
+
+ {/* Demostration purposes containers */}
+
+
+
-
-
-);
+ >
+ );
+};
export const Default = Template.bind({});
Default.args = {
diff --git a/packages/unity-react-core/src/components/Article/Article.jsx b/packages/unity-react-core/src/components/Article/Article.jsx
index 48fc2bf8eb..ebfd0c07ea 100644
--- a/packages/unity-react-core/src/components/Article/Article.jsx
+++ b/packages/unity-react-core/src/components/Article/Article.jsx
@@ -27,7 +27,7 @@ import { Wrapper, EventInfoWrapper } from "./Article.styles";
* @returns {JSX.Element}
*/
export const Article = ({
- type,
+ type = "news",
articleUrl,
publicationDate,
title,
@@ -192,7 +192,11 @@ export const Article = ({
data-testid="uds-hero"
className="uds-hero uds-hero-md"
style={{
- backgroundImage: `linear-gradient(180deg, #19191900 0%, #191919c9 100%), url(${headerImageUrl})`,
+ // @ts-ignore
+ "--color1": "#19191900",
+ "--color2": "#191919c9",
+ // moved colors to variable because hex color in linear-gradient breaks react
+ "backgroundImage": `linear-gradient(180deg, var(--color1) 0%, var(--color2) 100%), url(${headerImageUrl})`,
}}
/>
)}
@@ -369,17 +373,3 @@ Article.propTypes = {
*/
zoomUrl: PropTypes.string,
};
-
-Article.defaultProps = {
- type: "news",
- authorEmail: undefined,
- authorPhone: undefined,
- authorTitle: undefined,
- breadcrumbs: undefined,
- calendarUrl: undefined,
- headerImageUrl: undefined,
- eventLocation: undefined,
- eventTime: undefined,
- registrationUrl: undefined,
- zoomUrl: undefined,
-};
diff --git a/packages/unity-react-core/src/components/Button/Button.jsx b/packages/unity-react-core/src/components/Button/Button.jsx
index 2f80471f9b..ad044ff7dd 100644
--- a/packages/unity-react-core/src/components/Button/Button.jsx
+++ b/packages/unity-react-core/src/components/Button/Button.jsx
@@ -24,21 +24,21 @@ const gaDefaultObject = {
* @returns {JSX.Element}
*/
export const Button = ({
- label,
- cardTitle,
+ label = "",
+ cardTitle = "",
gaData,
ariaLabel,
block,
- color,
+ color = "gray",
disabled,
- element,
+ element = "button",
href,
icon,
innerRef,
onClick,
- size,
+ size = "default",
classes,
- target,
+ target = "_self",
...props
}) => {
const btnClasses = classNames("btn", {
@@ -164,20 +164,3 @@ Button.propTypes = {
*/
target: PropTypes.oneOf(["_blank", "_self", "_top", "_parent"]),
};
-
-Button.defaultProps = {
- label: "",
- cardTitle: "",
- ariaLabel: undefined,
- block: undefined,
- color: "gray",
- disabled: undefined,
- element: "button",
- href: undefined,
- icon: undefined,
- innerRef: undefined,
- onClick: undefined,
- size: "default",
- classes: undefined,
- target: "_self",
-};
diff --git a/packages/unity-react-core/src/components/ButtonIconOnly/ButtonIconOnly.jsx b/packages/unity-react-core/src/components/ButtonIconOnly/ButtonIconOnly.jsx
index fe6829256c..c5fb46f526 100644
--- a/packages/unity-react-core/src/components/ButtonIconOnly/ButtonIconOnly.jsx
+++ b/packages/unity-react-core/src/components/ButtonIconOnly/ButtonIconOnly.jsx
@@ -22,12 +22,12 @@ const gaDefaultObject = {
* @returns {JSX.Element}
*/
export const ButtonIconOnly = ({
- color,
- icon,
- innerRef,
- onClick,
- size,
- cardTitle,
+ color = "gray",
+ icon = undefined,
+ innerRef = undefined,
+ onClick = undefined,
+ size = "small",
+ cardTitle = "",
className,
gaData,
...rest
@@ -99,12 +99,3 @@ ButtonIconOnly.propTypes = {
size: PropTypes.oneOf(["large", "small"]),
className: PropTypes.string,
};
-
-ButtonIconOnly.defaultProps = {
- color: "gray",
- icon: undefined,
- innerRef: undefined,
- onClick: undefined,
- size: "small",
- cardTitle: "",
-};
diff --git a/packages/unity-react-core/src/components/ButtonTag/ButtonTag.jsx b/packages/unity-react-core/src/components/ButtonTag/ButtonTag.jsx
index e456cb7ef3..c60e0c1678 100644
--- a/packages/unity-react-core/src/components/ButtonTag/ButtonTag.jsx
+++ b/packages/unity-react-core/src/components/ButtonTag/ButtonTag.jsx
@@ -24,11 +24,11 @@ const gaDefaultObject = {
* @returns {JSX.Element}
*/
export const ButtonTag = ({
- label,
- cardTitle,
+ label = "",
+ cardTitle = "",
gaData,
ariaLabel,
- color,
+ color = "gray",
disabled,
element = "button",
innerRef,
@@ -137,15 +137,3 @@ ButtonTag.propTypes = {
*/
onClick: PropTypes.func,
};
-
-ButtonTag.defaultProps = {
- label: "",
- cardTitle: "",
- ariaLabel: undefined,
- color: "gray",
- disabled: undefined,
- element: "button",
- href: undefined,
- innerRef: undefined,
- onClick: undefined,
-};
diff --git a/packages/unity-react-core/src/components/Card/Card.jsx b/packages/unity-react-core/src/components/Card/Card.jsx
index fbdb40470e..7dc9f2c84a 100644
--- a/packages/unity-react-core/src/components/Card/Card.jsx
+++ b/packages/unity-react-core/src/components/Card/Card.jsx
@@ -29,22 +29,22 @@ const gaDefaultObject = {
* @returns {JSX.Element}
*/
export const Card = ({
- type,
- width,
- horizontal,
+ type = "default",
+ width = "100%",
+ horizontal = false,
image,
imageAltText,
title,
icon,
body,
- eventFormat,
+ eventFormat = "stack",
eventLocation,
eventTime,
buttons,
linkLabel,
linkUrl,
tags,
- showBorders,
+ showBorders = true,
cardLink,
}) => {
return (
@@ -154,44 +154,26 @@ Card.propTypes = {
cardLink: PropTypes.string,
};
-Card.defaultProps = {
- type: "default",
- width: "100%",
- horizontal: false,
- body: undefined,
- eventFormat: "stack",
- eventTime: undefined,
- eventLocation: undefined,
- icon: undefined,
- image: undefined,
- imageAltText: undefined,
- buttons: undefined,
- linkLabel: undefined,
- linkUrl: undefined,
- tags: undefined,
- showBorders: true,
-};
-
/*
* Sub-components defined after this
*/
const BaseCard = ({
- type,
- width,
- horizontal,
- image,
- imageAltText,
+ type = "default",
+ width = "100%",
+ horizontal = false,
+ image = "",
+ imageAltText = "",
title,
- icon,
- body,
- eventFormat,
- eventLocation,
- eventTime,
- buttons,
- linkLabel,
- linkUrl,
- tags,
- showBorders,
+ icon = undefined,
+ body = "",
+ eventFormat = "stack",
+ eventLocation = "",
+ eventTime = "",
+ buttons = undefined,
+ linkLabel = undefined,
+ linkUrl = undefined,
+ tags = undefined,
+ showBorders = true,
cardLink,
}) => {
const cardClass = classNames("card", "cards-components", {
@@ -297,35 +279,17 @@ BaseCard.propTypes = {
cardLink: PropTypes.string,
};
-BaseCard.defaultProps = {
- type: "default",
- width: "100%",
- horizontal: false,
- body: "",
- eventFormat: "stack",
- eventTime: "",
- eventLocation: "",
- icon: undefined,
- image: "",
- imageAltText: "",
- buttons: undefined,
- linkLabel: undefined,
- linkUrl: undefined,
- tags: undefined,
- showBorders: true,
-};
-
const CardContent = ({
- type,
- body,
- eventFormat,
- eventLocation,
- eventTime,
+ type = "default",
+ body = "",
+ eventFormat = "stack",
+ eventLocation = "",
+ eventTime = "",
title,
- buttons,
- linkLabel,
- linkUrl,
- tags,
+ buttons = undefined,
+ linkLabel = undefined,
+ linkUrl = undefined,
+ tags = undefined,
cardLink,
}) => (
<>
@@ -438,19 +402,11 @@ CardContent.propTypes = {
cardLink: PropTypes.string,
};
-CardContent.defaultProps = {
- type: "default",
- body: "",
- eventFormat: "stack",
- eventLocation: "",
- eventTime: "",
- buttons: undefined,
- linkLabel: undefined,
- linkUrl: undefined,
- tags: undefined,
-};
-
-const EventInfo = ({ eventFormat, eventTime, eventLocation }) => {
+const EventInfo = ({
+ eventFormat = "stack",
+ eventLocation = "",
+ eventTime = "",
+}) => {
if (eventFormat === "inline") {
return (
@@ -516,9 +472,3 @@ EventInfo.propTypes = {
eventLocation: PropTypes.string,
eventTime: PropTypes.string,
};
-
-EventInfo.defaultProps = {
- eventFormat: "stack",
- eventLocation: "",
- eventTime: "",
-};
diff --git a/packages/unity-react-core/src/components/Modal/Modal.stories.tsx b/packages/unity-react-core/src/components/Modal/Modal.stories.tsx
index f321fd6309..ce72416743 100644
--- a/packages/unity-react-core/src/components/Modal/Modal.stories.tsx
+++ b/packages/unity-react-core/src/components/Modal/Modal.stories.tsx
@@ -4,10 +4,9 @@ import { Modal } from "./Modal";
export default {
title: "Components/Modal",
component: Modal,
- globals: {
- framework: "react",
+ args: {
+ open: false,
},
- tags: ["!bootstrap"],
};
const modalTemplate = args =>
;
diff --git a/packages/unity-react-core/src/components/Modal/Modal.tsx b/packages/unity-react-core/src/components/Modal/Modal.tsx
index dd0d7f95d9..cf043a551d 100644
--- a/packages/unity-react-core/src/components/Modal/Modal.tsx
+++ b/packages/unity-react-core/src/components/Modal/Modal.tsx
@@ -2,6 +2,8 @@ import React, { useEffect } from "react";
import { ButtonIconOnly } from "../ButtonIconOnly/ButtonIconOnly";
import { GaEventWrapper } from "../GaEventWrapper/GaEventWrapper";
+import { useBaseSpecificFramework } from "../GaEventWrapper/useBaseSpecificFramework";
+import classNames from "classnames";
/**
*
* TODO: Should we be using bootstrap's built in modal functionality?
@@ -18,6 +20,7 @@ const defaultGaData = {
};
export interface ModalProps {
+ open?: boolean;
gaData?: {
name: string;
event: string;
@@ -29,51 +32,59 @@ export interface ModalProps {
};
}
-export const Modal: React.FC
= ({ gaData }) => {
- useEffect(() => {
- document
- ?.getElementById("openModalButton")
- .addEventListener("click", function () {
- document.getElementById("uds-modal").classList.add("open");
- });
+export const Modal: React.FC = ({ open, gaData }) => {
+ const { isReact, isBootstrap } = useBaseSpecificFramework();
+ const [openState, setOpen] = React.useState(open);
- document
- ?.getElementById("closeModalButton")
- .addEventListener("click", function () {
- document.getElementById("uds-modal").classList.remove("open");
- });
- });
+ const handleOpen = () => {
+ setOpen(true);
+ };
+
+ const handleClose = () => {
+ setOpen(false);
+ };
return (
-
-
-
-
-
-
Content
-
- Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do
- eiusmod incididuntåç ut labore et dolore magna aliqua eiusmod tempo.
-
-
+ {(openState || isBootstrap) && (
+
+
+
+
+
+
Content
+
+ Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do
+ eiusmod incididuntåç ut labore et dolore magna aliqua eiusmod
+ tempo.
+
+
+
-
+ )}
);
};
diff --git a/packages/unity-react-core/src/components/Pagination/PageItem/PageItem.jsx b/packages/unity-react-core/src/components/Pagination/PageItem/PageItem.jsx
index 026b248efb..918b3948c5 100644
--- a/packages/unity-react-core/src/components/Pagination/PageItem/PageItem.jsx
+++ b/packages/unity-react-core/src/components/Pagination/PageItem/PageItem.jsx
@@ -14,11 +14,11 @@ import React from "react";
*/
export const PageItem = ({
dataId,
- isClickeable,
- disabled,
- pageLinkIcon,
- selectedPage,
- onClick,
+ isClickeable = false,
+ disabled = false,
+ pageLinkIcon = false,
+ selectedPage = false,
+ onClick = () => {},
ellipses,
ariaLabel,
children,
@@ -69,11 +69,3 @@ PageItem.propTypes = {
ariaLabel: PropTypes.string,
ariaDisabled: PropTypes.bool,
};
-
-PageItem.defaultProps = {
- isClickeable: false,
- disabled: false,
- pageLinkIcon: false,
- selectedPage: false,
- onClick: () => {},
-};
diff --git a/packages/unity-react-core/src/components/Pagination/Pagination.jsx b/packages/unity-react-core/src/components/Pagination/Pagination.jsx
index 8574f174fa..1412c7a5e1 100644
--- a/packages/unity-react-core/src/components/Pagination/Pagination.jsx
+++ b/packages/unity-react-core/src/components/Pagination/Pagination.jsx
@@ -33,8 +33,8 @@ const defaultGAEvent = {
export const Pagination = ({
type,
background,
- currentPage,
- totalPages,
+ currentPage = 1,
+ totalPages = 10,
onChange,
}) => {
const [selectedPage, setSelectedPage] = useState(null);
@@ -230,8 +230,3 @@ Pagination.propTypes = {
*/
onChange: PropTypes.func.isRequired,
};
-
-Pagination.defaultProps = {
- currentPage: 1,
- totalPages: 10,
-};
diff --git a/packages/unity-react-core/src/components/TabbedPanels/TabbedPanels.jsx b/packages/unity-react-core/src/components/TabbedPanels/TabbedPanels.jsx
index c28dd57118..ffa010c883 100644
--- a/packages/unity-react-core/src/components/TabbedPanels/TabbedPanels.jsx
+++ b/packages/unity-react-core/src/components/TabbedPanels/TabbedPanels.jsx
@@ -10,6 +10,7 @@
import PropTypes from "prop-types";
import React, { useState, useEffect, useRef, useCallback } from "react";
+import { throttle, debounce } from "../../../../../shared";
import { useBaseSpecificFramework } from "../GaEventWrapper/useBaseSpecificFramework";
import { NavControls, TabHeader } from "./components";
@@ -26,19 +27,23 @@ function useRefs() {
return [refs, register];
}
-const Tab = ({ id, bgColor, selected, children }) =>
- selected && (
-
- {children}
-
+const Tab = ({ id, bgColor, selected, children }) => {
+ const { isBootstrap } = useBaseSpecificFramework();
+ return (
+ (selected || isBootstrap) && (
+
+ {children}
+
+ )
);
+};
Tab.propTypes = {
id: PropTypes.string.isRequired,
@@ -54,13 +59,15 @@ const TabbedPanels = ({
onTabChange = _ => {},
}) => {
const childrenArray = React.Children.toArray(children);
+ if (childrenArray.length === 0) {
+ return null;
+ }
const isMounted = useRef(false);
const [activeTabID, setActiveTabID] = useState(
initialTab && initialTab !== "null" ? initialTab : childrenArray[0].props.id
);
const headerTabs = useRef(null);
const [headerTabItems, setHeaderTabItems] = useRefs();
- const { isReact, isBootstrap } = useBaseSpecificFramework();
const updateActiveTabID = tab => {
onTabChange(tab);
@@ -72,31 +79,47 @@ const TabbedPanels = ({
const [scrollLeft, setScrollLeft] = useState(0);
const [scrollableWidth, setScrollableWidth] = useState();
+ const handleResize = () => {
+ setScrollableWidth(
+ headerTabs.current?.scrollWidth - headerTabs.current?.offsetWidth
+ );
+ };
+
+ const handleScroll = () => {
+ setScrollLeft(headerTabs.current?.scrollLeft);
+ };
+
+ const throttleScroll = () => {
+ const timeout = 150;
+ // prevent function from being called excessively
+ throttle(handleScroll, timeout);
+ // ensure function executes after scrolling stops
+ debounce(handleScroll, timeout);
+ };
+
+ const throttleResize = () => {
+ const timeout = 150;
+ // prevent function from being called excessively
+ throttle(handleResize, timeout);
+ // ensure function executes after scrolling stops
+ debounce(handleResize, timeout);
+ };
+
useEffect(() => {
- const onScroll = () => {
- setScrollLeft(headerTabs.current.scrollLeft);
- };
- headerTabs.current.addEventListener("scroll", onScroll);
- onScroll();
+ headerTabs.current.addEventListener("scroll", throttleScroll);
+ handleScroll();
return () => {
if (headerTabs.current) {
- headerTabs.current.removeEventListener("scroll", onScroll);
+ headerTabs.current.removeEventListener("scroll", throttleScroll);
}
};
}, [scrollableWidth]);
useEffect(() => {
- const onResize = () => {
- setScrollableWidth(
- headerTabs.current.scrollWidth - headerTabs.current.offsetWidth
- );
- };
- window.addEventListener("resize", onResize);
- onResize();
+ window.addEventListener("resize", throttleResize);
+ handleResize();
return () => {
- if (headerTabs.current) {
- window.removeEventListener("resize", onResize);
- }
+ window.removeEventListener("resize", throttleResize);
};
}, []);
@@ -190,10 +213,10 @@ const TabbedPanels = ({
title={child.props.title}
selected={activeTabID === child.props.id}
gaData={trackLinkEvent}
- selectTab={isReact && switchToTab}
+ selectTab={switchToTab}
key={child.props.id}
- leftKeyPressed={isReact && (() => incrementIndex(false))}
- rightKeyPressed={isReact && (() => incrementIndex())}
+ leftKeyPressed={() => incrementIndex(false)}
+ rightKeyPressed={() => incrementIndex()}
icon={child.props.icon}
index={index}
/>
@@ -205,7 +228,7 @@ const TabbedPanels = ({
hidePrev={scrollLeft <= 0}
hideNext={scrollLeft >= scrollableWidth}
gaData={trackArrowsEvent}
- slideNav={isReact && slideNav}
+ slideNav={slideNav}
/>
{
diff --git a/packages/unity-react-core/src/components/TabbedPanels/components/NavControls.jsx b/packages/unity-react-core/src/components/TabbedPanels/components/NavControls.jsx
index d18eabe0da..4eec29bbfc 100644
--- a/packages/unity-react-core/src/components/TabbedPanels/components/NavControls.jsx
+++ b/packages/unity-react-core/src/components/TabbedPanels/components/NavControls.jsx
@@ -3,6 +3,7 @@ import React from "react";
import { GaEventWrapper } from "../../GaEventWrapper/GaEventWrapper";
import { NavControlButtons } from "./NavControls.styles";
+import { useBaseSpecificFramework } from "../../GaEventWrapper/useBaseSpecificFramework";
/**
* @typedef {Object} NavControlsProps
@@ -12,14 +13,15 @@ import { NavControlButtons } from "./NavControls.styles";
* @property {() => void} slideNav
*/
const NavControls = ({ gaData, hidePrev, hideNext, slideNav }) => {
+ const { isReact, isBootstrap } = useBaseSpecificFramework();
return (
- {!hidePrev && (
+ {(!hidePrev || isBootstrap) && (
)}
- {!hideNext && (
+ {(!hideNext || isBootstrap) && (
),
],
- globals: {
- framework: "react",
- },
- tags: ["!bootstrap"],
};
export const BasicTable: StoryObj
= {
diff --git a/packages/unity-react-core/src/core/models/shared-prop-types.js b/packages/unity-react-core/src/core/models/shared-prop-types.js
index b7d82960f9..57ddae8d5e 100644
--- a/packages/unity-react-core/src/core/models/shared-prop-types.js
+++ b/packages/unity-react-core/src/core/models/shared-prop-types.js
@@ -18,7 +18,7 @@ const contentPropType = PropTypes.shape({
const accordionCardPropTypes = PropTypes.shape({
color: PropTypes.oneOf(["gold", "maroon", "gray", "dark"]),
content: PropTypes.shape({
- icon: PropTypes.string,
+ icon: PropTypes.arrayOf(PropTypes.string),
header: PropTypes.string,
body: PropTypes.string,
}),
diff --git a/packages/unity-react-core/vite.config.js b/packages/unity-react-core/vite.config.js
index 9ca5287036..ce573119c8 100644
--- a/packages/unity-react-core/vite.config.js
+++ b/packages/unity-react-core/vite.config.js
@@ -73,6 +73,9 @@ export default defineConfig({
},
},
],
+ // optimizeDeps: {
+ // force: true,
+ // },
resolve: {
alias: {
"@shared": path.resolve(__dirname, "./../../shared"),