@automattic/charts 3.2.0 → 4.0.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.
Files changed (109) hide show
  1. package/CHANGELOG.md +29 -0
  2. package/TOKENS.md +53 -58
  3. package/dist/index.cjs +1012 -542
  4. package/dist/index.cjs.map +1 -1
  5. package/dist/index.css +72 -29
  6. package/dist/index.d.cts +151 -179
  7. package/dist/index.d.ts +151 -179
  8. package/dist/index.js +1013 -544
  9. package/dist/index.js.map +1 -1
  10. package/package.json +6 -6
  11. package/src/charts/area-chart/area-chart.tsx +39 -25
  12. package/src/charts/area-chart/test/area-chart.test.tsx +4 -33
  13. package/src/charts/area-chart/test/tick-placement.test.tsx +55 -0
  14. package/src/charts/area-chart/test/tooltip-resolution-branches.test.tsx +86 -0
  15. package/src/charts/area-chart/test/tooltip-resolution.test.tsx +69 -0
  16. package/src/charts/area-chart/types.ts +4 -7
  17. package/src/charts/bar-chart/bar-chart.tsx +2 -1
  18. package/src/charts/bar-chart/private/test/use-bar-chart-options-formatting.test.tsx +69 -0
  19. package/src/charts/bar-chart/private/use-bar-chart-options.ts +27 -15
  20. package/src/charts/bar-list-chart/bar-list-chart.tsx +5 -0
  21. package/src/charts/conversion-funnel-chart/conversion-funnel-chart.module.scss +33 -23
  22. package/src/charts/conversion-funnel-chart/conversion-funnel-chart.tsx +138 -182
  23. package/src/charts/conversion-funnel-chart/test/conversion-funnel-chart.test.tsx +46 -0
  24. package/src/charts/geo-chart/geo-chart.module.scss +1 -0
  25. package/src/charts/geo-chart/geo-chart.tsx +5 -10
  26. package/src/charts/geo-chart/test/geo-chart.test.tsx +2 -2
  27. package/src/charts/heatmap-chart/heatmap-chart.module.scss +21 -16
  28. package/src/charts/heatmap-chart/heatmap-chart.tsx +45 -28
  29. package/src/charts/heatmap-chart/private/build-calendar-data.ts +3 -0
  30. package/src/charts/heatmap-chart/private/heatmap-legend.tsx +11 -4
  31. package/src/charts/heatmap-chart/test/heatmap-chart.test.tsx +51 -12
  32. package/src/charts/heatmap-chart/types.ts +2 -2
  33. package/src/charts/leaderboard-chart/hooks/use-fitted-row-count.ts +2 -2
  34. package/src/charts/leaderboard-chart/hooks/use-leaderboard-legend-items.ts +3 -5
  35. package/src/charts/leaderboard-chart/leaderboard-chart.module.scss +31 -19
  36. package/src/charts/leaderboard-chart/leaderboard-chart.tsx +27 -17
  37. package/src/charts/leaderboard-chart/test/leaderboard-chart.test.tsx +14 -0
  38. package/src/charts/leaderboard-chart/test/use-leaderboard-legend-items.test.tsx +2 -9
  39. package/src/charts/line-chart/line-chart.module.scss +10 -18
  40. package/src/charts/line-chart/line-chart.tsx +93 -24
  41. package/src/charts/line-chart/private/line-chart-annotation.tsx +18 -19
  42. package/src/charts/line-chart/test/default-tooltip-formatting.test.tsx +74 -0
  43. package/src/charts/line-chart/test/line-chart.test.tsx +27 -3
  44. package/src/charts/line-chart/test/tick-placement.test.tsx +84 -0
  45. package/src/charts/line-chart/test/tooltip-resolution.test.tsx +140 -0
  46. package/src/charts/line-chart/types.ts +4 -1
  47. package/src/charts/pie-chart/pie-chart.module.scss +13 -1
  48. package/src/charts/pie-chart/pie-chart.tsx +30 -40
  49. package/src/charts/pie-chart/test/pie-chart.test.tsx +56 -0
  50. package/src/charts/pie-semi-circle-chart/pie-semi-circle-chart.module.scss +8 -3
  51. package/src/charts/pie-semi-circle-chart/pie-semi-circle-chart.tsx +23 -37
  52. package/src/charts/pie-semi-circle-chart/test/pie-semi-circle-chart.test.tsx +50 -0
  53. package/src/charts/private/chart-layout/chart-layout.module.scss +3 -2
  54. package/src/charts/private/svg-empty-state/svg-empty-state.module.scss +1 -1
  55. package/src/charts/private/test/axis-formatting.test.tsx +85 -0
  56. package/src/charts/private/test/time-axis-formatting.test.ts +109 -0
  57. package/src/charts/private/test/time-axis-options.test.ts +267 -0
  58. package/src/charts/private/test/time-axis-tick-invariants.test.ts +153 -0
  59. package/src/charts/private/test/time-axis-tick-values.test.ts +280 -0
  60. package/src/charts/private/test/time-axis.test.ts +9 -69
  61. package/src/charts/private/time-axis-options.ts +106 -0
  62. package/src/charts/private/time-axis.ts +318 -136
  63. package/src/charts/private/x-zoom/x-zoom.module.scss +3 -3
  64. package/src/charts/private/xy-plot/xy-plot.module.scss +8 -0
  65. package/src/charts/sparkline/test/sparkline.test.tsx +29 -56
  66. package/src/charts/sparkline/types.ts +1 -1
  67. package/src/components/legend/private/base-legend.module.scss +9 -5
  68. package/src/components/tooltip/accessible-tooltip.tsx +13 -15
  69. package/src/components/tooltip/base-tooltip.module.scss +3 -3
  70. package/src/components/tooltip/private/bounded-tooltip.tsx +172 -0
  71. package/src/components/tooltip/test/accessible-tooltip.test.tsx +2 -3
  72. package/src/components/tooltip/test/bounded-tooltip.test.tsx +129 -0
  73. package/src/components/tooltip/test/xy-chart-tooltip.test.tsx +279 -0
  74. package/src/components/tooltip/xy-chart-tooltip.tsx +288 -0
  75. package/src/components/trend-indicator/trend-indicator.module.scss +2 -2
  76. package/src/hooks/test/use-xychart-theme.test.tsx +16 -3
  77. package/src/hooks/use-xychart-theme.ts +25 -9
  78. package/src/index.ts +4 -0
  79. package/src/providers/chart-context/global-charts-provider.tsx +37 -38
  80. package/src/providers/chart-context/hooks/use-chart-formatting.ts +22 -0
  81. package/src/providers/chart-context/index.ts +1 -0
  82. package/src/providers/chart-context/private/catalog-pointers.ts +42 -0
  83. package/src/providers/chart-context/private/series-palette.ts +3 -13
  84. package/src/providers/chart-context/test/{sparse-theme.test.ts → catalog-pointers.test.ts} +22 -10
  85. package/src/providers/chart-context/test/chart-context.test.tsx +177 -792
  86. package/src/providers/chart-context/test/use-global-charts-theme.test.tsx +7 -25
  87. package/src/providers/chart-context/themes.ts +7 -52
  88. package/src/providers/chart-context/types.ts +3 -0
  89. package/src/styles/chart-scope.scss +39 -62
  90. package/src/styles/test/chart-scope.test.ts +19 -47
  91. package/src/test-utils/series-fixtures.ts +31 -0
  92. package/src/types.ts +79 -166
  93. package/src/utils/bucket-info.ts +87 -0
  94. package/src/utils/color-utils.ts +0 -27
  95. package/src/utils/date-formatting.ts +174 -0
  96. package/src/utils/index.ts +3 -0
  97. package/src/utils/test/bucket-info.test.ts +185 -0
  98. package/src/utils/test/color-utils.test.ts +1 -48
  99. package/src/utils/test/date-formatting.test.ts +89 -0
  100. package/src/utils/test/get-styles.test.ts +10 -7
  101. package/src/utils/test/merge-themes.test.ts +18 -46
  102. package/src/visx/types.ts +29 -2
  103. package/src/hooks/test/use-xychart-theme-provider-override.test.tsx +0 -28
  104. package/src/providers/chart-context/private/theme-override-vars.ts +0 -131
  105. package/src/providers/chart-context/private/with-catalog-pointers.ts +0 -93
  106. package/src/providers/chart-context/test/theme-override-vars-guard.test.tsx +0 -29
  107. package/src/providers/chart-context/test/theme-override-vars.test.ts +0 -183
  108. package/src/providers/chart-context/test/with-catalog-pointers.test.ts +0 -104
  109. package/src/styles/test/wpds-fallbacks.test.ts +0 -131
