@grafana/components 0.0.1
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/LICENSE +201 -0
- package/README.md +3 -0
- package/dist/cjs/css/components.css +298 -0
- package/dist/cjs/index.cjs +3914 -0
- package/dist/cjs/index.cjs.map +1 -0
- package/dist/cjs/index.d.cts +132 -0
- package/dist/esm/_virtual/hoist-non-react-statics.cjs.js +4 -0
- package/dist/esm/_virtual/hoist-non-react-statics.cjs.js.map +1 -0
- package/dist/esm/_virtual/index.js +4 -0
- package/dist/esm/_virtual/index.js.map +1 -0
- package/dist/esm/_virtual/react-is.development.js +4 -0
- package/dist/esm/_virtual/react-is.development.js.map +1 -0
- package/dist/esm/_virtual/react-is.production.min.js +4 -0
- package/dist/esm/_virtual/react-is.production.min.js.map +1 -0
- package/dist/esm/components/ColorModeProvider/ColorModeProvider.js +25 -0
- package/dist/esm/components/ColorModeProvider/ColorModeProvider.js.map +1 -0
- package/dist/esm/components/ComparisonBadge/ComparisonBadge.js +74 -0
- package/dist/esm/components/ComparisonBadge/ComparisonBadge.js.map +1 -0
- package/dist/esm/components/ComparisonBadge/ComparisonBadge.styles.js +112 -0
- package/dist/esm/components/ComparisonBadge/ComparisonBadge.styles.js.map +1 -0
- package/dist/esm/components/ComparisonTooltip/ComparisonTooltip.js +41 -0
- package/dist/esm/components/ComparisonTooltip/ComparisonTooltip.js.map +1 -0
- package/dist/esm/components/ComparisonTooltip/ComparisonTooltip.styles.js +61 -0
- package/dist/esm/components/ComparisonTooltip/ComparisonTooltip.styles.js.map +1 -0
- package/dist/esm/components/Popover/Popover.js +120 -0
- package/dist/esm/components/Popover/Popover.js.map +1 -0
- package/dist/esm/components/Popover/Popover.styles.js +30 -0
- package/dist/esm/components/Popover/Popover.styles.js.map +1 -0
- package/dist/esm/css/components.css +298 -0
- package/dist/esm/index.d.ts +132 -0
- package/dist/esm/index.js +7 -0
- package/dist/esm/index.js.map +1 -0
- package/dist/esm/utils/comparison.js +34 -0
- package/dist/esm/utils/comparison.js.map +1 -0
- package/dist/esm/utils/formatters.js +29 -0
- package/dist/esm/utils/formatters.js.map +1 -0
- package/package.json +118 -0
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
import * as react from 'react';
|
|
2
|
+
import react__default, { ReactNode, JSX } from 'react';
|
|
3
|
+
import { ThemeColorMode } from '@grafana/design-tokens';
|
|
4
|
+
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
5
|
+
import { IconName } from '@grafana/ui';
|
|
6
|
+
import { Placement } from '@floating-ui/react';
|
|
7
|
+
|
|
8
|
+
interface ColorModeContextType {
|
|
9
|
+
colorMode: ThemeColorMode;
|
|
10
|
+
setColorMode: (colorMode: ThemeColorMode) => void;
|
|
11
|
+
}
|
|
12
|
+
interface ColorModeProviderProps {
|
|
13
|
+
children: ReactNode;
|
|
14
|
+
defaultColorMode?: ThemeColorMode;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Provides a shared context for the currently-active theme color mode, and sets
|
|
18
|
+
* the data-color-mode attribute on the document element whenever it changes.
|
|
19
|
+
*/
|
|
20
|
+
declare const ColorModeProvider: react__default.FC<ColorModeProviderProps>;
|
|
21
|
+
/**
|
|
22
|
+
* Use this to query the active color mode, or to set it, e.g. with an effect
|
|
23
|
+
* hook within a component which explicitly changes the active color mode:
|
|
24
|
+
*
|
|
25
|
+
* useEffect(() => {
|
|
26
|
+
* setColorMode(colorMode);
|
|
27
|
+
* }, [colorMode]);
|
|
28
|
+
*
|
|
29
|
+
*/
|
|
30
|
+
declare const useColorMode: () => ColorModeContextType;
|
|
31
|
+
|
|
32
|
+
interface PopoverProps {
|
|
33
|
+
/**
|
|
34
|
+
* Content used to trigger the Popover being displayed
|
|
35
|
+
*/
|
|
36
|
+
trigger: JSX.Element;
|
|
37
|
+
/**
|
|
38
|
+
* Content to render within the Popover
|
|
39
|
+
*/
|
|
40
|
+
children: JSX.Element;
|
|
41
|
+
/**
|
|
42
|
+
* Should the popover be open? Implicitly means the popover visibility is
|
|
43
|
+
* controlled; if omitted, the popover target will control visibility
|
|
44
|
+
*/
|
|
45
|
+
isOpen?: boolean;
|
|
46
|
+
/**
|
|
47
|
+
* Set to true if you want the tooltip to stay long enough so the user can
|
|
48
|
+
* move mouse over content to select text or click a link
|
|
49
|
+
*/
|
|
50
|
+
isInteractive?: boolean;
|
|
51
|
+
/**
|
|
52
|
+
* Placement of the Popover relative to the trigger content
|
|
53
|
+
*/
|
|
54
|
+
placement?: Placement;
|
|
55
|
+
/**
|
|
56
|
+
* Transition duration for hide/show effects, in milliseconds
|
|
57
|
+
*/
|
|
58
|
+
transitionDuration?: number;
|
|
59
|
+
/**
|
|
60
|
+
* Additional delay before hiding the popover after mouseout, in milliseconds
|
|
61
|
+
*/
|
|
62
|
+
hideDelay?: number;
|
|
63
|
+
}
|
|
64
|
+
declare const Popover: react.ForwardRefExoticComponent<PopoverProps & react.RefAttributes<HTMLElement>>;
|
|
65
|
+
|
|
66
|
+
interface ComparisonTooltipProps extends Omit<PopoverProps, 'children'> {
|
|
67
|
+
current?: string;
|
|
68
|
+
previous?: string;
|
|
69
|
+
previousLabel?: string;
|
|
70
|
+
currentLabel?: string;
|
|
71
|
+
title?: string;
|
|
72
|
+
currentIcon?: IconName;
|
|
73
|
+
previousIcon?: IconName;
|
|
74
|
+
hideDelay?: number;
|
|
75
|
+
}
|
|
76
|
+
declare const ComparisonTooltip: ({ trigger, placement, current, previous, previousLabel, currentLabel, title, currentIcon, previousIcon, hideDelay, }: ComparisonTooltipProps) => react_jsx_runtime.JSX.Element;
|
|
77
|
+
|
|
78
|
+
interface ComparisonBadgeProps extends Pick<ComparisonTooltipProps, 'currentLabel' | 'previousLabel' | 'placement'> {
|
|
79
|
+
current?: number | null;
|
|
80
|
+
previous?: number | null;
|
|
81
|
+
highlight?: boolean;
|
|
82
|
+
timeframeLabel?: string;
|
|
83
|
+
tooltip?: boolean;
|
|
84
|
+
}
|
|
85
|
+
declare const ComparisonBadge: ({ current, previous, currentLabel, previousLabel, placement, highlight, timeframeLabel, tooltip, }: ComparisonBadgeProps) => react_jsx_runtime.JSX.Element;
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* Shared utility functions for handling comparison calculations across components
|
|
89
|
+
*/
|
|
90
|
+
interface ComparisonResult {
|
|
91
|
+
hasComparison: boolean;
|
|
92
|
+
direction: 'up' | 'down' | 'neutral';
|
|
93
|
+
percentageChange: number;
|
|
94
|
+
percentageLabel: string;
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Calculate comparison metrics between a current value and a baseline value
|
|
98
|
+
* @param current - The current value to compare
|
|
99
|
+
* @param baseline - The baseline value to compare against (optional)
|
|
100
|
+
* @returns ComparisonResult object with calculated metrics
|
|
101
|
+
*/
|
|
102
|
+
declare const calculateComparison: (current: number | undefined | null, baseline: number | undefined | null) => ComparisonResult;
|
|
103
|
+
|
|
104
|
+
/**
|
|
105
|
+
* Number formatting options
|
|
106
|
+
*/
|
|
107
|
+
interface FormatNumberOptions {
|
|
108
|
+
/** Decimal places (default: 2) */
|
|
109
|
+
decimals?: number;
|
|
110
|
+
/** Threshold for compact formatting (default: 1000) */
|
|
111
|
+
compactThreshold?: number;
|
|
112
|
+
/** Never use compact formatting (for precise displays) */
|
|
113
|
+
precise?: boolean;
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
116
|
+
* Format numbers with optional compact notation (k, m, b)
|
|
117
|
+
* Components handle their own prefixes/suffixes ($ or %)
|
|
118
|
+
*
|
|
119
|
+
* @param value - The number to format (or 'loading' state)
|
|
120
|
+
* @param options - Formatting options
|
|
121
|
+
* @returns Formatted number string (no prefixes/suffixes)
|
|
122
|
+
*
|
|
123
|
+
* @example
|
|
124
|
+
* formatNumber(1234) // "1.2k"
|
|
125
|
+
* formatNumber(1234, { precise: true }) // "1,234.00"
|
|
126
|
+
* formatNumber(1234, { decimals: 0 }) // "1k"
|
|
127
|
+
* formatNumber(999) // "999.00"
|
|
128
|
+
*/
|
|
129
|
+
declare const formatNumber: (value: number | string | "loading", options?: FormatNumberOptions) => string;
|
|
130
|
+
|
|
131
|
+
export { ColorModeProvider, ComparisonBadge, ComparisonTooltip, Popover, calculateComparison, formatNumber, useColorMode };
|
|
132
|
+
export type { ColorModeContextType, ColorModeProviderProps, ComparisonResult, ComparisonTooltipProps, FormatNumberOptions, PopoverProps };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hoist-non-react-statics.cjs.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"react-is.development.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"react-is.production.min.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { jsx } from 'react/jsx-runtime';
|
|
2
|
+
import { createContext, useState, useEffect, useContext } from 'react';
|
|
3
|
+
|
|
4
|
+
const ColorModeContext = createContext(void 0);
|
|
5
|
+
const ColorModeProvider = ({
|
|
6
|
+
children,
|
|
7
|
+
defaultColorMode = "light"
|
|
8
|
+
}) => {
|
|
9
|
+
const [colorMode, setColorMode] = useState(defaultColorMode);
|
|
10
|
+
useEffect(() => {
|
|
11
|
+
console.log("ColorModeProvider", { colorMode });
|
|
12
|
+
document.documentElement.setAttribute("data-color-mode", colorMode);
|
|
13
|
+
}, [colorMode]);
|
|
14
|
+
return /* @__PURE__ */ jsx(ColorModeContext.Provider, { value: { colorMode, setColorMode }, children });
|
|
15
|
+
};
|
|
16
|
+
const useColorMode = () => {
|
|
17
|
+
const context = useContext(ColorModeContext);
|
|
18
|
+
if (context === void 0) {
|
|
19
|
+
throw new Error("useColorMode must be used within a ColorModeProvider");
|
|
20
|
+
}
|
|
21
|
+
return context;
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
export { ColorModeProvider, useColorMode };
|
|
25
|
+
//# sourceMappingURL=ColorModeProvider.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ColorModeProvider.js","sources":["../../../../src/components/ColorModeProvider/ColorModeProvider.tsx"],"sourcesContent":["import React, { createContext, useContext, useEffect, useState, ReactNode } from 'react';\nimport { ThemeColorMode } from '@grafana/design-tokens';\n\nimport '@grafana/design-tokens/dist/css/legacy/primitives.css';\nimport '@grafana/design-tokens/dist/css/legacy/colors.light.css';\nimport '@grafana/design-tokens/dist/css/legacy/colors.dark.css';\n\nexport interface ColorModeContextType {\n colorMode: ThemeColorMode;\n setColorMode: (colorMode: ThemeColorMode) => void;\n}\n\nexport interface ColorModeProviderProps {\n children: ReactNode;\n defaultColorMode?: ThemeColorMode;\n}\n\nconst ColorModeContext = createContext<ColorModeContextType | undefined>(undefined);\n\n/**\n * Provides a shared context for the currently-active theme color mode, and sets\n * the data-color-mode attribute on the document element whenever it changes.\n */\nexport const ColorModeProvider: React.FC<ColorModeProviderProps> = ({\n children,\n defaultColorMode = 'light',\n}) => {\n const [colorMode, setColorMode] = useState<ThemeColorMode>(defaultColorMode);\n\n useEffect(() => {\n console.log('ColorModeProvider', { colorMode });\n document.documentElement.setAttribute('data-color-mode', colorMode);\n }, [colorMode]);\n\n return (\n <ColorModeContext.Provider value={{ colorMode, setColorMode }}>\n {children}\n </ColorModeContext.Provider>\n );\n};\n\n/**\n * Use this to query the active color mode, or to set it, e.g. with an effect\n * hook within a component which explicitly changes the active color mode:\n *\n * useEffect(() => {\n * setColorMode(colorMode);\n * }, [colorMode]);\n *\n */\nexport const useColorMode = () => {\n const context = useContext(ColorModeContext);\n\n if (context === undefined) {\n throw new Error('useColorMode must be used within a ColorModeProvider');\n }\n\n return context;\n};\n"],"names":[],"mappings":";;;AAiBA,MAAM,gBAAA,GAAmB,cAAgD,MAAS,CAAA;AAM3E,MAAM,oBAAsD,CAAC;AAAA,EAClE,QAAA;AAAA,EACA,gBAAA,GAAmB;AACrB,CAAA,KAAM;AACJ,EAAA,MAAM,CAAC,SAAA,EAAW,YAAY,CAAA,GAAI,SAAyB,gBAAgB,CAAA;AAE3E,EAAA,SAAA,CAAU,MAAM;AACd,IAAA,OAAA,CAAQ,GAAA,CAAI,mBAAA,EAAqB,EAAE,SAAA,EAAW,CAAA;AAC9C,IAAA,QAAA,CAAS,eAAA,CAAgB,YAAA,CAAa,iBAAA,EAAmB,SAAS,CAAA;AAAA,EACpE,CAAA,EAAG,CAAC,SAAS,CAAC,CAAA;AAEd,EAAA,uBACE,GAAA,CAAC,iBAAiB,QAAA,EAAjB,EAA0B,OAAO,EAAE,SAAA,EAAW,YAAA,EAAa,EACzD,QAAA,EACH,CAAA;AAEJ;AAWO,MAAM,eAAe,MAAM;AAChC,EAAA,MAAM,OAAA,GAAU,WAAW,gBAAgB,CAAA;AAE3C,EAAA,IAAI,YAAY,MAAA,EAAW;AACzB,IAAA,MAAM,IAAI,MAAM,sDAAsD,CAAA;AAAA,EACxE;AAEA,EAAA,OAAO,OAAA;AACT;;;;"}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
|
|
2
|
+
import { cx } from '@emotion/css';
|
|
3
|
+
import { Icon } from '@grafana/ui';
|
|
4
|
+
import { calculateComparison } from '../../utils/comparison.js';
|
|
5
|
+
import { formatNumber } from '../../utils/formatters.js';
|
|
6
|
+
import { ComparisonTooltip } from '../ComparisonTooltip/ComparisonTooltip.js';
|
|
7
|
+
import { getComparisonBadgeStyles, cssVariables } from './ComparisonBadge.styles.js';
|
|
8
|
+
import { GlobalCSSVariables } from '../../node_modules/@grafana/design-tokens/dist/esm/lib/util/emotion.js';
|
|
9
|
+
|
|
10
|
+
const formatCurrency = (value) => {
|
|
11
|
+
return !!value ? `$${formatNumber(value, { precise: true })}` : "N/A";
|
|
12
|
+
};
|
|
13
|
+
const DIRECTION_ICON = {
|
|
14
|
+
up: "arrow-up",
|
|
15
|
+
down: "arrow-down",
|
|
16
|
+
neutral: "minus"
|
|
17
|
+
};
|
|
18
|
+
const ComparisonBadge = ({
|
|
19
|
+
current,
|
|
20
|
+
previous,
|
|
21
|
+
currentLabel,
|
|
22
|
+
previousLabel,
|
|
23
|
+
placement,
|
|
24
|
+
highlight = false,
|
|
25
|
+
timeframeLabel,
|
|
26
|
+
tooltip = true
|
|
27
|
+
}) => {
|
|
28
|
+
const { direction, hasComparison, percentageLabel } = calculateComparison(current, previous);
|
|
29
|
+
const styles = getComparisonBadgeStyles({ highlight, direction, tooltip });
|
|
30
|
+
const directionIconStyle = (() => {
|
|
31
|
+
switch (true) {
|
|
32
|
+
case direction == "neutral":
|
|
33
|
+
return styles.dash;
|
|
34
|
+
default:
|
|
35
|
+
return void 0;
|
|
36
|
+
}
|
|
37
|
+
})();
|
|
38
|
+
const badgeContent = /* @__PURE__ */ jsxs("div", { className: styles.container, children: [
|
|
39
|
+
/* @__PURE__ */ jsx("div", { className: styles.clockIconWrapper, children: /* @__PURE__ */ jsx(Icon, { name: "clock-nine" }) }),
|
|
40
|
+
/* @__PURE__ */ jsxs("div", { className: styles.trendLabelContainer, children: [
|
|
41
|
+
/* @__PURE__ */ jsxs("span", { className: styles.trendLabel, children: [
|
|
42
|
+
/* @__PURE__ */ jsx("span", { className: styles.trendIconWrapper, children: /* @__PURE__ */ jsx(
|
|
43
|
+
Icon,
|
|
44
|
+
{
|
|
45
|
+
name: DIRECTION_ICON[direction],
|
|
46
|
+
className: cx(styles.trendIcon, directionIconStyle)
|
|
47
|
+
}
|
|
48
|
+
) }),
|
|
49
|
+
hasComparison && percentageLabel && /* @__PURE__ */ jsx(Fragment, { children: percentageLabel })
|
|
50
|
+
] }),
|
|
51
|
+
timeframeLabel && /* @__PURE__ */ jsxs("span", { className: styles.timeframeLabel, children: [
|
|
52
|
+
"vs ",
|
|
53
|
+
timeframeLabel.toLowerCase()
|
|
54
|
+
] })
|
|
55
|
+
] })
|
|
56
|
+
] });
|
|
57
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
58
|
+
/* @__PURE__ */ jsx(GlobalCSSVariables, { variables: cssVariables(), defaultColorMode: null }),
|
|
59
|
+
tooltip ? /* @__PURE__ */ jsx(
|
|
60
|
+
ComparisonTooltip,
|
|
61
|
+
{
|
|
62
|
+
trigger: badgeContent,
|
|
63
|
+
current: formatCurrency(current),
|
|
64
|
+
previous: formatCurrency(previous),
|
|
65
|
+
currentLabel,
|
|
66
|
+
previousLabel,
|
|
67
|
+
placement
|
|
68
|
+
}
|
|
69
|
+
) : badgeContent
|
|
70
|
+
] });
|
|
71
|
+
};
|
|
72
|
+
|
|
73
|
+
export { ComparisonBadge };
|
|
74
|
+
//# sourceMappingURL=ComparisonBadge.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ComparisonBadge.js","sources":["../../../../src/components/ComparisonBadge/ComparisonBadge.tsx"],"sourcesContent":["import { cx } from '@emotion/css';\nimport { GlobalCSSVariables } from '@grafana/design-tokens';\nimport { Icon, IconName } from '@grafana/ui';\nimport { calculateComparison } from '../../utils/comparison';\nimport { formatNumber } from '../../utils/formatters';\nimport { ComparisonTooltipProps, ComparisonTooltip } from '../ComparisonTooltip';\nimport { cssVariables, getComparisonBadgeStyles } from './ComparisonBadge.styles';\n\nconst formatCurrency = (value: number | undefined | null): string => {\n return !!value ? `$${formatNumber(value, { precise: true })}` : 'N/A';\n};\n\nexport interface ComparisonBadgeProps\n extends Pick<ComparisonTooltipProps, 'currentLabel' | 'previousLabel' | 'placement'> {\n current?: number | null;\n previous?: number | null;\n highlight?: boolean;\n timeframeLabel?: string;\n tooltip?: boolean;\n}\n\nconst DIRECTION_ICON: Record<'up' | 'down' | 'neutral', IconName> = {\n up: 'arrow-up',\n down: 'arrow-down',\n neutral: 'minus',\n};\n\nexport const ComparisonBadge = ({\n current,\n previous,\n currentLabel,\n previousLabel,\n placement,\n highlight = false,\n timeframeLabel,\n tooltip = true,\n}: ComparisonBadgeProps) => {\n const { direction, hasComparison, percentageLabel } = calculateComparison(current, previous);\n const styles = getComparisonBadgeStyles({ highlight, direction, tooltip });\n\n const directionIconStyle = (() => {\n switch (true) {\n case direction == 'neutral':\n return styles.dash;\n default:\n return undefined;\n }\n })();\n\n const badgeContent = (\n <div className={styles.container}>\n <div className={styles.clockIconWrapper}>\n <Icon name=\"clock-nine\" />\n </div>\n <div className={styles.trendLabelContainer}>\n <span className={styles.trendLabel}>\n <span className={styles.trendIconWrapper}>\n <Icon\n name={DIRECTION_ICON[direction]}\n className={cx(styles.trendIcon, directionIconStyle)}\n />\n </span>\n {hasComparison && percentageLabel && <>{percentageLabel}</>}\n </span>\n {timeframeLabel && (\n <span className={styles.timeframeLabel}>vs {timeframeLabel.toLowerCase()}</span>\n )}\n </div>\n </div>\n );\n\n return (\n <>\n <GlobalCSSVariables variables={cssVariables()} defaultColorMode={null} />\n {tooltip ? (\n <ComparisonTooltip\n trigger={badgeContent}\n current={formatCurrency(current)}\n previous={formatCurrency(previous)}\n currentLabel={currentLabel}\n previousLabel={previousLabel}\n placement={placement}\n />\n ) : (\n badgeContent\n )}\n </>\n );\n};\n"],"names":[],"mappings":";;;;;;;;;AAQA,MAAM,cAAA,GAAiB,CAAC,KAAA,KAA6C;AACnE,EAAA,OAAO,CAAC,CAAC,KAAA,GAAQ,CAAA,CAAA,EAAI,YAAA,CAAa,KAAA,EAAO,EAAE,OAAA,EAAS,IAAA,EAAM,CAAC,CAAA,CAAA,GAAK,KAAA;AAClE,CAAA;AAWA,MAAM,cAAA,GAA8D;AAAA,EAClE,EAAA,EAAI,UAAA;AAAA,EACJ,IAAA,EAAM,YAAA;AAAA,EACN,OAAA,EAAS;AACX,CAAA;AAEO,MAAM,kBAAkB,CAAC;AAAA,EAC9B,OAAA;AAAA,EACA,QAAA;AAAA,EACA,YAAA;AAAA,EACA,aAAA;AAAA,EACA,SAAA;AAAA,EACA,SAAA,GAAY,KAAA;AAAA,EACZ,cAAA;AAAA,EACA,OAAA,GAAU;AACZ,CAAA,KAA4B;AAC1B,EAAA,MAAM,EAAE,SAAA,EAAW,aAAA,EAAe,iBAAgB,GAAI,mBAAA,CAAoB,SAAS,QAAQ,CAAA;AAC3F,EAAA,MAAM,SAAS,wBAAA,CAAyB,EAAE,SAAA,EAAW,SAAA,EAAW,SAAS,CAAA;AAEzE,EAAA,MAAM,sBAAsB,MAAM;AAChC,IAAA,QAAQ,IAAA;AAAM,MACZ,KAAK,SAAA,IAAa,SAAA;AAChB,QAAA,OAAO,MAAA,CAAO,IAAA;AAAA,MAChB;AACE,QAAA,OAAO,MAAA;AAAA;AACX,EACF,CAAA,GAAG;AAEH,EAAA,MAAM,YAAA,mBACJ,IAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAW,OAAO,SAAA,EACrB,QAAA,EAAA;AAAA,oBAAA,GAAA,CAAC,KAAA,EAAA,EAAI,WAAW,MAAA,CAAO,gBAAA,EACrB,8BAAC,IAAA,EAAA,EAAK,IAAA,EAAK,cAAa,CAAA,EAC1B,CAAA;AAAA,oBACA,IAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAW,MAAA,CAAO,mBAAA,EACrB,QAAA,EAAA;AAAA,sBAAA,IAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAW,MAAA,CAAO,UAAA,EACtB,QAAA,EAAA;AAAA,wBAAA,GAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAW,MAAA,CAAO,gBAAA,EACtB,QAAA,kBAAA,GAAA;AAAA,UAAC,IAAA;AAAA,UAAA;AAAA,YACC,IAAA,EAAM,eAAe,SAAS,CAAA;AAAA,YAC9B,SAAA,EAAW,EAAA,CAAG,MAAA,CAAO,SAAA,EAAW,kBAAkB;AAAA;AAAA,SACpD,EACF,CAAA;AAAA,QACC,aAAA,IAAiB,eAAA,oBAAmB,GAAA,CAAA,QAAA,EAAA,EAAG,QAAA,EAAA,eAAA,EAAgB;AAAA,OAAA,EAC1D,CAAA;AAAA,MACC,cAAA,oBACC,IAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAW,OAAO,cAAA,EAAgB,QAAA,EAAA;AAAA,QAAA,KAAA;AAAA,QAAI,eAAe,WAAA;AAAY,OAAA,EAAE;AAAA,KAAA,EAE7E;AAAA,GAAA,EACF,CAAA;AAGF,EAAA,uBACE,IAAA,CAAA,QAAA,EAAA,EACE,QAAA,EAAA;AAAA,oBAAA,GAAA,CAAC,kBAAA,EAAA,EAAmB,SAAA,EAAW,YAAA,EAAa,EAAG,kBAAkB,IAAA,EAAM,CAAA;AAAA,IACtE,OAAA,mBACC,GAAA;AAAA,MAAC,iBAAA;AAAA,MAAA;AAAA,QACC,OAAA,EAAS,YAAA;AAAA,QACT,OAAA,EAAS,eAAe,OAAO,CAAA;AAAA,QAC/B,QAAA,EAAU,eAAe,QAAQ,CAAA;AAAA,QACjC,YAAA;AAAA,QACA,aAAA;AAAA,QACA;AAAA;AAAA,KACF,GAEA;AAAA,GAAA,EAEJ,CAAA;AAEJ;;;;"}
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
import { css } from '@emotion/css';
|
|
2
|
+
import { getDesignTokens } from '../../node_modules/@grafana/design-tokens/dist/esm/lib/getDesignTokens/getDesignTokens.js';
|
|
3
|
+
|
|
4
|
+
const cssVariables = () => {
|
|
5
|
+
const { legacy } = getDesignTokens({ valueType: "css" });
|
|
6
|
+
return {
|
|
7
|
+
dark: {
|
|
8
|
+
"comparison-badge-icon-background-color": legacy.colors.background.secondary,
|
|
9
|
+
"comparison-badge-icon-highlight-background-color": legacy.palette.whiteBaseOpacity10
|
|
10
|
+
},
|
|
11
|
+
light: {
|
|
12
|
+
"comparison-badge-icon-background-color": legacy.colors.background.canvas,
|
|
13
|
+
"comparison-badge-icon-highlight-background-color": legacy.palette.blackBaseOpacity8
|
|
14
|
+
}
|
|
15
|
+
};
|
|
16
|
+
};
|
|
17
|
+
const BADGE_HEIGHT = 28;
|
|
18
|
+
const TREND_ICON_SIZE = 20;
|
|
19
|
+
const getComparisonBadgeStyles = ({
|
|
20
|
+
highlight,
|
|
21
|
+
direction,
|
|
22
|
+
tooltip
|
|
23
|
+
}) => {
|
|
24
|
+
const {
|
|
25
|
+
legacy,
|
|
26
|
+
primitives: { spacing, typography }
|
|
27
|
+
} = getDesignTokens({ valueType: "css" });
|
|
28
|
+
const labelColor = (() => {
|
|
29
|
+
switch (true) {
|
|
30
|
+
case highlight:
|
|
31
|
+
case direction === "up":
|
|
32
|
+
return legacy.colors.text.maxContrast;
|
|
33
|
+
default:
|
|
34
|
+
return legacy.colors.primary.text;
|
|
35
|
+
}
|
|
36
|
+
})();
|
|
37
|
+
return {
|
|
38
|
+
container: css({
|
|
39
|
+
boxSizing: "border-box",
|
|
40
|
+
background: "transparent",
|
|
41
|
+
borderRadius: legacy.borderRadius.pill,
|
|
42
|
+
border: `1px solid
|
|
43
|
+
${highlight ? legacy.colors.border.strong : legacy.colors.border.weak}`,
|
|
44
|
+
padding: `${spacing.xxs} ${spacing.sm} ${spacing.xxs} ${spacing.xxs}`,
|
|
45
|
+
textAlign: "left",
|
|
46
|
+
display: "inline-flex",
|
|
47
|
+
flexDirection: "row",
|
|
48
|
+
justifyContent: "center",
|
|
49
|
+
alignItems: "center",
|
|
50
|
+
fontFamily: typography.fontFamily.ui,
|
|
51
|
+
fontSize: typography.fontSize.ui.sm,
|
|
52
|
+
height: `${BADGE_HEIGHT}px`,
|
|
53
|
+
position: "relative",
|
|
54
|
+
transition: "background 0.2s ease-in-out",
|
|
55
|
+
...tooltip ? {
|
|
56
|
+
cursor: "pointer",
|
|
57
|
+
"&:hover": {
|
|
58
|
+
background: legacy.colors.background.secondary
|
|
59
|
+
}
|
|
60
|
+
} : {}
|
|
61
|
+
}),
|
|
62
|
+
clockIconWrapper: css({
|
|
63
|
+
background: highlight ? "var(--comparison-badge-icon-highlight-background-color)" : "var(--comparison-badge-icon-background-color)",
|
|
64
|
+
display: "flex",
|
|
65
|
+
alignItems: "center",
|
|
66
|
+
justifyContent: "center",
|
|
67
|
+
width: "22px",
|
|
68
|
+
height: "22px",
|
|
69
|
+
borderRadius: legacy.borderRadius.pill,
|
|
70
|
+
color: legacy.colors.text.primary
|
|
71
|
+
}),
|
|
72
|
+
trendLabelContainer: css({
|
|
73
|
+
display: "flex",
|
|
74
|
+
flexDirection: "row",
|
|
75
|
+
alignItems: "center",
|
|
76
|
+
gap: spacing.xxs,
|
|
77
|
+
paddingLeft: spacing.xxs,
|
|
78
|
+
fontWeight: typography.fontWeight.medium
|
|
79
|
+
}),
|
|
80
|
+
trendLabel: css({
|
|
81
|
+
display: "flex",
|
|
82
|
+
alignItems: "center",
|
|
83
|
+
color: labelColor,
|
|
84
|
+
lineHeight: `${BADGE_HEIGHT}px`,
|
|
85
|
+
fontWeight: typography.fontWeight.medium,
|
|
86
|
+
fontVariantNumeric: "tabular-nums"
|
|
87
|
+
}),
|
|
88
|
+
timeframeLabel: css({
|
|
89
|
+
color: highlight ? legacy.colors.text.maxContrast : legacy.colors.text.primary,
|
|
90
|
+
paddingLeft: spacing.xxs,
|
|
91
|
+
lineHeight: `${BADGE_HEIGHT}px`,
|
|
92
|
+
fontWeight: typography.fontWeight.normal
|
|
93
|
+
}),
|
|
94
|
+
trendIconWrapper: css({
|
|
95
|
+
display: "flex",
|
|
96
|
+
alignItems: "center",
|
|
97
|
+
justifyContent: "center",
|
|
98
|
+
width: "16px",
|
|
99
|
+
height: "16px"
|
|
100
|
+
}),
|
|
101
|
+
trendIcon: css({
|
|
102
|
+
width: `${TREND_ICON_SIZE}px`,
|
|
103
|
+
height: `${TREND_ICON_SIZE}px`
|
|
104
|
+
}),
|
|
105
|
+
dash: css({
|
|
106
|
+
color: legacy.colors.text.secondary
|
|
107
|
+
})
|
|
108
|
+
};
|
|
109
|
+
};
|
|
110
|
+
|
|
111
|
+
export { cssVariables, getComparisonBadgeStyles };
|
|
112
|
+
//# sourceMappingURL=ComparisonBadge.styles.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ComparisonBadge.styles.js","sources":["../../../../src/components/ComparisonBadge/ComparisonBadge.styles.ts"],"sourcesContent":["import { css } from '@emotion/css';\nimport { CSSVariables, getDesignTokens } from '@grafana/design-tokens';\n\nexport const cssVariables = (): CSSVariables => {\n const { legacy } = getDesignTokens({ valueType: 'css' });\n\n return {\n dark: {\n 'comparison-badge-icon-background-color': legacy.colors.background.secondary,\n 'comparison-badge-icon-highlight-background-color': legacy.palette.whiteBaseOpacity10,\n },\n light: {\n 'comparison-badge-icon-background-color': legacy.colors.background.canvas,\n 'comparison-badge-icon-highlight-background-color': legacy.palette.blackBaseOpacity8,\n },\n };\n};\n\nconst BADGE_HEIGHT = 28;\nconst TREND_ICON_SIZE = 20;\n\nexport const getComparisonBadgeStyles = ({\n highlight,\n direction,\n tooltip,\n}: {\n highlight: boolean;\n direction: string;\n tooltip?: boolean;\n}) => {\n const {\n legacy,\n primitives: { spacing, typography },\n } = getDesignTokens({ valueType: 'css' });\n\n const labelColor = (() => {\n switch (true) {\n case highlight:\n case direction === 'up':\n return legacy.colors.text.maxContrast;\n default:\n return legacy.colors.primary.text;\n }\n })();\n\n return {\n container: css({\n boxSizing: 'border-box',\n background: 'transparent',\n borderRadius: legacy.borderRadius.pill,\n border: `1px solid\n ${highlight ? legacy.colors.border.strong : legacy.colors.border.weak}`,\n padding: `${spacing.xxs} ${spacing.sm} ${spacing.xxs} ${spacing.xxs}`,\n textAlign: 'left',\n display: 'inline-flex',\n flexDirection: 'row',\n justifyContent: 'center',\n alignItems: 'center',\n fontFamily: typography.fontFamily.ui,\n fontSize: typography.fontSize.ui.sm,\n height: `${BADGE_HEIGHT}px`,\n position: 'relative',\n transition: 'background 0.2s ease-in-out',\n ...(tooltip\n ? {\n cursor: 'pointer',\n '&:hover': {\n background: legacy.colors.background.secondary,\n },\n }\n : {}),\n }),\n clockIconWrapper: css({\n background: highlight\n ? 'var(--comparison-badge-icon-highlight-background-color)'\n : 'var(--comparison-badge-icon-background-color)',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n width: '22px',\n height: '22px',\n borderRadius: legacy.borderRadius.pill,\n color: legacy.colors.text.primary,\n }),\n trendLabelContainer: css({\n display: 'flex',\n flexDirection: 'row',\n alignItems: 'center',\n gap: spacing.xxs,\n paddingLeft: spacing.xxs,\n fontWeight: typography.fontWeight.medium,\n }),\n trendLabel: css({\n display: 'flex',\n alignItems: 'center',\n color: labelColor,\n lineHeight: `${BADGE_HEIGHT}px`,\n fontWeight: typography.fontWeight.medium,\n fontVariantNumeric: 'tabular-nums',\n }),\n timeframeLabel: css({\n color: highlight ? legacy.colors.text.maxContrast : legacy.colors.text.primary,\n paddingLeft: spacing.xxs,\n lineHeight: `${BADGE_HEIGHT}px`,\n fontWeight: typography.fontWeight.normal,\n }),\n trendIconWrapper: css({\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n width: '16px',\n height: '16px',\n }),\n trendIcon: css({\n width: `${TREND_ICON_SIZE}px`,\n height: `${TREND_ICON_SIZE}px`,\n }),\n dash: css({\n color: legacy.colors.text.secondary,\n }),\n };\n};\n"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { jsx, jsxs } from 'react/jsx-runtime';
|
|
2
|
+
import { Icon } from '@grafana/ui';
|
|
3
|
+
import { Popover } from '../Popover/Popover.js';
|
|
4
|
+
import { getStyles } from './ComparisonTooltip.styles.js';
|
|
5
|
+
|
|
6
|
+
const ComparisonTooltip = ({
|
|
7
|
+
trigger,
|
|
8
|
+
placement = "top",
|
|
9
|
+
current,
|
|
10
|
+
previous,
|
|
11
|
+
previousLabel,
|
|
12
|
+
currentLabel = "Current",
|
|
13
|
+
title,
|
|
14
|
+
currentIcon = "eye",
|
|
15
|
+
previousIcon = "clock-nine",
|
|
16
|
+
hideDelay
|
|
17
|
+
}) => {
|
|
18
|
+
const styles = getStyles();
|
|
19
|
+
return /* @__PURE__ */ jsx(Popover, { trigger, placement, hideDelay, children: /* @__PURE__ */ jsxs("div", { className: styles.wrapper, children: [
|
|
20
|
+
title && /* @__PURE__ */ jsx("div", { className: styles.heading, children: title }),
|
|
21
|
+
/* @__PURE__ */ jsxs("div", { className: styles.content, children: [
|
|
22
|
+
/* @__PURE__ */ jsxs("div", { className: styles.section, children: [
|
|
23
|
+
/* @__PURE__ */ jsx("div", { className: styles.sectionTitle, children: currentLabel }),
|
|
24
|
+
/* @__PURE__ */ jsxs("div", { className: styles.value, children: [
|
|
25
|
+
/* @__PURE__ */ jsx(Icon, { name: currentIcon, size: "sm", className: styles.icon }),
|
|
26
|
+
/* @__PURE__ */ jsx("span", { children: current || "N/A" })
|
|
27
|
+
] })
|
|
28
|
+
] }),
|
|
29
|
+
/* @__PURE__ */ jsxs("div", { className: styles.section, children: [
|
|
30
|
+
/* @__PURE__ */ jsx("div", { className: styles.sectionTitle, children: previousLabel }),
|
|
31
|
+
/* @__PURE__ */ jsxs("div", { className: styles.value, children: [
|
|
32
|
+
/* @__PURE__ */ jsx(Icon, { name: previousIcon, size: "sm", className: styles.icon }),
|
|
33
|
+
/* @__PURE__ */ jsx("span", { children: previous || "N/A" })
|
|
34
|
+
] })
|
|
35
|
+
] })
|
|
36
|
+
] })
|
|
37
|
+
] }) });
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
export { ComparisonTooltip };
|
|
41
|
+
//# sourceMappingURL=ComparisonTooltip.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ComparisonTooltip.js","sources":["../../../../src/components/ComparisonTooltip/ComparisonTooltip.tsx"],"sourcesContent":["import { Icon, IconName } from '@grafana/ui';\nimport { Popover, PopoverProps } from '../Popover';\nimport { getStyles } from './ComparisonTooltip.styles';\n\nexport interface ComparisonTooltipProps extends Omit<PopoverProps, 'children'> {\n current?: string;\n previous?: string;\n previousLabel?: string;\n currentLabel?: string;\n title?: string;\n currentIcon?: IconName;\n previousIcon?: IconName;\n hideDelay?: number;\n}\n\nexport const ComparisonTooltip = ({\n trigger,\n placement = 'top',\n current,\n previous,\n previousLabel,\n currentLabel = 'Current',\n title,\n currentIcon = 'eye',\n previousIcon = 'clock-nine',\n hideDelay,\n}: ComparisonTooltipProps) => {\n const styles = getStyles();\n\n return (\n <Popover trigger={trigger} placement={placement} hideDelay={hideDelay}>\n <div className={styles.wrapper}>\n {title && <div className={styles.heading}>{title}</div>}\n <div className={styles.content}>\n <div className={styles.section}>\n <div className={styles.sectionTitle}>{currentLabel}</div>\n <div className={styles.value}>\n <Icon name={currentIcon} size=\"sm\" className={styles.icon} />\n <span>{current || 'N/A'}</span>\n </div>\n </div>\n <div className={styles.section}>\n <div className={styles.sectionTitle}>{previousLabel}</div>\n <div className={styles.value}>\n <Icon name={previousIcon} size=\"sm\" className={styles.icon} />\n <span>{previous || 'N/A'}</span>\n </div>\n </div>\n </div>\n </div>\n </Popover>\n );\n};\n"],"names":[],"mappings":";;;;;AAeO,MAAM,oBAAoB,CAAC;AAAA,EAChC,OAAA;AAAA,EACA,SAAA,GAAY,KAAA;AAAA,EACZ,OAAA;AAAA,EACA,QAAA;AAAA,EACA,aAAA;AAAA,EACA,YAAA,GAAe,SAAA;AAAA,EACf,KAAA;AAAA,EACA,WAAA,GAAc,KAAA;AAAA,EACd,YAAA,GAAe,YAAA;AAAA,EACf;AACF,CAAA,KAA8B;AAC5B,EAAA,MAAM,SAAS,SAAA,EAAU;AAEzB,EAAA,uBACE,GAAA,CAAC,WAAQ,OAAA,EAAkB,SAAA,EAAsB,WAC/C,QAAA,kBAAA,IAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAW,MAAA,CAAO,OAAA,EACpB,QAAA,EAAA;AAAA,IAAA,KAAA,oBAAS,GAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAW,MAAA,CAAO,SAAU,QAAA,EAAA,KAAA,EAAM,CAAA;AAAA,oBACjD,IAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAW,MAAA,CAAO,OAAA,EACrB,QAAA,EAAA;AAAA,sBAAA,IAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAW,MAAA,CAAO,OAAA,EACrB,QAAA,EAAA;AAAA,wBAAA,GAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAW,MAAA,CAAO,YAAA,EAAe,QAAA,EAAA,YAAA,EAAa,CAAA;AAAA,wBACnD,IAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAW,MAAA,CAAO,KAAA,EACrB,QAAA,EAAA;AAAA,0BAAA,GAAA,CAAC,QAAK,IAAA,EAAM,WAAA,EAAa,MAAK,IAAA,EAAK,SAAA,EAAW,OAAO,IAAA,EAAM,CAAA;AAAA,0BAC3D,GAAA,CAAC,MAAA,EAAA,EAAM,QAAA,EAAA,OAAA,IAAW,KAAA,EAAM;AAAA,SAAA,EAC1B;AAAA,OAAA,EACF,CAAA;AAAA,sBACA,IAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAW,MAAA,CAAO,OAAA,EACrB,QAAA,EAAA;AAAA,wBAAA,GAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAW,MAAA,CAAO,YAAA,EAAe,QAAA,EAAA,aAAA,EAAc,CAAA;AAAA,wBACpD,IAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAW,MAAA,CAAO,KAAA,EACrB,QAAA,EAAA;AAAA,0BAAA,GAAA,CAAC,QAAK,IAAA,EAAM,YAAA,EAAc,MAAK,IAAA,EAAK,SAAA,EAAW,OAAO,IAAA,EAAM,CAAA;AAAA,0BAC5D,GAAA,CAAC,MAAA,EAAA,EAAM,QAAA,EAAA,QAAA,IAAY,KAAA,EAAM;AAAA,SAAA,EAC3B;AAAA,OAAA,EACF;AAAA,KAAA,EACF;AAAA,GAAA,EACF,CAAA,EACF,CAAA;AAEJ;;;;"}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { css } from '@emotion/css';
|
|
2
|
+
import { getDesignTokens } from '../../node_modules/@grafana/design-tokens/dist/esm/lib/getDesignTokens/getDesignTokens.js';
|
|
3
|
+
|
|
4
|
+
const getStyles = () => {
|
|
5
|
+
const {
|
|
6
|
+
legacy,
|
|
7
|
+
primitives: { spacing, typography }
|
|
8
|
+
} = getDesignTokens({ valueType: "css" });
|
|
9
|
+
return {
|
|
10
|
+
wrapper: css({
|
|
11
|
+
display: "flex",
|
|
12
|
+
flexDirection: "column",
|
|
13
|
+
gap: spacing.xs
|
|
14
|
+
}),
|
|
15
|
+
heading: css({
|
|
16
|
+
padding: `${spacing.sm} ${spacing.md}`,
|
|
17
|
+
fontFamily: typography.fontFamily.ui,
|
|
18
|
+
fontSize: typography.fontSize.ui.sm,
|
|
19
|
+
fontWeight: typography.fontWeight.bold,
|
|
20
|
+
color: legacy.colors.text.primary,
|
|
21
|
+
background: legacy.colors.background.secondary,
|
|
22
|
+
borderRadius: legacy.borderRadius.md
|
|
23
|
+
}),
|
|
24
|
+
content: css({
|
|
25
|
+
display: "flex",
|
|
26
|
+
gap: spacing.xs
|
|
27
|
+
}),
|
|
28
|
+
section: css({
|
|
29
|
+
display: "flex",
|
|
30
|
+
flex: 1,
|
|
31
|
+
flexDirection: "column",
|
|
32
|
+
justifyContent: "flex-end",
|
|
33
|
+
gap: spacing.xs,
|
|
34
|
+
background: legacy.colors.background.secondary,
|
|
35
|
+
borderRadius: legacy.borderRadius.md,
|
|
36
|
+
padding: `${spacing.sm} ${spacing.md}`,
|
|
37
|
+
minWidth: `80px`
|
|
38
|
+
}),
|
|
39
|
+
sectionTitle: css({
|
|
40
|
+
fontFamily: typography.fontFamily.ui,
|
|
41
|
+
fontSize: typography.fontSize.ui.sm,
|
|
42
|
+
fontWeight: typography.fontWeight.medium,
|
|
43
|
+
color: legacy.colors.text.primary,
|
|
44
|
+
whiteSpace: "nowrap"
|
|
45
|
+
}),
|
|
46
|
+
value: css({
|
|
47
|
+
display: "flex",
|
|
48
|
+
alignItems: "center",
|
|
49
|
+
gap: spacing.xs,
|
|
50
|
+
fontFamily: typography.fontFamily.monospace,
|
|
51
|
+
fontSize: typography.fontSize.monospace.sm,
|
|
52
|
+
color: legacy.colors.text.secondary
|
|
53
|
+
}),
|
|
54
|
+
icon: css({
|
|
55
|
+
flexShrink: 0
|
|
56
|
+
})
|
|
57
|
+
};
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
export { getStyles };
|
|
61
|
+
//# sourceMappingURL=ComparisonTooltip.styles.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ComparisonTooltip.styles.js","sources":["../../../../src/components/ComparisonTooltip/ComparisonTooltip.styles.ts"],"sourcesContent":["import { css } from '@emotion/css';\nimport { getDesignTokens } from '@grafana/design-tokens';\n\nexport const getStyles = () => {\n const {\n legacy,\n primitives: { spacing, typography },\n } = getDesignTokens({ valueType: 'css' });\n\n return {\n wrapper: css({\n display: 'flex',\n flexDirection: 'column',\n gap: spacing.xs,\n }),\n heading: css({\n padding: `${spacing.sm} ${spacing.md}`,\n fontFamily: typography.fontFamily.ui,\n fontSize: typography.fontSize.ui.sm,\n fontWeight: typography.fontWeight.bold,\n color: legacy.colors.text.primary,\n background: legacy.colors.background.secondary,\n borderRadius: legacy.borderRadius.md,\n }),\n content: css({\n display: 'flex',\n gap: spacing.xs,\n }),\n section: css({\n display: 'flex',\n flex: 1,\n flexDirection: 'column',\n justifyContent: 'flex-end',\n gap: spacing.xs,\n background: legacy.colors.background.secondary,\n borderRadius: legacy.borderRadius.md,\n padding: `${spacing.sm} ${spacing.md}`,\n minWidth: `80px`,\n }),\n sectionTitle: css({\n fontFamily: typography.fontFamily.ui,\n fontSize: typography.fontSize.ui.sm,\n fontWeight: typography.fontWeight.medium,\n color: legacy.colors.text.primary,\n whiteSpace: 'nowrap',\n }),\n value: css({\n display: 'flex',\n alignItems: 'center',\n gap: spacing.xs,\n fontFamily: typography.fontFamily.monospace,\n fontSize: typography.fontSize.monospace.sm,\n color: legacy.colors.text.secondary,\n }),\n icon: css({\n flexShrink: 0,\n }),\n };\n};\n"],"names":[],"mappings":";;;AAGO,MAAM,YAAY,MAAM;AAC7B,EAAA,MAAM;AAAA,IACJ,MAAA;AAAA,IACA,UAAA,EAAY,EAAE,OAAA,EAAS,UAAA;AAAW,GACpC,GAAI,eAAA,CAAgB,EAAE,SAAA,EAAW,OAAO,CAAA;AAExC,EAAA,OAAO;AAAA,IACL,SAAS,GAAA,CAAI;AAAA,MACX,OAAA,EAAS,MAAA;AAAA,MACT,aAAA,EAAe,QAAA;AAAA,MACf,KAAK,OAAA,CAAQ;AAAA,KACd,CAAA;AAAA,IACD,SAAS,GAAA,CAAI;AAAA,MACX,SAAS,CAAA,EAAG,OAAA,CAAQ,EAAE,CAAA,CAAA,EAAI,QAAQ,EAAE,CAAA,CAAA;AAAA,MACpC,UAAA,EAAY,WAAW,UAAA,CAAW,EAAA;AAAA,MAClC,QAAA,EAAU,UAAA,CAAW,QAAA,CAAS,EAAA,CAAG,EAAA;AAAA,MACjC,UAAA,EAAY,WAAW,UAAA,CAAW,IAAA;AAAA,MAClC,KAAA,EAAO,MAAA,CAAO,MAAA,CAAO,IAAA,CAAK,OAAA;AAAA,MAC1B,UAAA,EAAY,MAAA,CAAO,MAAA,CAAO,UAAA,CAAW,SAAA;AAAA,MACrC,YAAA,EAAc,OAAO,YAAA,CAAa;AAAA,KACnC,CAAA;AAAA,IACD,SAAS,GAAA,CAAI;AAAA,MACX,OAAA,EAAS,MAAA;AAAA,MACT,KAAK,OAAA,CAAQ;AAAA,KACd,CAAA;AAAA,IACD,SAAS,GAAA,CAAI;AAAA,MACX,OAAA,EAAS,MAAA;AAAA,MACT,IAAA,EAAM,CAAA;AAAA,MACN,aAAA,EAAe,QAAA;AAAA,MACf,cAAA,EAAgB,UAAA;AAAA,MAChB,KAAK,OAAA,CAAQ,EAAA;AAAA,MACb,UAAA,EAAY,MAAA,CAAO,MAAA,CAAO,UAAA,CAAW,SAAA;AAAA,MACrC,YAAA,EAAc,OAAO,YAAA,CAAa,EAAA;AAAA,MAClC,SAAS,CAAA,EAAG,OAAA,CAAQ,EAAE,CAAA,CAAA,EAAI,QAAQ,EAAE,CAAA,CAAA;AAAA,MACpC,QAAA,EAAU,CAAA,IAAA;AAAA,KACX,CAAA;AAAA,IACD,cAAc,GAAA,CAAI;AAAA,MAChB,UAAA,EAAY,WAAW,UAAA,CAAW,EAAA;AAAA,MAClC,QAAA,EAAU,UAAA,CAAW,QAAA,CAAS,EAAA,CAAG,EAAA;AAAA,MACjC,UAAA,EAAY,WAAW,UAAA,CAAW,MAAA;AAAA,MAClC,KAAA,EAAO,MAAA,CAAO,MAAA,CAAO,IAAA,CAAK,OAAA;AAAA,MAC1B,UAAA,EAAY;AAAA,KACb,CAAA;AAAA,IACD,OAAO,GAAA,CAAI;AAAA,MACT,OAAA,EAAS,MAAA;AAAA,MACT,UAAA,EAAY,QAAA;AAAA,MACZ,KAAK,OAAA,CAAQ,EAAA;AAAA,MACb,UAAA,EAAY,WAAW,UAAA,CAAW,SAAA;AAAA,MAClC,QAAA,EAAU,UAAA,CAAW,QAAA,CAAS,SAAA,CAAU,EAAA;AAAA,MACxC,KAAA,EAAO,MAAA,CAAO,MAAA,CAAO,IAAA,CAAK;AAAA,KAC3B,CAAA;AAAA,IACD,MAAM,GAAA,CAAI;AAAA,MACR,UAAA,EAAY;AAAA,KACb;AAAA,GACH;AACF;;;;"}
|