diff --git a/packages/client/src/pages/PortalSettings/categories/common/index.js b/packages/client/src/pages/PortalSettings/categories/common/index.js index e98c3ea4d1..8f2aff41d1 100644 --- a/packages/client/src/pages/PortalSettings/categories/common/index.js +++ b/packages/client/src/pages/PortalSettings/categories/common/index.js @@ -38,6 +38,7 @@ import withLoading from "SRC_DIR/HOCs/withLoading"; import LoaderSubmenu from "./sub-components/loaderSubmenu"; import { resetSessionStorage } from "../../utils"; import { DeviceType } from "@docspace/shared/enums"; +import { SECTION_HEADER_HEIGHT } from "@docspace/shared/components/section/Section.constants"; const SubmenuCommon = (props) => { const { @@ -117,13 +118,7 @@ const SubmenuCommon = (props) => { data={data} startSelect={currentTab} onSelect={(e) => onSelect(e)} - topProps={ - currentDeviceType === DeviceType.desktop - ? 0 - : currentDeviceType === DeviceType.mobile - ? "53px" - : "61px" - } + topProps={SECTION_HEADER_HEIGHT[currentDeviceType]} /> ); }; diff --git a/packages/client/src/pages/PortalSettings/categories/data-management/index.js b/packages/client/src/pages/PortalSettings/categories/data-management/index.js index 4f0d9b14e4..312b2a2a68 100644 --- a/packages/client/src/pages/PortalSettings/categories/data-management/index.js +++ b/packages/client/src/pages/PortalSettings/categories/data-management/index.js @@ -44,6 +44,7 @@ import ManualBackup from "./backup/manual-backup"; import AutoBackup from "./backup/auto-backup"; import { DeviceType } from "@docspace/shared/enums"; import { isManagement } from "@docspace/shared/utils/common"; +import { SECTION_HEADER_HEIGHT } from "@docspace/shared/components/section/Section.constants"; const DataManagementWrapper = (props) => { const { @@ -144,13 +145,7 @@ const DataManagementWrapper = (props) => { data={data} startSelect={currentTab} onSelect={(e) => onSelect(e)} - topProps={ - currentDeviceType === DeviceType.desktop - ? 0 - : currentDeviceType === DeviceType.mobile - ? "53px" - : "61px" - } + topProps={SECTION_HEADER_HEIGHT[currentDeviceType]} /> ); }; diff --git a/packages/client/src/pages/PortalSettings/categories/developer-tools/index.js b/packages/client/src/pages/PortalSettings/categories/developer-tools/index.js index 1f83d7ae47..25b7413384 100644 --- a/packages/client/src/pages/PortalSettings/categories/developer-tools/index.js +++ b/packages/client/src/pages/PortalSettings/categories/developer-tools/index.js @@ -44,9 +44,9 @@ import { isMobile, isMobileOnly } from "react-device-detect"; import AppLoader from "@docspace/shared/components/app-loader"; import SSOLoader from "./sub-components/ssoLoader"; import { WebhookConfigsLoader } from "./Webhooks/sub-components/Loaders"; -import { DeviceType } from "@docspace/shared/enums"; import PluginSDK from "./PluginSDK"; import { Badge } from "@docspace/shared/components/badge"; +import { SECTION_HEADER_HEIGHT } from "@docspace/shared/components/section/Section.constants"; const StyledSubmenu = styled(Submenu)` .sticky { @@ -151,13 +151,7 @@ const DeveloperToolsWrapper = (props) => { data={data} startSelect={currentTab} onSelect={onSelect} - topProps={ - currentDeviceType === DeviceType.desktop - ? 0 - : currentDeviceType === DeviceType.mobile - ? "53px" - : "61px" - } + topProps={SECTION_HEADER_HEIGHT[currentDeviceType]} /> ); diff --git a/packages/client/src/pages/PortalSettings/categories/integration/index.js b/packages/client/src/pages/PortalSettings/categories/integration/index.js index f0d3af8586..fc60333cab 100644 --- a/packages/client/src/pages/PortalSettings/categories/integration/index.js +++ b/packages/client/src/pages/PortalSettings/categories/integration/index.js @@ -38,9 +38,9 @@ import ThirdParty from "./ThirdPartyServicesSettings"; import SMTPSettings from "./SMTPSettings"; import DocumentService from "./DocumentService"; import PluginPage from "./Plugins"; -import { DeviceType } from "@docspace/shared/enums"; import { Badge } from "@docspace/shared/components/badge"; import { Box } from "@docspace/shared/components/box"; +import { SECTION_HEADER_HEIGHT } from "@docspace/shared/components/section/Section.constants"; const IntegrationWrapper = (props) => { const { @@ -136,13 +136,7 @@ const IntegrationWrapper = (props) => { data={data} startSelect={currentTab} onSelect={onSelect} - topProps={ - currentDeviceType === DeviceType.desktop - ? 0 - : currentDeviceType === DeviceType.mobile - ? "53px" - : "61px" - } + topProps={SECTION_HEADER_HEIGHT[currentDeviceType]} /> ); }; diff --git a/packages/client/src/pages/PortalSettings/categories/security/index.js b/packages/client/src/pages/PortalSettings/categories/security/index.js index 8af5f06bc9..77adadef9c 100644 --- a/packages/client/src/pages/PortalSettings/categories/security/index.js +++ b/packages/client/src/pages/PortalSettings/categories/security/index.js @@ -40,6 +40,7 @@ import AccessLoader from "./sub-components/loaders/access-loader"; import AuditTrail from "./audit-trail/index.js"; import { resetSessionStorage } from "../../utils"; import { DeviceType } from "@docspace/shared/enums"; +import { SECTION_HEADER_HEIGHT } from "@docspace/shared/components/section/Section.constants"; const SecurityWrapper = (props) => { const { t, loadBaseInfo, resetIsInit, currentDeviceType } = props; @@ -110,13 +111,7 @@ const SecurityWrapper = (props) => { data={data} startSelect={currentTab} onSelect={(e) => onSelect(e)} - topProps={ - currentDeviceType === DeviceType.desktop - ? 0 - : currentDeviceType === DeviceType.mobile - ? "53px" - : "61px" - } + topProps={SECTION_HEADER_HEIGHT[currentDeviceType]} /> ); }; diff --git a/packages/client/src/pages/Profile/Section/Body/index.js b/packages/client/src/pages/Profile/Section/Body/index.js index 610c10ac5b..a0f86140db 100644 --- a/packages/client/src/pages/Profile/Section/Body/index.js +++ b/packages/client/src/pages/Profile/Section/Body/index.js @@ -41,7 +41,7 @@ import FileManagement from "./sub-components/file-management"; import InterfaceTheme from "./sub-components/interface-theme"; import { tablet } from "@docspace/shared/utils"; -import { DeviceType } from "@docspace/shared/enums"; +import { SECTION_HEADER_HEIGHT } from "@docspace/shared/components/section/Section.constants"; const Wrapper = styled.div` display: flex; @@ -54,6 +54,14 @@ const Wrapper = styled.div` } `; +const StyledSubMenu = styled(Submenu)` + > .sticky { + z-index: 201; + margin-inline-end: -17px; + padding-inline-end: 17px; + } +`; + const SectionBodyContent = (props) => { const { showProfileLoader, profile, currentDeviceType, t } = props; const navigate = useNavigate(); @@ -102,17 +110,11 @@ const SectionBodyContent = (props) => { return ( - ); diff --git a/packages/shared/components/section/Section.constants.ts b/packages/shared/components/section/Section.constants.ts index f5f7785e08..ac7005bc59 100644 --- a/packages/shared/components/section/Section.constants.ts +++ b/packages/shared/components/section/Section.constants.ts @@ -24,6 +24,8 @@ // content are licensed under the terms of the Creative Commons Attribution-ShareAlike 4.0 // International. See the License terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode +import { DeviceType } from "../../enums"; + export const SECTION_HEADER_NAME = "SectionHeader"; export const SECTION_FILTER_NAME = "SectionFilter"; export const SECTION_BODY_NAME = "SectionBody"; @@ -33,3 +35,9 @@ export const SECTION_INFO_PANEL_BODY_NAME = "InfoPanelBody"; export const SECTION_INFO_PANEL_HEADER_NAME = "InfoPanelHeader"; export const SECTION_WARNING_NAME = "SectionWarning"; export const SECTION_SUBMENU_NAME = "SectionSubmenu"; + +export const SECTION_HEADER_HEIGHT: Readonly> = { + [DeviceType.desktop]: "69px", + [DeviceType.tablet]: "61px", + [DeviceType.mobile]: "53px", +}; diff --git a/packages/shared/components/section/Section.styled.ts b/packages/shared/components/section/Section.styled.ts index 4113460c5e..c9ef3ef5e5 100644 --- a/packages/shared/components/section/Section.styled.ts +++ b/packages/shared/components/section/Section.styled.ts @@ -43,6 +43,7 @@ import { TViewAs } from "../../types"; import { Scrollbar } from "../scrollbar"; import DragAndDrop from "../drag-and-drop/DragAndDrop"; import { SectionContainerProps } from "./Section.types"; +import { SECTION_HEADER_HEIGHT } from "./Section.constants"; const StyledScrollbar = styled(Scrollbar)<{ $isScrollLocked?: boolean }>` ${({ $isScrollLocked }) => @@ -507,14 +508,7 @@ const sizeBetweenIcons = "8px"; const StyledSectionContainer = styled.section` position: relative; - ${(props) => - props.theme.interfaceDirection === "rtl" - ? css` - padding: 0 20px 0 0; - ` - : css` - padding: 0 0 0 20px; - `} + ${(props) => !props.withBodyScroll && "padding-inline-start: 20px;"} flex-grow: 1; display: flex; flex-direction: column; @@ -526,20 +520,37 @@ const StyledSectionContainer = styled.section` @media ${tablet} { width: 100%; max-width: 100vw !important; - ${(props) => - props.theme.interfaceDirection === "rtl" - ? css` - padding: 0 16px 0 0; - ` - : css` - padding: 0 0 0 16px; - `} + + ${(props) => !props.withBodyScroll && "padding-inline-start: 16px;"} ${tabletProps}; } @media ${mobile} { width: 100vw !important; max-width: 100vw !important; + padding-inline-start: 16px; + } + + .section-scroll > .scroll-body { + padding-inline-start: 20px !important; + + @media ${tablet} { + padding-inline-start: 16px !important; + } + } + + .section-sticky-container { + position: sticky; + top: 0; + background: ${(props) => props.theme.section.header.backgroundColor}; + z-index: 201; + padding-inline: 20px; + margin-inline: -20px -17px; + + @media ${tablet} { + padding-inline: 16px; + margin-inline: -16px; + } } .progress-bar_container { @@ -618,14 +629,6 @@ const StyledSectionContainer = styled.section` StyledSectionContainer.defaultProps = { theme: Base }; const StyledSectionFilter = styled.div` - ${(props) => - props.theme.interfaceDirection === "rtl" - ? css` - margin-left: 20px; - ` - : css` - margin-right: 20px; - `} @media ${tablet} { ${(props) => props.theme.interfaceDirection === "rtl" @@ -652,18 +655,18 @@ const StyledSectionHeader = styled.div<{ isFormGallery?: boolean }>` position: relative; display: flex; - height: 69px; - min-height: 69px; + height: ${SECTION_HEADER_HEIGHT.desktop}; + min-height: ${SECTION_HEADER_HEIGHT.desktop}; @media ${tablet} { - height: 61px; - min-height: 61px; + height: ${SECTION_HEADER_HEIGHT.tablet}; + min-height: ${SECTION_HEADER_HEIGHT.tablet}; ${({ isFormGallery }) => isFormGallery && css` - height: 69px; - min-height: 69px; + height: ${SECTION_HEADER_HEIGHT.desktop}; + min-height: ${SECTION_HEADER_HEIGHT.desktop}; `} .header-container { @@ -673,19 +676,10 @@ const StyledSectionHeader = styled.div<{ isFormGallery?: boolean }>` } @media ${mobile} { - height: 53px; - min-height: 53px; + height: ${SECTION_HEADER_HEIGHT.mobile}; + min-height: ${SECTION_HEADER_HEIGHT.mobile}; } - ${(props) => - props.theme.interfaceDirection === "rtl" - ? css` - padding-left: 20px; - ` - : css` - padding-right: 20px; - `} - box-sizing: border-box; ${NoUserSelect} @@ -700,28 +694,8 @@ const StyledSectionHeader = styled.div<{ isFormGallery?: boolean }>` display: flex; } - @media ${tablet} { - ${(props) => - props.theme.interfaceDirection === "rtl" - ? css` - padding-left: 16px; - margin-left: 0px; - ` - : css` - padding-right: 16px; - margin-right: 0px; - `} - } - @media ${mobile} { - ${(props) => - props.theme.interfaceDirection === "rtl" - ? css` - margin-left: 0px; - ` - : css` - margin-right: 0px; - `} + margin-inline-end: 0; } `; @@ -754,13 +728,13 @@ StyledSectionPaging.defaultProps = { theme: Base }; const StyledSectionSubmenu = styled.div` background: ${(props) => props.theme.section.header.backgroundColor}; - width: calc(100% - 20px); + width: 100%; z-index: 1; @media ${tablet} { width: calc(100% + 32px); position: sticky; - top: 61px; + top: ${SECTION_HEADER_HEIGHT.tablet}; margin: 0 -16px; & > div { padding: 0 16px; @@ -769,7 +743,7 @@ const StyledSectionSubmenu = styled.div` @media ${mobile} { position: sticky; - top: 53px; + top: ${SECTION_HEADER_HEIGHT.mobile}; } `; diff --git a/packages/shared/components/section/Section.types.ts b/packages/shared/components/section/Section.types.ts index 85e53b8e9c..8e12de989a 100644 --- a/packages/shared/components/section/Section.types.ts +++ b/packages/shared/components/section/Section.types.ts @@ -75,6 +75,8 @@ export interface SectionContainerProps { isSectionHeaderAvailable: boolean; viewAs?: TViewAs; children: React.ReactNode; + withBodyScroll: boolean; + currentDeviceType?: DeviceType; } export interface SectionFilterProps { diff --git a/packages/shared/components/section/index.tsx b/packages/shared/components/section/index.tsx index 340a02219c..8febe6206d 100644 --- a/packages/shared/components/section/index.tsx +++ b/packages/shared/components/section/index.tsx @@ -201,30 +201,35 @@ const Section = (props: SectionProps) => { ref={containerRef} isSectionHeaderAvailable={isSectionHeaderAvailable} showTwoProgress={showTwoProgress} + withBodyScroll={withBodyScroll} + currentDeviceType={currentDeviceType} > - {isSectionHeaderAvailable && - currentDeviceType === DeviceType.desktop && ( - - {sectionHeaderContent} - - )} + {currentDeviceType !== DeviceType.mobile && ( +
+ {isSectionHeaderAvailable && ( + + {sectionHeaderContent} + + )} - {isSectionSubmenuAvailable && - currentDeviceType === DeviceType.desktop && ( - {sectionSubmenuContent} - )} - {isSectionFilterAvailable && - currentDeviceType === DeviceType.desktop && ( - - {sectionFilterContent} - - )} + {isSectionSubmenuAvailable && ( + {sectionSubmenuContent} + )} + + {isSectionFilterAvailable && + currentDeviceType === DeviceType.desktop && ( + + {sectionFilterContent} + + )} +
+ )} {isSectionBodyAvailable && ( { getContextModel={getContextModel} > {isSectionHeaderAvailable && - currentDeviceType !== DeviceType.desktop && ( + currentDeviceType === DeviceType.mobile && ( { {sectionWarningContent} )} {isSectionSubmenuAvailable && - currentDeviceType !== DeviceType.desktop && ( + currentDeviceType === DeviceType.mobile && ( {sectionSubmenuContent} )} {isSectionFilterAvailable && diff --git a/packages/shared/components/section/sub-components/SectionBody.tsx b/packages/shared/components/section/sub-components/SectionBody.tsx index 4d1f6d2873..19bd8b3320 100644 --- a/packages/shared/components/section/sub-components/SectionBody.tsx +++ b/packages/shared/components/section/sub-components/SectionBody.tsx @@ -28,11 +28,8 @@ import React from "react"; // import { inject, observer } from "mobx-react"; -import { Scrollbar } from "@docspace/shared/components/scrollbar"; import { ContextMenu } from "@docspace/shared/components/context-menu"; -import { DeviceType } from "@docspace/shared/enums"; - import { StyledDropZoneBody, StyledSpacer, @@ -52,7 +49,6 @@ const SectionBody = React.memo( isDesktop, settingsStudio = false, - currentDeviceType, getContextModel, }: SectionBodyProps) => { const focusRef = React.useRef(null); @@ -98,7 +94,7 @@ const SectionBody = React.memo( React.useEffect(() => { if (!autoFocus) return; - if (focusRef.current) focusRef.current.focus(); + if (focusRef.current) focusRef.current.focus({ preventScroll: true }); }, [autoFocus]); const focusProps = autoFocus @@ -128,27 +124,12 @@ const SectionBody = React.memo( className="section-body" > {withScroll ? ( - currentDeviceType !== DeviceType.mobile ? ( - -
-
- {children} - -
-
-
- ) : ( -
-
- {children} - -
+
+
+ {children} +
- ) +
) : (
{children} @@ -168,27 +149,12 @@ const SectionBody = React.memo( className="section-body" > {withScroll ? ( - currentDeviceType !== DeviceType.mobile ? ( - -
-
- {children} - -
-
-
- ) : ( -
-
- {children} - -
+
+
+ {children} +
- ) +
) : (
{children}
)} diff --git a/packages/shared/components/section/sub-components/SectionContainer.tsx b/packages/shared/components/section/sub-components/SectionContainer.tsx index e9e508ef7e..4d9512163c 100644 --- a/packages/shared/components/section/sub-components/SectionContainer.tsx +++ b/packages/shared/components/section/sub-components/SectionContainer.tsx @@ -25,14 +25,33 @@ // International. See the License terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode import React from "react"; + +import { Scrollbar } from "../../scrollbar"; +import { DeviceType } from "../../../enums"; + import { StyledSectionContainer } from "../Section.styled"; import { SectionContainerProps } from "../Section.types"; const SectionContainer = React.forwardRef< HTMLDivElement, SectionContainerProps ->((props, forwardRef) => { - return ; +>(({ withBodyScroll, children, currentDeviceType, ...props }, forwardRef) => { + return ( + + {withBodyScroll && currentDeviceType !== DeviceType.mobile ? ( + + {children} + + ) : ( + children + )} + + ); }); SectionContainer.displayName = "SectionContainer";