chore: 调整 example 改大预览区域,代码白城drawer 展示与编辑 (#4173)

This commit is contained in:
liaoxuezhi 2022-04-28 10:53:06 +08:00 committed by GitHub
parent 35d5c23ca6
commit d16eca6fdc
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 163 additions and 91 deletions

View File

@ -21,7 +21,7 @@ class CodePreview extends React.Component {
render() { render() {
const {container, setAsideFolded, setHeaderVisible, ...rest} = this.props; const {container, setAsideFolded, setHeaderVisible, ...rest} = this.props;
return <Play {...rest} vertical />; return <Play {...rest} mini />;
} }
} }

View File

@ -10,6 +10,7 @@ import JSON5 from 'json5';
import CodeEditor from '../../src/components/Editor'; import CodeEditor from '../../src/components/Editor';
import copy from 'copy-to-clipboard'; import copy from 'copy-to-clipboard';
import {matchPath} from 'react-router-dom'; import {matchPath} from 'react-router-dom';
import Drawer from '../../src/components/Drawer';
const DEFAULT_CONTENT = `{ const DEFAULT_CONTENT = `{
"$schema": "/schemas/page.json#", "$schema": "/schemas/page.json#",
@ -107,7 +108,8 @@ export default class PlayGround extends React.Component {
this.state = { this.state = {
asideWidth: props.asideWidth || Math.max(300, window.innerWidth * 0.3), asideWidth: props.asideWidth || Math.max(300, window.innerWidth * 0.3),
schema: schema, schema: schema,
schemaCode: JSON.stringify(schema, null, 2) schemaCode: JSON.stringify(schema, null, 2),
isOpened: false
}; };
this.handleMouseDown = this.handleMouseDown.bind(this); this.handleMouseDown = this.handleMouseDown.bind(this);
@ -115,6 +117,8 @@ export default class PlayGround extends React.Component {
this.handleMouseUp = this.handleMouseUp.bind(this); this.handleMouseUp = this.handleMouseUp.bind(this);
this.removeWindowEvents = this.removeWindowEvents.bind(this); this.removeWindowEvents = this.removeWindowEvents.bind(this);
this.handleChange = this.handleChange.bind(this); this.handleChange = this.handleChange.bind(this);
this.toggleDrawer = this.toggleDrawer.bind(this);
this.close = this.close.bind(this);
this.schemaProps = {}; this.schemaProps = {};
const __ = makeTranslator(props.locale); const __ = makeTranslator(props.locale);
@ -397,6 +401,18 @@ export default class PlayGround extends React.Component {
window.removeEventListener('mousemove', this.handleMouseMove); window.removeEventListener('mousemove', this.handleMouseMove);
} }
toggleDrawer() {
this.setState({
isOpened: !this.state.isOpened
});
}
close() {
this.setState({
isOpened: false
});
}
editorDidMount = (editor, monaco) => { editorDidMount = (editor, monaco) => {
this.editor = editor; this.editor = editor;
this.monaco = monaco; this.monaco = monaco;
@ -463,8 +479,36 @@ export default class PlayGround extends React.Component {
} }
render() { render() {
const {vertical, height} = this.props; const {vertical, mini, height, theme, classPrefix} = this.props;
if (vertical) { console.log(classPrefix);
if (mini) {
return (
<div className="Playgroud Playgroud--mini">
<a onClick={this.toggleDrawer}>
编辑代码 <i className="fa fa-code p-l-xs"></i>
</a>
<Drawer
showCloseButton
resizable
theme={theme}
overlay={false}
position="right"
show={this.state.isOpened}
onHide={this.close}
>
<div className={`${classPrefix}Drawer-header`}>
编辑代码支持编辑实时预览
</div>
<div className={`${classPrefix}Drawer-body no-padder`}>
{this.renderEditor()}
</div>
</Drawer>
<div style={{minHeight: height}} className="Playgroud-preview">
{this.renderPreview()}
</div>
</div>
);
} else if (vertical) {
return ( return (
<div className="Playgroud"> <div className="Playgroud">
<div style={{minHeight: height}} className="Playgroud-preview"> <div style={{minHeight: height}} className="Playgroud-preview">

View File

@ -1055,6 +1055,22 @@ body.dark {
width: 350px; width: 350px;
flex-shrink: 0; flex-shrink: 0;
} }
&--mini {
display: block;
position: relative;
> a {
cursor: pointer;
display: block;
text-align: right;
position: absolute;
right: 0;
top: -20px;
}
.Playgroud-preview {
width: 100%;
}
}
} }
@media screen and (max-width: 767px) { @media screen and (max-width: 767px) {

View File

@ -9,6 +9,7 @@
right: 0; right: 0;
height: 100vh; height: 100vh;
width: 24px; width: 24px;
pointer-events: none;
h3 { h3 {
color: inherit; color: inherit;
@ -63,6 +64,7 @@
} }
&-toggle { &-toggle {
pointer-events: all;
background: var(--body-bg); background: var(--body-bg);
position: fixed; position: fixed;
top: 50%; top: 50%;
@ -86,6 +88,7 @@
} }
&-content { &-content {
pointer-events: all;
display: none; display: none;
} }

View File

@ -193,6 +193,7 @@
right: var(--gap-base); right: var(--gap-base);
left: auto; left: auto;
margin-top: 0; margin-top: 0;
z-index: 10;
} }
} }
@ -228,6 +229,7 @@
top: var(--gap-base); top: var(--gap-base);
right: var(--gap-base); right: var(--gap-base);
margin-right: 0; margin-right: 0;
z-index: 10;
} }
} }
@ -286,6 +288,7 @@
right: var(--gap-base); right: var(--gap-base);
left: auto; left: auto;
margin-bottom: 0; margin-bottom: 0;
z-index: 10;
} }
} }
@ -321,6 +324,7 @@
left: auto; left: auto;
right: var(--gap-base); right: var(--gap-base);
top: var(--gap-base); top: var(--gap-base);
z-index: 10;
} }
} }

