FunctionEditor.tsx 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104
  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 { onMoveLeft, onMoveRight, func: { def: { name, description } } } = this.props;
  21. const { showingDescription } = this.state;
  22. if (showingDescription) {
  23. return (
  24. <div style={{ overflow: 'auto', maxHeight: '30rem', textAlign: 'left', fontWeight: 'normal' }}>
  25. <h4 style={{ color: 'white' }}> {name} </h4>
  26. <div
  27. dangerouslySetInnerHTML={{
  28. __html: rst2html(description),
  29. }}
  30. />
  31. </div>
  32. );
  33. }
  34. return (
  35. <FunctionEditorControls
  36. {...this.props}
  37. onMoveLeft={() => {
  38. onMoveLeft(this.props.func);
  39. updatePopperPosition();
  40. }}
  41. onMoveRight={() => {
  42. onMoveRight(this.props.func);
  43. updatePopperPosition();
  44. }}
  45. onDescriptionShow={() => {
  46. this.setState({ showingDescription: true }, () => {
  47. updatePopperPosition();
  48. });
  49. }}
  50. />
  51. );
  52. };
  53. render() {
  54. return (
  55. <PopperController content={this.renderContent} placement="top" hideAfter={300}>
  56. {(showPopper, hidePopper, popperProps) => {
  57. return (
  58. <>
  59. {this.triggerRef && (
  60. <Popper
  61. {...popperProps}
  62. referenceElement={this.triggerRef.current}
  63. wrapperClassName="popper"
  64. className="popper__background"
  65. onMouseLeave={() => {
  66. this.setState({ showingDescription: false });
  67. hidePopper();
  68. }}
  69. onMouseEnter={showPopper}
  70. renderArrow={({ arrowProps, placement }) => (
  71. <div className="popper__arrow" data-placement={placement} {...arrowProps} />
  72. )}
  73. />
  74. )}
  75. <span
  76. ref={this.triggerRef}
  77. onClick={popperProps.show ? hidePopper : showPopper}
  78. onMouseLeave={() => {
  79. hidePopper();
  80. this.setState({ showingDescription: false });
  81. }}
  82. style={{ cursor: 'pointer' }}
  83. >
  84. {this.props.func.def.name}
  85. </span>
  86. </>
  87. );
  88. }}
  89. </PopperController>
  90. );
  91. }
  92. }
  93. export { FunctionEditor };