Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cb 4429 change divider behavior #2335

Merged
merged 19 commits into from
Jan 31, 2024
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 25 additions & 3 deletions webapp/packages/core-blocks/src/Split/Split.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,18 +7,40 @@
*/
import { Split as BaseSplit, SplitProps } from 'go-split';
import { observer } from 'mobx-react-lite';
import { useRef } from 'react';

import { s } from '../s';
import { useS } from '../useS';
import style from './Split.m.css';
import { useAutoMargin } from './useAutoMargin';

export type ISplitProps = SplitProps;
export type ISplitProps = SplitProps & {
disableAutoMargin?: boolean;
};

export const Split = observer<ISplitProps>(function Split({ className, split, ...rest }) {
export const Split = observer<ISplitProps>(function Split({ className, minSize, maxSize, split, disableAutoMargin = false, ...rest }) {
const styles = useS(style);
const ref = useRef<BaseSplit | null>(null);

const vertical = split === 'vertical' || split === undefined;
const horizontal = split === 'horizontal';

return <BaseSplit className={s(styles, { split: true, vertical, horizontal }, className)} split={split} {...rest} />;
const { maxSize: calculatedMaxSize, minSize: calculatedMinSize } = useAutoMargin({
disableAutoMargin,
split,
maxSize,
minSize,
ref,
});

return (
<BaseSplit
ref={ref}
minSize={calculatedMinSize}
maxSize={calculatedMaxSize}
className={s(styles, { split: true, vertical, horizontal }, className)}
split={split}
{...rest}
/>
);
});
8 changes: 6 additions & 2 deletions webapp/packages/core-blocks/src/Split/SplitControls.m.css
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@

.button {
composes: theme-button theme-button_unelevated theme-button_background theme-elevation-z3 from global;
opacity: 0;
opacity: 1;
transition-property: opacity, box-shadow !important;
transition: opacity 0.3s ease-in-out;
}
Expand All @@ -24,10 +24,14 @@
composes: theme-button_ripple from global;
}

.container:hover .button {
.container:hover .resizeButton {
opacity: 1;
}

.resizeButton {
opacity: 0;
}

.container[data-s-split='vertical'] {
flex-direction: column;
cursor: ew-resize;
Expand Down
34 changes: 31 additions & 3 deletions webapp/packages/core-blocks/src/Split/SplitControls.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,39 @@ import { useS } from '../useS';
import SplitControlsStyles from './SplitControls.m.css';
import { useSplit } from './useSplit';

// TODO поправить либу.

// TODO хранить/получить в стейте minSize/maxSize
// ??? ничего не менять

// рыба
// 1. disableAutoMargin props в компонент сплит.
// 2. если нету disableAutoMargin, то к компоненте split определяем
// коллизию окна браузера и панели (вправо, влево, вниз, вверх)
// если есть коллизия, то ставим minize/maxsize Splitter (component)

// рыба внутри либы
// 1. учитывать minSize/maxSize при состояниях minimize/maximize
// и учитывать эти значения при определении состояние mode
// 2. сделать геттер на реф дива который рендерит Split (его контейнер) - splitRef (protected)

// setSize, getMainStyleSize
// либа должна коллапсить не до 0 а до state.minSize
// либа должна коллапсить не до 100% если maxSize > 0, то до state.maxSize
// либа должна коллапсить не до 100% если maxSize < 0, то до calc(100% - maxSize in px)

// финальная рыба
// 1. дофиксить сплит контролс так как он не учитывает minSize/maxSize
sergeyteleshev marked this conversation as resolved.
Show resolved Hide resolved
export const SplitControls: React.FC = function SplitControls() {
const split = useSplit();
const styles = useS(SplitControlsStyles);
const isResizeMode = split.state.mode === 'resize';

const inverse = split.state.isMainSecond();

let inverseMode = split.state.mode;

if (split.state.size > split.state.getContainerSize()) {
if (split.state.size > split.state.getContainerSize() - split.state.maxSize) {
inverseMode = 'maximize';
}
Wroud marked this conversation as resolved.
Show resolved Hide resolved

Expand Down Expand Up @@ -64,12 +88,16 @@ export const SplitControls: React.FC = function SplitControls() {
onDoubleClick={split.state.onDoubleClick}
>
{split.state.mode !== 'minimize' && (
<button className={s(styles, { button: true, primary: !inverse })} type="button" onClick={handlers.handleCollapse}>
<button
className={s(styles, { button: true, primary: !inverse, resizeButton: isResizeMode })}
type="button"
onClick={handlers.handleCollapse}
>
<div className={s(styles, { ripple: true })} />
</button>
)}
{split.state.mode !== 'maximize' && (
<button className={s(styles, { button: true, primary: inverse })} type="button" onClick={handlers.handleExpand}>
<button className={s(styles, { button: true, primary: inverse, resizeButton: isResizeMode })} type="button" onClick={handlers.handleExpand}>
<div className={s(styles, { ripple: true })} />
</button>
)}
Expand Down
54 changes: 54 additions & 0 deletions webapp/packages/core-blocks/src/Split/useAutoMargin.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
/*
* CloudBeaver - Cloud Database Manager
* Copyright (C) 2020-2024 DBeaver Corp and others
*
* Licensed under the Apache License, Version 2.0.
* you may not use this file except in compliance with the License.
*/
import type { Split } from 'go-split';

type SplitPropsWithRef = React.PropsWithRef<Split>;
interface UseAutoMarginArgs {
ref?: React.MutableRefObject<Split | null>;
split: SplitPropsWithRef['props']['split'];
disableAutoMargin?: boolean;
minSize?: number;
maxSize?: number;
}

const DEFAULT_MIN_SIZE = 16;

export function useAutoMargin({ split, ref, disableAutoMargin, minSize, maxSize }: UseAutoMarginArgs) {
const splitRef = ref?.current?.splitRef;
const coords = splitRef?.current?.getBoundingClientRect();

if (disableAutoMargin) {
return {
minSize,
maxSize,
};
}

if (!ref?.current || !splitRef || !coords) {
return {
// this case needed for initial render so divider also has a margin
minSize: DEFAULT_MIN_SIZE,
maxSize,
};
}

const vertical = split === 'vertical' || split === undefined;
const horizontal = split === 'horizontal';

if (vertical) {
minSize = DEFAULT_MIN_SIZE;
maxSize = coords.width - DEFAULT_MIN_SIZE;
}

if (horizontal) {
minSize = DEFAULT_MIN_SIZE;
maxSize = coords.height - DEFAULT_MIN_SIZE;
}

return { minSize, maxSize };
}
Loading