import React, { FunctionComponent, useContext, useState } from 'react'; import { css, cx } from 'emotion'; import { GrafanaTheme } from '@grafana/data'; import { ThemeContext } from '../../themes/ThemeContext'; import { stylesFactory } from '../../themes/stylesFactory'; import { Icon } from '../Icon/Icon'; const getStyles = stylesFactory((theme: GrafanaTheme) => ({ collapse: css` label: collapse; margin-bottom: ${theme.spacing.sm}; `, collapseBody: css` label: collapse__body; padding: ${theme.panelPadding}px; `, loader: css` label: collapse__loader; height: 2px; position: relative; overflow: hidden; background: none; margin: ${theme.spacing.xs}; `, loaderActive: css` label: collapse__loader_active; &:after { content: ' '; display: block; width: 25%; top: 0; top: -50%; height: 250%; position: absolute; animation: loader 2s cubic-bezier(0.17, 0.67, 0.83, 0.67) 500ms; animation-iteration-count: 100; left: -25%; background: ${theme.colors.blue}; } @keyframes loader { from { left: -25%; opacity: 0.1; } to { left: 100%; opacity: 1; } } `, header: css` label: collapse__header; padding: ${theme.spacing.sm} ${theme.spacing.md}; display: flex; cursor: inherit; transition: all 0.1s linear; cursor: pointer; `, headerCollapsed: css` label: collapse__header--collapsed; cursor: pointer; padding: ${theme.spacing.sm} ${theme.spacing.md}; `, headerButtons: css` label: collapse__header-buttons; margin-right: ${theme.spacing.sm}; font-size: ${theme.typography.size.lg}; line-height: ${theme.typography.heading.h6}; display: inherit; `, headerButtonsCollapsed: css` label: collapse__header-buttons--collapsed; display: none; `, headerLabel: css` label: collapse__header-label; font-weight: ${theme.typography.weight.semibold}; margin-right: ${theme.spacing.sm}; font-size: ${theme.typography.heading.h6}; `, })); interface Props { isOpen?: boolean; label: string; loading?: boolean; collapsible?: boolean; onToggle?: (isOpen: boolean) => void; } export const ControlledCollapse: FunctionComponent = ({ isOpen, onToggle, ...otherProps }) => { const [open, setOpen] = useState(isOpen); return ( { setOpen(!open); if (onToggle) { onToggle(!open); } }} /> ); }; export const Collapse: FunctionComponent = ({ isOpen, label, loading, collapsible, onToggle, children }) => { const theme = useContext(ThemeContext); const style = getStyles(theme); const onClickToggle = () => { if (onToggle) { onToggle(!isOpen); } }; const panelClass = cx([style.collapse, 'panel-container']); const loaderClass = loading ? cx([style.loader, style.loaderActive]) : cx([style.loader]); const headerClass = collapsible ? cx([style.header]) : cx([style.headerCollapsed]); const headerButtonsClass = collapsible ? cx([style.headerButtons]) : cx([style.headerButtonsCollapsed]); return (
{label}
{isOpen && (
{children}
)}
); }; Collapse.displayName = 'Collapse';