Skip to content

Commit 5ee8a42

Browse files
enable bootstrap
1 parent 21581b3 commit 5ee8a42

File tree

7 files changed

+113
-83
lines changed

7 files changed

+113
-83
lines changed

packages/unity-react-core/src/components/Modal/Modal.stories.tsx

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,9 @@ import { Modal } from "./Modal";
44
export default {
55
title: "Components/Modal",
66
component: Modal,
7-
globals: {
8-
framework: "react",
7+
args: {
8+
open: false,
99
},
10-
tags: ["!bootstrap"],
1110
};
1211

1312
const modalTemplate = args => <Modal {...args} />;

packages/unity-react-core/src/components/Modal/Modal.tsx

Lines changed: 44 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@ import React, { useEffect } from "react";
22

33
import { ButtonIconOnly } from "../ButtonIconOnly/ButtonIconOnly";
44
import { GaEventWrapper } from "../GaEventWrapper/GaEventWrapper";
5+
import { useBaseSpecificFramework } from "../GaEventWrapper/useBaseSpecificFramework";
6+
import classNames from "classnames";
57
/**
68
*
79
* TODO: Should we be using bootstrap's built in modal functionality?
@@ -18,6 +20,7 @@ const defaultGaData = {
1820
};
1921

2022
export interface ModalProps {
23+
open?: boolean;
2124
gaData?: {
2225
name: string;
2326
event: string;
@@ -29,51 +32,59 @@ export interface ModalProps {
2932
};
3033
}
3134

32-
export const Modal: React.FC<ModalProps> = ({ gaData }) => {
33-
useEffect(() => {
34-
document
35-
?.getElementById("openModalButton")
36-
.addEventListener("click", function () {
37-
document.getElementById("uds-modal").classList.add("open");
38-
});
35+
export const Modal: React.FC<ModalProps> = ({ open, gaData }) => {
36+
const { isReact, isBootstrap } = useBaseSpecificFramework();
37+
const [openState, setOpen] = React.useState(open);
3938

40-
document
41-
?.getElementById("closeModalButton")
42-
.addEventListener("click", function () {
43-
document.getElementById("uds-modal").classList.remove("open");
44-
});
45-
});
39+
const handleOpen = () => {
40+
setOpen(true);
41+
};
42+
43+
const handleClose = () => {
44+
setOpen(false);
45+
};
4646

4747
return (
4848
<div className="container-fluid">
4949
<button
50-
onClick={() => {
51-
document.getElementById("uds-modal").classList.add("open");
52-
}}
50+
type="button"
51+
// data-bs-toggle={isBootstrap && "modal"}
52+
// data-bs-target={isBootstrap && "#uds-modal"}
53+
onClick={isReact && handleOpen}
5354
id="openModalButton"
5455
className="btn btn-dark"
5556
>
5657
Show modal
5758
</button>
5859

59-
<div id="uds-modal" className="uds-modal">
60-
<div className="uds-modal-container">
61-
<GaEventWrapper gaData={{ ...defaultGaData, ...gaData }}>
62-
<ButtonIconOnly
63-
// @ts-ignore
64-
id="closeModalButton"
65-
className="uds-modal-close-btn"
66-
icon={["fas", "times"]}
67-
/>
68-
</GaEventWrapper>
69-
<h1>Content</h1>
70-
<p>
71-
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do
72-
eiusmod incididuntåç ut labore et dolore magna aliqua eiusmod tempo.
73-
</p>
74-
<button className="btn btn-primary">button</button>
60+
{(openState || isBootstrap) && (
61+
<div
62+
id="uds-modal"
63+
className={classNames("uds-modal", { open: openState })}
64+
>
65+
<div className="uds-modal-container">
66+
<GaEventWrapper gaData={{ ...defaultGaData, ...gaData }}>
67+
<ButtonIconOnly
68+
// @ts-ignore
69+
id="closeModalButton"
70+
onClick={isReact && handleClose}
71+
// data-bs-dismiss={isBootstrap && "modal"}
72+
className="uds-modal-close-btn"
73+
icon={["fas", "times"]}
74+
/>
75+
</GaEventWrapper>
76+
<h1>Content</h1>
77+
<p>
78+
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do
79+
eiusmod incididuntåç ut labore et dolore magna aliqua eiusmod
80+
tempo.
81+
</p>
82+
<button type="button" className="btn btn-primary">
83+
button
84+
</button>
85+
</div>
7586
</div>
76-
</div>
87+
)}
7788
</div>
7889
);
7990
};

packages/unity-react-core/src/components/TabbedPanels/TabbedPanels.jsx

Lines changed: 56 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
import PropTypes from "prop-types";
1111
import React, { useState, useEffect, useRef, useCallback } from "react";
1212

13+
import { throttle, debounce } from "../../../../../shared";
1314
import { useBaseSpecificFramework } from "../GaEventWrapper/useBaseSpecificFramework";
1415
import { NavControls, TabHeader } from "./components";
1516

@@ -26,19 +27,23 @@ function useRefs() {
2627
return [refs, register];
2728
}
2829

29-
const Tab = ({ id, bgColor, selected, children }) =>
30-
selected && (
31-
<div
32-
className={`tab-pane fade show ${selected ? "show active" : ""} ${
33-
bgColor === "bg-dark" ? "text-white" : ""
34-
}`}
35-
id={`nav-${id}`}
36-
role="tabpanel"
37-
aria-labelledby={`nav-${id}-tab`}
38-
>
39-
{children}
40-
</div>
30+
const Tab = ({ id, bgColor, selected, children }) => {
31+
const { isBootstrap } = useBaseSpecificFramework();
32+
return (
33+
(selected || isBootstrap) && (
34+
<div
35+
className={`tab-pane fade show ${selected ? "show active" : ""} ${
36+
bgColor === "bg-dark" ? "text-white" : ""
37+
}`}
38+
id={`nav-${id}`}
39+
role="tabpanel"
40+
aria-labelledby={`nav-${id}-tab`}
41+
>
42+
{children}
43+
</div>
44+
)
4145
);
46+
};
4247

4348
Tab.propTypes = {
4449
id: PropTypes.string.isRequired,
@@ -54,13 +59,15 @@ const TabbedPanels = ({
5459
onTabChange = _ => {},
5560
}) => {
5661
const childrenArray = React.Children.toArray(children);
62+
if (childrenArray.length === 0) {
63+
return null;
64+
}
5765
const isMounted = useRef(false);
5866
const [activeTabID, setActiveTabID] = useState(
5967
initialTab && initialTab !== "null" ? initialTab : childrenArray[0].props.id
6068
);
6169
const headerTabs = useRef(null);
6270
const [headerTabItems, setHeaderTabItems] = useRefs();
63-
const { isReact, isBootstrap } = useBaseSpecificFramework();
6471

6572
const updateActiveTabID = tab => {
6673
onTabChange(tab);
@@ -72,31 +79,47 @@ const TabbedPanels = ({
7279
const [scrollLeft, setScrollLeft] = useState(0);
7380
const [scrollableWidth, setScrollableWidth] = useState();
7481

82+
const handleResize = () => {
83+
setScrollableWidth(
84+
headerTabs.current?.scrollWidth - headerTabs.current?.offsetWidth
85+
);
86+
};
87+
88+
const handleScroll = () => {
89+
setScrollLeft(headerTabs.current?.scrollLeft);
90+
};
91+
92+
const throttleScroll = () => {
93+
const timeout = 150;
94+
// prevent function from being called excessively
95+
throttle(handleScroll, timeout);
96+
// ensure function executes after scrolling stops
97+
debounce(handleScroll, timeout);
98+
};
99+
100+
const throttleResize = () => {
101+
const timeout = 150;
102+
// prevent function from being called excessively
103+
throttle(handleResize, timeout);
104+
// ensure function executes after scrolling stops
105+
debounce(handleResize, timeout);
106+
};
107+
75108
useEffect(() => {
76-
const onScroll = () => {
77-
setScrollLeft(headerTabs.current.scrollLeft);
78-
};
79-
headerTabs.current.addEventListener("scroll", onScroll);
80-
onScroll();
109+
headerTabs.current.addEventListener("scroll", throttleScroll);
110+
handleScroll();
81111
return () => {
82112
if (headerTabs.current) {
83-
headerTabs.current.removeEventListener("scroll", onScroll);
113+
headerTabs.current.removeEventListener("scroll", throttleScroll);
84114
}
85115
};
86116
}, [scrollableWidth]);
87117

88118
useEffect(() => {
89-
const onResize = () => {
90-
setScrollableWidth(
91-
headerTabs.current.scrollWidth - headerTabs.current.offsetWidth
92-
);
93-
};
94-
window.addEventListener("resize", onResize);
95-
onResize();
119+
window.addEventListener("resize", throttleResize);
120+
handleResize();
96121
return () => {
97-
if (headerTabs.current) {
98-
window.removeEventListener("resize", onResize);
99-
}
122+
window.removeEventListener("resize", throttleResize);
100123
};
101124
}, []);
102125

@@ -190,10 +213,10 @@ const TabbedPanels = ({
190213
title={child.props.title}
191214
selected={activeTabID === child.props.id}
192215
gaData={trackLinkEvent}
193-
selectTab={isReact && switchToTab}
216+
selectTab={switchToTab}
194217
key={child.props.id}
195-
leftKeyPressed={isReact && (() => incrementIndex(false))}
196-
rightKeyPressed={isReact && (() => incrementIndex())}
218+
leftKeyPressed={() => incrementIndex(false)}
219+
rightKeyPressed={() => incrementIndex()}
197220
icon={child.props.icon}
198221
index={index}
199222
/>
@@ -205,7 +228,7 @@ const TabbedPanels = ({
205228
hidePrev={scrollLeft <= 0}
206229
hideNext={scrollLeft >= scrollableWidth}
207230
gaData={trackArrowsEvent}
208-
slideNav={isReact && slideNav}
231+
slideNav={slideNav}
209232
/>
210233
</nav>
211234
<div

packages/unity-react-core/src/components/TabbedPanels/TabbedPanels.stories.jsx

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,6 @@ import { TabbedPanels, Tab } from "./TabbedPanels";
77
export default {
88
title: "Components/TabbedPanels",
99
component: TabbedPanels,
10-
globals: {
11-
framework: "react",
12-
},
13-
tags: ["!bootstrap"],
1410
};
1511

1612
const Template = () => {

packages/unity-react-core/src/components/TabbedPanels/components/NavControls.jsx

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import React from "react";
33

44
import { GaEventWrapper } from "../../GaEventWrapper/GaEventWrapper";
55
import { NavControlButtons } from "./NavControls.styles";
6+
import { useBaseSpecificFramework } from "../../GaEventWrapper/useBaseSpecificFramework";
67

78
/**
89
* @typedef {Object} NavControlsProps
@@ -12,27 +13,28 @@ import { NavControlButtons } from "./NavControls.styles";
1213
* @property {() => void} slideNav
1314
*/
1415
const NavControls = ({ gaData, hidePrev, hideNext, slideNav }) => {
16+
const { isReact, isBootstrap } = useBaseSpecificFramework();
1517
return (
1618
<NavControlButtons>
17-
{!hidePrev && (
19+
{(!hidePrev || isBootstrap) && (
1820
<GaEventWrapper gaData={{ ...gaData, text: "left chevron" }}>
1921
<button
2022
className="scroll-control-prev"
2123
type="button"
22-
onClick={() => slideNav(-1)}
24+
onClick={isReact && (() => slideNav(-1))}
2325
tabIndex={-1}
2426
>
2527
<span className="carousel-control-prev-icon" aria-hidden="true" />
2628
<span className="visually-hidden">Previous</span>
2729
</button>
2830
</GaEventWrapper>
2931
)}
30-
{!hideNext && (
32+
{(!hideNext || isBootstrap) && (
3133
<GaEventWrapper gaData={{ ...gaData, text: "right chevron" }}>
3234
<button
3335
className="scroll-control-next"
3436
type="button"
35-
onClick={() => slideNav(1)}
37+
onClick={isReact && (() => slideNav(1))}
3638
tabIndex={-1}
3739
>
3840
<span className="carousel-control-next-icon" aria-hidden="true" />

packages/unity-react-core/src/components/TabbedPanels/components/TabHeader.jsx

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import PropTypes from "prop-types";
77
import React, { forwardRef, useRef, useImperativeHandle } from "react";
88

99
import { GaEventWrapper } from "../../GaEventWrapper/GaEventWrapper";
10+
import { useBaseSpecificFramework } from "../../GaEventWrapper/useBaseSpecificFramework";
1011

1112
/**
1213
* @typedef {Object} TabHeaderProps
@@ -26,6 +27,7 @@ const TabHeader = forwardRef(function TabHeader(props, ref) {
2627
icon,
2728
gaData,
2829
} = props;
30+
const { isReact, isBootstrap } = useBaseSpecificFramework();
2931

3032
const inputRef = useRef(null);
3133

@@ -71,8 +73,9 @@ const TabHeader = forwardRef(function TabHeader(props, ref) {
7173
role="tab"
7274
aria-controls={`nav-${id}`}
7375
aria-selected={selected}
74-
onClick={e => selectTab(e, id, title)}
75-
onKeyDown={func}
76+
data-bs-toggle={isBootstrap && "tab"}
77+
onClick={isReact && (e => selectTab(e, id, title))}
78+
onKeyDown={isReact && func}
7679
tabIndex={selected ? "" : "-1"}
7780
>
7881
{title} {icon && <i className={`${icon?.[0]} fa-${icon?.[1]} me-1`} />}

packages/unity-react-core/src/components/Tables/Tables.stories.tsx

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,6 @@ const meta: Meta<typeof Table> = {
1212
</div>
1313
),
1414
],
15-
globals: {
16-
framework: "react",
17-
},
18-
tags: ["!bootstrap"],
1915
};
2016

2117
export const BasicTable: StoryObj<typeof Table> = {

0 commit comments

Comments
 (0)