mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-02-16 13:57:02 +08:00
remove some timer
This commit is contained in:
@@ -16,26 +16,28 @@ export const root = style({
|
||||
width: panelWidthVar,
|
||||
minWidth: panelWidthVar,
|
||||
height: '100%',
|
||||
zIndex: 4,
|
||||
transform: 'translateX(0)',
|
||||
maxWidth: '50%',
|
||||
selectors: {
|
||||
'&[data-is-floating="true"]': {
|
||||
position: 'absolute',
|
||||
width: `calc(${panelWidthVar})`,
|
||||
zIndex: 4,
|
||||
},
|
||||
'&[data-open="true"]': {
|
||||
maxWidth: '50%',
|
||||
},
|
||||
'&[data-open="false"][data-handle-position="right"]': {
|
||||
marginLeft: `calc(${panelWidthVar} * -1)`,
|
||||
},
|
||||
'&[data-open="false"][data-handle-position="left"]': {
|
||||
marginRight: `calc(${panelWidthVar} * -1)`,
|
||||
},
|
||||
'&[data-enable-animation="true"][data-is-floating="false"]': {
|
||||
transition: `margin-left ${animationTimeout} .05s, margin-right ${animationTimeout} .05s, width ${animationTimeout} .05s,background ${animationTimeout} .05s,scale ${animationTimeout} .05s`,
|
||||
},
|
||||
'&[data-enable-animation="true"][data-is-floating="true"]': {
|
||||
transition: 'margin-left 0.5s cubic-bezier(0.22,1,0.36,1)',
|
||||
'&[data-open="false"][data-handle-position="right"],&[data-is-floating="true"][data-handle-position="right"]':
|
||||
{
|
||||
marginLeft: `calc(${panelWidthVar} * -1)`,
|
||||
},
|
||||
'&[data-open="false"][data-handle-position="left"],&[data-is-floating="true"][data-handle-position="left"]':
|
||||
{
|
||||
marginRight: `calc(${panelWidthVar} * -1)`,
|
||||
},
|
||||
'&[data-open="true"][data-handle-position="right"][data-is-floating="true"]':
|
||||
{
|
||||
transform: `translateX(${panelWidthVar})`,
|
||||
},
|
||||
'&[data-open="true"][data-handle-position="left"][data-is-floating="true"]':
|
||||
{
|
||||
transform: `translateX(-${panelWidthVar})`,
|
||||
},
|
||||
'&[data-enable-animation="true"]': {
|
||||
transition: `margin-left ${animationTimeout}, margin-right ${animationTimeout}, transform ${animationTimeout}, background ${animationTimeout}`,
|
||||
},
|
||||
'&[data-transition-state="exited"]': {
|
||||
// avoid focus on hidden panel
|
||||
|
||||
@@ -1,13 +1,6 @@
|
||||
import { assignInlineVars } from '@vanilla-extract/dynamic';
|
||||
import clsx from 'clsx';
|
||||
import {
|
||||
forwardRef,
|
||||
useCallback,
|
||||
useEffect,
|
||||
useLayoutEffect,
|
||||
useRef,
|
||||
useState,
|
||||
} from 'react';
|
||||
import { forwardRef, useCallback, useLayoutEffect, useRef } from 'react';
|
||||
import { useTransition } from 'react-transition-state';
|
||||
|
||||
import * as styles from './resize-panel.css';
|
||||
@@ -129,17 +122,6 @@ const ResizeHandle = ({
|
||||
);
|
||||
};
|
||||
|
||||
// delay initial animation to avoid flickering
|
||||
function useEnableAnimation() {
|
||||
const [enable, setEnable] = useState(false);
|
||||
useEffect(() => {
|
||||
window.setTimeout(() => {
|
||||
setEnable(true);
|
||||
}, 500);
|
||||
}, []);
|
||||
return enable;
|
||||
}
|
||||
|
||||
const animationTimeout = 300;
|
||||
|
||||
export const ResizePanel = forwardRef<HTMLDivElement, ResizePanelProps>(
|
||||
@@ -152,7 +134,7 @@ export const ResizePanel = forwardRef<HTMLDivElement, ResizePanelProps>(
|
||||
maxWidth,
|
||||
width,
|
||||
floating,
|
||||
enableAnimation: _enableAnimation = true,
|
||||
enableAnimation = true,
|
||||
open,
|
||||
unmountOnExit,
|
||||
onOpen,
|
||||
@@ -165,7 +147,6 @@ export const ResizePanel = forwardRef<HTMLDivElement, ResizePanelProps>(
|
||||
},
|
||||
ref
|
||||
) {
|
||||
const enableAnimation = useEnableAnimation() && _enableAnimation;
|
||||
const safeWidth = Math.min(maxWidth, Math.max(minWidth, width));
|
||||
const [{ status }, toggle] = useTransition({
|
||||
timeout: animationTimeout,
|
||||
|
||||
@@ -185,7 +185,7 @@ const DesktopLayout = ({ children }: PropsWithChildren) => {
|
||||
<AppTabsHeader
|
||||
left={
|
||||
<>
|
||||
<SidebarSwitch show enableOpenHoverSidebar />
|
||||
<SidebarSwitch show />
|
||||
<NavigationButtons />
|
||||
</>
|
||||
}
|
||||
|
||||
@@ -18,15 +18,8 @@ interface HeaderPros {
|
||||
export const Header = ({ left, center, right }: HeaderPros) => {
|
||||
const appSidebarService = useService(AppSidebarService).sidebar;
|
||||
const open = useLiveData(appSidebarService.open$);
|
||||
const appSidebarFloating = useLiveData(appSidebarService.responsiveFloating$);
|
||||
const hoverFloating = useLiveData(appSidebarService.hoverFloating$);
|
||||
return (
|
||||
<div
|
||||
className={clsx(style.header)}
|
||||
data-open={open}
|
||||
data-sidebar-floating={appSidebarFloating || hoverFloating}
|
||||
data-testid="header"
|
||||
>
|
||||
<div className={clsx(style.header)} data-open={open} data-testid="header">
|
||||
<div className={clsx(style.headerSideContainer)}>
|
||||
<div className={clsx(style.headerItem, 'left')}>
|
||||
<div>{left}</div>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { cssVar, lightCssVariables } from '@toeverything/theme';
|
||||
import { createVar, globalStyle, keyframes, style } from '@vanilla-extract/css';
|
||||
import { createVar, globalStyle, style } from '@vanilla-extract/css';
|
||||
|
||||
export const panelWidthVar = createVar('panel-width');
|
||||
|
||||
@@ -42,19 +42,7 @@ globalStyle(`html[data-theme="dark"] ${appStyle}`, {
|
||||
},
|
||||
});
|
||||
|
||||
const anime = keyframes({
|
||||
'0%': {
|
||||
marginLeft: '8px',
|
||||
},
|
||||
'100%': {
|
||||
marginLeft: '0',
|
||||
},
|
||||
});
|
||||
|
||||
export const mainContainerStyle = style({
|
||||
vars: {
|
||||
[panelWidthVar]: '256px',
|
||||
},
|
||||
position: 'relative',
|
||||
zIndex: 0,
|
||||
width: '100%',
|
||||
@@ -76,14 +64,6 @@ export const mainContainerStyle = style({
|
||||
},
|
||||
},
|
||||
},
|
||||
'&[data-side-bar-open="true"][data-show-pin-sidebar-animation="true"]': {
|
||||
marginLeft: panelWidthVar,
|
||||
transition: 'margin-left 0.5s ease-in-out',
|
||||
},
|
||||
'&[data-client-border="true"][data-side-bar-open="true"][data-side-bar-floating="false"]':
|
||||
{
|
||||
animation: `${anime} 0.5s ease-in-out forwards`,
|
||||
},
|
||||
'&[data-client-border="true"][data-is-desktop="true"]': {
|
||||
marginTop: 0,
|
||||
},
|
||||
|
||||
@@ -1,22 +1,15 @@
|
||||
import { useAppSettingHelper } from '@affine/core/components/hooks/affine/use-app-setting-helper';
|
||||
import { AppSidebarService } from '@affine/core/modules/app-sidebar';
|
||||
import {
|
||||
DocsService,
|
||||
GlobalContextService,
|
||||
useLiveData,
|
||||
useService,
|
||||
} from '@toeverything/infra';
|
||||
import { assignInlineVars } from '@vanilla-extract/dynamic';
|
||||
import { clsx } from 'clsx';
|
||||
import type { HTMLAttributes, PropsWithChildren, ReactElement } from 'react';
|
||||
import { forwardRef, useMemo } from 'react';
|
||||
import { forwardRef } from 'react';
|
||||
|
||||
import {
|
||||
appStyle,
|
||||
mainContainerStyle,
|
||||
panelWidthVar,
|
||||
toolStyle,
|
||||
} from './index.css';
|
||||
import { appStyle, mainContainerStyle, toolStyle } from './index.css';
|
||||
|
||||
export type WorkspaceRootProps = PropsWithChildren<{
|
||||
className?: string;
|
||||
@@ -54,41 +47,16 @@ export interface MainContainerProps extends HTMLAttributes<HTMLDivElement> {}
|
||||
export const MainContainer = forwardRef<
|
||||
HTMLDivElement,
|
||||
PropsWithChildren<MainContainerProps>
|
||||
>(function MainContainer(
|
||||
{ className, children, style, ...props },
|
||||
ref
|
||||
): ReactElement {
|
||||
const appSidebarService = useService(AppSidebarService).sidebar;
|
||||
const appSideBarOpen = useLiveData(appSidebarService.open$);
|
||||
const appSidebarHoverFloating = useLiveData(appSidebarService.hoverFloating$);
|
||||
const appSideBarWidth = useLiveData(appSidebarService.width$);
|
||||
|
||||
const showAppSideBarPinAnimation = useLiveData(
|
||||
appSidebarService.showFloatToPinAnimation$
|
||||
);
|
||||
>(function MainContainer({ className, children, ...props }, ref): ReactElement {
|
||||
const { appSettings } = useAppSettingHelper();
|
||||
|
||||
const combinedStyle = useMemo(() => {
|
||||
const dynamicStyle = assignInlineVars({
|
||||
[panelWidthVar]: `${appSideBarWidth}px`,
|
||||
});
|
||||
return {
|
||||
...style,
|
||||
...dynamicStyle,
|
||||
};
|
||||
}, [appSideBarWidth, style]);
|
||||
|
||||
return (
|
||||
<div
|
||||
{...props}
|
||||
style={combinedStyle}
|
||||
className={clsx(mainContainerStyle, className)}
|
||||
data-is-desktop={BUILD_CONFIG.isElectron}
|
||||
data-transparent={false}
|
||||
data-client-border={appSettings.clientBorder}
|
||||
data-side-bar-open={appSideBarOpen}
|
||||
data-side-bar-floating={appSidebarHoverFloating}
|
||||
data-show-pin-sidebar-animation={showAppSideBarPinAnimation}
|
||||
data-testid="main-container"
|
||||
ref={ref}
|
||||
>
|
||||
|
||||
@@ -3,8 +3,6 @@ import { map } from 'rxjs';
|
||||
|
||||
import type { AppSidebarState } from '../providers/storage';
|
||||
|
||||
const isMobile = !BUILD_CONFIG.isElectron && window.innerWidth < 768;
|
||||
|
||||
enum APP_SIDEBAR_STATE {
|
||||
OPEN = 'open',
|
||||
WIDTH = 'width',
|
||||
@@ -15,11 +13,15 @@ export class AppSidebar extends Entity {
|
||||
super();
|
||||
}
|
||||
|
||||
/**
|
||||
* whether the sidebar is open,
|
||||
* even if the sidebar is not open, hovering can show the floating sidebar
|
||||
*/
|
||||
open$ = LiveData.from(
|
||||
this.appSidebarState
|
||||
.watch<boolean>(APP_SIDEBAR_STATE.OPEN)
|
||||
.pipe(map(value => value ?? !isMobile)),
|
||||
!isMobile
|
||||
.pipe(map(value => value ?? true)),
|
||||
true
|
||||
);
|
||||
|
||||
width$ = LiveData.from(
|
||||
@@ -28,11 +30,17 @@ export class AppSidebar extends Entity {
|
||||
.pipe(map(value => value ?? 248)),
|
||||
248
|
||||
);
|
||||
responsiveFloating$ = new LiveData<boolean>(isMobile);
|
||||
hoverFloating$ = new LiveData<boolean>(false);
|
||||
resizing$ = new LiveData<boolean>(false);
|
||||
|
||||
showFloatToPinAnimation$ = new LiveData<boolean>(false);
|
||||
/**
|
||||
* hovering can show the floating sidebar, without open it
|
||||
*/
|
||||
hovering$ = new LiveData<boolean>(false);
|
||||
|
||||
/**
|
||||
* small screen mode, will disable hover effect
|
||||
*/
|
||||
smallScreenMode$ = new LiveData<boolean>(false);
|
||||
resizing$ = new LiveData<boolean>(false);
|
||||
|
||||
getCachedAppSidebarOpenState = () => {
|
||||
return this.appSidebarState.get<boolean>(APP_SIDEBAR_STATE.OPEN);
|
||||
@@ -44,26 +52,15 @@ export class AppSidebar extends Entity {
|
||||
|
||||
setOpen = (open: boolean) => {
|
||||
this.appSidebarState.set(APP_SIDEBAR_STATE.OPEN, open);
|
||||
if (!open && this.hoverFloating$.value) {
|
||||
const timeout = setTimeout(() => {
|
||||
this.setHoverFloating(false);
|
||||
}, 500);
|
||||
return () => {
|
||||
clearTimeout(timeout);
|
||||
};
|
||||
}
|
||||
return;
|
||||
};
|
||||
|
||||
setResponsiveFloating = (floating: boolean) => {
|
||||
this.responsiveFloating$.next(floating);
|
||||
setSmallScreenMode = (smallScreenMode: boolean) => {
|
||||
this.smallScreenMode$.next(smallScreenMode);
|
||||
};
|
||||
|
||||
setHoverFloating = (hoverFloating: boolean) => {
|
||||
if (hoverFloating) {
|
||||
this.showFloatToPinAnimation$.next(false);
|
||||
}
|
||||
this.hoverFloating$.next(hoverFloating);
|
||||
setHovering = (hoverFloating: boolean) => {
|
||||
this.hovering$.next(hoverFloating);
|
||||
};
|
||||
|
||||
setResizing = (resizing: boolean) => {
|
||||
@@ -73,8 +70,4 @@ export class AppSidebar extends Entity {
|
||||
setWidth = (width: number) => {
|
||||
this.appSidebarState.set(APP_SIDEBAR_STATE.WIDTH, width);
|
||||
};
|
||||
|
||||
setShowFloatToPinAnimation = (show: boolean) => {
|
||||
this.showFloatToPinAnimation$.next(show);
|
||||
};
|
||||
}
|
||||
|
||||
@@ -31,9 +31,6 @@ export const hoverNavWrapperStyle = style({
|
||||
boxShadow: cssVar('--affine-popover-shadow'),
|
||||
borderRadius: '6px',
|
||||
},
|
||||
'&[data-is-floating="true"][data-show-pin-animation="true"]': {
|
||||
marginLeft: '0',
|
||||
},
|
||||
'&[data-is-floating="true"][data-is-electron="true"]': {
|
||||
height: '100%',
|
||||
marginTop: '-4px',
|
||||
|
||||
@@ -12,7 +12,7 @@ import {
|
||||
import clsx from 'clsx';
|
||||
import { debounce } from 'lodash-es';
|
||||
import type { PropsWithChildren, ReactElement } from 'react';
|
||||
import { useCallback, useContext, useEffect, useMemo, useRef } from 'react';
|
||||
import { useCallback, useContext, useEffect, useMemo, useState } from 'react';
|
||||
|
||||
import { AppSidebarService } from '../services/app-sidebar';
|
||||
import * as styles from './fallback.css';
|
||||
@@ -45,21 +45,45 @@ export function AppSidebar({ children }: PropsWithChildren) {
|
||||
|
||||
const open = useLiveData(appSidebarService.open$);
|
||||
const width = useLiveData(appSidebarService.width$);
|
||||
const responsiveFloating = useLiveData(appSidebarService.responsiveFloating$);
|
||||
const hoverFloating = useLiveData(appSidebarService.hoverFloating$);
|
||||
const smallScreenMode = useLiveData(appSidebarService.smallScreenMode$);
|
||||
const hovering = useLiveData(appSidebarService.hovering$) && open !== true;
|
||||
const resizing = useLiveData(appSidebarService.resizing$);
|
||||
const showFloatToPinAnimation = useLiveData(
|
||||
appSidebarService.showFloatToPinAnimation$
|
||||
);
|
||||
|
||||
const timeoutRef = useRef<NodeJS.Timeout | null>(null);
|
||||
|
||||
const clearExistingTimeout = useCallback(() => {
|
||||
if (timeoutRef.current) {
|
||||
clearTimeout(timeoutRef.current);
|
||||
timeoutRef.current = null;
|
||||
const [deferredHovering, setDeferredHovering] = useState(false);
|
||||
useEffect(() => {
|
||||
if (open) {
|
||||
// if open, we don't need to show the floating sidebar
|
||||
setDeferredHovering(false);
|
||||
return;
|
||||
}
|
||||
}, []);
|
||||
if (hovering) {
|
||||
// if hovering is true, we make a little delay here.
|
||||
// this allow the sidebar close animation to complete.
|
||||
const timeout = setTimeout(() => {
|
||||
setDeferredHovering(hovering);
|
||||
}, 150);
|
||||
return () => {
|
||||
clearTimeout(timeout);
|
||||
};
|
||||
} else {
|
||||
// if hovering is false, we set the deferred value after 1000ms
|
||||
const timeout = setTimeout(() => {
|
||||
setDeferredHovering(hovering);
|
||||
}, 1000);
|
||||
return () => {
|
||||
clearTimeout(timeout);
|
||||
};
|
||||
}
|
||||
}, [hovering, open]);
|
||||
|
||||
const sidebarState = smallScreenMode
|
||||
? open
|
||||
? 'floating-with-mask'
|
||||
: 'close'
|
||||
: open
|
||||
? 'open'
|
||||
: deferredHovering
|
||||
? 'floating'
|
||||
: 'close';
|
||||
|
||||
useEffect(() => {
|
||||
// do not float app sidebar on desktop
|
||||
@@ -71,19 +95,8 @@ export function AppSidebar({ children }: PropsWithChildren) {
|
||||
const isFloatingMaxWidth = window.matchMedia(
|
||||
`(max-width: ${floatingMaxWidth}px)`
|
||||
).matches;
|
||||
const isOverflowWidth = window.matchMedia(
|
||||
`(max-width: ${width / 0.4}px)`
|
||||
).matches;
|
||||
const isFloating = isFloatingMaxWidth || isOverflowWidth;
|
||||
if (
|
||||
open === undefined &&
|
||||
appSidebarService.getCachedAppSidebarOpenState() === undefined
|
||||
) {
|
||||
// give the initial value,
|
||||
// so that the sidebar can be closed on mobile by default
|
||||
appSidebarService.setOpen(!isFloating);
|
||||
}
|
||||
appSidebarService.setResponsiveFloating(isFloating);
|
||||
const isFloating = isFloatingMaxWidth;
|
||||
appSidebarService.setSmallScreenMode(isFloating);
|
||||
}
|
||||
|
||||
const dOnResize = debounce(onResize, 50);
|
||||
@@ -91,7 +104,7 @@ export function AppSidebar({ children }: PropsWithChildren) {
|
||||
return () => {
|
||||
window.removeEventListener('resize', dOnResize);
|
||||
};
|
||||
}, [appSidebarService, open, width]);
|
||||
}, [appSidebarService]);
|
||||
|
||||
const hasRightBorder = !BUILD_CONFIG.isElectron && !clientBorder;
|
||||
|
||||
@@ -121,34 +134,20 @@ export function AppSidebar({ children }: PropsWithChildren) {
|
||||
}, [appSidebarService]);
|
||||
|
||||
const onMouseEnter = useCallback(() => {
|
||||
if (!timeoutRef.current) {
|
||||
return;
|
||||
}
|
||||
clearExistingTimeout();
|
||||
}, [clearExistingTimeout]);
|
||||
appSidebarService.setHovering(true);
|
||||
}, [appSidebarService]);
|
||||
|
||||
const onMouseLeave = useCallback(() => {
|
||||
if (!hoverFloating) {
|
||||
clearExistingTimeout();
|
||||
return;
|
||||
}
|
||||
clearExistingTimeout();
|
||||
timeoutRef.current = setTimeout(() => {
|
||||
appSidebarService.setOpen(false);
|
||||
}, 1500);
|
||||
}, [hoverFloating, clearExistingTimeout, appSidebarService]);
|
||||
|
||||
useEffect(() => {
|
||||
return () => {
|
||||
clearExistingTimeout();
|
||||
};
|
||||
}, [clearExistingTimeout]);
|
||||
appSidebarService.setHovering(false);
|
||||
}, [appSidebarService]);
|
||||
|
||||
return (
|
||||
<>
|
||||
<ResizePanel
|
||||
floating={responsiveFloating || hoverFloating}
|
||||
open={open}
|
||||
floating={
|
||||
sidebarState === 'floating' || sidebarState === 'floating-with-mask'
|
||||
}
|
||||
open={sidebarState !== 'close'}
|
||||
resizing={resizing}
|
||||
maxWidth={MAX_WIDTH}
|
||||
minWidth={MIN_WIDTH}
|
||||
@@ -158,37 +157,36 @@ export function AppSidebar({ children }: PropsWithChildren) {
|
||||
onResizing={handleResizing}
|
||||
onWidthChange={handleWidthChange}
|
||||
className={clsx(navWrapperStyle, {
|
||||
[hoverNavWrapperStyle]: hoverFloating,
|
||||
[hoverNavWrapperStyle]: sidebarState === 'floating',
|
||||
})}
|
||||
resizeHandleOffset={0}
|
||||
resizeHandleVerticalPadding={clientBorder ? 16 : 0}
|
||||
onMouseEnter={onMouseEnter}
|
||||
onMouseLeave={onMouseLeave}
|
||||
data-transparent
|
||||
data-open={open}
|
||||
data-open={sidebarState !== 'close'}
|
||||
data-has-border={hasRightBorder}
|
||||
data-testid="app-sidebar-wrapper"
|
||||
data-is-macos-electron={isMacosDesktop}
|
||||
data-client-border={clientBorder}
|
||||
data-is-electron={BUILD_CONFIG.isElectron}
|
||||
data-show-pin-animation={showFloatToPinAnimation}
|
||||
>
|
||||
<nav className={navStyle} data-testid="app-sidebar">
|
||||
{!BUILD_CONFIG.isElectron && !hoverFloating && <SidebarHeader />}
|
||||
{!BUILD_CONFIG.isElectron && sidebarState !== 'floating' && (
|
||||
<SidebarHeader />
|
||||
)}
|
||||
<div className={navBodyStyle} data-testid="sliderBar-inner">
|
||||
{children}
|
||||
</div>
|
||||
</nav>
|
||||
</ResizePanel>
|
||||
{!hoverFloating && (
|
||||
<div
|
||||
data-testid="app-sidebar-float-mask"
|
||||
data-open={open}
|
||||
data-is-floating={responsiveFloating}
|
||||
className={sidebarFloatMaskStyle}
|
||||
onClick={handleClose}
|
||||
/>
|
||||
)}
|
||||
<div
|
||||
data-testid="app-sidebar-float-mask"
|
||||
data-open={open}
|
||||
data-is-floating={sidebarState === 'floating-with-mask'}
|
||||
className={sidebarFloatMaskStyle}
|
||||
onClick={handleClose}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -9,39 +9,26 @@ import * as styles from './sidebar-switch.css';
|
||||
|
||||
export const SidebarSwitch = ({
|
||||
show,
|
||||
enableOpenHoverSidebar,
|
||||
className,
|
||||
}: {
|
||||
show: boolean;
|
||||
enableOpenHoverSidebar?: boolean;
|
||||
className?: string;
|
||||
}) => {
|
||||
const appSidebarService = useService(AppSidebarService).sidebar;
|
||||
const open = useLiveData(appSidebarService.open$);
|
||||
const hoverFloating = useLiveData(appSidebarService.hoverFloating$);
|
||||
const switchRef = useRef<HTMLDivElement>(null);
|
||||
|
||||
const handleMouseEnter = useCallback(() => {
|
||||
if (!enableOpenHoverSidebar || open) {
|
||||
return;
|
||||
}
|
||||
appSidebarService.setHoverFloating(true);
|
||||
appSidebarService.setOpen(true);
|
||||
}, [appSidebarService, enableOpenHoverSidebar, open]);
|
||||
appSidebarService.setHovering(true);
|
||||
}, [appSidebarService]);
|
||||
|
||||
const handleClickSwitch = useCallback(() => {
|
||||
if (open && hoverFloating) {
|
||||
appSidebarService.setShowFloatToPinAnimation(true);
|
||||
const timeout = setTimeout(() => {
|
||||
appSidebarService.setShowFloatToPinAnimation(false);
|
||||
appSidebarService.setHoverFloating(false);
|
||||
}, 500);
|
||||
return () => {
|
||||
clearTimeout(timeout);
|
||||
};
|
||||
}
|
||||
return appSidebarService.toggleSidebar();
|
||||
}, [appSidebarService, hoverFloating, open]);
|
||||
appSidebarService.toggleSidebar();
|
||||
}, [appSidebarService]);
|
||||
|
||||
const handleMouseLeave = useCallback(() => {
|
||||
appSidebarService.setHovering(false);
|
||||
}, [appSidebarService]);
|
||||
|
||||
const t = useI18n();
|
||||
const tooltipContent = open
|
||||
@@ -54,13 +41,13 @@ export const SidebarSwitch = ({
|
||||
data-show={show}
|
||||
className={styles.sidebarSwitchClip}
|
||||
data-testid={`app-sidebar-arrow-button-${open ? 'collapse' : 'expand'}`}
|
||||
data-enable-open-hover-sidebar={enableOpenHoverSidebar}
|
||||
onMouseEnter={handleMouseEnter}
|
||||
onMouseLeave={handleMouseLeave}
|
||||
>
|
||||
<IconButton
|
||||
tooltip={tooltipContent}
|
||||
tooltipShortcut={['$mod', '/']}
|
||||
tooltipOptions={{ side: open && !hoverFloating ? 'bottom' : 'right' }}
|
||||
tooltipOptions={{ side: open ? 'bottom' : 'right' }}
|
||||
className={className}
|
||||
size="24"
|
||||
style={{
|
||||
|
||||
@@ -26,7 +26,7 @@ export const SidebarContainer = ({
|
||||
|
||||
return (
|
||||
<div className={clsx(styles.sidebarContainerInner, className)} {...props}>
|
||||
<Header floating={false} onToggle={handleToggleOpen}>
|
||||
<Header onToggle={handleToggleOpen}>
|
||||
<SidebarHeaderSwitcher />
|
||||
</Header>
|
||||
{sidebarTabs.length > 0 ? (
|
||||
|
||||
@@ -4,7 +4,6 @@ import { RightSidebarIcon } from '@blocksuite/icons/rc';
|
||||
import * as styles from './sidebar-header.css';
|
||||
|
||||
export type HeaderProps = {
|
||||
floating: boolean;
|
||||
onToggle?: () => void;
|
||||
children?: React.ReactNode;
|
||||
};
|
||||
@@ -13,20 +12,13 @@ function Container({
|
||||
children,
|
||||
style,
|
||||
className,
|
||||
floating,
|
||||
}: {
|
||||
children: React.ReactNode;
|
||||
className?: string;
|
||||
style?: React.CSSProperties;
|
||||
floating?: boolean;
|
||||
}) {
|
||||
return (
|
||||
<div
|
||||
data-testid="header"
|
||||
style={style}
|
||||
className={className}
|
||||
data-sidebar-floating={floating}
|
||||
>
|
||||
<div data-testid="header" style={style} className={className}>
|
||||
{children}
|
||||
</div>
|
||||
);
|
||||
@@ -40,9 +32,9 @@ const ToggleButton = ({ onToggle }: { onToggle?: () => void }) => {
|
||||
);
|
||||
};
|
||||
|
||||
export const Header = ({ floating, children, onToggle }: HeaderProps) => {
|
||||
export const Header = ({ children, onToggle }: HeaderProps) => {
|
||||
return (
|
||||
<Container className={styles.header} floating={floating}>
|
||||
<Container className={styles.header}>
|
||||
{children}
|
||||
{!BUILD_CONFIG.isElectron && (
|
||||
<>
|
||||
|
||||
Reference in New Issue
Block a user