@automattic/charts 2.0.0 → 3.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.
- package/CHANGELOG.md +28 -0
- package/TOKENS.md +107 -48
- package/dist/index.cjs +584 -209
- package/dist/index.cjs.map +1 -1
- package/dist/index.css +97 -43
- package/dist/index.d.cts +46 -41
- package/dist/index.d.ts +46 -41
- package/dist/index.js +582 -210
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
- package/src/charts/area-chart/area-chart.module.scss +8 -3
- package/src/charts/area-chart/area-chart.tsx +3 -5
- package/src/charts/bar-chart/bar-chart.module.scss +14 -6
- package/src/charts/bar-chart/bar-chart.tsx +24 -15
- package/src/charts/bar-chart/private/use-bar-chart-options.ts +197 -30
- package/src/charts/bar-chart/test/bar-chart.test.tsx +685 -1
- package/src/charts/conversion-funnel-chart/conversion-funnel-chart.module.scss +17 -12
- package/src/charts/conversion-funnel-chart/conversion-funnel-chart.tsx +107 -86
- package/src/charts/conversion-funnel-chart/test/chart-scope.test.tsx +36 -0
- package/src/charts/geo-chart/geo-chart.tsx +12 -4
- package/src/charts/heatmap-chart/heatmap-chart.module.scss +13 -9
- package/src/charts/heatmap-chart/heatmap-chart.tsx +12 -5
- package/src/charts/leaderboard-chart/leaderboard-chart.module.scss +13 -7
- package/src/charts/leaderboard-chart/types.ts +0 -2
- package/src/charts/line-chart/line-chart.module.scss +10 -5
- package/src/charts/line-chart/line-chart.tsx +3 -5
- package/src/charts/line-chart/private/line-chart-annotation.tsx +4 -4
- package/src/charts/pie-chart/pie-chart.tsx +4 -1
- package/src/charts/pie-semi-circle-chart/pie-semi-circle-chart.tsx +4 -1
- package/src/charts/private/svg-empty-state/svg-empty-state.module.scss +1 -1
- package/src/charts/private/test/time-axis.test.ts +247 -2
- package/src/charts/private/time-axis.ts +252 -63
- package/src/charts/private/with-responsive/test/with-responsive.test.tsx +16 -0
- package/src/charts/private/with-responsive/with-responsive.tsx +18 -11
- package/src/charts/private/x-zoom/x-zoom.module.scss +3 -3
- package/src/components/legend/private/base-legend.tsx +3 -1
- package/src/components/legend/test/legend.test.tsx +2 -1
- package/src/components/tooltip/accessible-tooltip.tsx +4 -2
- package/src/components/tooltip/base-tooltip.tsx +8 -1
- package/src/components/trend-indicator/test/trend-indicator.test.tsx +22 -1
- package/src/components/trend-indicator/trend-indicator.module.scss +3 -6
- package/src/components/trend-indicator/trend-indicator.tsx +3 -0
- package/src/hooks/test/use-chart-margin.test.tsx +60 -0
- package/src/hooks/test/use-xychart-theme-provider-override.test.tsx +28 -0
- package/src/hooks/test/use-xychart-theme-style-reads.test.tsx +89 -0
- package/src/hooks/test/use-xychart-theme.test.tsx +25 -0
- package/src/hooks/use-chart-margin.tsx +3 -4
- package/src/hooks/use-xychart-theme.ts +19 -11
- package/src/index.ts +9 -2
- package/src/providers/chart-context/global-charts-provider.tsx +35 -12
- package/src/providers/chart-context/private/theme-override-vars.ts +87 -0
- package/src/providers/chart-context/private/with-catalog-pointers.ts +50 -0
- package/src/providers/chart-context/test/chart-context.test.tsx +0 -40
- package/src/providers/chart-context/test/chart-scope-class.test.tsx +19 -0
- package/src/providers/chart-context/test/sparse-theme.test.ts +35 -0
- package/src/providers/chart-context/test/theme-override-vars-guard.test.tsx +29 -0
- package/src/providers/chart-context/test/theme-override-vars.test.ts +118 -0
- package/src/providers/chart-context/test/with-catalog-pointers.test.ts +47 -0
- package/src/providers/chart-context/themes.ts +18 -27
- package/src/providers/chart-context/types.ts +0 -3
- package/src/providers/chart-scope/chart-scope-context.ts +8 -0
- package/src/providers/chart-scope/index.ts +3 -0
- package/src/providers/chart-scope/test/chart-scope.test.tsx +24 -0
- package/src/providers/chart-scope/test/use-standalone-scope-class.test.tsx +20 -0
- package/src/providers/chart-scope/use-chart-scope-element.ts +9 -0
- package/src/providers/chart-scope/use-standalone-scope-class.ts +13 -0
- package/src/providers/index.ts +1 -0
- package/src/styles/chart-scope-class.ts +6 -0
- package/src/styles/chart-scope.scss +83 -0
- package/src/styles/test/chart-scope.test.ts +165 -0
- package/src/types.ts +6 -40
- package/src/utils/index.ts +1 -1
- package/src/utils/resolve-css-var.ts +69 -28
- package/src/utils/test/create-css-variable-resolver.test.ts +83 -0
- package/src/charts/private/grid-control/grid-control.module.scss +0 -8
- package/src/charts/private/grid-control/grid-control.tsx +0 -26
- package/src/charts/private/grid-control/index.ts +0 -1
- package/src/charts/private/grid-control/test/grid-control.test.tsx +0 -56
package/src/types.ts
CHANGED
|
@@ -482,12 +482,12 @@ export type AxisOptions = {
|
|
|
482
482
|
tickClassName?: string;
|
|
483
483
|
tickFormat?: TickFormatter< ScaleInput< AxisScale > >;
|
|
484
484
|
/**
|
|
485
|
-
* Bucket resolution of the data on
|
|
486
|
-
* tick formatter derives tick formats from it
|
|
487
|
-
* inferring the resolution from point spacing.
|
|
488
|
-
*
|
|
489
|
-
*
|
|
490
|
-
* Ignored when `tickFormat` is set.
|
|
485
|
+
* Bucket resolution of the data, set on whichever axis carries the dates.
|
|
486
|
+
* When set, the automatic tick formatter derives tick formats from it
|
|
487
|
+
* directly instead of inferring the resolution from point spacing. For
|
|
488
|
+
* daily-or-finer buckets the overall time span still constrains the choice —
|
|
489
|
+
* e.g. hourly buckets spanning more than a week get date ticks, since hour
|
|
490
|
+
* ticks would be unreadable at that span. Ignored when `tickFormat` is set.
|
|
491
491
|
*/
|
|
492
492
|
tickResolution?: TickResolution;
|
|
493
493
|
/**
|
|
@@ -736,40 +736,6 @@ export type BaseChartProps< T = DataPoint | DataPointDate | LeaderboardEntry > =
|
|
|
736
736
|
};
|
|
737
737
|
};
|
|
738
738
|
|
|
739
|
-
/**
|
|
740
|
-
* Properties for grid components
|
|
741
|
-
*/
|
|
742
|
-
export type GridProps = {
|
|
743
|
-
/**
|
|
744
|
-
* Width of the grid in pixels
|
|
745
|
-
*/
|
|
746
|
-
width: number;
|
|
747
|
-
/**
|
|
748
|
-
* Height of the grid in pixels
|
|
749
|
-
*/
|
|
750
|
-
height: number;
|
|
751
|
-
/**
|
|
752
|
-
* Grid visibility. x is default.
|
|
753
|
-
*/
|
|
754
|
-
gridVisibility?: 'x' | 'y' | 'xy' | 'none';
|
|
755
|
-
/**
|
|
756
|
-
* X-axis scale for the grid
|
|
757
|
-
* TODO: Fix any type after resolving visx scale type issues
|
|
758
|
-
*/
|
|
759
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
760
|
-
xScale: any;
|
|
761
|
-
/**
|
|
762
|
-
* Y-axis scale for the grid
|
|
763
|
-
* TODO: Fix any type after resolving visx scale type issues
|
|
764
|
-
*/
|
|
765
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
766
|
-
yScale: any;
|
|
767
|
-
/**
|
|
768
|
-
* Top offset for the grid
|
|
769
|
-
*/
|
|
770
|
-
top?: number;
|
|
771
|
-
};
|
|
772
|
-
|
|
773
739
|
/**
|
|
774
740
|
* Local type definitions for Popover API attributes and events
|
|
775
741
|
* These are used to avoid extending React module types while still getting type safety
|
package/src/utils/index.ts
CHANGED
|
@@ -30,7 +30,7 @@ export { mergeThemes } from './merge-themes';
|
|
|
30
30
|
export * from './color-utils';
|
|
31
31
|
|
|
32
32
|
// CSS utilities
|
|
33
|
-
export { resolveCssVariable } from './resolve-css-var';
|
|
33
|
+
export { resolveCssVariable, createCssVariableResolver } from './resolve-css-var';
|
|
34
34
|
|
|
35
35
|
// Font sizing utilities
|
|
36
36
|
export { resolveFontSize } from './resolve-font-size';
|
|
@@ -15,34 +15,57 @@ const CSS_VAR_NAME_PATTERN = /^--[\w-]+$/;
|
|
|
15
15
|
* @param element - Optional DOM element to resolve the variable from (defaults to document.documentElement)
|
|
16
16
|
* @return The resolved value, fallback value, or null if unresolvable
|
|
17
17
|
*/
|
|
18
|
-
export const resolveCssVariable = (
|
|
19
|
-
value
|
|
18
|
+
export const resolveCssVariable = ( value: string, element?: HTMLElement | null ): string | null =>
|
|
19
|
+
createCssVariableResolver( element )( value );
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Builds a resolver that reads every value from one `getComputedStyle` snapshot.
|
|
23
|
+
*
|
|
24
|
+
* `getComputedStyle` is the expensive half of resolving a token: each call can force the browser to flush pending style, and a chart theme resolves five roles at once. Taking the snapshot once per build turns that into a single query. The reads that share a snapshot happen synchronously inside one memo body, so no style change can land between them — the resolver is single-pass by design and is not meant to be held across renders.
|
|
25
|
+
*
|
|
26
|
+
* @param element - The element to resolve against, or null/undefined for the document root.
|
|
27
|
+
* @return A resolver that resolves each value exactly as `resolveCssVariable` does.
|
|
28
|
+
*/
|
|
29
|
+
export function createCssVariableResolver(
|
|
20
30
|
element?: HTMLElement | null
|
|
21
|
-
): string | null
|
|
22
|
-
|
|
23
|
-
return null;
|
|
24
|
-
}
|
|
31
|
+
): ( value: string ) => string | null {
|
|
32
|
+
let styles: CSSStyleDeclaration | null = null;
|
|
25
33
|
|
|
26
|
-
//
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
34
|
+
// Deferred so a resolver for a theme that turns out to hold only literals costs nothing. Only a successful read is kept: caching the null would leave a resolver built before its element is in the document dead for the rest of its life.
|
|
35
|
+
const getStyles = () => {
|
|
36
|
+
if ( ! styles ) {
|
|
37
|
+
styles = computedStyleFor( element );
|
|
38
|
+
}
|
|
30
39
|
|
|
31
|
-
|
|
32
|
-
|
|
40
|
+
return styles;
|
|
41
|
+
};
|
|
33
42
|
|
|
34
|
-
|
|
43
|
+
return ( value: string ): string | null => {
|
|
44
|
+
if ( ! value ) {
|
|
45
|
+
return null;
|
|
35
46
|
}
|
|
36
|
-
}
|
|
37
47
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
48
|
+
// Check if it's a var() expression: var(--name) or var(--name, fallback)
|
|
49
|
+
// Parse manually to avoid regex backtracking vulnerabilities
|
|
50
|
+
if ( value.startsWith( 'var(' ) && value.endsWith( ')' ) ) {
|
|
51
|
+
const parsed = parseVarExpression( value );
|
|
52
|
+
|
|
53
|
+
if ( parsed ) {
|
|
54
|
+
const resolved = readCustomProperty( parsed.varName, getStyles() );
|
|
42
55
|
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
}
|
|
56
|
+
return resolved || parsed.fallback;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
// Check if it's a plain variable name (starts with --)
|
|
61
|
+
if ( value.startsWith( '--' ) ) {
|
|
62
|
+
return readCustomProperty( value, getStyles() );
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
// Return regular values as-is (e.g., '#ffffff', 'red')
|
|
66
|
+
return value;
|
|
67
|
+
};
|
|
68
|
+
}
|
|
46
69
|
|
|
47
70
|
/**
|
|
48
71
|
* Parses a var() expression into its variable name and optional fallback.
|
|
@@ -87,24 +110,42 @@ function parseVarExpression( expr: string ): { varName: string; fallback: string
|
|
|
87
110
|
}
|
|
88
111
|
|
|
89
112
|
/**
|
|
90
|
-
*
|
|
113
|
+
* Takes one computed-style snapshot, or null where there is nothing to read (SSR, or a detached element).
|
|
114
|
+
*
|
|
115
|
+
* @param element - The element to read from, or null/undefined for the document root.
|
|
116
|
+
* @return The computed styles, or null.
|
|
117
|
+
*/
|
|
118
|
+
function computedStyleFor( element?: HTMLElement | null ): CSSStyleDeclaration | null {
|
|
119
|
+
if ( typeof window === 'undefined' || typeof document === 'undefined' ) {
|
|
120
|
+
return null;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
try {
|
|
124
|
+
return getComputedStyle( element || document.documentElement );
|
|
125
|
+
} catch {
|
|
126
|
+
// getComputedStyle throws on a detached element.
|
|
127
|
+
return null;
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
/**
|
|
132
|
+
* Reads one custom property from a computed-style snapshot.
|
|
91
133
|
*
|
|
92
134
|
* @param varName - A CSS variable name like '--my-color'
|
|
93
|
-
* @param
|
|
135
|
+
* @param styles - The snapshot to read from, or null
|
|
94
136
|
* @return The computed value or null
|
|
95
137
|
*/
|
|
96
|
-
function
|
|
97
|
-
if (
|
|
138
|
+
function readCustomProperty( varName: string, styles: CSSStyleDeclaration | null ): string | null {
|
|
139
|
+
if ( ! styles ) {
|
|
98
140
|
return null;
|
|
99
141
|
}
|
|
100
142
|
|
|
101
143
|
try {
|
|
102
|
-
const
|
|
103
|
-
const computedValue = getComputedStyle( targetElement ).getPropertyValue( varName ).trim();
|
|
144
|
+
const computedValue = styles.getPropertyValue( varName ).trim();
|
|
104
145
|
|
|
105
146
|
return computedValue || null;
|
|
106
147
|
} catch {
|
|
107
|
-
//
|
|
148
|
+
// Belt and braces — no engine is known to throw here. Kept because a caller may hand in a stand-in for CSSStyleDeclaration; `resolve-css-var.test.ts` covers exactly that.
|
|
108
149
|
return null;
|
|
109
150
|
}
|
|
110
151
|
}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import { createCssVariableResolver } from '../resolve-css-var';
|
|
2
|
+
|
|
3
|
+
describe( 'createCssVariableResolver', () => {
|
|
4
|
+
let originalGetComputedStyle: typeof window.getComputedStyle;
|
|
5
|
+
|
|
6
|
+
beforeEach( () => {
|
|
7
|
+
originalGetComputedStyle = window.getComputedStyle;
|
|
8
|
+
} );
|
|
9
|
+
|
|
10
|
+
afterEach( () => {
|
|
11
|
+
window.getComputedStyle = originalGetComputedStyle;
|
|
12
|
+
} );
|
|
13
|
+
|
|
14
|
+
const mockStyles = ( values: Record< string, string > ) => {
|
|
15
|
+
const spy = jest.fn( () => ( {
|
|
16
|
+
getPropertyValue: ( prop: string ) => values[ prop ] ?? '',
|
|
17
|
+
} ) );
|
|
18
|
+
window.getComputedStyle = spy as unknown as typeof window.getComputedStyle;
|
|
19
|
+
|
|
20
|
+
return spy;
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
it( 'reads many values from a single snapshot', () => {
|
|
24
|
+
const spy = mockStyles( { '--a': '#111', '--b': '#222' } );
|
|
25
|
+
const resolve = createCssVariableResolver();
|
|
26
|
+
|
|
27
|
+
expect( resolve( '--a' ) ).toBe( '#111' );
|
|
28
|
+
expect( resolve( 'var(--b)' ) ).toBe( '#222' );
|
|
29
|
+
expect( spy ).toHaveBeenCalledTimes( 1 );
|
|
30
|
+
} );
|
|
31
|
+
|
|
32
|
+
it( 'takes no snapshot at all for values that need no lookup', () => {
|
|
33
|
+
const spy = mockStyles( {} );
|
|
34
|
+
const resolve = createCssVariableResolver();
|
|
35
|
+
|
|
36
|
+
expect( resolve( '#ffffff' ) ).toBe( '#ffffff' );
|
|
37
|
+
expect( resolve( '' ) ).toBeNull();
|
|
38
|
+
expect( spy ).not.toHaveBeenCalled();
|
|
39
|
+
} );
|
|
40
|
+
|
|
41
|
+
it( 'resolves against the element it was built for', () => {
|
|
42
|
+
const element = document.createElement( 'div' );
|
|
43
|
+
const spy = jest.fn( ( target: Element ) => ( {
|
|
44
|
+
getPropertyValue: () => ( target === element ? '#c029dc' : '#000000' ),
|
|
45
|
+
} ) );
|
|
46
|
+
window.getComputedStyle = spy as unknown as typeof window.getComputedStyle;
|
|
47
|
+
|
|
48
|
+
expect( createCssVariableResolver( element )( '--accent' ) ).toBe( '#c029dc' );
|
|
49
|
+
expect( spy ).toHaveBeenCalledWith( element );
|
|
50
|
+
} );
|
|
51
|
+
|
|
52
|
+
it( 'falls back to the var() fallback when the property is unset', () => {
|
|
53
|
+
mockStyles( {} );
|
|
54
|
+
|
|
55
|
+
expect( createCssVariableResolver()( 'var(--missing, #dbdbdb)' ) ).toBe( '#dbdbdb' );
|
|
56
|
+
} );
|
|
57
|
+
|
|
58
|
+
// A failed read is not cached: a resolver built before its element is in the document would otherwise stay dead for the rest of its life, which is the shape CHARTS-255 introduces.
|
|
59
|
+
it( 'retries after a snapshot that could not be taken', () => {
|
|
60
|
+
const failing = jest.fn( () => {
|
|
61
|
+
throw new Error( 'not attached' );
|
|
62
|
+
} );
|
|
63
|
+
window.getComputedStyle = failing as unknown as typeof window.getComputedStyle;
|
|
64
|
+
|
|
65
|
+
const resolve = createCssVariableResolver();
|
|
66
|
+
expect( resolve( '--a' ) ).toBeNull();
|
|
67
|
+
|
|
68
|
+
mockStyles( { '--a': '#111' } );
|
|
69
|
+
expect( resolve( '--a' ) ).toBe( '#111' );
|
|
70
|
+
} );
|
|
71
|
+
|
|
72
|
+
it( 'matches resolveCssVariable for the values it is given', () => {
|
|
73
|
+
mockStyles( { '--a': '#111' } );
|
|
74
|
+
const resolve = createCssVariableResolver();
|
|
75
|
+
|
|
76
|
+
expect( [
|
|
77
|
+
resolve( '--a' ),
|
|
78
|
+
resolve( 'var(--a)' ),
|
|
79
|
+
resolve( 'var(--z, red)' ),
|
|
80
|
+
resolve( 'red' ),
|
|
81
|
+
] ).toEqual( [ '#111', '#111', 'red', 'red' ] );
|
|
82
|
+
} );
|
|
83
|
+
} );
|
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
import { GridRows, GridColumns } from '@visx/grid';
|
|
2
|
-
import styles from './grid-control.module.scss';
|
|
3
|
-
import type { GridProps } from '../../../types';
|
|
4
|
-
import type { FC } from 'react';
|
|
5
|
-
|
|
6
|
-
const GridControl: FC< GridProps > = ( {
|
|
7
|
-
width,
|
|
8
|
-
height,
|
|
9
|
-
xScale,
|
|
10
|
-
yScale,
|
|
11
|
-
gridVisibility = 'x',
|
|
12
|
-
top = 0,
|
|
13
|
-
} ) => {
|
|
14
|
-
return (
|
|
15
|
-
<g transform={ `translate(0, ${ top })` } className={ styles[ 'grid-control' ] }>
|
|
16
|
-
{ gridVisibility.includes( 'x' ) && (
|
|
17
|
-
<GridRows scale={ xScale } width={ width } data-testid="x-grid" />
|
|
18
|
-
) }
|
|
19
|
-
{ gridVisibility.includes( 'y' ) && (
|
|
20
|
-
<GridColumns scale={ yScale } height={ height } data-testid="y-grid" />
|
|
21
|
-
) }
|
|
22
|
-
</g>
|
|
23
|
-
);
|
|
24
|
-
};
|
|
25
|
-
|
|
26
|
-
export default GridControl;
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export { default as GridControl } from './grid-control';
|
|
@@ -1,56 +0,0 @@
|
|
|
1
|
-
import { render, screen } from '@testing-library/react';
|
|
2
|
-
import { scaleBand, scaleLinear } from '@visx/scale';
|
|
3
|
-
import GridControl from '../grid-control';
|
|
4
|
-
|
|
5
|
-
describe( 'GridControl', () => {
|
|
6
|
-
const defaultProps = {
|
|
7
|
-
width: 200,
|
|
8
|
-
height: 200,
|
|
9
|
-
xScale: scaleBand( { domain: [ 'A', 'B', 'C' ], range: [ 0, 100 ] } ),
|
|
10
|
-
yScale: scaleLinear( { domain: [ 0, 100 ], range: [ 100, 0 ] } ),
|
|
11
|
-
};
|
|
12
|
-
|
|
13
|
-
test( 'renders x-axis grid lines', () => {
|
|
14
|
-
render(
|
|
15
|
-
<svg>
|
|
16
|
-
<GridControl { ...defaultProps } gridVisibility="x" />
|
|
17
|
-
</svg>
|
|
18
|
-
);
|
|
19
|
-
const xGridLines = screen.getAllByTestId( 'x-grid' );
|
|
20
|
-
expect( xGridLines.length ).toBeGreaterThan( 0 );
|
|
21
|
-
expect( screen.queryAllByTestId( 'y-grid' ) ).toHaveLength( 0 );
|
|
22
|
-
} );
|
|
23
|
-
|
|
24
|
-
test( 'renders y-axis grid lines', () => {
|
|
25
|
-
render(
|
|
26
|
-
<svg>
|
|
27
|
-
<GridControl { ...defaultProps } gridVisibility="y" />
|
|
28
|
-
</svg>
|
|
29
|
-
);
|
|
30
|
-
expect( screen.queryAllByTestId( 'x-grid' ) ).toHaveLength( 0 );
|
|
31
|
-
const yGridLines = screen.getAllByTestId( 'y-grid' );
|
|
32
|
-
expect( yGridLines.length ).toBeGreaterThan( 0 );
|
|
33
|
-
} );
|
|
34
|
-
|
|
35
|
-
test( 'renders both axes grid lines', () => {
|
|
36
|
-
render(
|
|
37
|
-
<svg>
|
|
38
|
-
<GridControl { ...defaultProps } gridVisibility="xy" />
|
|
39
|
-
</svg>
|
|
40
|
-
);
|
|
41
|
-
const xGridLines = screen.getAllByTestId( 'x-grid' );
|
|
42
|
-
const yGridLines = screen.getAllByTestId( 'y-grid' );
|
|
43
|
-
expect( xGridLines.length ).toBeGreaterThan( 0 );
|
|
44
|
-
expect( yGridLines.length ).toBeGreaterThan( 0 );
|
|
45
|
-
} );
|
|
46
|
-
|
|
47
|
-
test( 'renders no grid lines when visibility is none', () => {
|
|
48
|
-
render(
|
|
49
|
-
<svg>
|
|
50
|
-
<GridControl { ...defaultProps } gridVisibility="none" />
|
|
51
|
-
</svg>
|
|
52
|
-
);
|
|
53
|
-
expect( screen.queryAllByTestId( 'x-grid' ) ).toHaveLength( 0 );
|
|
54
|
-
expect( screen.queryAllByTestId( 'y-grid' ) ).toHaveLength( 0 );
|
|
55
|
-
} );
|
|
56
|
-
} );
|