View File

@ -36,6 +36,7 @@ export interface DrawerProps {
disabled?: boolean; disabled?: boolean;
closeOnOutside?: boolean; closeOnOutside?: boolean;
classPrefix: string; classPrefix: string;
resizable?: boolean;
classnames: ClassNamesFn; classnames: ClassNamesFn;
onExited?: () => void; onExited?: () => void;
onEntered?: () => void; onEntered?: () => void;
@ -62,6 +63,8 @@ export class Drawer extends React.Component<DrawerProps, DrawerState> {
modalDom: HTMLElement; modalDom: HTMLElement;
contentDom: HTMLElement; contentDom: HTMLElement;
isRootClosed = false; isRootClosed = false;
resizer = React.createRef<HTMLDivElement>();
resizeCoord: number = 0;
componentDidMount() { componentDidMount() {
if (this.props.show) { if (this.props.show) {
@ -170,17 +173,99 @@ export class Drawer extends React.Component<DrawerProps, DrawerState> {
getDrawerStyle() { getDrawerStyle() {
const {width, height, position} = this.props; const {width, height, position} = this.props;
const offsetStyle: { const offsetStyle: {
width?: number | string, width?: number | string;
height?: number | string height?: number | string;
} = {}; } = {};
if ((position === 'left' || position === 'right') && width !== undefined) { if ((position === 'left' || position === 'right') && width !== undefined) {
offsetStyle.width = width; offsetStyle.width = width;
} else if ((position === 'top' || position === 'bottom') && height !== undefined) { } else if (
(position === 'top' || position === 'bottom') &&
height !== undefined
) {
offsetStyle.height = height; offsetStyle.height = height;
} }
return offsetStyle; return offsetStyle;
} }
@autobind
resizeMouseDown(e: React.MouseEvent<any>) {
const {position, classPrefix: ns} = this.props;
const drawer = this.contentDom;
const resizer = this.resizer.current!;
const drawerWidth = getComputedStyle(drawer).width as string;
const drawerHeight = getComputedStyle(drawer).height as string;
this.resizeCoord =
(position === 'left' &&
e.clientX -
resizer.offsetWidth -
parseInt(drawerWidth.substring(0, drawerWidth.length - 2))) ||
(position === 'right' &&
document.body.offsetWidth -
e.clientX -
resizer.offsetWidth -
parseInt(drawerWidth.substring(0, drawerWidth.length - 2))) ||
(position === 'top' &&
e.clientY -
resizer.offsetHeight -
parseInt(drawerHeight.substring(0, drawerHeight.length - 2))) ||
(position === 'bottom' &&
document.body.offsetHeight -
e.clientY -
resizer.offsetHeight -
parseInt(drawerHeight.substring(0, drawerHeight.length - 2))) ||
0;
document.body.addEventListener('mousemove', this.bindResize);
document.body.addEventListener('mouseup', this.removeResize);
}
@autobind
bindResize(e: any) {
const {position} = this.props;
const maxWH = 'calc(100% - 50px)';
const drawer = this.contentDom;
const drawerStyle = drawer.style;
let wh =
(position === 'left' && e.clientX) ||
(position === 'right' && document.body.offsetWidth - e.clientX) ||
(position === 'top' && e.clientY) ||
(position === 'bottom' && document.body.offsetHeight - e.clientY) ||
0;
wh = wh - this.resizeCoord + 'px';
if (position === 'left' || position === 'right') {
drawerStyle.maxWidth = maxWH;
drawerStyle.width = wh;
}
if (position === 'top' || position === 'bottom') {
drawerStyle.maxHeight = maxWH;
drawerStyle.height = wh;
}
}
@autobind
removeResize() {
document.body.removeEventListener('mousemove', this.bindResize);
document.body.removeEventListener('mouseup', this.removeResize);
}
renderResizeCtrl() {
const {classnames: cx} = this.props;
return (
<div
className={cx('Drawer-resizeCtrl')}
ref={this.resizer}
onMouseDown={this.resizeMouseDown}
>
<div className={cx('Drawer-resizeIcon')}>···</div>
</div>
);
}
render() { render() {
const { const {
classPrefix: ns, classPrefix: ns,
@ -194,7 +279,8 @@ export class Drawer extends React.Component<DrawerProps, DrawerState> {
onHide, onHide,
disabled, disabled,
overlay, overlay,
bodyClassName bodyClassName,
resizable
} = this.props; } = this.props;
const bodyStyle = this.getDrawerStyle(); const bodyStyle = this.getDrawerStyle();
@ -257,6 +343,7 @@ export class Drawer extends React.Component<DrawerProps, DrawerState> {
</a> </a>
) : null} ) : null}
{status === EXITED ? null : children} {status === EXITED ? null : children}
{resizable ? this.renderResizeCtrl() : null}
</div> </div>
</div> </div>
); );

View File

@ -218,9 +218,6 @@ export default class Drawer extends React.Component<DrawerProps> {
this.handleDialogConfirm = this.handleDialogConfirm.bind(this); this.handleDialogConfirm = this.handleDialogConfirm.bind(this);
this.handleDialogClose = this.handleDialogClose.bind(this); this.handleDialogClose = this.handleDialogClose.bind(this);
this.handleChildFinished = this.handleChildFinished.bind(this); this.handleChildFinished = this.handleChildFinished.bind(this);
this.resizeMouseDown = this.resizeMouseDown.bind(this);
this.bindResize = this.bindResize.bind(this);
this.removeResize = this.removeResize.bind(this);
this.handleEntered = this.handleEntered.bind(this); this.handleEntered = this.handleEntered.bind(this);
this.handleExited = this.handleExited.bind(this); this.handleExited = this.handleExited.bind(this);
this.handleFormInit = this.handleFormInit.bind(this); this.handleFormInit = this.handleFormInit.bind(this);
@ -489,84 +486,6 @@ export default class Drawer extends React.Component<DrawerProps> {
); );
} }
renderResizeCtrl() {
const {classnames: cx} = this.props;
return (
<div
className={cx('Drawer-resizeCtrl')}
onMouseDown={this.resizeMouseDown}
>
<div className={cx('Drawer-resizeIcon')}>···</div>
</div>
);
}
resizeMouseDown(e: React.MouseEvent<any>) {
const {position, classPrefix: ns, store} = this.props;
this.drawer = (findDOMNode(this) as HTMLElement).querySelector(
`.${ns}Drawer-content`
) as HTMLElement;
const resizeCtrl = (findDOMNode(this) as HTMLElement).querySelector(
`.${ns}Drawer-content .${ns}Drawer-resizeCtrl`
) as HTMLElement;
const drawerWidth = getComputedStyle(this.drawer).width as string;
const drawerHeight = getComputedStyle(this.drawer).height as string;
store.setResizeCoord(
(position === 'left' &&
e.clientX -
resizeCtrl.offsetWidth -
parseInt(drawerWidth.substring(0, drawerWidth.length - 2))) ||
(position === 'right' &&
document.body.offsetWidth -
e.clientX -
resizeCtrl.offsetWidth -
parseInt(drawerWidth.substring(0, drawerWidth.length - 2))) ||
(position === 'top' &&
e.clientY -
resizeCtrl.offsetHeight -
parseInt(drawerHeight.substring(0, drawerHeight.length - 2))) ||
(position === 'bottom' &&
document.body.offsetHeight -
e.clientY -
resizeCtrl.offsetHeight -
parseInt(drawerHeight.substring(0, drawerHeight.length - 2))) ||
0
);
document.body.addEventListener('mousemove', this.bindResize);
document.body.addEventListener('mouseup', this.removeResize);
}
bindResize(e: any) {
const {position, store} = this.props;
const maxWH = 'calc(100% - 50px)';
const drawerStyle = this.drawer.style;
let wh =
(position === 'left' && e.clientX) ||
(position === 'right' && document.body.offsetWidth - e.clientX) ||
(position === 'top' && e.clientY) ||
(position === 'bottom' && document.body.offsetHeight - e.clientY) ||
0;
wh = wh - store.resizeCoord + 'px';
if (position === 'left' || position === 'right') {
drawerStyle.maxWidth = maxWH;
drawerStyle.width = wh;
}
if (position === 'top' || position === 'bottom') {
drawerStyle.maxHeight = maxWH;
drawerStyle.height = wh;
}
}
removeResize() {
document.body.removeEventListener('mousemove', this.bindResize);
document.body.removeEventListener('mouseup', this.removeResize);
}
openFeedback(dialog: any, ctx: any) { openFeedback(dialog: any, ctx: any) {
return new Promise(resolve => { return new Promise(resolve => {
const {store} = this.props; const {store} = this.props;
@ -615,6 +534,7 @@ export default class Drawer extends React.Component<DrawerProps> {
return ( return (
<Container <Container
resizable={resizable}
classPrefix={ns} classPrefix={ns}
className={className} className={className}
size={size} size={size}
@ -712,8 +632,6 @@ export default class Drawer extends React.Component<DrawerProps> {
} }
) )
: null} : null}
{resizable ? this.renderResizeCtrl() : null}
</Container> </Container>
); );
} }