PanelResizer.tsx 2.0 KB

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