Web:Common: moved out catalog from page layout and refactoring page layout

This commit is contained in:
Timofey Boyko 2022-03-11 11:04:09 +03:00
parent b572b84410
commit 3ae4b92ad7
12 changed files with 524 additions and 516 deletions

View File

@ -0,0 +1,176 @@
import React from "react";
import { inject, observer } from "mobx-react";
import PropTypes from "prop-types";
import { isMobile, isMobileOnly } from "react-device-detect";
import { Resizable } from "re-resizable";
import {
isDesktop as isDesktopUtils,
isTablet as isTabletUtils,
isMobile as isMobileUtils,
} from "@appserver/components/utils/device";
import SubCatalogBackdrop from "./sub-components/catalog-backdrop";
import SubCatalogHeader from "./sub-components/catalog-header";
import SubCatalogMainButton from "./sub-components/catalog-main-button";
import SubCatalogBody from "./sub-components/catalog-body";
import { StyledCatalog } from "./styled-catalog";
const enable = {
top: false,
right: !isMobile,
bottom: false,
left: false,
};
const Catalog = ({
showText,
setShowText,
catalogOpen,
toggleShowText,
toggleCatalogOpen,
children,
...rest
}) => {
const [catalogHeaderContent, setCatalogHeaderContent] = React.useState(null);
const [
catalogMainButtonContent,
setCatalogMainButtonContent,
] = React.useState(null);
const [catalogBodyContent, setCatalogBodyContent] = React.useState(null);
const refTimer = React.useRef(null);
React.useEffect(() => {
if (isMobileOnly) {
window.addEventListener("popstate", hideText);
return () => window.removeEventListener("popstate", hideText);
}
}, [hideText]);
React.useEffect(() => {
window.addEventListener("resize", sizeChangeHandler);
return () => window.removeEventListener("resize", sizeChangeHandler);
}, []);
React.useEffect(() => {
sizeChangeHandler();
}, []);
React.useEffect(() => {
React.Children.forEach(children, (child) => {
const childType =
child && child.type && (child.type.displayName || child.type.name);
switch (childType) {
case Catalog.Header.displayName:
setCatalogHeaderContent(child);
break;
case Catalog.MainButton.displayName:
setCatalogMainButtonContent(child);
break;
case Catalog.Body.displayName:
setCatalogBodyContent(child);
break;
default:
break;
}
});
}, [children]);
const sizeChangeHandler = React.useCallback(() => {
clearTimeout(refTimer.current);
refTimer.current = setTimeout(() => {
if (isMobileOnly || isMobileUtils() || window.innerWidth === 375)
setShowText(true);
if (
((isTabletUtils() && window.innerWidth !== 375) || isMobile) &&
!isMobileOnly
)
setShowText(false);
if (isDesktopUtils() && !isMobile) setShowText(true);
}, 100);
}, [refTimer.current, setShowText]);
const hideText = React.useCallback((event) => {
event.preventDefault;
setShowText(false);
}, []);
return (
<>
<StyledCatalog showText={showText} catalogOpen={catalogOpen} {...rest}>
<Resizable
defaultSize={{
width: 256,
}}
enable={enable}
className="resizable-block"
handleWrapperClass="resizable-border not-selectable"
>
<SubCatalogHeader showText={showText} onClick={toggleShowText}>
{catalogHeaderContent ? catalogHeaderContent.props.children : null}
</SubCatalogHeader>
<SubCatalogMainButton showText={showText}>
{catalogMainButtonContent
? catalogMainButtonContent.props.children
: null}
</SubCatalogMainButton>
<SubCatalogBody showText={showText}>
{catalogBodyContent ? catalogBodyContent.props.children : null}
</SubCatalogBody>
</Resizable>
</StyledCatalog>
{catalogOpen && (isMobileOnly || window.innerWidth <= 375) && (
<>
<SubCatalogBackdrop onClick={toggleCatalogOpen} />
</>
)}
</>
);
};
Catalog.propTypes = {
showText: PropTypes.bool,
setShowText: PropTypes.func,
catalogOpen: PropTypes.bool,
toggleCatalogOpen: PropTypes.func,
children: PropTypes.any,
};
Catalog.Header = () => {
return null;
};
Catalog.Header.displayName = "Header";
Catalog.MainButton = () => {
return null;
};
Catalog.MainButton.displayName = "MainButton";
Catalog.Body = () => {
return null;
};
Catalog.Body.displayName = "Body";
export default inject(({ auth }) => {
const { isLoaded, settingsStore } = auth;
const {
showText,
setShowText,
catalogOpen,
toggleShowText,
toggleCatalogOpen,
} = settingsStore;
return {
showText,
setShowText,
catalogOpen,
toggleShowText,
toggleCatalogOpen,
};
})(observer(Catalog));

