1import { css, cx } from '@emotion/css'; 2import { GrafanaTheme2 } from '@grafana/data'; 3import { Select, stylesFactory, useTheme2 } from '@grafana/ui'; 4import { 5 SelectContainerProps, 6 SelectContainer as BaseSelectContainer, 7} from '@grafana/ui/src/components/Select/SelectContainer'; 8import { SelectCommonProps } from '@grafana/ui/src/components/Select/types'; 9import React, { useState } from 'react'; 10import { GroupTypeBase } from 'react-select'; 11 12interface InlineSelectProps<T> extends SelectCommonProps<T> { 13 label?: string; 14} 15 16function InlineSelect<T>({ label: labelProp, ...props }: InlineSelectProps<T>) { 17 const theme = useTheme2(); 18 const [id] = useState(() => Math.random().toString(16).slice(2)); 19 const styles = getSelectStyles(theme); 20 const components = { 21 SelectContainer, 22 ValueContainer, 23 SingleValue: ValueContainer, 24 }; 25 26 return ( 27 <div className={styles.root}> 28 {labelProp && ( 29 <label className={styles.label} htmlFor={id}> 30 {labelProp} 31 {':'} 32 </label> 33 )} 34 <Select openMenuOnFocus inputId={id} {...props} width="auto" components={components} /> 35 </div> 36 ); 37} 38 39export default InlineSelect; 40 41const SelectContainer = <Option, isMulti extends boolean, Group extends GroupTypeBase<Option>>( 42 props: SelectContainerProps<Option, isMulti, Group> 43) => { 44 const { children } = props; 45 46 const theme = useTheme2(); 47 const styles = getSelectStyles(theme); 48 49 return ( 50 <BaseSelectContainer {...props} className={cx(props.className, styles.container)}> 51 {children} 52 </BaseSelectContainer> 53 ); 54}; 55 56const ValueContainer = <Option, isMulti extends boolean, Group extends GroupTypeBase<Option>>( 57 props: SelectContainerProps<Option, isMulti, Group> 58) => { 59 const { className, children } = props; 60 const theme = useTheme2(); 61 const styles = getSelectStyles(theme); 62 63 return <div className={cx(className, styles.valueContainer)}>{children}</div>; 64}; 65 66const getSelectStyles = stylesFactory((theme: GrafanaTheme2) => ({ 67 root: css({ 68 display: 'flex', 69 fontSize: 12, 70 alignItems: 'center', 71 }), 72 73 label: css({ 74 color: theme.colors.text.secondary, 75 }), 76 77 container: css({ 78 background: 'none', 79 borderColor: 'transparent', 80 }), 81 82 valueContainer: css({ 83 display: 'flex', 84 alignItems: 'center', 85 flex: 'initial', 86 color: theme.colors.text.secondary, 87 fontSize: 12, 88 }), 89})); 90