UI: Use SelectableValue as Segment value (#20867)
* Use SelectableValue for segment value * Update cloudwatch components to use new segment props
This commit is contained in:
@@ -18,8 +18,9 @@ const toOption = (value: any) => ({ label: value, value: value });
|
||||
|
||||
SegmentStories.add('Array Options', () => {
|
||||
const options = ['Option1', 'Option2', 'OptionWithLooongLabel', 'Option4'].map(toOption);
|
||||
options[0].label = 'Option1 Label';
|
||||
return (
|
||||
<UseState initialState={options[0].value}>
|
||||
<UseState initialState={options[0] as SelectableValue}>
|
||||
{(value, updateValue) => (
|
||||
<>
|
||||
<div className="gf-form-inline">
|
||||
@@ -29,9 +30,9 @@ SegmentStories.add('Array Options', () => {
|
||||
<Segment
|
||||
value={value}
|
||||
options={options}
|
||||
onChange={(value: SelectableValue<string>) => {
|
||||
updateValue(value);
|
||||
action('Segment value changed')(value);
|
||||
onChange={item => {
|
||||
updateValue(item);
|
||||
action('Segment value changed')(item.value);
|
||||
}}
|
||||
/>
|
||||
<Segment
|
||||
@@ -53,7 +54,7 @@ const groupedOptions = [
|
||||
|
||||
SegmentStories.add('Grouped Array Options', () => {
|
||||
return (
|
||||
<UseState initialState={groupedOptions[0].options[0].value}>
|
||||
<UseState initialState={groupedOptions[0].options[0] as SelectableValue}>
|
||||
{(value, updateValue) => (
|
||||
<>
|
||||
<div className="gf-form-inline">
|
||||
@@ -63,9 +64,9 @@ SegmentStories.add('Grouped Array Options', () => {
|
||||
<Segment
|
||||
value={value}
|
||||
options={groupedOptions}
|
||||
onChange={(value: SelectableValue<string>) => {
|
||||
updateValue(value);
|
||||
action('Segment value changed')(value);
|
||||
onChange={item => {
|
||||
updateValue(item);
|
||||
action('Segment value changed')(item.value);
|
||||
}}
|
||||
/>
|
||||
<Segment
|
||||
@@ -83,7 +84,7 @@ SegmentStories.add('Grouped Array Options', () => {
|
||||
SegmentStories.add('With custom options allowed', () => {
|
||||
const options = ['Option1', 'Option2', 'OptionWithLooongLabel', 'Option4'].map(toOption);
|
||||
return (
|
||||
<UseState initialState={options[0].value}>
|
||||
<UseState initialState={options[0] as SelectableValue}>
|
||||
{(value, updateValue) => (
|
||||
<>
|
||||
<div className="gf-form-inline">
|
||||
@@ -94,9 +95,9 @@ SegmentStories.add('With custom options allowed', () => {
|
||||
allowCustomValue
|
||||
value={value}
|
||||
options={options}
|
||||
onChange={(value: SelectableValue<string>) => {
|
||||
updateValue(value);
|
||||
action('Segment value changed')(value);
|
||||
onChange={item => {
|
||||
updateValue(item);
|
||||
action('Segment value changed')(item.value);
|
||||
}}
|
||||
/>
|
||||
<Segment
|
||||
@@ -112,11 +113,11 @@ SegmentStories.add('With custom options allowed', () => {
|
||||
);
|
||||
});
|
||||
|
||||
const CustomLabelComponent = ({ value }: any) => <div className="gf-form-label">custom({value})</div>;
|
||||
const CustomLabelComponent = ({ value: { value } }: any) => <div className="gf-form-label">custom({value})</div>;
|
||||
|
||||
SegmentStories.add('Custom Label Field', () => {
|
||||
return (
|
||||
<UseState initialState={groupedOptions[0].options[0].value}>
|
||||
<UseState initialState={groupedOptions[0].options[0] as SelectableValue}>
|
||||
{(value, setValue) => (
|
||||
<>
|
||||
<div className="gf-form-inline">
|
||||
@@ -126,9 +127,9 @@ SegmentStories.add('Custom Label Field', () => {
|
||||
<Segment
|
||||
Component={<CustomLabelComponent value={value} />}
|
||||
options={groupedOptions}
|
||||
onChange={(value: SelectableValue<string>) => {
|
||||
setValue(value);
|
||||
action('Segment value changed')(value);
|
||||
onChange={item => {
|
||||
setValue(item);
|
||||
action('Segment value changed')(item.value);
|
||||
}}
|
||||
/>
|
||||
<Segment
|
||||
|
||||
@@ -18,18 +18,23 @@ export function Segment<T>({
|
||||
const [Label, width, expanded, setExpanded] = useExpandableLabel(false);
|
||||
|
||||
if (!expanded) {
|
||||
return <Label Component={Component || <a className={cx('gf-form-label', 'query-part', className)}>{value}</a>} />;
|
||||
return (
|
||||
<Label
|
||||
Component={Component || <a className={cx('gf-form-label', 'query-part', className)}>{value && value.label}</a>}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<SegmentSelect
|
||||
width={width}
|
||||
value={value}
|
||||
options={options}
|
||||
width={width}
|
||||
onClickOutside={() => setExpanded(false)}
|
||||
allowCustomValue={allowCustomValue}
|
||||
onChange={value => {
|
||||
onChange={item => {
|
||||
setExpanded(false);
|
||||
onChange(value);
|
||||
onChange(item);
|
||||
}}
|
||||
/>
|
||||
);
|
||||
|
||||
@@ -20,7 +20,7 @@ const loadOptions = (options: any): Promise<Array<SelectableValue<string>>> =>
|
||||
SegmentStories.add('Array Options', () => {
|
||||
const options = ['Option1', 'Option2', 'OptionWithLooongLabel', 'Option4'].map(toOption);
|
||||
return (
|
||||
<UseState initialState={options[0].value}>
|
||||
<UseState initialState={options[0] as SelectableValue}>
|
||||
{(value, updateValue) => (
|
||||
<>
|
||||
<div className="gf-form-inline">
|
||||
@@ -30,9 +30,9 @@ SegmentStories.add('Array Options', () => {
|
||||
<SegmentAsync
|
||||
value={value}
|
||||
loadOptions={() => loadOptions(options)}
|
||||
onChange={value => {
|
||||
updateValue(value);
|
||||
action('Segment value changed')(value);
|
||||
onChange={item => {
|
||||
updateValue(item);
|
||||
action('Segment value changed')(item.value);
|
||||
}}
|
||||
/>
|
||||
<SegmentAsync
|
||||
@@ -54,7 +54,7 @@ const groupedOptions = [
|
||||
|
||||
SegmentStories.add('Grouped Array Options', () => {
|
||||
return (
|
||||
<UseState initialState={groupedOptions[0].options[0].value}>
|
||||
<UseState initialState={groupedOptions[0].options[0] as SelectableValue}>
|
||||
{(value, updateValue) => (
|
||||
<>
|
||||
<div className="gf-form-inline">
|
||||
@@ -64,9 +64,9 @@ SegmentStories.add('Grouped Array Options', () => {
|
||||
<SegmentAsync
|
||||
value={value}
|
||||
loadOptions={() => loadOptions(groupedOptions)}
|
||||
onChange={value => {
|
||||
updateValue(value);
|
||||
action('Segment value changed')(value);
|
||||
onChange={item => {
|
||||
updateValue(item);
|
||||
action('Segment value changed')(item.value);
|
||||
}}
|
||||
/>
|
||||
<SegmentAsync
|
||||
@@ -84,7 +84,7 @@ SegmentStories.add('Grouped Array Options', () => {
|
||||
SegmentStories.add('With custom options allowed', () => {
|
||||
const options = ['Option1', 'Option2', 'OptionWithLooongLabel', 'Option4'].map(toOption);
|
||||
return (
|
||||
<UseState initialState={options[0].value}>
|
||||
<UseState initialState={options[0] as SelectableValue}>
|
||||
{(value, updateValue) => (
|
||||
<>
|
||||
<div className="gf-form-inline">
|
||||
@@ -95,9 +95,9 @@ SegmentStories.add('With custom options allowed', () => {
|
||||
allowCustomValue
|
||||
value={value}
|
||||
loadOptions={() => loadOptions(options)}
|
||||
onChange={value => {
|
||||
updateValue(value);
|
||||
action('Segment value changed')(value);
|
||||
onChange={item => {
|
||||
updateValue(item);
|
||||
action('Segment value changed')(item.value);
|
||||
}}
|
||||
/>
|
||||
<SegmentAsync
|
||||
@@ -113,10 +113,10 @@ SegmentStories.add('With custom options allowed', () => {
|
||||
);
|
||||
});
|
||||
|
||||
const CustomLabelComponent = ({ value }: any) => <div className="gf-form-label">custom({value})</div>;
|
||||
const CustomLabelComponent = ({ value: { value } }: any) => <div className="gf-form-label">custom({value})</div>;
|
||||
SegmentStories.add('Custom Label Field', () => {
|
||||
return (
|
||||
<UseState initialState={groupedOptions[0].options[0].value}>
|
||||
<UseState initialState={groupedOptions[0].options[0] as SelectableValue}>
|
||||
{(value, updateValue) => (
|
||||
<>
|
||||
<div className="gf-form-inline">
|
||||
@@ -126,9 +126,9 @@ SegmentStories.add('Custom Label Field', () => {
|
||||
<SegmentAsync
|
||||
Component={<CustomLabelComponent value={value} />}
|
||||
loadOptions={() => loadOptions(groupedOptions)}
|
||||
onChange={value => {
|
||||
updateValue(value);
|
||||
action('Segment value changed')(value);
|
||||
onChange={item => {
|
||||
updateValue(item);
|
||||
action('Segment value changed')(item.value);
|
||||
}}
|
||||
/>
|
||||
<SegmentAsync
|
||||
|
||||
@@ -29,15 +29,16 @@ export function SegmentAsync<T>({
|
||||
setLoadedOptions(opts);
|
||||
setSelectPlaceholder(opts.length ? '' : 'No options found');
|
||||
}}
|
||||
Component={Component || <a className={cx('gf-form-label', 'query-part', className)}>{value}</a>}
|
||||
Component={Component || <a className={cx('gf-form-label', 'query-part', className)}>{value && value.label}</a>}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<SegmentSelect
|
||||
width={width}
|
||||
value={value}
|
||||
options={loadedOptions}
|
||||
width={width}
|
||||
noOptionsMessage={selectPlaceholder}
|
||||
allowCustomValue={allowCustomValue}
|
||||
onClickOutside={() => {
|
||||
@@ -45,11 +46,11 @@ export function SegmentAsync<T>({
|
||||
setLoadedOptions([]);
|
||||
setExpanded(false);
|
||||
}}
|
||||
onChange={value => {
|
||||
onChange={item => {
|
||||
setSelectPlaceholder('');
|
||||
setLoadedOptions([]);
|
||||
setExpanded(false);
|
||||
onChange(value);
|
||||
onChange(item);
|
||||
}}
|
||||
/>
|
||||
);
|
||||
|
||||
@@ -5,8 +5,9 @@ import { SelectableValue } from '@grafana/data';
|
||||
import { Select } from '../Select/Select';
|
||||
|
||||
export interface Props<T> {
|
||||
value?: SelectableValue<T>;
|
||||
options: Array<SelectableValue<T>>;
|
||||
onChange: (value: T) => void;
|
||||
onChange: (item: SelectableValue<T>) => void;
|
||||
onClickOutside: () => void;
|
||||
width: number;
|
||||
noOptionsMessage?: string;
|
||||
@@ -14,6 +15,7 @@ export interface Props<T> {
|
||||
}
|
||||
|
||||
export function SegmentSelect<T>({
|
||||
value,
|
||||
options = [],
|
||||
onChange,
|
||||
onClickOutside,
|
||||
@@ -39,8 +41,9 @@ export function SegmentSelect<T>({
|
||||
placeholder=""
|
||||
autoFocus={true}
|
||||
isOpen={true}
|
||||
onChange={({ value }) => onChange(value!)}
|
||||
onChange={onChange}
|
||||
options={options}
|
||||
value={value}
|
||||
allowCustomValue={allowCustomValue}
|
||||
/>
|
||||
</div>
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
import { ReactElement } from 'react';
|
||||
import { SelectableValue } from '@grafana/data';
|
||||
|
||||
export interface SegmentProps<T> {
|
||||
onChange: (item: T) => void;
|
||||
value?: T;
|
||||
onChange: (item: SelectableValue<T>) => void;
|
||||
value?: SelectableValue<T>;
|
||||
Component?: ReactElement;
|
||||
className?: string;
|
||||
allowCustomValue?: boolean;
|
||||
|
||||
Reference in New Issue
Block a user