View File

@ -0,0 +1,269 @@
import styled, { css } from "styled-components";
import { isMobile, isMobileOnly, isTablet } from "react-device-detect";
import {
mobile,
tablet,
isMobile as isMobileUtils,
isTablet as isTabletUtils,
isDesktop as isDesktopUtils,
} from "@appserver/components/utils/device";
import Heading from "@appserver/components/heading";
import { Base } from "@appserver/components/themes";
import MenuIcon from "@appserver/components/public/static/images/menu.react.svg";
import CrossIcon from "@appserver/components/public/static/images/cross.react.svg";
const StyledCatalog = styled.div`
position: relative;
background: ${(props) => props.theme.catalog.background};
${isMobile &&
css`
margin-top: 48px;
`}
@media ${mobile} {
position: fixed;
margin-top: 16px;
height: calc(100vh - 64px) !important;
z-index: 400;
}
${isMobileOnly &&
css`
position: fixed;
margin-top: 64px !important;
height: calc(100vh - 64px) !important;
`}
z-index: ${(props) =>
props.showText && (isMobileOnly || isMobileUtils()) ? "205" : "100"};
.resizable-block {
display: flex;
flex-direction: column;
min-width: ${(props) => (props.showText ? "256px" : "52px")};
width: ${(props) => (props.showText ? "256px" : "52px")};
height: calc(100% - 44px) !important;
background: ${(props) => props.theme.catalog.background};
overflow-y: auto;
overflow-x: hidden;
scrollbar-width: none;
padding-bottom: 0px;
&::-webkit-scrollbar {
width: 0;
height: 0;
}
.resizable-border {
div {
cursor: ew-resize !important;
}
}
@media ${tablet} {
min-width: ${(props) => (props.showText ? "240px" : "52px")};
max-width: ${(props) => (props.showText ? "240px" : "52px")};
.resizable-border {
display: none;
}
}
@media ${mobile} {
display: ${(props) => (props.catalogOpen ? "flex" : "none")};
min-width: 100vw;
width: 100vw;
height: calc(100vh - 64px) !important;
margin: 0;
padding: 0;
padding-bottom: 0px;
}
${isTablet &&
css`
min-width: ${(props) => (props.showText ? "240px" : "52px")};
max-width: ${(props) => (props.showText ? "240px" : "52px")};
.resizable-border {
display: none;
}
`}
${isMobileOnly &&
css`
display: ${(props) => (props.catalogOpen ? "flex" : "none")};
min-width: 100vw !important;
width: 100vw;
height: calc(100vh - 64px) !important;
margin: 0;
padding: 0;
padding-bottom: 0px;
`}
}
`;
StyledCatalog.defaultProps = { theme: Base };
const StyledCatalogHeader = styled.div`
padding: 12px 20px 13px;
display: flex;
justify-content: flex-start;
align-items: center;
@media ${tablet} {
padding: 16px 16px 17px;
margin: 0;
justify-content: ${(props) => (props.showText ? "flex-start" : "center")};
}
@media ${mobile} {
border-bottom: ${(props) => props.theme.catalog.header.borderBottom};
padding: 12px 16px 12px;
margin-bottom: 16px !important;
}
${isTablet &&
css`
padding: 16px 16px 17px;
justify-content: ${(props) => (props.showText ? "flex-start" : "center")};
margin: 0;
`}
${isMobileOnly &&
css`
border-bottom: ${(props) =>
props.theme.catalog.header.borderBottom} !important;
padding: 12px 16px 12px !important;
margin-bottom: 16px !important;
`}
`;
StyledCatalogHeader.defaultProps = { theme: Base };
const StyledHeading = styled(Heading)`
margin: 0;
padding: 0;
font-weight: bold;
line-height: 28px;
@media ${tablet} {
display: ${(props) => (props.showText ? "block" : "none")};
margin-left: ${(props) => props.showText && "12px"};
}
${isTablet &&
css`
display: ${(props) => (props.showText ? "block" : "none")};
margin-left: ${(props) => props.showText && "12px"};
`}
@media ${mobile} {
margin-left: 0;
}
${isMobileOnly &&
css`
margin-left: 0 !important;
`}
`;
const StyledIconBox = styled.div`
display: none;
align-items: center;
height: 28px;
@media ${tablet} {
display: flex;
}
@media ${mobile} {
display: none;
}
${isMobile &&
css`
display: flex !important;
`}
${isMobileOnly &&
css`
display: none !important;
`}
`;
const StyledMenuIcon = styled(MenuIcon)`
display: block;
width: 20px;
height: 20px;
cursor: pointer;
path {
fill: ${(props) => props.theme.catalog.header.iconFill};
}
`;
StyledMenuIcon.defaultProps = { theme: Base };
const StyledCatalogMainButton = styled.div`
padding: 0px 20px 16px;
max-width: 216px;
@media ${tablet} {
display: none;
}
@media ${mobile} {
display: none;
}
${isTablet &&
css`
display: none;
`}
${isMobileOnly &&
css`
display: none;
`}
`;
const StyledControlContainer = styled.div`
background: ${(props) => props.theme.catalog.control.background};
width: 24px;
height: 24px;
position: absolute;
top: 30px;
right: 10px;
border-radius: 100px;
cursor: pointer;
display: flex;
align-items: center;
justify-content: center;
z-index: 290;
`;
StyledControlContainer.defaultProps = { theme: Base };
const StyledCrossIcon = styled(CrossIcon)`
width: 12px;
height: 12px;
path {
fill: ${(props) => props.theme.catalog.control.fill};
}
`;
StyledCrossIcon.defaultProps = { theme: Base };
export {
StyledCatalog,
StyledCatalogHeader,
StyledHeading,
StyledIconBox,
StyledMenuIcon,
StyledCatalogMainButton,
StyledControlContainer,
StyledCrossIcon,
};

