@grafana/components 0.0.31 → 0.0.32

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/README.md CHANGED
@@ -1,5 +1,38 @@
1
1
  # Grafana Product Design Engineering Components
2
2
 
3
+ ## Usage
4
+
5
+ Add `@grafana/components` to your project’s dependencies:
6
+
7
+ ```bash
8
+ $ npm install @grafana/components
9
+ ```
10
+
11
+ or
12
+
13
+ ```bash
14
+ $ yarn add @grafana/components
15
+ ```
16
+
17
+ For components that have elements based on Floating UI, you must ensure you wrap
18
+ your application in a `<PortalProvider>` component at a sufficient root level,
19
+ passing in the `defaultRoot` prop indicating the element floating elements
20
+ should be portalled inside of:
21
+
22
+ ```tsx
23
+ import { PortalProvider } from '@grafana/components';
24
+
25
+ const MyApp = () => {
26
+ return (
27
+ <>
28
+ <PortalProvider defaultRoot={document.getElementById('grafana-portal-container')}>
29
+ ...
30
+ </PortalProvider>
31
+ </>
32
+ );
33
+ };
34
+ ```
35
+
3
36
  ...
4
37
 
5
38
  ### Publishing
@@ -3,8 +3,8 @@
3
3
  Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
5
  var jsxRuntime = require('react/jsx-runtime');
6
- var runtime = require('@grafana/runtime');
7
6
  var React = require('react');
7
+ var runtime = require('@grafana/runtime');
8
8
  require('@grafana/design-tokens/dist/css/legacy/primitives.css');
9
9
  require('@grafana/design-tokens/dist/css/legacy/colors.light.css');
10
10
  require('@grafana/design-tokens/dist/css/legacy/colors.dark.css');
