FunctionEditor.tsx 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110
  1. import React from 'react';
  2. import { PopperController, Popper } from '@grafana/ui';
  3. import rst2html from 'rst2html';
  4. import { FunctionDescriptor, FunctionEditorControlsProps, FunctionEditorControls } from './FunctionEditorControls';
  5. interface FunctionEditorProps extends FunctionEditorControlsProps {
  6. func: FunctionDescriptor;
  7. }
  8. interface FunctionEditorState {
  9. showingDescription: boolean;
  10. }
  11. class FunctionEditor extends React.PureComponent<FunctionEditorProps, FunctionEditorState> {
  12. private triggerRef = React.createRef<HTMLSpanElement>();
  13. constructor(props: FunctionEditorProps) {
  14. super(props);
  15. this.state = {
  16. showingDescription: false,
  17. };
  18. }
  19. renderContent = ({ updatePopperPosition }) => {
  20. const {
  21. onMoveLeft,
  22. onMoveRight,
  23. func: {
  24. def: { name, description },
  25. },
  26. } = this.props;
  27. const { showingDescription } = this.state;
  28. if (showingDescription) {
  29. return (
  30. <div style={{ overflow: 'auto', maxHeight: '30rem', textAlign: 'left', fontWeight: 'normal' }}>
  31. <h4 style={{ color: 'white' }}> {name} </h4>
  32. <div
  33. dangerouslySetInnerHTML={{
  34. __html: rst2html(description),
  35. }}
  36. />
  37. </div>
  38. );
  39. }
  40. return (
  41. <FunctionEditorControls
  42. {...this.props}
  43. onMoveLeft={() => {
  44. onMoveLeft(this.props.func);
  45. updatePopperPosition();
  46. }}
  47. onMoveRight={() => {
  48. onMoveRight(this.props.func);
  49. updatePopperPosition();
  50. }}
  51. onDescriptionShow={() => {
  52. this.setState({ showingDescription: true }, () => {
  53. updatePopperPosition();
  54. });
  55. }}
  56. />
  57. );
  58. };
  59. render() {
  60. return (
  61. <PopperController content={this.renderContent} placement="top" hideAfter={300}>
  62. {(showPopper, hidePopper, popperProps) => {
  63. return (
  64. <>
  65. {this.triggerRef && (
  66. <Popper
  67. {...popperProps}
  68. referenceElement={this.triggerRef.current}
  69. wrapperClassName="popper"
  70. className="popper__background"
  71. onMouseLeave={() => {
  72. this.setState({ showingDescription: false });
  73. hidePopper();
  74. }}
  75. onMouseEnter={showPopper}
  76. renderArrow={({ arrowProps, placement }) => (
  77. <div className="popper__arrow" data-placement={placement} {...arrowProps} />
  78. )}
  79. />
  80. )}
  81. <span
  82. ref={this.triggerRef}
  83. onClick={popperProps.show ? hidePopper : showPopper}
  84. onMouseLeave={() => {
  85. hidePopper();
  86. this.setState({ showingDescription: false });
  87. }}
  88. style={{ cursor: 'pointer' }}
  89. >
  90. {this.props.func.def.name}
  91. </span>
  92. </>
  93. );
  94. }}
  95. </PopperController>
  96. );
  97. }
  98. }
  99. export { FunctionEditor };