View File

@ -0,0 +1,24 @@
import React from "react";
import PropTypes from "prop-types";
import Backdrop from "@appserver/components/backdrop";
import { StyledControlContainer, StyledCrossIcon } from "../styled-catalog";
const CatalogBackdrop = ({ showText, onClick, ...rest }) => {
return (
<>
<StyledControlContainer onClick={onClick} {...rest}>
<StyledCrossIcon />
</StyledControlContainer>
<Backdrop visible={true} zIndex={201} withBackground={true} />
</>
);
};
CatalogBackdrop.propTypes = {
showText: PropTypes.bool,
onClick: PropTypes.func,
};
export default React.memo(CatalogBackdrop);

View File

@ -0,0 +1,9 @@
import React from "react";
const CatalogBody = ({ children }) => {
return <> {children}</>;
};
CatalogBody.displayName = "Body";
export default React.memo(CatalogBody);

View File

@ -0,0 +1,33 @@
import React from "react";
import PropTypes from "prop-types";
import {
StyledCatalogHeader,
StyledHeading,
StyledIconBox,
StyledMenuIcon,
} from "../styled-catalog";
const CatalogHeader = ({ showText, children, onClick, ...rest }) => {
return (
<StyledCatalogHeader showText={showText} {...rest}>
<StyledIconBox name="catalog-burger">
<StyledMenuIcon onClick={onClick} />
</StyledIconBox>
<StyledHeading showText={showText} size="large">
{children}
</StyledHeading>
</StyledCatalogHeader>
);
};
CatalogHeader.propTypes = {
children: PropTypes.any,
showText: PropTypes.bool,
onClick: PropTypes.func,
};
CatalogHeader.displayName = "Header";
export default React.memo(CatalogHeader);

View File

@ -0,0 +1,11 @@
import React from "react";
import { StyledCatalogMainButton } from "../styled-catalog";
const CatalogMainButton = (props) => {
return <StyledCatalogMainButton {...props} />;
};
CatalogMainButton.displayName = "MainButton";
export default CatalogMainButton;

View File

