QueryOptionGroup.tsx 2.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283
  1. import { css } from '@emotion/css';
  2. import React from 'react';
  3. import { useToggle } from 'react-use';
  4. import { GrafanaTheme2 } from '@grafana/data';
  5. import { Stack } from '@grafana/experimental';
  6. import { Icon, useStyles2 } from '@grafana/ui';
  7. export interface Props {
  8. title: string;
  9. collapsedInfo: string[];
  10. children: React.ReactNode;
  11. }
  12. export function QueryOptionGroup({ title, children, collapsedInfo }: Props) {
  13. const [isOpen, toggleOpen] = useToggle(false);
  14. const styles = useStyles2(getStyles);
  15. return (
  16. <Stack gap={0} direction="column">
  17. <div className={styles.header} onClick={toggleOpen} title="Click to edit options">
  18. <div className={styles.toggle}>
  19. <Icon name={isOpen ? 'angle-down' : 'angle-right'} />
  20. </div>
  21. <h6 className={styles.title}>{title}</h6>
  22. {!isOpen && (
  23. <div className={styles.description}>
  24. {collapsedInfo.map((x, i) => (
  25. <span key={i}>{x}</span>
  26. ))}
  27. </div>
  28. )}
  29. </div>
  30. {isOpen && <div className={styles.body}>{children}</div>}
  31. </Stack>
  32. );
  33. }
  34. const getStyles = (theme: GrafanaTheme2) => {
  35. return {
  36. switchLabel: css({
  37. color: theme.colors.text.secondary,
  38. cursor: 'pointer',
  39. fontSize: theme.typography.bodySmall.fontSize,
  40. '&:hover': {
  41. color: theme.colors.text.primary,
  42. },
  43. }),
  44. header: css({
  45. display: 'flex',
  46. cursor: 'pointer',
  47. alignItems: 'baseline',
  48. color: theme.colors.text.primary,
  49. '&:hover': {
  50. background: theme.colors.emphasize(theme.colors.background.primary, 0.03),
  51. },
  52. }),
  53. title: css({
  54. flexGrow: 1,
  55. overflow: 'hidden',
  56. fontSize: theme.typography.bodySmall.fontSize,
  57. fontWeight: theme.typography.fontWeightMedium,
  58. margin: 0,
  59. }),
  60. description: css({
  61. color: theme.colors.text.secondary,
  62. fontSize: theme.typography.bodySmall.fontSize,
  63. paddingLeft: theme.spacing(2),
  64. gap: theme.spacing(2),
  65. display: 'flex',
  66. }),
  67. body: css({
  68. display: 'flex',
  69. paddingTop: theme.spacing(2),
  70. gap: theme.spacing(2),
  71. flexWrap: 'wrap',
  72. }),
  73. toggle: css({
  74. color: theme.colors.text.secondary,
  75. marginRight: `${theme.spacing(1)}`,
  76. }),
  77. };
  78. };