@grafana/scenes 6.6.2 → 6.7.0--canary.1086.14257790935.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/esm/utils/ControlsLabel.js +60 -13
- package/dist/esm/utils/ControlsLabel.js.map +1 -1
- package/dist/esm/variables/components/VariableValueSelectors.js +6 -1
- package/dist/esm/variables/components/VariableValueSelectors.js.map +1 -1
- package/dist/index.d.ts +4 -1
- package/dist/index.js +64 -13
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
|
@@ -1,14 +1,27 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import { useStyles2, useTheme2, Tooltip, Icon, IconButton } from '@grafana/ui';
|
|
3
3
|
import { selectors } from '@grafana/e2e-selectors';
|
|
4
|
-
import { css } from '@emotion/css';
|
|
4
|
+
import { css, cx } from '@emotion/css';
|
|
5
5
|
import { LoadingIndicator } from './LoadingIndicator.js';
|
|
6
6
|
|
|
7
|
-
function ControlsLabel(
|
|
7
|
+
function ControlsLabel({
|
|
8
|
+
htmlFor,
|
|
9
|
+
label,
|
|
10
|
+
description,
|
|
11
|
+
isLoading,
|
|
12
|
+
error,
|
|
13
|
+
icon,
|
|
14
|
+
layout,
|
|
15
|
+
isSelectable,
|
|
16
|
+
isSelected,
|
|
17
|
+
onSelect,
|
|
18
|
+
onCancel,
|
|
19
|
+
onRemove
|
|
20
|
+
}) {
|
|
8
21
|
const styles = useStyles2(getStyles);
|
|
9
22
|
const theme = useTheme2();
|
|
10
|
-
const isVertical =
|
|
11
|
-
const loadingIndicator = Boolean(
|
|
23
|
+
const isVertical = layout === "vertical";
|
|
24
|
+
const loadingIndicator = Boolean(isLoading) ? /* @__PURE__ */ React.createElement(
|
|
12
25
|
"div",
|
|
13
26
|
{
|
|
14
27
|
style: { marginLeft: theme.spacing(1), marginTop: "-1px" },
|
|
@@ -18,28 +31,62 @@ function ControlsLabel(props) {
|
|
|
18
31
|
LoadingIndicator,
|
|
19
32
|
{
|
|
20
33
|
onCancel: (e) => {
|
|
21
|
-
var _a;
|
|
22
34
|
e.preventDefault();
|
|
23
35
|
e.stopPropagation();
|
|
24
|
-
|
|
36
|
+
onCancel == null ? void 0 : onCancel();
|
|
25
37
|
}
|
|
26
38
|
}
|
|
27
39
|
)
|
|
28
40
|
) : null;
|
|
29
41
|
let errorIndicator = null;
|
|
30
|
-
if (
|
|
31
|
-
errorIndicator = /* @__PURE__ */ React.createElement(Tooltip, { content:
|
|
42
|
+
if (error) {
|
|
43
|
+
errorIndicator = /* @__PURE__ */ React.createElement(Tooltip, { content: error, placement: "bottom" }, /* @__PURE__ */ React.createElement(Icon, { className: styles.errorIcon, name: "exclamation-triangle" }));
|
|
32
44
|
}
|
|
33
45
|
let descriptionIndicator = null;
|
|
34
|
-
if (
|
|
35
|
-
descriptionIndicator = /* @__PURE__ */ React.createElement(Tooltip, { content:
|
|
46
|
+
if (description) {
|
|
47
|
+
descriptionIndicator = /* @__PURE__ */ React.createElement(Tooltip, { content: description, placement: isVertical ? "top" : "bottom" }, /* @__PURE__ */ React.createElement(Icon, { className: styles.normalIcon, name: "info-circle" }));
|
|
36
48
|
}
|
|
37
|
-
const testId = typeof
|
|
49
|
+
const testId = typeof label === "string" ? selectors.pages.Dashboard.SubMenu.submenuItemLabels(label) : "";
|
|
38
50
|
let labelElement;
|
|
39
51
|
if (isVertical) {
|
|
40
|
-
labelElement = /* @__PURE__ */ React.createElement(
|
|
52
|
+
labelElement = /* @__PURE__ */ React.createElement(
|
|
53
|
+
"label",
|
|
54
|
+
{
|
|
55
|
+
className: cx(
|
|
56
|
+
styles.verticalLabel,
|
|
57
|
+
isSelected && "dashboard-selected-element",
|
|
58
|
+
isSelectable && !isSelected && "dashboard-selectable-element"
|
|
59
|
+
),
|
|
60
|
+
"data-testid": testId,
|
|
61
|
+
htmlFor,
|
|
62
|
+
onPointerDown: onSelect
|
|
63
|
+
},
|
|
64
|
+
label,
|
|
65
|
+
descriptionIndicator,
|
|
66
|
+
errorIndicator,
|
|
67
|
+
icon && /* @__PURE__ */ React.createElement(Icon, { name: icon, className: styles.normalIcon }),
|
|
68
|
+
loadingIndicator,
|
|
69
|
+
onRemove && /* @__PURE__ */ React.createElement(IconButton, { variant: "secondary", size: "xs", name: "times", onClick: onRemove, tooltip: "Remove" })
|
|
70
|
+
);
|
|
41
71
|
} else {
|
|
42
|
-
labelElement = /* @__PURE__ */ React.createElement(
|
|
72
|
+
labelElement = /* @__PURE__ */ React.createElement(
|
|
73
|
+
"label",
|
|
74
|
+
{
|
|
75
|
+
className: cx(
|
|
76
|
+
styles.horizontalLabel,
|
|
77
|
+
isSelected && "dashboard-selected-element",
|
|
78
|
+
isSelectable && !isSelected && "dashboard-selectable-element"
|
|
79
|
+
),
|
|
80
|
+
"data-testid": testId,
|
|
81
|
+
htmlFor,
|
|
82
|
+
onPointerDown: onSelect
|
|
83
|
+
},
|
|
84
|
+
errorIndicator,
|
|
85
|
+
icon && /* @__PURE__ */ React.createElement(Icon, { name: icon, className: styles.normalIcon }),
|
|
86
|
+
label,
|
|
87
|
+
descriptionIndicator,
|
|
88
|
+
loadingIndicator
|
|
89
|
+
);
|
|
43
90
|
}
|
|
44
91
|
return labelElement;
|
|
45
92
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ControlsLabel.js","sources":["../../../src/utils/ControlsLabel.tsx"],"sourcesContent":["import React from 'react';\nimport { Icon, IconButton, Tooltip, useStyles2, useTheme2 } from '@grafana/ui';\nimport { selectors } from '@grafana/e2e-selectors';\nimport { GrafanaTheme2, IconName } from '@grafana/data';\nimport { css } from '@emotion/css';\nimport { LoadingIndicator } from './LoadingIndicator';\nimport { ControlsLayout } from '../core/types';\n\ninterface ControlsLabelProps {\n label: string;\n htmlFor?: string;\n description?: string;\n isLoading?: boolean;\n error?: string;\n icon?: IconName;\n layout?: ControlsLayout;\n onCancel?: () => void;\n onRemove?: () => void;\n}\n\nexport function ControlsLabel(
|
|
1
|
+
{"version":3,"file":"ControlsLabel.js","sources":["../../../src/utils/ControlsLabel.tsx"],"sourcesContent":["import React from 'react';\nimport { Icon, IconButton, Tooltip, useStyles2, useTheme2 } from '@grafana/ui';\nimport { selectors } from '@grafana/e2e-selectors';\nimport { GrafanaTheme2, IconName } from '@grafana/data';\nimport { css, cx } from '@emotion/css';\nimport { LoadingIndicator } from './LoadingIndicator';\nimport { ControlsLayout } from '../core/types';\n\ninterface ControlsLabelProps {\n label: string;\n htmlFor?: string;\n description?: string;\n isLoading?: boolean;\n error?: string;\n icon?: IconName;\n layout?: ControlsLayout;\n isSelected?: boolean;\n isSelectable?: boolean;\n onSelect?: (e: React.PointerEvent) => void;\n onCancel?: () => void;\n onRemove?: () => void;\n}\n\nexport function ControlsLabel({\n htmlFor,\n label,\n description,\n isLoading,\n error,\n icon,\n layout,\n isSelectable,\n isSelected,\n onSelect,\n onCancel,\n onRemove,\n}: ControlsLabelProps) {\n const styles = useStyles2(getStyles);\n const theme = useTheme2();\n const isVertical = layout === 'vertical';\n\n const loadingIndicator = Boolean(isLoading) ? (\n <div\n style={{ marginLeft: theme.spacing(1), marginTop: '-1px' }}\n aria-label={selectors.components.LoadingIndicator.icon}\n >\n <LoadingIndicator\n onCancel={(e) => {\n e.preventDefault();\n e.stopPropagation();\n onCancel?.();\n }}\n />\n </div>\n ) : null;\n\n let errorIndicator = null;\n if (error) {\n errorIndicator = (\n <Tooltip content={error} placement={'bottom'}>\n <Icon className={styles.errorIcon} name=\"exclamation-triangle\" />\n </Tooltip>\n );\n }\n\n let descriptionIndicator = null;\n if (description) {\n descriptionIndicator = (\n <Tooltip content={description} placement={isVertical ? 'top' : 'bottom'}>\n <Icon className={styles.normalIcon} name=\"info-circle\" />\n </Tooltip>\n );\n }\n\n const testId = typeof label === 'string' ? selectors.pages.Dashboard.SubMenu.submenuItemLabels(label) : '';\n let labelElement: JSX.Element;\n\n // The vertical layout has different css class and order of elements (label always first)\n\n if (isVertical) {\n labelElement = (\n <label\n className={cx(\n styles.verticalLabel,\n isSelected && 'dashboard-selected-element',\n isSelectable && !isSelected && 'dashboard-selectable-element'\n )}\n data-testid={testId}\n htmlFor={htmlFor}\n onPointerDown={onSelect}\n >\n {label}\n {descriptionIndicator}\n {errorIndicator}\n {icon && <Icon name={icon} className={styles.normalIcon} />}\n {loadingIndicator}\n {onRemove && <IconButton variant=\"secondary\" size=\"xs\" name=\"times\" onClick={onRemove} tooltip={'Remove'} />}\n </label>\n );\n } else {\n labelElement = (\n <label\n className={cx(\n styles.horizontalLabel,\n isSelected && 'dashboard-selected-element',\n isSelectable && !isSelected && 'dashboard-selectable-element'\n )}\n data-testid={testId}\n htmlFor={htmlFor}\n onPointerDown={onSelect}\n >\n {errorIndicator}\n {icon && <Icon name={icon} className={styles.normalIcon} />}\n {label}\n {descriptionIndicator}\n {loadingIndicator}\n </label>\n );\n }\n\n return labelElement;\n}\n\nconst getStyles = (theme: GrafanaTheme2) => ({\n horizontalLabel: css({\n background: theme.isDark ? theme.colors.background.primary : theme.colors.background.secondary,\n display: `flex`,\n alignItems: 'center',\n padding: theme.spacing(0, 1),\n fontWeight: theme.typography.fontWeightMedium,\n fontSize: theme.typography.bodySmall.fontSize,\n height: theme.spacing(theme.components.height.md),\n lineHeight: theme.spacing(theme.components.height.md),\n borderRadius: `${theme.shape.radius.default} 0 0 ${theme.shape.radius.default}`,\n border: `1px solid ${theme.components.input.borderColor}`,\n position: 'relative',\n // To make the border line up with the input border\n right: -1,\n whiteSpace: 'nowrap',\n gap: theme.spacing(0.5),\n }),\n verticalLabel: css({\n display: `flex`,\n alignItems: 'center',\n fontWeight: theme.typography.fontWeightMedium,\n fontSize: theme.typography.bodySmall.fontSize,\n lineHeight: theme.typography.bodySmall.lineHeight,\n whiteSpace: 'nowrap',\n marginBottom: theme.spacing(0.5),\n gap: theme.spacing(1),\n }),\n errorIcon: css({\n color: theme.colors.error.text,\n }),\n normalIcon: css({\n color: theme.colors.text.secondary,\n }),\n});\n"],"names":[],"mappings":";;;;;;AAuBO,SAAS,aAAc,CAAA;AAAA,EAC5B,OAAA;AAAA,EACA,KAAA;AAAA,EACA,WAAA;AAAA,EACA,SAAA;AAAA,EACA,KAAA;AAAA,EACA,IAAA;AAAA,EACA,MAAA;AAAA,EACA,YAAA;AAAA,EACA,UAAA;AAAA,EACA,QAAA;AAAA,EACA,QAAA;AAAA,EACA;AACF,CAAuB,EAAA;AACrB,EAAM,MAAA,MAAA,GAAS,WAAW,SAAS,CAAA;AACnC,EAAA,MAAM,QAAQ,SAAU,EAAA;AACxB,EAAA,MAAM,aAAa,MAAW,KAAA,UAAA;AAE9B,EAAM,MAAA,gBAAA,GAAmB,OAAQ,CAAA,SAAS,CACxC,mBAAA,KAAA,CAAA,aAAA;AAAA,IAAC,KAAA;AAAA,IAAA;AAAA,MACC,KAAA,EAAO,EAAE,UAAY,EAAA,KAAA,CAAM,QAAQ,CAAC,CAAA,EAAG,WAAW,MAAO,EAAA;AAAA,MACzD,YAAA,EAAY,SAAU,CAAA,UAAA,CAAW,gBAAiB,CAAA;AAAA,KAAA;AAAA,oBAElD,KAAA,CAAA,aAAA;AAAA,MAAC,gBAAA;AAAA,MAAA;AAAA,QACC,QAAA,EAAU,CAAC,CAAM,KAAA;AACf,UAAA,CAAA,CAAE,cAAe,EAAA;AACjB,UAAA,CAAA,CAAE,eAAgB,EAAA;AAClB,UAAA,QAAA,IAAA,IAAA,GAAA,MAAA,GAAA,QAAA,EAAA;AAAA;AACF;AAAA;AACF,GAEA,GAAA,IAAA;AAEJ,EAAA,IAAI,cAAiB,GAAA,IAAA;AACrB,EAAA,IAAI,KAAO,EAAA;AACT,IAAA,cAAA,mBACG,KAAA,CAAA,aAAA,CAAA,OAAA,EAAA,EAAQ,OAAS,EAAA,KAAA,EAAO,SAAW,EAAA,QAAA,EAAA,kBACjC,KAAA,CAAA,aAAA,CAAA,IAAA,EAAA,EAAK,SAAW,EAAA,MAAA,CAAO,SAAW,EAAA,IAAA,EAAK,wBAAuB,CACjE,CAAA;AAAA;AAIJ,EAAA,IAAI,oBAAuB,GAAA,IAAA;AAC3B,EAAA,IAAI,WAAa,EAAA;AACf,IAAA,oBAAA,mBACG,KAAA,CAAA,aAAA,CAAA,OAAA,EAAA,EAAQ,OAAS,EAAA,WAAA,EAAa,WAAW,UAAa,GAAA,KAAA,GAAQ,QAC7D,EAAA,kBAAA,KAAA,CAAA,aAAA,CAAC,QAAK,SAAW,EAAA,MAAA,CAAO,UAAY,EAAA,IAAA,EAAK,eAAc,CACzD,CAAA;AAAA;AAIJ,EAAM,MAAA,MAAA,GAAS,OAAO,KAAA,KAAU,QAAW,GAAA,SAAA,CAAU,MAAM,SAAU,CAAA,OAAA,CAAQ,iBAAkB,CAAA,KAAK,CAAI,GAAA,EAAA;AACxG,EAAI,IAAA,YAAA;AAIJ,EAAA,IAAI,UAAY,EAAA;AACd,IACE,YAAA,mBAAA,KAAA,CAAA,aAAA;AAAA,MAAC,OAAA;AAAA,MAAA;AAAA,QACC,SAAW,EAAA,EAAA;AAAA,UACT,MAAO,CAAA,aAAA;AAAA,UACP,UAAc,IAAA,4BAAA;AAAA,UACd,YAAA,IAAgB,CAAC,UAAc,IAAA;AAAA,SACjC;AAAA,QACA,aAAa,EAAA,MAAA;AAAA,QACb,OAAA;AAAA,QACA,aAAe,EAAA;AAAA,OAAA;AAAA,MAEd,KAAA;AAAA,MACA,oBAAA;AAAA,MACA,cAAA;AAAA,MACA,wBAAS,KAAA,CAAA,aAAA,CAAA,IAAA,EAAA,EAAK,MAAM,IAAM,EAAA,SAAA,EAAW,OAAO,UAAY,EAAA,CAAA;AAAA,MACxD,gBAAA;AAAA,MACA,QAAY,oBAAA,KAAA,CAAA,aAAA,CAAC,UAAW,EAAA,EAAA,OAAA,EAAQ,WAAY,EAAA,IAAA,EAAK,IAAK,EAAA,IAAA,EAAK,OAAQ,EAAA,OAAA,EAAS,QAAU,EAAA,OAAA,EAAS,QAAU,EAAA;AAAA,KAC5G;AAAA,GAEG,MAAA;AACL,IACE,YAAA,mBAAA,KAAA,CAAA,aAAA;AAAA,MAAC,OAAA;AAAA,MAAA;AAAA,QACC,SAAW,EAAA,EAAA;AAAA,UACT,MAAO,CAAA,eAAA;AAAA,UACP,UAAc,IAAA,4BAAA;AAAA,UACd,YAAA,IAAgB,CAAC,UAAc,IAAA;AAAA,SACjC;AAAA,QACA,aAAa,EAAA,MAAA;AAAA,QACb,OAAA;AAAA,QACA,aAAe,EAAA;AAAA,OAAA;AAAA,MAEd,cAAA;AAAA,MACA,wBAAS,KAAA,CAAA,aAAA,CAAA,IAAA,EAAA,EAAK,MAAM,IAAM,EAAA,SAAA,EAAW,OAAO,UAAY,EAAA,CAAA;AAAA,MACxD,KAAA;AAAA,MACA,oBAAA;AAAA,MACA;AAAA,KACH;AAAA;AAIJ,EAAO,OAAA,YAAA;AACT;AAEA,MAAM,SAAA,GAAY,CAAC,KAA0B,MAAA;AAAA,EAC3C,iBAAiB,GAAI,CAAA;AAAA,IACnB,UAAA,EAAY,MAAM,MAAS,GAAA,KAAA,CAAM,OAAO,UAAW,CAAA,OAAA,GAAU,KAAM,CAAA,MAAA,CAAO,UAAW,CAAA,SAAA;AAAA,IACrF,OAAS,EAAA,CAAA,IAAA,CAAA;AAAA,IACT,UAAY,EAAA,QAAA;AAAA,IACZ,OAAS,EAAA,KAAA,CAAM,OAAQ,CAAA,CAAA,EAAG,CAAC,CAAA;AAAA,IAC3B,UAAA,EAAY,MAAM,UAAW,CAAA,gBAAA;AAAA,IAC7B,QAAA,EAAU,KAAM,CAAA,UAAA,CAAW,SAAU,CAAA,QAAA;AAAA,IACrC,QAAQ,KAAM,CAAA,OAAA,CAAQ,KAAM,CAAA,UAAA,CAAW,OAAO,EAAE,CAAA;AAAA,IAChD,YAAY,KAAM,CAAA,OAAA,CAAQ,KAAM,CAAA,UAAA,CAAW,OAAO,EAAE,CAAA;AAAA,IACpD,YAAA,EAAc,CAAG,EAAA,KAAA,CAAM,KAAM,CAAA,MAAA,CAAO,OAAO,CAAQ,KAAA,EAAA,KAAA,CAAM,KAAM,CAAA,MAAA,CAAO,OAAO,CAAA,CAAA;AAAA,IAC7E,MAAQ,EAAA,CAAA,UAAA,EAAa,KAAM,CAAA,UAAA,CAAW,MAAM,WAAW,CAAA,CAAA;AAAA,IACvD,QAAU,EAAA,UAAA;AAAA;AAAA,IAEV,KAAO,EAAA,EAAA;AAAA,IACP,UAAY,EAAA,QAAA;AAAA,IACZ,GAAA,EAAK,KAAM,CAAA,OAAA,CAAQ,GAAG;AAAA,GACvB,CAAA;AAAA,EACD,eAAe,GAAI,CAAA;AAAA,IACjB,OAAS,EAAA,CAAA,IAAA,CAAA;AAAA,IACT,UAAY,EAAA,QAAA;AAAA,IACZ,UAAA,EAAY,MAAM,UAAW,CAAA,gBAAA;AAAA,IAC7B,QAAA,EAAU,KAAM,CAAA,UAAA,CAAW,SAAU,CAAA,QAAA;AAAA,IACrC,UAAA,EAAY,KAAM,CAAA,UAAA,CAAW,SAAU,CAAA,UAAA;AAAA,IACvC,UAAY,EAAA,QAAA;AAAA,IACZ,YAAA,EAAc,KAAM,CAAA,OAAA,CAAQ,GAAG,CAAA;AAAA,IAC/B,GAAA,EAAK,KAAM,CAAA,OAAA,CAAQ,CAAC;AAAA,GACrB,CAAA;AAAA,EACD,WAAW,GAAI,CAAA;AAAA,IACb,KAAA,EAAO,KAAM,CAAA,MAAA,CAAO,KAAM,CAAA;AAAA,GAC3B,CAAA;AAAA,EACD,YAAY,GAAI,CAAA;AAAA,IACd,KAAA,EAAO,KAAM,CAAA,MAAA,CAAO,IAAK,CAAA;AAAA,GAC1B;AACH,CAAA,CAAA;;;;"}
|
|
@@ -5,6 +5,7 @@ import { sceneGraph } from '../../core/sceneGraph/index.js';
|
|
|
5
5
|
import { ControlsLabel } from '../../utils/ControlsLabel.js';
|
|
6
6
|
import { css } from '@emotion/css';
|
|
7
7
|
import { selectors } from '@grafana/e2e-selectors';
|
|
8
|
+
import { useElementSelection } from '@grafana/ui';
|
|
8
9
|
|
|
9
10
|
class VariableValueSelectors extends SceneObjectBase {
|
|
10
11
|
}
|
|
@@ -26,6 +27,7 @@ function VariableValueSelectWrapper({ variable, layout, showAlways, hideLabel })
|
|
|
26
27
|
function VariableLabel({ variable, layout, hideLabel }) {
|
|
27
28
|
var _a;
|
|
28
29
|
const { state } = variable;
|
|
30
|
+
const { isSelected, onSelect, isSelectable } = useElementSelection(`var-${variable.state.name}`);
|
|
29
31
|
if (variable.state.hide === VariableHide.hideLabel || hideLabel) {
|
|
30
32
|
return null;
|
|
31
33
|
}
|
|
@@ -43,7 +45,10 @@ function VariableLabel({ variable, layout, hideLabel }) {
|
|
|
43
45
|
label: labelOrName,
|
|
44
46
|
error: state.error,
|
|
45
47
|
layout,
|
|
46
|
-
description: (_a = state.description) != null ? _a : void 0
|
|
48
|
+
description: (_a = state.description) != null ? _a : void 0,
|
|
49
|
+
isSelected,
|
|
50
|
+
isSelectable,
|
|
51
|
+
onSelect
|
|
47
52
|
}
|
|
48
53
|
);
|
|
49
54
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"VariableValueSelectors.js","sources":["../../../../src/variables/components/VariableValueSelectors.tsx"],"sourcesContent":["import React from 'react';\n\nimport { VariableHide } from '@grafana/data';\n\nimport { SceneObjectBase, useSceneObjectState } from '../../core/SceneObjectBase';\nimport { sceneGraph } from '../../core/sceneGraph';\nimport { ControlsLayout, SceneComponentProps, SceneObjectState } from '../../core/types';\nimport { SceneVariable, SceneVariableState } from '../types';\nimport { ControlsLabel } from '../../utils/ControlsLabel';\nimport { css } from '@emotion/css';\nimport { selectors } from '@grafana/e2e-selectors';\n\nexport interface VariableValueSelectorsState extends SceneObjectState {\n layout?: ControlsLayout;\n}\n\nexport class VariableValueSelectors extends SceneObjectBase<VariableValueSelectorsState> {\n public static Component = VariableValueSelectorsRenderer;\n}\n\nfunction VariableValueSelectorsRenderer({ model }: SceneComponentProps<VariableValueSelectors>) {\n const variables = sceneGraph.getVariables(model)!.useState();\n\n return (\n <>\n {variables.variables.map((variable) => (\n <VariableValueSelectWrapper key={variable.state.key} variable={variable} layout={model.state.layout} />\n ))}\n </>\n );\n}\n\ninterface VariableSelectProps {\n layout?: ControlsLayout;\n variable: SceneVariable;\n /** To override hide from VariableValueSelectByName */\n showAlways?: boolean;\n /** To provide an option to hide the label in the variable value selector */\n hideLabel?: boolean;\n}\n\nexport function VariableValueSelectWrapper({ variable, layout, showAlways, hideLabel }: VariableSelectProps) {\n const state = useSceneObjectState<SceneVariableState>(variable, { shouldActivateOrKeepAlive: true });\n\n if (state.hide === VariableHide.hideVariable && !showAlways) {\n return null;\n }\n\n if (layout === 'vertical') {\n return (\n <div className={verticalContainer} data-testid={selectors.pages.Dashboard.SubMenu.submenuItem}>\n <VariableLabel variable={variable} layout={layout} hideLabel={hideLabel} />\n <variable.Component model={variable} />\n </div>\n );\n }\n\n return (\n <div className={containerStyle} data-testid={selectors.pages.Dashboard.SubMenu.submenuItem}>\n <VariableLabel variable={variable} hideLabel={hideLabel} />\n <variable.Component model={variable} />\n </div>\n );\n}\n\nfunction VariableLabel({ variable, layout, hideLabel }: VariableSelectProps) {\n const { state } = variable;\n\n if (variable.state.hide === VariableHide.hideLabel || hideLabel) {\n return null;\n }\n\n const elementId = `var-${state.key}`;\n const labelOrName = state.label || state.name;\n\n return (\n <ControlsLabel\n htmlFor={elementId}\n isLoading={state.loading}\n onCancel={() => variable.onCancel?.()}\n label={labelOrName}\n error={state.error}\n layout={layout}\n description={state.description ?? undefined}\n />\n );\n}\n\nconst containerStyle = css({\n display: 'flex',\n // No border for second element (inputs) as label and input border is shared\n '> :nth-child(2)': css({\n borderTopLeftRadius: 0,\n borderBottomLeftRadius: 0,\n }),\n});\n\nconst verticalContainer = css({ display: 'flex', flexDirection: 'column' });\n"],"names":["_a"],"mappings":"
|
|
1
|
+
{"version":3,"file":"VariableValueSelectors.js","sources":["../../../../src/variables/components/VariableValueSelectors.tsx"],"sourcesContent":["import React from 'react';\n\nimport { VariableHide } from '@grafana/data';\n\nimport { SceneObjectBase, useSceneObjectState } from '../../core/SceneObjectBase';\nimport { sceneGraph } from '../../core/sceneGraph';\nimport { ControlsLayout, SceneComponentProps, SceneObjectState } from '../../core/types';\nimport { SceneVariable, SceneVariableState } from '../types';\nimport { ControlsLabel } from '../../utils/ControlsLabel';\nimport { css } from '@emotion/css';\nimport { selectors } from '@grafana/e2e-selectors';\nimport { useElementSelection } from '@grafana/ui';\n\nexport interface VariableValueSelectorsState extends SceneObjectState {\n layout?: ControlsLayout;\n}\n\nexport class VariableValueSelectors extends SceneObjectBase<VariableValueSelectorsState> {\n public static Component = VariableValueSelectorsRenderer;\n}\n\nfunction VariableValueSelectorsRenderer({ model }: SceneComponentProps<VariableValueSelectors>) {\n const variables = sceneGraph.getVariables(model)!.useState();\n\n return (\n <>\n {variables.variables.map((variable) => (\n <VariableValueSelectWrapper key={variable.state.key} variable={variable} layout={model.state.layout} />\n ))}\n </>\n );\n}\n\ninterface VariableSelectProps {\n layout?: ControlsLayout;\n variable: SceneVariable;\n /** To override hide from VariableValueSelectByName */\n showAlways?: boolean;\n /** To provide an option to hide the label in the variable value selector */\n hideLabel?: boolean;\n}\n\nexport function VariableValueSelectWrapper({ variable, layout, showAlways, hideLabel }: VariableSelectProps) {\n const state = useSceneObjectState<SceneVariableState>(variable, { shouldActivateOrKeepAlive: true });\n\n if (state.hide === VariableHide.hideVariable && !showAlways) {\n return null;\n }\n\n if (layout === 'vertical') {\n return (\n <div className={verticalContainer} data-testid={selectors.pages.Dashboard.SubMenu.submenuItem}>\n <VariableLabel variable={variable} layout={layout} hideLabel={hideLabel} />\n <variable.Component model={variable} />\n </div>\n );\n }\n\n return (\n <div className={containerStyle} data-testid={selectors.pages.Dashboard.SubMenu.submenuItem}>\n <VariableLabel variable={variable} hideLabel={hideLabel} />\n <variable.Component model={variable} />\n </div>\n );\n}\n\nfunction VariableLabel({ variable, layout, hideLabel }: VariableSelectProps) {\n const { state } = variable;\n const { isSelected, onSelect, isSelectable } = useElementSelection(`var-${variable.state.name}`);\n\n if (variable.state.hide === VariableHide.hideLabel || hideLabel) {\n return null;\n }\n\n const elementId = `var-${state.key}`;\n const labelOrName = state.label || state.name;\n\n return (\n <ControlsLabel\n htmlFor={elementId}\n isLoading={state.loading}\n onCancel={() => variable.onCancel?.()}\n label={labelOrName}\n error={state.error}\n layout={layout}\n description={state.description ?? undefined}\n isSelected={isSelected}\n isSelectable={isSelectable}\n onSelect={onSelect}\n />\n );\n}\n\nconst containerStyle = css({\n display: 'flex',\n // No border for second element (inputs) as label and input border is shared\n '> :nth-child(2)': css({\n borderTopLeftRadius: 0,\n borderBottomLeftRadius: 0,\n }),\n});\n\nconst verticalContainer = css({ display: 'flex', flexDirection: 'column' });\n"],"names":["_a"],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -2858,10 +2858,13 @@ interface ControlsLabelProps {
|
|
|
2858
2858
|
error?: string;
|
|
2859
2859
|
icon?: IconName;
|
|
2860
2860
|
layout?: ControlsLayout;
|
|
2861
|
+
isSelected?: boolean;
|
|
2862
|
+
isSelectable?: boolean;
|
|
2863
|
+
onSelect?: (e: React__default.PointerEvent) => void;
|
|
2861
2864
|
onCancel?: () => void;
|
|
2862
2865
|
onRemove?: () => void;
|
|
2863
2866
|
}
|
|
2864
|
-
declare function ControlsLabel(
|
|
2867
|
+
declare function ControlsLabel({ htmlFor, label, description, isLoading, error, icon, layout, isSelectable, isSelected, onSelect, onCancel, onRemove, }: ControlsLabelProps): JSX.Element;
|
|
2865
2868
|
|
|
2866
2869
|
declare function renderSelectForVariable(model: MultiValueVariable): React__default.JSX.Element;
|
|
2867
2870
|
|
package/dist/index.js
CHANGED
|
@@ -3349,11 +3349,24 @@ function LoadingIndicator(props) {
|
|
|
3349
3349
|
));
|
|
3350
3350
|
}
|
|
3351
3351
|
|
|
3352
|
-
function ControlsLabel(
|
|
3352
|
+
function ControlsLabel({
|
|
3353
|
+
htmlFor,
|
|
3354
|
+
label,
|
|
3355
|
+
description,
|
|
3356
|
+
isLoading,
|
|
3357
|
+
error,
|
|
3358
|
+
icon,
|
|
3359
|
+
layout,
|
|
3360
|
+
isSelectable,
|
|
3361
|
+
isSelected,
|
|
3362
|
+
onSelect,
|
|
3363
|
+
onCancel,
|
|
3364
|
+
onRemove
|
|
3365
|
+
}) {
|
|
3353
3366
|
const styles = ui.useStyles2(getStyles$g);
|
|
3354
3367
|
const theme = ui.useTheme2();
|
|
3355
|
-
const isVertical =
|
|
3356
|
-
const loadingIndicator = Boolean(
|
|
3368
|
+
const isVertical = layout === "vertical";
|
|
3369
|
+
const loadingIndicator = Boolean(isLoading) ? /* @__PURE__ */ React__default.default.createElement(
|
|
3357
3370
|
"div",
|
|
3358
3371
|
{
|
|
3359
3372
|
style: { marginLeft: theme.spacing(1), marginTop: "-1px" },
|
|
@@ -3363,28 +3376,62 @@ function ControlsLabel(props) {
|
|
|
3363
3376
|
LoadingIndicator,
|
|
3364
3377
|
{
|
|
3365
3378
|
onCancel: (e) => {
|
|
3366
|
-
var _a;
|
|
3367
3379
|
e.preventDefault();
|
|
3368
3380
|
e.stopPropagation();
|
|
3369
|
-
|
|
3381
|
+
onCancel == null ? void 0 : onCancel();
|
|
3370
3382
|
}
|
|
3371
3383
|
}
|
|
3372
3384
|
)
|
|
3373
3385
|
) : null;
|
|
3374
3386
|
let errorIndicator = null;
|
|
3375
|
-
if (
|
|
3376
|
-
errorIndicator = /* @__PURE__ */ React__default.default.createElement(ui.Tooltip, { content:
|
|
3387
|
+
if (error) {
|
|
3388
|
+
errorIndicator = /* @__PURE__ */ React__default.default.createElement(ui.Tooltip, { content: error, placement: "bottom" }, /* @__PURE__ */ React__default.default.createElement(ui.Icon, { className: styles.errorIcon, name: "exclamation-triangle" }));
|
|
3377
3389
|
}
|
|
3378
3390
|
let descriptionIndicator = null;
|
|
3379
|
-
if (
|
|
3380
|
-
descriptionIndicator = /* @__PURE__ */ React__default.default.createElement(ui.Tooltip, { content:
|
|
3391
|
+
if (description) {
|
|
3392
|
+
descriptionIndicator = /* @__PURE__ */ React__default.default.createElement(ui.Tooltip, { content: description, placement: isVertical ? "top" : "bottom" }, /* @__PURE__ */ React__default.default.createElement(ui.Icon, { className: styles.normalIcon, name: "info-circle" }));
|
|
3381
3393
|
}
|
|
3382
|
-
const testId = typeof
|
|
3394
|
+
const testId = typeof label === "string" ? e2eSelectors.selectors.pages.Dashboard.SubMenu.submenuItemLabels(label) : "";
|
|
3383
3395
|
let labelElement;
|
|
3384
3396
|
if (isVertical) {
|
|
3385
|
-
labelElement = /* @__PURE__ */ React__default.default.createElement(
|
|
3397
|
+
labelElement = /* @__PURE__ */ React__default.default.createElement(
|
|
3398
|
+
"label",
|
|
3399
|
+
{
|
|
3400
|
+
className: css.cx(
|
|
3401
|
+
styles.verticalLabel,
|
|
3402
|
+
isSelected && "dashboard-selected-element",
|
|
3403
|
+
isSelectable && !isSelected && "dashboard-selectable-element"
|
|
3404
|
+
),
|
|
3405
|
+
"data-testid": testId,
|
|
3406
|
+
htmlFor,
|
|
3407
|
+
onPointerDown: onSelect
|
|
3408
|
+
},
|
|
3409
|
+
label,
|
|
3410
|
+
descriptionIndicator,
|
|
3411
|
+
errorIndicator,
|
|
3412
|
+
icon && /* @__PURE__ */ React__default.default.createElement(ui.Icon, { name: icon, className: styles.normalIcon }),
|
|
3413
|
+
loadingIndicator,
|
|
3414
|
+
onRemove && /* @__PURE__ */ React__default.default.createElement(ui.IconButton, { variant: "secondary", size: "xs", name: "times", onClick: onRemove, tooltip: "Remove" })
|
|
3415
|
+
);
|
|
3386
3416
|
} else {
|
|
3387
|
-
labelElement = /* @__PURE__ */ React__default.default.createElement(
|
|
3417
|
+
labelElement = /* @__PURE__ */ React__default.default.createElement(
|
|
3418
|
+
"label",
|
|
3419
|
+
{
|
|
3420
|
+
className: css.cx(
|
|
3421
|
+
styles.horizontalLabel,
|
|
3422
|
+
isSelected && "dashboard-selected-element",
|
|
3423
|
+
isSelectable && !isSelected && "dashboard-selectable-element"
|
|
3424
|
+
),
|
|
3425
|
+
"data-testid": testId,
|
|
3426
|
+
htmlFor,
|
|
3427
|
+
onPointerDown: onSelect
|
|
3428
|
+
},
|
|
3429
|
+
errorIndicator,
|
|
3430
|
+
icon && /* @__PURE__ */ React__default.default.createElement(ui.Icon, { name: icon, className: styles.normalIcon }),
|
|
3431
|
+
label,
|
|
3432
|
+
descriptionIndicator,
|
|
3433
|
+
loadingIndicator
|
|
3434
|
+
);
|
|
3388
3435
|
}
|
|
3389
3436
|
return labelElement;
|
|
3390
3437
|
}
|
|
@@ -9295,6 +9342,7 @@ function VariableValueSelectWrapper({ variable, layout, showAlways, hideLabel })
|
|
|
9295
9342
|
function VariableLabel({ variable, layout, hideLabel }) {
|
|
9296
9343
|
var _a;
|
|
9297
9344
|
const { state } = variable;
|
|
9345
|
+
const { isSelected, onSelect, isSelectable } = ui.useElementSelection(`var-${variable.state.name}`);
|
|
9298
9346
|
if (variable.state.hide === data.VariableHide.hideLabel || hideLabel) {
|
|
9299
9347
|
return null;
|
|
9300
9348
|
}
|
|
@@ -9312,7 +9360,10 @@ function VariableLabel({ variable, layout, hideLabel }) {
|
|
|
9312
9360
|
label: labelOrName,
|
|
9313
9361
|
error: state.error,
|
|
9314
9362
|
layout,
|
|
9315
|
-
description: (_a = state.description) != null ? _a : void 0
|
|
9363
|
+
description: (_a = state.description) != null ? _a : void 0,
|
|
9364
|
+
isSelected,
|
|
9365
|
+
isSelectable,
|
|
9366
|
+
onSelect
|
|
9316
9367
|
}
|
|
9317
9368
|
);
|
|
9318
9369
|
}
|