Skip to content

Commit

Permalink
User interaction improvement (#949)
Browse files Browse the repository at this point in the history
* feat: show more menu in navbar

* feat: able to drag and change run sidebar width
  • Loading branch information
PeterPanZH authored Apr 9, 2021
1 parent 22b159a commit 6da5a64
Show file tree
Hide file tree
Showing 10 changed files with 406 additions and 162 deletions.
3 changes: 3 additions & 0 deletions frontend/packages/core/public/locales/en/common.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,11 @@
"graph": "Graphs",
"high-dimensional": "High Dimensional",
"histogram": "Histogram",
"hyper-parameter": "Hyper Parameters",
"image": "Image",
"inactive": "Inactive",
"loading": "Please wait while loading data",
"more": "More",
"next-page": "Next Page",
"pr-curve": "PR Curve",
"previous-page": "Prev Page",
Expand Down
3 changes: 3 additions & 0 deletions frontend/packages/core/public/locales/zh/common.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,11 @@
"graph": "网络结构",
"high-dimensional": "高维数据映射",
"histogram": "直方图",
"hyper-parameter": "超参可视化",
"image": "图像",
"inactive": "待使用",
"loading": "数据载入中,请稍等",
"more": "更多",
"next-page": "下一页",
"pr-curve": "PR曲线",
"previous-page": "上一页",
Expand Down
108 changes: 102 additions & 6 deletions frontend/packages/core/src/components/Aside.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@
* limitations under the License.
*/

import React, {FunctionComponent} from 'react';
import {WithStyled, asideWidth, rem, size, transitionProps} from '~/utils/style';
import React, {FunctionComponent, useCallback, useLayoutEffect, useRef, useState} from 'react';
import {WithStyled, asideWidth, rem, transitionProps} from '~/utils/style';

import styled from 'styled-components';

Expand All @@ -30,11 +30,16 @@ export const AsideSection = styled.section`
}
`;

const Wrapper = styled.div<{width?: string | number}>`
${props => size('100%', props.width == null ? asideWidth : props.width)}
const Wrapper = styled.div.attrs<{width: string | number}>(({width}) => ({
style: {
width: 'number' === typeof width ? `${width}px` : width
}
}))<{width: string | number}>`
height: 100%;
overflow: hidden;
display: flex;
flex-direction: column;
position: relative;
> .aside-top {
flex: auto;
Expand All @@ -55,16 +60,107 @@ const Wrapper = styled.div<{width?: string | number}>`
box-shadow: 0 -${rem(5)} ${rem(16)} 0 rgba(0, 0, 0, 0.03);
padding: ${rem(20)};
}
> .aside-resize-bar-left,
> .aside-resize-bar-right {
position: absolute;
width: ${rem(8)};
height: 100%;
top: 0;
cursor: col-resize;
user-select: none;
&.aside-resize-bar-left {
left: 0;
}
&.aside-resize-bar-right {
right: 0;
}
}
`;

type AsideProps = {
width?: string | number;
bottom?: React.ReactNode;
resizable?: 'left' | 'right';
minWidth?: number;
maxWidth?: number;
onResized?: (width: number) => unknown;
};

const Aside: FunctionComponent<AsideProps & WithStyled> = ({width, bottom, className, children}) => {
const Aside: FunctionComponent<AsideProps & WithStyled> = ({
width,
bottom,
resizable,
minWidth,
maxWidth,
onResized,
className,
children
}) => {
const [sideWidth, setSideWidth] = useState<NonNullable<typeof width>>(width ?? asideWidth);
const ref = useRef<HTMLDivElement>(null);
const resizing = useRef<boolean>(false);
const range = useRef({
min: minWidth ?? null,
max: maxWidth ?? null
});

useLayoutEffect(() => {
range.current.min = minWidth ?? null;
}, [minWidth]);
useLayoutEffect(() => {
range.current.max = maxWidth ?? null;
}, [maxWidth]);

useLayoutEffect(() => {
if (range.current.min == null && ref.current) {
const {width} = ref.current.getBoundingClientRect();
range.current.min = width;
}
}, []);

const mousedown = useCallback(() => {
resizing.current = true;
}, []);

const mousemove = useCallback(
(event: MouseEvent) => {
if (ref.current && resizing.current) {
const clientX = event.clientX;
const {left, right} = ref.current.getBoundingClientRect();
let w = 0;
if (resizable === 'left') {
w = Math.max(range.current.min ?? 0, right - clientX);
} else if (resizable === 'right') {
w = Math.max(range.current.min ?? 0, clientX - left);
}
w = Math.min(range.current.max ?? document.body.clientWidth / 2, w);
setSideWidth(w);
}
},
[resizable]
);

const mouseup = useCallback(() => {
resizing.current = false;
if (ref.current) {
onResized?.(ref.current.getBoundingClientRect().width);
}
}, [onResized]);

useLayoutEffect(() => {
document.addEventListener('mousemove', mousemove);
return () => document.removeEventListener('mousemove', mousemove);
}, [mousemove]);
useLayoutEffect(() => {
document.addEventListener('mouseup', mouseup);
return () => document.removeEventListener('mouseup', mouseup);
}, [mouseup]);

return (
<Wrapper width={width} className={className}>
<Wrapper width={sideWidth} className={className} ref={ref}>
{resizable ? <div className={`aside-resize-bar-${resizable}`} onMouseDown={mousedown}></div> : null}
<div className="aside-top">{children}</div>
{bottom && <div className="aside-bottom">{bottom}</div>}
</Wrapper>
Expand Down
Loading

0 comments on commit 6da5a64

Please sign in to comment.