mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-02-12 04:18:54 +00:00
refactor(core): side bar resizing (#5280)
Rewrite sidebar panel using a customized react-resizable-panels version that supports sidebar pixel sizing (not using flex percentages). Now the left & right sidebar using the same `ResizePanel` impl. fix https://github.com/toeverything/AFFiNE/issues/5271 fix TOV-163 fix TOV-146 fix TOV-168 fix TOV-109 fix TOV-165
This commit is contained in:
@@ -1,21 +1,12 @@
|
||||
import { baseTheme } from '@toeverything/theme';
|
||||
import type { ComplexStyleRule } from '@vanilla-extract/css';
|
||||
import { createVar, style } from '@vanilla-extract/css';
|
||||
import { style } from '@vanilla-extract/css';
|
||||
|
||||
export const floatingMaxWidth = 768;
|
||||
export const navWidthVar = createVar('nav-width');
|
||||
|
||||
export const navWrapperStyle = style({
|
||||
vars: {
|
||||
[navWidthVar]: '256px',
|
||||
},
|
||||
position: 'relative',
|
||||
width: navWidthVar,
|
||||
minWidth: navWidthVar,
|
||||
height: '100%',
|
||||
zIndex: 3,
|
||||
paddingBottom: '8px',
|
||||
backgroundColor: 'transparent',
|
||||
backgroundColor: 'var(--affine-background-primary-color)',
|
||||
'@media': {
|
||||
print: {
|
||||
display: 'none',
|
||||
@@ -23,23 +14,7 @@ export const navWrapperStyle = style({
|
||||
},
|
||||
},
|
||||
selectors: {
|
||||
'&[data-is-floating="true"]': {
|
||||
position: 'absolute',
|
||||
width: `calc(${navWidthVar})`,
|
||||
zIndex: 4,
|
||||
backgroundColor: 'var(--affine-background-primary-color)',
|
||||
},
|
||||
'&[data-open="false"]': {
|
||||
marginLeft: `calc(${navWidthVar} * -1)`,
|
||||
},
|
||||
'&[data-enable-animation="true"]': {
|
||||
transition: 'margin-left .3s .05s, width .3s .05s',
|
||||
},
|
||||
'&[data-is-floating="false"].has-background': {
|
||||
backgroundColor: 'var(--affine-white-60)',
|
||||
borderRight: '1px solid var(--affine-border-color)',
|
||||
},
|
||||
'&.has-border': {
|
||||
'&[data-has-border=true]': {
|
||||
borderRight: '1px solid var(--affine-border-color)',
|
||||
},
|
||||
},
|
||||
@@ -63,7 +38,6 @@ export const navStyle = style({
|
||||
height: '100%',
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
zIndex: parseInt(baseTheme.zIndexModal),
|
||||
});
|
||||
|
||||
export const navHeaderStyle = style({
|
||||
|
||||
@@ -1,18 +1,16 @@
|
||||
import { assignInlineVars } from '@vanilla-extract/dynamic';
|
||||
import clsx from 'clsx';
|
||||
import { useAtom, useAtomValue } from 'jotai';
|
||||
import { debounce } from 'lodash-es';
|
||||
import type { PropsWithChildren, ReactElement } from 'react';
|
||||
import { useEffect, useRef, useState } from 'react';
|
||||
import { useEffect } from 'react';
|
||||
|
||||
import { Skeleton } from '../../ui/skeleton';
|
||||
import { ResizePanel } from '../resize-panel';
|
||||
import { fallbackHeaderStyle, fallbackStyle } from './fallback.css';
|
||||
import {
|
||||
floatingMaxWidth,
|
||||
navBodyStyle,
|
||||
navHeaderStyle,
|
||||
navStyle,
|
||||
navWidthVar,
|
||||
navWrapperStyle,
|
||||
sidebarFloatMaskStyle,
|
||||
} from './index.css';
|
||||
@@ -23,7 +21,6 @@ import {
|
||||
appSidebarResizingAtom,
|
||||
appSidebarWidthAtom,
|
||||
} from './index.jotai';
|
||||
import { ResizeIndicator } from './resize-indicator';
|
||||
import type { SidebarHeaderProps } from './sidebar-header';
|
||||
import { SidebarHeader } from './sidebar-header';
|
||||
|
||||
@@ -33,30 +30,19 @@ export type AppSidebarProps = PropsWithChildren<
|
||||
}
|
||||
>;
|
||||
|
||||
function useEnableAnimation() {
|
||||
const [enable, setEnable] = useState(false);
|
||||
useEffect(() => {
|
||||
window.setTimeout(() => {
|
||||
setEnable(true);
|
||||
}, 500);
|
||||
}, []);
|
||||
return enable;
|
||||
}
|
||||
|
||||
export type History = {
|
||||
stack: string[];
|
||||
current: number;
|
||||
};
|
||||
|
||||
const MAX_WIDTH = 480;
|
||||
const MIN_WIDTH = 256;
|
||||
|
||||
export function AppSidebar(props: AppSidebarProps): ReactElement {
|
||||
const [open, setOpen] = useAtom(appSidebarOpenAtom);
|
||||
const appSidebarWidth = useAtomValue(appSidebarWidthAtom);
|
||||
const [appSidebarFloating, setAppSidebarFloating] = useAtom(
|
||||
appSidebarFloatingAtom
|
||||
);
|
||||
|
||||
const isResizing = useAtomValue(appSidebarResizingAtom);
|
||||
const navRef = useRef<HTMLDivElement>(null);
|
||||
const [width, setWidth] = useAtom(appSidebarWidthAtom);
|
||||
const [floating, setFloating] = useAtom(appSidebarFloatingAtom);
|
||||
const [resizing, setResizing] = useAtom(appSidebarResizingAtom);
|
||||
|
||||
useEffect(() => {
|
||||
function onResize() {
|
||||
@@ -64,7 +50,7 @@ export function AppSidebar(props: AppSidebarProps): ReactElement {
|
||||
`(max-width: ${floatingMaxWidth}px)`
|
||||
).matches;
|
||||
const isOverflowWidth = window.matchMedia(
|
||||
`(max-width: ${appSidebarWidth / 0.4}px)`
|
||||
`(max-width: ${width / 0.4}px)`
|
||||
).matches;
|
||||
const isFloating = isFloatingMaxWidth || isOverflowWidth;
|
||||
if (
|
||||
@@ -75,7 +61,7 @@ export function AppSidebar(props: AppSidebarProps): ReactElement {
|
||||
// so that the sidebar can be closed on mobile by default
|
||||
setOpen(!isFloating);
|
||||
}
|
||||
setAppSidebarFloating(isFloating && !!open);
|
||||
setFloating(isFloating && !!open);
|
||||
}
|
||||
|
||||
const dOnResize = debounce(onResize, 50);
|
||||
@@ -83,33 +69,34 @@ export function AppSidebar(props: AppSidebarProps): ReactElement {
|
||||
return () => {
|
||||
window.removeEventListener('resize', dOnResize);
|
||||
};
|
||||
}, [appSidebarWidth, open, setAppSidebarFloating, setOpen]);
|
||||
|
||||
// disable animation to avoid UI flash
|
||||
const enableAnimation = useEnableAnimation();
|
||||
}, [open, setFloating, setOpen, width]);
|
||||
|
||||
const transparent = environment.isDesktop && !props.hasBackground;
|
||||
const isMacosDesktop = environment.isDesktop && environment.isMacOs;
|
||||
const hasRightBorder = !environment.isDesktop || !transparent;
|
||||
|
||||
return (
|
||||
<>
|
||||
<div
|
||||
style={assignInlineVars({
|
||||
[navWidthVar]: `${appSidebarWidth}px`,
|
||||
})}
|
||||
className={clsx(navWrapperStyle, {
|
||||
'has-background': environment.isDesktop && props.hasBackground,
|
||||
'has-border':
|
||||
!environment.isDesktop ||
|
||||
(environment.isDesktop && props.hasBackground),
|
||||
})}
|
||||
data-open={open}
|
||||
<ResizePanel
|
||||
floating={floating}
|
||||
open={open}
|
||||
resizing={resizing}
|
||||
maxWidth={MAX_WIDTH}
|
||||
minWidth={MIN_WIDTH}
|
||||
width={width}
|
||||
resizeHandlePos="right"
|
||||
onOpen={setOpen}
|
||||
onResizing={setResizing}
|
||||
onWidthChange={setWidth}
|
||||
className={navWrapperStyle}
|
||||
resizeHandleVerticalPadding={transparent ? 16 : 0}
|
||||
data-transparent={transparent}
|
||||
data-has-border={hasRightBorder}
|
||||
data-testid="app-sidebar-wrapper"
|
||||
data-is-macos-electron={isMacosDesktop}
|
||||
data-is-floating={appSidebarFloating}
|
||||
data-has-background={props.hasBackground}
|
||||
data-enable-animation={enableAnimation && !isResizing}
|
||||
data-has-background={environment.isDesktop && props.hasBackground}
|
||||
>
|
||||
<nav className={navStyle} ref={navRef} data-testid="app-sidebar">
|
||||
<nav className={navStyle} data-testid="app-sidebar">
|
||||
<SidebarHeader
|
||||
router={props.router}
|
||||
generalShortcutsInfo={props.generalShortcutsInfo}
|
||||
@@ -118,12 +105,11 @@ export function AppSidebar(props: AppSidebarProps): ReactElement {
|
||||
{props.children}
|
||||
</div>
|
||||
</nav>
|
||||
<ResizeIndicator targetElement={navRef.current} />
|
||||
</div>
|
||||
</ResizePanel>
|
||||
<div
|
||||
data-testid="app-sidebar-float-mask"
|
||||
data-open={open}
|
||||
data-is-floating={appSidebarFloating}
|
||||
data-is-floating={floating}
|
||||
className={sidebarFloatMaskStyle}
|
||||
onClick={() => setOpen(false)}
|
||||
/>
|
||||
@@ -132,15 +118,12 @@ export function AppSidebar(props: AppSidebarProps): ReactElement {
|
||||
}
|
||||
|
||||
export const AppSidebarFallback = (): ReactElement | null => {
|
||||
const appSidebarWidth = useAtomValue(appSidebarWidthAtom);
|
||||
const width = useAtomValue(appSidebarWidthAtom);
|
||||
return (
|
||||
<div
|
||||
style={assignInlineVars({
|
||||
[navWidthVar]: `${appSidebarWidth}px`,
|
||||
})}
|
||||
className={clsx(navWrapperStyle, {
|
||||
'has-border': true,
|
||||
})}
|
||||
style={{ width }}
|
||||
className={navWrapperStyle}
|
||||
data-has-border
|
||||
data-open="true"
|
||||
>
|
||||
<nav className={navStyle}>
|
||||
|
||||
@@ -1,45 +0,0 @@
|
||||
import { style } from '@vanilla-extract/css';
|
||||
|
||||
export const resizerContainer = style({
|
||||
position: 'absolute',
|
||||
right: 0,
|
||||
top: '16px',
|
||||
bottom: '16px',
|
||||
width: '16px',
|
||||
zIndex: 'calc(var(--affine-z-index-modal) + 1)',
|
||||
transform: 'translateX(50%)',
|
||||
backgroundColor: 'transparent',
|
||||
opacity: 0,
|
||||
cursor: 'col-resize',
|
||||
'@media': {
|
||||
'(max-width: 600px)': {
|
||||
// do not allow resizing on mobile
|
||||
display: 'none',
|
||||
},
|
||||
},
|
||||
transition: 'opacity 0.15s ease 0.1s',
|
||||
selectors: {
|
||||
'&:hover': {
|
||||
opacity: 1,
|
||||
},
|
||||
'&[data-resizing="true"]': {
|
||||
opacity: 1,
|
||||
transition: 'width .3s, min-width .3s, max-width .3s',
|
||||
},
|
||||
'&[data-open="false"]': {
|
||||
display: 'none',
|
||||
},
|
||||
'&[data-open="open"]': {
|
||||
display: 'block',
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
export const resizerInner = style({
|
||||
position: 'absolute',
|
||||
height: '100%',
|
||||
width: '4px',
|
||||
left: '6px',
|
||||
borderRadius: '4px',
|
||||
backgroundColor: 'var(--affine-primary-color)',
|
||||
});
|
||||
@@ -1,62 +0,0 @@
|
||||
import { assertExists } from '@blocksuite/global/utils';
|
||||
import { useAtom, useSetAtom } from 'jotai';
|
||||
import type { ReactElement } from 'react';
|
||||
import { useCallback } from 'react';
|
||||
|
||||
import {
|
||||
appSidebarOpenAtom,
|
||||
appSidebarResizingAtom,
|
||||
appSidebarWidthAtom,
|
||||
} from '../index.jotai';
|
||||
import * as styles from './index.css';
|
||||
|
||||
type ResizeIndicatorProps = {
|
||||
targetElement: HTMLElement | null;
|
||||
};
|
||||
|
||||
export const ResizeIndicator = (props: ResizeIndicatorProps): ReactElement => {
|
||||
const setWidth = useSetAtom(appSidebarWidthAtom);
|
||||
const [sidebarOpen, setSidebarOpen] = useAtom(appSidebarOpenAtom);
|
||||
const [isResizing, setIsResizing] = useAtom(appSidebarResizingAtom);
|
||||
|
||||
const onResizeStart = useCallback(() => {
|
||||
let resized = false;
|
||||
assertExists(props.targetElement);
|
||||
const { left: anchorLeft } = props.targetElement.getBoundingClientRect();
|
||||
|
||||
function onMouseMove(e: MouseEvent) {
|
||||
e.preventDefault();
|
||||
if (!props.targetElement) return;
|
||||
const newWidth = Math.min(480, Math.max(e.clientX - anchorLeft, 256));
|
||||
setWidth(newWidth);
|
||||
setIsResizing(true);
|
||||
resized = true;
|
||||
}
|
||||
|
||||
document.addEventListener('mousemove', onMouseMove);
|
||||
document.addEventListener(
|
||||
'mouseup',
|
||||
() => {
|
||||
// if not resized, toggle sidebar
|
||||
if (!resized) {
|
||||
setSidebarOpen(o => !o);
|
||||
}
|
||||
setIsResizing(false);
|
||||
document.removeEventListener('mousemove', onMouseMove);
|
||||
},
|
||||
{ once: true }
|
||||
);
|
||||
}, [props.targetElement, setIsResizing, setSidebarOpen, setWidth]);
|
||||
|
||||
return (
|
||||
<div
|
||||
className={styles.resizerContainer}
|
||||
data-testid="app-sidebar-resizer"
|
||||
data-resizing={isResizing}
|
||||
data-open={sidebarOpen}
|
||||
onMouseDown={onResizeStart}
|
||||
>
|
||||
<div className={styles.resizerInner} />
|
||||
</div>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1 @@
|
||||
export * from './resize-panel';
|
||||
@@ -0,0 +1,100 @@
|
||||
import { createVar, style } from '@vanilla-extract/css';
|
||||
|
||||
export const panelWidthVar = createVar('panel-width');
|
||||
export const resizeHandleOffsetVar = createVar('resize-handle-offset');
|
||||
export const resizeHandleVerticalPadding = createVar(
|
||||
'resize-handle-vertical-padding'
|
||||
);
|
||||
|
||||
export const root = style({
|
||||
vars: {
|
||||
[panelWidthVar]: '256px',
|
||||
[resizeHandleOffsetVar]: '0',
|
||||
},
|
||||
position: 'relative',
|
||||
width: panelWidthVar,
|
||||
minWidth: 0,
|
||||
height: '100%',
|
||||
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"]': {
|
||||
transition: 'margin-left .3s .05s, margin-right .3s .05s, width .3s .05s',
|
||||
},
|
||||
'&[data-is-floating="false"][data-transparent=true]': {
|
||||
backgroundColor: 'transparent',
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
export const panelContent = style({
|
||||
position: 'relative',
|
||||
height: '100%',
|
||||
overflow: 'auto',
|
||||
});
|
||||
|
||||
export const resizeHandleContainer = style({
|
||||
position: 'absolute',
|
||||
right: resizeHandleOffsetVar,
|
||||
top: resizeHandleVerticalPadding,
|
||||
bottom: resizeHandleVerticalPadding,
|
||||
width: 16,
|
||||
zIndex: '1',
|
||||
transform: 'translateX(50%)',
|
||||
backgroundColor: 'transparent',
|
||||
opacity: 0,
|
||||
display: 'flex',
|
||||
justifyContent: 'center',
|
||||
cursor: 'ew-resize',
|
||||
'@media': {
|
||||
'(max-width: 600px)': {
|
||||
// do not allow resizing on small screen
|
||||
display: 'none',
|
||||
},
|
||||
},
|
||||
transition: 'opacity 0.15s ease 0.1s',
|
||||
selectors: {
|
||||
'&[data-resizing="true"], &:hover': {
|
||||
opacity: 1,
|
||||
},
|
||||
'&[data-open="false"]': {
|
||||
display: 'none',
|
||||
},
|
||||
'&[data-open="open"]': {
|
||||
display: 'block',
|
||||
},
|
||||
'&[data-handle-position="left"]': {
|
||||
left: resizeHandleOffsetVar,
|
||||
right: 'auto',
|
||||
transform: 'translateX(-50%)',
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
export const resizerInner = style({
|
||||
position: 'absolute',
|
||||
height: '100%',
|
||||
width: '2px',
|
||||
borderRadius: '2px',
|
||||
backgroundColor: 'var(--affine-primary-color)',
|
||||
transition: 'all 0.2s ease-in-out',
|
||||
transform: 'translateX(0.5px)',
|
||||
selectors: {
|
||||
[`${resizeHandleContainer}[data-resizing="true"] &`]: {
|
||||
width: '4px',
|
||||
borderRadius: '4px',
|
||||
},
|
||||
},
|
||||
});
|
||||
@@ -0,0 +1,181 @@
|
||||
import { assertExists } from '@blocksuite/global/utils';
|
||||
import { assignInlineVars } from '@vanilla-extract/dynamic';
|
||||
import clsx from 'clsx';
|
||||
import { forwardRef, useCallback, useEffect, useRef, useState } from 'react';
|
||||
|
||||
import * as styles from './resize-panel.css';
|
||||
|
||||
export interface ResizeHandleProps
|
||||
extends React.HtmlHTMLAttributes<HTMLDivElement> {
|
||||
resizing: boolean;
|
||||
open: boolean;
|
||||
minWidth: number;
|
||||
maxWidth: number;
|
||||
resizeHandlePos: 'left' | 'right';
|
||||
resizeHandleOffset?: number;
|
||||
resizeHandleVerticalPadding?: number;
|
||||
onOpen: (open: boolean) => void;
|
||||
onResizing: (resizing: boolean) => void;
|
||||
onWidthChange: (width: number) => void;
|
||||
}
|
||||
|
||||
export interface ResizePanelProps
|
||||
extends React.HtmlHTMLAttributes<HTMLDivElement> {
|
||||
resizing: boolean;
|
||||
open: boolean;
|
||||
floating?: boolean;
|
||||
minWidth: number;
|
||||
maxWidth: number;
|
||||
resizeHandlePos: 'left' | 'right';
|
||||
resizeHandleOffset?: number;
|
||||
resizeHandleVerticalPadding?: number;
|
||||
enableAnimation?: boolean;
|
||||
width: number;
|
||||
onOpen: (open: boolean) => void;
|
||||
onResizing: (resizing: boolean) => void;
|
||||
onWidthChange: (width: number) => void;
|
||||
}
|
||||
|
||||
const ResizeHandle = ({
|
||||
className,
|
||||
resizing,
|
||||
minWidth,
|
||||
maxWidth,
|
||||
resizeHandlePos,
|
||||
resizeHandleOffset,
|
||||
resizeHandleVerticalPadding,
|
||||
open,
|
||||
onOpen,
|
||||
onResizing,
|
||||
onWidthChange,
|
||||
...rest
|
||||
}: ResizeHandleProps) => {
|
||||
const ref = useRef<HTMLDivElement>(null);
|
||||
const onResizeStart = useCallback(() => {
|
||||
let resized = false;
|
||||
const panelContainer = ref.current?.parentElement;
|
||||
assertExists(
|
||||
panelContainer,
|
||||
'parent element not found for resize indicator'
|
||||
);
|
||||
|
||||
const { left: anchorLeft, right: anchorRight } =
|
||||
panelContainer.getBoundingClientRect();
|
||||
|
||||
function onMouseMove(e: MouseEvent) {
|
||||
e.preventDefault();
|
||||
if (!panelContainer) return;
|
||||
const newWidth = Math.min(
|
||||
maxWidth,
|
||||
Math.max(
|
||||
resizeHandlePos === 'right'
|
||||
? e.clientX - anchorLeft
|
||||
: anchorRight - e.clientX,
|
||||
minWidth
|
||||
)
|
||||
);
|
||||
onWidthChange(newWidth);
|
||||
onResizing(true);
|
||||
resized = true;
|
||||
}
|
||||
|
||||
document.addEventListener('mousemove', onMouseMove);
|
||||
document.addEventListener(
|
||||
'mouseup',
|
||||
() => {
|
||||
// if not resized, toggle sidebar
|
||||
if (!resized) {
|
||||
onOpen(false);
|
||||
}
|
||||
onResizing(false);
|
||||
document.removeEventListener('mousemove', onMouseMove);
|
||||
},
|
||||
{ once: true }
|
||||
);
|
||||
}, [maxWidth, resizeHandlePos, minWidth, onWidthChange, onResizing, onOpen]);
|
||||
|
||||
return (
|
||||
<div
|
||||
{...rest}
|
||||
data-testid="resize-handle"
|
||||
ref={ref}
|
||||
style={assignInlineVars({
|
||||
[styles.resizeHandleOffsetVar]: `${resizeHandleOffset ?? 0}px`,
|
||||
[styles.resizeHandleVerticalPadding]: `${
|
||||
resizeHandleVerticalPadding ?? 0
|
||||
}px`,
|
||||
})}
|
||||
className={clsx(styles.resizeHandleContainer, className)}
|
||||
data-handle-position={resizeHandlePos}
|
||||
data-resizing={resizing}
|
||||
data-open={open}
|
||||
onMouseDown={onResizeStart}
|
||||
>
|
||||
<div className={styles.resizerInner} />
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
function useEnableAnimation() {
|
||||
const [enable, setEnable] = useState(false);
|
||||
useEffect(() => {
|
||||
window.setTimeout(() => {
|
||||
setEnable(true);
|
||||
}, 500);
|
||||
}, []);
|
||||
return enable;
|
||||
}
|
||||
|
||||
export const ResizePanel = forwardRef<HTMLDivElement, ResizePanelProps>(
|
||||
function ResizePanel(
|
||||
{
|
||||
children,
|
||||
className,
|
||||
resizing,
|
||||
minWidth,
|
||||
maxWidth,
|
||||
width,
|
||||
floating,
|
||||
enableAnimation: _enableAnimation = true,
|
||||
open,
|
||||
onOpen,
|
||||
onResizing,
|
||||
onWidthChange,
|
||||
resizeHandlePos,
|
||||
resizeHandleOffset,
|
||||
resizeHandleVerticalPadding,
|
||||
...rest
|
||||
},
|
||||
ref
|
||||
) {
|
||||
const enableAnimation = useEnableAnimation() && _enableAnimation;
|
||||
return (
|
||||
<div
|
||||
{...rest}
|
||||
ref={ref}
|
||||
style={assignInlineVars({
|
||||
[styles.panelWidthVar]: `${width}px`,
|
||||
})}
|
||||
className={clsx(className, styles.root)}
|
||||
data-open={open}
|
||||
data-is-floating={floating}
|
||||
data-handle-position={resizeHandlePos}
|
||||
data-enable-animation={enableAnimation && !resizing}
|
||||
>
|
||||
{children}
|
||||
<ResizeHandle
|
||||
resizeHandlePos={resizeHandlePos}
|
||||
resizeHandleOffset={resizeHandleOffset}
|
||||
resizeHandleVerticalPadding={resizeHandleVerticalPadding}
|
||||
maxWidth={maxWidth}
|
||||
minWidth={minWidth}
|
||||
onOpen={onOpen}
|
||||
onResizing={onResizing}
|
||||
onWidthChange={onWidthChange}
|
||||
open={open}
|
||||
resizing={resizing}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
);
|
||||
@@ -60,6 +60,8 @@ export const mainContainerStyle = style({
|
||||
margin: '8px',
|
||||
borderRadius: '5px',
|
||||
overflow: 'hidden',
|
||||
// todo: is this performance intensive?
|
||||
filter: 'drop-shadow(0px 0px 4px rgba(66,65,73,.14))',
|
||||
'@media': {
|
||||
print: {
|
||||
overflow: 'visible',
|
||||
@@ -86,39 +88,6 @@ export const mainContainerStyle = style({
|
||||
},
|
||||
} as ComplexStyleRule);
|
||||
|
||||
// These styles override the default styles of the react-resizable-panels
|
||||
// as the default styles make the overflow part hidden when printing to PDF.
|
||||
// See https://github.com/toeverything/AFFiNE/pull/3893
|
||||
globalStyle(`${mainContainerStyle} > div[data-panel-group]`, {
|
||||
'@media': {
|
||||
print: {
|
||||
overflow: 'visible !important',
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
// These styles override the default styles of the react-resizable-panels
|
||||
// as the default styles make the overflow part hidden when printing to PDF.
|
||||
// See https://github.com/toeverything/AFFiNE/pull/3893
|
||||
globalStyle(`${mainContainerStyle} > div[data-panel-group] > div[data-panel]`, {
|
||||
'@media': {
|
||||
print: {
|
||||
overflow: 'visible !important',
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
// Hack margin so that it works normally when sidebar is closed
|
||||
globalStyle(
|
||||
`[data-testid=app-sidebar-wrapper][data-open=true][data-is-floating=false][data-has-background=false]
|
||||
~ ${mainContainerStyle}[data-show-padding="true"]`,
|
||||
{
|
||||
// transition added here to prevent the transition from being applied on page load
|
||||
transition: 'margin-left .3s ease-in-out',
|
||||
marginLeft: '0',
|
||||
}
|
||||
);
|
||||
|
||||
export const toolStyle = style({
|
||||
position: 'absolute',
|
||||
right: '30px',
|
||||
|
||||
Reference in New Issue
Block a user