ui: replace stupid react-split-pane with allotment

pull/523/head
undefined 2 years ago
parent 6bf35f8f73
commit fe1d964eba
No known key found for this signature in database

@ -1,12 +0,0 @@
diff --git a/index.d.ts b/index.d.ts
index d116f54d6da12d24b48e24ff3636c9066059aa58..9d62eac28d5480aa6c2e796d603757d5999ea0af 100644
--- a/index.d.ts
+++ b/index.d.ts
@@ -25,6 +25,7 @@ export type SplitPaneProps = {
pane2Style?: React.CSSProperties;
resizerClassName?: string;
step?: number;
+ children: React.ReactNode;
};
export type SplitPaneState = {

@ -1,9 +0,0 @@
.splitpane-fill
display: flex
position: absolute
overflow: hidden
left: 0
width: 100%
top: 0
height: 100%
user-select: none

@ -1,19 +0,0 @@
import classNames from 'classnames';
import PropTypes from 'prop-types';
export default function SplitPaneFillOverlayComponent(props) {
const {
className,
children,
...rest
} = props;
const cn = classNames(className, 'splitpane-fill');
return (
<div {...rest} className={cn}>{children}</div>
);
}
SplitPaneFillOverlayComponent.propTypes = {
className: PropTypes.string,
children: PropTypes.node,
};

@ -1,27 +0,0 @@
$resizer-extend = 4px
$resizer-extend-color = rgba($primary-color, 0.3)
.Resizer
background: #000
opacity: .2
z-index: 1
box-sizing: border-box
background-clip: padding-box
.Resizer.horizontal
height: ($resizer-extend * 2 + 1px)
margin: -($resizer-extend) 0
border-top: $resizer-extend solid transparent
border-bottom: $resizer-extend solid transparent
cursor: row-resize
width: 100%
.Resizer.vertical
width: ($resizer-extend * 2 + 1px)
margin: 0 -($resizer-extend)
border-left: $resizer-extend solid transparent
border-right: $resizer-extend solid transparent
cursor: col-resize
.Resizer:hover
border-color: $resizer-extend-color

@ -1,7 +1,6 @@
import classNames from 'classnames';
import PropTypes from 'prop-types';
import React from 'react';
import SplitPaneFillOverlay from 'vj/components/react-splitpane/SplitPaneFillOverlayComponent';
export default function PanelComponent(props) {
const {
@ -12,10 +11,10 @@ export default function PanelComponent(props) {
} = props;
const cn = classNames(className, 'flex-col');
return (
<SplitPaneFillOverlay {...rest} className={cn}>
<div {...rest} className={`${cn} splitpane-fill`}>
<div className="scratchpad__panel-title">{title}</div>
<div className="flex-col flex-fill">{children}</div>
</SplitPaneFillOverlay>
</div>
);
}

@ -1,39 +1,17 @@
import ProblemIcon from '@vscode/codicons/src/icons/file.svg?react';
import { Allotment } from 'allotment';
import $ from 'jquery';
import _ from 'lodash';
import type * as monaco from 'monaco-editor';
import React from 'react';
import { useDispatch, useSelector, useStore } from 'react-redux';
import SplitPane from 'react-split-pane';
import Dom from 'vj/components/react/DomComponent';
import SplitPaneFillOverlay from 'vj/components/react-splitpane/SplitPaneFillOverlayComponent';
import { Context, ctx, Service } from 'vj/context';
import ScratchpadEditor from './ScratchpadEditorContainer';
import ScratchpadPretest from './ScratchpadPretestContainer';
import ScratchpadRecords from './ScratchpadRecordsContainer';
import ScratchpadToolbar from './ScratchpadToolbarContainer';
function buildNestedPane([a, ...panes], mode: 'horizontal' | 'vertical' = 'horizontal') {
const elements = [
a,
...panes.filter((p) => p.props.visible),
];
if (elements.length === 1) return a;
return elements
.reduce((prev, curr) => (
<SplitPane
split={mode}
primary="second"
defaultSize={curr.props.size}
key={curr.element.key}
onChange={curr.onChange}
>
{prev}
{curr.element}
</SplitPane>
));
}
const pages = {
problem: {
icon: () => <ProblemIcon />,
@ -88,14 +66,7 @@ export default function ScratchpadContainer() {
const dispatch = useDispatch();
const ui = useSelector<any, any>((state) => state.ui, _.isEqual);
const handleChangeSize = _.debounce((uiElement, size) => {
dispatch({
type: 'SCRATCHPAD_UI_CHANGE_SIZE',
payload: {
uiElement,
size,
},
});
const handleChangeSize = _.debounce(() => {
$('#scratchpad').trigger('vjScratchpadRelayout');
forceUpdate();
}, 500);
@ -109,12 +80,8 @@ export default function ScratchpadContainer() {
const showSidebar = Object.keys(pages).length > 1;
return (
<SplitPane
split="vertical"
primary="first"
size={showSidebar ? 50 : 0}
allowResize={false}
>
<Allotment onChange={handleChangeSize}>
<Allotment.Pane visible={showSidebar} minSize={50} maxSize={50}>
<div className="scratchpad__tablist" style={{ display: showSidebar ? 'block' : 'none' }}>
{Object.keys(pages).map((key) => {
const Component = pages[key].icon;
@ -125,15 +92,8 @@ export default function ScratchpadContainer() {
);
})}
</div>
<SplitPane
defaultSize={ui.main.size}
size={ui.main.size}
minSize={ui.activePage !== null ? 250 : 0}
split="vertical"
primary="first"
onChange={(size) => handleChangeSize('main', size)}
allowResize={ui.activePage !== null}
>
</Allotment.Pane>
<Allotment.Pane visible={!!ui.activePage}>
<div className="scratchpad__problem">
{Object.keys(pages).map((key) => {
const Component = pages[key].component;
@ -144,23 +104,19 @@ export default function ScratchpadContainer() {
);
})}
</div>
{buildNestedPane([
<SplitPaneFillOverlay key="editor" className="flex-col">
</Allotment.Pane>
<Allotment vertical onChange={handleChangeSize}>
<div key="editor" className="flex-col splitpane-fill">
<ScratchpadToolbar />
<ScratchpadEditor />
</SplitPaneFillOverlay>,
{
props: ui.pretest,
onChange: (size) => handleChangeSize('pretest', size),
element: <ScratchpadPretest key="pretest" />,
},
{
props: ui.records,
onChange: (size) => handleChangeSize('records', size),
element: <ScratchpadRecords key="records" />,
},
])}
</SplitPane>
</SplitPane>
</div>
<Allotment.Pane visible={ui.pretest.visible}>
<ScratchpadPretest key="pretest" />
</Allotment.Pane>
<Allotment.Pane visible={ui.records.visible}>
<ScratchpadRecords key="records" />
</Allotment.Pane>
</Allotment>
</Allotment>
);
}

@ -8,7 +8,6 @@ export interface Context {
[Context.events]: Events<Context>;
setTimeout: typeof setTimeout;
setInterval: typeof setInterval;
setImmediate: typeof setImmediate;
api: ApiMixin;
}
@ -37,10 +36,9 @@ const T = <F extends (...args: any[]) => any>(origFunc: F, disposeFunc?) =>
this.caller?.on('dispose', () => (disposeFunc ? disposeFunc(res) : res()));
};
export class ApiMixin extends Service {
static readonly methods = ['addScript', 'setInterval', 'setTimeout', 'setImmediate', 'provideModule', 'inject', 'broadcast'];
static readonly methods = ['setInterval', 'setTimeout'];
setInterval = T(setInterval, clearInterval);
setTimeout = T(setTimeout, clearTimeout);
setImmediate = T(setImmediate, clearImmediate);
constructor(ctx) {
super(ctx, 'api', true);
}

@ -40,6 +40,7 @@
"@types/sharedworker": "^0.0.91",
"@types/webpack-env": "^1.18.0",
"@vscode/codicons": "^0.0.32",
"allotment": "^1.18.1",
"autoprefixer": "^10.4.13",
"browser-update": "^3.3.44",
"chalk": "^5.2.0",
@ -87,7 +88,6 @@
"react-dom": "^18.2.0",
"react-query": "^3.39.3",
"react-redux": "^8.0.5",
"react-split-pane": "^0.1.92",
"reconnecting-websocket": "^4.4.0",
"redux": "^4.2.1",
"redux-logger": "^3.0.6",

@ -1,5 +1,6 @@
import 'normalize.css/normalize.css';
import 'vditor/dist/index.css';
import 'allotment/dist/style.css';
import 'pickadate/lib/themes/classic.css';
import 'pickadate/lib/themes/classic.date.css';
import 'pickadate/lib/themes/classic.time.css';

Loading…
Cancel
Save