Skip to content

Commit a6f08fa

Browse files
committed
Add DonutChart with patterns, useChart hook, and density support
- Donut chart component with configurable patterns - useChart hook for density-aware chart properties - Fill patterns for accessibility - Updated documentation and examples
1 parent bb9f9ad commit a6f08fa

File tree

28 files changed

+977
-1113
lines changed

28 files changed

+977
-1113
lines changed

.changeset/tasty-snakes-clean.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
---
2+
"@salt-ds/highcharts-theme": patch
3+
---
4+
5+
- `useChart` hook is density-aware. When Salt density changes, it triggers a `chart.redraw()` and returns a `legendIconSize` mapped to Salt size tokens, enabling responsive legend symbol sizing.
6+
- Salt theme defaults (styled mode): 20-color palette, vertical right-aligned legend with consistent spacing, larger title/axis-title margins, and line markers disabled by default.
7+
- Type compatibility: expose `HighchartsOptionsCompat` so newer fields (e.g. `plotOptions.pie.borderRadius`) type-check while staying assignable to upstream `Options` across Highcharts v10–v12.
8+
- CSS and usage guidance: import Salt base styles before the Highcharts theme, and wrap charts with `highcharts-theme-salt`; add `salt-fill-patterns` to opt into pattern fills.
9+
Example: `import "@salt-ds/theme/index.css"; import "@salt-ds/highcharts-theme/index.css";`
10+
11+
Includes a Donut chart example using `useDensity` + `useChart` to demonstrate density reactivity and optional pattern fills.

.storybook/preview.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ import "@fontsource/open-sans/800.css";
1313
import "@fontsource/pt-mono";
1414
import "@salt-ds/theme/css/theme-next.css";
1515
import "@salt-ds/theme/index.css";
16+
import "highcharts/css/highcharts.css";
17+
import "@salt-ds/highcharts-theme/index.css";
1618
import "./styles.css";
1719

1820
import { SaltProvider, SaltProviderNext } from "@salt-ds/core";

packages/highcharts-theme/README.md

