diff --git a/flow-typed/npm/@box/blueprint-web-assets_vx.x.x.js b/flow-typed/npm/@box/blueprint-web-assets_vx.x.x.js index e2a1e28542..f560a35465 100644 --- a/flow-typed/npm/@box/blueprint-web-assets_vx.x.x.js +++ b/flow-typed/npm/@box/blueprint-web-assets_vx.x.x.js @@ -9,6 +9,10 @@ declare module '@box/blueprint-web-assets/icons/Medium' { declare export var XMark: React$ComponentType; declare export var Comment: React$ComponentType; declare export var Metadata: React$ComponentType; + declare export var ChevronDown: React$ComponentType; + declare export var ChevronUp: React$ComponentType; + declare export var RightSidebarChevronClose: React$ComponentType; + declare export var RightSidebarChevronOpen: React$ComponentType; } declare module '@box/blueprint-web-assets/icons/MediumFilled' { diff --git a/package.json b/package.json index 2afbb97e10..32c4dfda9f 100644 --- a/package.json +++ b/package.json @@ -125,7 +125,7 @@ "@babel/template": "^7.24.7", "@babel/types": "^7.24.7", "@box/blueprint-web": "^12.98.0", - "@box/blueprint-web-assets": "^4.80.4", + "@box/blueprint-web-assets": "4.88.2", "@box/box-ai-agent-selector": "^0.53.0", "@box/box-ai-content-answers": "^0.139.0", "@box/box-item-type-selector": "^0.73.1", @@ -297,7 +297,7 @@ }, "peerDependencies": { "@box/blueprint-web": "^12.98.0", - "@box/blueprint-web-assets": "^4.80.4", + "@box/blueprint-web-assets": "4.88.2", "@box/box-ai-agent-selector": "^0.53.0", "@box/box-ai-content-answers": "^0.139.0", "@box/box-item-type-selector": "^0.73.1", diff --git a/src/components/sidebar-toggle-button/SidebarToggleButton.js b/src/components/sidebar-toggle-button/SidebarToggleButton.js index c62760b738..ebf4b3afea 100644 --- a/src/components/sidebar-toggle-button/SidebarToggleButton.js +++ b/src/components/sidebar-toggle-button/SidebarToggleButton.js @@ -3,7 +3,15 @@ import * as React from 'react'; import classNames from 'classnames'; import { injectIntl } from 'react-intl'; import type { IntlShape } from 'react-intl'; -import { Tooltip as BPTooltip } from '@box/blueprint-web'; + +import { IconButton, Tooltip as BPTooltip, useBreakpoint, Breakpoint } from '@box/blueprint-web'; +import { + ChevronDown, + ChevronUp, + RightSidebarChevronClose, + RightSidebarChevronOpen, +} from '@box/blueprint-web-assets/icons/Medium'; + import IconHide from '../../icons/general/IconHide'; import IconShow from '../../icons/general/IconShow'; import PlainButton from '../plain-button'; @@ -32,21 +40,20 @@ const SidebarToggleButton = ({ onClick, ...rest }: Props) => { + const breakpoint = useBreakpoint(); const { enabled: isPreviewModernizationEnabled } = useFeatureConfig('previewModernization'); + const isCollapsed = !isOpen ? 'collapsed' : ''; const intlMessage = isOpen ? messages.sidebarHide : messages.sidebarShow; const intlText = intl.formatMessage(intlMessage); - const classes = classNames(className, 'bdl-SidebarToggleButton', { + const classes = classNames(className, { 'bdl-is-collapsed': isCollapsed, + 'bdl-SidebarToggleButton': !isPreviewModernizationEnabled, 'bdl-SidebarToggleButton--modernized': isPreviewModernizationEnabled, }); - const tooltipPosition = direction === DIRECTION_LEFT ? 'middle-right' : 'middle-left'; - const renderButton = () => { - if (direction === DIRECTION_LEFT) { - return isOpen ? : ; - } - return isOpen ? : ; - }; + + const isDirectionLeft = direction === DIRECTION_LEFT; + const tooltipPosition = isDirectionLeft ? 'middle-right' : 'middle-left'; // Adding this to stop the mousedown event from being propagated up to box-annotations as // that will cause the active annotation to no longer be active which means that it will not be displayed. @@ -56,26 +63,43 @@ const SidebarToggleButton = ({ }; if (isPreviewModernizationEnabled) { - const tooltipPositionModernized = direction === DIRECTION_LEFT ? DIRECTION_RIGHT : DIRECTION_LEFT; + const isBelowMediumView = breakpoint <= Breakpoint.Medium; + const tooltipPositionModernized = isDirectionLeft ? DIRECTION_RIGHT : DIRECTION_LEFT; + + const renderModernizedIcon = () => { + if (isBelowMediumView) { + return isOpen ? ChevronDown : ChevronUp; + } + + if (isDirectionLeft) { + return isOpen ? RightSidebarChevronOpen : RightSidebarChevronClose; + } + + return isOpen ? RightSidebarChevronClose : RightSidebarChevronOpen; + }; return ( - {/* Workaround to attach BP tooltip to legacy button, remove span when buttons are migrated to BP */} - - - {renderButton()} - - + ); } + + const renderIcon = () => { + if (isDirectionLeft) { + return isOpen ? : ; + } + return isOpen ? : ; + }; + return ( - {renderButton()} + {renderIcon()} ); diff --git a/src/components/sidebar-toggle-button/SidebarToggleButton.scss b/src/components/sidebar-toggle-button/SidebarToggleButton.scss index f62b6a3d1a..0b940965ce 100644 --- a/src/components/sidebar-toggle-button/SidebarToggleButton.scss +++ b/src/components/sidebar-toggle-button/SidebarToggleButton.scss @@ -30,14 +30,16 @@ } } +.bdl-SidebarToggleButton--modernized { + // See: src/elements/content-sidebar/ContentSidebar.scss + // Establish a stacking context so the button appears above other positioned elements + // within ContentSidebar's z-index: 5 stacking context, preventing it from being blocked. + position: relative; +} + .bcs-SidebarNav--modernized { - .bdl-SidebarToggleButton { - &:not(.bdl-is-disabled):hover svg, - &:not(.is-disabled):hover svg, - &:not(.bdl-is-disabled):focus svg, - &:not(.is-disabled):focus svg, - &.bdl-is-collapsed svg, - &.bdl-is-collapsed:hover svg { + .bdl-SidebarToggleButton--modernized { + &:hover svg { transform: scale(1.09); transition: transform 150ms; } diff --git a/src/components/sidebar-toggle-button/__tests__/SidebarToggleButton.test.js b/src/components/sidebar-toggle-button/__tests__/SidebarToggleButton.test.js index e00f10abbd..50be15accd 100644 --- a/src/components/sidebar-toggle-button/__tests__/SidebarToggleButton.test.js +++ b/src/components/sidebar-toggle-button/__tests__/SidebarToggleButton.test.js @@ -65,9 +65,15 @@ describe('components/sidebar-toggle-button/SidebarToggleButton', () => { wrapperProps: { features: { previewModernization: { enabled: isPreviewModernizationEnabled } } }, }); const button = screen.getByRole('button'); - expect(button).toHaveClass('bdl-SidebarToggleButton'); - const isModernized = button.classList.contains('bdl-SidebarToggleButton--modernized'); - expect(isModernized).toBe(isPreviewModernizationEnabled); + + if (isPreviewModernizationEnabled) { + expect(button).toHaveClass('bdl-SidebarToggleButton--modernized'); + expect(button).not.toHaveClass('bdl-SidebarToggleButton'); + } else { + expect(button).toHaveClass('bdl-SidebarToggleButton'); + expect(button).not.toHaveClass('bdl-SidebarToggleButton--modernized'); + } + fireEvent.click(button); expect(onClick).toHaveBeenCalled(); }, diff --git a/yarn.lock b/yarn.lock index 6f2fc0d78c..1482dc8da2 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1419,7 +1419,12 @@ resolved "https://registry.yarnpkg.com/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz#75a2e8b51cb758a7553d6804a5932d7aace75c39" integrity sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw== -"@box/blueprint-web-assets@^4.80.0", "@box/blueprint-web-assets@^4.80.4": +"@box/blueprint-web-assets@4.88.2": + version "4.88.2" + resolved "https://registry.yarnpkg.com/@box/blueprint-web-assets/-/blueprint-web-assets-4.88.2.tgz#cb98f14dcd5a072d7c97be31030485cf9219478e" + integrity sha512-TAtiYWvudxj3i5GAa4NsiHzlF9WcIARBbp1dCxgwsFP652NEamo/3SH2wyhcc/5u1bJJLftxe5xsTv6a7dpj0w== + +"@box/blueprint-web-assets@^4.80.0": version "4.80.4" resolved "https://registry.yarnpkg.com/@box/blueprint-web-assets/-/blueprint-web-assets-4.80.4.tgz#3db74e9c1006d2eb86ddc7e4caa23a4f0376cf92" integrity sha512-zXIUfIC+RgzpQkA6KtLi0M5gtbXjNO3orWPNsVaJgEbYjrKahC4AejL2j4/XNaxt7AO0Xvz6vRr1Zjn1Byu4YA== @@ -14400,7 +14405,7 @@ node-fetch@^2.6.12, node-fetch@^2.6.7: dependencies: whatwg-url "^5.0.0" -node-forge@1.3.2, node-forge@^1: +node-forge@^1: version "1.3.2" resolved "https://registry.yarnpkg.com/node-forge/-/node-forge-1.3.2.tgz#d0d2659a26eef778bf84d73e7f55c08144ee7750" integrity sha512-6xKiQ+cph9KImrRh0VsjH2d8/GXA4FIMlgU4B757iI1ApvcyA9VlouP0yZJha01V+huImO+kKMU7ih+2+E14fw==