@@ -26,7 +26,6 @@ const ColorModeProvider = ({
26
26
  }) => {
27
27
  const [colorMode, setColorMode] = React.useState(defaultColorMode);
28
28
  React.useEffect(() => {
29
- console.log("ColorModeProvider", { colorMode });
30
29
  document.documentElement.setAttribute("data-color-mode", colorMode);
31
30
  }, [colorMode]);
32
31
  return /* @__PURE__ */ jsxRuntime.jsx(ColorModeContext.Provider, { value: { colorMode, setColorMode }, children });
@@ -46,18 +45,26 @@ const useColorModeChange = ({
46
45
  getAppEvents,
47
46
  useTheme2
48
47
  }) => {
49
- const { setColorMode } = useColorMode();
48
+ const { colorMode, setColorMode } = useColorMode();
50
49
  const appEvents = getAppEvents();
51
- appEvents.subscribe(runtime.ThemeChangedEvent, ({ payload }) => {
52
- const { isLight: isLight2 } = payload;
53
- const newColorMode2 = getThemeColorMode(isLight2);
54
- console.log("ThemeChangedEvent", { colorMode: newColorMode2 });
55
- setColorMode(newColorMode2);
56
- });
57
50
  const { isLight } = useTheme2();
58
- const newColorMode = getThemeColorMode(isLight);
59
- setColorMode(newColorMode);
60
- return newColorMode;
51
+ React.useEffect(() => {
52
+ const themeChangedEvent = appEvents.subscribe(
53
+ runtime.ThemeChangedEvent,
54
+ ({ payload }) => {
55
+ const newColorMode = getThemeColorMode(payload.isLight);
56
+ setColorMode(newColorMode);
57
+ }
58
+ );
59
+ return () => {
60
+ themeChangedEvent.unsubscribe();
61
+ };
62
+ }, [appEvents, setColorMode]);
63
+ React.useEffect(() => {
64
+ const newColorMode = getThemeColorMode(isLight);
65
+ setColorMode(newColorMode);
66
+ }, [isLight, setColorMode]);
67
+ return colorMode;
61
68
  };
62
69
 
63
70
  const ColorModeChangeHandler = ({ children, getAppEvents, useTheme2 }) => {
@@ -127,24 +134,17 @@ const calculateComparison = (current, baseline) => {
127
134
  };
128
135
 
129
136
  const PortalContext = React.createContext(void 0);
130
- const PortalProvider = ({
131
- children,
132
- defaultRoot: _root = null
133
- }) => {
134
- const defaultRoot = (() => {
135
- switch (true) {
136
- case Boolean(_root):
137
- return _root;
138
- default:
139
- return document.body;
140
- }
141
- })();
142
- const [root, setRoot] = React.useState(defaultRoot);
137
+ const PortalProvider = ({ children, defaultRoot = null }) => {
138
+ const [root, setRoot] = React.useState(defaultRoot != null ? defaultRoot : document.body);
143
139
  return /* @__PURE__ */ jsxRuntime.jsx(PortalContext.Provider, { value: { root, setRoot }, children });
144
140
  };
145
- const usePortal = () => {
141
+ const usePortal = ({ allowOutsideProvider = false } = {}) => {
146
142
  const context = React.useContext(PortalContext);
147
143
  if (context === void 0) {
144
+ if (allowOutsideProvider) {
145
+ return { root: document.body, setRoot: () => {
146
+ } };
147
+ }
148
148
  throw new Error("usePortal must be used within a PortalProvider");
149
149
  }
150
150
  return context;
@@ -217,8 +217,8 @@ const Popover = React.forwardRef(
217
217
  const isOpen = isOpenControlled != null ? isOpenControlled : isOpenState;
218
218
  const middleware = getMiddleware({ placement, arrowRef });
219
219
  const styles = getStyles$7();
220
+ const { root } = usePortal();
220
221
  const portalRoot = (() => {
221
- const { root } = usePortal();
222
222
  switch (true) {
223
223
  case portalContainer instanceof HTMLElement:
224
224
  return portalContainer;
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs","sources":["../../src/components/ColorModeProvider/ColorModeProvider.tsx","../../src/hooks/useColorModeChange.ts","../../src/components/ColorModeChangeHandler/ColorModeChangeHandler.tsx","../../src/components/ColorMode/ColorMode.tsx","../../src/utils/formatters.ts","../../src/utils/comparison.ts","../../src/components/PortalProvider/PortalProvider.tsx","../../src/components/Popover/Popover.styles.ts","../../src/components/Popover/Popover.tsx","../../src/components/ComparisonTooltip/ComparisonTooltip.styles.ts","../../src/components/ComparisonTooltip/ComparisonTooltip.tsx","../../src/components/ComparisonBadge/ComparisonBadge.styles.ts","../../src/components/ComparisonBadge/ComparisonBadge.tsx","../../src/components/GenericSkeleton/GenericSkeleton.styles.ts","../../src/components/GenericSkeleton/GenericSkeleton.tsx","../../src/components/StackedChart/shared.styles.ts","../../src/components/StackedChartSegment/StackedChartSegment.styles.ts","../../src/components/StackedChartSegment/StackedChartSegment.tsx","../../src/components/StackedChart/StackedChart.styles.ts","../../src/components/StackedChartSegmentTooltip/StackedChartSegmentTooltip.styles.ts","../../src/components/StackedChartSegmentTooltip/StackedChartSegmentTooltip.tsx","../../src/components/StackedChartSkeleton/StackedChartSkeleton.styles.ts","../../src/components/StackedChart/common.ts","../../src/components/StackedChartSkeleton/StackedChartSkeleton.tsx","../../src/components/StackedChartNoData/StackedChartNoData.styles.ts","../../src/components/StackedChartNoData/StackedChartNoData.tsx","../../src/components/StackedChart/StackedChart.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","import type { EventBus, GrafanaTheme2 } from '@grafana/data';\nimport { ThemeChangedEvent } from '@grafana/runtime';\nimport type { ThemeColorMode } from '@grafana/design-tokens';\nimport { useColorMode } from '../components/ColorModeProvider/ColorModeProvider';\n\nconst getThemeColorMode = (isLight: boolean): ThemeColorMode => {\n return isLight ? 'light' : 'dark';\n};\n\nexport interface ColorModeChangeProps {\n getAppEvents: () => EventBus;\n useTheme2: () => GrafanaTheme2;\n}\n\n/**\n * This allows us to register an event listener for when the ThemeChangedEvent\n * is fired, and update the currently active color mode accordingly. It will\n * also determine the color mode on initial registration, and update the context\n * provider accordingly.\n */\nexport const useColorModeChange = ({\n getAppEvents,\n useTheme2,\n}: ColorModeChangeProps): ThemeColorMode => {\n const { setColorMode } = useColorMode();\n const appEvents = getAppEvents();\n\n appEvents.subscribe<ThemeChangedEvent>(ThemeChangedEvent, ({ payload }) => {\n const { isLight } = payload;\n const newColorMode = getThemeColorMode(isLight);\n\n console.log('ThemeChangedEvent', { colorMode: newColorMode });\n setColorMode(newColorMode);\n });\n\n /**\n * Longterm the current colorMode should ideally exist outside of useTheme2\n */\n const { isLight } = useTheme2();\n const newColorMode = getThemeColorMode(isLight);\n setColorMode(newColorMode);\n\n return newColorMode;\n};\n","import React from 'react';\nimport { useColorModeChange, ColorModeChangeProps } from '../../hooks';\n\nexport type ColorModeWrapper = React.FC<ColorModeChangeProps & { children: React.ReactNode }>;\n\nexport const ColorModeChangeHandler: ColorModeWrapper = ({ children, getAppEvents, useTheme2 }) => {\n useColorModeChange({ getAppEvents, useTheme2 });\n\n return children;\n};\n","import { ColorModeWrapper, ColorModeChangeHandler } from '../ColorModeChangeHandler';\nimport { ColorModeProvider } from '../ColorModeProvider';\n\nexport const ColorMode: ColorModeWrapper = ({ children, getAppEvents, useTheme2 }) => {\n return (\n <ColorModeProvider>\n <ColorModeChangeHandler getAppEvents={getAppEvents} useTheme2={useTheme2}>\n {children}\n </ColorModeChangeHandler>\n </ColorModeProvider>\n );\n};\n","/**\n * Number formatting options\n */\nexport interface FormatNumberOptions {\n /** Decimal places (default: 2) */\n decimals?: number;\n /** Threshold for compact formatting (default: 1000) */\n compactThreshold?: number;\n /** Never use compact formatting (for precise displays) */\n precise?: boolean;\n}\n\n/**\n * Format numbers with optional compact notation (k, m, b)\n * Components handle their own prefixes/suffixes ($ or %)\n *\n * @param value - The number to format (or 'loading' state)\n * @param options - Formatting options\n * @returns Formatted number string (no prefixes/suffixes)\n *\n * @example\n * formatNumber(1234) // \"1.2k\"\n * formatNumber(1234, { precise: true }) // \"1,234.00\"\n * formatNumber(1234, { decimals: 0 }) // \"1k\"\n * formatNumber(999) // \"999.00\"\n */\nexport const formatNumber = (\n value: number | string | 'loading',\n options: FormatNumberOptions = {},\n): string => {\n const { decimals = 2, compactThreshold = 1000, precise = false } = options;\n\n if (value === 'loading') {\n return '';\n }\n\n const num = typeof value === 'string' ? parseFloat(value) : value;\n if (isNaN(num)) {\n return 'N/A';\n }\n\n const abs = Math.abs(num);\n\n // Use compact notation if above threshold and not precise\n if (!precise && abs >= compactThreshold) {\n const sign = num < 0 ? '-' : '';\n const absNum = Math.abs(num);\n // Always use 1 decimal place for compact notation for consistency\n if (absNum >= 1000000000) {\n return `${sign}${(absNum / 1000000000).toFixed(1)}b`;\n } else if (absNum >= 1000000) {\n return `${sign}${(absNum / 1000000).toFixed(1)}m`;\n } else if (absNum >= 1000) {\n return `${sign}${(absNum / 1000).toFixed(1)}k`;\n }\n }\n\n // Standard formatting with specified decimal places\n return num.toLocaleString('en-US', {\n minimumFractionDigits: decimals,\n maximumFractionDigits: decimals,\n });\n};\n","/**\n * Shared utility functions for handling comparison calculations across components\n */\n\nimport { formatNumber } from './formatters';\n\nexport interface ComparisonResult {\n hasComparison: boolean;\n direction: 'up' | 'down' | 'neutral';\n percentageChange: number;\n percentageLabel: string;\n}\n\n/**\n * Calculate comparison metrics between a current value and a baseline value\n * @param current - The current value to compare\n * @param baseline - The baseline value to compare against (optional)\n * @returns ComparisonResult object with calculated metrics\n */\nexport const calculateComparison = (\n current: number | undefined | null,\n baseline: number | undefined | null,\n): ComparisonResult => {\n // If either value is missing, null, undefined, or baseline is 0, return neutral state\n if (\n current === undefined ||\n current === null ||\n baseline === undefined ||\n baseline === null ||\n baseline === 0\n ) {\n return {\n hasComparison: false,\n direction: 'neutral',\n percentageChange: 0,\n percentageLabel: '',\n };\n }\n\n // If values are equal, return neutral state\n if (current === baseline) {\n return {\n hasComparison: true,\n direction: 'neutral',\n percentageChange: 0,\n percentageLabel: '0%',\n };\n }\n\n // Calculate percentage change\n const percentageChange = Math.abs(((current - baseline) / baseline) * 100);\n const direction = current > baseline ? 'up' : 'down';\n\n return {\n hasComparison: true,\n direction,\n percentageChange,\n percentageLabel: `${formatNumber(percentageChange, {\n compactThreshold: 10000,\n decimals: 2,\n })}%`,\n };\n};\n","import React, { createContext, useContext, useState, ReactNode } from 'react';\nimport type { FloatingPortalProps } from '@floating-ui/react';\n\nexport type PortalRoot = FloatingPortalProps['root'];\n\nexport interface PortalContextType {\n root: PortalRoot;\n setRoot: (root: PortalRoot) => void;\n}\n\nexport interface PortalProviderProps {\n children: ReactNode;\n defaultRoot?: PortalRoot;\n}\n\nconst PortalContext = createContext<PortalContextType | undefined>(undefined);\n\n/**\n * Provides a shared context for a portal root, which can be a selector string,\n * an HTMLElement, or null.\n */\nexport const PortalProvider: React.FC<PortalProviderProps> = ({\n children,\n defaultRoot: _root = null,\n}) => {\n const defaultRoot = (() => {\n switch (true) {\n case Boolean(_root):\n return _root;\n default:\n return document.body;\n }\n })();\n\n const [root, setRoot] = useState<PortalRoot>(defaultRoot);\n\n return <PortalContext.Provider value={{ root, setRoot }}>{children}</PortalContext.Provider>;\n};\n\n/**\n * Use this hook to access the portal root context.\n */\nexport const usePortal = () => {\n const context = useContext(PortalContext);\n\n if (context === undefined) {\n throw new Error('usePortal must be used within a PortalProvider');\n }\n\n return context;\n};\n","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 const backgroundColor = legacy.colors.background.secondary;\n\n return {\n arrow: css({\n fill: backgroundColor,\n }),\n shadow: css({\n filter: `drop-shadow(${legacy.boxShadows.z2})`,\n }),\n container: css({\n backgroundColor,\n borderRadius: `calc(${legacy.borderRadius.md} + ${spacing.xs})`,\n padding: spacing.xs,\n color: legacy.colors.text.primary,\n fontFamily: typography.fontFamily.ui,\n fontSize: typography.fontSize.ui.sm,\n }),\n };\n};\n","import {\n forwardRef,\n cloneElement,\n useCallback,\n useId,\n useRef,\n useState,\n useLayoutEffect,\n JSX,\n} from 'react';\nimport {\n arrow,\n autoUpdate,\n flip,\n FloatingArrow,\n offset,\n Placement,\n safePolygon,\n shift,\n useDismiss,\n useFloating,\n useFocus,\n useHover,\n useRole,\n useInteractions,\n useTransitionStyles,\n FloatingPortal,\n FloatingPortalProps,\n} from '@floating-ui/react';\nimport { usePortal } from '../PortalProvider';\nimport { getStyles } from './Popover.styles';\n\nexport interface PopoverProps {\n /**\n * Content used to trigger the Popover being displayed\n */\n trigger: JSX.Element;\n\n /**\n * Content to render within the Popover\n */\n children: JSX.Element;\n /**\n * Should the popover be open? Implicitly means the popover visibility is\n * controlled; if omitted, the popover target will control visibility\n */\n isOpen?: boolean;\n\n /**\n * Set to true if you want the tooltip to stay long enough so the user can\n * move mouse over content to select text or click a link\n */\n isInteractive?: boolean;\n\n /**\n * Placement of the Popover relative to the trigger content\n */\n placement?: Placement;\n\n /**\n * Transition duration for hide/show effects, in milliseconds\n */\n transitionDuration?: number;\n\n /**\n * Additional delay before hiding the popover after mouseout, in milliseconds\n */\n hideDelay?: number;\n\n /**\n * Virtual element to anchor the popover to instead of the trigger\n */\n virtualElement?: React.RefObject<Element>;\n\n /**\n * DOM element or ID to render the portal into, falls back to document.body\n */\n portalContainer?: FloatingPortalProps['root'];\n}\n\nconst POPOVER_OFFSET = 8;\n\nconst getMiddleware = ({\n placement,\n arrowRef,\n}: {\n placement?: Placement;\n arrowRef: React.RefObject<null>;\n}) => {\n const BOUNDARY_ELEMENT_ID = 'floating-boundary';\n const _flip = flip({\n // Ensure we flip to the perpendicular axis if it doesn't fit\n // on narrow viewports.\n crossAxis: 'alignment',\n fallbackAxisSideDirection: 'end',\n boundary: document.getElementById(BOUNDARY_ELEMENT_ID) ?? undefined,\n });\n\n const middleware = placement?.includes('-') ? [_flip, shift()] : [shift(), _flip];\n\n // the order of middleware is important!\n // `arrow` should almost always be at the end\n // see https://floating-ui.com/docs/arrow#order\n return [\n offset(POPOVER_OFFSET),\n ...middleware,\n arrow({\n element: arrowRef,\n }),\n ];\n};\n\nexport const Popover = forwardRef<HTMLElement, PopoverProps>(\n (\n {\n trigger,\n children,\n isOpen: isOpenControlled,\n isInteractive = false,\n placement = 'bottom',\n transitionDuration = 200,\n hideDelay = 500,\n virtualElement,\n portalContainer,\n },\n forwardedRef,\n ) => {\n const arrowRef = useRef(null);\n const closeTimer = useRef<number | undefined>(undefined);\n const popoverId = useId();\n const [isOpenState, setOpen] = useState(isOpenControlled);\n const [isDelayedOpen, setDelayedOpen] = useState(isOpenControlled);\n const isOpen = isOpenControlled ?? isOpenState;\n const middleware = getMiddleware({ placement, arrowRef });\n const styles = getStyles();\n const portalRoot = (() => {\n const { root } = usePortal();\n\n switch (true) {\n case portalContainer instanceof HTMLElement:\n return portalContainer;\n case typeof portalContainer === 'string':\n return document.getElementById(portalContainer);\n default:\n return root;\n }\n })();\n\n const { context, refs, floatingStyles } = useFloating({\n open: isOpen,\n placement,\n onOpenChange: (open) => {\n setOpen(open);\n clearTimeout(closeTimer.current);\n\n if (!open) {\n closeTimer.current = window.setTimeout(() => {\n setDelayedOpen(open);\n }, transitionDuration + hideDelay);\n } else {\n setDelayedOpen(open);\n }\n },\n middleware,\n whileElementsMounted: autoUpdate,\n });\n\n useLayoutEffect(() => {\n if (virtualElement && virtualElement.current !== null) {\n const domRect = virtualElement.current.getBoundingClientRect();\n\n refs.setPositionReference({\n getBoundingClientRect: () => {\n if (virtualElement.current !== null)\n return virtualElement.current.getBoundingClientRect();\n return domRect;\n },\n contextElement: virtualElement.current,\n });\n }\n }, [refs, virtualElement]);\n\n const { getReferenceProps, getFloatingProps } = useInteractions([\n useDismiss(context),\n useHover(context, {\n handleClose: isInteractive ? safePolygon() : undefined,\n move: false,\n delay: {\n open: 0,\n close: hideDelay,\n },\n }),\n useFocus(context),\n useRole(context),\n ]);\n\n const { styles: transitionStyles } = useTransitionStyles(context, {\n duration: transitionDuration,\n initial: ({ side }) => ({\n opacity: 0,\n transform:\n side === 'top' || side === 'bottom'\n ? `translateY(${POPOVER_OFFSET}px)`\n : `translateX(${POPOVER_OFFSET}px)`,\n }),\n open: ({ side }) => ({\n opacity: 1,\n transform: side === 'top' || side === 'bottom' ? `translateY(0)` : `translateX(0)`,\n }),\n close: ({ side }) => ({\n opacity: 0,\n transform:\n side === 'top' || side === 'bottom'\n ? `translateY(${POPOVER_OFFSET}px)`\n : `translateX(${POPOVER_OFFSET}px)`,\n }),\n });\n\n const handleRef = useCallback(\n (ref: HTMLElement | null) => {\n refs.setReference(ref);\n\n if (typeof forwardedRef === 'function') {\n forwardedRef(ref);\n } else if (forwardedRef) {\n forwardedRef.current = ref;\n }\n },\n [forwardedRef, refs],\n );\n\n return (\n <>\n {/* element to trigger displaying the popover */}\n {cloneElement(trigger, {\n ref: handleRef,\n tabIndex: 0,\n 'aria-describedby': isOpen ? popoverId : undefined,\n ...getReferenceProps(),\n })}\n {/* content to render inside the popover when open */}\n {(isDelayedOpen || isOpen) && (\n <FloatingPortal root={portalRoot}>\n <div ref={refs.setFloating} style={floatingStyles} {...getFloatingProps()}>\n <div style={transitionStyles} className={styles.shadow}>\n <FloatingArrow className={styles.arrow} ref={arrowRef} context={context} />\n <div id={popoverId} role=\"tooltip\" className={styles.container}>\n {children}\n </div>\n </div>\n </div>\n </FloatingPortal>\n )}\n </>\n );\n },\n);\n\nPopover.displayName = 'Popover';\n","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 const background = legacy.colors.background.primary;\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,\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,\n borderRadius: legacy.borderRadius.md,\n padding: `${spacing.sm} ${spacing.md}`,\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","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","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 whiteSpace: 'nowrap',\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","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 hideDelay?: number;\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 hideDelay,\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 hideDelay={hideDelay}\n />\n ) : (\n badgeContent\n )}\n </>\n );\n};\n","import { css, keyframes } 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 'skeleton-gradient-background-color': legacy.palette.whiteBaseOpacity12,\n },\n light: {\n 'skeleton-gradient-background-color': legacy.palette.blackBaseOpacity12,\n },\n };\n};\n\nconst shimmer = keyframes({\n '0%': {\n transform: 'translateX(-100%);',\n },\n '100%': {\n transform: 'translateX(100%);',\n },\n});\n\nexport const getStyles = (animationDuration: number) => {\n return css({\n display: 'flex',\n width: '100%',\n height: '100%',\n background: 'transparent',\n position: 'relative',\n overflow: 'hidden',\n borderRadius: '5px',\n '&::before': {\n content: \"''\",\n position: 'absolute',\n top: 0,\n left: 0,\n width: '100%',\n height: '100%',\n animation: `${shimmer} ${animationDuration}s ease-in-out infinite`,\n transform: 'translateX(-100%)',\n background:\n 'linear-gradient(90deg, transparent, var(--skeleton-gradient-background-color), transparent)',\n },\n });\n};\n","import { GlobalCSSVariables } from '@grafana/design-tokens';\nimport { cssVariables, getStyles } from './GenericSkeleton.styles';\n\nexport interface GenericSkeletonProps {\n /**\n * Duration of animation in seconds\n */\n animationDuration?: number;\n}\n\nexport const GenericSkeleton = ({ animationDuration = 2 }: GenericSkeletonProps) => {\n const styles = getStyles(animationDuration);\n\n return (\n <>\n <GlobalCSSVariables variables={cssVariables()} defaultColorMode={null} />\n <div className={styles} />\n </>\n );\n};\n","/**\n * Apply a filter to rotate the hue by 10 degrees per index\n */\nexport const filterHueRotate = (index: number) => ({\n filter: `hue-rotate(${index * 10}deg)`,\n});\n","import { css } from '@emotion/css';\nimport { getDesignTokens } from '@grafana/design-tokens';\nimport { StackedChartSegmentProps } from './types';\nimport { filterHueRotate } from '../StackedChart/shared.styles';\n\nexport const diagonalStripedBackground = ({\n stripeColor,\n stripeWidth = 2,\n gapWidth = 6,\n}: {\n stripeColor: string;\n stripeWidth?: number;\n gapWidth?: number;\n}) => {\n return `repeating-linear-gradient(\n -45deg,\n ${stripeColor},\n ${stripeColor} ${stripeWidth}px,\n transparent ${stripeWidth}px,\n transparent ${gapWidth}px)`;\n};\n\nexport const getSegmentStyles = () =>\n css({\n display: 'flex',\n height: '100%',\n });\n\nexport const getStyles = <T extends string>({\n index,\n state = 'default',\n}: Pick<StackedChartSegmentProps<T>, 'index' | 'state'>) => {\n const { legacy } = getDesignTokens({ valueType: 'css' });\n const hasColor = ['color', 'active'].includes(state);\n\n const backgroundImage = diagonalStripedBackground({\n stripeColor:\n state === 'dimmed' ? legacy.colors.secondary.shade : legacy.colors.secondary.transparent,\n });\n\n return css({\n cursor: hasColor ? 'pointer' : undefined,\n borderRadius: legacy.borderRadius.sm,\n transitionDuration: '0.2s',\n transitionTimingFunction: 'ease-in-out',\n transitionProperty: 'background, filter, box-shadow',\n background: hasColor ? legacy.colors.primary.main : legacy.colors.secondary.transparent,\n backgroundImage,\n opacity: state === 'dimmed' ? 0.4 : undefined,\n boxShadow: state === 'active' ? legacy.boxShadows.z1 : 'none',\n ...(hasColor ? filterHueRotate(index) : {}),\n });\n};\n","import clsx from 'clsx';\nimport React from 'react';\nimport { StackedChartSegmentProps } from './types';\nimport { getStyles, getSegmentStyles } from './StackedChartSegment.styles';\n\nconst _StackedChartSegment = <T extends string>(\n {\n categoryId,\n state = 'default',\n index,\n value,\n total = 100,\n minValue = 4,\n onMouseOver,\n onMouseOut,\n }: StackedChartSegmentProps<T>,\n ref: React.ForwardedRef<HTMLDivElement>,\n) => {\n const width = `${Math.max((value / total) * 100, minValue)}%`;\n\n return (\n <div\n ref={ref}\n className={clsx(getStyles({ state, index }), getSegmentStyles())}\n onMouseOver={onMouseOver && onMouseOver({ ref, categoryId })}\n onMouseOut={onMouseOut && onMouseOut({ ref, categoryId })}\n style={{ width }}\n />\n );\n};\n\n_StackedChartSegment.displayName = 'StackedChartSegment';\n\nexport const StackedChartSegment = React.forwardRef(_StackedChartSegment);\n","import { css } from '@emotion/css';\nimport { getDesignTokens } from '@grafana/design-tokens';\n\nexport const getStyles = ({ height }: { height: number }) => {\n const {\n primitives: { spacing },\n } = getDesignTokens({ valueType: 'css' });\n\n return {\n container: css({\n display: 'flex',\n width: '100%',\n height,\n gap: spacing.xxs,\n }),\n };\n};\n\nexport const diagonalStripedBackground = ({\n stripeColor,\n stripeWidth = 2,\n gapWidth = 6,\n}: {\n stripeColor: string;\n stripeWidth?: number;\n gapWidth?: number;\n}) => {\n return `repeating-linear-gradient(\n -45deg,\n ${stripeColor},\n ${stripeColor} ${stripeWidth}px,\n transparent ${stripeWidth}px,\n transparent ${gapWidth}px)`;\n};\n","import { css } from '@emotion/css';\nimport { getDesignTokens } from '@grafana/design-tokens';\nimport { filterHueRotate } from '../StackedChart/shared.styles';\n\nexport const getStyles = (index: number) => {\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 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.primary,\n borderRadius: legacy.borderRadius.md,\n padding: `${spacing.sm} ${spacing.md}`,\n }),\n title: css({\n fontFamily: typography.fontFamily.ui,\n fontSize: typography.fontSize.ui.sm,\n fontWeight: typography.fontWeight.medium,\n // TODO: this should come from a token!\n lineHeight: '16px',\n color: legacy.colors.text.primary,\n whiteSpace: 'nowrap',\n }),\n value: css({\n // TODO: this should come from a token!\n lineHeight: '16px',\n color: legacy.colors.text.secondary,\n }),\n color: css({\n color: legacy.colors.primary.main,\n fill: 'currentColor',\n ...filterHueRotate(index),\n }),\n };\n};\n","import { StackedChartSegmentProps } from '../StackedChartSegment/types';\nimport { Popover, PopoverProps } from '../Popover';\nimport { getStyles } from './StackedChartSegmentTooltip.styles';\n\nexport type StackedChartTooltipContentFormatter = (\n args: {\n colorClassName: string;\n } & Required<Pick<StackedChartSegmentProps<string>, 'value' | 'total' | 'index'>>,\n) => React.ReactElement;\n\nexport interface StackedChartSegmentTooltipProps<T extends string>\n extends Pick<StackedChartSegmentProps<T>, 'title' | 'value' | 'total' | 'index'>,\n Omit<PopoverProps, 'children'> {\n formatContent?: StackedChartTooltipContentFormatter;\n}\n\n/**\n * The default content formatter assumes a percentage value, but you can create\n * your own formatter using the provided arguments of total and index. The\n * colorClassName allows you to set the colour of some text or an icon to the\n * same colour as the equivalent chart segment.\n */\nconst defaultContentFormatter: StackedChartTooltipContentFormatter = ({\n value,\n colorClassName,\n}) => {\n const valueString = value < 0.1 ? '< 0.1' : `${value.toFixed(1)}`;\n\n return (\n <>\n <span className={colorClassName}>{valueString}%</span> of total usage\n </>\n );\n};\n\nexport const StackedChartSegmentTooltip = <T extends string>({\n trigger,\n placement = 'top',\n hideDelay,\n title,\n value,\n total = 100,\n index,\n formatContent = defaultContentFormatter,\n virtualElement,\n}: StackedChartSegmentTooltipProps<T>) => {\n const styles = getStyles(index);\n\n return (\n <Popover\n trigger={trigger}\n placement={placement}\n hideDelay={hideDelay}\n virtualElement={virtualElement}\n >\n <div className={styles.wrapper}>\n <div className={styles.content}>\n <div className={styles.section}>\n <div className={styles.title}>{title}</div>\n <div className={styles.value}>\n {formatContent({ value, total, index, colorClassName: styles.color })}\n </div>\n </div>\n </div>\n </div>\n </Popover>\n );\n};\n","import { css } from '@emotion/css';\n\nexport const getStyles = (height: number) => {\n return css({\n width: '100%',\n height: `${height}px`,\n borderRadius: '4px',\n overflow: 'hidden',\n });\n};\n","export const STACKED_CHART_DEFAULT_HEIGHT = 24;\n","import { getStyles } from './StackedChartSkeleton.styles';\nimport { GenericSkeleton } from '../GenericSkeleton';\nimport { STACKED_CHART_DEFAULT_HEIGHT } from '../StackedChart/common';\n\nexport interface StackedChartSkeletonProps {\n /**\n * Height to render the stacked chart skeleton, in pixels\n */\n height?: number;\n}\n\nexport const StackedChartSkeleton = ({\n height = STACKED_CHART_DEFAULT_HEIGHT,\n}: StackedChartSkeletonProps) => {\n const styles = getStyles(height);\n\n return (\n <div className={styles}>\n <GenericSkeleton />\n </div>\n );\n};\n","import { css } from '@emotion/css';\nimport { getDesignTokens, CSSVariables } from '@grafana/design-tokens';\n\nexport const cssVariables = (): CSSVariables => {\n const { legacy } = getDesignTokens({ valueType: 'css' });\n\n return {\n dark: {\n 'stacked-chart-no-data-background-color': legacy.palette.blackBaseOpacity15,\n },\n light: {\n 'stacked-chart-no-data-background-color': legacy.palette.blackBaseOpacity4,\n },\n };\n};\n\nexport const getStyles = (height: number) => {\n const {\n legacy,\n primitives: { typography, spacing },\n } = getDesignTokens({ valueType: 'css' });\n\n return {\n container: css({\n display: 'flex',\n flex: 1,\n width: '100%',\n height: `${height}px`,\n alignItems: 'center',\n justifyContent: 'center',\n gap: spacing.sm,\n borderRadius: legacy.borderRadius.md,\n color: legacy.colors.text.secondary,\n fontFamily: typography.fontFamily.ui,\n fontSize: typography.fontSize.ui.sm,\n paddingTop: spacing.xxs,\n background: 'var(--stacked-chart-no-data-background-color)',\n }),\n label: css({\n fontWeight: typography.fontWeight.medium,\n textTransform: 'lowercase',\n }),\n };\n};\n","import { GlobalCSSVariables } from '@grafana/design-tokens';\nimport { Icon } from '@grafana/ui';\nimport { cssVariables, getStyles } from './StackedChartNoData.styles';\nimport { STACKED_CHART_DEFAULT_HEIGHT } from '../StackedChart/common';\n\nexport type StackedChartNoDataMessageFormatter = (args: {\n period: string;\n className: string;\n}) => React.ReactElement;\n\nexport interface StackedChartNoDataProps {\n /**\n * Height to render the stacked chart skeleton, in pixels\n */\n height?: number;\n\n /**\n * Period for which this chart has no data, as a preformatted string\n */\n period?: string;\n\n /**\n * Optional formatter for content message\n */\n formatMessage?: StackedChartNoDataMessageFormatter;\n}\n\n/**\n * The default content formatter assumes a percentage value, but you can create\n * your own formatter using the provided arguments of total and index. The\n * colorClassName allows you to set the colour of some text or an icon to the\n * same colour as the equivalent chart segment.\n */\nconst defaultContentFormatter: StackedChartNoDataMessageFormatter = ({ period, className }) => (\n <>\n No data for <span className={className}>{period}</span>\n </>\n);\n\nexport const StackedChartNoData = ({\n height = STACKED_CHART_DEFAULT_HEIGHT,\n period = 'current',\n formatMessage = defaultContentFormatter,\n}: StackedChartNoDataProps) => {\n const styles = getStyles(height);\n\n return (\n <>\n <GlobalCSSVariables variables={cssVariables()} defaultColorMode={null} />\n <div className={styles.container}>\n <Icon name=\"exclamation-triangle\" size=\"sm\" />\n <span>{formatMessage({ period, className: styles.label })}</span>\n </div>\n </>\n );\n};\n","import { useRef, useState } from 'react';\nimport { StackedChartSegment } from '../StackedChartSegment';\nimport { getStyles } from './StackedChart.styles';\nimport { StackedChartSegmentState, SegmentMouseEventHandler } from '../StackedChartSegment/types';\nimport { StackedChartSegmentTooltip } from '../StackedChartSegmentTooltip';\nimport { StackedChartSkeleton } from '../StackedChartSkeleton';\nimport { StackedChartNoData, StackedChartNoDataProps } from '../StackedChartNoData';\nimport { STACKED_CHART_DEFAULT_HEIGHT } from './common';\n\nexport interface StackedChartCategory {\n title: string;\n value: number;\n}\n\nconst DUMMY_CATEGORY: StackedChartCategory = {\n title: 'Category',\n value: 0.01,\n};\n\nexport type StackedChartCategories<T extends string> = Partial<Record<T, StackedChartCategory>>;\n\nexport type StackedChartSortOrder = 'largest-first' | 'smallest-first' | 'natural';\n\ntype MouseEventHandler = ({\n categoryId,\n ref,\n}: {\n categoryId: string;\n ref: React.ForwardedRef<HTMLDivElement>;\n}) => void;\n\nexport interface StackedChartProps<T extends string> {\n /**\n * How should category segments be sorted?\n */\n sortOrder?: StackedChartSortOrder;\n\n /**\n * Height to render the stacked chart, in pixels\n */\n height?: number;\n\n /**\n * initial category ID to highlight; if omitted then all segments will render\n * in colour and highlight based on mouseover events.\n */\n highlightedCategoryId?: T;\n\n /**\n * Should the whole StackedChart be dimmed, i.e. with a highlighted category\n * not in color, all other categories faded out?\n */\n isDimmed?: boolean;\n\n /**\n * Event handler for whenever a segment gets a mouseover event\n */\n onSegmentMouseOver?: MouseEventHandler;\n\n /**\n * Event handler for whenever a segment gets a mouseout event\n */\n onSegmentMouseOut?: MouseEventHandler;\n\n /**\n * String representing the period for which the chart is displaying data\n */\n period?: string;\n\n formatNoDataMessage?: StackedChartNoDataProps['formatMessage'];\n\n /**\n * Is the StackedChart explicitly in a loading state?\n */\n isSkeleton?: boolean;\n\n /**\n * Array of StackedChartCategory to build the chart from\n */\n categories?: StackedChartCategories<T>;\n}\n\n/**\n * Custom hook to assign a ref per categoryId\n */\nconst useCategoryRefs = <T extends string>(\n categoryIds: T[],\n): Record<T, React.RefObject<HTMLDivElement>> => {\n const refsMap = useRef<Map<T, React.RefObject<HTMLDivElement>>>(new Map());\n\n for (const categoryId of categoryIds) {\n if (!refsMap.current.has(categoryId)) {\n refsMap.current.set(categoryId, { current: null });\n }\n }\n\n const result = {} as Record<T, React.RefObject<HTMLDivElement>>;\n for (const categoryId of categoryIds) {\n result[categoryId] = refsMap.current.get(categoryId)!;\n }\n\n return result;\n};\n\nexport const StackedChart = <T extends string>({\n categories,\n highlightedCategoryId: initialHighlightedCategoryId,\n isSkeleton = false,\n isDimmed = false,\n sortOrder = 'largest-first',\n height = STACKED_CHART_DEFAULT_HEIGHT,\n onSegmentMouseOver,\n onSegmentMouseOut,\n period = 'current',\n formatNoDataMessage,\n}: StackedChartProps<T>) => {\n const shouldRenderSkeleton = isSkeleton || !categories;\n let highlightedSegmentRef = useRef<HTMLDivElement>(null);\n const [highlightedCategoryId, setHighlightedCategoryId] = useState<string | undefined>(\n /**\n * Using a type assertion here ultimately because you can’t pass a generic\n * type argument to the type of props in React.forwardRef (it is inferred as\n * of type string).\n *\n * See: https://stackoverflow.com/questions/51884498/using-react-forwardref-with-typescript-generic-jsx-arguments\n */\n initialHighlightedCategoryId as string,\n );\n const [isHovered, setHovered] = useState<boolean>(false);\n const timer = useRef<number | undefined>(undefined);\n\n const sortedCategoryIds = (() => {\n let categoryIds: T[] = [];\n\n for (const categoryId in categories) {\n categoryIds.push(categoryId);\n }\n\n // return early since we may not even have any categories at this point\n if (shouldRenderSkeleton) return categoryIds;\n\n switch (sortOrder) {\n case 'largest-first':\n return categoryIds.sort(\n (a, b) => (categories[b]?.value ?? 0) - (categories[a]?.value ?? 0),\n );\n case 'smallest-first':\n return categoryIds.sort(\n (a, b) => (categories[a]?.value ?? 0) - (categories[b]?.value ?? 0),\n );\n default:\n return categoryIds;\n }\n })();\n\n const categoryRefs = useCategoryRefs(sortedCategoryIds);\n\n /**\n * Determine what the total value is for all category values combined\n */\n const total = shouldRenderSkeleton\n ? 0\n : Math.round(\n sortedCategoryIds.reduce((sum, categoryId) => {\n return sum + (categories[categoryId]?.value ?? 0);\n }, 0),\n );\n\n const styles = getStyles({ height });\n\n const onMouseOver: SegmentMouseEventHandler =\n ({ ref, categoryId }) =>\n () => {\n clearTimeout(timer.current);\n setHovered(true);\n\n /**\n * Only update the highlighted category ID if an initial category wasn’t\n * supplied\n */\n if (!initialHighlightedCategoryId) {\n setHighlightedCategoryId(categoryId);\n }\n\n if (onSegmentMouseOver) onSegmentMouseOver({ ref, categoryId });\n };\n\n const onMouseOut: SegmentMouseEventHandler =\n ({ ref, categoryId }) =>\n () => {\n /**\n * TODO: rather than use a timeout, maybe use the parent element being\n * moused over (event bubbling?) to validate whether the mouse has left\n * the entire chart vs an individual segment?\n */\n timer.current = window.setTimeout(() => {\n setHovered(false);\n /**\n * Only clear the highlighted category if an initial category wasn’t\n * supplied\n */\n if (!initialHighlightedCategoryId) {\n setHighlightedCategoryId(undefined);\n }\n }, 50);\n\n if (onSegmentMouseOut) onSegmentMouseOut({ ref, categoryId });\n };\n\n const highlightedCategory: (StackedChartCategory & { index: number }) | undefined =\n !shouldRenderSkeleton &&\n initialHighlightedCategoryId &&\n categories[initialHighlightedCategoryId]\n ? {\n ...categories[initialHighlightedCategoryId],\n index: sortedCategoryIds.indexOf(initialHighlightedCategoryId),\n }\n : undefined;\n\n const content = (\n <div className={styles.container}>\n {sortedCategoryIds.map((categoryId, index) => {\n /**\n * Some dummy category data is returned here for the scenario when\n * rendering a skeleton\n */\n const category =\n !shouldRenderSkeleton && categories?.[categoryId] !== undefined\n ? categories?.[categoryId]\n : DUMMY_CATEGORY;\n const ref = categoryRefs[categoryId];\n\n if (categoryId === initialHighlightedCategoryId && ref) highlightedSegmentRef = ref;\n\n const segmentState = ((): StackedChartSegmentState => {\n switch (true) {\n /**\n * If no initial highlighted category was set, and a category is\n * moused over, use the _active_ state for that category rather\n * than the color state; this adds a drop shadow to the segment.\n * Also, if an initial highlighted category _was_ set, and it\n * receives a hover event, also set it to active.\n */\n case !initialHighlightedCategoryId && highlightedCategoryId === categoryId && !isDimmed:\n case initialHighlightedCategoryId === categoryId && isHovered && !isDimmed:\n return 'active';\n\n /**\n * - no initial highlighted category ID was passed _and_ there is\n * no highlightedCategoryId (i.e. all segments in colour)\n * - the highlighted category is this category (but the chart\n * isn’t dimmed)\n * - the initial highlighted category is this category (but the\n * chart isn’t dimmed)\n */\n case !initialHighlightedCategoryId && !highlightedCategoryId && !isDimmed:\n case initialHighlightedCategoryId === categoryId && !isDimmed:\n return 'color';\n\n /**\n * Has an initial highlighted category, but is dimmed (i.e. all\n * segments excepted the highlighted category)\n */\n case Boolean(initialHighlightedCategoryId) &&\n initialHighlightedCategoryId !== categoryId &&\n isDimmed:\n case !initialHighlightedCategoryId && !highlightedCategoryId && isDimmed:\n case highlightedCategoryId !== categoryId && isDimmed:\n return 'dimmed';\n\n /**\n * In any other case, the segment should be the default grey\n */\n default:\n return 'default';\n }\n })();\n\n const segmentProps = {\n key: categoryId,\n index,\n ref,\n categoryId,\n title: category.title,\n value: category.value,\n total,\n state: segmentState,\n onMouseOver,\n onMouseOut,\n };\n\n /**\n * Only wrap the segment in a tooltip if no initially highlighted\n * category ID was supplied.\n */\n return initialHighlightedCategoryId ? (\n <StackedChartSegment {...segmentProps} />\n ) : (\n <StackedChartSegmentTooltip\n key={categoryId}\n title={category.title}\n value={category.value}\n index={index}\n hideDelay={0}\n trigger={<StackedChartSegment {...segmentProps} />}\n />\n );\n })}\n </div>\n );\n\n /**\n * If we should only render a skeleton, return early with that component\n */\n if (shouldRenderSkeleton) return <StackedChartSkeleton height={height} />;\n\n /**\n * If the initial highlighted category isn’t within the provided set of\n * categories, fall back to displaying the No Data component\n */\n if (\n initialHighlightedCategoryId &&\n sortedCategoryIds.indexOf(initialHighlightedCategoryId) === -1\n )\n return (\n <StackedChartNoData height={height} period={period} formatMessage={formatNoDataMessage} />\n );\n\n /**\n * If an initial highlight category was provided, wrap the entire chart inside\n * a tooltip using the props for the highlighted segment to drive the tooltip\n * content.\n */\n return initialHighlightedCategoryId && highlightedCategory ? (\n <StackedChartSegmentTooltip\n hideDelay={0}\n trigger={content}\n virtualElement={highlightedSegmentRef}\n {...highlightedCategory}\n />\n ) : (\n content\n );\n};\n"],"names":["createContext","useState","useEffect","jsx","useContext","ThemeChangedEvent","isLight","newColorMode","getStyles","getDesignTokens","css","flip","shift","offset","arrow","forwardRef","useRef","useId","useFloating","autoUpdate","useLayoutEffect","useInteractions","useDismiss","useHover","safePolygon","useFocus","useRole","useTransitionStyles","useCallback","jsxs","Fragment","cloneElement","FloatingPortal","FloatingArrow","Icon","cssVariables","cx","GlobalCSSVariables","keyframes","clsx","React","defaultContentFormatter"],"mappings":"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"}
1
+ {"version":3,"file":"index.cjs","sources":["../../src/components/ColorModeProvider/ColorModeProvider.tsx","../../src/hooks/useColorModeChange.ts","../../src/components/ColorModeChangeHandler/ColorModeChangeHandler.tsx","../../src/components/ColorMode/ColorMode.tsx","../../src/utils/formatters.ts","../../src/utils/comparison.ts","../../src/components/PortalProvider/PortalProvider.tsx","../../src/components/Popover/Popover.styles.ts","../../src/components/Popover/Popover.tsx","../../src/components/ComparisonTooltip/ComparisonTooltip.styles.ts","../../src/components/ComparisonTooltip/ComparisonTooltip.tsx","../../src/components/ComparisonBadge/ComparisonBadge.styles.ts","../../src/components/ComparisonBadge/ComparisonBadge.tsx","../../src/components/GenericSkeleton/GenericSkeleton.styles.ts","../../src/components/GenericSkeleton/GenericSkeleton.tsx","../../src/components/StackedChart/shared.styles.ts","../../src/components/StackedChartSegment/StackedChartSegment.styles.ts","../../src/components/StackedChartSegment/StackedChartSegment.tsx","../../src/components/StackedChart/StackedChart.styles.ts","../../src/components/StackedChartSegmentTooltip/StackedChartSegmentTooltip.styles.ts","../../src/components/StackedChartSegmentTooltip/StackedChartSegmentTooltip.tsx","../../src/components/StackedChartSkeleton/StackedChartSkeleton.styles.ts","../../src/components/StackedChart/common.ts","../../src/components/StackedChartSkeleton/StackedChartSkeleton.tsx","../../src/components/StackedChartNoData/StackedChartNoData.styles.ts","../../src/components/StackedChartNoData/StackedChartNoData.tsx","../../src/components/StackedChart/StackedChart.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 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","import { useEffect } from 'react';\nimport type { EventBus, GrafanaTheme2 } from '@grafana/data';\nimport { ThemeChangedEvent } from '@grafana/runtime';\nimport type { ThemeColorMode } from '@grafana/design-tokens';\nimport { useColorMode } from '../components/ColorModeProvider/ColorModeProvider';\n\nconst getThemeColorMode = (isLight: boolean): ThemeColorMode => {\n return isLight ? 'light' : 'dark';\n};\n\nexport interface ColorModeChangeProps {\n getAppEvents: () => EventBus;\n useTheme2: () => GrafanaTheme2;\n}\n\n/**\n * This allows us to register an event listener for when the ThemeChangedEvent\n * is fired, and update the currently active color mode accordingly. It will\n * also determine the color mode on initial registration, and update the context\n * provider accordingly.\n */\nexport const useColorModeChange = ({\n getAppEvents,\n useTheme2,\n}: ColorModeChangeProps): ThemeColorMode => {\n const { colorMode, setColorMode } = useColorMode();\n const appEvents = getAppEvents();\n\n /**\n * Longterm the current colorMode should ideally exist outside of useTheme2\n */\n const { isLight } = useTheme2();\n\n useEffect(() => {\n const themeChangedEvent = appEvents.subscribe<ThemeChangedEvent>(\n ThemeChangedEvent,\n ({ payload }) => {\n const newColorMode = getThemeColorMode(payload.isLight);\n setColorMode(newColorMode);\n },\n );\n\n return () => {\n themeChangedEvent.unsubscribe();\n };\n }, [appEvents, setColorMode]);\n\n // Sync color mode when theme changes (runs on mount and when isLight changes)\n useEffect(() => {\n const newColorMode = getThemeColorMode(isLight);\n setColorMode(newColorMode);\n }, [isLight, setColorMode]);\n\n return colorMode;\n};\n","import React from 'react';\nimport { useColorModeChange, ColorModeChangeProps } from '../../hooks';\n\nexport type ColorModeWrapper = React.FC<ColorModeChangeProps & { children: React.ReactNode }>;\n\nexport const ColorModeChangeHandler: ColorModeWrapper = ({ children, getAppEvents, useTheme2 }) => {\n useColorModeChange({ getAppEvents, useTheme2 });\n\n return children;\n};\n","import { ColorModeWrapper, ColorModeChangeHandler } from '../ColorModeChangeHandler';\nimport { ColorModeProvider } from '../ColorModeProvider';\n\nexport const ColorMode: ColorModeWrapper = ({ children, getAppEvents, useTheme2 }) => {\n return (\n <ColorModeProvider>\n <ColorModeChangeHandler getAppEvents={getAppEvents} useTheme2={useTheme2}>\n {children}\n </ColorModeChangeHandler>\n </ColorModeProvider>\n );\n};\n","/**\n * Number formatting options\n */\nexport interface FormatNumberOptions {\n /** Decimal places (default: 2) */\n decimals?: number;\n /** Threshold for compact formatting (default: 1000) */\n compactThreshold?: number;\n /** Never use compact formatting (for precise displays) */\n precise?: boolean;\n}\n\n/**\n * Format numbers with optional compact notation (k, m, b)\n * Components handle their own prefixes/suffixes ($ or %)\n *\n * @param value - The number to format (or 'loading' state)\n * @param options - Formatting options\n * @returns Formatted number string (no prefixes/suffixes)\n *\n * @example\n * formatNumber(1234) // \"1.2k\"\n * formatNumber(1234, { precise: true }) // \"1,234.00\"\n * formatNumber(1234, { decimals: 0 }) // \"1k\"\n * formatNumber(999) // \"999.00\"\n */\nexport const formatNumber = (\n value: number | string | 'loading',\n options: FormatNumberOptions = {},\n): string => {\n const { decimals = 2, compactThreshold = 1000, precise = false } = options;\n\n if (value === 'loading') {\n return '';\n }\n\n const num = typeof value === 'string' ? parseFloat(value) : value;\n if (isNaN(num)) {\n return 'N/A';\n }\n\n const abs = Math.abs(num);\n\n // Use compact notation if above threshold and not precise\n if (!precise && abs >= compactThreshold) {\n const sign = num < 0 ? '-' : '';\n const absNum = Math.abs(num);\n // Always use 1 decimal place for compact notation for consistency\n if (absNum >= 1000000000) {\n return `${sign}${(absNum / 1000000000).toFixed(1)}b`;\n } else if (absNum >= 1000000) {\n return `${sign}${(absNum / 1000000).toFixed(1)}m`;\n } else if (absNum >= 1000) {\n return `${sign}${(absNum / 1000).toFixed(1)}k`;\n }\n }\n\n // Standard formatting with specified decimal places\n return num.toLocaleString('en-US', {\n minimumFractionDigits: decimals,\n maximumFractionDigits: decimals,\n });\n};\n","/**\n * Shared utility functions for handling comparison calculations across components\n */\n\nimport { formatNumber } from './formatters';\n\nexport interface ComparisonResult {\n hasComparison: boolean;\n direction: 'up' | 'down' | 'neutral';\n percentageChange: number;\n percentageLabel: string;\n}\n\n/**\n * Calculate comparison metrics between a current value and a baseline value\n * @param current - The current value to compare\n * @param baseline - The baseline value to compare against (optional)\n * @returns ComparisonResult object with calculated metrics\n */\nexport const calculateComparison = (\n current: number | undefined | null,\n baseline: number | undefined | null,\n): ComparisonResult => {\n // If either value is missing, null, undefined, or baseline is 0, return neutral state\n if (\n current === undefined ||\n current === null ||\n baseline === undefined ||\n baseline === null ||\n baseline === 0\n ) {\n return {\n hasComparison: false,\n direction: 'neutral',\n percentageChange: 0,\n percentageLabel: '',\n };\n }\n\n // If values are equal, return neutral state\n if (current === baseline) {\n return {\n hasComparison: true,\n direction: 'neutral',\n percentageChange: 0,\n percentageLabel: '0%',\n };\n }\n\n // Calculate percentage change\n const percentageChange = Math.abs(((current - baseline) / baseline) * 100);\n const direction = current > baseline ? 'up' : 'down';\n\n return {\n hasComparison: true,\n direction,\n percentageChange,\n percentageLabel: `${formatNumber(percentageChange, {\n compactThreshold: 10000,\n decimals: 2,\n })}%`,\n };\n};\n","import React, { createContext, useContext, useState, ReactNode } from 'react';\nimport type { FloatingPortalProps } from '@floating-ui/react';\n\nexport type PortalRoot = FloatingPortalProps['root'];\n\nexport interface PortalContextType {\n root: PortalRoot;\n setRoot: (root: PortalRoot) => void;\n}\n\nexport interface PortalProviderProps {\n children: ReactNode;\n defaultRoot?: PortalRoot;\n}\n\nexport interface UsePortalOptions {\n /** If true, returns document.body instead of throwing when outside provider */\n allowOutsideProvider?: boolean;\n}\n\nconst PortalContext = createContext<PortalContextType | undefined>(undefined);\n\n/**\n * Provides a shared context for a portal root, which can be a selector string,\n * an HTMLElement, or null.\n *\n * Wrap your application (or a subtree) in this provider to enable\n * Popover, Tooltip, and other floating components to render correctly.\n *\n * @example\n * ```tsx\n * <PortalProvider defaultRoot={document.getElementById('grafana-portal-container')}>\n * <App />\n * </PortalProvider>\n * ```\n */\nexport const PortalProvider: React.FC<PortalProviderProps> = ({ children, defaultRoot = null }) => {\n const [root, setRoot] = useState<PortalRoot>(defaultRoot ?? document.body);\n\n return <PortalContext.Provider value={{ root, setRoot }}>{children}</PortalContext.Provider>;\n};\n\n/**\n * Use this hook to access the portal root context.\n */\nexport const usePortal = ({ allowOutsideProvider = false }: UsePortalOptions = {}) => {\n const context = useContext(PortalContext);\n\n if (context === undefined) {\n if (allowOutsideProvider) {\n return { root: document.body, setRoot: () => {} };\n }\n throw new Error('usePortal must be used within a PortalProvider');\n }\n\n return context;\n};\n","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 const backgroundColor = legacy.colors.background.secondary;\n\n return {\n arrow: css({\n fill: backgroundColor,\n }),\n shadow: css({\n filter: `drop-shadow(${legacy.boxShadows.z2})`,\n }),\n container: css({\n backgroundColor,\n borderRadius: `calc(${legacy.borderRadius.md} + ${spacing.xs})`,\n padding: spacing.xs,\n color: legacy.colors.text.primary,\n fontFamily: typography.fontFamily.ui,\n fontSize: typography.fontSize.ui.sm,\n }),\n };\n};\n","import {\n forwardRef,\n cloneElement,\n useCallback,\n useId,\n useRef,\n useState,\n useLayoutEffect,\n JSX,\n} from 'react';\nimport {\n arrow,\n autoUpdate,\n flip,\n FloatingArrow,\n offset,\n Placement,\n safePolygon,\n shift,\n useDismiss,\n useFloating,\n useFocus,\n useHover,\n useRole,\n useInteractions,\n useTransitionStyles,\n FloatingPortal,\n FloatingPortalProps,\n} from '@floating-ui/react';\nimport { usePortal } from '../PortalProvider';\nimport { getStyles } from './Popover.styles';\n\nexport interface PopoverProps {\n /**\n * Content used to trigger the Popover being displayed\n */\n trigger: JSX.Element;\n\n /**\n * Content to render within the Popover\n */\n children: JSX.Element;\n /**\n * Should the popover be open? Implicitly means the popover visibility is\n * controlled; if omitted, the popover target will control visibility\n */\n isOpen?: boolean;\n\n /**\n * Set to true if you want the tooltip to stay long enough so the user can\n * move mouse over content to select text or click a link\n */\n isInteractive?: boolean;\n\n /**\n * Placement of the Popover relative to the trigger content\n */\n placement?: Placement;\n\n /**\n * Transition duration for hide/show effects, in milliseconds\n */\n transitionDuration?: number;\n\n /**\n * Additional delay before hiding the popover after mouseout, in milliseconds\n */\n hideDelay?: number;\n\n /**\n * Virtual element to anchor the popover to instead of the trigger\n */\n virtualElement?: React.RefObject<Element>;\n\n /**\n * DOM element or ID to render the portal into, falls back to document.body\n */\n portalContainer?: FloatingPortalProps['root'];\n}\n\nconst POPOVER_OFFSET = 8;\n\nconst getMiddleware = ({\n placement,\n arrowRef,\n}: {\n placement?: Placement;\n arrowRef: React.RefObject<null>;\n}) => {\n const BOUNDARY_ELEMENT_ID = 'floating-boundary';\n const _flip = flip({\n // Ensure we flip to the perpendicular axis if it doesn't fit\n // on narrow viewports.\n crossAxis: 'alignment',\n fallbackAxisSideDirection: 'end',\n boundary: document.getElementById(BOUNDARY_ELEMENT_ID) ?? undefined,\n });\n\n const middleware = placement?.includes('-') ? [_flip, shift()] : [shift(), _flip];\n\n // the order of middleware is important!\n // `arrow` should almost always be at the end\n // see https://floating-ui.com/docs/arrow#order\n return [\n offset(POPOVER_OFFSET),\n ...middleware,\n arrow({\n element: arrowRef,\n }),\n ];\n};\n\nexport const Popover = forwardRef<HTMLElement, PopoverProps>(\n (\n {\n trigger,\n children,\n isOpen: isOpenControlled,\n isInteractive = false,\n placement = 'bottom',\n transitionDuration = 200,\n hideDelay = 500,\n virtualElement,\n portalContainer,\n },\n forwardedRef,\n ) => {\n const arrowRef = useRef(null);\n const closeTimer = useRef<number | undefined>(undefined);\n const popoverId = useId();\n const [isOpenState, setOpen] = useState(isOpenControlled);\n const [isDelayedOpen, setDelayedOpen] = useState(isOpenControlled);\n const isOpen = isOpenControlled ?? isOpenState;\n const middleware = getMiddleware({ placement, arrowRef });\n const styles = getStyles();\n const { root } = usePortal();\n\n const portalRoot = (() => {\n switch (true) {\n case portalContainer instanceof HTMLElement:\n return portalContainer;\n case typeof portalContainer === 'string':\n return document.getElementById(portalContainer);\n default:\n return root;\n }\n })();\n\n const { context, refs, floatingStyles } = useFloating({\n open: isOpen,\n placement,\n onOpenChange: (open) => {\n setOpen(open);\n clearTimeout(closeTimer.current);\n\n if (!open) {\n closeTimer.current = window.setTimeout(() => {\n setDelayedOpen(open);\n }, transitionDuration + hideDelay);\n } else {\n setDelayedOpen(open);\n }\n },\n middleware,\n whileElementsMounted: autoUpdate,\n });\n\n useLayoutEffect(() => {\n if (virtualElement && virtualElement.current !== null) {\n const domRect = virtualElement.current.getBoundingClientRect();\n\n refs.setPositionReference({\n getBoundingClientRect: () => {\n if (virtualElement.current !== null)\n return virtualElement.current.getBoundingClientRect();\n return domRect;\n },\n contextElement: virtualElement.current,\n });\n }\n }, [refs, virtualElement]);\n\n const { getReferenceProps, getFloatingProps } = useInteractions([\n useDismiss(context),\n useHover(context, {\n handleClose: isInteractive ? safePolygon() : undefined,\n move: false,\n delay: {\n open: 0,\n close: hideDelay,\n },\n }),\n useFocus(context),\n useRole(context),\n ]);\n\n const { styles: transitionStyles } = useTransitionStyles(context, {\n duration: transitionDuration,\n initial: ({ side }) => ({\n opacity: 0,\n transform:\n side === 'top' || side === 'bottom'\n ? `translateY(${POPOVER_OFFSET}px)`\n : `translateX(${POPOVER_OFFSET}px)`,\n }),\n open: ({ side }) => ({\n opacity: 1,\n transform: side === 'top' || side === 'bottom' ? `translateY(0)` : `translateX(0)`,\n }),\n close: ({ side }) => ({\n opacity: 0,\n transform:\n side === 'top' || side === 'bottom'\n ? `translateY(${POPOVER_OFFSET}px)`\n : `translateX(${POPOVER_OFFSET}px)`,\n }),\n });\n\n const handleRef = useCallback(\n (ref: HTMLElement | null) => {\n refs.setReference(ref);\n\n if (typeof forwardedRef === 'function') {\n forwardedRef(ref);\n } else if (forwardedRef) {\n forwardedRef.current = ref;\n }\n },\n [forwardedRef, refs],\n );\n\n return (\n <>\n {/* element to trigger displaying the popover */}\n {cloneElement(trigger, {\n ref: handleRef,\n tabIndex: 0,\n 'aria-describedby': isOpen ? popoverId : undefined,\n ...getReferenceProps(),\n })}\n {/* content to render inside the popover when open */}\n {(isDelayedOpen || isOpen) && (\n <FloatingPortal root={portalRoot}>\n <div ref={refs.setFloating} style={floatingStyles} {...getFloatingProps()}>\n <div style={transitionStyles} className={styles.shadow}>\n <FloatingArrow className={styles.arrow} ref={arrowRef} context={context} />\n <div id={popoverId} role=\"tooltip\" className={styles.container}>\n {children}\n </div>\n </div>\n </div>\n </FloatingPortal>\n )}\n </>\n );\n },\n);\n\nPopover.displayName = 'Popover';\n","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 const background = legacy.colors.background.primary;\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,\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,\n borderRadius: legacy.borderRadius.md,\n padding: `${spacing.sm} ${spacing.md}`,\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","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","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 whiteSpace: 'nowrap',\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","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 hideDelay?: number;\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 hideDelay,\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 hideDelay={hideDelay}\n />\n ) : (\n badgeContent\n )}\n </>\n );\n};\n","import { css, keyframes } 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 'skeleton-gradient-background-color': legacy.palette.whiteBaseOpacity12,\n },\n light: {\n 'skeleton-gradient-background-color': legacy.palette.blackBaseOpacity12,\n },\n };\n};\n\nconst shimmer = keyframes({\n '0%': {\n transform: 'translateX(-100%);',\n },\n '100%': {\n transform: 'translateX(100%);',\n },\n});\n\nexport const getStyles = (animationDuration: number) => {\n return css({\n display: 'flex',\n width: '100%',\n height: '100%',\n background: 'transparent',\n position: 'relative',\n overflow: 'hidden',\n borderRadius: '5px',\n '&::before': {\n content: \"''\",\n position: 'absolute',\n top: 0,\n left: 0,\n width: '100%',\n height: '100%',\n animation: `${shimmer} ${animationDuration}s ease-in-out infinite`,\n transform: 'translateX(-100%)',\n background:\n 'linear-gradient(90deg, transparent, var(--skeleton-gradient-background-color), transparent)',\n },\n });\n};\n","import { GlobalCSSVariables } from '@grafana/design-tokens';\nimport { cssVariables, getStyles } from './GenericSkeleton.styles';\n\nexport interface GenericSkeletonProps {\n /**\n * Duration of animation in seconds\n */\n animationDuration?: number;\n}\n\nexport const GenericSkeleton = ({ animationDuration = 2 }: GenericSkeletonProps) => {\n const styles = getStyles(animationDuration);\n\n return (\n <>\n <GlobalCSSVariables variables={cssVariables()} defaultColorMode={null} />\n <div className={styles} />\n </>\n );\n};\n","/**\n * Apply a filter to rotate the hue by 10 degrees per index\n */\nexport const filterHueRotate = (index: number) => ({\n filter: `hue-rotate(${index * 10}deg)`,\n});\n","import { css } from '@emotion/css';\nimport { getDesignTokens } from '@grafana/design-tokens';\nimport { StackedChartSegmentProps } from './types';\nimport { filterHueRotate } from '../StackedChart/shared.styles';\n\nexport const diagonalStripedBackground = ({\n stripeColor,\n stripeWidth = 2,\n gapWidth = 6,\n}: {\n stripeColor: string;\n stripeWidth?: number;\n gapWidth?: number;\n}) => {\n return `repeating-linear-gradient(\n -45deg,\n ${stripeColor},\n ${stripeColor} ${stripeWidth}px,\n transparent ${stripeWidth}px,\n transparent ${gapWidth}px)`;\n};\n\nexport const getSegmentStyles = () =>\n css({\n display: 'flex',\n height: '100%',\n });\n\nexport const getStyles = <T extends string>({\n index,\n state = 'default',\n}: Pick<StackedChartSegmentProps<T>, 'index' | 'state'>) => {\n const { legacy } = getDesignTokens({ valueType: 'css' });\n const hasColor = ['color', 'active'].includes(state);\n\n const backgroundImage = diagonalStripedBackground({\n stripeColor:\n state === 'dimmed' ? legacy.colors.secondary.shade : legacy.colors.secondary.transparent,\n });\n\n return css({\n cursor: hasColor ? 'pointer' : undefined,\n borderRadius: legacy.borderRadius.sm,\n transitionDuration: '0.2s',\n transitionTimingFunction: 'ease-in-out',\n transitionProperty: 'background, filter, box-shadow',\n background: hasColor ? legacy.colors.primary.main : legacy.colors.secondary.transparent,\n backgroundImage,\n opacity: state === 'dimmed' ? 0.4 : undefined,\n boxShadow: state === 'active' ? legacy.boxShadows.z1 : 'none',\n ...(hasColor ? filterHueRotate(index) : {}),\n });\n};\n","import clsx from 'clsx';\nimport React from 'react';\nimport { StackedChartSegmentProps } from './types';\nimport { getStyles, getSegmentStyles } from './StackedChartSegment.styles';\n\nconst _StackedChartSegment = <T extends string>(\n {\n categoryId,\n state = 'default',\n index,\n value,\n total = 100,\n minValue = 4,\n onMouseOver,\n onMouseOut,\n }: StackedChartSegmentProps<T>,\n ref: React.ForwardedRef<HTMLDivElement>,\n) => {\n const width = `${Math.max((value / total) * 100, minValue)}%`;\n\n return (\n <div\n ref={ref}\n className={clsx(getStyles({ state, index }), getSegmentStyles())}\n onMouseOver={onMouseOver && onMouseOver({ ref, categoryId })}\n onMouseOut={onMouseOut && onMouseOut({ ref, categoryId })}\n style={{ width }}\n />\n );\n};\n\n_StackedChartSegment.displayName = 'StackedChartSegment';\n\nexport const StackedChartSegment = React.forwardRef(_StackedChartSegment);\n","import { css } from '@emotion/css';\nimport { getDesignTokens } from '@grafana/design-tokens';\n\nexport const getStyles = ({ height }: { height: number }) => {\n const {\n primitives: { spacing },\n } = getDesignTokens({ valueType: 'css' });\n\n return {\n container: css({\n display: 'flex',\n width: '100%',\n height,\n gap: spacing.xxs,\n }),\n };\n};\n\nexport const diagonalStripedBackground = ({\n stripeColor,\n stripeWidth = 2,\n gapWidth = 6,\n}: {\n stripeColor: string;\n stripeWidth?: number;\n gapWidth?: number;\n}) => {\n return `repeating-linear-gradient(\n -45deg,\n ${stripeColor},\n ${stripeColor} ${stripeWidth}px,\n transparent ${stripeWidth}px,\n transparent ${gapWidth}px)`;\n};\n","import { css } from '@emotion/css';\nimport { getDesignTokens } from '@grafana/design-tokens';\nimport { filterHueRotate } from '../StackedChart/shared.styles';\n\nexport const getStyles = (index: number) => {\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 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.primary,\n borderRadius: legacy.borderRadius.md,\n padding: `${spacing.sm} ${spacing.md}`,\n }),\n title: css({\n fontFamily: typography.fontFamily.ui,\n fontSize: typography.fontSize.ui.sm,\n fontWeight: typography.fontWeight.medium,\n // TODO: this should come from a token!\n lineHeight: '16px',\n color: legacy.colors.text.primary,\n whiteSpace: 'nowrap',\n }),\n value: css({\n // TODO: this should come from a token!\n lineHeight: '16px',\n color: legacy.colors.text.secondary,\n }),\n color: css({\n color: legacy.colors.primary.main,\n fill: 'currentColor',\n ...filterHueRotate(index),\n }),\n };\n};\n","import { StackedChartSegmentProps } from '../StackedChartSegment/types';\nimport { Popover, PopoverProps } from '../Popover';\nimport { getStyles } from './StackedChartSegmentTooltip.styles';\n\nexport type StackedChartTooltipContentFormatter = (\n args: {\n colorClassName: string;\n } & Required<Pick<StackedChartSegmentProps<string>, 'value' | 'total' | 'index'>>,\n) => React.ReactElement;\n\nexport interface StackedChartSegmentTooltipProps<T extends string>\n extends Pick<StackedChartSegmentProps<T>, 'title' | 'value' | 'total' | 'index'>,\n Omit<PopoverProps, 'children'> {\n formatContent?: StackedChartTooltipContentFormatter;\n}\n\n/**\n * The default content formatter assumes a percentage value, but you can create\n * your own formatter using the provided arguments of total and index. The\n * colorClassName allows you to set the colour of some text or an icon to the\n * same colour as the equivalent chart segment.\n */\nconst defaultContentFormatter: StackedChartTooltipContentFormatter = ({\n value,\n colorClassName,\n}) => {\n const valueString = value < 0.1 ? '< 0.1' : `${value.toFixed(1)}`;\n\n return (\n <>\n <span className={colorClassName}>{valueString}%</span> of total usage\n </>\n );\n};\n\nexport const StackedChartSegmentTooltip = <T extends string>({\n trigger,\n placement = 'top',\n hideDelay,\n title,\n value,\n total = 100,\n index,\n formatContent = defaultContentFormatter,\n virtualElement,\n}: StackedChartSegmentTooltipProps<T>) => {\n const styles = getStyles(index);\n\n return (\n <Popover\n trigger={trigger}\n placement={placement}\n hideDelay={hideDelay}\n virtualElement={virtualElement}\n >\n <div className={styles.wrapper}>\n <div className={styles.content}>\n <div className={styles.section}>\n <div className={styles.title}>{title}</div>\n <div className={styles.value}>\n {formatContent({ value, total, index, colorClassName: styles.color })}\n </div>\n </div>\n </div>\n </div>\n </Popover>\n );\n};\n","import { css } from '@emotion/css';\n\nexport const getStyles = (height: number) => {\n return css({\n width: '100%',\n height: `${height}px`,\n borderRadius: '4px',\n overflow: 'hidden',\n });\n};\n","export const STACKED_CHART_DEFAULT_HEIGHT = 24;\n","import { getStyles } from './StackedChartSkeleton.styles';\nimport { GenericSkeleton } from '../GenericSkeleton';\nimport { STACKED_CHART_DEFAULT_HEIGHT } from '../StackedChart/common';\n\nexport interface StackedChartSkeletonProps {\n /**\n * Height to render the stacked chart skeleton, in pixels\n */\n height?: number;\n}\n\nexport const StackedChartSkeleton = ({\n height = STACKED_CHART_DEFAULT_HEIGHT,\n}: StackedChartSkeletonProps) => {\n const styles = getStyles(height);\n\n return (\n <div className={styles}>\n <GenericSkeleton />\n </div>\n );\n};\n","import { css } from '@emotion/css';\nimport { getDesignTokens, CSSVariables } from '@grafana/design-tokens';\n\nexport const cssVariables = (): CSSVariables => {\n const { legacy } = getDesignTokens({ valueType: 'css' });\n\n return {\n dark: {\n 'stacked-chart-no-data-background-color': legacy.palette.blackBaseOpacity15,\n },\n light: {\n 'stacked-chart-no-data-background-color': legacy.palette.blackBaseOpacity4,\n },\n };\n};\n\nexport const getStyles = (height: number) => {\n const {\n legacy,\n primitives: { typography, spacing },\n } = getDesignTokens({ valueType: 'css' });\n\n return {\n container: css({\n display: 'flex',\n flex: 1,\n width: '100%',\n height: `${height}px`,\n alignItems: 'center',\n justifyContent: 'center',\n gap: spacing.sm,\n borderRadius: legacy.borderRadius.md,\n color: legacy.colors.text.secondary,\n fontFamily: typography.fontFamily.ui,\n fontSize: typography.fontSize.ui.sm,\n paddingTop: spacing.xxs,\n background: 'var(--stacked-chart-no-data-background-color)',\n }),\n label: css({\n fontWeight: typography.fontWeight.medium,\n textTransform: 'lowercase',\n }),\n };\n};\n","import { GlobalCSSVariables } from '@grafana/design-tokens';\nimport { Icon } from '@grafana/ui';\nimport { cssVariables, getStyles } from './StackedChartNoData.styles';\nimport { STACKED_CHART_DEFAULT_HEIGHT } from '../StackedChart/common';\n\nexport type StackedChartNoDataMessageFormatter = (args: {\n period: string;\n className: string;\n}) => React.ReactElement;\n\nexport interface StackedChartNoDataProps {\n /**\n * Height to render the stacked chart skeleton, in pixels\n */\n height?: number;\n\n /**\n * Period for which this chart has no data, as a preformatted string\n */\n period?: string;\n\n /**\n * Optional formatter for content message\n */\n formatMessage?: StackedChartNoDataMessageFormatter;\n}\n\n/**\n * The default content formatter assumes a percentage value, but you can create\n * your own formatter using the provided arguments of total and index. The\n * colorClassName allows you to set the colour of some text or an icon to the\n * same colour as the equivalent chart segment.\n */\nconst defaultContentFormatter: StackedChartNoDataMessageFormatter = ({ period, className }) => (\n <>\n No data for <span className={className}>{period}</span>\n </>\n);\n\nexport const StackedChartNoData = ({\n height = STACKED_CHART_DEFAULT_HEIGHT,\n period = 'current',\n formatMessage = defaultContentFormatter,\n}: StackedChartNoDataProps) => {\n const styles = getStyles(height);\n\n return (\n <>\n <GlobalCSSVariables variables={cssVariables()} defaultColorMode={null} />\n <div className={styles.container}>\n <Icon name=\"exclamation-triangle\" size=\"sm\" />\n <span>{formatMessage({ period, className: styles.label })}</span>\n </div>\n </>\n );\n};\n","import { useRef, useState } from 'react';\nimport { StackedChartSegment } from '../StackedChartSegment';\nimport { getStyles } from './StackedChart.styles';\nimport { StackedChartSegmentState, SegmentMouseEventHandler } from '../StackedChartSegment/types';\nimport { StackedChartSegmentTooltip } from '../StackedChartSegmentTooltip';\nimport { StackedChartSkeleton } from '../StackedChartSkeleton';\nimport { StackedChartNoData, StackedChartNoDataProps } from '../StackedChartNoData';\nimport { STACKED_CHART_DEFAULT_HEIGHT } from './common';\n\nexport interface StackedChartCategory {\n title: string;\n value: number;\n}\n\nconst DUMMY_CATEGORY: StackedChartCategory = {\n title: 'Category',\n value: 0.01,\n};\n\nexport type StackedChartCategories<T extends string> = Partial<Record<T, StackedChartCategory>>;\n\nexport type StackedChartSortOrder = 'largest-first' | 'smallest-first' | 'natural';\n\n/**\n * Callback function invoked when a mouse event occurs on a chart segment.\n *\n * This is a simplified callback (not a React event handler) that receives\n * segment metadata. It's called after the internal event handling is complete.\n *\n * @param args - Object containing segment metadata\n * @param args.categoryId - The unique identifier of the segment that triggered the event\n * @param args.ref - React ref to the segment's DOM element, useful for positioning tooltips or popovers\n *\n * @example\n * ```tsx\n * <StackedChart\n * categories={categories}\n * onSegmentMouseOver={({ categoryId, ref }) => {\n * console.log(`Hovered segment: ${categoryId}`);\n * // ref.current gives you the DOM element if needed\n * }}\n * onSegmentMouseOut={({ categoryId }) => {\n * console.log(`Left segment: ${categoryId}`);\n * }}\n * />\n * ```\n */\ntype MouseEventHandler = ({\n categoryId,\n ref,\n}: {\n categoryId: string;\n ref: React.ForwardedRef<HTMLDivElement>;\n}) => void;\n\nexport interface StackedChartProps<T extends string> {\n /**\n * How should category segments be sorted?\n */\n sortOrder?: StackedChartSortOrder;\n\n /**\n * Height to render the stacked chart, in pixels\n */\n height?: number;\n\n /**\n * initial category ID to highlight; if omitted then all segments will render\n * in colour and highlight based on mouseover events.\n */\n highlightedCategoryId?: T;\n\n /**\n * Should the whole StackedChart be dimmed, i.e. with a highlighted category\n * not in color, all other categories faded out?\n */\n isDimmed?: boolean;\n\n /**\n * Callback invoked when the mouse enters a chart segment.\n *\n * Receives the segment's `categoryId` and a `ref` to its DOM element.\n * Use this to implement custom hover behavior, analytics tracking,\n * or coordination with external UI elements.\n *\n * @example\n * ```tsx\n * onSegmentMouseOver={({ categoryId, ref }) => {\n * setActiveCategory(categoryId);\n * // Optional: use ref.current for DOM measurements\n * }}\n * ```\n */\n onSegmentMouseOver?: MouseEventHandler;\n\n /**\n * Callback invoked when the mouse leaves a chart segment.\n *\n * Receives the segment's `categoryId` and a `ref` to its DOM element.\n * Use this to clean up hover state or hide related UI elements.\n *\n * @example\n * ```tsx\n * onSegmentMouseOut={({ categoryId }) => {\n * setActiveCategory(null);\n * }}\n * ```\n */\n onSegmentMouseOut?: MouseEventHandler;\n\n /**\n * String representing the period for which the chart is displaying data\n */\n period?: string;\n\n formatNoDataMessage?: StackedChartNoDataProps['formatMessage'];\n\n /**\n * Is the StackedChart explicitly in a loading state?\n */\n isSkeleton?: boolean;\n\n /**\n * Array of StackedChartCategory to build the chart from\n */\n categories?: StackedChartCategories<T>;\n}\n\n/**\n * Custom hook to assign a ref per categoryId\n */\nconst useCategoryRefs = <T extends string>(\n categoryIds: T[],\n): Record<T, React.RefObject<HTMLDivElement>> => {\n const refsMap = useRef<Map<T, React.RefObject<HTMLDivElement>>>(new Map());\n\n for (const categoryId of categoryIds) {\n if (!refsMap.current.has(categoryId)) {\n refsMap.current.set(categoryId, { current: null });\n }\n }\n\n const result = {} as Record<T, React.RefObject<HTMLDivElement>>;\n for (const categoryId of categoryIds) {\n result[categoryId] = refsMap.current.get(categoryId)!;\n }\n\n return result;\n};\n\nexport const StackedChart = <T extends string>({\n categories,\n highlightedCategoryId: initialHighlightedCategoryId,\n isSkeleton = false,\n isDimmed = false,\n sortOrder = 'largest-first',\n height = STACKED_CHART_DEFAULT_HEIGHT,\n onSegmentMouseOver,\n onSegmentMouseOut,\n period = 'current',\n formatNoDataMessage,\n}: StackedChartProps<T>) => {\n const shouldRenderSkeleton = isSkeleton || !categories;\n let highlightedSegmentRef = useRef<HTMLDivElement>(null);\n const [highlightedCategoryId, setHighlightedCategoryId] = useState<string | undefined>(\n /**\n * Using a type assertion here ultimately because you can’t pass a generic\n * type argument to the type of props in React.forwardRef (it is inferred as\n * of type string).\n *\n * See: https://stackoverflow.com/questions/51884498/using-react-forwardref-with-typescript-generic-jsx-arguments\n */\n initialHighlightedCategoryId as string,\n );\n const [isHovered, setHovered] = useState<boolean>(false);\n const timer = useRef<number | undefined>(undefined);\n\n const sortedCategoryIds = (() => {\n let categoryIds: T[] = [];\n\n for (const categoryId in categories) {\n categoryIds.push(categoryId);\n }\n\n // return early since we may not even have any categories at this point\n if (shouldRenderSkeleton) return categoryIds;\n\n switch (sortOrder) {\n case 'largest-first':\n return categoryIds.sort(\n (a, b) => (categories[b]?.value ?? 0) - (categories[a]?.value ?? 0),\n );\n case 'smallest-first':\n return categoryIds.sort(\n (a, b) => (categories[a]?.value ?? 0) - (categories[b]?.value ?? 0),\n );\n default:\n return categoryIds;\n }\n })();\n\n const categoryRefs = useCategoryRefs(sortedCategoryIds);\n\n /**\n * Determine what the total value is for all category values combined\n */\n const total = shouldRenderSkeleton\n ? 0\n : Math.round(\n sortedCategoryIds.reduce((sum, categoryId) => {\n return sum + (categories[categoryId]?.value ?? 0);\n }, 0),\n );\n\n const styles = getStyles({ height });\n\n const onMouseOver: SegmentMouseEventHandler =\n ({ ref, categoryId }) =>\n () => {\n clearTimeout(timer.current);\n setHovered(true);\n\n /**\n * Only update the highlighted category ID if an initial category wasn’t\n * supplied\n */\n if (!initialHighlightedCategoryId) {\n setHighlightedCategoryId(categoryId);\n }\n\n if (onSegmentMouseOver) onSegmentMouseOver({ ref, categoryId });\n };\n\n const onMouseOut: SegmentMouseEventHandler =\n ({ ref, categoryId }) =>\n () => {\n /**\n * TODO: rather than use a timeout, maybe use the parent element being\n * moused over (event bubbling?) to validate whether the mouse has left\n * the entire chart vs an individual segment?\n */\n timer.current = window.setTimeout(() => {\n setHovered(false);\n /**\n * Only clear the highlighted category if an initial category wasn’t\n * supplied\n */\n if (!initialHighlightedCategoryId) {\n setHighlightedCategoryId(undefined);\n }\n }, 50);\n\n if (onSegmentMouseOut) onSegmentMouseOut({ ref, categoryId });\n };\n\n const highlightedCategory: (StackedChartCategory & { index: number }) | undefined =\n !shouldRenderSkeleton &&\n initialHighlightedCategoryId &&\n categories[initialHighlightedCategoryId]\n ? {\n ...categories[initialHighlightedCategoryId],\n index: sortedCategoryIds.indexOf(initialHighlightedCategoryId),\n }\n : undefined;\n\n const content = (\n <div className={styles.container}>\n {sortedCategoryIds.map((categoryId, index) => {\n /**\n * Some dummy category data is returned here for the scenario when\n * rendering a skeleton\n */\n const category =\n !shouldRenderSkeleton && categories?.[categoryId] !== undefined\n ? categories?.[categoryId]\n : DUMMY_CATEGORY;\n const ref = categoryRefs[categoryId];\n\n if (categoryId === initialHighlightedCategoryId && ref) highlightedSegmentRef = ref;\n\n const segmentState = ((): StackedChartSegmentState => {\n switch (true) {\n /**\n * If no initial highlighted category was set, and a category is\n * moused over, use the _active_ state for that category rather\n * than the color state; this adds a drop shadow to the segment.\n * Also, if an initial highlighted category _was_ set, and it\n * receives a hover event, also set it to active.\n */\n case !initialHighlightedCategoryId && highlightedCategoryId === categoryId && !isDimmed:\n case initialHighlightedCategoryId === categoryId && isHovered && !isDimmed:\n return 'active';\n\n /**\n * - no initial highlighted category ID was passed _and_ there is\n * no highlightedCategoryId (i.e. all segments in colour)\n * - the highlighted category is this category (but the chart\n * isn’t dimmed)\n * - the initial highlighted category is this category (but the\n * chart isn’t dimmed)\n */\n case !initialHighlightedCategoryId && !highlightedCategoryId && !isDimmed:\n case initialHighlightedCategoryId === categoryId && !isDimmed:\n return 'color';\n\n /**\n * Has an initial highlighted category, but is dimmed (i.e. all\n * segments excepted the highlighted category)\n */\n case Boolean(initialHighlightedCategoryId) &&\n initialHighlightedCategoryId !== categoryId &&\n isDimmed:\n case !initialHighlightedCategoryId && !highlightedCategoryId && isDimmed:\n case highlightedCategoryId !== categoryId && isDimmed:\n return 'dimmed';\n\n /**\n * In any other case, the segment should be the default grey\n */\n default:\n return 'default';\n }\n })();\n\n const segmentProps = {\n key: categoryId,\n index,\n ref,\n categoryId,\n title: category.title,\n value: category.value,\n total,\n state: segmentState,\n onMouseOver,\n onMouseOut,\n };\n\n /**\n * Only wrap the segment in a tooltip if no initially highlighted\n * category ID was supplied.\n */\n return initialHighlightedCategoryId ? (\n <StackedChartSegment {...segmentProps} />\n ) : (\n <StackedChartSegmentTooltip\n key={categoryId}\n title={category.title}\n value={category.value}\n index={index}\n hideDelay={0}\n trigger={<StackedChartSegment {...segmentProps} />}\n />\n );\n })}\n </div>\n );\n\n /**\n * If we should only render a skeleton, return early with that component\n */\n if (shouldRenderSkeleton) return <StackedChartSkeleton height={height} />;\n\n /**\n * If the initial highlighted category isn’t within the provided set of\n * categories, fall back to displaying the No Data component\n */\n if (\n initialHighlightedCategoryId &&\n sortedCategoryIds.indexOf(initialHighlightedCategoryId) === -1\n )\n return (\n <StackedChartNoData height={height} period={period} formatMessage={formatNoDataMessage} />\n );\n\n /**\n * If an initial highlight category was provided, wrap the entire chart inside\n * a tooltip using the props for the highlighted segment to drive the tooltip\n * content.\n */\n return initialHighlightedCategoryId && highlightedCategory ? (\n <StackedChartSegmentTooltip\n hideDelay={0}\n trigger={content}\n virtualElement={highlightedSegmentRef}\n {...highlightedCategory}\n />\n ) : (\n content\n );\n};\n"],"names":["createContext","useState","useEffect","jsx","useContext","ThemeChangedEvent","getStyles","getDesignTokens","css","flip","shift","offset","arrow","forwardRef","useRef","useId","useFloating","autoUpdate","useLayoutEffect","useInteractions","useDismiss","useHover","safePolygon","useFocus","useRole","useTransitionStyles","useCallback","jsxs","Fragment","cloneElement","FloatingPortal","FloatingArrow","Icon","cssVariables","cx","GlobalCSSVariables","keyframes","clsx","React","defaultContentFormatter"],"mappings":"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"}
@@ -130,15 +130,29 @@ interface PortalProviderProps {
130
130
  children: ReactNode;
131
131
  defaultRoot?: PortalRoot;
132
132
  }
133
+ interface UsePortalOptions {
134
+ /** If true, returns document.body instead of throwing when outside provider */
135
+ allowOutsideProvider?: boolean;
136
+ }
133
137
  /**
134
138
  * Provides a shared context for a portal root, which can be a selector string,
135
139
  * an HTMLElement, or null.
140
+ *
141
+ * Wrap your application (or a subtree) in this provider to enable
142
+ * Popover, Tooltip, and other floating components to render correctly.
143
+ *
144
+ * @example
145
+ * ```tsx
146
+ * <PortalProvider defaultRoot={document.getElementById('grafana-portal-container')}>
147
+ * <App />
148
+ * </PortalProvider>
149
+ * ```
136
150
  */
137
151
  declare const PortalProvider: React__default.FC<PortalProviderProps>;
138
152
  /**
139
153
  * Use this hook to access the portal root context.
140
154
  */
141
- declare const usePortal: () => PortalContextType;
155
+ declare const usePortal: ({ allowOutsideProvider }?: UsePortalOptions) => PortalContextType;
142
156
 
143
157
  type StackedChartNoDataMessageFormatter = (args: {
144
158
  period: string;
@@ -166,6 +180,30 @@ interface StackedChartCategory {
166
180
  }
167
181
  type StackedChartCategories<T extends string> = Partial<Record<T, StackedChartCategory>>;
168
182
  type StackedChartSortOrder = 'largest-first' | 'smallest-first' | 'natural';
183
+ /**
184
+ * Callback function invoked when a mouse event occurs on a chart segment.
185
+ *
186
+ * This is a simplified callback (not a React event handler) that receives
187
+ * segment metadata. It's called after the internal event handling is complete.
188
+ *
189
+ * @param args - Object containing segment metadata
190
+ * @param args.categoryId - The unique identifier of the segment that triggered the event
191
+ * @param args.ref - React ref to the segment's DOM element, useful for positioning tooltips or popovers
192
+ *
193
+ * @example
194
+ * ```tsx
195
+ * <StackedChart
196
+ * categories={categories}
197
+ * onSegmentMouseOver={({ categoryId, ref }) => {
198
+ * console.log(`Hovered segment: ${categoryId}`);
199
+ * // ref.current gives you the DOM element if needed
200
+ * }}
201
+ * onSegmentMouseOut={({ categoryId }) => {
202
+ * console.log(`Left segment: ${categoryId}`);
203
+ * }}
204
+ * />
205
+ * ```
206
+ */
169
207
  type MouseEventHandler = ({ categoryId, ref, }: {
170
208
  categoryId: string;
171
209
  ref: React.ForwardedRef<HTMLDivElement>;
@@ -190,11 +228,33 @@ interface StackedChartProps<T extends string> {
190
228
  */
191
229
  isDimmed?: boolean;
192
230
  /**
193
- * Event handler for whenever a segment gets a mouseover event
231
+ * Callback invoked when the mouse enters a chart segment.
232
+ *
233
+ * Receives the segment's `categoryId` and a `ref` to its DOM element.
234
+ * Use this to implement custom hover behavior, analytics tracking,
235
+ * or coordination with external UI elements.
236
+ *
237
+ * @example
238
+ * ```tsx
239
+ * onSegmentMouseOver={({ categoryId, ref }) => {
240
+ * setActiveCategory(categoryId);
241
+ * // Optional: use ref.current for DOM measurements
242
+ * }}
243
+ * ```
194
244
  */
195
245
  onSegmentMouseOver?: MouseEventHandler;
196
246
  /**
197
- * Event handler for whenever a segment gets a mouseout event
247
+ * Callback invoked when the mouse leaves a chart segment.
248
+ *
249
+ * Receives the segment's `categoryId` and a `ref` to its DOM element.
250
+ * Use this to clean up hover state or hide related UI elements.
251
+ *
252
+ * @example
253
+ * ```tsx
254
+ * onSegmentMouseOut={({ categoryId }) => {
255
+ * setActiveCategory(null);
256
+ * }}
257
+ * ```
198
258
  */
199
259
  onSegmentMouseOut?: MouseEventHandler;
200
260
  /**
@@ -334,4 +394,4 @@ interface FormatNumberOptions {
334
394
  declare const formatNumber: (value: number | string | "loading", options?: FormatNumberOptions) => string;
335
395
 
336
396
  export { ColorMode, ColorModeChangeHandler, ColorModeProvider, ComparisonBadge, ComparisonTooltip, GenericSkeleton, Popover, PortalProvider, StackedChart, StackedChartNoData, StackedChartSegment, StackedChartSegmentTooltip, StackedChartSkeleton, calculateComparison, formatNumber, useColorMode, useColorModeChange, usePortal };
337
- export type { ColorModeChangeProps, ColorModeContextType, ColorModeProviderProps, ColorModeWrapper, ComparisonResult, ComparisonTooltipProps, FormatNumberOptions, GenericSkeletonProps, PopoverProps, PortalContextType, PortalProviderProps, PortalRoot, StackedChartCategories, StackedChartCategory, StackedChartNoDataMessageFormatter, StackedChartNoDataProps, StackedChartProps, StackedChartSegmentTooltipProps, StackedChartSkeletonProps, StackedChartSortOrder, StackedChartTooltipContentFormatter };
397
+ export type { ColorModeChangeProps, ColorModeContextType, ColorModeProviderProps, ColorModeWrapper, ComparisonResult, ComparisonTooltipProps, FormatNumberOptions, GenericSkeletonProps, PopoverProps, PortalContextType, PortalProviderProps, PortalRoot, SegmentMouseEventHandler, StackedChartCategories, StackedChartCategory, StackedChartNoDataMessageFormatter, StackedChartNoDataProps, StackedChartProps, StackedChartSegmentProps, StackedChartSegmentState, StackedChartSegmentTooltipProps, StackedChartSkeletonProps, StackedChartSortOrder, StackedChartTooltipContentFormatter, UsePortalOptions };
@@ -11,7 +11,6 @@ const ColorModeProvider = ({
11
11
  }) => {
12
12
  const [colorMode, setColorMode] = useState(defaultColorMode);
13
13
  useEffect(() => {
14
- console.log("ColorModeProvider", { colorMode });
15
14
  document.documentElement.setAttribute("data-color-mode", colorMode);
16
15
  }, [colorMode]);
17
16
  return /* @__PURE__ */ jsx(ColorModeContext.Provider, { value: { colorMode, setColorMode }, children });
@@ -1 +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;;;;"}
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 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,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;;;;"}
@@ -47,8 +47,8 @@ const Popover = forwardRef(
47
47
  const isOpen = isOpenControlled != null ? isOpenControlled : isOpenState;
48
48
  const middleware = getMiddleware({ placement, arrowRef });
49
49
  const styles = getStyles();
50
+ const { root } = usePortal();
50
51
  const portalRoot = (() => {
51
- const { root } = usePortal();
52
52
  switch (true) {
53
53
  case portalContainer instanceof HTMLElement:
54
54
  return portalContainer;
@@ -1 +1 @@
1
- {"version":3,"file":"Popover.js","sources":["../../../../src/components/Popover/Popover.tsx"],"sourcesContent":["import {\n forwardRef,\n cloneElement,\n useCallback,\n useId,\n useRef,\n useState,\n useLayoutEffect,\n JSX,\n} from 'react';\nimport {\n arrow,\n autoUpdate,\n flip,\n FloatingArrow,\n offset,\n Placement,\n safePolygon,\n shift,\n useDismiss,\n useFloating,\n useFocus,\n useHover,\n useRole,\n useInteractions,\n useTransitionStyles,\n FloatingPortal,\n FloatingPortalProps,\n} from '@floating-ui/react';\nimport { usePortal } from '../PortalProvider';\nimport { getStyles } from './Popover.styles';\n\nexport interface PopoverProps {\n /**\n * Content used to trigger the Popover being displayed\n */\n trigger: JSX.Element;\n\n /**\n * Content to render within the Popover\n */\n children: JSX.Element;\n /**\n * Should the popover be open? Implicitly means the popover visibility is\n * controlled; if omitted, the popover target will control visibility\n */\n isOpen?: boolean;\n\n /**\n * Set to true if you want the tooltip to stay long enough so the user can\n * move mouse over content to select text or click a link\n */\n isInteractive?: boolean;\n\n /**\n * Placement of the Popover relative to the trigger content\n */\n placement?: Placement;\n\n /**\n * Transition duration for hide/show effects, in milliseconds\n */\n transitionDuration?: number;\n\n /**\n * Additional delay before hiding the popover after mouseout, in milliseconds\n */\n hideDelay?: number;\n\n /**\n * Virtual element to anchor the popover to instead of the trigger\n */\n virtualElement?: React.RefObject<Element>;\n\n /**\n * DOM element or ID to render the portal into, falls back to document.body\n */\n portalContainer?: FloatingPortalProps['root'];\n}\n\nconst POPOVER_OFFSET = 8;\n\nconst getMiddleware = ({\n placement,\n arrowRef,\n}: {\n placement?: Placement;\n arrowRef: React.RefObject<null>;\n}) => {\n const BOUNDARY_ELEMENT_ID = 'floating-boundary';\n const _flip = flip({\n // Ensure we flip to the perpendicular axis if it doesn't fit\n // on narrow viewports.\n crossAxis: 'alignment',\n fallbackAxisSideDirection: 'end',\n boundary: document.getElementById(BOUNDARY_ELEMENT_ID) ?? undefined,\n });\n\n const middleware = placement?.includes('-') ? [_flip, shift()] : [shift(), _flip];\n\n // the order of middleware is important!\n // `arrow` should almost always be at the end\n // see https://floating-ui.com/docs/arrow#order\n return [\n offset(POPOVER_OFFSET),\n ...middleware,\n arrow({\n element: arrowRef,\n }),\n ];\n};\n\nexport const Popover = forwardRef<HTMLElement, PopoverProps>(\n (\n {\n trigger,\n children,\n isOpen: isOpenControlled,\n isInteractive = false,\n placement = 'bottom',\n transitionDuration = 200,\n hideDelay = 500,\n virtualElement,\n portalContainer,\n },\n forwardedRef,\n ) => {\n const arrowRef = useRef(null);\n const closeTimer = useRef<number | undefined>(undefined);\n const popoverId = useId();\n const [isOpenState, setOpen] = useState(isOpenControlled);\n const [isDelayedOpen, setDelayedOpen] = useState(isOpenControlled);\n const isOpen = isOpenControlled ?? isOpenState;\n const middleware = getMiddleware({ placement, arrowRef });\n const styles = getStyles();\n const portalRoot = (() => {\n const { root } = usePortal();\n\n switch (true) {\n case portalContainer instanceof HTMLElement:\n return portalContainer;\n case typeof portalContainer === 'string':\n return document.getElementById(portalContainer);\n default:\n return root;\n }\n })();\n\n const { context, refs, floatingStyles } = useFloating({\n open: isOpen,\n placement,\n onOpenChange: (open) => {\n setOpen(open);\n clearTimeout(closeTimer.current);\n\n if (!open) {\n closeTimer.current = window.setTimeout(() => {\n setDelayedOpen(open);\n }, transitionDuration + hideDelay);\n } else {\n setDelayedOpen(open);\n }\n },\n middleware,\n whileElementsMounted: autoUpdate,\n });\n\n useLayoutEffect(() => {\n if (virtualElement && virtualElement.current !== null) {\n const domRect = virtualElement.current.getBoundingClientRect();\n\n refs.setPositionReference({\n getBoundingClientRect: () => {\n if (virtualElement.current !== null)\n return virtualElement.current.getBoundingClientRect();\n return domRect;\n },\n contextElement: virtualElement.current,\n });\n }\n }, [refs, virtualElement]);\n\n const { getReferenceProps, getFloatingProps } = useInteractions([\n useDismiss(context),\n useHover(context, {\n handleClose: isInteractive ? safePolygon() : undefined,\n move: false,\n delay: {\n open: 0,\n close: hideDelay,\n },\n }),\n useFocus(context),\n useRole(context),\n ]);\n\n const { styles: transitionStyles } = useTransitionStyles(context, {\n duration: transitionDuration,\n initial: ({ side }) => ({\n opacity: 0,\n transform:\n side === 'top' || side === 'bottom'\n ? `translateY(${POPOVER_OFFSET}px)`\n : `translateX(${POPOVER_OFFSET}px)`,\n }),\n open: ({ side }) => ({\n opacity: 1,\n transform: side === 'top' || side === 'bottom' ? `translateY(0)` : `translateX(0)`,\n }),\n close: ({ side }) => ({\n opacity: 0,\n transform:\n side === 'top' || side === 'bottom'\n ? `translateY(${POPOVER_OFFSET}px)`\n : `translateX(${POPOVER_OFFSET}px)`,\n }),\n });\n\n const handleRef = useCallback(\n (ref: HTMLElement | null) => {\n refs.setReference(ref);\n\n if (typeof forwardedRef === 'function') {\n forwardedRef(ref);\n } else if (forwardedRef) {\n forwardedRef.current = ref;\n }\n },\n [forwardedRef, refs],\n );\n\n return (\n <>\n {/* element to trigger displaying the popover */}\n {cloneElement(trigger, {\n ref: handleRef,\n tabIndex: 0,\n 'aria-describedby': isOpen ? popoverId : undefined,\n ...getReferenceProps(),\n })}\n {/* content to render inside the popover when open */}\n {(isDelayedOpen || isOpen) && (\n <FloatingPortal root={portalRoot}>\n <div ref={refs.setFloating} style={floatingStyles} {...getFloatingProps()}>\n <div style={transitionStyles} className={styles.shadow}>\n <FloatingArrow className={styles.arrow} ref={arrowRef} context={context} />\n <div id={popoverId} role=\"tooltip\" className={styles.container}>\n {children}\n </div>\n </div>\n </div>\n </FloatingPortal>\n )}\n </>\n );\n },\n);\n\nPopover.displayName = 'Popover';\n"],"names":[],"mappings":";;;;;;AAgFA,MAAM,cAAA,GAAiB,CAAA;AAEvB,MAAM,gBAAgB,CAAC;AAAA,EACrB,SAAA;AAAA,EACA;AACF,CAAA,KAGM;AAxFN,EAAA,IAAA,EAAA;AAyFE,EAAA,MAAM,mBAAA,GAAsB,mBAAA;AAC5B,EAAA,MAAM,QAAQ,IAAA,CAAK;AAAA;AAAA;AAAA,IAGjB,SAAA,EAAW,WAAA;AAAA,IACX,yBAAA,EAA2B,KAAA;AAAA,IAC3B,QAAA,EAAA,CAAU,EAAA,GAAA,QAAA,CAAS,cAAA,CAAe,mBAAmB,MAA3C,IAAA,GAAA,EAAA,GAAgD;AAAA,GAC3D,CAAA;AAED,EAAA,MAAM,UAAA,GAAA,CAAa,SAAA,IAAA,IAAA,GAAA,MAAA,GAAA,SAAA,CAAW,QAAA,CAAS,GAAA,CAAA,IAAO,CAAC,KAAA,EAAO,KAAA,EAAO,CAAA,GAAI,CAAC,KAAA,EAAM,EAAG,KAAK,CAAA;AAKhF,EAAA,OAAO;AAAA,IACL,OAAO,cAAc,CAAA;AAAA,IACrB,GAAG,UAAA;AAAA,IACH,KAAA,CAAM;AAAA,MACJ,OAAA,EAAS;AAAA,KACV;AAAA,GACH;AACF,CAAA;AAEO,MAAM,OAAA,GAAU,UAAA;AAAA,EACrB,CACE;AAAA,IACE,OAAA;AAAA,IACA,QAAA;AAAA,IACA,MAAA,EAAQ,gBAAA;AAAA,IACR,aAAA,GAAgB,KAAA;AAAA,IAChB,SAAA,GAAY,QAAA;AAAA,IACZ,kBAAA,GAAqB,GAAA;AAAA,IACrB,SAAA,GAAY,GAAA;AAAA,IACZ,cAAA;AAAA,IACA;AAAA,KAEF,YAAA,KACG;AACH,IAAA,MAAM,QAAA,GAAW,OAAO,IAAI,CAAA;AAC5B,IAAA,MAAM,UAAA,GAAa,OAA2B,MAAS,CAAA;AACvD,IAAA,MAAM,YAAY,KAAA,EAAM;AACxB,IAAA,MAAM,CAAC,WAAA,EAAa,OAAO,CAAA,GAAI,SAAS,gBAAgB,CAAA;AACxD,IAAA,MAAM,CAAC,aAAA,EAAe,cAAc,CAAA,GAAI,SAAS,gBAAgB,CAAA;AACjE,IAAA,MAAM,SAAS,gBAAA,IAAA,IAAA,GAAA,gBAAA,GAAoB,WAAA;AACnC,IAAA,MAAM,UAAA,GAAa,aAAA,CAAc,EAAE,SAAA,EAAW,UAAU,CAAA;AACxD,IAAA,MAAM,SAAS,SAAA,EAAU;AACzB,IAAA,MAAM,cAAc,MAAM;AACxB,MAAA,MAAM,EAAE,IAAA,EAAK,GAAI,SAAA,EAAU;AAE3B,MAAA,QAAQ,IAAA;AAAM,QACZ,KAAK,eAAA,YAA2B,WAAA;AAC9B,UAAA,OAAO,eAAA;AAAA,QACT,KAAK,OAAO,eAAA,KAAoB,QAAA;AAC9B,UAAA,OAAO,QAAA,CAAS,eAAe,eAAe,CAAA;AAAA,QAChD;AACE,UAAA,OAAO,IAAA;AAAA;AACX,IACF,CAAA,GAAG;AAEH,IAAA,MAAM,EAAE,OAAA,EAAS,IAAA,EAAM,cAAA,KAAmB,WAAA,CAAY;AAAA,MACpD,IAAA,EAAM,MAAA;AAAA,MACN,SAAA;AAAA,MACA,YAAA,EAAc,CAAC,IAAA,KAAS;AACtB,QAAA,OAAA,CAAQ,IAAI,CAAA;AACZ,QAAA,YAAA,CAAa,WAAW,OAAO,CAAA;AAE/B,QAAA,IAAI,CAAC,IAAA,EAAM;AACT,UAAA,UAAA,CAAW,OAAA,GAAU,MAAA,CAAO,UAAA,CAAW,MAAM;AAC3C,YAAA,cAAA,CAAe,IAAI,CAAA;AAAA,UACrB,CAAA,EAAG,qBAAqB,SAAS,CAAA;AAAA,QACnC,CAAA,MAAO;AACL,UAAA,cAAA,CAAe,IAAI,CAAA;AAAA,QACrB;AAAA,MACF,CAAA;AAAA,MACA,UAAA;AAAA,MACA,oBAAA,EAAsB;AAAA,KACvB,CAAA;AAED,IAAA,eAAA,CAAgB,MAAM;AACpB,MAAA,IAAI,cAAA,IAAkB,cAAA,CAAe,OAAA,KAAY,IAAA,EAAM;AACrD,QAAA,MAAM,OAAA,GAAU,cAAA,CAAe,OAAA,CAAQ,qBAAA,EAAsB;AAE7D,QAAA,IAAA,CAAK,oBAAA,CAAqB;AAAA,UACxB,uBAAuB,MAAM;AAC3B,YAAA,IAAI,eAAe,OAAA,KAAY,IAAA;AAC7B,cAAA,OAAO,cAAA,CAAe,QAAQ,qBAAA,EAAsB;AACtD,YAAA,OAAO,OAAA;AAAA,UACT,CAAA;AAAA,UACA,gBAAgB,cAAA,CAAe;AAAA,SAChC,CAAA;AAAA,MACH;AAAA,IACF,CAAA,EAAG,CAAC,IAAA,EAAM,cAAc,CAAC,CAAA;AAEzB,IAAA,MAAM,EAAE,iBAAA,EAAmB,gBAAA,EAAiB,GAAI,eAAA,CAAgB;AAAA,MAC9D,WAAW,OAAO,CAAA;AAAA,MAClB,SAAS,OAAA,EAAS;AAAA,QAChB,WAAA,EAAa,aAAA,GAAgB,WAAA,EAAY,GAAI,MAAA;AAAA,QAC7C,IAAA,EAAM,KAAA;AAAA,QACN,KAAA,EAAO;AAAA,UACL,IAAA,EAAM,CAAA;AAAA,UACN,KAAA,EAAO;AAAA;AACT,OACD,CAAA;AAAA,MACD,SAAS,OAAO,CAAA;AAAA,MAChB,QAAQ,OAAO;AAAA,KAChB,CAAA;AAED,IAAA,MAAM,EAAE,MAAA,EAAQ,gBAAA,EAAiB,GAAI,oBAAoB,OAAA,EAAS;AAAA,MAChE,QAAA,EAAU,kBAAA;AAAA,MACV,OAAA,EAAS,CAAC,EAAE,IAAA,EAAK,MAAO;AAAA,QACtB,OAAA,EAAS,CAAA;AAAA,QACT,SAAA,EACE,SAAS,KAAA,IAAS,IAAA,KAAS,WACvB,CAAA,WAAA,EAAc,cAAc,CAAA,GAAA,CAAA,GAC5B,CAAA,WAAA,EAAc,cAAc,CAAA,GAAA;AAAA,OACpC,CAAA;AAAA,MACA,IAAA,EAAM,CAAC,EAAE,IAAA,EAAK,MAAO;AAAA,QACnB,OAAA,EAAS,CAAA;AAAA,QACT,SAAA,EAAW,IAAA,KAAS,KAAA,IAAS,IAAA,KAAS,WAAW,CAAA,aAAA,CAAA,GAAkB,CAAA,aAAA;AAAA,OACrE,CAAA;AAAA,MACA,KAAA,EAAO,CAAC,EAAE,IAAA,EAAK,MAAO;AAAA,QACpB,OAAA,EAAS,CAAA;AAAA,QACT,SAAA,EACE,SAAS,KAAA,IAAS,IAAA,KAAS,WACvB,CAAA,WAAA,EAAc,cAAc,CAAA,GAAA,CAAA,GAC5B,CAAA,WAAA,EAAc,cAAc,CAAA,GAAA;AAAA,OACpC;AAAA,KACD,CAAA;AAED,IAAA,MAAM,SAAA,GAAY,WAAA;AAAA,MAChB,CAAC,GAAA,KAA4B;AAC3B,QAAA,IAAA,CAAK,aAAa,GAAG,CAAA;AAErB,QAAA,IAAI,OAAO,iBAAiB,UAAA,EAAY;AACtC,UAAA,YAAA,CAAa,GAAG,CAAA;AAAA,QAClB,WAAW,YAAA,EAAc;AACvB,UAAA,YAAA,CAAa,OAAA,GAAU,GAAA;AAAA,QACzB;AAAA,MACF,CAAA;AAAA,MACA,CAAC,cAAc,IAAI;AAAA,KACrB;AAEA,IAAA,uBACE,IAAA,CAAA,QAAA,EAAA,EAEG,QAAA,EAAA;AAAA,MAAA,YAAA,CAAa,OAAA,EAAS;AAAA,QACrB,GAAA,EAAK,SAAA;AAAA,QACL,QAAA,EAAU,CAAA;AAAA,QACV,kBAAA,EAAoB,SAAS,SAAA,GAAY,MAAA;AAAA,QACzC,GAAG,iBAAA;AAAkB,OACtB,CAAA;AAAA,MAAA,CAEC,aAAA,IAAiB,2BACjB,GAAA,CAAC,cAAA,EAAA,EAAe,MAAM,UAAA,EACpB,QAAA,kBAAA,GAAA,CAAC,KAAA,EAAA,EAAI,GAAA,EAAK,IAAA,CAAK,WAAA,EAAa,OAAO,cAAA,EAAiB,GAAG,kBAAiB,EACtE,QAAA,kBAAA,IAAA,CAAC,SAAI,KAAA,EAAO,gBAAA,EAAkB,SAAA,EAAW,MAAA,CAAO,MAAA,EAC9C,QAAA,EAAA;AAAA,wBAAA,GAAA,CAAC,iBAAc,SAAA,EAAW,MAAA,CAAO,KAAA,EAAO,GAAA,EAAK,UAAU,OAAA,EAAkB,CAAA;AAAA,wBACzE,GAAA,CAAC,SAAI,EAAA,EAAI,SAAA,EAAW,MAAK,SAAA,EAAU,SAAA,EAAW,MAAA,CAAO,SAAA,EAClD,QAAA,EACH;AAAA,OAAA,EACF,GACF,CAAA,EACF;AAAA,KAAA,EAEJ,CAAA;AAAA,EAEJ;AACF;AAEA,OAAA,CAAQ,WAAA,GAAc,SAAA;;;;"}
1
+ {"version":3,"file":"Popover.js","sources":["../../../../src/components/Popover/Popover.tsx"],"sourcesContent":["import {\n forwardRef,\n cloneElement,\n useCallback,\n useId,\n useRef,\n useState,\n useLayoutEffect,\n JSX,\n} from 'react';\nimport {\n arrow,\n autoUpdate,\n flip,\n FloatingArrow,\n offset,\n Placement,\n safePolygon,\n shift,\n useDismiss,\n useFloating,\n useFocus,\n useHover,\n useRole,\n useInteractions,\n useTransitionStyles,\n FloatingPortal,\n FloatingPortalProps,\n} from '@floating-ui/react';\nimport { usePortal } from '../PortalProvider';\nimport { getStyles } from './Popover.styles';\n\nexport interface PopoverProps {\n /**\n * Content used to trigger the Popover being displayed\n */\n trigger: JSX.Element;\n\n /**\n * Content to render within the Popover\n */\n children: JSX.Element;\n /**\n * Should the popover be open? Implicitly means the popover visibility is\n * controlled; if omitted, the popover target will control visibility\n */\n isOpen?: boolean;\n\n /**\n * Set to true if you want the tooltip to stay long enough so the user can\n * move mouse over content to select text or click a link\n */\n isInteractive?: boolean;\n\n /**\n * Placement of the Popover relative to the trigger content\n */\n placement?: Placement;\n\n /**\n * Transition duration for hide/show effects, in milliseconds\n */\n transitionDuration?: number;\n\n /**\n * Additional delay before hiding the popover after mouseout, in milliseconds\n */\n hideDelay?: number;\n\n /**\n * Virtual element to anchor the popover to instead of the trigger\n */\n virtualElement?: React.RefObject<Element>;\n\n /**\n * DOM element or ID to render the portal into, falls back to document.body\n */\n portalContainer?: FloatingPortalProps['root'];\n}\n\nconst POPOVER_OFFSET = 8;\n\nconst getMiddleware = ({\n placement,\n arrowRef,\n}: {\n placement?: Placement;\n arrowRef: React.RefObject<null>;\n}) => {\n const BOUNDARY_ELEMENT_ID = 'floating-boundary';\n const _flip = flip({\n // Ensure we flip to the perpendicular axis if it doesn't fit\n // on narrow viewports.\n crossAxis: 'alignment',\n fallbackAxisSideDirection: 'end',\n boundary: document.getElementById(BOUNDARY_ELEMENT_ID) ?? undefined,\n });\n\n const middleware = placement?.includes('-') ? [_flip, shift()] : [shift(), _flip];\n\n // the order of middleware is important!\n // `arrow` should almost always be at the end\n // see https://floating-ui.com/docs/arrow#order\n return [\n offset(POPOVER_OFFSET),\n ...middleware,\n arrow({\n element: arrowRef,\n }),\n ];\n};\n\nexport const Popover = forwardRef<HTMLElement, PopoverProps>(\n (\n {\n trigger,\n children,\n isOpen: isOpenControlled,\n isInteractive = false,\n placement = 'bottom',\n transitionDuration = 200,\n hideDelay = 500,\n virtualElement,\n portalContainer,\n },\n forwardedRef,\n ) => {\n const arrowRef = useRef(null);\n const closeTimer = useRef<number | undefined>(undefined);\n const popoverId = useId();\n const [isOpenState, setOpen] = useState(isOpenControlled);\n const [isDelayedOpen, setDelayedOpen] = useState(isOpenControlled);\n const isOpen = isOpenControlled ?? isOpenState;\n const middleware = getMiddleware({ placement, arrowRef });\n const styles = getStyles();\n const { root } = usePortal();\n\n const portalRoot = (() => {\n switch (true) {\n case portalContainer instanceof HTMLElement:\n return portalContainer;\n case typeof portalContainer === 'string':\n return document.getElementById(portalContainer);\n default:\n return root;\n }\n })();\n\n const { context, refs, floatingStyles } = useFloating({\n open: isOpen,\n placement,\n onOpenChange: (open) => {\n setOpen(open);\n clearTimeout(closeTimer.current);\n\n if (!open) {\n closeTimer.current = window.setTimeout(() => {\n setDelayedOpen(open);\n }, transitionDuration + hideDelay);\n } else {\n setDelayedOpen(open);\n }\n },\n middleware,\n whileElementsMounted: autoUpdate,\n });\n\n useLayoutEffect(() => {\n if (virtualElement && virtualElement.current !== null) {\n const domRect = virtualElement.current.getBoundingClientRect();\n\n refs.setPositionReference({\n getBoundingClientRect: () => {\n if (virtualElement.current !== null)\n return virtualElement.current.getBoundingClientRect();\n return domRect;\n },\n contextElement: virtualElement.current,\n });\n }\n }, [refs, virtualElement]);\n\n const { getReferenceProps, getFloatingProps } = useInteractions([\n useDismiss(context),\n useHover(context, {\n handleClose: isInteractive ? safePolygon() : undefined,\n move: false,\n delay: {\n open: 0,\n close: hideDelay,\n },\n }),\n useFocus(context),\n useRole(context),\n ]);\n\n const { styles: transitionStyles } = useTransitionStyles(context, {\n duration: transitionDuration,\n initial: ({ side }) => ({\n opacity: 0,\n transform:\n side === 'top' || side === 'bottom'\n ? `translateY(${POPOVER_OFFSET}px)`\n : `translateX(${POPOVER_OFFSET}px)`,\n }),\n open: ({ side }) => ({\n opacity: 1,\n transform: side === 'top' || side === 'bottom' ? `translateY(0)` : `translateX(0)`,\n }),\n close: ({ side }) => ({\n opacity: 0,\n transform:\n side === 'top' || side === 'bottom'\n ? `translateY(${POPOVER_OFFSET}px)`\n : `translateX(${POPOVER_OFFSET}px)`,\n }),\n });\n\n const handleRef = useCallback(\n (ref: HTMLElement | null) => {\n refs.setReference(ref);\n\n if (typeof forwardedRef === 'function') {\n forwardedRef(ref);\n } else if (forwardedRef) {\n forwardedRef.current = ref;\n }\n },\n [forwardedRef, refs],\n );\n\n return (\n <>\n {/* element to trigger displaying the popover */}\n {cloneElement(trigger, {\n ref: handleRef,\n tabIndex: 0,\n 'aria-describedby': isOpen ? popoverId : undefined,\n ...getReferenceProps(),\n })}\n {/* content to render inside the popover when open */}\n {(isDelayedOpen || isOpen) && (\n <FloatingPortal root={portalRoot}>\n <div ref={refs.setFloating} style={floatingStyles} {...getFloatingProps()}>\n <div style={transitionStyles} className={styles.shadow}>\n <FloatingArrow className={styles.arrow} ref={arrowRef} context={context} />\n <div id={popoverId} role=\"tooltip\" className={styles.container}>\n {children}\n </div>\n </div>\n </div>\n </FloatingPortal>\n )}\n </>\n );\n },\n);\n\nPopover.displayName = 'Popover';\n"],"names":[],"mappings":"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"}
@@ -2,24 +2,17 @@ import { jsx } from 'react/jsx-runtime';
2
2
  import { createContext, useContext, useState } from 'react';
3
3
 
4
4
  const PortalContext = createContext(void 0);
5
- const PortalProvider = ({
6
- children,
7
- defaultRoot: _root = null
8
- }) => {
9
- const defaultRoot = (() => {
10
- switch (true) {
11
- case Boolean(_root):
12
- return _root;
13
- default:
14
- return document.body;
15
- }
16
- })();
17
- const [root, setRoot] = useState(defaultRoot);
5
+ const PortalProvider = ({ children, defaultRoot = null }) => {
6
+ const [root, setRoot] = useState(defaultRoot != null ? defaultRoot : document.body);
18
7
  return /* @__PURE__ */ jsx(PortalContext.Provider, { value: { root, setRoot }, children });
19
8
  };
20
- const usePortal = () => {
9
+ const usePortal = ({ allowOutsideProvider = false } = {}) => {
21
10
  const context = useContext(PortalContext);
22
11
  if (context === void 0) {
12
+ if (allowOutsideProvider) {
13
+ return { root: document.body, setRoot: () => {
14
+ } };
15
+ }
23
16
  throw new Error("usePortal must be used within a PortalProvider");
24
17
  }
25
18
  return context;
@@ -1 +1 @@
1
- {"version":3,"file":"PortalProvider.js","sources":["../../../../src/components/PortalProvider/PortalProvider.tsx"],"sourcesContent":["import React, { createContext, useContext, useState, ReactNode } from 'react';\nimport type { FloatingPortalProps } from '@floating-ui/react';\n\nexport type PortalRoot = FloatingPortalProps['root'];\n\nexport interface PortalContextType {\n root: PortalRoot;\n setRoot: (root: PortalRoot) => void;\n}\n\nexport interface PortalProviderProps {\n children: ReactNode;\n defaultRoot?: PortalRoot;\n}\n\nconst PortalContext = createContext<PortalContextType | undefined>(undefined);\n\n/**\n * Provides a shared context for a portal root, which can be a selector string,\n * an HTMLElement, or null.\n */\nexport const PortalProvider: React.FC<PortalProviderProps> = ({\n children,\n defaultRoot: _root = null,\n}) => {\n const defaultRoot = (() => {\n switch (true) {\n case Boolean(_root):\n return _root;\n default:\n return document.body;\n }\n })();\n\n const [root, setRoot] = useState<PortalRoot>(defaultRoot);\n\n return <PortalContext.Provider value={{ root, setRoot }}>{children}</PortalContext.Provider>;\n};\n\n/**\n * Use this hook to access the portal root context.\n */\nexport const usePortal = () => {\n const context = useContext(PortalContext);\n\n if (context === undefined) {\n throw new Error('usePortal must be used within a PortalProvider');\n }\n\n return context;\n};\n"],"names":[],"mappings":";;;AAeA,MAAM,aAAA,GAAgB,cAA6C,MAAS,CAAA;AAMrE,MAAM,iBAAgD,CAAC;AAAA,EAC5D,QAAA;AAAA,EACA,aAAa,KAAA,GAAQ;AACvB,CAAA,KAAM;AACJ,EAAA,MAAM,eAAe,MAAM;AACzB,IAAA,QAAQ,IAAA;AAAM,MACZ,KAAK,QAAQ,KAAK,CAAA;AAChB,QAAA,OAAO,KAAA;AAAA,MACT;AACE,QAAA,OAAO,QAAA,CAAS,IAAA;AAAA;AACpB,EACF,CAAA,GAAG;AAEH,EAAA,MAAM,CAAC,IAAA,EAAM,OAAO,CAAA,GAAI,SAAqB,WAAW,CAAA;AAExD,EAAA,uBAAO,GAAA,CAAC,cAAc,QAAA,EAAd,EAAuB,OAAO,EAAE,IAAA,EAAM,OAAA,EAAQ,EAAI,QAAA,EAAS,CAAA;AACrE;AAKO,MAAM,YAAY,MAAM;AAC7B,EAAA,MAAM,OAAA,GAAU,WAAW,aAAa,CAAA;AAExC,EAAA,IAAI,YAAY,MAAA,EAAW;AACzB,IAAA,MAAM,IAAI,MAAM,gDAAgD,CAAA;AAAA,EAClE;AAEA,EAAA,OAAO,OAAA;AACT;;;;"}
1
+ {"version":3,"file":"PortalProvider.js","sources":["../../../../src/components/PortalProvider/PortalProvider.tsx"],"sourcesContent":["import React, { createContext, useContext, useState, ReactNode } from 'react';\nimport type { FloatingPortalProps } from '@floating-ui/react';\n\nexport type PortalRoot = FloatingPortalProps['root'];\n\nexport interface PortalContextType {\n root: PortalRoot;\n setRoot: (root: PortalRoot) => void;\n}\n\nexport interface PortalProviderProps {\n children: ReactNode;\n defaultRoot?: PortalRoot;\n}\n\nexport interface UsePortalOptions {\n /** If true, returns document.body instead of throwing when outside provider */\n allowOutsideProvider?: boolean;\n}\n\nconst PortalContext = createContext<PortalContextType | undefined>(undefined);\n\n/**\n * Provides a shared context for a portal root, which can be a selector string,\n * an HTMLElement, or null.\n *\n * Wrap your application (or a subtree) in this provider to enable\n * Popover, Tooltip, and other floating components to render correctly.\n *\n * @example\n * ```tsx\n * <PortalProvider defaultRoot={document.getElementById('grafana-portal-container')}>\n * <App />\n * </PortalProvider>\n * ```\n */\nexport const PortalProvider: React.FC<PortalProviderProps> = ({ children, defaultRoot = null }) => {\n const [root, setRoot] = useState<PortalRoot>(defaultRoot ?? document.body);\n\n return <PortalContext.Provider value={{ root, setRoot }}>{children}</PortalContext.Provider>;\n};\n\n/**\n * Use this hook to access the portal root context.\n */\nexport const usePortal = ({ allowOutsideProvider = false }: UsePortalOptions = {}) => {\n const context = useContext(PortalContext);\n\n if (context === undefined) {\n if (allowOutsideProvider) {\n return { root: document.body, setRoot: () => {} };\n }\n throw new Error('usePortal must be used within a PortalProvider');\n }\n\n return context;\n};\n"],"names":[],"mappings":";;;AAoBA,MAAM,aAAA,GAAgB,cAA6C,MAAS,CAAA;AAgBrE,MAAM,iBAAgD,CAAC,EAAE,QAAA,EAAU,WAAA,GAAc,MAAK,KAAM;AACjG,EAAA,MAAM,CAAC,IAAA,EAAM,OAAO,IAAI,QAAA,CAAqB,WAAA,IAAA,IAAA,GAAA,WAAA,GAAe,SAAS,IAAI,CAAA;AAEzE,EAAA,uBAAO,GAAA,CAAC,cAAc,QAAA,EAAd,EAAuB,OAAO,EAAE,IAAA,EAAM,OAAA,EAAQ,EAAI,QAAA,EAAS,CAAA;AACrE;AAKO,MAAM,YAAY,CAAC,EAAE,uBAAuB,KAAA,EAAM,GAAsB,EAAC,KAAM;AACpF,EAAA,MAAM,OAAA,GAAU,WAAW,aAAa,CAAA;AAExC,EAAA,IAAI,YAAY,MAAA,EAAW;AACzB,IAAA,IAAI,oBAAA,EAAsB;AACxB,MAAA,OAAO,EAAE,IAAA,EAAM,QAAA,CAAS,IAAA,EAAM,SAAS,MAAM;AAAA,MAAC,CAAA,EAAE;AAAA,IAClD;AACA,IAAA,MAAM,IAAI,MAAM,gDAAgD,CAAA;AAAA,EAClE;AAEA,EAAA,OAAO,OAAA;AACT;;;;"}
@@ -1 +1 @@
1
- {"version":3,"file":"StackedChart.js","sources":["../../../../src/components/StackedChart/StackedChart.tsx"],"sourcesContent":["import { useRef, useState } from 'react';\nimport { StackedChartSegment } from '../StackedChartSegment';\nimport { getStyles } from './StackedChart.styles';\nimport { StackedChartSegmentState, SegmentMouseEventHandler } from '../StackedChartSegment/types';\nimport { StackedChartSegmentTooltip } from '../StackedChartSegmentTooltip';\nimport { StackedChartSkeleton } from '../StackedChartSkeleton';\nimport { StackedChartNoData, StackedChartNoDataProps } from '../StackedChartNoData';\nimport { STACKED_CHART_DEFAULT_HEIGHT } from './common';\n\nexport interface StackedChartCategory {\n title: string;\n value: number;\n}\n\nconst DUMMY_CATEGORY: StackedChartCategory = {\n title: 'Category',\n value: 0.01,\n};\n\nexport type StackedChartCategories<T extends string> = Partial<Record<T, StackedChartCategory>>;\n\nexport type StackedChartSortOrder = 'largest-first' | 'smallest-first' | 'natural';\n\ntype MouseEventHandler = ({\n categoryId,\n ref,\n}: {\n categoryId: string;\n ref: React.ForwardedRef<HTMLDivElement>;\n}) => void;\n\nexport interface StackedChartProps<T extends string> {\n /**\n * How should category segments be sorted?\n */\n sortOrder?: StackedChartSortOrder;\n\n /**\n * Height to render the stacked chart, in pixels\n */\n height?: number;\n\n /**\n * initial category ID to highlight; if omitted then all segments will render\n * in colour and highlight based on mouseover events.\n */\n highlightedCategoryId?: T;\n\n /**\n * Should the whole StackedChart be dimmed, i.e. with a highlighted category\n * not in color, all other categories faded out?\n */\n isDimmed?: boolean;\n\n /**\n * Event handler for whenever a segment gets a mouseover event\n */\n onSegmentMouseOver?: MouseEventHandler;\n\n /**\n * Event handler for whenever a segment gets a mouseout event\n */\n onSegmentMouseOut?: MouseEventHandler;\n\n /**\n * String representing the period for which the chart is displaying data\n */\n period?: string;\n\n formatNoDataMessage?: StackedChartNoDataProps['formatMessage'];\n\n /**\n * Is the StackedChart explicitly in a loading state?\n */\n isSkeleton?: boolean;\n\n /**\n * Array of StackedChartCategory to build the chart from\n */\n categories?: StackedChartCategories<T>;\n}\n\n/**\n * Custom hook to assign a ref per categoryId\n */\nconst useCategoryRefs = <T extends string>(\n categoryIds: T[],\n): Record<T, React.RefObject<HTMLDivElement>> => {\n const refsMap = useRef<Map<T, React.RefObject<HTMLDivElement>>>(new Map());\n\n for (const categoryId of categoryIds) {\n if (!refsMap.current.has(categoryId)) {\n refsMap.current.set(categoryId, { current: null });\n }\n }\n\n const result = {} as Record<T, React.RefObject<HTMLDivElement>>;\n for (const categoryId of categoryIds) {\n result[categoryId] = refsMap.current.get(categoryId)!;\n }\n\n return result;\n};\n\nexport const StackedChart = <T extends string>({\n categories,\n highlightedCategoryId: initialHighlightedCategoryId,\n isSkeleton = false,\n isDimmed = false,\n sortOrder = 'largest-first',\n height = STACKED_CHART_DEFAULT_HEIGHT,\n onSegmentMouseOver,\n onSegmentMouseOut,\n period = 'current',\n formatNoDataMessage,\n}: StackedChartProps<T>) => {\n const shouldRenderSkeleton = isSkeleton || !categories;\n let highlightedSegmentRef = useRef<HTMLDivElement>(null);\n const [highlightedCategoryId, setHighlightedCategoryId] = useState<string | undefined>(\n /**\n * Using a type assertion here ultimately because you can’t pass a generic\n * type argument to the type of props in React.forwardRef (it is inferred as\n * of type string).\n *\n * See: https://stackoverflow.com/questions/51884498/using-react-forwardref-with-typescript-generic-jsx-arguments\n */\n initialHighlightedCategoryId as string,\n );\n const [isHovered, setHovered] = useState<boolean>(false);\n const timer = useRef<number | undefined>(undefined);\n\n const sortedCategoryIds = (() => {\n let categoryIds: T[] = [];\n\n for (const categoryId in categories) {\n categoryIds.push(categoryId);\n }\n\n // return early since we may not even have any categories at this point\n if (shouldRenderSkeleton) return categoryIds;\n\n switch (sortOrder) {\n case 'largest-first':\n return categoryIds.sort(\n (a, b) => (categories[b]?.value ?? 0) - (categories[a]?.value ?? 0),\n );\n case 'smallest-first':\n return categoryIds.sort(\n (a, b) => (categories[a]?.value ?? 0) - (categories[b]?.value ?? 0),\n );\n default:\n return categoryIds;\n }\n })();\n\n const categoryRefs = useCategoryRefs(sortedCategoryIds);\n\n /**\n * Determine what the total value is for all category values combined\n */\n const total = shouldRenderSkeleton\n ? 0\n : Math.round(\n sortedCategoryIds.reduce((sum, categoryId) => {\n return sum + (categories[categoryId]?.value ?? 0);\n }, 0),\n );\n\n const styles = getStyles({ height });\n\n const onMouseOver: SegmentMouseEventHandler =\n ({ ref, categoryId }) =>\n () => {\n clearTimeout(timer.current);\n setHovered(true);\n\n /**\n * Only update the highlighted category ID if an initial category wasn’t\n * supplied\n */\n if (!initialHighlightedCategoryId) {\n setHighlightedCategoryId(categoryId);\n }\n\n if (onSegmentMouseOver) onSegmentMouseOver({ ref, categoryId });\n };\n\n const onMouseOut: SegmentMouseEventHandler =\n ({ ref, categoryId }) =>\n () => {\n /**\n * TODO: rather than use a timeout, maybe use the parent element being\n * moused over (event bubbling?) to validate whether the mouse has left\n * the entire chart vs an individual segment?\n */\n timer.current = window.setTimeout(() => {\n setHovered(false);\n /**\n * Only clear the highlighted category if an initial category wasn’t\n * supplied\n */\n if (!initialHighlightedCategoryId) {\n setHighlightedCategoryId(undefined);\n }\n }, 50);\n\n if (onSegmentMouseOut) onSegmentMouseOut({ ref, categoryId });\n };\n\n const highlightedCategory: (StackedChartCategory & { index: number }) | undefined =\n !shouldRenderSkeleton &&\n initialHighlightedCategoryId &&\n categories[initialHighlightedCategoryId]\n ? {\n ...categories[initialHighlightedCategoryId],\n index: sortedCategoryIds.indexOf(initialHighlightedCategoryId),\n }\n : undefined;\n\n const content = (\n <div className={styles.container}>\n {sortedCategoryIds.map((categoryId, index) => {\n /**\n * Some dummy category data is returned here for the scenario when\n * rendering a skeleton\n */\n const category =\n !shouldRenderSkeleton && categories?.[categoryId] !== undefined\n ? categories?.[categoryId]\n : DUMMY_CATEGORY;\n const ref = categoryRefs[categoryId];\n\n if (categoryId === initialHighlightedCategoryId && ref) highlightedSegmentRef = ref;\n\n const segmentState = ((): StackedChartSegmentState => {\n switch (true) {\n /**\n * If no initial highlighted category was set, and a category is\n * moused over, use the _active_ state for that category rather\n * than the color state; this adds a drop shadow to the segment.\n * Also, if an initial highlighted category _was_ set, and it\n * receives a hover event, also set it to active.\n */\n case !initialHighlightedCategoryId && highlightedCategoryId === categoryId && !isDimmed:\n case initialHighlightedCategoryId === categoryId && isHovered && !isDimmed:\n return 'active';\n\n /**\n * - no initial highlighted category ID was passed _and_ there is\n * no highlightedCategoryId (i.e. all segments in colour)\n * - the highlighted category is this category (but the chart\n * isn’t dimmed)\n * - the initial highlighted category is this category (but the\n * chart isn’t dimmed)\n */\n case !initialHighlightedCategoryId && !highlightedCategoryId && !isDimmed:\n case initialHighlightedCategoryId === categoryId && !isDimmed:\n return 'color';\n\n /**\n * Has an initial highlighted category, but is dimmed (i.e. all\n * segments excepted the highlighted category)\n */\n case Boolean(initialHighlightedCategoryId) &&\n initialHighlightedCategoryId !== categoryId &&\n isDimmed:\n case !initialHighlightedCategoryId && !highlightedCategoryId && isDimmed:\n case highlightedCategoryId !== categoryId && isDimmed:\n return 'dimmed';\n\n /**\n * In any other case, the segment should be the default grey\n */\n default:\n return 'default';\n }\n })();\n\n const segmentProps = {\n key: categoryId,\n index,\n ref,\n categoryId,\n title: category.title,\n value: category.value,\n total,\n state: segmentState,\n onMouseOver,\n onMouseOut,\n };\n\n /**\n * Only wrap the segment in a tooltip if no initially highlighted\n * category ID was supplied.\n */\n return initialHighlightedCategoryId ? (\n <StackedChartSegment {...segmentProps} />\n ) : (\n <StackedChartSegmentTooltip\n key={categoryId}\n title={category.title}\n value={category.value}\n index={index}\n hideDelay={0}\n trigger={<StackedChartSegment {...segmentProps} />}\n />\n );\n })}\n </div>\n );\n\n /**\n * If we should only render a skeleton, return early with that component\n */\n if (shouldRenderSkeleton) return <StackedChartSkeleton height={height} />;\n\n /**\n * If the initial highlighted category isn’t within the provided set of\n * categories, fall back to displaying the No Data component\n */\n if (\n initialHighlightedCategoryId &&\n sortedCategoryIds.indexOf(initialHighlightedCategoryId) === -1\n )\n return (\n <StackedChartNoData height={height} period={period} formatMessage={formatNoDataMessage} />\n );\n\n /**\n * If an initial highlight category was provided, wrap the entire chart inside\n * a tooltip using the props for the highlighted segment to drive the tooltip\n * content.\n */\n return initialHighlightedCategoryId && highlightedCategory ? (\n <StackedChartSegmentTooltip\n hideDelay={0}\n trigger={content}\n virtualElement={highlightedSegmentRef}\n {...highlightedCategory}\n />\n ) : (\n content\n );\n};\n"],"names":[],"mappings":";;;;;;;;;AAcA,MAAM,cAAA,GAAuC;AAAA,EAC3C,KAAA,EAAO,UAAA;AAAA,EACP,KAAA,EAAO;AACT,CAAA;AAoEA,MAAM,eAAA,GAAkB,CACtB,WAAA,KAC+C;AAC/C,EAAA,MAAM,OAAA,GAAU,MAAA,iBAAgD,IAAI,GAAA,EAAK,CAAA;AAEzE,EAAA,KAAA,MAAW,cAAc,WAAA,EAAa;AACpC,IAAA,IAAI,CAAC,OAAA,CAAQ,OAAA,CAAQ,GAAA,CAAI,UAAU,CAAA,EAAG;AACpC,MAAA,OAAA,CAAQ,QAAQ,GAAA,CAAI,UAAA,EAAY,EAAE,OAAA,EAAS,MAAM,CAAA;AAAA,IACnD;AAAA,EACF;AAEA,EAAA,MAAM,SAAS,EAAC;AAChB,EAAA,KAAA,MAAW,cAAc,WAAA,EAAa;AACpC,IAAA,MAAA,CAAO,UAAU,CAAA,GAAI,OAAA,CAAQ,OAAA,CAAQ,IAAI,UAAU,CAAA;AAAA,EACrD;AAEA,EAAA,OAAO,MAAA;AACT,CAAA;AAEO,MAAM,eAAe,CAAmB;AAAA,EAC7C,UAAA;AAAA,EACA,qBAAA,EAAuB,4BAAA;AAAA,EACvB,UAAA,GAAa,KAAA;AAAA,EACb,QAAA,GAAW,KAAA;AAAA,EACX,SAAA,GAAY,eAAA;AAAA,EACZ,MAAA,GAAS,4BAAA;AAAA,EACT,kBAAA;AAAA,EACA,iBAAA;AAAA,EACA,MAAA,GAAS,SAAA;AAAA,EACT;AACF,CAAA,KAA4B;AAC1B,EAAA,MAAM,oBAAA,GAAuB,cAAc,CAAC,UAAA;AAC5C,EAAA,IAAI,qBAAA,GAAwB,OAAuB,IAAI,CAAA;AACvD,EAAA,MAAM,CAAC,qBAAA,EAAuB,wBAAwB,CAAA,GAAI,QAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAQxD;AAAA,GACF;AACA,EAAA,MAAM,CAAC,SAAA,EAAW,UAAU,CAAA,GAAI,SAAkB,KAAK,CAAA;AACvD,EAAA,MAAM,KAAA,GAAQ,OAA2B,MAAS,CAAA;AAElD,EAAA,MAAM,qBAAqB,MAAM;AAC/B,IAAA,IAAI,cAAmB,EAAC;AAExB,IAAA,KAAA,MAAW,cAAc,UAAA,EAAY;AACnC,MAAA,WAAA,CAAY,KAAK,UAAU,CAAA;AAAA,IAC7B;AAGA,IAAA,IAAI,sBAAsB,OAAO,WAAA;AAEjC,IAAA,QAAQ,SAAA;AAAW,MACjB,KAAK,eAAA;AACH,QAAA,OAAO,WAAA,CAAY,IAAA;AAAA,UACjB,CAAC,GAAG,CAAA,KAAG;AAhJjB,YAAA,IAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA;AAgJqB,YAAA,OAAA,CAAA,CAAA,EAAA,GAAA,CAAA,EAAA,GAAA,UAAA,CAAW,CAAC,CAAA,KAAZ,IAAA,GAAA,MAAA,GAAA,EAAA,CAAe,KAAA,KAAf,IAAA,GAAA,EAAA,GAAwB,CAAA,KAAA,CAAM,EAAA,GAAA,CAAA,EAAA,GAAA,UAAA,CAAW,CAAC,CAAA,KAAZ,IAAA,GAAA,MAAA,GAAA,EAAA,CAAe,KAAA,KAAf,IAAA,GAAA,EAAA,GAAwB,CAAA,CAAA;AAAA,UAAA;AAAA,SACnE;AAAA,MACF,KAAK,gBAAA;AACH,QAAA,OAAO,WAAA,CAAY,IAAA;AAAA,UACjB,CAAC,GAAG,CAAA,KAAG;AApJjB,YAAA,IAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA;AAoJqB,YAAA,OAAA,CAAA,CAAA,EAAA,GAAA,CAAA,EAAA,GAAA,UAAA,CAAW,CAAC,CAAA,KAAZ,IAAA,GAAA,MAAA,GAAA,EAAA,CAAe,KAAA,KAAf,IAAA,GAAA,EAAA,GAAwB,CAAA,KAAA,CAAM,EAAA,GAAA,CAAA,EAAA,GAAA,UAAA,CAAW,CAAC,CAAA,KAAZ,IAAA,GAAA,MAAA,GAAA,EAAA,CAAe,KAAA,KAAf,IAAA,GAAA,EAAA,GAAwB,CAAA,CAAA;AAAA,UAAA;AAAA,SACnE;AAAA,MACF;AACE,QAAA,OAAO,WAAA;AAAA;AACX,EACF,CAAA,GAAG;AAEH,EAAA,MAAM,YAAA,GAAe,gBAAgB,iBAAiB,CAAA;AAKtD,EAAA,MAAM,KAAA,GAAQ,oBAAA,GACV,CAAA,GACA,IAAA,CAAK,KAAA;AAAA,IACH,iBAAA,CAAkB,MAAA,CAAO,CAAC,GAAA,EAAK,UAAA,KAAe;AAnKtD,MAAA,IAAA,EAAA,EAAA,EAAA;AAoKU,MAAA,OAAO,QAAO,EAAA,GAAA,CAAA,EAAA,GAAA,UAAA,CAAW,UAAU,CAAA,KAArB,IAAA,GAAA,MAAA,GAAA,EAAA,CAAwB,UAAxB,IAAA,GAAA,EAAA,GAAiC,CAAA,CAAA;AAAA,IACjD,GAAG,CAAC;AAAA,GACN;AAEJ,EAAA,MAAM,MAAA,GAAS,SAAA,CAAU,EAAE,MAAA,EAAQ,CAAA;AAEnC,EAAA,MAAM,cACJ,CAAC,EAAE,GAAA,EAAK,UAAA,OACR,MAAM;AACJ,IAAA,YAAA,CAAa,MAAM,OAAO,CAAA;AAC1B,IAAA,UAAA,CAAW,IAAI,CAAA;AAMf,IAAA,IAAI,CAAC,4BAAA,EAA8B;AACjC,MAAA,wBAAA,CAAyB,UAAU,CAAA;AAAA,IACrC;AAEA,IAAA,IAAI,kBAAA,EAAoB,kBAAA,CAAmB,EAAE,GAAA,EAAK,YAAY,CAAA;AAAA,EAChE,CAAA;AAEF,EAAA,MAAM,aACJ,CAAC,EAAE,GAAA,EAAK,UAAA,OACR,MAAM;AAMJ,IAAA,KAAA,CAAM,OAAA,GAAU,MAAA,CAAO,UAAA,CAAW,MAAM;AACtC,MAAA,UAAA,CAAW,KAAK,CAAA;AAKhB,MAAA,IAAI,CAAC,4BAAA,EAA8B;AACjC,QAAA,wBAAA,CAAyB,MAAS,CAAA;AAAA,MACpC;AAAA,IACF,GAAG,EAAE,CAAA;AAEL,IAAA,IAAI,iBAAA,EAAmB,iBAAA,CAAkB,EAAE,GAAA,EAAK,YAAY,CAAA;AAAA,EAC9D,CAAA;AAEF,EAAA,MAAM,sBACJ,CAAC,oBAAA,IACD,4BAAA,IACA,UAAA,CAAW,4BAA4B,CAAA,GACnC;AAAA,IACE,GAAG,WAAW,4BAA4B,CAAA;AAAA,IAC1C,KAAA,EAAO,iBAAA,CAAkB,OAAA,CAAQ,4BAA4B;AAAA,GAC/D,GACA,MAAA;AAEN,EAAA,MAAM,OAAA,mBACJ,GAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAW,MAAA,CAAO,WACpB,QAAA,EAAA,iBAAA,CAAkB,GAAA,CAAI,CAAC,UAAA,EAAY,KAAA,KAAU;AAK5C,IAAA,MAAM,WACJ,CAAC,oBAAA,IAAA,CAAwB,yCAAa,UAAA,CAAA,MAAgB,MAAA,GAClD,yCAAa,UAAA,CAAA,GACb,cAAA;AACN,IAAA,MAAM,GAAA,GAAM,aAAa,UAAU,CAAA;AAEnC,IAAA,IAAI,UAAA,KAAe,4BAAA,IAAgC,GAAA,EAAK,qBAAA,GAAwB,GAAA;AAEhF,IAAA,MAAM,gBAAgB,MAAgC;AACpD,MAAA,QAAQ,IAAA;AAAM;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,QAQZ,MAAK,CAAC,4BAAA,IAAgC,qBAAA,KAA0B,cAAc,CAAC,QAAA;AAAA,QAC/E,MAAK,4BAAA,KAAiC,UAAA,IAAc,SAAA,IAAa,CAAC,QAAA;AAChE,UAAA,OAAO,QAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,QAUT,MAAK,CAAC,4BAAA,IAAgC,CAAC,yBAAyB,CAAC,QAAA;AAAA,QACjE,MAAK,4BAAA,KAAiC,UAAA,IAAc,CAAC,QAAA;AACnD,UAAA,OAAO,OAAA;AAAA;AAAA;AAAA;AAAA;AAAA,QAMT,MAAK,OAAA,CAAQ,4BAA4B,CAAA,IACvC,iCAAiC,UAAA,IACjC,QAAA;AAAA,QACF,MAAK,CAAC,4BAAA,IAAgC,CAAC,qBAAA,IAAyB,QAAA;AAAA,QAChE,MAAK,0BAA0B,UAAA,IAAc,QAAA;AAC3C,UAAA,OAAO,QAAA;AAAA;AAAA;AAAA;AAAA,QAKT;AACE,UAAA,OAAO,SAAA;AAAA;AACX,IACF,CAAA,GAAG;AAEH,IAAA,MAAM,YAAA,GAAe;AAAA,MACnB,GAAA,EAAK,UAAA;AAAA,MACL,KAAA;AAAA,MACA,GAAA;AAAA,MACA,UAAA;AAAA,MACA,OAAO,QAAA,CAAS,KAAA;AAAA,MAChB,OAAO,QAAA,CAAS,KAAA;AAAA,MAChB,KAAA;AAAA,MACA,KAAA,EAAO,YAAA;AAAA,MACP,WAAA;AAAA,MACA;AAAA,KACF;AAMA,IAAA,OAAO,4BAAA,mBACL,GAAA,CAAC,mBAAA,EAAA,EAAqB,GAAG,cAAc,CAAA,mBAEvC,GAAA;AAAA,MAAC,0BAAA;AAAA,MAAA;AAAA,QAEC,OAAO,QAAA,CAAS,KAAA;AAAA,QAChB,OAAO,QAAA,CAAS,KAAA;AAAA,QAChB,KAAA;AAAA,QACA,SAAA,EAAW,CAAA;AAAA,QACX,OAAA,kBAAS,GAAA,CAAC,mBAAA,EAAA,EAAqB,GAAG,YAAA,EAAc;AAAA,OAAA;AAAA,MAL3C;AAAA,KAMP;AAAA,EAEJ,CAAC,CAAA,EACH,CAAA;AAMF,EAAA,IAAI,oBAAA,EAAsB,uBAAO,GAAA,CAAC,oBAAA,EAAA,EAAqB,MAAA,EAAgB,CAAA;AAMvE,EAAA,IACE,4BAAA,IACA,iBAAA,CAAkB,OAAA,CAAQ,4BAA4B,CAAA,KAAM,EAAA;AAE5D,IAAA,uBACE,GAAA,CAAC,kBAAA,EAAA,EAAmB,MAAA,EAAgB,MAAA,EAAgB,eAAe,mBAAA,EAAqB,CAAA;AAQ5F,EAAA,OAAO,gCAAgC,mBAAA,mBACrC,GAAA;AAAA,IAAC,0BAAA;AAAA,IAAA;AAAA,MACC,SAAA,EAAW,CAAA;AAAA,MACX,OAAA,EAAS,OAAA;AAAA,MACT,cAAA,EAAgB,qBAAA;AAAA,MACf,GAAG;AAAA;AAAA,GACN,GAEA,OAAA;AAEJ;;;;"}
1
+ {"version":3,"file":"StackedChart.js","sources":["../../../../src/components/StackedChart/StackedChart.tsx"],"sourcesContent":["import { useRef, useState } from 'react';\nimport { StackedChartSegment } from '../StackedChartSegment';\nimport { getStyles } from './StackedChart.styles';\nimport { StackedChartSegmentState, SegmentMouseEventHandler } from '../StackedChartSegment/types';\nimport { StackedChartSegmentTooltip } from '../StackedChartSegmentTooltip';\nimport { StackedChartSkeleton } from '../StackedChartSkeleton';\nimport { StackedChartNoData, StackedChartNoDataProps } from '../StackedChartNoData';\nimport { STACKED_CHART_DEFAULT_HEIGHT } from './common';\n\nexport interface StackedChartCategory {\n title: string;\n value: number;\n}\n\nconst DUMMY_CATEGORY: StackedChartCategory = {\n title: 'Category',\n value: 0.01,\n};\n\nexport type StackedChartCategories<T extends string> = Partial<Record<T, StackedChartCategory>>;\n\nexport type StackedChartSortOrder = 'largest-first' | 'smallest-first' | 'natural';\n\n/**\n * Callback function invoked when a mouse event occurs on a chart segment.\n *\n * This is a simplified callback (not a React event handler) that receives\n * segment metadata. It's called after the internal event handling is complete.\n *\n * @param args - Object containing segment metadata\n * @param args.categoryId - The unique identifier of the segment that triggered the event\n * @param args.ref - React ref to the segment's DOM element, useful for positioning tooltips or popovers\n *\n * @example\n * ```tsx\n * <StackedChart\n * categories={categories}\n * onSegmentMouseOver={({ categoryId, ref }) => {\n * console.log(`Hovered segment: ${categoryId}`);\n * // ref.current gives you the DOM element if needed\n * }}\n * onSegmentMouseOut={({ categoryId }) => {\n * console.log(`Left segment: ${categoryId}`);\n * }}\n * />\n * ```\n */\ntype MouseEventHandler = ({\n categoryId,\n ref,\n}: {\n categoryId: string;\n ref: React.ForwardedRef<HTMLDivElement>;\n}) => void;\n\nexport interface StackedChartProps<T extends string> {\n /**\n * How should category segments be sorted?\n */\n sortOrder?: StackedChartSortOrder;\n\n /**\n * Height to render the stacked chart, in pixels\n */\n height?: number;\n\n /**\n * initial category ID to highlight; if omitted then all segments will render\n * in colour and highlight based on mouseover events.\n */\n highlightedCategoryId?: T;\n\n /**\n * Should the whole StackedChart be dimmed, i.e. with a highlighted category\n * not in color, all other categories faded out?\n */\n isDimmed?: boolean;\n\n /**\n * Callback invoked when the mouse enters a chart segment.\n *\n * Receives the segment's `categoryId` and a `ref` to its DOM element.\n * Use this to implement custom hover behavior, analytics tracking,\n * or coordination with external UI elements.\n *\n * @example\n * ```tsx\n * onSegmentMouseOver={({ categoryId, ref }) => {\n * setActiveCategory(categoryId);\n * // Optional: use ref.current for DOM measurements\n * }}\n * ```\n */\n onSegmentMouseOver?: MouseEventHandler;\n\n /**\n * Callback invoked when the mouse leaves a chart segment.\n *\n * Receives the segment's `categoryId` and a `ref` to its DOM element.\n * Use this to clean up hover state or hide related UI elements.\n *\n * @example\n * ```tsx\n * onSegmentMouseOut={({ categoryId }) => {\n * setActiveCategory(null);\n * }}\n * ```\n */\n onSegmentMouseOut?: MouseEventHandler;\n\n /**\n * String representing the period for which the chart is displaying data\n */\n period?: string;\n\n formatNoDataMessage?: StackedChartNoDataProps['formatMessage'];\n\n /**\n * Is the StackedChart explicitly in a loading state?\n */\n isSkeleton?: boolean;\n\n /**\n * Array of StackedChartCategory to build the chart from\n */\n categories?: StackedChartCategories<T>;\n}\n\n/**\n * Custom hook to assign a ref per categoryId\n */\nconst useCategoryRefs = <T extends string>(\n categoryIds: T[],\n): Record<T, React.RefObject<HTMLDivElement>> => {\n const refsMap = useRef<Map<T, React.RefObject<HTMLDivElement>>>(new Map());\n\n for (const categoryId of categoryIds) {\n if (!refsMap.current.has(categoryId)) {\n refsMap.current.set(categoryId, { current: null });\n }\n }\n\n const result = {} as Record<T, React.RefObject<HTMLDivElement>>;\n for (const categoryId of categoryIds) {\n result[categoryId] = refsMap.current.get(categoryId)!;\n }\n\n return result;\n};\n\nexport const StackedChart = <T extends string>({\n categories,\n highlightedCategoryId: initialHighlightedCategoryId,\n isSkeleton = false,\n isDimmed = false,\n sortOrder = 'largest-first',\n height = STACKED_CHART_DEFAULT_HEIGHT,\n onSegmentMouseOver,\n onSegmentMouseOut,\n period = 'current',\n formatNoDataMessage,\n}: StackedChartProps<T>) => {\n const shouldRenderSkeleton = isSkeleton || !categories;\n let highlightedSegmentRef = useRef<HTMLDivElement>(null);\n const [highlightedCategoryId, setHighlightedCategoryId] = useState<string | undefined>(\n /**\n * Using a type assertion here ultimately because you can’t pass a generic\n * type argument to the type of props in React.forwardRef (it is inferred as\n * of type string).\n *\n * See: https://stackoverflow.com/questions/51884498/using-react-forwardref-with-typescript-generic-jsx-arguments\n */\n initialHighlightedCategoryId as string,\n );\n const [isHovered, setHovered] = useState<boolean>(false);\n const timer = useRef<number | undefined>(undefined);\n\n const sortedCategoryIds = (() => {\n let categoryIds: T[] = [];\n\n for (const categoryId in categories) {\n categoryIds.push(categoryId);\n }\n\n // return early since we may not even have any categories at this point\n if (shouldRenderSkeleton) return categoryIds;\n\n switch (sortOrder) {\n case 'largest-first':\n return categoryIds.sort(\n (a, b) => (categories[b]?.value ?? 0) - (categories[a]?.value ?? 0),\n );\n case 'smallest-first':\n return categoryIds.sort(\n (a, b) => (categories[a]?.value ?? 0) - (categories[b]?.value ?? 0),\n );\n default:\n return categoryIds;\n }\n })();\n\n const categoryRefs = useCategoryRefs(sortedCategoryIds);\n\n /**\n * Determine what the total value is for all category values combined\n */\n const total = shouldRenderSkeleton\n ? 0\n : Math.round(\n sortedCategoryIds.reduce((sum, categoryId) => {\n return sum + (categories[categoryId]?.value ?? 0);\n }, 0),\n );\n\n const styles = getStyles({ height });\n\n const onMouseOver: SegmentMouseEventHandler =\n ({ ref, categoryId }) =>\n () => {\n clearTimeout(timer.current);\n setHovered(true);\n\n /**\n * Only update the highlighted category ID if an initial category wasn’t\n * supplied\n */\n if (!initialHighlightedCategoryId) {\n setHighlightedCategoryId(categoryId);\n }\n\n if (onSegmentMouseOver) onSegmentMouseOver({ ref, categoryId });\n };\n\n const onMouseOut: SegmentMouseEventHandler =\n ({ ref, categoryId }) =>\n () => {\n /**\n * TODO: rather than use a timeout, maybe use the parent element being\n * moused over (event bubbling?) to validate whether the mouse has left\n * the entire chart vs an individual segment?\n */\n timer.current = window.setTimeout(() => {\n setHovered(false);\n /**\n * Only clear the highlighted category if an initial category wasn’t\n * supplied\n */\n if (!initialHighlightedCategoryId) {\n setHighlightedCategoryId(undefined);\n }\n }, 50);\n\n if (onSegmentMouseOut) onSegmentMouseOut({ ref, categoryId });\n };\n\n const highlightedCategory: (StackedChartCategory & { index: number }) | undefined =\n !shouldRenderSkeleton &&\n initialHighlightedCategoryId &&\n categories[initialHighlightedCategoryId]\n ? {\n ...categories[initialHighlightedCategoryId],\n index: sortedCategoryIds.indexOf(initialHighlightedCategoryId),\n }\n : undefined;\n\n const content = (\n <div className={styles.container}>\n {sortedCategoryIds.map((categoryId, index) => {\n /**\n * Some dummy category data is returned here for the scenario when\n * rendering a skeleton\n */\n const category =\n !shouldRenderSkeleton && categories?.[categoryId] !== undefined\n ? categories?.[categoryId]\n : DUMMY_CATEGORY;\n const ref = categoryRefs[categoryId];\n\n if (categoryId === initialHighlightedCategoryId && ref) highlightedSegmentRef = ref;\n\n const segmentState = ((): StackedChartSegmentState => {\n switch (true) {\n /**\n * If no initial highlighted category was set, and a category is\n * moused over, use the _active_ state for that category rather\n * than the color state; this adds a drop shadow to the segment.\n * Also, if an initial highlighted category _was_ set, and it\n * receives a hover event, also set it to active.\n */\n case !initialHighlightedCategoryId && highlightedCategoryId === categoryId && !isDimmed:\n case initialHighlightedCategoryId === categoryId && isHovered && !isDimmed:\n return 'active';\n\n /**\n * - no initial highlighted category ID was passed _and_ there is\n * no highlightedCategoryId (i.e. all segments in colour)\n * - the highlighted category is this category (but the chart\n * isn’t dimmed)\n * - the initial highlighted category is this category (but the\n * chart isn’t dimmed)\n */\n case !initialHighlightedCategoryId && !highlightedCategoryId && !isDimmed:\n case initialHighlightedCategoryId === categoryId && !isDimmed:\n return 'color';\n\n /**\n * Has an initial highlighted category, but is dimmed (i.e. all\n * segments excepted the highlighted category)\n */\n case Boolean(initialHighlightedCategoryId) &&\n initialHighlightedCategoryId !== categoryId &&\n isDimmed:\n case !initialHighlightedCategoryId && !highlightedCategoryId && isDimmed:\n case highlightedCategoryId !== categoryId && isDimmed:\n return 'dimmed';\n\n /**\n * In any other case, the segment should be the default grey\n */\n default:\n return 'default';\n }\n })();\n\n const segmentProps = {\n key: categoryId,\n index,\n ref,\n categoryId,\n title: category.title,\n value: category.value,\n total,\n state: segmentState,\n onMouseOver,\n onMouseOut,\n };\n\n /**\n * Only wrap the segment in a tooltip if no initially highlighted\n * category ID was supplied.\n */\n return initialHighlightedCategoryId ? (\n <StackedChartSegment {...segmentProps} />\n ) : (\n <StackedChartSegmentTooltip\n key={categoryId}\n title={category.title}\n value={category.value}\n index={index}\n hideDelay={0}\n trigger={<StackedChartSegment {...segmentProps} />}\n />\n );\n })}\n </div>\n );\n\n /**\n * If we should only render a skeleton, return early with that component\n */\n if (shouldRenderSkeleton) return <StackedChartSkeleton height={height} />;\n\n /**\n * If the initial highlighted category isn’t within the provided set of\n * categories, fall back to displaying the No Data component\n */\n if (\n initialHighlightedCategoryId &&\n sortedCategoryIds.indexOf(initialHighlightedCategoryId) === -1\n )\n return (\n <StackedChartNoData height={height} period={period} formatMessage={formatNoDataMessage} />\n );\n\n /**\n * If an initial highlight category was provided, wrap the entire chart inside\n * a tooltip using the props for the highlighted segment to drive the tooltip\n * content.\n */\n return initialHighlightedCategoryId && highlightedCategory ? (\n <StackedChartSegmentTooltip\n hideDelay={0}\n trigger={content}\n virtualElement={highlightedSegmentRef}\n {...highlightedCategory}\n />\n ) : (\n content\n );\n};\n"],"names":[],"mappings":"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"}
@@ -1,3 +1,4 @@
1
+ import { useEffect } from 'react';
1
2
  import { ThemeChangedEvent } from '@grafana/runtime';
2
3
  import { useColorMode } from '../components/ColorModeProvider/ColorModeProvider.js';
3
4
 
@@ -8,18 +9,26 @@ const useColorModeChange = ({
8
9
  getAppEvents,
9
10
  useTheme2
10
11
  }) => {
11
- const { setColorMode } = useColorMode();
12
+ const { colorMode, setColorMode } = useColorMode();
12
13
  const appEvents = getAppEvents();
13
- appEvents.subscribe(ThemeChangedEvent, ({ payload }) => {
14
- const { isLight: isLight2 } = payload;
15
- const newColorMode2 = getThemeColorMode(isLight2);
16
- console.log("ThemeChangedEvent", { colorMode: newColorMode2 });
17
- setColorMode(newColorMode2);
18
- });
19
14
  const { isLight } = useTheme2();
20
- const newColorMode = getThemeColorMode(isLight);
21
- setColorMode(newColorMode);
22
- return newColorMode;
15
+ useEffect(() => {
16
+ const themeChangedEvent = appEvents.subscribe(
17
+ ThemeChangedEvent,
18
+ ({ payload }) => {
19
+ const newColorMode = getThemeColorMode(payload.isLight);
20
+ setColorMode(newColorMode);
21
+ }
22
+ );
23
+ return () => {
24
+ themeChangedEvent.unsubscribe();
25
+ };
26
+ }, [appEvents, setColorMode]);
27
+ useEffect(() => {
28
+ const newColorMode = getThemeColorMode(isLight);
29
+ setColorMode(newColorMode);
30
+ }, [isLight, setColorMode]);
31
+ return colorMode;
23
32
  };
24
33
 
25
34
  export { useColorModeChange };
@@ -1 +1 @@
1
- {"version":3,"file":"useColorModeChange.js","sources":["../../../src/hooks/useColorModeChange.ts"],"sourcesContent":["import type { EventBus, GrafanaTheme2 } from '@grafana/data';\nimport { ThemeChangedEvent } from '@grafana/runtime';\nimport type { ThemeColorMode } from '@grafana/design-tokens';\nimport { useColorMode } from '../components/ColorModeProvider/ColorModeProvider';\n\nconst getThemeColorMode = (isLight: boolean): ThemeColorMode => {\n return isLight ? 'light' : 'dark';\n};\n\nexport interface ColorModeChangeProps {\n getAppEvents: () => EventBus;\n useTheme2: () => GrafanaTheme2;\n}\n\n/**\n * This allows us to register an event listener for when the ThemeChangedEvent\n * is fired, and update the currently active color mode accordingly. It will\n * also determine the color mode on initial registration, and update the context\n * provider accordingly.\n */\nexport const useColorModeChange = ({\n getAppEvents,\n useTheme2,\n}: ColorModeChangeProps): ThemeColorMode => {\n const { setColorMode } = useColorMode();\n const appEvents = getAppEvents();\n\n appEvents.subscribe<ThemeChangedEvent>(ThemeChangedEvent, ({ payload }) => {\n const { isLight } = payload;\n const newColorMode = getThemeColorMode(isLight);\n\n console.log('ThemeChangedEvent', { colorMode: newColorMode });\n setColorMode(newColorMode);\n });\n\n /**\n * Longterm the current colorMode should ideally exist outside of useTheme2\n */\n const { isLight } = useTheme2();\n const newColorMode = getThemeColorMode(isLight);\n setColorMode(newColorMode);\n\n return newColorMode;\n};\n"],"names":["isLight","newColorMode"],"mappings":";;;AAKA,MAAM,iBAAA,GAAoB,CAAC,OAAA,KAAqC;AAC9D,EAAA,OAAO,UAAU,OAAA,GAAU,MAAA;AAC7B,CAAA;AAaO,MAAM,qBAAqB,CAAC;AAAA,EACjC,YAAA;AAAA,EACA;AACF,CAAA,KAA4C;AAC1C,EAAA,MAAM,EAAE,YAAA,EAAa,GAAI,YAAA,EAAa;AACtC,EAAA,MAAM,YAAY,YAAA,EAAa;AAE/B,EAAA,SAAA,CAAU,SAAA,CAA6B,iBAAA,EAAmB,CAAC,EAAE,SAAQ,KAAM;AACzE,IAAA,MAAM,EAAE,OAAA,EAAAA,QAAAA,EAAQ,GAAI,OAAA;AACpB,IAAA,MAAMC,aAAAA,GAAe,kBAAkBD,QAAO,CAAA;AAE9C,IAAA,OAAA,CAAQ,GAAA,CAAI,mBAAA,EAAqB,EAAE,SAAA,EAAWC,eAAc,CAAA;AAC5D,IAAA,YAAA,CAAaA,aAAY,CAAA;AAAA,EAC3B,CAAC,CAAA;AAKD,EAAA,MAAM,EAAE,OAAA,EAAQ,GAAI,SAAA,EAAU;AAC9B,EAAA,MAAM,YAAA,GAAe,kBAAkB,OAAO,CAAA;AAC9C,EAAA,YAAA,CAAa,YAAY,CAAA;AAEzB,EAAA,OAAO,YAAA;AACT;;;;"}
1
+ {"version":3,"file":"useColorModeChange.js","sources":["../../../src/hooks/useColorModeChange.ts"],"sourcesContent":["import { useEffect } from 'react';\nimport type { EventBus, GrafanaTheme2 } from '@grafana/data';\nimport { ThemeChangedEvent } from '@grafana/runtime';\nimport type { ThemeColorMode } from '@grafana/design-tokens';\nimport { useColorMode } from '../components/ColorModeProvider/ColorModeProvider';\n\nconst getThemeColorMode = (isLight: boolean): ThemeColorMode => {\n return isLight ? 'light' : 'dark';\n};\n\nexport interface ColorModeChangeProps {\n getAppEvents: () => EventBus;\n useTheme2: () => GrafanaTheme2;\n}\n\n/**\n * This allows us to register an event listener for when the ThemeChangedEvent\n * is fired, and update the currently active color mode accordingly. It will\n * also determine the color mode on initial registration, and update the context\n * provider accordingly.\n */\nexport const useColorModeChange = ({\n getAppEvents,\n useTheme2,\n}: ColorModeChangeProps): ThemeColorMode => {\n const { colorMode, setColorMode } = useColorMode();\n const appEvents = getAppEvents();\n\n /**\n * Longterm the current colorMode should ideally exist outside of useTheme2\n */\n const { isLight } = useTheme2();\n\n useEffect(() => {\n const themeChangedEvent = appEvents.subscribe<ThemeChangedEvent>(\n ThemeChangedEvent,\n ({ payload }) => {\n const newColorMode = getThemeColorMode(payload.isLight);\n setColorMode(newColorMode);\n },\n );\n\n return () => {\n themeChangedEvent.unsubscribe();\n };\n }, [appEvents, setColorMode]);\n\n // Sync color mode when theme changes (runs on mount and when isLight changes)\n useEffect(() => {\n const newColorMode = getThemeColorMode(isLight);\n setColorMode(newColorMode);\n }, [isLight, setColorMode]);\n\n return colorMode;\n};\n"],"names":[],"mappings":";;;;AAMA,MAAM,iBAAA,GAAoB,CAAC,OAAA,KAAqC;AAC9D,EAAA,OAAO,UAAU,OAAA,GAAU,MAAA;AAC7B,CAAA;AAaO,MAAM,qBAAqB,CAAC;AAAA,EACjC,YAAA;AAAA,EACA;AACF,CAAA,KAA4C;AAC1C,EAAA,MAAM,EAAE,SAAA,EAAW,YAAA,EAAa,GAAI,YAAA,EAAa;AACjD,EAAA,MAAM,YAAY,YAAA,EAAa;AAK/B,EAAA,MAAM,EAAE,OAAA,EAAQ,GAAI,SAAA,EAAU;AAE9B,EAAA,SAAA,CAAU,MAAM;AACd,IAAA,MAAM,oBAAoB,SAAA,CAAU,SAAA;AAAA,MAClC,iBAAA;AAAA,MACA,CAAC,EAAE,OAAA,EAAQ,KAAM;AACf,QAAA,MAAM,YAAA,GAAe,iBAAA,CAAkB,OAAA,CAAQ,OAAO,CAAA;AACtD,QAAA,YAAA,CAAa,YAAY,CAAA;AAAA,MAC3B;AAAA,KACF;AAEA,IAAA,OAAO,MAAM;AACX,MAAA,iBAAA,CAAkB,WAAA,EAAY;AAAA,IAChC,CAAA;AAAA,EACF,CAAA,EAAG,CAAC,SAAA,EAAW,YAAY,CAAC,CAAA;AAG5B,EAAA,SAAA,CAAU,MAAM;AACd,IAAA,MAAM,YAAA,GAAe,kBAAkB,OAAO,CAAA;AAC9C,IAAA,YAAA,CAAa,YAAY,CAAA;AAAA,EAC3B,CAAA,EAAG,CAAC,OAAA,EAAS,YAAY,CAAC,CAAA;AAE1B,EAAA,OAAO,SAAA;AACT;;;;"}
@@ -130,15 +130,29 @@ interface PortalProviderProps {
130
130
  children: ReactNode;
131
131
  defaultRoot?: PortalRoot;
132
132
  }
133
+ interface UsePortalOptions {
134
+ /** If true, returns document.body instead of throwing when outside provider */
135
+ allowOutsideProvider?: boolean;
136
+ }
133
137
  /**
134
138
  * Provides a shared context for a portal root, which can be a selector string,
135
139
  * an HTMLElement, or null.
140
+ *
141
+ * Wrap your application (or a subtree) in this provider to enable
142
+ * Popover, Tooltip, and other floating components to render correctly.
143
+ *
144
+ * @example
145
+ * ```tsx
146
+ * <PortalProvider defaultRoot={document.getElementById('grafana-portal-container')}>
147
+ * <App />
148
+ * </PortalProvider>
149
+ * ```
136
150
  */
137
151
  declare const PortalProvider: React__default.FC<PortalProviderProps>;
138
152
  /**
139
153
  * Use this hook to access the portal root context.
140
154
  */
141
- declare const usePortal: () => PortalContextType;
155
+ declare const usePortal: ({ allowOutsideProvider }?: UsePortalOptions) => PortalContextType;
142
156
 
143
157
  type StackedChartNoDataMessageFormatter = (args: {
144
158
  period: string;
@@ -166,6 +180,30 @@ interface StackedChartCategory {
166
180
  }
167
181
  type StackedChartCategories<T extends string> = Partial<Record<T, StackedChartCategory>>;
168
182
  type StackedChartSortOrder = 'largest-first' | 'smallest-first' | 'natural';
183
+ /**
184
+ * Callback function invoked when a mouse event occurs on a chart segment.
185
+ *
186
+ * This is a simplified callback (not a React event handler) that receives
187
+ * segment metadata. It's called after the internal event handling is complete.
188
+ *
189
+ * @param args - Object containing segment metadata
190
+ * @param args.categoryId - The unique identifier of the segment that triggered the event
191
+ * @param args.ref - React ref to the segment's DOM element, useful for positioning tooltips or popovers
192
+ *
193
+ * @example
194
+ * ```tsx
195
+ * <StackedChart
196
+ * categories={categories}
197
+ * onSegmentMouseOver={({ categoryId, ref }) => {
198
+ * console.log(`Hovered segment: ${categoryId}`);
199
+ * // ref.current gives you the DOM element if needed
200
+ * }}
201
+ * onSegmentMouseOut={({ categoryId }) => {
202
+ * console.log(`Left segment: ${categoryId}`);
203
+ * }}
204
+ * />
205
+ * ```
206
+ */
169
207
  type MouseEventHandler = ({ categoryId, ref, }: {
170
208
  categoryId: string;
171
209
  ref: React.ForwardedRef<HTMLDivElement>;
@@ -190,11 +228,33 @@ interface StackedChartProps<T extends string> {
190
228
  */
191
229
  isDimmed?: boolean;
192
230
  /**
193
- * Event handler for whenever a segment gets a mouseover event
231
+ * Callback invoked when the mouse enters a chart segment.
232
+ *
233
+ * Receives the segment's `categoryId` and a `ref` to its DOM element.
234
+ * Use this to implement custom hover behavior, analytics tracking,
235
+ * or coordination with external UI elements.
236
+ *
237
+ * @example
238
+ * ```tsx
239
+ * onSegmentMouseOver={({ categoryId, ref }) => {
240
+ * setActiveCategory(categoryId);
241
+ * // Optional: use ref.current for DOM measurements
242
+ * }}
243
+ * ```
194
244
  */
195
245
  onSegmentMouseOver?: MouseEventHandler;
196
246
  /**
197
- * Event handler for whenever a segment gets a mouseout event
247
+ * Callback invoked when the mouse leaves a chart segment.
248
+ *
249
+ * Receives the segment's `categoryId` and a `ref` to its DOM element.
250
+ * Use this to clean up hover state or hide related UI elements.
251
+ *
252
+ * @example
253
+ * ```tsx
254
+ * onSegmentMouseOut={({ categoryId }) => {
255
+ * setActiveCategory(null);
256
+ * }}
257
+ * ```
198
258
  */
199
259
  onSegmentMouseOut?: MouseEventHandler;
200
260
  /**
@@ -334,4 +394,4 @@ interface FormatNumberOptions {
334
394
  declare const formatNumber: (value: number | string | "loading", options?: FormatNumberOptions) => string;
335
395
 
336
396
  export { ColorMode, ColorModeChangeHandler, ColorModeProvider, ComparisonBadge, ComparisonTooltip, GenericSkeleton, Popover, PortalProvider, StackedChart, StackedChartNoData, StackedChartSegment, StackedChartSegmentTooltip, StackedChartSkeleton, calculateComparison, formatNumber, useColorMode, useColorModeChange, usePortal };
337
- export type { ColorModeChangeProps, ColorModeContextType, ColorModeProviderProps, ColorModeWrapper, ComparisonResult, ComparisonTooltipProps, FormatNumberOptions, GenericSkeletonProps, PopoverProps, PortalContextType, PortalProviderProps, PortalRoot, StackedChartCategories, StackedChartCategory, StackedChartNoDataMessageFormatter, StackedChartNoDataProps, StackedChartProps, StackedChartSegmentTooltipProps, StackedChartSkeletonProps, StackedChartSortOrder, StackedChartTooltipContentFormatter };
397
+ export type { ColorModeChangeProps, ColorModeContextType, ColorModeProviderProps, ColorModeWrapper, ComparisonResult, ComparisonTooltipProps, FormatNumberOptions, GenericSkeletonProps, PopoverProps, PortalContextType, PortalProviderProps, PortalRoot, SegmentMouseEventHandler, StackedChartCategories, StackedChartCategory, StackedChartNoDataMessageFormatter, StackedChartNoDataProps, StackedChartProps, StackedChartSegmentProps, StackedChartSegmentState, StackedChartSegmentTooltipProps, StackedChartSkeletonProps, StackedChartSortOrder, StackedChartTooltipContentFormatter, UsePortalOptions };
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "author": "Grafana Labs",
3
3
  "name": "@grafana/components",
4
4
  "license": "Apache-2.0",
5
- "version": "0.0.31",
5
+ "version": "0.0.32",
6
6
  "description": "Product Design Engineering Components for Grafana",
7
7
  "repository": {
8
8
  "type": "git",