import { css, cx } from '@emotion/css'; import { PureComponent } from 'react'; import * as React from 'react'; import { GrafanaTheme2, VariableOption } from '@grafana/data'; import { selectors } from '@grafana/e2e-selectors'; import { Tooltip, Themeable2, withTheme2, clearButtonStyles, stylesFactory } from '@grafana/ui'; import { Trans, t } from 'app/core/internationalization'; import { ALL_VARIABLE_VALUE } from '../../constants'; export interface Props extends React.HTMLProps, Themeable2 { multi: boolean; values: VariableOption[]; selectedValues: VariableOption[]; highlightIndex: number; onToggle: (option: VariableOption, clearOthers: boolean) => void; onToggleAll: () => void; /** * Used for aria-controls */ id: string; } class VariableOptions extends PureComponent { onToggle = (option: VariableOption) => (event: React.MouseEvent) => { const clearOthers = event.shiftKey || event.ctrlKey || event.metaKey; this.handleEvent(event); this.props.onToggle(option, clearOthers); }; onToggleAll = (event: React.MouseEvent) => { this.handleEvent(event); this.props.onToggleAll(); }; handleEvent(event: React.MouseEvent) { event.preventDefault(); event.stopPropagation(); } render() { // Don't want to pass faulty rest props to the div const { multi, values, highlightIndex, selectedValues, onToggle, onToggleAll, theme, ...restProps } = this.props; const styles = getStyles(theme); return (
    {this.renderMultiToggle()} {values.map((option, index) => this.renderOption(option, index))}
); } renderOption(option: VariableOption, index: number) { const { highlightIndex, multi, theme } = this.props; const styles = getStyles(theme); const isAllOption = option.value === ALL_VARIABLE_VALUE; return (
  • ); } renderMultiToggle() { const { multi, selectedValues, theme, values } = this.props; const styles = getStyles(theme); const isAllOptionConfigured = values.some((option) => option.value === ALL_VARIABLE_VALUE); if (!multi) { return null; } const tooltipContent = () => Clear selections; return ( ); } } const getStyles = stylesFactory((theme: GrafanaTheme2) => { const checkboxImageUrl = theme.isDark ? 'public/img/checkbox.png' : 'public/img/checkbox_white.png'; return { hideVariableOptionIcon: css({ display: 'none', }), highlighted: css({ backgroundColor: theme.colors.action.hover, }), noStyledButton: css({ width: '100%', textAlign: 'left', }), variableOption: css({ display: 'block', padding: '2px 27px 0 8px', position: 'relative', whiteSpace: 'nowrap', minWidth: '115px', ['&:hover']: { backgroundColor: theme.colors.action.hover, }, }), variableOptionColumnHeader: css({ paddingTop: '5px', paddingBottom: '5px', marginBottom: '5px', }), variableOptionIcon: css({ display: 'inline-block', width: '24px', height: '18px', position: 'relative', top: '4px', background: `url(${checkboxImageUrl}) left top no-repeat`, }), variableOptionIconManySelected: css({ background: `url(${checkboxImageUrl}) 0px -36px no-repeat`, }), variableOptionIconSelected: css({ background: `url(${checkboxImageUrl}) 0px -18px no-repeat`, }), variableValueDropdown: css({ backgroundColor: theme.colors.background.primary, border: `1px solid ${theme.colors.border.weak}`, borderRadius: theme.shape.borderRadius(2), boxShadow: theme.shadows.z2, position: 'absolute', top: theme.spacing(theme.components.height.md), maxHeight: '400px', minHeight: '150px', minWidth: '150px', overflowY: 'auto', overflowX: 'hidden', zIndex: theme.zIndex.typeahead, }), variableOptionsColumn: css({ maxHeight: '350px', display: 'table-cell', lineHeight: '26px', listStyleType: 'none', }), variableOptionsWrapper: css({ display: 'table', width: '100%', }), variableAllOption: css({ borderBottom: `1px solid ${theme.colors.border.weak}`, paddingBottom: theme.spacing(1), }), noPaddingBotton: css({ paddingBottom: 0, }), }; }); export default withTheme2(VariableOptions);