github.com/grafana/pyroscope@v1.18.0/public/app/ui/Box.tsx (about) 1 import React, { useState } from 'react'; 2 import classNames from 'classnames/bind'; 3 import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; 4 import { faChevronDown } from '@fortawesome/free-solid-svg-icons/faChevronDown'; 5 import styles from './Box.module.scss'; 6 import { LoadingOverlay } from './LoadingOverlay'; 7 8 const cx = classNames.bind(styles); 9 /** 10 * Box renders its children with a box around it 11 */ 12 13 export interface BoxProps { 14 children: React.ReactNode; 15 // Disable padding, disabled by default since it should be used for more special cases 16 noPadding?: boolean; 17 18 // Additional classnames 19 className?: string; 20 isLoading?: boolean; 21 } 22 export default function Box(props: BoxProps) { 23 const { children, noPadding, className = '', isLoading = false } = props; 24 25 const paddingClass = noPadding ? '' : styles.padding; 26 27 return ( 28 <div className={`${styles.box} ${paddingClass} ${className}`}> 29 <LoadingOverlay active={isLoading}>{children}</LoadingOverlay> 30 </div> 31 ); 32 } 33 34 export interface CollapseBoxProps { 35 /** must be non empty */ 36 title: string; 37 children: React.ReactNode; 38 isLoading?: boolean; 39 } 40 41 export function CollapseBox({ title, children, isLoading }: CollapseBoxProps) { 42 const [collapsed, toggleCollapse] = useState(false); 43 44 return ( 45 <div className={styles.collapseBox}> 46 <div 47 onClick={() => toggleCollapse((c) => !c)} 48 className={styles.collapseTitle} 49 aria-hidden 50 > 51 <div>{title}</div> 52 <FontAwesomeIcon 53 className={cx({ 54 [styles.collapseIcon]: true, 55 [styles.collapsed]: collapsed, 56 })} 57 icon={faChevronDown} 58 /> 59 </div> 60 <Box 61 className={cx({ 62 [styles.collapsedContent]: collapsed, 63 })} 64 isLoading={isLoading} 65 > 66 {children} 67 </Box> 68 </div> 69 ); 70 }