PanelResizer.tsx 2.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182
  1. import React, { PureComponent } from 'react';
  2. import { throttle } from 'lodash';
  3. import Draggable, { DraggableEventHandler } from 'react-draggable';
  4. import { PanelModel } from '../state/PanelModel';
  5. interface Props {
  6. isEditing: boolean;
  7. render: (styles: object) => JSX.Element;
  8. panel: PanelModel;
  9. }
  10. interface State {
  11. editorHeight: number;
  12. }
  13. export class PanelResizer extends PureComponent<Props, State> {
  14. initialHeight: number = Math.floor(document.documentElement.scrollHeight * 0.3);
  15. prevEditorHeight: number;
  16. throttledChangeHeight: (height: number) => void;
  17. throttledResizeDone: () => void;
  18. noStyles: object = {};
  19. constructor(props) {
  20. super(props);
  21. const { panel } = this.props;
  22. this.state = {
  23. editorHeight: this.initialHeight,
  24. };
  25. this.throttledChangeHeight = throttle(this.changeHeight, 20, { trailing: true });
  26. this.throttledResizeDone = throttle(() => {
  27. panel.resizeDone();
  28. }, 50);
  29. }
  30. get largestHeight() {
  31. return document.documentElement.scrollHeight * 0.9;
  32. }
  33. get smallestHeight() {
  34. return 100;
  35. }
  36. changeHeight = (height: number) => {
  37. const sh = this.smallestHeight;
  38. const lh = this.largestHeight;
  39. height = height < sh ? sh : height;
  40. height = height > lh ? lh : height;
  41. this.prevEditorHeight = this.state.editorHeight;
  42. this.setState({
  43. editorHeight: height,
  44. });
  45. };
  46. onDrag: DraggableEventHandler = (evt, data) => {
  47. const newHeight = this.state.editorHeight + data.y;
  48. this.throttledChangeHeight(newHeight);
  49. this.throttledResizeDone();
  50. };
  51. render() {
  52. const { render, isEditing } = this.props;
  53. const { editorHeight } = this.state;
  54. return (
  55. <>
  56. {render(isEditing ? { height: editorHeight } : this.noStyles)}
  57. {isEditing && (
  58. <div className="panel-editor-container__resizer">
  59. <Draggable axis="y" grid={[100, 1]} onDrag={this.onDrag} position={{ x: 0, y: 0 }}>
  60. <div className="panel-editor-resizer">
  61. <div className="panel-editor-resizer__handle" />
  62. </div>
  63. </Draggable>
  64. </div>
  65. )}
  66. </>
  67. );
  68. }
  69. }