|
1 | 1 | import { css } from '@emotion/css'; |
2 | 2 | import { noop } from 'lodash'; |
3 | | -import React, { PropsWithChildren } from 'react'; |
| 3 | +import React, { PropsWithChildren, ReactNode } from 'react'; |
4 | 4 |
|
5 | 5 | import { GrafanaTheme2 } from '@grafana/data'; |
6 | 6 | import { IconButton, InlineFieldRow, InlineLabel, InlineSegmentGroup, useStyles2 } from '@grafana/ui'; |
7 | 7 |
|
8 | | -interface Props { |
9 | | - label: string; |
| 8 | +const getStyles = (theme: GrafanaTheme2) => { |
| 9 | + return { |
| 10 | + iconWrapper: css` |
| 11 | + display: flex; |
| 12 | + `, |
| 13 | + icon: css` |
| 14 | + color: ${theme.colors.text.secondary}; |
| 15 | + margin-left: ${theme.spacing(0.25)}; |
| 16 | + `, |
| 17 | + }; |
| 18 | +}; |
| 19 | + |
| 20 | +interface BaseRowProps { label: ReactNode; }; |
| 21 | +export const QueryEditorBaseRow = ({ label, children }: PropsWithChildren<BaseRowProps>) => { |
| 22 | + return ( |
| 23 | + <InlineFieldRow> |
| 24 | + <InlineSegmentGroup> |
| 25 | + <InlineLabel width={17} as="div"> |
| 26 | + {label} |
| 27 | + </InlineLabel> |
| 28 | + </InlineSegmentGroup> |
| 29 | + {children} |
| 30 | + </InlineFieldRow> |
| 31 | + ); |
| 32 | +}; |
| 33 | + |
| 34 | +interface RowProps extends BaseRowProps { |
10 | 35 | onRemoveClick?: false | (() => void); |
11 | 36 | onHideClick?: false | (() => void); |
12 | 37 | hidden?: boolean; |
13 | 38 | } |
14 | | - |
15 | 39 | export const QueryEditorRow = ({ |
16 | 40 | children, |
17 | 41 | label, |
18 | 42 | onRemoveClick, |
19 | 43 | onHideClick, |
20 | 44 | hidden = false, |
21 | | -}: PropsWithChildren<Props>) => { |
| 45 | +}: PropsWithChildren<RowProps>) => { |
22 | 46 | const styles = useStyles2(getStyles); |
23 | 47 |
|
24 | 48 | return ( |
25 | | - <InlineFieldRow> |
26 | | - <InlineSegmentGroup> |
27 | | - <InlineLabel width={17} as="div"> |
28 | | - <span>{label}</span> |
29 | | - <span className={styles.iconWrapper}> |
30 | | - {onHideClick && ( |
31 | | - <IconButton |
32 | | - name={hidden ? 'eye-slash' : 'eye'} |
33 | | - onClick={onHideClick} |
34 | | - size="sm" |
35 | | - aria-pressed={hidden} |
36 | | - aria-label="hide metric" |
37 | | - className={styles.icon} |
38 | | - type="button" |
39 | | - /> |
40 | | - )} |
| 49 | + <QueryEditorBaseRow label={(<> |
| 50 | + <span>{label}</span> |
| 51 | + <span className={styles.iconWrapper}> |
| 52 | + {onHideClick && ( |
41 | 53 | <IconButton |
42 | | - name="trash-alt" |
| 54 | + name={hidden ? 'eye-slash' : 'eye'} |
| 55 | + onClick={onHideClick} |
43 | 56 | size="sm" |
| 57 | + aria-pressed={hidden} |
| 58 | + aria-label="hide metric" |
44 | 59 | className={styles.icon} |
45 | | - onClick={onRemoveClick || noop} |
46 | | - disabled={!onRemoveClick} |
47 | | - aria-label="remove metric" |
48 | 60 | type="button" |
49 | 61 | /> |
50 | | - </span> |
51 | | - </InlineLabel> |
52 | | - </InlineSegmentGroup> |
| 62 | + )} |
| 63 | + <IconButton |
| 64 | + name="trash-alt" |
| 65 | + size="sm" |
| 66 | + className={styles.icon} |
| 67 | + onClick={onRemoveClick || noop} |
| 68 | + disabled={!onRemoveClick} |
| 69 | + aria-label="remove metric" |
| 70 | + type="button" |
| 71 | + /> |
| 72 | + </span> |
| 73 | + </>)}> |
53 | 74 | {children} |
54 | | - </InlineFieldRow> |
| 75 | + </QueryEditorBaseRow> |
55 | 76 | ); |
56 | 77 | }; |
57 | 78 |
|
58 | | -const getStyles = (theme: GrafanaTheme2) => { |
59 | | - return { |
60 | | - iconWrapper: css` |
61 | | - display: flex; |
62 | | - `, |
63 | | - icon: css` |
64 | | - color: ${theme.colors.text.secondary}; |
65 | | - margin-left: ${theme.spacing(0.25)}; |
66 | | - `, |
67 | | - }; |
68 | | -}; |
| 79 | + |
0 commit comments