@ -27,11 +27,6 @@ import FloatingButton from "../FloatingButton";
import { inject, observer } from "mobx-react"; import { inject, observer } from "mobx-react";
import Selecto from "react-selecto"; import Selecto from "react-selecto";
import styled, { css } from "styled-components"; import styled, { css } from "styled-components";
import Catalog from "./sub-components/catalog";
import SubCatalogBackdrop from "./sub-components/catalog-backdrop";
import SubCatalogHeader from "./sub-components/catalog-header";
import SubCatalogMainButton from "./sub-components/catalog-main-button";
import SubCatalogBody from "./sub-components/catalog-body";
const StyledSelectoWrapper = styled.div` const StyledSelectoWrapper = styled.div`
.selecto-selection { .selecto-selection {
@ -58,21 +53,6 @@ const StyledMainBar = styled.div`
`} `}
`; `;
function CatalogHeader() {
return null;
}
CatalogHeader.displayName = "CatalogHeader";
function CatalogMainButton() {
return null;
}
CatalogMainButton.displayName = "CatalogMainButton";
function CatalogBody() {
return null;
}
CatalogBody.displayName = "CatalogBody";
function ArticleHeader() { function ArticleHeader() {
return null; return null;
} }
@ -109,9 +89,6 @@ function SectionPaging() {
SectionPaging.displayName = "SectionPaging"; SectionPaging.displayName = "SectionPaging";
class PageLayout extends React.Component { class PageLayout extends React.Component {
static CatalogHeader = CatalogHeader;
static CatalogMainButton = CatalogMainButton;
static CatalogBody = CatalogBody;
static ArticleHeader = ArticleHeader; static ArticleHeader = ArticleHeader;
static ArticleMainButton = ArticleMainButton; static ArticleMainButton = ArticleMainButton;
static ArticleBody = ArticleBody; static ArticleBody = ArticleBody;
@ -259,16 +236,8 @@ class PageLayout extends React.Component {
isArticlePinned, isArticlePinned,
isDesktop, isDesktop,
isHomepage, isHomepage,
showText,
catalogOpen,
userShowText,
setShowText,
toggleShowText,
toggleCatalogOpen,
} = this.props; } = this.props;
let catalogHeaderContent = null;
let catalogMainButtonContent = null;
let catalogBodyContent = null;
let articleHeaderContent = null; let articleHeaderContent = null;
let articleMainButtonContent = null; let articleMainButtonContent = null;
let articleBodyContent = null; let articleBodyContent = null;
@ -281,15 +250,6 @@ class PageLayout extends React.Component {
child && child.type && (child.type.displayName || child.type.name); child && child.type && (child.type.displayName || child.type.name);
switch (childType) { switch (childType) {
case CatalogHeader.displayName:
catalogHeaderContent = child;
break;
case CatalogMainButton.displayName:
catalogMainButtonContent = child;
break;
case CatalogBody.displayName:
catalogBodyContent = child;
break;
case ArticleHeader.displayName: case ArticleHeader.displayName:
articleHeaderContent = child; articleHeaderContent = child;
break; break;
@ -336,61 +296,11 @@ class PageLayout extends React.Component {
isSectionBodyAvailable || isSectionBodyAvailable ||
isSectionPagingAvailable || isSectionPagingAvailable ||
isArticleAvailable, isArticleAvailable,
isBackdropAvailable = isArticleAvailable, isBackdropAvailable = isArticleAvailable;
isCatalogHeaderAvailable = !!catalogHeaderContent,
isCatalogMainButtonAvailable = !!catalogMainButtonContent,
isCatalogBodyAvailable = !!catalogBodyContent,
isCatalogAvailable =
isCatalogHeaderAvailable ||
isCatalogMainButtonAvailable ||
isCatalogBodyAvailable;
const renderPageLayout = () => { const renderPageLayout = () => {
return ( return (
<> <>
{isCatalogAvailable && (
<>
{catalogOpen && (isMobileOnly || window.innerWidth <= 375) && (
<>
<SubCatalogBackdrop onClick={toggleCatalogOpen} />
<Backdrop visible={true} zIndex={201} />
</>
)}
<Catalog
showText={showText}
catalogOpen={catalogOpen}
toggleCatalogOpen={toggleCatalogOpen}
setShowText={setShowText}
>
{isCatalogHeaderAvailable && (
<SubCatalogHeader
showText={showText}
onClick={toggleShowText}
>
{catalogHeaderContent
? catalogHeaderContent.props.children
: null}
</SubCatalogHeader>
)}
{isCatalogMainButtonAvailable && (
<SubCatalogMainButton showText={showText}>
{catalogMainButtonContent
? catalogMainButtonContent.props.children
: null}
</SubCatalogMainButton>
)}
{isCatalogBodyAvailable && (
<SubCatalogBody showText={showText}>
{catalogBodyContent
? catalogBodyContent.props.children
: null}
</SubCatalogBody>
)}
</Catalog>
</>
)}
{isBackdropAvailable && ( {isBackdropAvailable && (
<Backdrop <Backdrop
zIndex={400} zIndex={400}
@ -448,7 +358,6 @@ class PageLayout extends React.Component {
}} }}
> >
<Section <Section
catalogOpen={catalogOpen}
widthProp={width} widthProp={width}
unpinArticle={this.unpinArticle} unpinArticle={this.unpinArticle}
pinned={isArticlePinned} pinned={isArticlePinned}
@ -627,13 +536,6 @@ PageLayout.propTypes = {
isHeaderVisible: PropTypes.bool, isHeaderVisible: PropTypes.bool,
firstLoad: PropTypes.bool, firstLoad: PropTypes.bool,
isHomepage: PropTypes.bool, isHomepage: PropTypes.bool,
showText: PropTypes.bool,
userShowText: PropTypes.bool,
setShowText: PropTypes.func,
toggleShowText: PropTypes.func,
showCatalog: PropTypes.bool,
toggleCatalogOpen: PropTypes.func,
catalogOpen: PropTypes.bool,
}; };
PageLayout.defaultProps = { PageLayout.defaultProps = {
@ -641,8 +543,6 @@ PageLayout.defaultProps = {
withBodyAutoFocus: false, withBodyAutoFocus: false,
}; };
PageLayout.CatalogHeader = CatalogHeader;
PageLayout.CatalogMainButton = CatalogMainButton;
PageLayout.ArticleHeader = ArticleHeader; PageLayout.ArticleHeader = ArticleHeader;
PageLayout.ArticleMainButton = ArticleMainButton; PageLayout.ArticleMainButton = ArticleMainButton;
PageLayout.ArticleBody = ArticleBody; PageLayout.ArticleBody = ArticleBody;
@ -664,13 +564,6 @@ export default inject(({ auth }) => {
setIsArticleVisible, setIsArticleVisible,
setIsBackdropVisible, setIsBackdropVisible,
isDesktopClient, isDesktopClient,
showText,
userShowText,
setShowText,
toggleShowText,
showCatalog,
toggleCatalogOpen,
catalogOpen,
} = settingsStore; } = settingsStore;
return { return {
@ -685,12 +578,5 @@ export default inject(({ auth }) => {
isBackdropVisible, isBackdropVisible,
setIsBackdropVisible, setIsBackdropVisible,
isDesktop: isDesktopClient, isDesktop: isDesktopClient,
showText,
setShowText,
toggleShowText,
showCatalog,
userShowText,
toggleCatalogOpen,
catalogOpen,
}; };
})(observer(PageLayout)); })(observer(PageLayout));

View File

@ -1,48 +0,0 @@
import React from "react";
import PropTypes from "prop-types";
import styled from "styled-components";
import CrossIcon from "@appserver/components/public/static/images/cross.react.svg";
import Base from "@appserver/components/themes/base";
const StyledControlContainer = styled.div`
background: ${(props) => props.theme.catalog.control.background};
width: 24px;
height: 24px;
position: absolute;
top: 30px;
right: 10px;
border-radius: 100px;
cursor: pointer;
display: flex;
align-items: center;
justify-content: center;
z-index: 290;
`;
StyledControlContainer.defaultProps = { theme: Base };
const StyledCrossIcon = styled(CrossIcon)`
width: 12px;
height: 12px;
path {
fill: ${(props) => props.theme.catalog.control.fill};
}
`;
StyledCrossIcon.defaultProps = { theme: Base };
const CatalogBackdrop = (props) => {
const { showText, onClick, ...rest } = props;
return (
<StyledControlContainer onClick={onClick} {...rest}>
<StyledCrossIcon />
</StyledControlContainer>
);
};
CatalogBackdrop.propTypes = {
showText: PropTypes.bool,
onClick: PropTypes.func,
};
export default React.memo(CatalogBackdrop);

View File

@ -1,9 +0,0 @@
import React from "react";
const CatalogBody = (props) => {
return <> {props.children}</>;
};
CatalogBody.displayName = "CatalogBody";
export default React.memo(CatalogBody);

View File

@ -1,134 +0,0 @@
import React from "react";
import PropTypes from "prop-types";
import styled, { css } from "styled-components";
import Heading from "@appserver/components/heading";
import { isMobileOnly, isTablet } from "react-device-detect";
import MenuIcon from "@appserver/components/public/static/images/menu.react.svg";
import { tablet, mobile } from "@appserver/components/utils/device";
import Base from "@appserver/components/themes/base";
const StyledCatalogHeader = styled.div`
padding: 12px 20px 13px;
display: flex;
justify-content: flex-start;
align-items: center;
@media ${tablet} {
padding: 16px 16px 17px;
margin: 0;
justify-content: ${(props) => (props.showText ? "flex-start" : "center")};
}
@media ${mobile} {
border-bottom: ${(props) => props.theme.catalog.header.borderBottom};
padding: 12px 16px 12px;
margin-bottom: 16px !important;
}
${isTablet &&
css`
padding: 16px 16px 17px;
justify-content: ${(props) => (props.showText ? "flex-start" : "center")};
margin: 0;
`}
${isMobileOnly &&
css`
border-bottom: ${(props) =>
props.theme.catalog.header.borderBottom} !important;
padding: 12px 16px 12px !important;
margin-bottom: 16px !important;
`}
`;
StyledCatalogHeader.defaultProps = { theme: Base };
const StyledHeading = styled(Heading)`
margin: 0;
padding: 0;
font-weight: bold;
line-height: 28px;
@media ${tablet} {
display: ${(props) => (props.showText ? "block" : "none")};
margin-left: ${(props) => props.showText && "12px"};
}
${isTablet &&
css`
display: ${(props) => (props.showText ? "block" : "none")};
margin-left: ${(props) => props.showText && "12px"};
`}
@media ${mobile} {
margin-left: 0;
}
${isMobileOnly &&
css`
margin-left: 0 !important;
`}
`;
const StyledIconBox = styled.div`
display: none;
align-items: center;
height: 28px;
@media ${tablet} {
display: flex;
}
@media ${mobile} {
display: none;
}
${isTablet &&
css`
display: flex !important;
`}
${isMobileOnly &&
css`
display: none !important;
`}
`;
const StyledMenuIcon = styled(MenuIcon)`
display: block;
width: 20px;
height: 20px;
cursor: pointer;
path {
fill: ${(props) => props.theme.catalog.header.iconFill};
}
`;
StyledMenuIcon.defaultProps = { theme: Base };
const CatalogHeader = (props) => {
const { showText, children, onClick, ...rest } = props;
return (
<StyledCatalogHeader showText={showText} {...rest}>
<StyledIconBox name="catalog-burger">
<StyledMenuIcon onClick={onClick} />
</StyledIconBox>
<StyledHeading showText={showText} size="large">
{children}
</StyledHeading>
</StyledCatalogHeader>
);
};
CatalogHeader.propTypes = {
children: PropTypes.any,
showText: PropTypes.bool,
onClick: PropTypes.func,
};
CatalogHeader.displayName = "CatalogHeader";
export default React.memo(CatalogHeader);

View File

@ -1,34 +0,0 @@
import React from "react";
import styled, { css } from "styled-components";
import { isMobileOnly, isTablet } from "react-device-detect";
import { mobile, tablet } from "@appserver/components/utils/device";
const StyledCatalogMainButton = styled.div`
padding: 0px 20px 16px;
max-width: 216px;
@media ${tablet} {
display: none;
}
@media ${mobile} {
display: none;
}
${isTablet &&
css`
display: none;
`}
${isMobileOnly &&
css`
display: none;
`}
`;
const CatalogMainButton = (props) => {
return <StyledCatalogMainButton {...props} />;
};
CatalogMainButton.displayName = "CatalogMainButton";
export default CatalogMainButton;

View File

@ -1,175 +0,0 @@
import React from "react";
import styled, { css } from "styled-components";
import PropTypes from "prop-types";
import { Resizable } from "re-resizable";
import { isMobile, isMobileOnly, isTablet } from "react-device-detect";
import {
mobile,
tablet,
isMobile as isMobileUtils,
isTablet as isTabletUtils,
isDesktop as isDesktopUtils,
} from "@appserver/components/utils/device";
import { Base } from "@appserver/components/themes";
const StyledCatalog = styled.div`
position: relative;
background: ${(props) => props.theme.catalog.background};
${isMobile &&
css`
margin-top: 48px;
`}
@media ${mobile} {
position: fixed;
margin-top: 16px;
height: calc(100vh - 64px) !important;
z-index: 400;
}
${isMobileOnly &&
css`
position: fixed;
margin-top: 64px !important;
height: calc(100vh - 64px) !important;
`}
z-index: ${(props) =>
props.showText && (isMobileOnly || isMobileUtils()) ? "201" : "100"};
.resizable-block {
display: flex;
flex-direction: column;
min-width: ${(props) => (props.showText ? "256px" : "52px")};
width: ${(props) => (props.showText ? "256px" : "52px")};
height: calc(100% - 44px) !important;
background: ${(props) => props.theme.catalog.background};
overflow-y: auto;
overflow-x: hidden;
scrollbar-width: none;
padding-bottom: 0px;
&::-webkit-scrollbar {
width: 0;
height: 0;
}
.resizable-border {
div {
cursor: ew-resize !important;
}
}
@media ${tablet} {
min-width: ${(props) => (props.showText ? "240px" : "52px")};
max-width: ${(props) => (props.showText ? "240px" : "52px")};
.resizable-border {
display: none;
}
}
@media ${mobile} {
display: ${(props) => (props.catalogOpen ? "flex" : "none")};
min-width: 100vw;
width: 100vw;
height: calc(100vh - 64px) !important;
margin: 0;
padding: 0;
padding-bottom: 0px;
}
${isTablet &&
css`
min-width: ${(props) => (props.showText ? "240px" : "52px")};
max-width: ${(props) => (props.showText ? "240px" : "52px")};
.resizable-border {
display: none;
}
`}
${isMobileOnly &&
css`
display: ${(props) => (props.catalogOpen ? "flex" : "none")};
min-width: 100vw !important;
width: 100vw;
height: calc(100vh - 64px) !important;
margin: 0;
padding: 0;
padding-bottom: 0px;
`}
}
`;
StyledCatalog.defaultProps = { theme: Base };
const Catalog = (props) => {
const { showText, setShowText, catalogOpen, children, ...rest } = props;
const refTimer = React.useRef(null);
const enable = {
top: false,
right: !isMobile,
bottom: false,
left: false,
};
const hideText = React.useCallback((event) => {
event.preventDefault;
setShowText(false);
}, []);
React.useEffect(() => {
if (isMobileOnly) {
window.addEventListener("popstate", hideText);
return () => window.removeEventListener("popstate", hideText);
}
}, [hideText]);
React.useEffect(() => {
window.addEventListener("resize", sizeChangeHandler);
return () => window.removeEventListener("resize", sizeChangeHandler);
});
React.useEffect(() => {
sizeChangeHandler();
}, []);
const sizeChangeHandler = () => {
clearTimeout(refTimer.current);
refTimer.current = setTimeout(() => {
if (isMobileOnly || isMobileUtils() || window.innerWidth === 375)
props.setShowText(true);
if (
((isTabletUtils() && window.innerWidth !== 375) || isMobile) &&
!isMobileOnly
)
props.setShowText(false);
if (isDesktopUtils() && !isMobile) props.setShowText(true);
}, 100);
};
return (
<StyledCatalog showText={showText} catalogOpen={catalogOpen} {...rest}>
<Resizable
defaultSize={{
width: 256,
}}
enable={enable}
className="resizable-block"
handleWrapperClass="resizable-border not-selectable"
>
{children}
</Resizable>
</StyledCatalog>
);
};
Catalog.propTypes = {
showText: PropTypes.bool,
setShowText: PropTypes.func,
children: PropTypes.any,
};
export default Catalog;