@sproutsocial/seeds-react-data-viz 0.14.0 → 0.15.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,83 @@
1
+ import * as react from 'react';
2
+ import { ReactNode } from 'react';
3
+ import { TypeIconName } from '@sproutsocial/seeds-react-icon';
4
+ import { C as ChartDataPoint, a as CategoryAxis, D as DatetimeAxis, V as ValueFormat, b as ChartTooltipProps, c as ChartAnnotation } from '../axis-PJwu5Xmo.js';
5
+ import { C as ChartExportHandle } from '../chartExport-CKYpuhik.js';
6
+ import { h as TypeChartStylePattern } from '../types-B7ILUQ6_.js';
7
+ import 'highcharts';
8
+
9
+ /**
10
+ * Chart variant. `line`/`area` connect points with straight segments;
11
+ * `spline`/`areaspline` smooth them into curves; `area`/`areaspline` fill the
12
+ * region below the line. Maps directly to the Highcharts series type.
13
+ */
14
+ type LineAreaVariant = "line" | "spline" | "area" | "areaspline";
15
+ interface LineAreaSeries {
16
+ name: string;
17
+ /**
18
+ * Y-values indexed parallel to `xAxis.categories` on a category axis, or
19
+ * `[timestamp, value]` / `{ x, y }` points on a datetime axis.
20
+ */
21
+ data: Array<ChartDataPoint>;
22
+ color?: string;
23
+ /** Seeds icon or partner-logo name rendered before the series name in the legend. */
24
+ icon?: TypeIconName;
25
+ /** Line dash style. Applies to `line`/`spline` variants; a no-op on filled area variants. Default `"solid"`. */
26
+ pattern?: TypeChartStylePattern;
27
+ }
28
+ type LineAreaXAxis = CategoryAxis | DatetimeAxis;
29
+ interface LineAreaYAxis {
30
+ min?: number;
31
+ max?: number;
32
+ /** Default: true. */
33
+ showGridLines?: boolean;
34
+ title?: string;
35
+ /**
36
+ * Declarative value formatting applied to y-axis tick labels. Omit for the
37
+ * zero-config decimal default (smart 1k/10k abbreviation).
38
+ */
39
+ format?: ValueFormat;
40
+ }
41
+ interface LineAreaChartProps {
42
+ /** Wired into Highcharts' `accessibility.description`. */
43
+ description: string;
44
+ /** Applied to the chart's container element — e.g. Tailwind utility classes for sizing or spacing. */
45
+ className?: string;
46
+ /** Chart variant: `line` | `spline` | `area` | `areaspline`. */
47
+ variant: LineAreaVariant;
48
+ series: Array<LineAreaSeries>;
49
+ xAxis: LineAreaXAxis;
50
+ yAxis?: LineAreaYAxis;
51
+ /** IANA timezone for datetime-axis ticks and tooltips. Default `"UTC"`. Ignored for category axes. */
52
+ timezone?: string;
53
+ /**
54
+ * Stacking for multi-series charts. `"normal"` stacks values; `"percent"`
55
+ * normalizes each point to 100%. Honored only on `area`/`areaspline` variants
56
+ * (a `stacked-area` chart); ignored on `line`/`spline`. Unstacked when omitted.
57
+ */
58
+ stacking?: "normal" | "percent";
59
+ /** Appended to each tooltip value (e.g., `"%"`). */
60
+ valueSuffix?: string;
61
+ /** Override for the default tooltip content. */
62
+ tooltip?: (args: ChartTooltipProps) => ReactNode;
63
+ /** Declarative annotations rendered at positions on the chart. */
64
+ annotations?: ChartAnnotation[];
65
+ /** Click handler invoked with the x-axis value of the clicked point — the category name on a category axis, the numeric timestamp on a datetime axis. */
66
+ onClick?: ({ position }: {
67
+ position: number | string;
68
+ }) => void;
69
+ /** Footer content shown in the default tooltip when `onClick` is set. */
70
+ tooltipClickLabel?: ReactNode;
71
+ /** Override for the value shown when a data point is invalid/missing (null). Defaults to an em-dash. */
72
+ invalidNumberLabel?: ReactNode;
73
+ /**
74
+ * Fired once per chart instance with an opaque {@link ChartExportHandle} for
75
+ * triggering PNG/SVG/PDF/CSV downloads. Re-fires only on a genuine remount,
76
+ * never on data or prop updates.
77
+ */
78
+ onReady?: (handle: ChartExportHandle) => void;
79
+ }
80
+
81
+ declare const LineAreaChart: react.NamedExoticComponent<LineAreaChartProps>;
82
+
83
+ export { CategoryAxis, ChartExportHandle, DatetimeAxis, LineAreaChart, type LineAreaChartProps, type LineAreaSeries, type LineAreaVariant, type LineAreaXAxis, type LineAreaYAxis };
@@ -0,0 +1,151 @@
1
+ "use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } } function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; }
2
+
3
+
4
+
5
+
6
+
7
+
8
+
9
+
10
+ var _chunkVSZSIN34js = require('../chunk-VSZSIN34.js');
11
+
12
+
13
+
14
+ var _chunkEEVKTTT3js = require('../chunk-EEVKTTT3.js');
15
+
16
+ // src/charts/line-area/LineAreaChart.tsx
17
+ var _react = require('react');
18
+
19
+ // src/charts/line-area/adapter.ts
20
+ var AREA_VARIANTS = /* @__PURE__ */ new Set(["area", "areaspline"]);
21
+ function pointY(point) {
22
+ if (point === null) return null;
23
+ if (typeof point === "number") return point;
24
+ if (Array.isArray(point)) return point[1];
25
+ return point.y;
26
+ }
27
+ function withIsolatedPointMarkers(data) {
28
+ return data.map((point, i) => {
29
+ if (point === null) return null;
30
+ if (pointY(point) === null) return point;
31
+ const prevY = i === 0 ? null : pointY(data[i - 1]);
32
+ const nextY = i === data.length - 1 ? null : pointY(data[i + 1]);
33
+ if (prevY !== null || nextY !== null) return point;
34
+ const marker = { enabled: true, symbol: "circle" };
35
+ if (typeof point === "number") return { y: point, marker };
36
+ if (Array.isArray(point)) return { x: point[0], y: point[1], marker };
37
+ return { ...point, marker };
38
+ });
39
+ }
40
+ function buildLineAreaChartOptions(props) {
41
+ const tooltipTimezone = _chunkVSZSIN34js.resolveTooltipTimezone.call(void 0, props.xAxis, props.timezone);
42
+ const isStacked = AREA_VARIANTS.has(props.variant) && Boolean(props.stacking);
43
+ const { annotations, lookup: annotationLookup } = _chunkVSZSIN34js.buildAnnotationConfig.call(void 0,
44
+ props.annotations
45
+ );
46
+ const options = {
47
+ ..._chunkVSZSIN34js.buildBaseChartOptions.call(void 0, {
48
+ type: props.variant,
49
+ description: props.description,
50
+ valueSuffix: props.valueSuffix,
51
+ reserveTopMargin: Boolean(annotations),
52
+ timezone: tooltipTimezone
53
+ }),
54
+ xAxis: _chunkVSZSIN34js.buildDimensionalAxis.call(void 0, props.xAxis, _nullishCoalesce(tooltipTimezone, () => ( "UTC"))),
55
+ yAxis: {
56
+ min: _optionalChain([props, 'access', _ => _.yAxis, 'optionalAccess', _2 => _2.min]),
57
+ max: _optionalChain([props, 'access', _3 => _3.yAxis, 'optionalAccess', _4 => _4.max]),
58
+ // Anchor the value axis to 0 (like v1/bar/area): line/spline otherwise
59
+ // auto-scale above 0, which truncates the axis and pushes the annotation
60
+ // anchor (y: 0) out of range. `soft` still extends for negative data.
61
+ softMin: 0,
62
+ softMax: 0,
63
+ gridLineWidth: _optionalChain([props, 'access', _5 => _5.yAxis, 'optionalAccess', _6 => _6.showGridLines]) === false ? 0 : 1,
64
+ title: { text: _nullishCoalesce(_optionalChain([props, 'access', _7 => _7.yAxis, 'optionalAccess', _8 => _8.title]), () => ( "")) },
65
+ // Zero-config default: abbreviate value-axis ticks (1.20K / 1.20M / 1.20B).
66
+ labels: {
67
+ // A declarative `format` drives ticks through the shared valueFormatter;
68
+ // absent it, the zero-config decimal default (1.20K / 1.20M / 1.20B).
69
+ formatter: _optionalChain([props, 'access', _9 => _9.yAxis, 'optionalAccess', _10 => _10.format]) ? _chunkVSZSIN34js.makeValueAxisLabelFormatter.call(void 0, props.yAxis.format) : _chunkVSZSIN34js.defaultValueAxisLabelFormatter
70
+ }
71
+ },
72
+ plotOptions: {
73
+ series: {
74
+ animation: false,
75
+ // Hide point markers by default (matching v1 + designs); isolated points
76
+ // re-enable their own marker via `withIsolatedPointMarkers`.
77
+ marker: { enabled: false },
78
+ ...props.onClick ? {
79
+ point: {
80
+ events: {
81
+ click: (event) => props.onClick({ position: event.point.x })
82
+ }
83
+ }
84
+ } : {}
85
+ },
86
+ // Type-scoped stacking: only the (area) variant stacks. `isStacked` already
87
+ // guarantees `props.variant` is an area variant here, so the computed key is
88
+ // always a valid plotOptions slot. Matches bar's per-type placement and keeps
89
+ // line/spline unstacked.
90
+ ...isStacked ? { [props.variant]: { stacking: props.stacking } } : {}
91
+ },
92
+ series: props.series.map((s) => ({
93
+ type: props.variant,
94
+ name: s.name,
95
+ data: withIsolatedPointMarkers(s.data)
96
+ })),
97
+ ...annotations ? { annotations } : {}
98
+ };
99
+ return { options, annotationLookup, tooltipTimezone };
100
+ }
101
+
102
+ // src/charts/line-area/styles.ts
103
+ var _styledcomponents = require('styled-components'); var _styledcomponents2 = _interopRequireDefault(_styledcomponents);
104
+ var LineAreaChartContainer = _styledcomponents2.default.div`
105
+ background-color: ${({ theme }) => theme.colors.container.background.base};
106
+ ${(props) => props.$isArea ? _chunkEEVKTTT3js.areaChartStyles : _chunkEEVKTTT3js.lineChartStyles}
107
+ `;
108
+
109
+ // src/charts/line-area/LineAreaChart.tsx
110
+ var _jsxruntime = require('react/jsx-runtime');
111
+ var AREA_VARIANTS2 = /* @__PURE__ */ new Set(["area", "areaspline"]);
112
+ var LineAreaChart = _react.memo.call(void 0, function LineAreaChart2(props) {
113
+ const { colors, patterns } = _chunkVSZSIN34js.useSeedsChartSetup.call(void 0, {
114
+ series: props.series,
115
+ includePatterns: true
116
+ });
117
+ const { options, annotationLookup, tooltipTimezone } = _react.useMemo.call(void 0,
118
+ () => buildLineAreaChartOptions(props),
119
+ [props]
120
+ );
121
+ const hasOnClick = Boolean(props.onClick);
122
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
123
+ LineAreaChartContainer,
124
+ {
125
+ $colors: colors,
126
+ $patterns: patterns,
127
+ $hasOnClick: hasOnClick,
128
+ $isArea: AREA_VARIANTS2.has(props.variant),
129
+ className: props.className,
130
+ children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
131
+ _chunkVSZSIN34js.ChartRenderer,
132
+ {
133
+ options,
134
+ series: props.series,
135
+ colors,
136
+ tooltip: props.tooltip,
137
+ annotationLookup,
138
+ hasOnClick,
139
+ tooltipClickLabel: props.tooltipClickLabel,
140
+ timezone: tooltipTimezone,
141
+ invalidNumberLabel: props.invalidNumberLabel,
142
+ onReady: props.onReady
143
+ }
144
+ )
145
+ }
146
+ );
147
+ });
148
+
149
+
150
+ exports.LineAreaChart = LineAreaChart;
151
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["/home/runner/_work/seeds/seeds/seeds-react/seeds-react-data-viz/dist/line-area/index.js","../../src/charts/line-area/LineAreaChart.tsx","../../src/charts/line-area/adapter.ts","../../src/charts/line-area/styles.ts"],"names":["AREA_VARIANTS","LineAreaChart"],"mappings":"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","file":"/home/runner/_work/seeds/seeds/seeds-react/seeds-react-data-viz/dist/line-area/index.js","sourcesContent":[null,"import { memo, useMemo } from \"react\";\nimport { useSeedsChartSetup, ChartRenderer } from \"../shared/chartBase\";\nimport { buildLineAreaChartOptions } from \"./adapter\";\nimport { LineAreaChartContainer } from \"./styles\";\nimport type { LineAreaChartProps, LineAreaVariant } from \"./types\";\n\nconst AREA_VARIANTS = new Set<LineAreaVariant>([\"area\", \"areaspline\"]);\n\nexport const LineAreaChart = memo(function LineAreaChart(\n props: LineAreaChartProps\n) {\n const { colors, patterns } = useSeedsChartSetup({\n series: props.series,\n includePatterns: true,\n });\n const { options, annotationLookup, tooltipTimezone } = useMemo(\n () => buildLineAreaChartOptions(props),\n [props]\n );\n const hasOnClick = Boolean(props.onClick);\n\n return (\n <LineAreaChartContainer\n $colors={colors}\n $patterns={patterns}\n $hasOnClick={hasOnClick}\n $isArea={AREA_VARIANTS.has(props.variant)}\n className={props.className}\n >\n <ChartRenderer\n options={options}\n series={props.series}\n colors={colors}\n tooltip={props.tooltip}\n annotationLookup={annotationLookup}\n hasOnClick={hasOnClick}\n tooltipClickLabel={props.tooltipClickLabel}\n timezone={tooltipTimezone}\n invalidNumberLabel={props.invalidNumberLabel}\n onReady={props.onReady}\n />\n </LineAreaChartContainer>\n );\n});\n","import { buildAnnotationConfig } from \"../shared/annotations\";\nimport type { ChartAnnotationLookup } from \"../shared/annotations\";\nimport type {\n SeedsChartDataPoint,\n SeedsChartOptions,\n} from \"../shared/chartBase\";\nimport { buildBaseChartOptions } from \"../shared/baseChartOptions\";\nimport {\n buildDimensionalAxis,\n resolveTooltipTimezone,\n} from \"../shared/axisOptions\";\nimport {\n defaultValueAxisLabelFormatter,\n makeValueAxisLabelFormatter,\n} from \"../shared/valueAxisLabelFormatter\";\nimport type { ChartDataPoint } from \"../shared/axis\";\nimport type { LineAreaChartProps, LineAreaVariant } from \"./types\";\n\n// `stacking` is meaningful only for filled variants; on `line`/`spline` it's a\n// no-op, so the adapter drops it rather than emitting a misleading option.\nconst AREA_VARIANTS = new Set<LineAreaVariant>([\"area\", \"areaspline\"]);\n\ntype SeriesPoint =\n | number\n | null\n | [number, number | null]\n | SeedsChartDataPoint;\n\nfunction pointY(point: ChartDataPoint): number | null {\n if (point === null) return null;\n if (typeof point === \"number\") return point;\n if (Array.isArray(point)) return point[1];\n return point.y;\n}\n\n// Mirrors v1's marker handling: point markers are hidden by default (set on\n// `plotOptions.series`), but an *isolated* non-null point — one with a null (or\n// the chart edge) on both sides — gets a circle marker so a point with no\n// connecting line segment stays visible. Connected points pass through\n// unchanged so the line/area renders dot-free, matching v1 and the designs.\nfunction withIsolatedPointMarkers(\n data: ReadonlyArray<ChartDataPoint>\n): SeriesPoint[] {\n return data.map((point, i): SeriesPoint => {\n if (point === null) return null; // explicit gap\n if (pointY(point) === null) return point; // tuple/object with null y — a gap\n const prevY = i === 0 ? null : pointY(data[i - 1]!);\n const nextY = i === data.length - 1 ? null : pointY(data[i + 1]!);\n if (prevY !== null || nextY !== null) return point; // connected → no marker\n const marker = { enabled: true, symbol: \"circle\" as const };\n if (typeof point === \"number\") return { y: point, marker };\n if (Array.isArray(point)) return { x: point[0], y: point[1], marker };\n return { ...point, marker };\n });\n}\n\nexport function buildLineAreaChartOptions(props: LineAreaChartProps): {\n options: SeedsChartOptions;\n annotationLookup: ChartAnnotationLookup | undefined;\n /** Resolved timezone for the tooltip date formatter; undefined on category axes. */\n tooltipTimezone: string | undefined;\n} {\n const tooltipTimezone = resolveTooltipTimezone(props.xAxis, props.timezone);\n const isStacked = AREA_VARIANTS.has(props.variant) && Boolean(props.stacking);\n const { annotations, lookup: annotationLookup } = buildAnnotationConfig(\n props.annotations\n );\n\n const options: SeedsChartOptions = {\n ...buildBaseChartOptions({\n type: props.variant,\n description: props.description,\n valueSuffix: props.valueSuffix,\n reserveTopMargin: Boolean(annotations),\n timezone: tooltipTimezone,\n }),\n xAxis: buildDimensionalAxis(props.xAxis, tooltipTimezone ?? \"UTC\"),\n yAxis: {\n min: props.yAxis?.min,\n max: props.yAxis?.max,\n // Anchor the value axis to 0 (like v1/bar/area): line/spline otherwise\n // auto-scale above 0, which truncates the axis and pushes the annotation\n // anchor (y: 0) out of range. `soft` still extends for negative data.\n softMin: 0,\n softMax: 0,\n gridLineWidth: props.yAxis?.showGridLines === false ? 0 : 1,\n title: { text: props.yAxis?.title ?? \"\" },\n // Zero-config default: abbreviate value-axis ticks (1.20K / 1.20M / 1.20B).\n labels: {\n // A declarative `format` drives ticks through the shared valueFormatter;\n // absent it, the zero-config decimal default (1.20K / 1.20M / 1.20B).\n formatter: props.yAxis?.format\n ? makeValueAxisLabelFormatter(props.yAxis.format)\n : defaultValueAxisLabelFormatter,\n },\n },\n plotOptions: {\n series: {\n animation: false,\n // Hide point markers by default (matching v1 + designs); isolated points\n // re-enable their own marker via `withIsolatedPointMarkers`.\n marker: { enabled: false },\n ...(props.onClick\n ? {\n point: {\n events: {\n click: (event) => props.onClick!({ position: event.point.x }),\n },\n },\n }\n : {}),\n },\n // Type-scoped stacking: only the (area) variant stacks. `isStacked` already\n // guarantees `props.variant` is an area variant here, so the computed key is\n // always a valid plotOptions slot. Matches bar's per-type placement and keeps\n // line/spline unstacked.\n ...(isStacked ? { [props.variant]: { stacking: props.stacking } } : {}),\n },\n series: props.series.map((s) => ({\n type: props.variant,\n name: s.name,\n data: withIsolatedPointMarkers(s.data),\n })),\n ...(annotations ? { annotations } : {}),\n };\n\n return { options, annotationLookup, tooltipTimezone };\n}\n","import styled from \"styled-components\";\nimport { lineChartStyles, areaChartStyles } from \"../../styles/chartStyles\";\nimport type {\n TypeChartStyleColor,\n TypeChartStyleHasOnClick,\n TypeChartStylePattern,\n} from \"../../types\";\n\ntype StyleProps = Readonly<{\n $colors: ReadonlyArray<TypeChartStyleColor>;\n $patterns: ReadonlyArray<TypeChartStylePattern>;\n $hasOnClick: TypeChartStyleHasOnClick;\n /** `area`/`areaspline` fill below the line; `line`/`spline` show only the stroke. */\n $isArea: boolean;\n}>;\n\n// Plain styled `div` — not `Box`. Per the DS Tailwind direction, components\n// render semantic elements internally (and accept `className`) rather than\n// depending on the `Box` component. The container background — previously Box's\n// `bg` prop — is set explicitly here.\n//\n// The line/area CSS is still v1's styled-components layer (`chartStyles.ts`);\n// migrating those styles to CSS modules is a tracked clean-up follow-up.\nexport const LineAreaChartContainer = styled.div<StyleProps>`\n background-color: ${({ theme }) => theme.colors.container.background.base};\n ${(props) => (props.$isArea ? areaChartStyles : lineChartStyles)}\n`;\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sproutsocial/seeds-react-data-viz",
3
- "version": "0.14.0",
3
+ "version": "0.15.0",
4
4
  "description": "Seeds React Data Viz Components",
5
5
  "author": "Sprout Social, Inc.",
6
6
  "license": "MIT",
@@ -18,6 +18,11 @@
18
18
  "import": "./dist/esm/bar/index.js",
19
19
  "require": "./dist/bar/index.js"
20
20
  },
