From 5233b5c056d124a7f662efd3d670621145f9bcb5 Mon Sep 17 00:00:00 2001 From: Aminejv Date: Thu, 28 Oct 2021 17:15:22 +0100 Subject: [PATCH] feat(Filter/Popup): add responsive popup component --- components/core/Filter/Content.js | 2 +- components/core/Filter/Navbar.js | 28 +++++++++-- components/core/Filter/Popup.js | 80 +++++++++++++++++++++++++++++++ components/core/Filter/index.js | 22 ++++++++- scenes/SceneFilesFolder.js | 30 ++++++++++-- 5 files changed, 153 insertions(+), 9 deletions(-) create mode 100644 components/core/Filter/Popup.js diff --git a/components/core/Filter/Content.js b/components/core/Filter/Content.js index 965da507..3ec7e0f1 100644 --- a/components/core/Filter/Content.js +++ b/components/core/Filter/Content.js @@ -12,7 +12,7 @@ const STYLES_DATAVIEWER_WRAPPER = (theme) => css` min-height: 100vh; padding: calc(20px + ${theme.sizes.filterNavbar}px) 24px 44px; @media (max-width: ${theme.sizes.mobile}px) { - padding: 31px 16px 44px; + padding: calc(31px + ${theme.sizes.filterNavbar}px) 16px 44px; } `; diff --git a/components/core/Filter/Navbar.js b/components/core/Filter/Navbar.js index 0625a095..7a182917 100644 --- a/components/core/Filter/Navbar.js +++ b/components/core/Filter/Navbar.js @@ -1,5 +1,6 @@ import * as React from "react"; import * as ReactDOM from "react-dom"; +import * as Styles from "~/common/styles"; import { usePortals } from "~/components/core/PortalsProvider"; import { css } from "@emotion/react"; @@ -16,8 +17,9 @@ export function NavbarPortal({ children }) { return filterNavbarElement ? ReactDOM.createPortal( <> - +
{children}
+ , filterNavbarElement ) @@ -29,12 +31,27 @@ export function NavbarPortal({ children }) { * -----------------------------------------------------------------------------------------------*/ const STYLES_NAVBAR = (theme) => css` + position: relative; display: flex; justify-content: space-between; align-items: center; - background-color: ${theme.semantic.bgWhite}; padding: 9px 24px 11px; box-shadow: ${theme.shadow.lightSmall}; + + @media (max-width: ${theme.sizes.mobile}px) { + padding: 9px 16px 11px; + } +`; + +const STYLES_NAVBAR_BACKGROUND = (theme) => css` + position: absolute; + width: 100%; + height: 100%; + top: 0px; + left: 0px; + z-index: -1; + + background-color: ${theme.semantic.bgWhite}; @supports ((-webkit-backdrop-filter: blur(75px)) or (backdrop-filter: blur(75px))) { -webkit-backdrop-filter: blur(75px); backdrop-filter: blur(75px); @@ -49,5 +66,10 @@ const STYLES_NAVBAR = (theme) => css` export function Navbar({ children }) { const { filterNavbar } = usePortals(); const [, setFilterElement] = filterNavbar; - return
{children}
; + return ( +
+ {children} +
+
+ ); } diff --git a/components/core/Filter/Popup.js b/components/core/Filter/Popup.js new file mode 100644 index 00000000..1438f2e7 --- /dev/null +++ b/components/core/Filter/Popup.js @@ -0,0 +1,80 @@ +import * as React from "react"; +import * as SVG from "~/common/svg"; +import * as Styles from "~/common/styles"; +import * as Filters from "~/components/core/Filter/Filters"; + +import { useFilterContext } from "~/components/core/Filter/Provider"; +import { motion } from "framer-motion"; +import { css } from "@emotion/react"; + +/* ------------------------------------------------------------------------------------------------- + * Popup trigger + * -----------------------------------------------------------------------------------------------*/ + +export function PopupTrigger({ children, isMobile, ...props }) { + const [{ sidebarState, popupState }, { hidePopup, togglePopup }] = useFilterContext(); + + React.useEffect(() => { + if (sidebarState.isVisible) { + hidePopup(); + } + }, [sidebarState.isVisible]); + + if (sidebarState.isVisible && !isMobile) return null; + + return ( + + ); +} + +/* ------------------------------------------------------------------------------------------------- + * Popup + * -----------------------------------------------------------------------------------------------*/ +const STYLES_SIDEBAR_FILTER_WRAPPER = (theme) => css` + position: sticky; + top: ${theme.sizes.header + theme.sizes.filterNavbar}px; + width: 236px; + max-height: 420px; + overflow-y: auto; + overflow-x: hidden; + border-radius: 16px; + padding: 20px 16px; + box-shadow: ${theme.shadow.lightLarge}; + border: 1px solid ${theme.semantic.borderGrayLight}; + + background-color: ${theme.semantic.bgLight}; + @supports ((-webkit-backdrop-filter: blur(75px)) or (backdrop-filter: blur(75px))) { + background-color: ${theme.semantic.bgBlurWhite}; + -webkit-backdrop-filter: blur(75px); + backdrop-filter: blur(75px); + } + + @media (max-width: ${theme.sizes.mobile}px) { + border-radius: unset; + width: 100%; + max-height: 375px; + padding: 15px 8px; + } +`; + +export function Popup({ viewer, css, ...props }) { + const [{ popupState }] = useFilterContext(); + + if (!popupState.isVisible) return null; + + return ( +
+ + +
+ ); +} diff --git a/components/core/Filter/index.js b/components/core/Filter/index.js index e9f6f0d1..98a88bcd 100644 --- a/components/core/Filter/index.js +++ b/components/core/Filter/index.js @@ -4,14 +4,21 @@ import * as System from "~/components/system"; import { Navbar, NavbarPortal } from "~/components/core/Filter/Navbar"; import { Provider } from "~/components/core/Filter/Provider"; import { Sidebar, SidebarTrigger } from "~/components/core/Filter/Sidebar"; +import { Popup, PopupTrigger } from "~/components/core/Filter/Popup"; import { Content } from "~/components/core/Filter/Content"; +import { useFilterContext } from "~/components/core/Filter/Provider"; /* ------------------------------------------------------------------------------------------------- * Title * -----------------------------------------------------------------------------------------------*/ function Title() { - return All; + const [{ filterState }] = useFilterContext(); + return ( + + {filterState.title} + + ); } /* ------------------------------------------------------------------------------------------------- @@ -21,4 +28,15 @@ function Actions() { return
; } -export { Title, Actions, Sidebar, SidebarTrigger, Provider, Navbar, Content, NavbarPortal }; +export { + Title, + Actions, + Sidebar, + SidebarTrigger, + Popup, + PopupTrigger, + Provider, + Navbar, + Content, + NavbarPortal, +}; diff --git a/scenes/SceneFilesFolder.js b/scenes/SceneFilesFolder.js index d350d9c4..019d4bad 100644 --- a/scenes/SceneFilesFolder.js +++ b/scenes/SceneFilesFolder.js @@ -17,12 +17,24 @@ const STYLES_SCENE_PAGE = css` `; const STYLES_FILTER_TITLE_WRAPPER = css` + ${Styles.MOBILE_HIDDEN}; position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); `; +const STYLES_FILTER_POPUP_WRAPPER = (theme) => css` + position: absolute; + top: calc(${theme.sizes.filterNavbar}px + 4px); + left: 4px; + width: 100%; + @media (max-width: ${theme.sizes.mobile}px) { + top: ${theme.sizes.filterNavbar}px; + left: 0px; + } +`; + export default function SceneFilesFolder({ viewer, page, onAction, isMobile }) { const [index, setIndex] = React.useState(-1); @@ -47,9 +59,21 @@ export default function SceneFilesFolder({ viewer, page, onAction, isMobile }) { /> -
- +
+
+ +
+
+ +
+ + + + + +
+
@@ -57,7 +81,7 @@ export default function SceneFilesFolder({ viewer, page, onAction, isMobile }) {
- +