diff --git a/package.json b/package.json
index 4696cd8e0..e953461b1 100644
--- a/package.json
+++ b/package.json
@@ -118,7 +118,7 @@
"chalk": "4.1.2",
"clean-webpack-plugin": "^4.0.0",
"concurrently": "^8.0.0",
- "cross-env": "^7.0.3",
+ "cross-env": "^10.1.0",
"css-loader": "^7.1.2",
"eslint": "^8.29.0",
"eslint-config-prettier": "^9.0.0",
@@ -175,5 +175,6 @@
"React",
"Spectrum",
"Charts"
- ]
+ ],
+ "dependencies": {}
}
diff --git a/packages/constants/constants.ts b/packages/constants/constants.ts
index 804518ac8..c1b2c7e26 100644
--- a/packages/constants/constants.ts
+++ b/packages/constants/constants.ts
@@ -18,6 +18,7 @@ export const DEFAULT_AXIS_ANNOTATION_COLOR = 'gray-600';
export const DEFAULT_AXIS_ANNOTATION_OFFSET = 80;
export const DEFAULT_BACKGROUND_COLOR = 'transparent';
export const DEFAULT_BULLET_DIRECTION = 'column';
+export const DEFAULT_GAUGE_DIRECTION = 'column';
export const DEFAULT_CATEGORICAL_DIMENSION = 'category';
export const DEFAULT_COLOR = 'series';
export const DEFAULT_COLOR_SCHEME = 'light';
@@ -35,6 +36,8 @@ export const DEFAULT_LINE_WIDTHS = ['M'];
export const DEFAULT_LINEAR_DIMENSION = 'x';
export const DEFAULT_LOCALE = 'en-US';
export const DEFAULT_METRIC = 'value';
+export const DEFAULT_MAX_ARC_VALUE = 100;
+export const DEFAULT_MIN_ARC_VALUE = 0;
export const DEFAULT_SCALE_TYPE = 'normal';
export const DEFAULT_SCALE_VALUE = 100;
export const DEFAULT_SECONDARY_COLOR = 'subSeries';
diff --git a/packages/docs/docs/api/visualizations/Gauge.md b/packages/docs/docs/api/visualizations/Gauge.md
new file mode 100644
index 000000000..6c8a60c5d
--- /dev/null
+++ b/packages/docs/docs/api/visualizations/Gauge.md
@@ -0,0 +1,62 @@
+## ALPHA RELEASE
+
+Gauge is currently in alpha. This means that the component, behavior and API are all subject to change.
+
+```
+import { Chart, ChartProps } from '@adobe/react-spectrum-charts';
+import { Gauge, GaugeSummary, SegmentLabel } from '@adobe/react-spectrum-charts/rc';
+```
+
+# Gauge
+
+The `Gauge` component is used to display data in a dashboard gauge style.
+
+## Data visualization
+
+Unlike many other chart types, `Gauge` draws two marks (arcs) for a given series, and a mark needle for progression measurement and data tracking. The two arcs shown are the backgrounds arc and the filling color arc, showing the progress based on the current value.
+
+
+## Props
+
+
+
+
+ | name |
+ type |
+ default |
+ description |
+
+
+
+
+ | color |
+ string |
+ 'series' |
+ Key in the data that is used as the color to current value. |
+
+
+ | currVal |
+ number |
+ 75 |
+ The current value tracked and its progress in the gauge. Set to 75 out of 100 by default. |
+
+
+ | metric |
+ number |
+ 'value' |
+ The key in the data that is used for the current value. |
+
+
+ | maxArcValue |
+ number |
+ 100 |
+ The maximum value of the arc in the gauge. Set to 100 by default. |
+
+
+ | minArcValue |
+ number |
+ 0 |
+ The minimum value of the arc in the gauge. Set to 0 by default. |
+
+
+
diff --git a/packages/react-spectrum-charts/src/alpha/components/Gauge/Gauge.tsx b/packages/react-spectrum-charts/src/alpha/components/Gauge/Gauge.tsx
new file mode 100644
index 000000000..f7e541287
--- /dev/null
+++ b/packages/react-spectrum-charts/src/alpha/components/Gauge/Gauge.tsx
@@ -0,0 +1,36 @@
+/*
+ * Copyright 2025 Adobe. All rights reserved.
+ * This file is licensed to you under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License. You may obtain a copy
+ * of the License at http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under
+ * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
+ * OF ANY KIND, either express or implied. See the License for the specific language
+ * governing permissions and limitations under the License.
+ */
+
+/* eslint-disable @typescript-eslint/no-unused-vars */
+import { FC } from 'react';
+
+import {
+ DEFAULT_MAX_ARC_VALUE,
+ DEFAULT_MIN_ARC_VALUE,
+} from '@spectrum-charts/constants';
+
+import { GaugeProps } from '../../../types';
+
+// I assume this houses all the props for all variations of a Gauge chart?
+const Gauge: FC = ({
+ name = 'gauge0',
+ metric = 'currentAmount', // CurrVal
+ minArcValue = DEFAULT_MIN_ARC_VALUE, // Min Arc Value
+ maxArcValue = DEFAULT_MAX_ARC_VALUE, // Max Arc Value
+}) => {
+ return null;
+};
+
+// displayName is used to validate the component type in the spec builder
+Gauge.displayName = 'Gauge';
+
+export { Gauge };
diff --git a/packages/react-spectrum-charts/src/alpha/components/Gauge/index.ts b/packages/react-spectrum-charts/src/alpha/components/Gauge/index.ts
new file mode 100644
index 000000000..72f28c6a1
--- /dev/null
+++ b/packages/react-spectrum-charts/src/alpha/components/Gauge/index.ts
@@ -0,0 +1,13 @@
+/*
+ * Copyright 2025 Adobe. All rights reserved.
+ * This file is licensed to you under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License. You may obtain a copy
+ * of the License at http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under
+ * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
+ * OF ANY KIND, either express or implied. See the License for the specific language
+ * governing permissions and limitations under the License.
+ */
+
+export * from './Gauge';
diff --git a/packages/react-spectrum-charts/src/alpha/components/index.ts b/packages/react-spectrum-charts/src/alpha/components/index.ts
index fedea5918..ea2dcf0e4 100644
--- a/packages/react-spectrum-charts/src/alpha/components/index.ts
+++ b/packages/react-spectrum-charts/src/alpha/components/index.ts
@@ -13,3 +13,4 @@
export * from './Bullet';
export * from './Combo';
export * from './Venn';
+export * from './Gauge/Gauge';
diff --git a/packages/react-spectrum-charts/src/rscToSbAdapter/childrenAdapter.ts b/packages/react-spectrum-charts/src/rscToSbAdapter/childrenAdapter.ts
index 37283ebba..6a4b33744 100644
--- a/packages/react-spectrum-charts/src/rscToSbAdapter/childrenAdapter.ts
+++ b/packages/react-spectrum-charts/src/rscToSbAdapter/childrenAdapter.ts
@@ -18,6 +18,7 @@ import {
ChartPopoverOptions,
ChartTooltipOptions,
DonutSummaryOptions,
+ GaugeOptions,
LegendOptions,
LineOptions,
MarkOptions,
@@ -30,7 +31,7 @@ import {
TrendlineOptions,
} from '@spectrum-charts/vega-spec-builder';
-import { Bullet, Combo, Venn } from '../alpha';
+import { Bullet, Combo, Gauge, Venn } from '../alpha';
import { Annotation } from '../components/Annotation';
import { Area } from '../components/Area';
import { Axis } from '../components/Axis';
@@ -158,6 +159,10 @@ export const childrenToOptions = (
marks.push({ ...child.props, markType: 'bullet' } as BulletOptions);
break;
+ case Gauge.displayName:
+ marks.push({ ...child.props, markType: 'gauge' } as GaugeOptions);
+ break;
+
case ChartPopover.displayName:
chartPopovers.push(getChartPopoverOptions(child.props as ChartPopoverProps));
break;
diff --git a/packages/react-spectrum-charts/src/stories/components/Bullet/Bullet.story.tsx b/packages/react-spectrum-charts/src/stories/components/Bullet/Bullet.story.tsx
index 350e9ac3f..81c4b7536 100644
--- a/packages/react-spectrum-charts/src/stories/components/Bullet/Bullet.story.tsx
+++ b/packages/react-spectrum-charts/src/stories/components/Bullet/Bullet.story.tsx
@@ -39,7 +39,7 @@ const BulletStory: StoryFn =
const { width, height, ...bulletProps } = args;
const chartProps = useChartProps({ ...defaultChartProps, width: width ?? 350, height: height ?? 350 });
return (
-
+
);
diff --git a/packages/react-spectrum-charts/src/stories/components/Gauge/Gauge.story.tsx b/packages/react-spectrum-charts/src/stories/components/Gauge/Gauge.story.tsx
new file mode 100644
index 000000000..5e2d200b1
--- /dev/null
+++ b/packages/react-spectrum-charts/src/stories/components/Gauge/Gauge.story.tsx
@@ -0,0 +1,80 @@
+/*
+ * Copyright 2025 Adobe. All rights reserved.
+ * This file is licensed to you under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License. You may obtain a copy
+ * of the License at http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under
+ * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
+ * OF ANY KIND, either express or implied. See the License for the specific language
+ * governing permissions and limitations under the License.
+ */
+import { ReactElement } from 'react';
+
+import { StoryFn } from '@storybook/react';
+
+import { Chart } from '../../../Chart';
+// Gauge chart component from alpha export
+import { Gauge } from '../../../alpha';
+import { Title } from '../../../components';
+import useChartProps from '../../../hooks/useChartProps';
+import { bindWithProps } from '../../../test-utils';
+import { GaugeProps, ChartProps } from '../../../types';
+import { basicGaugeData } from './data';
+
+export default {
+ title: 'RSC/Gauge (alpha)',
+ component: Gauge,
+};
+
+// Default chart properties
+const defaultChartProps: ChartProps = {
+ data: basicGaugeData,
+ width: 500,
+ height: 600,
+};
+
+// Basic Gauge chart story
+const GaugeStory: StoryFn = (args): ReactElement => {
+ const { width, height, ...gaugeProps } = args;
+ const chartProps = useChartProps({ ...defaultChartProps, width: width ?? 500, height: height ?? 500 });
+ return (
+
+
+
+ );
+};
+
+// Gauge with Title
+const GaugeTitleStory: StoryFn = (args): ReactElement => {
+ const chartProps = useChartProps({ ...defaultChartProps, width: 400 });
+ return (
+
+
+
+
+ );
+};
+
+// Basic Gauge chart story. All the ones below it are variations of the Gauge chart.
+const Basic = bindWithProps(GaugeStory);
+Basic.args = {
+ metric: 'currentAmount',
+ color: 'blue-900',
+};
+
+const GaugeVariation2 = bindWithProps(GaugeStory);
+GaugeVariation2.args = {
+ metric: 'currentAmount',
+ color: 'red-900',
+};
+
+const GaugeVariation3 = bindWithProps(GaugeStory);
+GaugeVariation3.args = {
+ metric: 'currentAmount',
+ color: 'fuchsia-900',
+};
+
+
+
+export { Basic, GaugeVariation2, GaugeVariation3 };
diff --git a/packages/react-spectrum-charts/src/stories/components/Gauge/Gauge.test.tsx b/packages/react-spectrum-charts/src/stories/components/Gauge/Gauge.test.tsx
new file mode 100644
index 000000000..0824494b7
--- /dev/null
+++ b/packages/react-spectrum-charts/src/stories/components/Gauge/Gauge.test.tsx
@@ -0,0 +1,36 @@
+/*
+ * Copyright 2025 Adobe. All rights reserved.
+ * This file is licensed to you under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License. You may obtain a copy
+ * of the License at http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under
+ * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
+ * OF ANY KIND, either express or implied. See the License for the specific language
+ * governing permissions and limitations under the License.
+ */
+import { Gauge } from '../../../alpha';
+import { findChart, findMarksByGroupName, render } from '../../../test-utils';
+import { Basic } from './Gauge.story';
+
+describe('Gauge', () => {
+ // Gauge is not a real React component. This test provides test coverage for sonarqube
+ test('Gauge pseudo element', () => {
+ render();
+ });
+
+ test('Basic gauge renders properly', async () => {
+ render();
+ const chart = await findChart();
+ expect(chart).toBeInTheDocument();
+
+ const backgroundArc = await findMarksByGroupName(chart, 'BackgroundArcRounded');
+ expect(backgroundArc).toBeDefined();
+
+ const fillerArc = await findMarksByGroupName(chart, 'FillerArc');
+ expect(fillerArc).toBeDefined();
+
+ const needleRule = await findMarksByGroupName(chart, 'Needle', 'line');
+ expect(needleRule).toBeDefined();
+ });
+});
diff --git a/packages/react-spectrum-charts/src/stories/components/Gauge/data.ts b/packages/react-spectrum-charts/src/stories/components/Gauge/data.ts
new file mode 100644
index 000000000..8f527fbd3
--- /dev/null
+++ b/packages/react-spectrum-charts/src/stories/components/Gauge/data.ts
@@ -0,0 +1,19 @@
+/*
+ * Copyright 2025 Adobe. All rights reserved.
+ * This file is licensed to you under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License. You may obtain a copy
+ * of the License at http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under
+ * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
+ * OF ANY KIND, either express or implied. See the License for the specific language
+ * governing permissions and limitations under the License.
+ */
+
+
+
+export const basicGaugeData = [
+ { graphLabel: 'Customers', currentAmount: 60, target: 80 },
+];
+
+
diff --git a/packages/react-spectrum-charts/src/types/chart.types.ts b/packages/react-spectrum-charts/src/types/chart.types.ts
index 2cd21f23c..69cb33b5d 100644
--- a/packages/react-spectrum-charts/src/types/chart.types.ts
+++ b/packages/react-spectrum-charts/src/types/chart.types.ts
@@ -36,6 +36,7 @@ import {
ComboElement,
DonutElement,
DonutSummaryElement,
+ GaugeElement,
LineElement,
MetricRangeElement,
ScatterElement,
@@ -54,6 +55,7 @@ export type ChartChildElement =
| BigNumberElement
| DonutElement
| ComboElement
+ | GaugeElement
| LegendElement
| LineElement
| ScatterElement
diff --git a/packages/react-spectrum-charts/src/types/marks/gauge.types.ts b/packages/react-spectrum-charts/src/types/marks/gauge.types.ts
new file mode 100644
index 000000000..d9af24e5e
--- /dev/null
+++ b/packages/react-spectrum-charts/src/types/marks/gauge.types.ts
@@ -0,0 +1,18 @@
+/*
+ * Copyright 2025 Adobe. All rights reserved.
+ * This file is licensed to you under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License. You may obtain a copy
+ * of the License at http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under
+ * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
+ * OF ANY KIND, either express or implied. See the License for the specific language
+ * governing permissions and limitations under the License.
+ */
+import { JSXElementConstructor, ReactElement } from 'react';
+
+import { GaugeOptions } from '@spectrum-charts/vega-spec-builder'; // TODO: update this when GaugeOptions is added
+
+export interface GaugeProps extends Omit {}
+
+export type GaugeElement = ReactElement>;
diff --git a/packages/react-spectrum-charts/src/types/marks/index.ts b/packages/react-spectrum-charts/src/types/marks/index.ts
index 05e62d712..3b71c1ac2 100644
--- a/packages/react-spectrum-charts/src/types/marks/index.ts
+++ b/packages/react-spectrum-charts/src/types/marks/index.ts
@@ -16,6 +16,7 @@ export * from './bigNumber.types';
export * from './bullet.types';
export * from './combo.types';
export * from './donut.types';
+export * from './gauge.types';
export * from './line.types';
export * from './scatter.types';
export * from './venn.types';
diff --git a/packages/react-spectrum-charts/src/utils/utils.ts b/packages/react-spectrum-charts/src/utils/utils.ts
index 712e1084e..ebafc9843 100644
--- a/packages/react-spectrum-charts/src/utils/utils.ts
+++ b/packages/react-spectrum-charts/src/utils/utils.ts
@@ -17,7 +17,7 @@ import { SELECTED_GROUP, SELECTED_ITEM, SELECTED_SERIES, SERIES_ID } from '@spec
import { combineNames, toCamelCase } from '@spectrum-charts/utils';
import { Datum } from '@spectrum-charts/vega-spec-builder';
-import { Bullet, Combo, Venn } from '../alpha';
+import { Bullet, Combo, Gauge, Venn } from '../alpha';
import {
Annotation,
Area,
@@ -56,6 +56,7 @@ import {
ComboElement,
DonutElement,
DonutSummaryElement,
+ GaugeElement,
LegendElement,
LineElement,
MetricRangeElement,
@@ -102,6 +103,7 @@ type ElementCounts = {
scatter: number;
combo: number;
bullet: number;
+ gauge: number;
venn: number;
};
@@ -134,6 +136,7 @@ export const sanitizeChildren = (children: unknown): (ChartChildElement | MarkCh
AxisThumbnail.displayName,
Bar.displayName,
Bullet.displayName,
+ Gauge.displayName,
ChartPopover.displayName,
ChartTooltip.displayName,
Combo.displayName,
@@ -165,6 +168,7 @@ export const sanitizeRscChartChildren = (children: unknown): ChartChildElement[]
Axis.displayName,
Bar.displayName,
Donut.displayName,
+ Gauge.displayName,
Legend.displayName,
Line.displayName,
Scatter.displayName,
@@ -409,6 +413,9 @@ const getElementName = (element: unknown, elementCounts: ElementCounts) => {
case Bullet.displayName:
elementCounts.bullet++;
return getComponentName(element as BulletElement, `bullet${elementCounts.bullet}`);
+ case Gauge.displayName:
+ elementCounts.gauge++;
+ return getComponentName(element as GaugeElement, `gauge${elementCounts.gauge}`);
case Legend.displayName:
elementCounts.legend++;
return getComponentName(element as LegendElement, `legend${elementCounts.legend}`);
@@ -449,6 +456,7 @@ const initElementCounts = (): ElementCounts => ({
line: -1,
scatter: -1,
combo: -1,
+ gauge: -1,
venn: -1,
});
diff --git a/packages/vega-spec-builder/src/chartSpecBuilder.ts b/packages/vega-spec-builder/src/chartSpecBuilder.ts
index a61db2215..928287b7c 100644
--- a/packages/vega-spec-builder/src/chartSpecBuilder.ts
+++ b/packages/vega-spec-builder/src/chartSpecBuilder.ts
@@ -41,6 +41,7 @@ import { addArea } from './area/areaSpecBuilder';
import { addAxis } from './axis/axisSpecBuilder';
import { addBar } from './bar/barSpecBuilder';
import { addBullet } from './bullet/bulletSpecBuilder';
+import { addGauge } from './gauge/gaugeSpecBuilder';
import { addCombo } from './combo/comboSpecBuilder';
import { getSeriesIdTransform } from './data/dataUtils';
import { addDonut } from './donut/donutSpecBuilder';
@@ -128,7 +129,8 @@ export function buildSpec({
spec.signals = getDefaultSignals(options);
spec.scales = getDefaultScales(colors, colorScheme, lineTypes, lineWidths, opacities, symbolShapes, symbolSizes);
- let { areaCount, barCount, bulletCount, comboCount, donutCount, lineCount, scatterCount, vennCount } =
+ // added gaugeCount below
+ let { areaCount, barCount, bulletCount, comboCount, donutCount, gaugeCount, lineCount, scatterCount, vennCount } =
initializeComponentCounts();
const specOptions = { colorScheme, idKey, highlightedItem };
spec = [...marks].reduce((acc: ScSpec, mark) => {
@@ -148,6 +150,9 @@ export function buildSpec({
case 'donut':
donutCount++;
return addDonut(acc, { ...mark, ...specOptions, index: donutCount });
+ case 'gauge':
+ gaugeCount++;
+ return addGauge(acc, { ...mark, ...specOptions, index: gaugeCount });
case 'line':
lineCount++;
return addLine(acc, { ...mark, ...specOptions, index: lineCount });
@@ -217,6 +222,7 @@ const initializeComponentCounts = () => {
comboCount: -1,
donutCount: -1,
bulletCount: -1,
+ gaugeCount: -1,
lineCount: -1,
scatterCount: -1,
vennCount: -1,
diff --git a/packages/vega-spec-builder/src/gauge/gaugeDataUtils.test.ts b/packages/vega-spec-builder/src/gauge/gaugeDataUtils.test.ts
new file mode 100644
index 000000000..6fb00aaa4
--- /dev/null
+++ b/packages/vega-spec-builder/src/gauge/gaugeDataUtils.test.ts
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2025 Adobe. All rights reserved.
+ * This file is licensed to you under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License. You may obtain a copy
+ * of the License at http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under
+ * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
+ * OF ANY KIND, either express or implied. See the License for the specific language
+ * governing permissions and limitations under the License.
+ */
+import { Data } from 'vega';
+import { getGaugeTableData } from './gaugeDataUtils';
+
+describe('getGaugeTableData', () => {
+ it('Should create a new table data if it does not exist', () => {
+ const data: Data[] = [];
+
+ const result = getGaugeTableData(data);
+
+ expect(result.name).toBe('table');
+ expect(result.values).toEqual([]);
+
+ expect(data.length).toBe(1);
+ expect(data[0]).toEqual(result);
+ });
+
+ it('Should return the existing table data if it exists', () => {
+ const existingTableData: Data = {
+ name: 'table',
+ values: [4],
+ };
+ const data: Data[] = [existingTableData];
+
+ const result = getGaugeTableData(data);
+
+ expect(result).toEqual(existingTableData);
+ });
+});
diff --git a/packages/vega-spec-builder/src/gauge/gaugeDataUtils.ts b/packages/vega-spec-builder/src/gauge/gaugeDataUtils.ts
new file mode 100644
index 000000000..8bc25995f
--- /dev/null
+++ b/packages/vega-spec-builder/src/gauge/gaugeDataUtils.ts
@@ -0,0 +1,50 @@
+/*
+ * Copyright 2025 Adobe. All rights reserved.
+ * This file is licensed to you under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License. You may obtain a copy
+ * of the License at http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under
+ * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
+ * OF ANY KIND, either express or implied. See the License for the specific language
+ * governing permissions and limitations under the License.
+ */
+import { Data, ValuesData } from 'vega';
+
+import { TABLE } from '@spectrum-charts/constants';
+
+import { getTableData } from '../data/dataUtils';
+
+/**
+ * Retrieves the gauge table data from the provided data array.
+ * If it doesn't exist, creates and pushes a new one.
+ * @param data The data array.
+ * @returns The gauge table data.
+ */
+export const getGaugeTableData = (data: Data[]): ValuesData => {
+ let tableData = getTableData(data);
+ if (!tableData) {
+ tableData = {
+ name: TABLE,
+ values: [],
+ };
+ data.push(tableData);
+ }
+ return tableData;
+};
+
+/**
+ * Generates the necessary formula transforms for the gauge chart.
+ * It calculates the xPaddingForTarget and, if in flexible scale mode, adds the flexibleScaleValue.
+ * It also generates a color expression for the threshold bars if applicable.
+ * @param gaugeOptions The gauge spec properties.
+ * @returns An array of formula transforms.
+ */
+
+/**
+ * Generates a Vega expression for the color of the gauge chart based on the provided thresholds.
+ * The expression checks the value of the metric field against the thresholds and assigns the appropriate color.
+ * @param defaultColor The default color to use if no thresholds are met.
+ * @returns A string representing the Vega expression for the color.
+ */
+
diff --git a/packages/vega-spec-builder/src/gauge/gaugeMarkUtils.test.ts b/packages/vega-spec-builder/src/gauge/gaugeMarkUtils.test.ts
new file mode 100644
index 000000000..3b2cd2e4c
--- /dev/null
+++ b/packages/vega-spec-builder/src/gauge/gaugeMarkUtils.test.ts
@@ -0,0 +1,74 @@
+/*
+ * Copyright 2025 Adobe. All rights reserved.
+ * This file is licensed to you under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License. You may obtain a copy
+ * of the License at http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under
+ * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
+ * OF ANY KIND, either express or implied. See the License for the specific language
+ * governing permissions and limitations under the License.
+ */
+import { GroupMark } from 'vega';
+
+import {
+ addGaugeMarks,
+ getBackgroundArc,
+ getFillerArc,
+ getNeedle,
+} from './gaugeMarkUtils';
+
+import { defaultGaugeOptions } from './gaugeTestUtils';
+import { spectrumColors } from '../../../themes';
+
+describe('getGaugeMarks', () => {
+ test('Should return the correct marks object', () => {
+ const data = addGaugeMarks([], defaultGaugeOptions);
+ expect(data).toBeDefined();
+ expect(Array.isArray(data)).toBe(true);
+ expect(data).toHaveLength(3);
+ expect(data[0].type).toBe('arc');
+ expect(data[1].type).toBe('arc');
+ expect(data[2].type).toBe('rule');
+ });
+});
+
+
+describe('getGaugeBackgroundArc', () => {
+ test('Should return the correct background arc mark object', () => {
+ const data = getBackgroundArc("backgroundTestName", spectrumColors['light']['blue-200'], spectrumColors['light']['blue-300']);
+ expect(data).toBeDefined();
+ expect(data.encode?.enter).toBeDefined();
+
+ // Expect the correct amount of fields in the update object
+ expect(Object.keys(data.encode?.enter ?? {}).length).toBe(8);
+ });
+});
+
+
+describe('getFillerArc', () => {
+ test('Should return the correct filler arc mark object', () => {
+ const data = getFillerArc("fillerTestName", spectrumColors['light']['magenta-900']);
+ expect(data).toBeDefined();
+
+ expect(data.encode?.update).toBeDefined();
+ expect(Object.keys(data.encode?.update ?? {}).length).toBe(1);
+
+ expect(data.encode?.enter).toBeDefined();
+ expect(Object.keys(data.encode?.enter ?? {}).length).toBe(7)
+ });
+});
+
+
+describe('getGaugeNeedle', () => {
+ test('Should return the needle mark object', () => {
+ const data = getNeedle("needleTestName");
+ expect(data).toBeDefined();
+ expect(data.encode?.update).toBeDefined();
+ expect(Object.keys(data.encode?.update ?? {}).length).toBe(4);
+
+ expect(data.encode?.enter).toBeDefined();
+ expect(Object.keys(data.encode?.enter ?? {}).length).toBe(3)
+ });
+});
+
diff --git a/packages/vega-spec-builder/src/gauge/gaugeMarkUtils.ts b/packages/vega-spec-builder/src/gauge/gaugeMarkUtils.ts
new file mode 100644
index 000000000..a196a84ab
--- /dev/null
+++ b/packages/vega-spec-builder/src/gauge/gaugeMarkUtils.ts
@@ -0,0 +1,100 @@
+/*
+ * Copyright 2025 Adobe. All rights reserved.
+ * This file is licensed to you under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License. You may obtain a copy
+ * of the License at http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under
+ * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
+ * OF ANY KIND, either express or implied. See the License for the specific language
+ * governing permissions and limitations under the License.
+ */
+import { produce } from 'immer';
+import { Mark } from 'vega';
+
+import { DEFAULT_COLOR_SCHEME } from '@spectrum-charts/constants';
+
+import { GaugeSpecOptions } from '../types';
+import { spectrumColors } from '@spectrum-charts/themes';
+
+export const addGaugeMarks = produce((marks, opt) => {
+ const {
+ name,
+ colorScheme = DEFAULT_COLOR_SCHEME,
+ } = opt;
+ const backgroundFill = spectrumColors[colorScheme]['gray-200'];
+ const backgroundStroke = spectrumColors[colorScheme]['gray-300'];
+ const fillerColorSignal = 'fillerColorToCurrVal';
+
+ // Background arc
+ marks.push(getBackgroundArc(name, backgroundFill, backgroundStroke));
+
+ // Filler arc (fills to clampedValue)
+ marks.push(getFillerArc(name, fillerColorSignal));
+
+ // Needle to clampedValue
+ marks.push(getNeedle(name));
+});
+
+export function getBackgroundArc(name: string, fill: string, stroke: string): Mark {
+ return {
+ name: `${name}BackgroundArcRounded`,
+ description: 'Background Arc (Round Edge)',
+ type: 'arc',
+ encode: {
+ enter: {
+ x: { signal: 'centerX' },
+ y: { signal: 'centerY' },
+ innerRadius: { signal: 'innerRadius' },
+ outerRadius: { signal: 'outerRadius' },
+ startAngle: { signal: 'startAngle' },
+ endAngle: { signal: 'endAngle' },
+ fill: { value: fill },
+ stroke: { value: stroke }
+ }
+ }
+ };
+}
+
+export function getFillerArc(name: string, fillerColorSignal: string): Mark {
+ return {
+ name: `${name}FillerArc`,
+ description: 'Filler Arc',
+ type: 'arc',
+ encode: {
+ enter: {
+ x: { signal: 'centerX' },
+ y: { signal: 'centerY' },
+ innerRadius: { signal: 'innerRadius' },
+ outerRadius: { signal: 'outerRadius' },
+ startAngle: { signal: 'startAngle' },
+ endAngle: { signal: 'endAngle' },
+ fill: { signal: fillerColorSignal }
+ },
+ update: {
+ endAngle: { signal: "scale('angleScale', clampedVal)" }
+ }
+ }
+ };
+}
+
+ export function getNeedle(name: string): Mark {
+ return {
+ name: `${name}Needle`,
+ description: 'Needle (rule)',
+ type: 'rule',
+ encode: {
+ enter: {
+ stroke: { value: '#333' },
+ strokeWidth: { value: 3 },
+ strokeCap: { value: 'round' }
+ },
+ update: {
+ x: { signal: 'centerX' },
+ y: { signal: 'centerY' },
+ x2: { signal: 'needleTipX' },
+ y2: { signal: 'needleTipY' }
+ }
+ }
+ };
+}
diff --git a/packages/vega-spec-builder/src/gauge/gaugeSpecBuilder.test.ts b/packages/vega-spec-builder/src/gauge/gaugeSpecBuilder.test.ts
new file mode 100644
index 000000000..cc159950b
--- /dev/null
+++ b/packages/vega-spec-builder/src/gauge/gaugeSpecBuilder.test.ts
@@ -0,0 +1,138 @@
+/*
+ * Copyright 2025 Adobe. All rights reserved.
+ * This file is licensed to you under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License. You may obtain a copy
+ * of the License at http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under
+ * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
+ * OF ANY KIND, either express or implied. See the License for the specific language
+ * governing permissions and limitations under the License.
+ */
+import { GaugeOptions, ScSpec } from '../types';
+import { addGauge, addData, addScales, addSignals } from './gaugeSpecBuilder';
+import { defaultGaugeOptions } from './gaugeTestUtils';
+
+import { getColorValue, spectrumColors } from '../../../themes';
+
+import { DEFAULT_COLOR_SCHEME } from '@spectrum-charts/constants';
+
+const byName = (signals: any[], name: string) => signals.find(s => s.name === name);
+
+describe('addGauge', () => {
+ let spec: ScSpec;
+
+ beforeEach(() => {
+ spec = { data: [], marks: [], scales: [], usermeta: {} };
+ });
+
+ test('should create a spec with gauge chart properties', () => {
+ const newSpec = addGauge(spec, defaultGaugeOptions);
+
+ expect(newSpec).toBeDefined();
+ expect(newSpec).toHaveProperty('data');
+ expect(newSpec).toHaveProperty('marks');
+ expect(newSpec).toHaveProperty('scales');
+ expect(newSpec).toHaveProperty('signals');
+ });
+});
+
+describe('getGaugeScales', () => {
+ test('Should return the correct scale object', () => {
+ const data = addScales([], defaultGaugeOptions);
+ expect(data).toBeDefined();
+ expect(data).toHaveLength(1);
+ expect('range' in data[0] && data[0].range).toBeTruthy();
+ if ('range' in data[0] && data[0].range) {
+ expect(data[0].range[1].signal).toBe('endAngle');
+ }
+ });
+});
+
+describe('getGaugeSignals', () => {
+ test('Should return the correct signals object', () => {
+ const data = addSignals([], defaultGaugeOptions);
+ expect(data).toBeDefined();
+ expect(data).toHaveLength(19);
+ });
+});
+
+describe('getGaugeData', () => {
+ test('Should return the data object', () => {
+ const data = addData([], defaultGaugeOptions);
+ expect(data).toHaveLength(1);
+ });
+});
+
+describe('addGauge (defaults & overrides for gaugeOptions)', () => {
+ let spec: ScSpec;
+
+ beforeEach(() => {
+ spec = { data: [], marks: [], scales: [], usermeta: {} };
+ });
+
+ test('uses defaults when no overrides are provided', () => {
+ const newSpec = addGauge(spec, defaultGaugeOptions);
+
+ expect(newSpec).toBeDefined();
+ expect(newSpec.signals).toBeDefined();
+
+ const signals = newSpec.signals as any[];
+
+ // min/max come from defaults in gaugeOptions
+ expect(byName(signals, 'arcMaxVal')?.value).toBe(100);
+ expect(byName(signals, 'arcMinVal')?.value).toBe(0);
+
+ // default angles: -120° .. +120°
+ expect(byName(signals, 'startAngle')?.update).toBe('-PI * 2 / 3');
+ expect(byName(signals, 'endAngle')?.update).toBe('PI * 2 / 3');
+
+ // default metric is 'currentAmount'
+ expect(byName(signals, 'currVal')?.update).toBe("data('table')[0].currentAmount");
+
+ // background fill from DEFAULT_COLOR_SCHEME
+ const scheme = DEFAULT_COLOR_SCHEME;
+ const expectedBgFill = spectrumColors[scheme]['gray-200'];
+ expect(byName(signals, 'backgroundfillColor')?.value).toBe(expectedBgFill);
+
+ // fillerColorToCurrVal uses light
+ expect(byName(signals, 'fillerColorToCurrVal')?.value).toBe('light');
+ });
+
+ test('applies user overrides (colorScheme, color, min/max, metric, name, index)', () => {
+ const overrides = {
+ ...defaultGaugeOptions,
+ colorScheme: 'dark' as const,
+ color: spectrumColors.dark['yellow-900'],
+ backgroundFill: spectrumColors.dark['gray-200'],
+ minArcValue: 50,
+ maxArcValue: 500,
+ metric: 'myMetric',
+ name: 'Revenue Gauge',
+ index: 2,
+ };
+
+ const newSpec = addGauge(spec, overrides);
+ const signals = newSpec.signals as any[];
+
+ // min/max should reflect overrides
+ expect(byName(signals, 'arcMinVal')?.value).toBe(50);
+ expect(byName(signals, 'arcMaxVal')?.value).toBe(500);
+
+ // metric override reflected in currVal
+ expect(byName(signals, 'currVal')?.update).toBe("data('table')[0].myMetric");
+
+ // background fill should read from dark scheme
+ expect(byName(signals, 'backgroundfillColor')?.value).toBe(spectrumColors.dark['gray-200']);
+
+ // filler color should be computed via getColorValue with dark scheme
+ const expectedFillerDark = getColorValue(spectrumColors.dark['yellow-900'], 'dark');
+ expect(byName(signals, 'fillerColorToCurrVal')?.value).toBe(expectedFillerDark);
+
+ // sanity: start/end angles remain the same defaults
+ expect(byName(signals, 'startAngle')?.update).toBe('-PI * 2 / 3');
+ expect(byName(signals, 'endAngle')?.update).toBe('PI * 2 / 3');
+ });
+
+});
+
diff --git a/packages/vega-spec-builder/src/gauge/gaugeSpecBuilder.ts b/packages/vega-spec-builder/src/gauge/gaugeSpecBuilder.ts
new file mode 100644
index 000000000..cc255b56e
--- /dev/null
+++ b/packages/vega-spec-builder/src/gauge/gaugeSpecBuilder.ts
@@ -0,0 +1,102 @@
+/*
+ * Copyright 2025 Adobe. All rights reserved.
+ * This file is licensed to you under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License. You may obtain a copy
+ * of the License at http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under
+ * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
+ * OF ANY KIND, either express or implied. See the License for the specific language
+ * governing permissions and limitations under the License.
+ */
+import { produce } from 'immer';
+import { Signal, Scale, Data } from 'vega';
+import { addGaugeMarks } from './gaugeMarkUtils';
+
+
+import { DEFAULT_COLOR_SCHEME } from '@spectrum-charts/constants';
+
+// import { getColorValue, spectrumColors } from '@spectrum-charts/themes';
+import { getColorValue, spectrumColors } from '@spectrum-charts/themes';
+import { toCamelCase } from '@spectrum-charts/utils';
+
+import { ColorScheme, GaugeOptions, GaugeSpecOptions, ScSpec } from '../types';
+import { getGaugeTableData } from './gaugeDataUtils';
+
+const DEFAULT_COLOR = spectrumColors.light['blue-900'];
+
+
+/**
+ * Adds a simple Gauge chart to the spec
+ *
+ */
+export const addGauge = produce<
+ ScSpec,
+ [GaugeOptions & { colorScheme?: ColorScheme; index?: number; idKey: string }]
+>(
+ (
+ spec,
+ {
+ colorScheme = DEFAULT_COLOR_SCHEME,
+ index = 0,
+ color = DEFAULT_COLOR,
+ ...options
+ }
+ ) => {
+ const gaugeOptions: GaugeSpecOptions = {
+ backgroundFill: spectrumColors[colorScheme]['gray-200'],
+ backgroundStroke: spectrumColors[colorScheme]['gray-300'],
+ color: getColorValue(color, colorScheme),
+ fillerColorSignal: 'fillerColorToCurrVal',
+ colorScheme: colorScheme,
+ index,
+ maxArcValue: 100,
+ minArcValue: 0,
+ metric: 'currentAmount',
+ name: toCamelCase(name ?? `gauge${index}`),
+ ...options,
+ };
+
+ spec.signals = addSignals(spec.signals ?? [], gaugeOptions);
+ spec.scales = addScales(spec.scales ?? [], gaugeOptions);
+ spec.marks = addGaugeMarks(spec.marks ?? [], gaugeOptions);
+ spec.data = addData(spec.data ?? [], gaugeOptions);
+
+ }
+);
+
+export const addSignals = produce((signals, options) => {
+ signals.push({ name: 'arcMaxVal', value: options.maxArcValue });
+ signals.push({ name: 'arcMinVal', value: options.minArcValue });
+ signals.push({ name: 'backgroundfillColor', value: `${options.backgroundFill}`});
+ signals.push({ name: 'centerX', update: "width/2"})
+ signals.push({ name: 'centerY', update: "height/2 + outerRadius/2"})
+ signals.push({ name: 'clampedVal', update: "min(max(arcMinVal, currVal), arcMaxVal)"})
+ signals.push({ name: 'currVal', update: `data('table')[0].${options.metric}` });
+ signals.push({ name: 'endAngle', update: "PI * 2 / 3" }); // 120 degrees
+ signals.push({ name: 'fillerColorToCurrVal', value: `${options.color}`})
+ signals.push({ name: 'innerRadius', update: "outerRadius - (radiusRef * 0.25)"})
+ signals.push({ name: 'needleAngle', update: "needleAngleOriginal - PI/2"})
+ signals.push({ name: 'needleAngleOriginal', update: "scale('angleScale', clampedVal)"})
+ signals.push({ name: 'needleLength', update: "innerRadius"})
+ signals.push({ name: 'needleTipX', update: "centerX + needleLength * cos(needleAngle)"})
+ signals.push({ name: 'needleTipY', update: "centerY + needleLength * sin(needleAngle)"})
+ signals.push({ name: 'outerRadius', update: "radiusRef * 0.95"})
+ signals.push({ name: 'radiusRef', update: "min(width/2, height/2)"})
+ signals.push({ name: 'startAngle', update: "-PI * 2 / 3" }); // -120 degrees
+ signals.push({ name: 'theta', update: "scale('angleScale', clampedVal)"})
+});
+
+export const addScales = produce((scales, options) => {
+ scales.push({
+ name: 'angleScale',
+ type: 'linear',
+ domain: [{ signal: 'arcMinVal' }, { signal: 'arcMaxVal' }],
+ range: [{ signal: 'startAngle' }, { signal: 'endAngle' }],
+ clamp: true
+ });
+});
+
+export const addData = produce((data, options) => {
+ const tableData = getGaugeTableData(data);
+});
\ No newline at end of file
diff --git a/packages/vega-spec-builder/src/gauge/gaugeTestUtils.ts b/packages/vega-spec-builder/src/gauge/gaugeTestUtils.ts
new file mode 100644
index 000000000..79787257f
--- /dev/null
+++ b/packages/vega-spec-builder/src/gauge/gaugeTestUtils.ts
@@ -0,0 +1,29 @@
+/*
+ * Copyright 2025 Adobe. All rights reserved.
+ * This file is licensed to you under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License. You may obtain a copy
+ * of the License at http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under
+ * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
+ * OF ANY KIND, either express or implied. See the License for the specific language
+ * governing permissions and limitations under the License.
+ */
+import { GaugeSpecOptions } from '../types';
+import { spectrumColors } from '@spectrum-charts/themes';
+import { DEFAULT_COLOR_SCHEME } from '@spectrum-charts/constants';
+import { MARK_ID } from '@spectrum-charts/constants';
+
+export const defaultGaugeOptions: GaugeSpecOptions = {
+ colorScheme: DEFAULT_COLOR_SCHEME,
+ idKey: MARK_ID,
+ index: 5,
+ name: 'gaugeTestName',
+ metric: 'currentAmount',
+ color: DEFAULT_COLOR_SCHEME,
+ minArcValue: 0,
+ maxArcValue: 100,
+ backgroundFill: spectrumColors[DEFAULT_COLOR_SCHEME]['gray-200'],
+ backgroundStroke: spectrumColors[DEFAULT_COLOR_SCHEME]['gray-300'],
+ fillerColorSignal: 'light'
+};
diff --git a/packages/vega-spec-builder/src/types/chartSpec.types.ts b/packages/vega-spec-builder/src/types/chartSpec.types.ts
index 70f415a82..408065b52 100644
--- a/packages/vega-spec-builder/src/types/chartSpec.types.ts
+++ b/packages/vega-spec-builder/src/types/chartSpec.types.ts
@@ -20,6 +20,7 @@ import {
BulletOptions,
ComboOptions,
DonutOptions,
+ GaugeOptions,
LineOptions,
ScatterOptions,
VennOptions,
@@ -58,6 +59,7 @@ export type MarkOptions =
| BulletOptions
| ComboOptions
| DonutOptions
+ | GaugeOptions
| LineOptions
| ScatterOptions
| VennOptions;
diff --git a/packages/vega-spec-builder/src/types/marks/gaugeSpec.types.ts b/packages/vega-spec-builder/src/types/marks/gaugeSpec.types.ts
new file mode 100644
index 000000000..9467cd068
--- /dev/null
+++ b/packages/vega-spec-builder/src/types/marks/gaugeSpec.types.ts
@@ -0,0 +1,50 @@
+/*
+ * Copyright 2025 Adobe. All rights reserved.
+ * This file is licensed to you under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License. You may obtain a copy
+ * of the License at http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under
+ * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
+ * OF ANY KIND, either express or implied. See the License for the specific language
+ * governing permissions and limitations under the License.
+ */
+import { ColorScheme } from '../chartSpec.types';
+import { NumberFormat, PartiallyRequired } from '../specUtil.types';
+
+export type ThresholdBackground = { thresholdMin?: number; thresholdMax?: number; fill?: string };
+
+export interface GaugeOptions {
+ /** Sets the name of the component. */
+ name?: string;
+ /** Key in the data that is used as the metric */
+ metric?: string;
+ /** Key in the data that is used as the color facet */
+ color?: string;
+ /** Minimum value for the scale. This value must be greater than zero, and less than maxArcValue */
+ minArcValue?: number;
+ /** Maximum value for the scale. This value must be greater than zero, and greater than minArcValue */
+ maxArcValue?: number;
+ /** Color of the background arc */
+ backgroundFill?: string;
+ /** Color of the background stroke */
+ backgroundStroke?: string;
+ /** Color of the filler color arc */
+ fillerColorSignal?: string;
+}
+
+type GaugeOptionsWithDefaults =
+ | 'name'
+ | 'metric'
+ | 'color'
+ | 'minArcValue'
+ | 'maxArcValue'
+ | 'backgroundFill'
+ | 'backgroundStroke'
+ | 'fillerColorSignal'
+
+export interface GaugeSpecOptions extends PartiallyRequired {
+ colorScheme: ColorScheme;
+ idKey: string;
+ index: number;
+}
diff --git a/packages/vega-spec-builder/src/types/marks/index.ts b/packages/vega-spec-builder/src/types/marks/index.ts
index b0bc1076f..d84369eae 100644
--- a/packages/vega-spec-builder/src/types/marks/index.ts
+++ b/packages/vega-spec-builder/src/types/marks/index.ts
@@ -14,6 +14,7 @@ export * from './areaSpec.types';
export * from './barSpec.types';
export * from './bigNumberSpec.types';
export * from './bulletSpec.types';
+export * from './gaugeSpec.types';
export * from './comboSpec.types';
export * from './donutSpec.types';
export * from './lineSpec.types';
diff --git a/yarn.lock b/yarn.lock
index 5664a7126..132dd5a3f 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -3078,6 +3078,11 @@
utility-types "^3.10.0"
webpack "^5.88.1"
+"@epic-web/invariant@^1.0.0":
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/@epic-web/invariant/-/invariant-1.0.0.tgz#1073e5dee6dd540410784990eb73e4acd25c9813"
+ integrity sha512-lrTPqgvfFQtR/eY/qkIzp98OGdNJu0m5ji3q/nJI8v3SXkRKEnWiOxMmbvcSoAIzv/cGiuvRy57k4suKQSAdwA==
+
"@es-joy/jsdoccomment@~0.49.0":
version "0.49.0"
resolved "https://registry.yarnpkg.com/@es-joy/jsdoccomment/-/jsdoccomment-0.49.0.tgz#e5ec1eda837c802eca67d3b29e577197f14ba1db"
@@ -8181,15 +8186,10 @@ caniuse-api@^3.0.0:
lodash.memoize "^4.1.2"
lodash.uniq "^4.5.0"
-caniuse-lite@^1.0.0, caniuse-lite@^1.0.30001702, caniuse-lite@^1.0.30001716:
- version "1.0.30001718"
- resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001718.tgz#dae13a9c80d517c30c6197515a96131c194d8f82"
- integrity sha512-AflseV1ahcSunK53NfEs9gFWgOEmzr0f+kaMFA4xiLZlr9Hzt7HxcSpIFcnNCUkz6R6dWKa54rUz3HUmI3nVcw==
-
-caniuse-lite@^1.0.30001669:
- version "1.0.30001677"
- resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001677.tgz#27c2e2c637e007cfa864a16f7dfe7cde66b38b5f"
- integrity sha512-fmfjsOlJUpMWu+mAAtZZZHz7UEwsUxIIvu1TJfO1HqFQvB/B+ii0xr9B5HpbZY/mC4XZ8SvjHJqtAY6pDPQEog==
+caniuse-lite@^1.0.0, caniuse-lite@^1.0.30001669, caniuse-lite@^1.0.30001702, caniuse-lite@^1.0.30001716:
+ version "1.0.30001754"
+ resolved "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001754.tgz"
+ integrity sha512-x6OeBXueoAceOmotzx3PO4Zpt4rzpeIFsSr6AAePTZxSkXiYDUmpypEl7e2+8NCd9bD7bXjqyef8CJYPC1jfxg==
capital-case@^1.0.4:
version "1.0.4"
@@ -8815,14 +8815,15 @@ create-jest@^29.7.0:
jest-util "^29.7.0"
prompts "^2.0.1"
-cross-env@^7.0.3:
- version "7.0.3"
- resolved "https://registry.yarnpkg.com/cross-env/-/cross-env-7.0.3.tgz#865264b29677dc015ba8418918965dd232fc54cf"
- integrity sha512-+/HKd6EgcQCJGh2PSjZuUitQBQynKor4wrFbRg4DtAgS1aWO+gU52xpH7M9ScGgXSYmAVS9bIJ8EzuaGw0oNAw==
+cross-env@^10.1.0:
+ version "10.1.0"
+ resolved "https://registry.yarnpkg.com/cross-env/-/cross-env-10.1.0.tgz#cfd2a6200df9ed75bfb9cb3d7ce609c13ea21783"
+ integrity sha512-GsYosgnACZTADcmEyJctkJIoqAhHjttw7RsFrVoJNXbsWWqaq6Ym+7kZjq6mS45O0jij6vtiReppKQEtqWy6Dw==
dependencies:
- cross-spawn "^7.0.1"
+ "@epic-web/invariant" "^1.0.0"
+ cross-spawn "^7.0.6"
-cross-spawn@^7.0.1, cross-spawn@^7.0.2, cross-spawn@^7.0.3:
+cross-spawn@^7.0.2, cross-spawn@^7.0.3:
version "7.0.3"
resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6"
integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==