21
+ "./line-area": {
22
+ "types": "./dist/line-area/index.d.ts",
23
+ "import": "./dist/esm/line-area/index.js",
24
+ "require": "./dist/line-area/index.js"
25
+ },
21
26
  "./export": {
22
27
  "types": "./dist/export/index.d.ts",
23
28
  "import": "./dist/esm/export/index.js",
@@ -1 +0,0 @@
1
- {"version":3,"sources":["/home/runner/_work/seeds/seeds/seeds-react/seeds-react-data-viz/dist/chunk-VFBZ7FNK.js","../src/components/ColorBox/ColorBox.tsx","../../seeds-react-theme-provider/src/index.tsx","../src/components/ColorBox/DatavizColorBox.tsx","../src/components/ColorBox/NetworkColorBox.tsx","../src/components/ChartLegend/components/ChartLegendLabel.tsx","../src/components/ChartLegend/ChartLegend.tsx","../src/components/ChartTooltip/ChartTooltip.tsx","../src/components/ChartTooltip/components/ChartTooltipFooter.tsx","../src/components/ChartTooltip/components/ChartTooltipHeader.tsx","../src/components/ChartTooltip/components/ChartTooltipPortal.tsx","../src/components/ChartTable/ChartTable.tsx","../src/components/ChartTooltip/components/ChartTooltipTable.tsx","../src/components/ChartTooltip/components/ChartTooltipTitle.tsx","../src/helpers/transformDataToSeries.ts","../src/helpers/transformTimeSeriesTooltipData.ts","../src/helpers/yAxisLabelFormatter.ts","../src/helpers/xAxisLabelFormatter.ts","../src/helpers/isHourlyTimeData.ts","../src/helpers/isCategoricalHourData.ts","../src/helpers/getStorybookRandomColor.ts","../src/helpers/getStorybookCategoricalData.ts","../src/helpers/getStorybookSparseTimelineData.ts","../src/constants/chartOptions.ts","../src/styles/chartStyles.ts","../src/components/ChartLegend/components/ChartLegendLabelContentWithIcon.tsx","../src/components/VerticalBarChart/styles.ts"],"names":["jsx","props"],"mappings":"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","file":"/home/runner/_work/seeds/seeds/seeds-react/seeds-react-data-viz/dist/chunk-VFBZ7FNK.js","sourcesContent":[null,"import { css, type CSSProp } from \"styled-components\";\nimport { Box, type TypeBoxProps } from \"@sproutsocial/seeds-react-box\";\nimport ThemeProvider from \"@sproutsocial/seeds-react-theme-provider\";\nimport { type TypeSproutTheme } from \"@sproutsocial/seeds-react-theme\";\n\nexport type TypeColorBoxProps = TypeBoxProps;\n\n/**\n * ColorBox extends Box to apply basic styles.\n */\nexport const ColorBox = ({\n display = \"inline-block\",\n height = \"16px\",\n width = \"16px\",\n minWidth = width,\n borderRadius = \"400\",\n ...props\n}: TypeColorBoxProps) => {\n return (\n <Box\n {...props}\n display={display}\n height={height}\n width={width}\n minWidth={minWidth}\n borderRadius={borderRadius}\n css={\n css`\n cursor: ${(\n props: typeof ThemeProvider & {\n onClick: ((e: React.MouseEvent<HTMLElement>) => void) | void;\n }\n ) => (props?.onClick ? \"pointer\" : \"default\")};\n ` as CSSProp<TypeSproutTheme>\n }\n />\n );\n};\n","import * as React from \"react\";\nimport {\n ThemeProvider as BaseThemeProvider,\n createGlobalStyle,\n} from \"styled-components\";\nimport { theme } from \"@sproutsocial/seeds-react-theme\";\nimport type {\n TypeSproutTheme,\n TypeTheme,\n} from \"@sproutsocial/seeds-react-theme\";\n\n// We can append additional themes types here\ntype TypeAllThemes = TypeTheme | TypeSproutTheme;\n\ntype TypeProps = {\n readonly theme?: TypeAllThemes;\n readonly children?: React.ReactNode;\n};\n\n// CSS custom properties for token values that cannot be represented in SCSS maps\n// (e.g. radial-gradient + color-mix). These are injected here so styled-components\n// consumers get the values without needing to load the compiled SCSS theme CSS.\nconst GlobalTokenStyles = createGlobalStyle`\n :root {\n --color-container-bg-ai-generated: radial-gradient(\n circle at bottom left,\n color-mix(in srgb, #205bc3, transparent 80%) 0%,\n color-mix(in srgb, #6f5ed3, transparent 80%) 61%,\n color-mix(in srgb, #f282f5, transparent 80%) 100%\n ), #f3f4f4;\n }\n`;\n\nconst ThemeProvider = (props: TypeProps) => (\n <BaseThemeProvider {...props} theme={props.theme || theme}>\n <GlobalTokenStyles />\n {props.children}\n </BaseThemeProvider>\n);\n\nexport default ThemeProvider;\n","import type * as React from \"react\";\nimport styled from \"styled-components\";\nimport { theme } from \"@sproutsocial/seeds-react-theme\";\nimport { ColorBox, type TypeColorBoxProps } from \"./ColorBox\";\n\nexport type TypeDatavizColorBoxProps = Readonly<\n Partial<TypeColorBoxProps> & {\n colorIndex: number;\n }\n>;\nexport type TypeDatavizColorBox = (\n props: TypeDatavizColorBoxProps\n) => React.JSXElementConstructor<TypeDatavizColorBoxProps>;\n\n/**\n * DatavizColorBox extends ColorBox to set the background color from a rotation of <a href=\"https://seeds.sproutsocial.com/visual/dataviz#color-combinations-for-general-sprout-social-data-visualizations\">dataviz colors</a>.\n */\nexport const DatavizColorBox = styled(ColorBox).attrs(\n ({ colorIndex }: TypeDatavizColorBoxProps) => ({\n style: {\n background: getDatavizColor(colorIndex),\n opacity: getDatavizOpacity(colorIndex),\n },\n })\n)<TypeDatavizColorBoxProps>``;\n\nexport const getDatavizColor = (colorIndex: number): string =>\n theme.colors.DATAVIZ_COLORS_LIST[\n colorIndex % theme.colors.DATAVIZ_COLORS_LIST.length\n ] || \"\";\n\nexport const getDatavizOpacity = (colorIndex: number): number => {\n const opacitySteps = [1, 0.6, 0.4, 0.2];\n const opacityStep =\n Math.floor(colorIndex / theme.colors.DATAVIZ_COLORS_LIST.length) %\n opacitySteps.length;\n // @ts-ignore\n return opacitySteps[opacityStep];\n};\n\n// information on 8 digit hex codes can be found here: https://css-tricks.com/8-digit-hex-codes/\nexport const getDatavizColorWithAlpha = (colorIndex: number): string => {\n const color = getDatavizColor(colorIndex);\n const opacity = getDatavizOpacity(colorIndex);\n\n // make sure the opacity is always between 0 and 1\n if (opacity < 0 || opacity > 1) {\n return color;\n }\n\n // sourced from https://stackoverflow.com/a/66143374\n return `${color}${Math.floor(opacity * 255)\n .toString(16)\n .padStart(2, \"0\")}`;\n};\n","import NETWORK_COLORS from \"@sproutsocial/seeds-networkcolor\";\n\nimport { ColorBox, type TypeColorBoxProps } from \"./ColorBox\";\n\n// $Keys<typeof NETWORK_COLORS>\ntype TypeNetworkColor =\n | \"NETWORK_COLOR_TWITTER\"\n | \"NETWORK_COLOR_TWITTER_LIKE\"\n | \"NETWORK_COLOR_FACEBOOK\"\n | \"NETWORK_COLOR_FACEBOOK_AUDIENCE_NETWORK\"\n | \"NETWORK_COLOR_LINKEDIN\"\n | \"NETWORK_COLOR_INSTAGRAM\"\n | \"NETWORK_COLOR_FEEDLY\"\n | \"NETWORK_COLOR_ANALYTICS\"\n | \"NETWORK_COLOR_YOUTUBE\"\n | \"NETWORK_COLOR_MESSENGER\"\n | \"NETWORK_COLOR_SNAPCHAT\"\n | \"NETWORK_COLOR_PINTEREST\"\n | \"NETWORK_COLOR_REDDIT\"\n | \"NETWORK_COLOR_TUMBLR\"\n | \"NETWORK_COLOR_GOOGLE_MY_BUSINESS\"\n | \"NETWORK_COLOR_TIKTOK\"\n | \"NETWORK_COLOR_TRIPADVISOR\"\n | \"NETWORK_COLOR_GLASSDOOR\"\n | \"NETWORK_COLOR_SALESFORCE\"\n | \"NETWORK_COLOR_ZENDESK\"\n | \"NETWORK_COLOR_HUBSPOT\"\n | \"NETWORK_COLOR_MICROSOFT_DYNAMICS\";\n\ntype TypeNetworkColorBoxProps = Readonly<\n TypeColorBoxProps & {\n networkColor: TypeNetworkColor;\n }\n>;\n\n/**\n * NetworkColorBox extends ColorBox to set the background color to a <a href=\"https://seeds.sproutsocial.com/visual/color#full-color-palette\">network color</a>.\n */\nexport const NetworkColorBox = ({\n networkColor,\n ...props\n}: TypeNetworkColorBoxProps) => {\n return <ColorBox {...props} bg={NETWORK_COLORS[networkColor]} />;\n};\n","import styled from \"styled-components\";\nimport { memo } from \"react\";\nimport { Box, type TypeBoxProps } from \"@sproutsocial/seeds-react-box\";\nimport { Text } from \"@sproutsocial/seeds-react-text\";\n\nimport type { TypeLegendLabel } from \"../ChartLegend\";\n\nimport { ColorBox } from \"../../ColorBox\";\n\nconst StyledBox = styled(Box)<TypeBoxProps>`\n list-style: none;\n display: flex;\n align-items: center;\n gap: ${({ theme }) => theme.space[300]};\n`;\n\nexport type TypeChartLegendLabelProps = Readonly<{\n children: TypeLegendLabel[\"content\"];\n color: TypeLegendLabel[\"color\"];\n // optional\n containerBoxProps?: TypeBoxProps;\n}>;\n\nexport const ChartLegendLabel = memo<TypeChartLegendLabelProps>(\n function ChartLegendLabel({\n children,\n color = \"#CCC\",\n containerBoxProps = {},\n }: TypeChartLegendLabelProps) {\n return (\n <StyledBox {...containerBoxProps}>\n <ColorBox bg={color} />\n <Text as=\"div\" fontSize={200} color=\"text.subtext\">\n {children}\n </Text>\n </StyledBox>\n );\n }\n);\n","import { memo } from \"react\";\nimport { Box, type TypeBoxProps } from \"@sproutsocial/seeds-react-box\";\nimport { theme } from \"@sproutsocial/seeds-react-theme\";\n\nimport { ChartLegendLabel } from \"./components/ChartLegendLabel\";\n\nexport type TypeLegendLabel = Readonly<{\n content: React.ReactNode;\n color?: string;\n}>;\n\nexport type TypeChartLegendProps = Readonly<{\n legendLabels: ReadonlyArray<TypeLegendLabel>;\n // optional\n containerBoxProps?: TypeBoxProps;\n stacked?: boolean;\n}>;\n\nexport const ChartLegend = memo<TypeChartLegendProps>(function ChartLegend({\n legendLabels,\n containerBoxProps = {},\n stacked = false,\n}: TypeChartLegendProps) {\n return (\n <Box\n as=\"ul\"\n aria-hidden=\"true\"\n display=\"flex\"\n justifyContent=\"center\"\n flexDirection={stacked ? \"column\" : \"row\"}\n flexWrap=\"wrap\"\n columnGap={450}\n rowGap={200}\n m={0}\n p={0}\n {...containerBoxProps}\n >\n {legendLabels.map(({ color, content }, index) => (\n <ChartLegendLabel\n key={`chart-legend-label-${index}`}\n color={color || theme.colors.DATAVIZ_COLORS_LIST[index]}\n containerBoxProps={{ as: \"li\" }}\n >\n {content}\n </ChartLegendLabel>\n ))}\n </Box>\n );\n});\n","import { memo } from \"react\";\nimport styled from \"styled-components\";\nimport { Box } from \"@sproutsocial/seeds-react-box\";\n\n// styled components\nconst StyledBox = styled(Box)`\n .Icon,\n .logo {\n stroke: none;\n }\n`;\n\n// Chart Tooltip\ntype TypeChartTooltipProps = Readonly<{\n children: React.ReactNode;\n}>;\n\nexport const ChartTooltip = memo<TypeChartTooltipProps>(function ChartTooltip({\n children,\n}: TypeChartTooltipProps) {\n return (\n <StyledBox\n bg=\"container.background.base\"\n boxShadow=\"medium\"\n border={500}\n borderColor=\"container.border.base\"\n borderRadius={500}\n p={400}\n minWidth={285}\n >\n <Box display=\"flex\" flexDirection=\"column\" gap={350}>\n {children}\n </Box>\n </StyledBox>\n );\n});\n","import { memo } from \"react\";\nimport { Box } from \"@sproutsocial/seeds-react-box\";\n\ntype TypeChartTooltipFooterProps = {\n children: React.ReactNode;\n};\n\nexport const ChartTooltipFooter = memo<TypeChartTooltipFooterProps>(\n function ChartTooltipFooter({ children }: TypeChartTooltipFooterProps) {\n return (\n <Box\n borderTop={500}\n borderColor=\"container.border.base\"\n mx={-400}\n mb={-200}\n px={400}\n pt={350}\n >\n {children}\n </Box>\n );\n }\n);\n","import { memo } from \"react\";\nimport { Box } from \"@sproutsocial/seeds-react-box\";\n\ntype TypeChartTooltipHeaderProps = {\n children: React.ReactNode;\n};\n\nexport const ChartTooltipHeader = memo<TypeChartTooltipHeaderProps>(\n function ChartTooltipHeader({ children }: TypeChartTooltipHeaderProps) {\n return (\n <Box\n borderBottom={500}\n borderColor=\"container.border.base\"\n mx={-400}\n mt={-200}\n px={400}\n pb={350}\n >\n {children}\n </Box>\n );\n }\n);\n","import { memo, useState, useRef, useEffect, type ReactNode } from \"react\";\nimport { createPortal } from \"react-dom\";\nimport type {\n Tooltip,\n Chart,\n TooltipFormatterContextObject,\n TooltipFormatterCallbackFunction,\n} from \"highcharts\";\n\ninterface ExtendedHighchartsTooltip extends Tooltip {\n label: {\n box: { attr({ height, width }: { height: number; width: number }): void };\n text: { element: HTMLElement };\n };\n}\n\nexport const generateChartTooltipPortalId = (chartId: number) =>\n `highcharts-custom-tooltip-${chartId}`;\n\ntype ChartTooltipPortalProps = Readonly<{\n chart: Chart;\n renderContent: (context: TooltipFormatterContextObject) => ReactNode;\n}>;\n\nexport const ChartTooltipPortal = memo<ChartTooltipPortalProps>(\n function ChartTooltipPortal({\n chart,\n renderContent,\n }: ChartTooltipPortalProps) {\n const isInitialized = useRef<boolean>(false);\n const [node, setNode] = useState<HTMLElement | null>(null);\n const [context, setContext] =\n useState<TooltipFormatterContextObject | null>(null);\n\n useEffect(() => {\n const formatter: TooltipFormatterCallbackFunction = function () {\n // Ensures that tooltip DOM container is rendered before React portal is created.\n if (!isInitialized.current) {\n isInitialized.current = true;\n chart.tooltip.refresh.apply(chart.tooltip, [this.point]);\n chart.tooltip.hide(0);\n }\n\n setContext(this);\n\n return `<div id=\"${generateChartTooltipPortalId(\n chart.index\n )}\" role='tooltip'></div>`;\n };\n\n chart.update({ tooltip: { formatter } });\n }, [chart]);\n\n useEffect(() => {\n // In some cases tooltip is not available on the chart yet\n if (context?.series?.chart?.tooltip) {\n const tooltip = context.series.chart\n .tooltip as ExtendedHighchartsTooltip;\n const textElement = tooltip.label.text.element;\n\n tooltip.label.box.attr({\n height: textElement.offsetHeight,\n width: textElement.offsetWidth,\n });\n\n setNode(\n document.getElementById(generateChartTooltipPortalId(chart.index))\n );\n }\n }, [context, chart.index]);\n\n return node && context ? createPortal(renderContent(context), node) : null;\n }\n);\n","import { memo } from \"react\";\nimport styled from \"styled-components\";\nimport { Text } from \"@sproutsocial/seeds-react-text\";\nimport { Table as SeedsTable } from \"@sproutsocial/seeds-react-table\";\n\nconst StyledSeedsTable = styled<typeof SeedsTable>(SeedsTable)`\n tbody tr:last-child {\n border-bottom: none;\n }\n tr:last-child td,\n tr:last-child th {\n padding-bottom: 0;\n }\n tr:first-child td,\n tr:first-child th {\n padding-top: 0;\n }\n tr th {\n padding-left: 0;\n }\n tr td:last-child {\n padding-right: 0;\n }\n`;\n\nconst StyledSeedsTableRow = styled(SeedsTable.TableRow)<{\n $isAppendedRow?: boolean;\n}>`\n ${({ $isAppendedRow, theme }) =>\n $isAppendedRow\n ? `border-top: 2px solid ${theme.colors.container.border.base}`\n : \"\"}\n`;\n\nexport type TypeChartTableProps = Readonly<{\n rows: ReadonlyArray<{\n cells: ReadonlyArray<{\n content: React.ReactNode;\n align?: React.ComponentProps<typeof SeedsTable.Cell>[\"align\"];\n colSpan?: React.ComponentProps<typeof SeedsTable.Cell>[\"colSpan\"];\n }>;\n isAppendedRow?: boolean;\n }>;\n}>;\n\nexport const ChartTable = memo<TypeChartTableProps>(function ChartTable({\n rows,\n}: TypeChartTableProps) {\n if (!rows || rows.length === 0) {\n return null;\n }\n\n return (\n <StyledSeedsTable>\n <SeedsTable.TableBody>\n {rows.map(({ cells, isAppendedRow }, rowIndex) => {\n if (!cells || cells.length === 0) {\n return null;\n }\n\n return (\n <StyledSeedsTableRow\n key={`chart-tooltip-table-row-${rowIndex}`}\n $isAppendedRow={isAppendedRow}\n >\n {cells.map(\n ({ content, align = \"left\", colSpan = 1 }, cellIndex) => {\n const uniqueIdentifier = `chart-tooltip-table-cell-${cellIndex}`;\n return (\n <SeedsTable.Cell\n key={uniqueIdentifier}\n id={uniqueIdentifier}\n scope={cellIndex === 0 ? \"row\" : undefined}\n align={align}\n colSpan={colSpan}\n py={200}\n >\n <Text.SmallBodyCopy as=\"div\">\n {content}\n </Text.SmallBodyCopy>\n </SeedsTable.Cell>\n );\n }\n )}\n </StyledSeedsTableRow>\n );\n })}\n </SeedsTable.TableBody>\n </StyledSeedsTable>\n );\n});\n","import { memo } from \"react\";\n\nimport { ChartTable, type TypeChartTableProps } from \"../../ChartTable\";\n\nexport type TypeChartTooltipTableProps = {\n rows: TypeChartTableProps[\"rows\"];\n};\n\nexport const ChartTooltipTable = memo<TypeChartTooltipTableProps>(\n function ChartTooltipTable({ rows }: TypeChartTooltipTableProps) {\n return <ChartTable rows={rows} />;\n }\n);\n","import { memo } from \"react\";\nimport { Text } from \"@sproutsocial/seeds-react-text\";\n\ntype TypeChartTooltipTitleProps = {\n children: React.ReactNode;\n};\n\nexport const ChartTooltipTitle = memo<TypeChartTooltipTitleProps>(\n function ChartTooltipTitle({ children }: TypeChartTooltipTitleProps) {\n return <Text.SmallSubHeadline as=\"p\">{children}</Text.SmallSubHeadline>;\n }\n);\n","import type {\n SeriesSplineOptions,\n SeriesAreasplineOptions,\n SeriesColumnOptions,\n} from \"highcharts\";\n\nimport type { TypeAreaChartProps } from \"../components/AreaChart\";\nimport type { TypeLineChartProps } from \"../components/LineChart\";\nimport type { TypeVerticalBarChartProps, TypeSeriesType } from \"../types\";\n\ntype TypeTimeSeriesOptions =\n | SeriesSplineOptions\n | SeriesAreasplineOptions\n | SeriesColumnOptions;\n\n// returns a transformed set of data to series with some logic for handling null values\nexport const transformDataToSeries = (\n {\n data,\n }: {\n data:\n | TypeAreaChartProps[\"data\"]\n | TypeLineChartProps[\"data\"]\n | TypeVerticalBarChartProps[\"data\"];\n },\n type: TypeSeriesType\n): TypeTimeSeriesOptions[] => {\n // Check if we have categorical data (string x values)\n const hasCategoricalData = data.some((series) =>\n series.points.some((point) => typeof point.x === \"string\")\n );\n\n return data.map((dataItem, dataIndex) => {\n const points = dataItem.points || [];\n const dataPoints = points.map((point, pointsIndex) => {\n let enableMarker = false;\n const isFirstPoint = pointsIndex === 0;\n const isLastPoint = pointsIndex === points.length - 1;\n\n // @ts-ignore\n const previousY = isFirstPoint ? null : points[pointsIndex - 1].y;\n // @ts-ignore\n const nextY = isLastPoint ? null : points[pointsIndex + 1].y;\n\n if (isFirstPoint && nextY === null) {\n // if the first point has data and the second point is null, show a marker for the first point\n enableMarker = true;\n } else if (isLastPoint && previousY === null) {\n // if the last point has data and the second to last point is null, show a marker for the last point\n enableMarker = true;\n } else if (previousY === null && nextY === null) {\n // if the a point has null values on both sides, show a marker\n enableMarker = true;\n }\n\n return {\n x: hasCategoricalData ? pointsIndex : point.x,\n y: point.y,\n marker: {\n enabled: enableMarker ? enableMarker : undefined,\n symbol: enableMarker ? \"circle\" : undefined,\n },\n // For categorical data, store the original category name\n ...(hasCategoricalData && { name: point.x }),\n };\n });\n\n return {\n colorIndex: dataIndex,\n data: dataPoints as TypeTimeSeriesOptions[\"data\"],\n name: dataItem.name as TypeTimeSeriesOptions[\"name\"],\n type: type,\n };\n });\n};\n","import type { TooltipFormatterContextObject } from \"highcharts\";\nimport { theme } from \"@sproutsocial/seeds-react-theme\";\n\nimport type { TypeAreaChartProps } from \"../components/AreaChart\";\nimport type { TypeLineChartProps } from \"../components/LineChart\";\nimport type { TypeChartTooltipProps } from \"../types\";\n\ntype TypeTransformTimeSeriesTooltipDataProps = Readonly<{\n context: TooltipFormatterContextObject;\n data: TypeAreaChartProps[\"data\"] | TypeLineChartProps[\"data\"];\n}>;\ntype TypeTransformTimeSeriesTooltipDataReturn = TypeChartTooltipProps[\"data\"];\n\nexport const transformTimeSeriesTooltipData = ({\n context,\n data,\n}: TypeTransformTimeSeriesTooltipDataProps): TypeTransformTimeSeriesTooltipDataReturn => {\n // @ts-ignore\n return (context.series.chart.series || []).map((series, index) => {\n const pointIndex = context.point.index;\n const y = series?.points?.[pointIndex]?.y;\n\n return {\n color:\n data[index]?.styles?.color || theme.colors.DATAVIZ_COLORS_LIST[index],\n ...(data[index]?.icon ? { icon: data[index]?.icon } : {}),\n name: series.name,\n value: typeof y === \"number\" ? y : null,\n };\n });\n};\n","import type {\n AxisLabelsFormatterContextObject,\n AxisTickPositionsArray,\n} from \"highcharts\";\nimport { formatDuration } from \"@sproutsocial/seeds-react-duration\";\nimport { formatNumeral } from \"@sproutsocial/seeds-react-numeral\";\n\nimport type { TypeChartNumberFormat } from \"../types\";\n\ntype TypeYAxisLabelFormatterProps = Readonly<{\n numberLocale: Intl.LocalesArgument;\n textLocale: Intl.LocalesArgument;\n tickPositions: AxisTickPositionsArray;\n value: AxisLabelsFormatterContextObject[\"value\"];\n // optional\n currency?: string;\n numberFormat?: TypeChartNumberFormat;\n}>;\n\nexport const yAxisLabelFormatter = ({\n numberLocale,\n textLocale,\n tickPositions,\n value,\n currency = \"USD\",\n numberFormat = \"decimal\",\n}: TypeYAxisLabelFormatterProps): string => {\n const numberValue = Number(value);\n\n if (numberValue === 0) {\n return formatNumeral({\n locale: numberLocale as string,\n number: numberValue,\n });\n }\n\n if (numberFormat === \"duration\") {\n return formatDuration({\n display: \"narrow\",\n locale: textLocale,\n milliseconds: numberValue,\n });\n }\n\n // Seeds formatNumeral helper starts abbreviating numbers above 10,000. this maxValue logic\n // helps bring that threshold down to 1,000 if the last tick on the y axis is greater than 9,999\n // so we render \"2k 4k 6k 8k 10k\" instead of \"2,000 4,000 6,000 8,000 10k\"\n const maxValue =\n tickPositions && tickPositions.length > 0\n ? tickPositions[tickPositions.length - 1]\n : undefined;\n const abbreviate =\n typeof maxValue === \"number\" && maxValue > 9999 ? 1000 : true;\n\n return formatNumeral({\n abbreviate,\n currency,\n format: numberFormat,\n locale: numberLocale as string,\n number: numberValue,\n });\n};\n","import type {\n AxisLabelsFormatterContextObject,\n AxisTickPositionsArray,\n} from \"highcharts\";\n\nimport type {\n ExtendedTimeTicksInfoObject,\n TypeChartTimeFormat,\n} from \"../types\";\n\nconst getDatePartsInTimezone = (date: Date, timezone: string) => {\n const formatter = new Intl.DateTimeFormat(\"en-US\", {\n year: \"numeric\",\n month: \"numeric\",\n day: \"numeric\",\n timeZone: timezone,\n });\n const parts = formatter.formatToParts(date);\n return {\n day: parseInt(parts.find((p) => p.type === \"day\")?.value ?? \"0\", 10),\n month: parseInt(parts.find((p) => p.type === \"month\")?.value ?? \"0\", 10),\n year: parseInt(parts.find((p) => p.type === \"year\")?.value ?? \"0\", 10),\n };\n};\n\ntype TypeXAxisLabelFormatterProps = Readonly<{\n textLocale: Intl.LocalesArgument;\n tickPositions: AxisTickPositionsArray;\n unitName: ExtendedTimeTicksInfoObject[\"unitName\"];\n value: AxisLabelsFormatterContextObject[\"value\"];\n // optional\n timeFormat?: TypeChartTimeFormat;\n timezone?: string;\n}>;\n\nexport const xAxisLabelFormatter = ({\n textLocale,\n tickPositions = [],\n unitName,\n value,\n // optional\n timeFormat = \"12\",\n timezone = \"UTC\",\n}: TypeXAxisLabelFormatterProps): string => {\n // Handle categorical (string) data\n if (typeof value === \"string\") {\n return `<span>${value}</span>`;\n }\n const tickIndex = tickPositions.indexOf(value as number);\n const isFirst = tickIndex === 0;\n const previousValue = tickPositions[tickIndex - 1];\n\n const valueDate = new Date(value);\n const valueParts = getDatePartsInTimezone(valueDate, timezone);\n const previousValueDate = previousValue ? new Date(previousValue) : undefined;\n const previousValueParts = previousValueDate\n ? getDatePartsInTimezone(previousValueDate, timezone)\n : undefined;\n\n let firstPartOptions = {};\n let secondPartOptions = {};\n\n switch (unitName) {\n case \"hour\":\n firstPartOptions =\n timeFormat === \"24\"\n ? { hour: \"numeric\", minute: \"numeric\", hour12: false }\n : { hour: \"numeric\" };\n if (isFirst || valueParts.day !== previousValueParts?.day) {\n secondPartOptions = { day: \"numeric\", month: \"short\" };\n }\n break;\n case \"day\":\n case \"week\":\n firstPartOptions = { day: \"numeric\" };\n if (isFirst || valueParts.month !== previousValueParts?.month) {\n secondPartOptions = { month: \"short\" };\n }\n break;\n case \"month\":\n firstPartOptions = { month: \"short\" };\n if (isFirst || valueParts.year !== previousValueParts?.year) {\n secondPartOptions = { year: \"numeric\" };\n }\n break;\n case \"year\":\n firstPartOptions = { year: \"numeric\" };\n break;\n default:\n firstPartOptions = {};\n break;\n }\n\n const firstPart = new Intl.DateTimeFormat(textLocale, {\n ...firstPartOptions,\n timeZone: timezone,\n }).format(valueDate);\n const secondPart =\n Object.keys(secondPartOptions).length > 0\n ? new Intl.DateTimeFormat(textLocale, {\n ...secondPartOptions,\n timeZone: timezone,\n }).format(valueDate)\n : undefined;\n\n return `<span>${firstPart}</span>${\n secondPart ? `<span>${secondPart}</span>` : \"\"\n }`;\n};\n","/**\n * Helper to detect if data is hourly time data (all x values are hours of the same day)\n * @param data - Array of series data with points containing x values\n * @returns boolean indicating if all x values are hours of the same day\n * @deprecated Auto-detection of hourly data is deprecated. v2 is declarative:\n * use `xAxis={{ type: \"datetime\", timeFormat: \"12\" | \"24\" }}` + a top-level\n * `timezone` instead of relying on implicit detection. See\n * `seeds-tooling/seeds-codemod-cli/src/usage-patterns/VERTICALBARCHARTV1_PATTERNS.md`\n * (CE-8).\n */\nexport function isHourlyTimeData(\n data: ReadonlyArray<\n Readonly<{ points: ReadonlyArray<{ x: number | string }> }>\n >\n): boolean {\n // Return false if there is no data.\n if (!data.length) return false;\n\n // Flatten all data points into a single array of x values.\n const xVals = data.flatMap((series) => series.points.map((p) => p.x));\n\n // Return false if there are no x values.\n if (!xVals.length) return false;\n\n // Return false if any x values are strings (categorical data)\n if (xVals.some((x) => typeof x === \"string\")) return false;\n\n // Check if all x values are on the same calendar date.\n // We do this by converting each timestamp to a YYYY-MM-DD string and checking if there's only one unique date string.\n const dates = (xVals as number[]).map((x) => {\n const d = new Date(x);\n return `${d.getUTCFullYear()}-${d.getUTCMonth()}-${d.getUTCDate()}`;\n });\n const uniqueDates = new Set(dates);\n if (uniqueDates.size !== 1) return false;\n\n // Check if all x values are exactly on the hour (e.g., 2:00:00, not 2:00:01).\n // We also check that the hour is within the valid 0-23 range.\n return (xVals as number[]).every((x) => {\n const d = new Date(x);\n const hour = d.getUTCHours();\n const minutes = d.getUTCMinutes();\n const seconds = d.getUTCSeconds();\n return hour >= 0 && hour <= 23 && minutes === 0 && seconds === 0;\n });\n}\n","/**\n * Helper to detect if data is categorical hour data (all x values are hour strings)\n * Supports both 12-hour format (\"12 AM\", \"1 PM\") and 24-hour format (\"00:00\", \"13:00\", \"23:00\")\n * @param data - Array of series data with points containing x values\n * @returns boolean indicating if all x values are hour strings\n * @deprecated Auto-detection of hourly data is deprecated. v2 is declarative:\n * use `xAxis={{ type: \"datetime\", timeFormat: \"12\" | \"24\" }}` + a top-level\n * `timezone` instead of relying on implicit detection. See\n * `seeds-tooling/seeds-codemod-cli/src/usage-patterns/VERTICALBARCHARTV1_PATTERNS.md`\n * (CE-8).\n */\nexport function isCategoricalHourData(\n data: ReadonlyArray<\n Readonly<{ points: ReadonlyArray<{ x: number | string }> }>\n >\n): boolean {\n // Return false if there is no data.\n if (!data.length) return false;\n\n // Flatten all data points into a single array of x values.\n const xVals = data.flatMap((series) => series.points.map((p) => p.x));\n\n // Return false if there are no x values.\n if (!xVals.length) return false;\n\n // Return false if any x values are not strings (numerical data)\n if (xVals.some((x) => typeof x !== \"string\")) return false;\n\n // Check if all x values match either 12-hour or 24-hour format patterns\n const hour12Pattern = /^\\d{1,2} (AM|PM)$/; // \"12 AM\", \"1 PM\", \"10 AM\"\n const hour24Pattern = /^([01]?\\d|2[0-3]):([0-5]\\d)$/; // \"00:00\", \"13:00\", \"23:59\"\n\n const stringValues = xVals as string[];\n\n // Check if all values match 12-hour format\n const allMatch12Hour = stringValues.every((x) => hour12Pattern.test(x));\n\n // Check if all values match 24-hour format\n const allMatch24Hour = stringValues.every((x) => hour24Pattern.test(x));\n\n return allMatch12Hour || allMatch24Hour;\n}\n","export const getStorybookRandomColor = (): string => {\n const letters = \"0123456789ABCDEF\";\n let color = \"#\";\n for (let i = 0; i < 6; i++) {\n color += letters[Math.floor(Math.random() * 16)];\n }\n return color;\n};\n","import { getStorybookRandomColor } from \"./getStorybookRandomColor\";\n\nexport const getStorybookCategoricalData = ({\n showNulls,\n showNegativeValues,\n numberOfSeries,\n yAxisMax,\n showCustomColors,\n showDashedLines,\n categoryType,\n}: {\n showNulls: boolean;\n showNegativeValues: boolean;\n numberOfSeries: number;\n yAxisMax: number;\n showCustomColors: boolean;\n showDashedLines: boolean;\n categoryType: \"hours\" | \"hours24\" | \"days\" | \"months\" | \"custom\";\n}) => {\n // Define different category sets\n const categoryOptions = {\n hours: [\n \"12 AM\",\n \"1 AM\",\n \"2 AM\",\n \"3 AM\",\n \"4 AM\",\n \"5 AM\",\n \"6 AM\",\n \"7 AM\",\n \"8 AM\",\n \"9 AM\",\n \"10 AM\",\n \"11 AM\",\n \"12 PM\",\n \"1 PM\",\n \"2 PM\",\n \"3 PM\",\n \"4 PM\",\n \"5 PM\",\n \"6 PM\",\n \"7 PM\",\n \"8 PM\",\n \"9 PM\",\n \"10 PM\",\n \"11 PM\",\n ],\n hours24: [\n \"00:00\",\n \"01:00\",\n \"02:00\",\n \"03:00\",\n \"04:00\",\n \"05:00\",\n \"06:00\",\n \"07:00\",\n \"08:00\",\n \"09:00\",\n \"10:00\",\n \"11:00\",\n \"12:00\",\n \"13:00\",\n \"14:00\",\n \"15:00\",\n \"16:00\",\n \"17:00\",\n \"18:00\",\n \"19:00\",\n \"20:00\",\n \"21:00\",\n \"22:00\",\n \"23:00\",\n ],\n days: [\n \"Monday\",\n \"Tuesday\",\n \"Wednesday\",\n \"Thursday\",\n \"Friday\",\n \"Saturday\",\n \"Sunday\",\n ],\n months: [\n \"January\",\n \"February\",\n \"March\",\n \"April\",\n \"May\",\n \"June\",\n \"July\",\n \"August\",\n \"September\",\n \"October\",\n \"November\",\n \"December\",\n ],\n custom: [\n \"Category A\",\n \"Category B\",\n \"Category C\",\n \"Category D\",\n \"Category E\",\n ],\n };\n\n const categories = categoryOptions[categoryType];\n const numberOfPoints = categories.length;\n\n return [...Array(numberOfSeries).keys()].map((seriesIndex) => {\n let nullsArray: ReadonlyArray<number> = [];\n\n if (showNulls) {\n const nullsArrayLength = Math.floor(numberOfPoints / 5);\n nullsArray = [...Array(nullsArrayLength)].map(() =>\n Math.floor(Math.random() * numberOfPoints)\n );\n }\n\n return {\n points: categories.map((category, pointIndex) => {\n const showNull =\n nullsArray && nullsArray.length > 0\n ? nullsArray.includes(pointIndex)\n : false;\n const randomValue = Math.random();\n const positiveOrNegativeYAxisMax = showNegativeValues\n ? randomValue < 0.5\n ? -yAxisMax\n : yAxisMax\n : yAxisMax;\n\n return {\n x: category,\n y: showNull\n ? null\n : Math.floor(randomValue * positiveOrNegativeYAxisMax),\n };\n }),\n name: `Series ${seriesIndex + 1}`,\n styles: {\n color: showCustomColors ? getStorybookRandomColor() : undefined,\n pattern: showDashedLines ? \"dashed\" : \"solid\",\n },\n };\n });\n};\n","import { getStorybookRandomColor } from \"./getStorybookRandomColor\";\n\nexport const getStorybookSparseTimelineData = ({\n showNulls,\n showNegativeValues,\n numberOfSeries,\n yAxisMax,\n showCustomColors,\n showDashedLines,\n numberOfPoints = 5,\n timeSpanHours = 24,\n}: {\n showNulls: boolean;\n showNegativeValues: boolean;\n numberOfSeries: number;\n yAxisMax: number;\n showCustomColors: boolean;\n showDashedLines: boolean;\n numberOfPoints?: number;\n timeSpanHours?: number;\n}) => {\n const seriesNames = [\n \"Posts Published\",\n \"Comments\",\n \"Likes\",\n \"Shares\",\n \"Clicks\",\n \"Views\",\n \"Saves\",\n \"Reposts\",\n \"Mentions\",\n \"Reactions\",\n ];\n\n const baseDate = new Date(\"2024-01-01T00:00:00Z\");\n const timeSpanMs = timeSpanHours * 60 * 60 * 1000;\n\n return [...Array(numberOfSeries).keys()].map((seriesIndex) => {\n let nullsArray: ReadonlyArray<number> = [];\n\n if (showNulls) {\n const nullsArrayLength = Math.floor(numberOfPoints / 5);\n nullsArray = [...Array(nullsArrayLength)].map(() =>\n Math.floor(Math.random() * numberOfPoints)\n );\n }\n\n // Generate random timestamps for this series\n const timestamps = [...Array(numberOfPoints)]\n .map(() => {\n const randomOffset = Math.random() * timeSpanMs;\n return baseDate.getTime() + randomOffset;\n })\n .sort((a, b) => a - b); // Sort chronologically\n\n return {\n points: timestamps.map((timestamp, pointIndex) => {\n const showNull =\n nullsArray && nullsArray.length > 0\n ? nullsArray.includes(pointIndex)\n : false;\n const randomValue = Math.random();\n const positiveOrNegativeYAxisMax = showNegativeValues\n ? randomValue < 0.5\n ? -yAxisMax\n : yAxisMax\n : yAxisMax;\n\n return {\n x: timestamp,\n y: showNull\n ? null\n : Math.floor(randomValue * positiveOrNegativeYAxisMax),\n };\n }),\n name: seriesNames[seriesIndex] || `Series ${seriesIndex + 1}`,\n styles: {\n color: showCustomColors ? getStorybookRandomColor() : undefined,\n pattern: showDashedLines ? \"dashed\" : \"solid\",\n },\n };\n });\n};\n","import type { Options } from \"highcharts\";\nimport _ from \"lodash\";\n\n// options that should apply to all charts\n// this is being exported because it's needed for the listening bubble chart component.\n// when that components gets moved into the data-viz package, we can remove the export here\nexport const baseChartOptions: Options = {\n chart: {\n animation: false,\n styledMode: true,\n },\n credits: {\n enabled: false,\n },\n exporting: {\n enabled: false,\n fallbackToExportServer: false,\n },\n legend: {\n enabled: false,\n },\n title: {\n text: undefined,\n },\n tooltip: {\n hideDelay: 0,\n outside: true,\n padding: 0,\n shape: \"rect\",\n shared: true,\n useHTML: true,\n },\n};\n\n// options that should apply to time series charts\nexport const TIME_SERIES_CHART_HEIGHT = 275;\nexport const timeSeriesChartOptions: Options = _.merge({}, baseChartOptions, {\n annotations: [\n {\n draggable: \"\",\n labelOptions: {\n useHTML: true,\n padding: 0, // removes \"left\" property padding created by highcharts so that label is centered\n },\n },\n ],\n chart: {\n // events.click is set at the component level because of the optional onClick prop\n height: TIME_SERIES_CHART_HEIGHT,\n spacing: [5, 1, 0, 2],\n },\n plotOptions: {\n series: {\n animation: false,\n clip: false,\n marker: {\n enabled: false,\n states: {\n hover: {\n enabled: false,\n },\n },\n },\n },\n },\n xAxis: {\n crosshair: {\n zIndex: 3,\n },\n minPadding: 0, // must be handled dynamically instead of css\n maxPadding: 0, // must be handled dynamically instead of css\n type: \"datetime\",\n labels: {\n useHTML: true,\n // formatter is set at the component level because of the required text locale prop\n },\n },\n yAxis: {\n labels: {\n useHTML: true,\n // formatter is set at the component level because of the optional yAxisLabelFormatter prop\n },\n softMax: 0,\n softMin: 0,\n title: {\n text: undefined,\n },\n plotLines: [\n /* Adds a custom plotLine at y=0 to represent the chart baseline.\n This approach allows full control over the line's appearance (e.g., color, z-index),\n unlike relying on the default xAxis line, which always renders at the bottom of the chart\n even when y=0 appears elsewhere (e.g., with negative values).\n */\n {\n className: \"y-axis-zero-line\",\n value: 0,\n zIndex: 3, // ensures the line appears over the default y=0 line, which we can't seleect as specifically\n },\n ],\n },\n});\n\n// options that should apply to LineChart\nexport const lineChartOptions: Options = _.merge({}, timeSeriesChartOptions, {\n // plotOptions.spline.events.click is set at the component level because of the optional onClick prop\n});\n\n// options that should apply to AreaChart\nexport const areaChartOptions: Options = _.merge({}, timeSeriesChartOptions, {\n plotOptions: {\n areaspline: {\n // events.click is set at the component level because of the optional onClick prop\n stacking: \"normal\",\n },\n },\n});\n\nexport const columnChartOptions: Options = _.merge({}, timeSeriesChartOptions, {\n plotOptions: {\n column: {\n stacking: \"normal\",\n pointPadding: 0.25,\n groupPadding: 0.25,\n borderRadius: 4,\n },\n },\n xAxis: {\n crosshair: false,\n },\n yAxis: {\n plotLines: [\n {\n // For stacked column charts with visible borders (e.g., white for contrast),\n // we raise the zIndex of the y=0 plotLine to ensure it remains visible\n // and isn't visually covered by overlapping column borders.\n zIndex: 5,\n },\n ],\n },\n});\n\n/**\n * The default series limit for VerticalBarChart.\n * This limit is recommended to maintain chart readability and accessibility.\n * @see {VerticalBarChart}\n */\nexport const VERTICAL_BAR_CHART_DEFAULT_SERIES_LIMIT = 10;\n\n// options that should apply to DonutChart\nexport const DONUT_CHART_HALO_SIZE = 10; // 10 is the default from highcharts\nexport const DONUT_CHART_HEIGHT = 250 + DONUT_CHART_HALO_SIZE * 2;\nexport const DONUT_CHART_WIDTH = DONUT_CHART_HEIGHT;\nexport const donutChartOptions: Options = _.merge({}, baseChartOptions, {\n chart: {\n height: DONUT_CHART_HEIGHT,\n spacing: [0, 0, 0, 0],\n },\n plotOptions: {\n pie: {\n animation: false,\n borderRadius: 0, // must be handled here instead of css because of path rendering\n dataLabels: {\n enabled: false,\n },\n innerSize: \"50%\",\n },\n },\n});\n","import { css, createGlobalStyle } from \"styled-components\";\nimport { theme } from \"@sproutsocial/seeds-react-theme\";\nimport {\n type TypeChartStyleColor,\n type TypeChartStyleHasOnClick,\n type TypeChartStylePattern,\n} from \"../types\";\nimport \"highcharts/css/highcharts.css\";\n\nexport const GlobalChartStyleOverrides = createGlobalStyle`\n // USAGE NOTE:\n // Put general styles in baseChartStyles instead when possible to avoid excessive global styling.\n // This global component is only for styles that can't override highcharts defaults when scoped.\n\n .highcharts-tooltip-container {\n z-index: 7 !important;\n }\n .highcharts-tooltip-box {\n fill: transparent !important;\n }\n`;\n\n// options that should apply to all charts\nexport const baseChartStyles = css<\n Readonly<{ $colors: ReadonlyArray<TypeChartStyleColor> }>\n>`\n --highcharts-background-color: ${({ theme }) =>\n theme.colors.container.background.base};\n\n // set color variables and map to each series\n ${({ $colors }) =>\n $colors\n .map((color, index) => {\n const chartColor = color || theme.colors.DATAVIZ_COLORS_LIST[index];\n return `\n\t\t\t\t// map colors to custom assigned colors or fallback to default data viz color rotation\n\t\t\t\t--highcharts-color-${index}: ${chartColor};\n\n\t\t\t\t// highcharts already accounts for 10 series, but if we have more, we need to add them\n\t\t\t\t.highcharts-color-${index} {\n\t\t\t\t\tcolor: var(--highcharts-color-${index});\n\t\t\t\t\tstroke: var(--highcharts-color-${index});\n\t\t\t\t\tfill: var(--highcharts-color-${index});\n\t\t\t\t}`;\n })\n .join(\"\\n\")}\n\n // set overall chart background color\n .highcharts-background {\n fill: ${({ theme }) => theme.colors.container.background.base};\n }\n\n g.highcharts-annotation-label {\n display: none;\n }\n\n div.highcharts-annotation-label {\n top: 0 !important;\n transform: translateX(-50%); // centers the label on the targeted axis point\n pointer-events: none; // prevents tooltip hover from being interrupted by this element since it renders after on the dom\n }\n`;\n\n// options that should apply to time series charts\nexport const timeSeriesChartStyles = css<\n Readonly<{\n $colors: ReadonlyArray<TypeChartStyleColor>;\n $hasOnClick: TypeChartStyleHasOnClick;\n }>\n>`\n ${baseChartStyles}\n\n // vertical crosshair styles\n\t.highcharts-crosshair {\n stroke: ${({ theme }) => theme.colors.container.border.decorative.neutral};\n stroke-width: 1;\n }\n\n // axis and gridline styles\n .highcharts-grid-line {\n stroke: ${({ theme }) => theme.colors.container.border.base};\n }\n\n .highcharts-axis-line {\n stroke: ${({ theme }) => theme.colors.container.border.base};\n }\n\n .highcharts-tick {\n stroke: none;\n }\n .highcharts-xaxis-labels,\n .highcharts-yaxis-labels {\n // v1 HTML labels (useHTML: true). v2 SVG label styles live in\n // charts/shared/styles.ts (axisLabelV2Styles) — don't add v2 rules here.\n > span {\n font-family: ${({ theme }) => theme.fontFamily};\n ${({ theme }) => theme.typography[100]};\n font-weight: ${({ theme }) => theme.fontWeights.normal};\n color: ${({ theme }) => theme.colors.text.subtext};\n }\n }\n .highcharts-xaxis-labels {\n // v1 HTML stacked labels (useHTML: true). v2 SVG stacked-label styles live\n // in charts/shared/styles.ts (axisLabelV2Styles).\n > span {\n display: flex;\n flex-direction: column;\n align-items: center;\n > span:nth-of-type(2) {\n font-weight: ${({ theme }) => theme.fontWeights.semibold};\n }\n }\n }\n\n // we don't want to drop the opacity when another item is hovered\n .highcharts-series-inactive {\n opacity: 1;\n }\n\n // apply cursor pointer when click functionality is turned on\n ${({ $hasOnClick }) =>\n $hasOnClick &&\n `\n \t\t\t.highcharts-series,\n \t\t\t.highcharts-point {\n \t\t\t\tcursor: pointer;\n \t\t\t}\n \t\t\t.highcharts-plot-background,\n \t\t\t.highcharts-crosshair,\n \t\t\t.highcharts-grid-line {\n \t\t\t\tfill: transparent;\n \t\t\t\tcursor: pointer;\n \t\t}`}\n\n path.highcharts-plot-line.y-axis-zero-line {\n stroke: ${({ theme }) => theme.colors.container.border.decorative.neutral};\n }\n`;\n\n// options that should apply to line charts\nexport const lineChartStyles = css<\n Readonly<{\n $colors: ReadonlyArray<TypeChartStyleColor>;\n $patterns: ReadonlyArray<TypeChartStylePattern>;\n $hasOnClick: TypeChartStyleHasOnClick;\n }>\n>`\n ${timeSeriesChartStyles}\n\n // set the line stroke\n\t.highcharts-graph {\n stroke-width: 3;\n }\n\n // dashed line styles\n ${({ $patterns }) =>\n $patterns.map((pattern, index) => {\n return pattern === \"dashed\"\n ? `\n \t\t\t\t\t// highcharts already accounts for 10 series, but if we have more, we need to add them\n \t\t\t\t\t.highcharts-series-${index} {\n \t\t\t\t\t\tstroke-dasharray: 2, 8;\n \t\t\t\t\t}`\n : \"\";\n })}\n`;\n\n// options that should apply to area charts\nexport const areaChartStyles = css`\n ${timeSeriesChartStyles}\n\n // don't need to show a stroke for the line part of each area\n\t.highcharts-graph {\n stroke-width: 0;\n }\n\n // fill areas to full opacity\n .highcharts-area {\n fill-opacity: 1;\n }\n`;\n\n// options that should apply to donut charts\nexport const donutChartStyles = css<\n Readonly<{\n $colors: ReadonlyArray<TypeChartStyleColor>;\n $hasOnClick: TypeChartStyleHasOnClick;\n }>\n>`\n ${baseChartStyles}\n\n // remove 250ms fade in/out when hovering over different donut chart slices\n\t.highcharts-point {\n transition: opacity 0s;\n }\n\n // remove stroke on donut slices\n .highcharts-pie-series .highcharts-point {\n stroke: none;\n }\n\n // don't reduce opacity when hovering\n .highcharts-point-hover {\n fill-opacity: none;\n }\n\n // apply cursor pointer when click functionality is turned on\n ${({ $hasOnClick }) =>\n $hasOnClick &&\n `\n \t\t\t.highcharts-series,\n \t\t\t.highcharts-point {\n \t\t\t\tcursor: pointer;\n \t\t\t}\n \t\t\t.highcharts-plot-background,\n \t\t\t.highcharts-crosshair,\n \t\t\t.highcharts-grid-line {\n \t\t\t\tfill: transparent;\n \t\t\t\tcursor: pointer;\n \t\t}`}\n`;\n","import { memo } from \"react\";\nimport { Box } from \"@sproutsocial/seeds-react-box\";\n\nexport type TypeChartLegendLabelContentWithIconProps = Readonly<{\n children: React.ReactNode;\n // optional\n icon?: React.ReactNode;\n}>;\n\nexport const ChartLegendLabelContentWithIcon =\n memo<TypeChartLegendLabelContentWithIconProps>(\n function ChartLegendLabelContentWithIcon({\n children,\n icon,\n }: TypeChartLegendLabelContentWithIconProps) {\n return icon ? (\n <Box display=\"flex\" alignItems=\"center\" gap={200}>\n {icon}\n {children}\n </Box>\n ) : (\n children\n );\n }\n );\n","import { timeSeriesChartStyles } from \"../../styles/chartStyles\";\nimport { css } from \"styled-components\";\nimport type {\n TypeChartStyleColor,\n TypeChartStyleHasOnClick,\n} from \"../../types\";\n\n// options that should apply to line charts\nexport const verticalBarChartStyles = css<\n Readonly<{\n $colors: ReadonlyArray<TypeChartStyleColor>;\n $hasOnClick: TypeChartStyleHasOnClick;\n }>\n>`\n ${timeSeriesChartStyles}\n\n /*\n When the chart container is hovered, reduce the opacity of all columns.\n Then, for the column that is being hovered, restore its opacity.\n This gives the effect of fading out the non-hovered columns.\n */\n .highcharts-container:hover .highcharts-point {\n fill-opacity: 0.3;\n }\n\n .highcharts-point.column-hover {\n fill-opacity: 1 !important;\n }\n`;\n"]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../../src/components/ColorBox/ColorBox.tsx","../../../seeds-react-theme-provider/src/index.tsx","../../src/components/ColorBox/DatavizColorBox.tsx","../../src/components/ColorBox/NetworkColorBox.tsx","../../src/components/ChartLegend/components/ChartLegendLabel.tsx","../../src/components/ChartLegend/ChartLegend.tsx","../../src/components/ChartTooltip/ChartTooltip.tsx","../../src/components/ChartTooltip/components/ChartTooltipFooter.tsx","../../src/components/ChartTooltip/components/ChartTooltipHeader.tsx","../../src/components/ChartTooltip/components/ChartTooltipPortal.tsx","../../src/components/ChartTable/ChartTable.tsx","../../src/components/ChartTooltip/components/ChartTooltipTable.tsx","../../src/components/ChartTooltip/components/ChartTooltipTitle.tsx","../../src/helpers/transformDataToSeries.ts","../../src/helpers/transformTimeSeriesTooltipData.ts","../../src/helpers/yAxisLabelFormatter.ts","../../src/helpers/xAxisLabelFormatter.ts","../../src/helpers/isHourlyTimeData.ts","../../src/helpers/isCategoricalHourData.ts","../../src/helpers/getStorybookRandomColor.ts","../../src/helpers/getStorybookCategoricalData.ts","../../src/helpers/getStorybookSparseTimelineData.ts","../../src/constants/chartOptions.ts","../../src/styles/chartStyles.ts","../../src/components/ChartLegend/components/ChartLegendLabelContentWithIcon.tsx","../../src/components/VerticalBarChart/styles.ts"],"sourcesContent":["import { css, type CSSProp } from \"styled-components\";\nimport { Box, type TypeBoxProps } from \"@sproutsocial/seeds-react-box\";\nimport ThemeProvider from \"@sproutsocial/seeds-react-theme-provider\";\nimport { type TypeSproutTheme } from \"@sproutsocial/seeds-react-theme\";\n\nexport type TypeColorBoxProps = TypeBoxProps;\n\n/**\n * ColorBox extends Box to apply basic styles.\n */\nexport const ColorBox = ({\n display = \"inline-block\",\n height = \"16px\",\n width = \"16px\",\n minWidth = width,\n borderRadius = \"400\",\n ...props\n}: TypeColorBoxProps) => {\n return (\n <Box\n {...props}\n display={display}\n height={height}\n width={width}\n minWidth={minWidth}\n borderRadius={borderRadius}\n css={\n css`\n cursor: ${(\n props: typeof ThemeProvider & {\n onClick: ((e: React.MouseEvent<HTMLElement>) => void) | void;\n }\n ) => (props?.onClick ? \"pointer\" : \"default\")};\n ` as CSSProp<TypeSproutTheme>\n }\n />\n );\n};\n","import * as React from \"react\";\nimport {\n ThemeProvider as BaseThemeProvider,\n createGlobalStyle,\n} from \"styled-components\";\nimport { theme } from \"@sproutsocial/seeds-react-theme\";\nimport type {\n TypeSproutTheme,\n TypeTheme,\n} from \"@sproutsocial/seeds-react-theme\";\n\n// We can append additional themes types here\ntype TypeAllThemes = TypeTheme | TypeSproutTheme;\n\ntype TypeProps = {\n readonly theme?: TypeAllThemes;\n readonly children?: React.ReactNode;\n};\n\n// CSS custom properties for token values that cannot be represented in SCSS maps\n// (e.g. radial-gradient + color-mix). These are injected here so styled-components\n// consumers get the values without needing to load the compiled SCSS theme CSS.\nconst GlobalTokenStyles = createGlobalStyle`\n :root {\n --color-container-bg-ai-generated: radial-gradient(\n circle at bottom left,\n color-mix(in srgb, #205bc3, transparent 80%) 0%,\n color-mix(in srgb, #6f5ed3, transparent 80%) 61%,\n color-mix(in srgb, #f282f5, transparent 80%) 100%\n ), #f3f4f4;\n }\n`;\n\nconst ThemeProvider = (props: TypeProps) => (\n <BaseThemeProvider {...props} theme={props.theme || theme}>\n <GlobalTokenStyles />\n {props.children}\n </BaseThemeProvider>\n);\n\nexport default ThemeProvider;\n","import type * as React from \"react\";\nimport styled from \"styled-components\";\nimport { theme } from \"@sproutsocial/seeds-react-theme\";\nimport { ColorBox, type TypeColorBoxProps } from \"./ColorBox\";\n\nexport type TypeDatavizColorBoxProps = Readonly<\n Partial<TypeColorBoxProps> & {\n colorIndex: number;\n }\n>;\nexport type TypeDatavizColorBox = (\n props: TypeDatavizColorBoxProps\n) => React.JSXElementConstructor<TypeDatavizColorBoxProps>;\n\n/**\n * DatavizColorBox extends ColorBox to set the background color from a rotation of <a href=\"https://seeds.sproutsocial.com/visual/dataviz#color-combinations-for-general-sprout-social-data-visualizations\">dataviz colors</a>.\n */\nexport const DatavizColorBox = styled(ColorBox).attrs(\n ({ colorIndex }: TypeDatavizColorBoxProps) => ({\n style: {\n background: getDatavizColor(colorIndex),\n opacity: getDatavizOpacity(colorIndex),\n },\n })\n)<TypeDatavizColorBoxProps>``;\n\nexport const getDatavizColor = (colorIndex: number): string =>\n theme.colors.DATAVIZ_COLORS_LIST[\n colorIndex % theme.colors.DATAVIZ_COLORS_LIST.length\n ] || \"\";\n\nexport const getDatavizOpacity = (colorIndex: number): number => {\n const opacitySteps = [1, 0.6, 0.4, 0.2];\n const opacityStep =\n Math.floor(colorIndex / theme.colors.DATAVIZ_COLORS_LIST.length) %\n opacitySteps.length;\n // @ts-ignore\n return opacitySteps[opacityStep];\n};\n\n// information on 8 digit hex codes can be found here: https://css-tricks.com/8-digit-hex-codes/\nexport const getDatavizColorWithAlpha = (colorIndex: number): string => {\n const color = getDatavizColor(colorIndex);\n const opacity = getDatavizOpacity(colorIndex);\n\n // make sure the opacity is always between 0 and 1\n if (opacity < 0 || opacity > 1) {\n return color;\n }\n\n // sourced from https://stackoverflow.com/a/66143374\n return `${color}${Math.floor(opacity * 255)\n .toString(16)\n .padStart(2, \"0\")}`;\n};\n","import NETWORK_COLORS from \"@sproutsocial/seeds-networkcolor\";\n\nimport { ColorBox, type TypeColorBoxProps } from \"./ColorBox\";\n\n// $Keys<typeof NETWORK_COLORS>\ntype TypeNetworkColor =\n | \"NETWORK_COLOR_TWITTER\"\n | \"NETWORK_COLOR_TWITTER_LIKE\"\n | \"NETWORK_COLOR_FACEBOOK\"\n | \"NETWORK_COLOR_FACEBOOK_AUDIENCE_NETWORK\"\n | \"NETWORK_COLOR_LINKEDIN\"\n | \"NETWORK_COLOR_INSTAGRAM\"\n | \"NETWORK_COLOR_FEEDLY\"\n | \"NETWORK_COLOR_ANALYTICS\"\n | \"NETWORK_COLOR_YOUTUBE\"\n | \"NETWORK_COLOR_MESSENGER\"\n | \"NETWORK_COLOR_SNAPCHAT\"\n | \"NETWORK_COLOR_PINTEREST\"\n | \"NETWORK_COLOR_REDDIT\"\n | \"NETWORK_COLOR_TUMBLR\"\n | \"NETWORK_COLOR_GOOGLE_MY_BUSINESS\"\n | \"NETWORK_COLOR_TIKTOK\"\n | \"NETWORK_COLOR_TRIPADVISOR\"\n | \"NETWORK_COLOR_GLASSDOOR\"\n | \"NETWORK_COLOR_SALESFORCE\"\n | \"NETWORK_COLOR_ZENDESK\"\n | \"NETWORK_COLOR_HUBSPOT\"\n | \"NETWORK_COLOR_MICROSOFT_DYNAMICS\";\n\ntype TypeNetworkColorBoxProps = Readonly<\n TypeColorBoxProps & {\n networkColor: TypeNetworkColor;\n }\n>;\n\n/**\n * NetworkColorBox extends ColorBox to set the background color to a <a href=\"https://seeds.sproutsocial.com/visual/color#full-color-palette\">network color</a>.\n */\nexport const NetworkColorBox = ({\n networkColor,\n ...props\n}: TypeNetworkColorBoxProps) => {\n return <ColorBox {...props} bg={NETWORK_COLORS[networkColor]} />;\n};\n","import styled from \"styled-components\";\nimport { memo } from \"react\";\nimport { Box, type TypeBoxProps } from \"@sproutsocial/seeds-react-box\";\nimport { Text } from \"@sproutsocial/seeds-react-text\";\n\nimport type { TypeLegendLabel } from \"../ChartLegend\";\n\nimport { ColorBox } from \"../../ColorBox\";\n\nconst StyledBox = styled(Box)<TypeBoxProps>`\n list-style: none;\n display: flex;\n align-items: center;\n gap: ${({ theme }) => theme.space[300]};\n`;\n\nexport type TypeChartLegendLabelProps = Readonly<{\n children: TypeLegendLabel[\"content\"];\n color: TypeLegendLabel[\"color\"];\n // optional\n containerBoxProps?: TypeBoxProps;\n}>;\n\nexport const ChartLegendLabel = memo<TypeChartLegendLabelProps>(\n function ChartLegendLabel({\n children,\n color = \"#CCC\",\n containerBoxProps = {},\n }: TypeChartLegendLabelProps) {\n return (\n <StyledBox {...containerBoxProps}>\n <ColorBox bg={color} />\n <Text as=\"div\" fontSize={200} color=\"text.subtext\">\n {children}\n </Text>\n </StyledBox>\n );\n }\n);\n","import { memo } from \"react\";\nimport { Box, type TypeBoxProps } from \"@sproutsocial/seeds-react-box\";\nimport { theme } from \"@sproutsocial/seeds-react-theme\";\n\nimport { ChartLegendLabel } from \"./components/ChartLegendLabel\";\n\nexport type TypeLegendLabel = Readonly<{\n content: React.ReactNode;\n color?: string;\n}>;\n\nexport type TypeChartLegendProps = Readonly<{\n legendLabels: ReadonlyArray<TypeLegendLabel>;\n // optional\n containerBoxProps?: TypeBoxProps;\n stacked?: boolean;\n}>;\n\nexport const ChartLegend = memo<TypeChartLegendProps>(function ChartLegend({\n legendLabels,\n containerBoxProps = {},\n stacked = false,\n}: TypeChartLegendProps) {\n return (\n <Box\n as=\"ul\"\n aria-hidden=\"true\"\n display=\"flex\"\n justifyContent=\"center\"\n flexDirection={stacked ? \"column\" : \"row\"}\n flexWrap=\"wrap\"\n columnGap={450}\n rowGap={200}\n m={0}\n p={0}\n {...containerBoxProps}\n >\n {legendLabels.map(({ color, content }, index) => (\n <ChartLegendLabel\n key={`chart-legend-label-${index}`}\n color={color || theme.colors.DATAVIZ_COLORS_LIST[index]}\n containerBoxProps={{ as: \"li\" }}\n >\n {content}\n </ChartLegendLabel>\n ))}\n </Box>\n );\n});\n","import { memo } from \"react\";\nimport styled from \"styled-components\";\nimport { Box } from \"@sproutsocial/seeds-react-box\";\n\n// styled components\nconst StyledBox = styled(Box)`\n .Icon,\n .logo {\n stroke: none;\n }\n`;\n\n// Chart Tooltip\ntype TypeChartTooltipProps = Readonly<{\n children: React.ReactNode;\n}>;\n\nexport const ChartTooltip = memo<TypeChartTooltipProps>(function ChartTooltip({\n children,\n}: TypeChartTooltipProps) {\n return (\n <StyledBox\n bg=\"container.background.base\"\n boxShadow=\"medium\"\n border={500}\n borderColor=\"container.border.base\"\n borderRadius={500}\n p={400}\n minWidth={285}\n >\n <Box display=\"flex\" flexDirection=\"column\" gap={350}>\n {children}\n </Box>\n </StyledBox>\n );\n});\n","import { memo } from \"react\";\nimport { Box } from \"@sproutsocial/seeds-react-box\";\n\ntype TypeChartTooltipFooterProps = {\n children: React.ReactNode;\n};\n\nexport const ChartTooltipFooter = memo<TypeChartTooltipFooterProps>(\n function ChartTooltipFooter({ children }: TypeChartTooltipFooterProps) {\n return (\n <Box\n borderTop={500}\n borderColor=\"container.border.base\"\n mx={-400}\n mb={-200}\n px={400}\n pt={350}\n >\n {children}\n </Box>\n );\n }\n);\n","import { memo } from \"react\";\nimport { Box } from \"@sproutsocial/seeds-react-box\";\n\ntype TypeChartTooltipHeaderProps = {\n children: React.ReactNode;\n};\n\nexport const ChartTooltipHeader = memo<TypeChartTooltipHeaderProps>(\n function ChartTooltipHeader({ children }: TypeChartTooltipHeaderProps) {\n return (\n <Box\n borderBottom={500}\n borderColor=\"container.border.base\"\n mx={-400}\n mt={-200}\n px={400}\n pb={350}\n >\n {children}\n </Box>\n );\n }\n);\n","import { memo, useState, useRef, useEffect, type ReactNode } from \"react\";\nimport { createPortal } from \"react-dom\";\nimport type {\n Tooltip,\n Chart,\n TooltipFormatterContextObject,\n TooltipFormatterCallbackFunction,\n} from \"highcharts\";\n\ninterface ExtendedHighchartsTooltip extends Tooltip {\n label: {\n box: { attr({ height, width }: { height: number; width: number }): void };\n text: { element: HTMLElement };\n };\n}\n\nexport const generateChartTooltipPortalId = (chartId: number) =>\n `highcharts-custom-tooltip-${chartId}`;\n\ntype ChartTooltipPortalProps = Readonly<{\n chart: Chart;\n renderContent: (context: TooltipFormatterContextObject) => ReactNode;\n}>;\n\nexport const ChartTooltipPortal = memo<ChartTooltipPortalProps>(\n function ChartTooltipPortal({\n chart,\n renderContent,\n }: ChartTooltipPortalProps) {\n const isInitialized = useRef<boolean>(false);\n const [node, setNode] = useState<HTMLElement | null>(null);\n const [context, setContext] =\n useState<TooltipFormatterContextObject | null>(null);\n\n useEffect(() => {\n const formatter: TooltipFormatterCallbackFunction = function () {\n // Ensures that tooltip DOM container is rendered before React portal is created.\n if (!isInitialized.current) {\n isInitialized.current = true;\n chart.tooltip.refresh.apply(chart.tooltip, [this.point]);\n chart.tooltip.hide(0);\n }\n\n setContext(this);\n\n return `<div id=\"${generateChartTooltipPortalId(\n chart.index\n )}\" role='tooltip'></div>`;\n };\n\n chart.update({ tooltip: { formatter } });\n }, [chart]);\n\n useEffect(() => {\n // In some cases tooltip is not available on the chart yet\n if (context?.series?.chart?.tooltip) {\n const tooltip = context.series.chart\n .tooltip as ExtendedHighchartsTooltip;\n const textElement = tooltip.label.text.element;\n\n tooltip.label.box.attr({\n height: textElement.offsetHeight,\n width: textElement.offsetWidth,\n });\n\n setNode(\n document.getElementById(generateChartTooltipPortalId(chart.index))\n );\n }\n }, [context, chart.index]);\n\n return node && context ? createPortal(renderContent(context), node) : null;\n }\n);\n","import { memo } from \"react\";\nimport styled from \"styled-components\";\nimport { Text } from \"@sproutsocial/seeds-react-text\";\nimport { Table as SeedsTable } from \"@sproutsocial/seeds-react-table\";\n\nconst StyledSeedsTable = styled<typeof SeedsTable>(SeedsTable)`\n tbody tr:last-child {\n border-bottom: none;\n }\n tr:last-child td,\n tr:last-child th {\n padding-bottom: 0;\n }\n tr:first-child td,\n tr:first-child th {\n padding-top: 0;\n }\n tr th {\n padding-left: 0;\n }\n tr td:last-child {\n padding-right: 0;\n }\n`;\n\nconst StyledSeedsTableRow = styled(SeedsTable.TableRow)<{\n $isAppendedRow?: boolean;\n}>`\n ${({ $isAppendedRow, theme }) =>\n $isAppendedRow\n ? `border-top: 2px solid ${theme.colors.container.border.base}`\n : \"\"}\n`;\n\nexport type TypeChartTableProps = Readonly<{\n rows: ReadonlyArray<{\n cells: ReadonlyArray<{\n content: React.ReactNode;\n align?: React.ComponentProps<typeof SeedsTable.Cell>[\"align\"];\n colSpan?: React.ComponentProps<typeof SeedsTable.Cell>[\"colSpan\"];\n }>;\n isAppendedRow?: boolean;\n }>;\n}>;\n\nexport const ChartTable = memo<TypeChartTableProps>(function ChartTable({\n rows,\n}: TypeChartTableProps) {\n if (!rows || rows.length === 0) {\n return null;\n }\n\n return (\n <StyledSeedsTable>\n <SeedsTable.TableBody>\n {rows.map(({ cells, isAppendedRow }, rowIndex) => {\n if (!cells || cells.length === 0) {\n return null;\n }\n\n return (\n <StyledSeedsTableRow\n key={`chart-tooltip-table-row-${rowIndex}`}\n $isAppendedRow={isAppendedRow}\n >\n {cells.map(\n ({ content, align = \"left\", colSpan = 1 }, cellIndex) => {\n const uniqueIdentifier = `chart-tooltip-table-cell-${cellIndex}`;\n return (\n <SeedsTable.Cell\n key={uniqueIdentifier}\n id={uniqueIdentifier}\n scope={cellIndex === 0 ? \"row\" : undefined}\n align={align}\n colSpan={colSpan}\n py={200}\n >\n <Text.SmallBodyCopy as=\"div\">\n {content}\n </Text.SmallBodyCopy>\n </SeedsTable.Cell>\n );\n }\n )}\n </StyledSeedsTableRow>\n );\n })}\n </SeedsTable.TableBody>\n </StyledSeedsTable>\n );\n});\n","import { memo } from \"react\";\n\nimport { ChartTable, type TypeChartTableProps } from \"../../ChartTable\";\n\nexport type TypeChartTooltipTableProps = {\n rows: TypeChartTableProps[\"rows\"];\n};\n\nexport const ChartTooltipTable = memo<TypeChartTooltipTableProps>(\n function ChartTooltipTable({ rows }: TypeChartTooltipTableProps) {\n return <ChartTable rows={rows} />;\n }\n);\n","import { memo } from \"react\";\nimport { Text } from \"@sproutsocial/seeds-react-text\";\n\ntype TypeChartTooltipTitleProps = {\n children: React.ReactNode;\n};\n\nexport const ChartTooltipTitle = memo<TypeChartTooltipTitleProps>(\n function ChartTooltipTitle({ children }: TypeChartTooltipTitleProps) {\n return <Text.SmallSubHeadline as=\"p\">{children}</Text.SmallSubHeadline>;\n }\n);\n","import type {\n SeriesSplineOptions,\n SeriesAreasplineOptions,\n SeriesColumnOptions,\n} from \"highcharts\";\n\nimport type { TypeAreaChartProps } from \"../components/AreaChart\";\nimport type { TypeLineChartProps } from \"../components/LineChart\";\nimport type { TypeVerticalBarChartProps, TypeSeriesType } from \"../types\";\n\ntype TypeTimeSeriesOptions =\n | SeriesSplineOptions\n | SeriesAreasplineOptions\n | SeriesColumnOptions;\n\n// returns a transformed set of data to series with some logic for handling null values\nexport const transformDataToSeries = (\n {\n data,\n }: {\n data:\n | TypeAreaChartProps[\"data\"]\n | TypeLineChartProps[\"data\"]\n | TypeVerticalBarChartProps[\"data\"];\n },\n type: TypeSeriesType\n): TypeTimeSeriesOptions[] => {\n // Check if we have categorical data (string x values)\n const hasCategoricalData = data.some((series) =>\n series.points.some((point) => typeof point.x === \"string\")\n );\n\n return data.map((dataItem, dataIndex) => {\n const points = dataItem.points || [];\n const dataPoints = points.map((point, pointsIndex) => {\n let enableMarker = false;\n const isFirstPoint = pointsIndex === 0;\n const isLastPoint = pointsIndex === points.length - 1;\n\n // @ts-ignore\n const previousY = isFirstPoint ? null : points[pointsIndex - 1].y;\n // @ts-ignore\n const nextY = isLastPoint ? null : points[pointsIndex + 1].y;\n\n if (isFirstPoint && nextY === null) {\n // if the first point has data and the second point is null, show a marker for the first point\n enableMarker = true;\n } else if (isLastPoint && previousY === null) {\n // if the last point has data and the second to last point is null, show a marker for the last point\n enableMarker = true;\n } else if (previousY === null && nextY === null) {\n // if the a point has null values on both sides, show a marker\n enableMarker = true;\n }\n\n return {\n x: hasCategoricalData ? pointsIndex : point.x,\n y: point.y,\n marker: {\n enabled: enableMarker ? enableMarker : undefined,\n symbol: enableMarker ? \"circle\" : undefined,\n },\n // For categorical data, store the original category name\n ...(hasCategoricalData && { name: point.x }),\n };\n });\n\n return {\n colorIndex: dataIndex,\n data: dataPoints as TypeTimeSeriesOptions[\"data\"],\n name: dataItem.name as TypeTimeSeriesOptions[\"name\"],\n type: type,\n };\n });\n};\n","import type { TooltipFormatterContextObject } from \"highcharts\";\nimport { theme } from \"@sproutsocial/seeds-react-theme\";\n\nimport type { TypeAreaChartProps } from \"../components/AreaChart\";\nimport type { TypeLineChartProps } from \"../components/LineChart\";\nimport type { TypeChartTooltipProps } from \"../types\";\n\ntype TypeTransformTimeSeriesTooltipDataProps = Readonly<{\n context: TooltipFormatterContextObject;\n data: TypeAreaChartProps[\"data\"] | TypeLineChartProps[\"data\"];\n}>;\ntype TypeTransformTimeSeriesTooltipDataReturn = TypeChartTooltipProps[\"data\"];\n\nexport const transformTimeSeriesTooltipData = ({\n context,\n data,\n}: TypeTransformTimeSeriesTooltipDataProps): TypeTransformTimeSeriesTooltipDataReturn => {\n // @ts-ignore\n return (context.series.chart.series || []).map((series, index) => {\n const pointIndex = context.point.index;\n const y = series?.points?.[pointIndex]?.y;\n\n return {\n color:\n data[index]?.styles?.color || theme.colors.DATAVIZ_COLORS_LIST[index],\n ...(data[index]?.icon ? { icon: data[index]?.icon } : {}),\n name: series.name,\n value: typeof y === \"number\" ? y : null,\n };\n });\n};\n","import type {\n AxisLabelsFormatterContextObject,\n AxisTickPositionsArray,\n} from \"highcharts\";\nimport { formatDuration } from \"@sproutsocial/seeds-react-duration\";\nimport { formatNumeral } from \"@sproutsocial/seeds-react-numeral\";\n\nimport type { TypeChartNumberFormat } from \"../types\";\n\ntype TypeYAxisLabelFormatterProps = Readonly<{\n numberLocale: Intl.LocalesArgument;\n textLocale: Intl.LocalesArgument;\n tickPositions: AxisTickPositionsArray;\n value: AxisLabelsFormatterContextObject[\"value\"];\n // optional\n currency?: string;\n numberFormat?: TypeChartNumberFormat;\n}>;\n\nexport const yAxisLabelFormatter = ({\n numberLocale,\n textLocale,\n tickPositions,\n value,\n currency = \"USD\",\n numberFormat = \"decimal\",\n}: TypeYAxisLabelFormatterProps): string => {\n const numberValue = Number(value);\n\n if (numberValue === 0) {\n return formatNumeral({\n locale: numberLocale as string,\n number: numberValue,\n });\n }\n\n if (numberFormat === \"duration\") {\n return formatDuration({\n display: \"narrow\",\n locale: textLocale,\n milliseconds: numberValue,\n });\n }\n\n // Seeds formatNumeral helper starts abbreviating numbers above 10,000. this maxValue logic\n // helps bring that threshold down to 1,000 if the last tick on the y axis is greater than 9,999\n // so we render \"2k 4k 6k 8k 10k\" instead of \"2,000 4,000 6,000 8,000 10k\"\n const maxValue =\n tickPositions && tickPositions.length > 0\n ? tickPositions[tickPositions.length - 1]\n : undefined;\n const abbreviate =\n typeof maxValue === \"number\" && maxValue > 9999 ? 1000 : true;\n\n return formatNumeral({\n abbreviate,\n currency,\n format: numberFormat,\n locale: numberLocale as string,\n number: numberValue,\n });\n};\n","import type {\n AxisLabelsFormatterContextObject,\n AxisTickPositionsArray,\n} from \"highcharts\";\n\nimport type {\n ExtendedTimeTicksInfoObject,\n TypeChartTimeFormat,\n} from \"../types\";\n\nconst getDatePartsInTimezone = (date: Date, timezone: string) => {\n const formatter = new Intl.DateTimeFormat(\"en-US\", {\n year: \"numeric\",\n month: \"numeric\",\n day: \"numeric\",\n timeZone: timezone,\n });\n const parts = formatter.formatToParts(date);\n return {\n day: parseInt(parts.find((p) => p.type === \"day\")?.value ?? \"0\", 10),\n month: parseInt(parts.find((p) => p.type === \"month\")?.value ?? \"0\", 10),\n year: parseInt(parts.find((p) => p.type === \"year\")?.value ?? \"0\", 10),\n };\n};\n\ntype TypeXAxisLabelFormatterProps = Readonly<{\n textLocale: Intl.LocalesArgument;\n tickPositions: AxisTickPositionsArray;\n unitName: ExtendedTimeTicksInfoObject[\"unitName\"];\n value: AxisLabelsFormatterContextObject[\"value\"];\n // optional\n timeFormat?: TypeChartTimeFormat;\n timezone?: string;\n}>;\n\nexport const xAxisLabelFormatter = ({\n textLocale,\n tickPositions = [],\n unitName,\n value,\n // optional\n timeFormat = \"12\",\n timezone = \"UTC\",\n}: TypeXAxisLabelFormatterProps): string => {\n // Handle categorical (string) data\n if (typeof value === \"string\") {\n return `<span>${value}</span>`;\n }\n const tickIndex = tickPositions.indexOf(value as number);\n const isFirst = tickIndex === 0;\n const previousValue = tickPositions[tickIndex - 1];\n\n const valueDate = new Date(value);\n const valueParts = getDatePartsInTimezone(valueDate, timezone);\n const previousValueDate = previousValue ? new Date(previousValue) : undefined;\n const previousValueParts = previousValueDate\n ? getDatePartsInTimezone(previousValueDate, timezone)\n : undefined;\n\n let firstPartOptions = {};\n let secondPartOptions = {};\n\n switch (unitName) {\n case \"hour\":\n firstPartOptions =\n timeFormat === \"24\"\n ? { hour: \"numeric\", minute: \"numeric\", hour12: false }\n : { hour: \"numeric\" };\n if (isFirst || valueParts.day !== previousValueParts?.day) {\n secondPartOptions = { day: \"numeric\", month: \"short\" };\n }\n break;\n case \"day\":\n case \"week\":\n firstPartOptions = { day: \"numeric\" };\n if (isFirst || valueParts.month !== previousValueParts?.month) {\n secondPartOptions = { month: \"short\" };\n }\n break;\n case \"month\":\n firstPartOptions = { month: \"short\" };\n if (isFirst || valueParts.year !== previousValueParts?.year) {\n secondPartOptions = { year: \"numeric\" };\n }\n break;\n case \"year\":\n firstPartOptions = { year: \"numeric\" };\n break;\n default:\n firstPartOptions = {};\n break;\n }\n\n const firstPart = new Intl.DateTimeFormat(textLocale, {\n ...firstPartOptions,\n timeZone: timezone,\n }).format(valueDate);\n const secondPart =\n Object.keys(secondPartOptions).length > 0\n ? new Intl.DateTimeFormat(textLocale, {\n ...secondPartOptions,\n timeZone: timezone,\n }).format(valueDate)\n : undefined;\n\n return `<span>${firstPart}</span>${\n secondPart ? `<span>${secondPart}</span>` : \"\"\n }`;\n};\n","/**\n * Helper to detect if data is hourly time data (all x values are hours of the same day)\n * @param data - Array of series data with points containing x values\n * @returns boolean indicating if all x values are hours of the same day\n * @deprecated Auto-detection of hourly data is deprecated. v2 is declarative:\n * use `xAxis={{ type: \"datetime\", timeFormat: \"12\" | \"24\" }}` + a top-level\n * `timezone` instead of relying on implicit detection. See\n * `seeds-tooling/seeds-codemod-cli/src/usage-patterns/VERTICALBARCHARTV1_PATTERNS.md`\n * (CE-8).\n */\nexport function isHourlyTimeData(\n data: ReadonlyArray<\n Readonly<{ points: ReadonlyArray<{ x: number | string }> }>\n >\n): boolean {\n // Return false if there is no data.\n if (!data.length) return false;\n\n // Flatten all data points into a single array of x values.\n const xVals = data.flatMap((series) => series.points.map((p) => p.x));\n\n // Return false if there are no x values.\n if (!xVals.length) return false;\n\n // Return false if any x values are strings (categorical data)\n if (xVals.some((x) => typeof x === \"string\")) return false;\n\n // Check if all x values are on the same calendar date.\n // We do this by converting each timestamp to a YYYY-MM-DD string and checking if there's only one unique date string.\n const dates = (xVals as number[]).map((x) => {\n const d = new Date(x);\n return `${d.getUTCFullYear()}-${d.getUTCMonth()}-${d.getUTCDate()}`;\n });\n const uniqueDates = new Set(dates);\n if (uniqueDates.size !== 1) return false;\n\n // Check if all x values are exactly on the hour (e.g., 2:00:00, not 2:00:01).\n // We also check that the hour is within the valid 0-23 range.\n return (xVals as number[]).every((x) => {\n const d = new Date(x);\n const hour = d.getUTCHours();\n const minutes = d.getUTCMinutes();\n const seconds = d.getUTCSeconds();\n return hour >= 0 && hour <= 23 && minutes === 0 && seconds === 0;\n });\n}\n","/**\n * Helper to detect if data is categorical hour data (all x values are hour strings)\n * Supports both 12-hour format (\"12 AM\", \"1 PM\") and 24-hour format (\"00:00\", \"13:00\", \"23:00\")\n * @param data - Array of series data with points containing x values\n * @returns boolean indicating if all x values are hour strings\n * @deprecated Auto-detection of hourly data is deprecated. v2 is declarative:\n * use `xAxis={{ type: \"datetime\", timeFormat: \"12\" | \"24\" }}` + a top-level\n * `timezone` instead of relying on implicit detection. See\n * `seeds-tooling/seeds-codemod-cli/src/usage-patterns/VERTICALBARCHARTV1_PATTERNS.md`\n * (CE-8).\n */\nexport function isCategoricalHourData(\n data: ReadonlyArray<\n Readonly<{ points: ReadonlyArray<{ x: number | string }> }>\n >\n): boolean {\n // Return false if there is no data.\n if (!data.length) return false;\n\n // Flatten all data points into a single array of x values.\n const xVals = data.flatMap((series) => series.points.map((p) => p.x));\n\n // Return false if there are no x values.\n if (!xVals.length) return false;\n\n // Return false if any x values are not strings (numerical data)\n if (xVals.some((x) => typeof x !== \"string\")) return false;\n\n // Check if all x values match either 12-hour or 24-hour format patterns\n const hour12Pattern = /^\\d{1,2} (AM|PM)$/; // \"12 AM\", \"1 PM\", \"10 AM\"\n const hour24Pattern = /^([01]?\\d|2[0-3]):([0-5]\\d)$/; // \"00:00\", \"13:00\", \"23:59\"\n\n const stringValues = xVals as string[];\n\n // Check if all values match 12-hour format\n const allMatch12Hour = stringValues.every((x) => hour12Pattern.test(x));\n\n // Check if all values match 24-hour format\n const allMatch24Hour = stringValues.every((x) => hour24Pattern.test(x));\n\n return allMatch12Hour || allMatch24Hour;\n}\n","export const getStorybookRandomColor = (): string => {\n const letters = \"0123456789ABCDEF\";\n let color = \"#\";\n for (let i = 0; i < 6; i++) {\n color += letters[Math.floor(Math.random() * 16)];\n }\n return color;\n};\n","import { getStorybookRandomColor } from \"./getStorybookRandomColor\";\n\nexport const getStorybookCategoricalData = ({\n showNulls,\n showNegativeValues,\n numberOfSeries,\n yAxisMax,\n showCustomColors,\n showDashedLines,\n categoryType,\n}: {\n showNulls: boolean;\n showNegativeValues: boolean;\n numberOfSeries: number;\n yAxisMax: number;\n showCustomColors: boolean;\n showDashedLines: boolean;\n categoryType: \"hours\" | \"hours24\" | \"days\" | \"months\" | \"custom\";\n}) => {\n // Define different category sets\n const categoryOptions = {\n hours: [\n \"12 AM\",\n \"1 AM\",\n \"2 AM\",\n \"3 AM\",\n \"4 AM\",\n \"5 AM\",\n \"6 AM\",\n \"7 AM\",\n \"8 AM\",\n \"9 AM\",\n \"10 AM\",\n \"11 AM\",\n \"12 PM\",\n \"1 PM\",\n \"2 PM\",\n \"3 PM\",\n \"4 PM\",\n \"5 PM\",\n \"6 PM\",\n \"7 PM\",\n \"8 PM\",\n \"9 PM\",\n \"10 PM\",\n \"11 PM\",\n ],\n hours24: [\n \"00:00\",\n \"01:00\",\n \"02:00\",\n \"03:00\",\n \"04:00\",\n \"05:00\",\n \"06:00\",\n \"07:00\",\n \"08:00\",\n \"09:00\",\n \"10:00\",\n \"11:00\",\n \"12:00\",\n \"13:00\",\n \"14:00\",\n \"15:00\",\n \"16:00\",\n \"17:00\",\n \"18:00\",\n \"19:00\",\n \"20:00\",\n \"21:00\",\n \"22:00\",\n \"23:00\",\n ],\n days: [\n \"Monday\",\n \"Tuesday\",\n \"Wednesday\",\n \"Thursday\",\n \"Friday\",\n \"Saturday\",\n \"Sunday\",\n ],\n months: [\n \"January\",\n \"February\",\n \"March\",\n \"April\",\n \"May\",\n \"June\",\n \"July\",\n \"August\",\n \"September\",\n \"October\",\n \"November\",\n \"December\",\n ],\n custom: [\n \"Category A\",\n \"Category B\",\n \"Category C\",\n \"Category D\",\n \"Category E\",\n ],\n };\n\n const categories = categoryOptions[categoryType];\n const numberOfPoints = categories.length;\n\n return [...Array(numberOfSeries).keys()].map((seriesIndex) => {\n let nullsArray: ReadonlyArray<number> = [];\n\n if (showNulls) {\n const nullsArrayLength = Math.floor(numberOfPoints / 5);\n nullsArray = [...Array(nullsArrayLength)].map(() =>\n Math.floor(Math.random() * numberOfPoints)\n );\n }\n\n return {\n points: categories.map((category, pointIndex) => {\n const showNull =\n nullsArray && nullsArray.length > 0\n ? nullsArray.includes(pointIndex)\n : false;\n const randomValue = Math.random();\n const positiveOrNegativeYAxisMax = showNegativeValues\n ? randomValue < 0.5\n ? -yAxisMax\n : yAxisMax\n : yAxisMax;\n\n return {\n x: category,\n y: showNull\n ? null\n : Math.floor(randomValue * positiveOrNegativeYAxisMax),\n };\n }),\n name: `Series ${seriesIndex + 1}`,\n styles: {\n color: showCustomColors ? getStorybookRandomColor() : undefined,\n pattern: showDashedLines ? \"dashed\" : \"solid\",\n },\n };\n });\n};\n","import { getStorybookRandomColor } from \"./getStorybookRandomColor\";\n\nexport const getStorybookSparseTimelineData = ({\n showNulls,\n showNegativeValues,\n numberOfSeries,\n yAxisMax,\n showCustomColors,\n showDashedLines,\n numberOfPoints = 5,\n timeSpanHours = 24,\n}: {\n showNulls: boolean;\n showNegativeValues: boolean;\n numberOfSeries: number;\n yAxisMax: number;\n showCustomColors: boolean;\n showDashedLines: boolean;\n numberOfPoints?: number;\n timeSpanHours?: number;\n}) => {\n const seriesNames = [\n \"Posts Published\",\n \"Comments\",\n \"Likes\",\n \"Shares\",\n \"Clicks\",\n \"Views\",\n \"Saves\",\n \"Reposts\",\n \"Mentions\",\n \"Reactions\",\n ];\n\n const baseDate = new Date(\"2024-01-01T00:00:00Z\");\n const timeSpanMs = timeSpanHours * 60 * 60 * 1000;\n\n return [...Array(numberOfSeries).keys()].map((seriesIndex) => {\n let nullsArray: ReadonlyArray<number> = [];\n\n if (showNulls) {\n const nullsArrayLength = Math.floor(numberOfPoints / 5);\n nullsArray = [...Array(nullsArrayLength)].map(() =>\n Math.floor(Math.random() * numberOfPoints)\n );\n }\n\n // Generate random timestamps for this series\n const timestamps = [...Array(numberOfPoints)]\n .map(() => {\n const randomOffset = Math.random() * timeSpanMs;\n return baseDate.getTime() + randomOffset;\n })\n .sort((a, b) => a - b); // Sort chronologically\n\n return {\n points: timestamps.map((timestamp, pointIndex) => {\n const showNull =\n nullsArray && nullsArray.length > 0\n ? nullsArray.includes(pointIndex)\n : false;\n const randomValue = Math.random();\n const positiveOrNegativeYAxisMax = showNegativeValues\n ? randomValue < 0.5\n ? -yAxisMax\n : yAxisMax\n : yAxisMax;\n\n return {\n x: timestamp,\n y: showNull\n ? null\n : Math.floor(randomValue * positiveOrNegativeYAxisMax),\n };\n }),\n name: seriesNames[seriesIndex] || `Series ${seriesIndex + 1}`,\n styles: {\n color: showCustomColors ? getStorybookRandomColor() : undefined,\n pattern: showDashedLines ? \"dashed\" : \"solid\",\n },\n };\n });\n};\n","import type { Options } from \"highcharts\";\nimport _ from \"lodash\";\n\n// options that should apply to all charts\n// this is being exported because it's needed for the listening bubble chart component.\n// when that components gets moved into the data-viz package, we can remove the export here\nexport const baseChartOptions: Options = {\n chart: {\n animation: false,\n styledMode: true,\n },\n credits: {\n enabled: false,\n },\n exporting: {\n enabled: false,\n fallbackToExportServer: false,\n },\n legend: {\n enabled: false,\n },\n title: {\n text: undefined,\n },\n tooltip: {\n hideDelay: 0,\n outside: true,\n padding: 0,\n shape: \"rect\",\n shared: true,\n useHTML: true,\n },\n};\n\n// options that should apply to time series charts\nexport const TIME_SERIES_CHART_HEIGHT = 275;\nexport const timeSeriesChartOptions: Options = _.merge({}, baseChartOptions, {\n annotations: [\n {\n draggable: \"\",\n labelOptions: {\n useHTML: true,\n padding: 0, // removes \"left\" property padding created by highcharts so that label is centered\n },\n },\n ],\n chart: {\n // events.click is set at the component level because of the optional onClick prop\n height: TIME_SERIES_CHART_HEIGHT,\n spacing: [5, 1, 0, 2],\n },\n plotOptions: {\n series: {\n animation: false,\n clip: false,\n marker: {\n enabled: false,\n states: {\n hover: {\n enabled: false,\n },\n },\n },\n },\n },\n xAxis: {\n crosshair: {\n zIndex: 3,\n },\n minPadding: 0, // must be handled dynamically instead of css\n maxPadding: 0, // must be handled dynamically instead of css\n type: \"datetime\",\n labels: {\n useHTML: true,\n // formatter is set at the component level because of the required text locale prop\n },\n },\n yAxis: {\n labels: {\n useHTML: true,\n // formatter is set at the component level because of the optional yAxisLabelFormatter prop\n },\n softMax: 0,\n softMin: 0,\n title: {\n text: undefined,\n },\n plotLines: [\n /* Adds a custom plotLine at y=0 to represent the chart baseline.\n This approach allows full control over the line's appearance (e.g., color, z-index),\n unlike relying on the default xAxis line, which always renders at the bottom of the chart\n even when y=0 appears elsewhere (e.g., with negative values).\n */\n {\n className: \"y-axis-zero-line\",\n value: 0,\n zIndex: 3, // ensures the line appears over the default y=0 line, which we can't seleect as specifically\n },\n ],\n },\n});\n\n// options that should apply to LineChart\nexport const lineChartOptions: Options = _.merge({}, timeSeriesChartOptions, {\n // plotOptions.spline.events.click is set at the component level because of the optional onClick prop\n});\n\n// options that should apply to AreaChart\nexport const areaChartOptions: Options = _.merge({}, timeSeriesChartOptions, {\n plotOptions: {\n areaspline: {\n // events.click is set at the component level because of the optional onClick prop\n stacking: \"normal\",\n },\n },\n});\n\nexport const columnChartOptions: Options = _.merge({}, timeSeriesChartOptions, {\n plotOptions: {\n column: {\n stacking: \"normal\",\n pointPadding: 0.25,\n groupPadding: 0.25,\n borderRadius: 4,\n },\n },\n xAxis: {\n crosshair: false,\n },\n yAxis: {\n plotLines: [\n {\n // For stacked column charts with visible borders (e.g., white for contrast),\n // we raise the zIndex of the y=0 plotLine to ensure it remains visible\n // and isn't visually covered by overlapping column borders.\n zIndex: 5,\n },\n ],\n },\n});\n\n/**\n * The default series limit for VerticalBarChart.\n * This limit is recommended to maintain chart readability and accessibility.\n * @see {VerticalBarChart}\n */\nexport const VERTICAL_BAR_CHART_DEFAULT_SERIES_LIMIT = 10;\n\n// options that should apply to DonutChart\nexport const DONUT_CHART_HALO_SIZE = 10; // 10 is the default from highcharts\nexport const DONUT_CHART_HEIGHT = 250 + DONUT_CHART_HALO_SIZE * 2;\nexport const DONUT_CHART_WIDTH = DONUT_CHART_HEIGHT;\nexport const donutChartOptions: Options = _.merge({}, baseChartOptions, {\n chart: {\n height: DONUT_CHART_HEIGHT,\n spacing: [0, 0, 0, 0],\n },\n plotOptions: {\n pie: {\n animation: false,\n borderRadius: 0, // must be handled here instead of css because of path rendering\n dataLabels: {\n enabled: false,\n },\n innerSize: \"50%\",\n },\n },\n});\n","import { css, createGlobalStyle } from \"styled-components\";\nimport { theme } from \"@sproutsocial/seeds-react-theme\";\nimport {\n type TypeChartStyleColor,\n type TypeChartStyleHasOnClick,\n type TypeChartStylePattern,\n} from \"../types\";\nimport \"highcharts/css/highcharts.css\";\n\nexport const GlobalChartStyleOverrides = createGlobalStyle`\n // USAGE NOTE:\n // Put general styles in baseChartStyles instead when possible to avoid excessive global styling.\n // This global component is only for styles that can't override highcharts defaults when scoped.\n\n .highcharts-tooltip-container {\n z-index: 7 !important;\n }\n .highcharts-tooltip-box {\n fill: transparent !important;\n }\n`;\n\n// options that should apply to all charts\nexport const baseChartStyles = css<\n Readonly<{ $colors: ReadonlyArray<TypeChartStyleColor> }>\n>`\n --highcharts-background-color: ${({ theme }) =>\n theme.colors.container.background.base};\n\n // set color variables and map to each series\n ${({ $colors }) =>\n $colors\n .map((color, index) => {\n const chartColor = color || theme.colors.DATAVIZ_COLORS_LIST[index];\n return `\n\t\t\t\t// map colors to custom assigned colors or fallback to default data viz color rotation\n\t\t\t\t--highcharts-color-${index}: ${chartColor};\n\n\t\t\t\t// highcharts already accounts for 10 series, but if we have more, we need to add them\n\t\t\t\t.highcharts-color-${index} {\n\t\t\t\t\tcolor: var(--highcharts-color-${index});\n\t\t\t\t\tstroke: var(--highcharts-color-${index});\n\t\t\t\t\tfill: var(--highcharts-color-${index});\n\t\t\t\t}`;\n })\n .join(\"\\n\")}\n\n // set overall chart background color\n .highcharts-background {\n fill: ${({ theme }) => theme.colors.container.background.base};\n }\n\n g.highcharts-annotation-label {\n display: none;\n }\n\n div.highcharts-annotation-label {\n top: 0 !important;\n transform: translateX(-50%); // centers the label on the targeted axis point\n pointer-events: none; // prevents tooltip hover from being interrupted by this element since it renders after on the dom\n }\n`;\n\n// options that should apply to time series charts\nexport const timeSeriesChartStyles = css<\n Readonly<{\n $colors: ReadonlyArray<TypeChartStyleColor>;\n $hasOnClick: TypeChartStyleHasOnClick;\n }>\n>`\n ${baseChartStyles}\n\n // vertical crosshair styles\n\t.highcharts-crosshair {\n stroke: ${({ theme }) => theme.colors.container.border.decorative.neutral};\n stroke-width: 1;\n }\n\n // axis and gridline styles\n .highcharts-grid-line {\n stroke: ${({ theme }) => theme.colors.container.border.base};\n }\n\n .highcharts-axis-line {\n stroke: ${({ theme }) => theme.colors.container.border.base};\n }\n\n .highcharts-tick {\n stroke: none;\n }\n .highcharts-xaxis-labels,\n .highcharts-yaxis-labels {\n // v1 HTML labels (useHTML: true). v2 SVG label styles live in\n // charts/shared/styles.ts (axisLabelV2Styles) — don't add v2 rules here.\n > span {\n font-family: ${({ theme }) => theme.fontFamily};\n ${({ theme }) => theme.typography[100]};\n font-weight: ${({ theme }) => theme.fontWeights.normal};\n color: ${({ theme }) => theme.colors.text.subtext};\n }\n }\n .highcharts-xaxis-labels {\n // v1 HTML stacked labels (useHTML: true). v2 SVG stacked-label styles live\n // in charts/shared/styles.ts (axisLabelV2Styles).\n > span {\n display: flex;\n flex-direction: column;\n align-items: center;\n > span:nth-of-type(2) {\n font-weight: ${({ theme }) => theme.fontWeights.semibold};\n }\n }\n }\n\n // we don't want to drop the opacity when another item is hovered\n .highcharts-series-inactive {\n opacity: 1;\n }\n\n // apply cursor pointer when click functionality is turned on\n ${({ $hasOnClick }) =>\n $hasOnClick &&\n `\n \t\t\t.highcharts-series,\n \t\t\t.highcharts-point {\n \t\t\t\tcursor: pointer;\n \t\t\t}\n \t\t\t.highcharts-plot-background,\n \t\t\t.highcharts-crosshair,\n \t\t\t.highcharts-grid-line {\n \t\t\t\tfill: transparent;\n \t\t\t\tcursor: pointer;\n \t\t}`}\n\n path.highcharts-plot-line.y-axis-zero-line {\n stroke: ${({ theme }) => theme.colors.container.border.decorative.neutral};\n }\n`;\n\n// options that should apply to line charts\nexport const lineChartStyles = css<\n Readonly<{\n $colors: ReadonlyArray<TypeChartStyleColor>;\n $patterns: ReadonlyArray<TypeChartStylePattern>;\n $hasOnClick: TypeChartStyleHasOnClick;\n }>\n>`\n ${timeSeriesChartStyles}\n\n // set the line stroke\n\t.highcharts-graph {\n stroke-width: 3;\n }\n\n // dashed line styles\n ${({ $patterns }) =>\n $patterns.map((pattern, index) => {\n return pattern === \"dashed\"\n ? `\n \t\t\t\t\t// highcharts already accounts for 10 series, but if we have more, we need to add them\n \t\t\t\t\t.highcharts-series-${index} {\n \t\t\t\t\t\tstroke-dasharray: 2, 8;\n \t\t\t\t\t}`\n : \"\";\n })}\n`;\n\n// options that should apply to area charts\nexport const areaChartStyles = css`\n ${timeSeriesChartStyles}\n\n // don't need to show a stroke for the line part of each area\n\t.highcharts-graph {\n stroke-width: 0;\n }\n\n // fill areas to full opacity\n .highcharts-area {\n fill-opacity: 1;\n }\n`;\n\n// options that should apply to donut charts\nexport const donutChartStyles = css<\n Readonly<{\n $colors: ReadonlyArray<TypeChartStyleColor>;\n $hasOnClick: TypeChartStyleHasOnClick;\n }>\n>`\n ${baseChartStyles}\n\n // remove 250ms fade in/out when hovering over different donut chart slices\n\t.highcharts-point {\n transition: opacity 0s;\n }\n\n // remove stroke on donut slices\n .highcharts-pie-series .highcharts-point {\n stroke: none;\n }\n\n // don't reduce opacity when hovering\n .highcharts-point-hover {\n fill-opacity: none;\n }\n\n // apply cursor pointer when click functionality is turned on\n ${({ $hasOnClick }) =>\n $hasOnClick &&\n `\n \t\t\t.highcharts-series,\n \t\t\t.highcharts-point {\n \t\t\t\tcursor: pointer;\n \t\t\t}\n \t\t\t.highcharts-plot-background,\n \t\t\t.highcharts-crosshair,\n \t\t\t.highcharts-grid-line {\n \t\t\t\tfill: transparent;\n \t\t\t\tcursor: pointer;\n \t\t}`}\n`;\n","import { memo } from \"react\";\nimport { Box } from \"@sproutsocial/seeds-react-box\";\n\nexport type TypeChartLegendLabelContentWithIconProps = Readonly<{\n children: React.ReactNode;\n // optional\n icon?: React.ReactNode;\n}>;\n\nexport const ChartLegendLabelContentWithIcon =\n memo<TypeChartLegendLabelContentWithIconProps>(\n function ChartLegendLabelContentWithIcon({\n children,\n icon,\n }: TypeChartLegendLabelContentWithIconProps) {\n return icon ? (\n <Box display=\"flex\" alignItems=\"center\" gap={200}>\n {icon}\n {children}\n </Box>\n ) : (\n children\n );\n }\n );\n","import { timeSeriesChartStyles } from \"../../styles/chartStyles\";\nimport { css } from \"styled-components\";\nimport type {\n TypeChartStyleColor,\n TypeChartStyleHasOnClick,\n} from \"../../types\";\n\n// options that should apply to line charts\nexport const verticalBarChartStyles = css<\n Readonly<{\n $colors: ReadonlyArray<TypeChartStyleColor>;\n $hasOnClick: TypeChartStyleHasOnClick;\n }>\n>`\n ${timeSeriesChartStyles}\n\n /*\n When the chart container is hovered, reduce the opacity of all columns.\n Then, for the column that is being hovered, restore its opacity.\n This gives the effect of fading out the non-hovered columns.\n */\n .highcharts-container:hover .highcharts-point {\n fill-opacity: 0.3;\n }\n\n .highcharts-point.column-hover {\n fill-opacity: 1 !important;\n }\n`;\n"],"mappings":"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","names":["jsx","props","theme","theme","jsx","styled","Box","jsx","jsxs","styled","Box","theme","ChartLegendLabel","memo","Box","theme","jsx","memo","ChartLegend","Box","theme","memo","styled","Box","jsx","StyledBox","ChartTooltip","memo","Box","jsx","ChartTooltipFooter","memo","Box","jsx","ChartTooltipHeader","memo","ChartTooltipPortal","memo","styled","Text","jsx","theme","ChartTable","memo","jsx","memo","ChartTooltipTable","memo","Text","jsx","ChartTooltipTitle","theme","css","createGlobalStyle","theme","createGlobalStyle","css","theme","memo","Box","jsxs","ChartLegendLabelContentWithIcon","css"]}