From 61bf22c6f80e764bdf5c3b56bb0124a95aa0f793 Mon Sep 17 00:00:00 2001 From: Sofien-Sellami <73444179+Sofien-Sellami@users.noreply.github.com> Date: Mon, 8 Jan 2024 19:59:20 +0100 Subject: [PATCH] feat(ui): sidePanel expandedWidth (#3728) --- .../src/Components/SidePanelWithServices.tsx | 5 +- .../ui/src/components/SidePanel/SidePanel.tsx | 97 +++++++++++++------ 2 files changed, 69 insertions(+), 33 deletions(-) diff --git a/extensions/default/src/Components/SidePanelWithServices.tsx b/extensions/default/src/Components/SidePanelWithServices.tsx index 23e9841b0..5e6ba0074 100644 --- a/extensions/default/src/Components/SidePanelWithServices.tsx +++ b/extensions/default/src/Components/SidePanelWithServices.tsx @@ -8,6 +8,7 @@ export type SidePanelWithServicesProps = { className: string; activeTabIndex: number; tabs: any; + expandedWidth?: number; }; const SidePanelWithServices = ({ @@ -16,7 +17,8 @@ const SidePanelWithServices = ({ className, activeTabIndex: activeTabIndexProp, tabs, -}) => { + expandedWidth, +}: SidePanelWithServicesProps) => { const panelService: PanelService = servicesManager?.services?.panelService; // Tracks whether this SidePanel has been opened at least once since this SidePanel was inserted into the DOM. @@ -53,6 +55,7 @@ const SidePanelWithServices = ({ onOpen={() => { setHasBeenOpened(true); }} + expandedWidth={expandedWidth} > ); }; diff --git a/platform/ui/src/components/SidePanel/SidePanel.tsx b/platform/ui/src/components/SidePanel/SidePanel.tsx index 4e25615cc..030c802b4 100644 --- a/platform/ui/src/components/SidePanel/SidePanel.tsx +++ b/platform/ui/src/components/SidePanel/SidePanel.tsx @@ -1,39 +1,26 @@ import classnames from 'classnames'; import PropTypes from 'prop-types'; import React, { CSSProperties, useCallback, useEffect, useState } from 'react'; +import { useTranslation } from 'react-i18next'; import Icon from '../Icon'; import Tooltip from '../Tooltip'; +type StyleMap = { + open: { + left: { marginLeft: string }; + right: { marginRight: string }; + }; + closed: { + left: { marginLeft: string }; + right: { marginRight: string }; + }; +}; const borderSize = 4; -const expandedWidth = 248; const collapsedWidth = 25; const closeIconWidth = 30; const gridHorizontalPadding = 10; const tabSpacerWidth = 2; -const gridAvailableWidth = expandedWidth - closeIconWidth - gridHorizontalPadding; - -const baseStyle = { - maxWidth: `${expandedWidth}px`, - width: `${expandedWidth}px`, - // To align the top of the side panel with the top of the viewport grid, use position relative and offset the - // top by the same top offset as the viewport grid. Also adjust the height so that there is no overflow. - position: 'relative', - top: '0.2%', - height: '99.8%', -}; - -const collapsedHideWidth = expandedWidth - collapsedWidth - borderSize; -const styleMap = { - open: { - left: { marginLeft: '0px' }, - right: { marginRight: '0px' }, - }, - closed: { - left: { marginLeft: `-${collapsedHideWidth}px` }, - right: { marginRight: `-${collapsedHideWidth}px` }, - }, -}; const baseClasses = 'transition-all duration-300 ease-in-out bg-black border-black justify-start box-content flex flex-col'; @@ -62,7 +49,7 @@ const getTabWidth = (numTabs: number) => { } }; -const getGridWidth = (numTabs: number) => { +const getGridWidth = (numTabs: number, gridAvailableWidth: number) => { const spacersWidth = (numTabs - 1) * tabSpacerWidth; const tabsWidth = getTabWidth(numTabs) * numTabs; @@ -73,14 +60,13 @@ const getGridWidth = (numTabs: number) => { return gridAvailableWidth; }; -const getNumGridColumns = (numTabs: number) => { +const getNumGridColumns = (numTabs: number, gridWidth: number) => { if (numTabs === 1) { return 1; } // Start by calculating the number of tabs assuming each tab was accompanied by a spacer. const tabWidth = getTabWidth(numTabs); - const gridWidth = getGridWidth(numTabs); const numTabsWithOneSpacerEach = Math.floor(gridWidth / (tabWidth + tabSpacerWidth)); // But there is always one less spacer than tabs, so now check if an extra tab with one less spacer fits. @@ -94,8 +80,12 @@ const getNumGridColumns = (numTabs: number) => { return numTabsWithOneSpacerEach; }; -const getGridStyle = (side: string, numTabs: number = 0): CSSProperties => { - const gridWidth = getGridWidth(numTabs); +const getGridStyle = ( + side: string, + numTabs: number = 0, + gridWidth: number, + expandedWidth: number +): CSSProperties => { const relativePosition = Math.max(0, Math.floor(expandedWidth - gridWidth) / 2 - closeIconWidth); return { position: 'relative', @@ -128,11 +118,53 @@ const getTabIconClassNames = (numTabs: number, isActiveTab: boolean) => { rounded: isActiveTab, }); }; +const createStyleMap = ( + expandedWidth: number, + borderSize: number, + collapsedWidth: number +): StyleMap => { + const collapsedHideWidth = expandedWidth - collapsedWidth - borderSize; + + return { + open: { + left: { marginLeft: '0px' }, + right: { marginRight: '0px' }, + }, + closed: { + left: { marginLeft: `-${collapsedHideWidth}px` }, + right: { marginRight: `-${collapsedHideWidth}px` }, + }, + }; +}; + +const createBaseStyle = (expandedWidth: number) => { + return { + maxWidth: `${expandedWidth}px`, + width: `${expandedWidth}px`, + // To align the top of the side panel with the top of the viewport grid, use position relative and offset the + // top by the same top offset as the viewport grid. Also adjust the height so that there is no overflow. + position: 'relative', + top: '0.2%', + height: '99.8%', + }; +}; +const SidePanel = ({ + side, + className, + activeTabIndex: activeTabIndexProp, + tabs, + onOpen, + expandedWidth = 248, +}) => { + const { t } = useTranslation('SidePanel'); -const SidePanel = ({ side, className, activeTabIndex: activeTabIndexProp, tabs, onOpen }) => { const [panelOpen, setPanelOpen] = useState(activeTabIndexProp !== null); const [activeTabIndex, setActiveTabIndex] = useState(0); + const styleMap = createStyleMap(expandedWidth, borderSize, collapsedWidth); + const baseStyle = createBaseStyle(expandedWidth); + const gridAvailableWidth = expandedWidth - closeIconWidth - gridHorizontalPadding; + const gridWidth = getGridWidth(tabs.length, gridAvailableWidth); const openStatus = panelOpen ? 'open' : 'closed'; const style = Object.assign({}, styleMap[openStatus][side], baseStyle); @@ -238,13 +270,13 @@ const SidePanel = ({ side, className, activeTabIndex: activeTabIndexProp, tabs, }; const getTabGridComponent = () => { - const numCols = getNumGridColumns(tabs.length); + const numCols = getNumGridColumns(tabs.length, gridWidth); return (