mirror of
https://github.com/grafana/grafana.git
synced 2025-02-15 10:03:33 -06:00
* refactor: tooltip is required * refactor: add tooltips * refactor: add tooltips * refactor: add tooltips * refactor: add tooltips * refactor: add tooltips * refactor: add tooltips * refactor: adjust tests * refactor: apply changes from code review * refactor: adjust component for e2e test * refactor: adjust fallback * refactor: apply changes from code review * refactor: apply changes from code review * refactor: set IconButton default as type=button and remove from use cases * refactor: remove aria-labels when duplicated and type=button from use cases * refactor: clean up * refactor: fix tests * refactor: fix type errors * refactor: remove changes in order in order to add them to a separate PR * refactor: set IconButton default as type=button * refactor: remove tooltip * refactor: apply changes requested in review
135 lines
3.1 KiB
TypeScript
135 lines
3.1 KiB
TypeScript
import React, { useMemo } from 'react';
|
|
|
|
import { FieldOverrideEditorProps, SelectableValue } from '@grafana/data';
|
|
import { LineStyle } from '@grafana/schema';
|
|
import { HorizontalGroup, IconButton, RadioButtonGroup, Select } from '@grafana/ui';
|
|
|
|
type LineFill = 'solid' | 'dash' | 'dot';
|
|
|
|
const lineFillOptions: Array<SelectableValue<LineFill>> = [
|
|
{
|
|
label: 'Solid',
|
|
value: 'solid',
|
|
},
|
|
{
|
|
label: 'Dash',
|
|
value: 'dash',
|
|
},
|
|
{
|
|
label: 'Dots',
|
|
value: 'dot',
|
|
},
|
|
];
|
|
|
|
const dashOptions: Array<SelectableValue<string>> = [
|
|
'10, 10', // default
|
|
'10, 15',
|
|
'10, 20',
|
|
'10, 25',
|
|
'10, 30',
|
|
'10, 40',
|
|
'15, 10',
|
|
'20, 10',
|
|
'25, 10',
|
|
'30, 10',
|
|
'40, 10',
|
|
'50, 10',
|
|
'5, 10',
|
|
'30, 3, 3',
|
|
].map((txt) => ({
|
|
label: txt,
|
|
value: txt,
|
|
}));
|
|
|
|
const dotOptions: Array<SelectableValue<string>> = [
|
|
'0, 10', // default
|
|
'0, 20',
|
|
'0, 30',
|
|
'0, 40',
|
|
'0, 3, 3',
|
|
].map((txt) => ({
|
|
label: txt,
|
|
value: txt,
|
|
}));
|
|
|
|
type Props = FieldOverrideEditorProps<LineStyle, unknown>;
|
|
|
|
export const LineStyleEditor = ({ value, onChange }: Props) => {
|
|
const options = useMemo(() => (value?.fill === 'dash' ? dashOptions : dotOptions), [value]);
|
|
const current = useMemo(() => {
|
|
if (!value?.dash?.length) {
|
|
return options[0];
|
|
}
|
|
const str = value.dash?.join(', ');
|
|
const val = options.find((o) => o.value === str);
|
|
if (!val) {
|
|
return {
|
|
label: str,
|
|
value: str,
|
|
};
|
|
}
|
|
return val;
|
|
}, [value, options]);
|
|
|
|
return (
|
|
<HorizontalGroup>
|
|
<RadioButtonGroup
|
|
value={value?.fill || 'solid'}
|
|
options={lineFillOptions}
|
|
onChange={(v) => {
|
|
let dash: number[] | undefined = undefined;
|
|
if (v === 'dot') {
|
|
dash = parseText(dotOptions[0].value!);
|
|
} else if (v === 'dash') {
|
|
dash = parseText(dashOptions[0].value!);
|
|
}
|
|
onChange({
|
|
...value,
|
|
fill: v!,
|
|
dash,
|
|
});
|
|
}}
|
|
/>
|
|
{value?.fill && value?.fill !== 'solid' && (
|
|
<>
|
|
<Select
|
|
allowCustomValue={true}
|
|
options={options}
|
|
value={current}
|
|
width={20}
|
|
onChange={(v) => {
|
|
onChange({
|
|
...value,
|
|
dash: parseText(v.value ?? ''),
|
|
});
|
|
}}
|
|
formatCreateLabel={(t) => `Segments: ${parseText(t).join(', ')}`}
|
|
/>
|
|
<div>
|
|
|
|
<a
|
|
title="The input expects a segment list"
|
|
href="https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/setLineDash#Parameters"
|
|
target="_blank"
|
|
rel="noreferrer"
|
|
>
|
|
<IconButton name="question-circle" tooltip="Help" />
|
|
</a>
|
|
</div>
|
|
</>
|
|
)}
|
|
</HorizontalGroup>
|
|
);
|
|
};
|
|
|
|
function parseText(txt: string): number[] {
|
|
const segments: number[] = [];
|
|
for (const s of txt.split(/(?:,| )+/)) {
|
|
const num = Number.parseInt(s, 10);
|
|
if (!isNaN(num)) {
|
|
segments.push(num);
|
|
}
|
|
}
|
|
return segments;
|
|
}
|