Skip to content

Commit

Permalink
Merge pull request #965 from airswap/feature/overlay-redesign
Browse files Browse the repository at this point in the history
Feature/overlay redesign
  • Loading branch information
makkelie-dev authored Oct 19, 2024
2 parents ea882b6 + d86a1fb commit 35257be
Show file tree
Hide file tree
Showing 15 changed files with 200 additions and 119 deletions.
1 change: 0 additions & 1 deletion src/components/@widgets/SwapWidget/SwapWidget.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -658,7 +658,6 @@ const SwapWidget: FC = () => {
</ButtonContainer>

<Overlay
hasDynamicHeight
isHidden={!showTokenSelectModalFor}
title={t("common.selectToken")}
onClose={() => setShowTokenSelectModalFor(null)}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,10 @@ const AvailableOrdersWidget = ({
});

const sortedOrders = useMemo(() => {
if (!bestRfqOrder) {
return [];
}

const ordersToSort: (FullOrderERC20 | OrderERC20)[] = [...orders];

if (
Expand Down Expand Up @@ -108,6 +112,10 @@ const AvailableOrdersWidget = ({
});
};

if (!senderToken || !signerToken) {
return <div />;
}

return (
<Container>
<AvailableOrdersList
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@ import styled from "styled-components/macro";
import { OverlayActionButton } from "../../../Overlay/Overlay.styles";

export const Container = styled.div`
padding-bottom: 2rem;
padding-bottom: 3rem;
`;

export const StyledCloseButton = styled(OverlayActionButton)`
margin-top: 1.5rem;
margin-top: 3rem;
`;
59 changes: 17 additions & 42 deletions src/components/Overlay/Overlay.styles.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import { motion } from "framer-motion";
import { css } from "styled-components";
import styled from "styled-components/macro";

Expand All @@ -11,8 +10,9 @@ import { InfoSubHeading } from "../Typography/Typography";
import { StyledH3 } from "../Typography/Typography.styles";

type ContainerProps = {
hasOverflow: boolean;
isHidden: boolean;
hasDynamicHeight: boolean;
showScrollbar: boolean;
hasTitle: boolean;
};

Expand Down Expand Up @@ -41,46 +41,29 @@ export const ScrollContainer = styled.div<ScrollContainerProps>`
${ScrollBarStyle};
`;

export const ContentContainer = styled(motion.div)`
export const ContentContainer = styled.div<{ isHidden: boolean }>`
position: relative;
border: 1px solid ${(props) => props.theme.colors.borderGrey};
border-radius: 2rem;
margin-block-end: 2rem;
width: calc(100vw - 4rem);
max-width: 38.75rem;
height: fit-content;
max-height: 47.5rem;
min-height: 30rem;
padding: 0 ${sizes.tradeContainerPadding};
backdrop-filter: blur(25px);
background: rgba(57, 122, 255, 0.11);
transform: translateY(${(props) => (props.isHidden ? "100vh" : "0vh")});
pointer-events: ${(props) => (props.isHidden ? "none" : "visible")};
transition: transform ease-out 0.3s;
@media ${breakPoints.phoneOnly} {
padding: 0 ${sizes.tradeContainerMobilePadding};
}
&::before {
content: "";
display: block;
position: absolute;
top: 0;
left: 0;
border-radius: 2rem;
width: 100%;
height: 100%;
background: ${(props) => props.theme.colors.darkBlue};
filter: brightness(0.5);
opacity: 0.8;
pointer-events: none;
z-index: -1;
}
`;

export const TitleContainer = styled.div`
display: flex;
align-items: center;
flex-direction: row;
justify-content: space-between;
margin-block-end: 1rem;
margin-block-end: 2rem;
padding-block-start: ${sizes.tradeContainerPadding};
transition: background ease-in-out 0.3s;
Expand Down Expand Up @@ -131,32 +114,24 @@ export const OverlayActionButton = styled(Button)`
${OverlayActionButtonStyle};
`;

const containerDynamicHeightStyle = css`
padding-block-start: 0;
@media (max-height: 700px) {
padding-block-start: 2rem;
}
@media (min-height: 800px) {
margin-block-start: -2rem;
}
`;

export const Container = styled.div<ContainerProps>`
display: flex;
flex-direction: column;
justify-content: flex-start;
align-items: center;
position: absolute;
top: 0;
left: 0;
width: 100%;
height: ${(props) => (props.hasDynamicHeight ? "auto" : "100%")};
padding-block-start: 2rem;
height: 100svh;
padding-block: 2rem;
overflow-y: ${(props) => (props.showScrollbar ? "auto" : "hidden")};;
pointer-events: ${(props) => (props.isHidden ? "none" : "visible")};
z-index: 2;
${(props) => props.hasDynamicHeight && containerDynamicHeightStyle};
background: ${(props) =>
props.isHidden ? "rgba(0, 0, 0, 0);" : "rgba(0, 0, 0, 0.5)"};
backdrop-filter: ${(props) => (props.isHidden ? "none" : "blur(25px)")};
z-index: 10;
transition: background ease-out 0.3s;
}
`;

Expand Down
105 changes: 56 additions & 49 deletions src/components/Overlay/Overlay.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
import { FC, useContext, useEffect, useState } from "react";
import { FC, useContext, useEffect, useRef, useState } from "react";
import { createPortal } from "react-dom";
import { useTranslation } from "react-i18next";

import { AnimatePresence, useReducedMotion } from "framer-motion";
import { useWindowSize } from "usehooks-ts";

import { InterfaceContext } from "../../contexts/interface/Interface";
import useDebounce from "../../hooks/useDebounce";
import useElementSize from "../../hooks/useElementSize";
import useIsOverflowing from "../../hooks/useIsOverflowing";
import { useKeyPress } from "../../hooks/useKeyPress";
import CloseButton from "../../styled-components/CloseButton/CloseButton";
import {
Container,
StyledTitle,
Expand Down Expand Up @@ -44,27 +47,31 @@ export const overlayShowHideAnimationDuration = 0.3;
const Overlay: FC<OverlayProps> = ({
onClose,
title = "",
hasDynamicHeight = false,
isHidden = true,
subTitle = "",
shouldAnimate = true,
children,
className = "",
}) => {
const { t } = useTranslation();
const shouldReduceMotion = useReducedMotion();
const [initialized, setInitialized] = useState(false);
const animationIsDisabled = !shouldAnimate || (!isHidden && !initialized);
const ref = useRef<HTMLDivElement>(null);
const contentRef = useRef<HTMLDivElement>(null);

const { setShowOverlay } = useContext(InterfaceContext);
const { showOverlay, setShowOverlay } = useContext(InterfaceContext);
const [isAnimatedOut, setIsAnimatedOut] = useState(false);
const { height: containerHeight } = useWindowSize();
const { height: contentHeight } = useElementSize(contentRef);
const paddingBlock = 32;
const contentY = Math.max(
0,
(containerHeight - paddingBlock * 2 - contentHeight) / 2
);

useKeyPress(onClose, ["Escape"]);

useEffect(() => {
setInitialized(true);
}, []);
setIsAnimatedOut(false);

useEffect(() => {
if (isHidden) {
setShowOverlay(false);
}
Expand All @@ -74,55 +81,55 @@ const Overlay: FC<OverlayProps> = ({
() => {
// Make sure the animation ended before setting the showOverlay state
setShowOverlay(!isHidden);

if (isHidden) {
setIsAnimatedOut(true);
}
},
250,
[isHidden]
);

return (
return createPortal(
<Container
hasDynamicHeight={hasDynamicHeight}
ref={ref}
hasTitle={!!title}
hasOverflow={!contentY}
isHidden={isHidden}
showScrollbar={!!showOverlay && !isHidden}
style={{
visibility: isAnimatedOut ? "hidden" : "visible",
}}
className={className}
>
<AnimatePresence>
{!isHidden && (
<ContentContainer
key="content"
transition={{
ease: "easeOut",
duration:
shouldReduceMotion || animationIsDisabled
? 0
: overlayShowHideAnimationDuration,
}}
initial={{ y: "100vh" }}
animate={{ y: "0%" }}
exit={{ y: "100vh" }}
>
<TitleContainer>
<TitleSubContainer>
<StyledTitle type="h2" as="h1">
{title}
</StyledTitle>
{!!subTitle && (
<StyledInfoSubHeading>{subTitle}</StyledInfoSubHeading>
)}
</TitleSubContainer>
<StyledCloseButton
icon="exit-modal"
ariaLabel={t("common.back")}
iconSize={1}
tabIndex={isHidden ? -1 : 0}
onClick={onClose}
/>
</TitleContainer>
{children}
</ContentContainer>
)}
</AnimatePresence>
</Container>
<ContentContainer
isHidden={isHidden}
ref={contentRef}
style={{
marginTop: `${contentY}px`,
}}
>
<TitleContainer>
<TitleSubContainer>
<StyledTitle type="h2" as="h1">
{title}
</StyledTitle>
{!!subTitle && (
<StyledInfoSubHeading>{subTitle}</StyledInfoSubHeading>
)}
</TitleSubContainer>
<StyledCloseButton
icon="exit-modal"
ariaLabel={t("common.back")}
iconSize={1}
tabIndex={isHidden ? -1 : 0}
onClick={onClose}
/>
</TitleContainer>
{children}
</ContentContainer>
</Container>,
document.getElementById("root") as HTMLElement
);
};

Expand Down
15 changes: 9 additions & 6 deletions src/components/Page/Page.styles.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ export const InnerContainer = styled.div<{ $isScrollLocked?: boolean }>`
position: relative;
width: 100%;
height: 100%;
flex-grow: 1;
@media ${breakPoints.phoneOnly}, ${breakPoints.shallowScreenOnly} {
justify-content: flex-start;
Expand All @@ -24,25 +25,27 @@ export const InnerContainer = styled.div<{ $isScrollLocked?: boolean }>`
}
`;

export const StyledPage = styled.div`
export const StyledPage = styled.div<{ showOverlay?: boolean }>`
display: flex;
flex-direction: column;
position: relative;
min-width: 18rem;
height: 100vh;
min-height: 37.5rem;
min-height: 100vh;
min-height: 100svh;
max-height: ${(props) => (props.showOverlay ? "100vh" : "unset")};
overflow-x: hidden;
overflow-y: ${(props) => (props.showOverlay ? "hidden" : "unset")};
@media (min-height: 29rem) and (max-width: ${breakpointSizes.phone}) {
display: flex;
flex-direction: column;
justify-content: center;
height: 100vh;
padding-top: 0;
padding-bottom: 0;
}
@media ${breakPoints.phoneOnly} {
width: 100%;
height: 100vh;
min-height: ${sizes.widgetMobileSize};
padding: 0 ${sizes.pageMobilePadding};
}
`;
Expand Down
2 changes: 1 addition & 1 deletion src/components/Page/Page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ const Page: FC<PageProps> = ({ children, className }): ReactElement => {
}, []);

return (
<StyledPage style={{ height: `${pageHeight}px` }} className={className}>
<StyledPage showOverlay={showOverlay} className={className}>
<HelmetContainer title={t("app.title")} />
<InnerContainer>
<Toaster open={transactionsTabIsOpen} />
Expand Down
2 changes: 1 addition & 1 deletion src/components/TransactionsTab/TransactionsTab.styles.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ export const Container = styled(motion.div)`
display: flex;
flex-direction: column;
width: 100%;
max-width: ${sizes.widgetMobileSize};
max-width: ${sizes.widgetMobileWidth};
height: 100%;
padding: 1.5rem 1.5rem 0;
background-color: ${(props) => props.theme.colors.black};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ export const StyledWalletProviderList = styled.div`
display: flex;
flex-direction: column;
margin-block-start: 3rem;
padding-block-end: 2rem;
padding-block-end: 3rem;
`;

export const TitleContainer = styled.div`
Expand Down
Loading

0 comments on commit 35257be

Please sign in to comment.