Lines changed: 69 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ The Salt Highcharts theme overrides the default Highcharts CSS. To ensure the th
3333
> You can download the [Highcharts CSS
3434
> here](https://code.highcharts.com/10.2.0/css/highcharts.css), specifying the
3535
> required version via the URL.
36+
> For more information on loading Highcharts CSS, [visit the Highcharts docs](https://www.highcharts.com/docs/chart-design-and-style/style-by-css).
3637
3738
### Import Salt Highcharts theme
3839

@@ -52,7 +53,7 @@ Then wrap your Highcharts with `highcharts-theme-salt` class name as shown below
5253

5354
### Set Highcharts Global options
5455

55-
Many Highchart stylistic properties cannot be configured via CSS alone. To adhere to the Salt design system, import and set the [Highcharts global options](https://www.highcharts.com/docs/getting-started/how-to-set-options) at your entry point.
56+
Many Highchart stylistic properties can't be configured via CSS alone. To adhere to the Salt design system, import and set the [Highcharts global options](https://www.highcharts.com/docs/getting-started/how-to-set-options) at your entry point.
5657

5758
```js
5859
import Highcharts from "highcharts";
@@ -68,9 +69,72 @@ For granular control, you can also use the `Highcharts.merge()` utility function
6869

6970
To see which Options properties the Salt Highchart Theme package provides, see `src/highcharts-options-salt.ts`.
7071

71-
### Patterns and Fills
72+
## Chart density
7273

73-
The Salt Highcharts theme also provides Salt patterns and fills that can be applied to create visible contrast between series. For example, the `salt-line-patterns` class applies
74-
a line pattern to each series in a Line Chart.
74+
Highcharts doesn't automatically respond to changes in CSS custom properties after the initial render. Use the `useChart` hook to trigger redraws when density changes and to retrieve density‑aware values for your chart options.
7575

76-
Guidance on Fills TBA.
76+
The `useChart` hook takes a `chartRef` and reads the current Salt `density` internally.
77+
78+
```jsx
79+
import { useRef, useMemo } from "react";
80+
import Highcharts from "highcharts";
81+
import HighchartsReact from "highcharts-react-official";
82+
import { useChart } from "@salt-ds/highcharts-theme";
83+
84+
export const DensityAwareChart = () => {
85+
const chartRef = useRef(null);
86+
87+
// Force a redraw and grab density-aware values (density is read internally)
88+
const { legendIconSize } = useChart({ chartRef });
89+
90+
const options = useMemo(
91+
() => ({
92+
chart: { type: "pie" },
93+
legend: {
94+
symbolHeight: legendIconSize,
95+
symbolWidth: legendIconSize,
96+
},
97+
}),
98+
[legendIconSize],
99+
);
100+
101+
return (
102+
<div className="highcharts-theme-salt">
103+
<HighchartsReact
104+
ref={chartRef}
105+
highcharts={Highcharts}
106+
options={options}
107+
/>
108+
</div>
109+
);
110+
};
111+
```
112+
113+
### Patterns and fills
114+
115+
The Salt Highcharts theme provides patterns and fills to create visible contrast between series. This improves accessibility and readability, especially for users who rely on non‑color cues.
116+
117+
#### Line patterns
118+
119+
Apply line patterns to line‑type charts by adding `salt-line-patterns` to the chart container (alongside `highcharts-theme-salt`).
120+
121+
```jsx
122+
<div className="highcharts-theme-salt salt-line-patterns">
123+
<HighchartsReact highcharts={Highcharts} options={yourChartSpecificOptions} />
124+
</div>
125+
```
126+
127+
#### Fill patterns
128+
129+
Apply fill patterns (e.g., for donut/pie/bar) by adding `salt-fill-patterns` to the chart container.
130+
131+
```jsx
132+
<div className="highcharts-theme-salt salt-fill-patterns">
133+
<HighchartsReact highcharts={Highcharts} options={yourChartSpecificOptions} />
134+
</div>
135+
```
136+
137+
Notes:
138+
139+
- Make sure the chart is wrapped with `highcharts-theme-salt` so the Salt theme styles apply.
140+
- Patterns are purely CSS‑driven; Highcharts options don't need to be modified to enable them.
Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
/* Pattern fills for pie/donut charts */
2+
.highcharts-theme-salt.salt-fill-patterns .highcharts-color-0:not(.highcharts-data-label-connector) {
3+
fill: url(#diagonal-up);
4+
}
5+
6+
.highcharts-theme-salt.salt-fill-patterns .highcharts-color-1:not(.highcharts-data-label-connector) {
7+
fill: url(#dot);
8+
}
9+
10+
.highcharts-theme-salt.salt-fill-patterns .highcharts-color-2:not(.highcharts-data-label-connector) {
11+
fill: url(#zigzag);
12+
}
13+
14+
.highcharts-theme-salt.salt-fill-patterns .highcharts-color-3:not(.highcharts-data-label-connector) {
15+
fill: url(#vertical-lines);
16+
}
17+
18+
.highcharts-theme-salt.salt-fill-patterns .highcharts-color-4:not(.highcharts-data-label-connector) {
19+
fill: url(#diagonal-down);
20+
}
21+
22+
.highcharts-theme-salt.salt-fill-patterns .highcharts-color-5:not(.highcharts-data-label-connector) {
23+
fill: url(#upward-point);
24+
}
25+
26+
.highcharts-theme-salt.salt-fill-patterns .highcharts-color-6:not(.highcharts-data-label-connector) {
27+
fill: url(#horizontal-lines);
28+
}
29+
30+
.highcharts-theme-salt.salt-fill-patterns .highcharts-color-7:not(.highcharts-data-label-connector) {
31+
fill: url(#crosshatch);
32+
}
33+
34+
.highcharts-theme-salt.salt-fill-patterns .highcharts-color-8:not(.highcharts-data-label-connector) {
35+
fill: url(#net);
36+
}
37+
38+
.highcharts-theme-salt.salt-fill-patterns .highcharts-color-9:not(.highcharts-data-label-connector) {
39+
fill: url(#steps);
40+
}
41+
42+
.highcharts-theme-salt.salt-fill-patterns .highcharts-color-10:not(.highcharts-data-label-connector) {
43+
fill: url(#pavement);
44+
}
45+
46+
.highcharts-theme-salt.salt-fill-patterns .highcharts-color-11:not(.highcharts-data-label-connector) {
47+
fill: url(#scallop);
48+
}
49+
50+
.highcharts-theme-salt.salt-fill-patterns .highcharts-color-12:not(.highcharts-data-label-connector) {
51+
fill: url(#vertical-wave);
52+
}
53+
54+
.highcharts-theme-salt.salt-fill-patterns .highcharts-color-13:not(.highcharts-data-label-connector) {
55+
fill: url(#metal);
56+
}
57+
58+
.highcharts-theme-salt.salt-fill-patterns .highcharts-color-14:not(.highcharts-data-label-connector) {
59+
fill: url(#scales);
60+
}
61+
62+
.highcharts-theme-salt.salt-fill-patterns .highcharts-color-15:not(.highcharts-data-label-connector) {
63+
fill: url(#triangle);
64+
}
65+
66+
.highcharts-theme-salt.salt-fill-patterns .highcharts-color-16:not(.highcharts-data-label-connector) {
67+
fill: url(#horizontal-wave);
68+
}
69+
70+
.highcharts-theme-salt.salt-fill-patterns .highcharts-color-17:not(.highcharts-data-label-connector) {
71+
fill: url(#cage);
72+
}
73+
74+
.highcharts-theme-salt.salt-fill-patterns .highcharts-color-18:not(.highcharts-data-label-connector) {
75+
fill: url(#line-dot);
76+
}
77+
78+
.highcharts-theme-salt.salt-fill-patterns .highcharts-color-19:not(.highcharts-data-label-connector) {
79+
fill: url(#squares);
80+
}

packages/highcharts-theme/css/salt-highcharts-theme.css

Lines changed: 91 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,60 @@
4848
stroke: var(--salt-category-10-subtle-borderColor);
4949
}
5050

51+
.highcharts-theme-salt .highcharts-color-10 {
52+
fill: var(--salt-category-11-bold-background);
53+
stroke: var(--salt-category-11-subtle-borderColor);
54+
}
55+
56+
.highcharts-theme-salt .highcharts-color-11 {
57+
fill: var(--salt-category-12-bold-background);
58+
stroke: var(--salt-category-12-subtle-borderColor);
59+
}
60+
61+
.highcharts-theme-salt .highcharts-color-12 {
62+
fill: var(--salt-category-13-bold-background);
63+
stroke: var(--salt-category-13-subtle-borderColor);
64+
}
65+
66+
.highcharts-theme-salt .highcharts-color-13 {
67+
fill: var(--salt-category-14-bold-background);
68+
stroke: var(--salt-category-14-subtle-borderColor);
69+
}
70+
71+
.highcharts-theme-salt .highcharts-color-14 {
72+
fill: var(--salt-category-15-bold-background);
73+
stroke: var(--salt-category-15-subtle-borderColor);
74+
}
75+
76+
.highcharts-theme-salt .highcharts-color-15 {
77+
fill: var(--salt-category-16-bold-background);
78+
stroke: var(--salt-category-16-subtle-borderColor);
79+
}
80+
81+
.highcharts-theme-salt .highcharts-color-16 {
82+
fill: var(--salt-category-17-bold-background);
83+
stroke: var(--salt-category-17-subtle-borderColor);
84+
}
85+
86+
.highcharts-theme-salt .highcharts-color-17 {
87+
fill: var(--salt-category-18-bold-background);
88+
stroke: var(--salt-category-18-subtle-borderColor);
89+
}
90+
91+
.highcharts-theme-salt .highcharts-color-18 {
92+
fill: var(--salt-category-19-bold-background);
93+
stroke: var(--salt-category-19-subtle-borderColor);
94+
}
95+
96+
.highcharts-theme-salt .highcharts-color-19 {
97+
fill: var(--salt-category-20-bold-background);
98+
stroke: var(--salt-category-20-subtle-borderColor);
99+
}
100+
101+
.highcharts-theme-salt .highcharts-container {
102+
font-family: var(--salt-text-fontFamily);
103+
}
104+
51105
.highcharts-theme-salt .highcharts-grid-line {
52106
stroke: var(--salt-separable-tertiary-borderColor);
53107
}
@@ -70,11 +124,21 @@
70124

71125
/* Deselected legend state, requires !important to override default styles, which also use !important */
72126
.highcharts-theme-salt .highcharts-legend-item-hidden * {
73-
stroke: revert !important;
74127
fill: revert !important;
75128
opacity: 0.2;
76129
}
77130

131+
/* Unset stroke for the path in a line series legend - specific to line chart and isolated as it adds incorrect stroke to pie chart legend */
132+
.highcharts-theme-salt .highcharts-line-series.highcharts-legend-item-hidden path {
133+
stroke: revert !important;
134+
}
135+
136+
/* Maintain full opacity on legend items during hover. Only reduce opacity when item is hidden */
137+
.highcharts-theme-salt .highcharts-legend-series-active .highcharts-legend-item:not(.highcharts-legend-item-hidden) *,
138+
.highcharts-theme-salt .highcharts-legend-point-active .highcharts-legend-item:not(.highcharts-legend-item-hidden) * {
139+
opacity: 1;
140+
}
141+
78142
.highcharts-theme-salt .highcharts-legend-item > text,
79143
.highcharts-theme-salt .highcharts-legend-item span {
80144
fill: var(--salt-content-secondary-foreground);
@@ -117,6 +181,11 @@
117181
fill: var(--salt-content-secondary-foreground-disabled);
118182
}
119183

184+
.highcharts-theme-salt circle.highcharts-legend-nav-active,
185+
.highcharts-theme-salt circle.highcharts-legend-nav-inactive {
186+
fill: transparent;
187+
}
188+
120189
.highcharts-theme-salt text.highcharts-legend-navigation {
121190
fill: var(--salt-content-secondary-foreground);
122191
font-weight: var(--salt-text-label-fontWeight);
@@ -125,6 +194,27 @@
125194
font-family: var(--salt-text-label-fontFamily);
126195
}
127196

197+
/* Override default stroke for line chart data series hover point circle */
128198
.highcharts-theme-salt .highcharts-point {
129199
stroke: var(--salt-color-white);
130200
}
201+
202+
/* Override default stroke for pie chart segment border */
203+
.highcharts-theme-salt .highcharts-pie-series .highcharts-point {
204+
stroke: var(--salt-container-primary-background);
205+
}
206+
207+
/* Data connector line for Donut/Pie chart */
208+
.highcharts-theme-salt .highcharts-data-label-connector {
209+
fill: none;
210+
}
211+
212+
/* Removes extra hover style for Donut/Pie */
213+
.highcharts-theme-salt .highcharts-halo {
214+
display: none;
215+
}
216+
217+
/* Reduces opacity of deselected segments for Donut/Pie */
218+
.highcharts-theme-salt .highcharts-point-inactive {
219+
opacity: 0.25;
220+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
@import url(css/salt-highcharts-theme.css);
22
@import url(css/salt-highcharts-v11.css);
33
@import url(css/salt-line-patterns.css);
4+
@import url(css/salt-fill-patterns.css);

packages/highcharts-theme/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626
},
2727
"peerDependencies": {
2828
"@salt-ds/theme": "workspace:^",
29-
"highcharts": "^10.2.0",
29+
"highcharts": ">=10 <13",
3030
"highcharts-react-official": "^3.2.2"
3131
}
3232
}
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
declare module "*.css" {
2+
const content: string;
3+
export default content;
4+
}

0 commit comments

Comments
 (0)