LiveTailButton.tsx 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143
  1. import React from 'react';
  2. import classNames from 'classnames';
  3. import { css } from 'emotion';
  4. import memoizeOne from 'memoize-one';
  5. import tinycolor from 'tinycolor2';
  6. import { CSSTransition } from 'react-transition-group';
  7. import { GrafanaTheme, GrafanaThemeType, useTheme } from '@grafana/ui';
  8. const getStyles = memoizeOne((theme: GrafanaTheme) => {
  9. const orange = theme.type === GrafanaThemeType.Dark ? '#FF780A' : '#ED5700';
  10. const orangeLighter = tinycolor(orange)
  11. .lighten(10)
  12. .toString();
  13. const pulseTextColor = tinycolor(orange)
  14. .desaturate(90)
  15. .toString();
  16. return {
  17. noRightBorderStyle: css`
  18. label: noRightBorderStyle;
  19. border-right: 0;
  20. `,
  21. liveButton: css`
  22. label: liveButton;
  23. transition: background-color 1s, border-color 1s, color 1s;
  24. margin: 0;
  25. `,
  26. isLive: css`
  27. label: isLive;
  28. border-color: ${orange};
  29. color: ${orange};
  30. background: transparent;
  31. &:focus {
  32. border-color: ${orange};
  33. color: ${orange};
  34. }
  35. &:active,
  36. &:hover {
  37. border-color: ${orangeLighter};
  38. color: ${orangeLighter};
  39. }
  40. `,
  41. isPaused: css`
  42. label: isPaused;
  43. border-color: ${orange};
  44. background: transparent;
  45. animation: pulse 3s ease-out 0s infinite normal forwards;
  46. &:focus {
  47. border-color: ${orange};
  48. }
  49. &:active,
  50. &:hover {
  51. border-color: ${orangeLighter};
  52. }
  53. @keyframes pulse {
  54. 0% {
  55. color: ${pulseTextColor};
  56. }
  57. 50% {
  58. color: ${orange};
  59. }
  60. 100% {
  61. color: ${pulseTextColor};
  62. }
  63. }
  64. `,
  65. stopButtonEnter: css`
  66. label: stopButtonEnter;
  67. width: 0;
  68. opacity: 0;
  69. overflow: hidden;
  70. `,
  71. stopButtonEnterActive: css`
  72. label: stopButtonEnterActive;
  73. opacity: 1;
  74. width: 32px;
  75. transition: opacity 500ms ease-in 50ms, width 500ms ease-in 50ms;
  76. `,
  77. stopButtonExit: css`
  78. label: stopButtonExit;
  79. width: 32px;
  80. opacity: 1;
  81. overflow: hidden;
  82. `,
  83. stopButtonExitActive: css`
  84. label: stopButtonExitActive;
  85. opacity: 0;
  86. width: 0;
  87. transition: opacity 500ms ease-in 50ms, width 500ms ease-in 50ms;
  88. `,
  89. };
  90. });
  91. type LiveTailButtonProps = {
  92. start: () => void;
  93. stop: () => void;
  94. pause: () => void;
  95. resume: () => void;
  96. isLive: boolean;
  97. isPaused: boolean;
  98. };
  99. export function LiveTailButton(props: LiveTailButtonProps) {
  100. const { start, pause, resume, isLive, isPaused, stop } = props;
  101. const theme = useTheme();
  102. const styles = getStyles(theme);
  103. const onClickMain = isLive ? (isPaused ? resume : pause) : start;
  104. return (
  105. <>
  106. <button
  107. className={classNames('btn navbar-button', styles.liveButton, {
  108. [`btn--radius-right-0 ${styles.noRightBorderStyle}`]: isLive,
  109. [styles.isLive]: isLive && !isPaused,
  110. [styles.isPaused]: isLive && isPaused,
  111. })}
  112. onClick={onClickMain}
  113. >
  114. <i className={classNames('fa', isPaused || !isLive ? 'fa-play' : 'fa-pause')} />
  115. &nbsp; Live tailing
  116. </button>
  117. <CSSTransition
  118. mountOnEnter={true}
  119. unmountOnExit={true}
  120. timeout={500}
  121. in={isLive}
  122. classNames={{
  123. enter: styles.stopButtonEnter,
  124. enterActive: styles.stopButtonEnterActive,
  125. exit: styles.stopButtonExit,
  126. exitActive: styles.stopButtonExitActive,
  127. }}
  128. >
  129. <div>
  130. <button className={`btn navbar-button navbar-button--attached ${styles.isLive}`} onClick={stop}>
  131. <i className={'fa fa-stop'} />
  132. </button>
  133. </div>
  134. </CSSTransition>
  135. </>
  136. );
  137. }