@@ -1,131 +0,0 @@
1
- import { globSync, readFileSync } from 'node:fs';
2
- import { join } from 'node:path';
3
- import dsTokenFallbacks from '@wordpress/theme/postcss-plugins/postcss-ds-token-fallbacks';
4
-
5
- const SOURCE = join( __dirname, '..', '..' );
6
-
7
- // @wordpress/theme publishes its token map only through this plugin. The `Declaration`
8
- // visitor rewrites a declaration's `value` in place and reads nothing else off the node,
9
- // so a synthetic node is enough to ask it what a token is worth. It throws on a token the
10
- // installed design system does not define, which is how a rename surfaces here.
11
- const { Declaration: rewriteValue } = dsTokenFallbacks() as {
12
- Declaration: ( declaration: { value: string } ) => void;
13
- };
14
-
15
- const normalize = ( value: string ): string => value.replace( /\s+/g, ' ' ).trim();
16
-
17
- /**
18
- * Reports the fallback expression the installed design system defines for a token.
19
- *
20
- * @param token - A `--wpds-*` custom property name.
21
- * @return The design system's value for it.
22
- */
23
- function specFallback( token: string ): string {
24
- const declaration = { value: `var(${ token })` };
25
- rewriteValue( declaration );
26
-
27
- // The plugin is expected to throw on a token the design system does not define. Should a
28
- // future version return the reference untouched instead, slicing off a prefix that isn't
29
- // there would yield a fragment of the token name and fail some later assertion with a
30
- // value nothing wrote. Fail here, naming the token, rather than there.
31
- const prefix = `var(${ token }, `;
32
-
33
- if ( ! declaration.value.startsWith( prefix ) || ! declaration.value.endsWith( ')' ) ) {
34
- throw new Error(
35
- `@wordpress/theme did not supply a fallback for ${ token } — got "${ declaration.value }".`
36
- );
37
- }
38
-
39
- return declaration.value.slice( prefix.length, -1 );
40
- }
41
-
42
- type Reference = {
43
- file: string;
44
- token: string;
45
- /** The written fallback, or null where the reference is bare. */
46
- fallback: string | null;
47
- };
48
-
49
- /**
50
- * Finds every `--wpds-*` reference in a file. Scanning for the closing parenthesis by depth, rather than matching a regex, keeps a fallback that is itself a function call or a nested `var()` intact — `cubic-bezier(0.15, 0, 0.15, 1)` and `var(--wp-admin-theme-color, #3858e9)` both end at a parenthesis an inner call opened.
51
- *
52
- * @param source - The file's contents.
53
- * @param file - Its path, relative to `src`.
54
- * @return Every reference the file makes.
55
- */
56
- function referencesIn( source: string, file: string ): Reference[] {
57
- const opener = /var\(\s*(--wpds-[\w-]+)\s*/g;
58
- const references: Reference[] = [];
59
- let match;
60
-
61
- while ( ( match = opener.exec( source ) ) !== null ) {
62
- const token = match[ 1 ];
63
-
64
- if ( source[ opener.lastIndex ] !== ',' ) {
65
- references.push( { file, token, fallback: null } );
66
- continue;
67
- }
68
-
69
- let index = opener.lastIndex + 1;
70
- let depth = 1;
71
-
72
- while ( index < source.length && depth > 0 ) {
73
- if ( source[ index ] === '(' ) {
74
- depth++;
75
- } else if ( source[ index ] === ')' ) {
76
- depth--;
77
- }
78
-
79
- if ( depth > 0 ) {
80
- index++;
81
- }
82
- }
83
-
84
- references.push( {
85
- file,
86
- token,
87
- fallback: normalize( source.slice( opener.lastIndex + 1, index ) ),
88
- } );
89
- }
90
-
91
- return references;
92
- }
93
-
94
- const references = globSync( '**/*.{scss,css,ts,tsx,mdx}', { cwd: SOURCE } )
95
- // Paths are relative to `src`, so a top-level `src/test/` arrives without a leading slash.
96
- .filter( file => ! /(^|\/)test\//.test( file ) )
97
- .flatMap( file => referencesIn( readFileSync( join( SOURCE, file ), 'utf8' ), file ) );
98
-
99
- describe( 'design token references', () => {
100
- it( 'finds the references, so a broken scan cannot pass as a clean one', () => {
101
- expect( references.length ).toBeGreaterThan( 30 );
102
- } );
103
-
104
- // Every fallback here is hand-written, because both of this package's consumption paths
105
- // have to carry it: `@wordpress/build` apps read `dist/`, while webpack apps resolve the
106
- // SCSS through the `jetpack:src` export condition and compile it themselves. Neither
107
- // build injects fallbacks, so a bare reference in a stylesheet renders as nothing at all
108
- // in a host that has not loaded the design-system stylesheet — and WordPress ships none.
109
- //
110
- // A bare reference in TS can be deliberate: `stories/theme-config.tsx` seeds a series
111
- // colour from a token `ThemeProvider` generates, where resolving to nothing is the
112
- // wanted behaviour when no provider is above the chart.
113
- it( 'writes a fallback for every token a stylesheet reads', () => {
114
- expect(
115
- references.filter(
116
- reference => reference.fallback === null && /\.(scss|css)$/.test( reference.file )
117
- )
118
- ).toEqual( [] );
119
- } );
120
-
121
- // This is the check that keeps a hand-written value honest. It is what `499` — a font
122
- // weight that was spec once and drifted — needed and did not have.
123
- it( 'writes the design system value as that fallback', () => {
124
- const drifted = references
125
- .filter( reference => reference.fallback !== null )
126
- .map( reference => ( { ...reference, spec: normalize( specFallback( reference.token ) ) } ) )
127
- .filter( reference => reference.fallback !== reference.spec );
128
-
129
- expect( drifted ).toEqual( [] );
130
- } );
131
- } );