@pie-lib/charting 7.1.0-beta.8 → 8.0.0-next.20261002094057

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 (232) hide show
  1. package/dist/_virtual/_rolldown/runtime.js +20 -0
  2. package/dist/actions-button.d.ts +26 -0
  3. package/dist/actions-button.js +84 -0
  4. package/dist/autosize-input.d.ts +10 -0
  5. package/dist/autosize-input.js +66 -0
  6. package/dist/axes.d.ts +84 -0
  7. package/dist/axes.js +376 -0
  8. package/dist/bars/bar.d.ts +47 -0
  9. package/dist/bars/bar.js +27 -0
  10. package/dist/bars/common/bars.d.ts +98 -0
  11. package/dist/bars/common/bars.js +174 -0
  12. package/dist/bars/common/correct-check-icon.d.ts +18 -0
  13. package/dist/bars/common/correct-check-icon.js +50 -0
  14. package/dist/bars/histogram.d.ts +47 -0
  15. package/dist/bars/histogram.js +28 -0
  16. package/dist/chart-setup.d.ts +29 -0
  17. package/dist/chart-setup.js +231 -0
  18. package/dist/chart-type.d.ts +32 -0
  19. package/dist/chart-type.js +68 -0
  20. package/dist/chart-types.d.ts +41 -0
  21. package/dist/chart-types.js +17 -0
  22. package/dist/chart.d.ts +88 -0
  23. package/dist/chart.js +250 -0
  24. package/dist/common/correctness-indicators.d.ts +70 -0
  25. package/dist/common/correctness-indicators.js +106 -0
  26. package/dist/common/drag-handle.d.ts +129 -0
  27. package/dist/common/drag-handle.js +120 -0
  28. package/dist/common/drag-icon.d.ts +23 -0
  29. package/dist/common/drag-icon.js +45 -0
  30. package/dist/common/styles.d.ts +23 -0
  31. package/dist/common/styles.js +17 -0
  32. package/dist/grid.d.ts +45 -0
  33. package/dist/grid.js +56 -0
  34. package/dist/index.d.ts +14 -0
  35. package/dist/index.js +6 -0
  36. package/dist/key-legend.d.ts +19 -0
  37. package/dist/key-legend.js +46 -0
  38. package/dist/line/common/drag-handle.d.ts +120 -0
  39. package/dist/line/common/drag-handle.js +92 -0
  40. package/dist/line/common/line.d.ts +96 -0
  41. package/dist/line/common/line.js +114 -0
  42. package/dist/line/line-cross.d.ts +47 -0
  43. package/dist/line/line-cross.js +133 -0
  44. package/dist/line/line-dot.d.ts +47 -0
  45. package/dist/line/line-dot.js +101 -0
  46. package/dist/mark-label.d.ts +55 -0
  47. package/dist/mark-label.js +143 -0
  48. package/dist/node_modules/.bun/@visx_axis@4.0.0_d84c32d47042070f/node_modules/@visx/axis/esm/axis/Axis.js +67 -0
  49. package/dist/node_modules/.bun/@visx_axis@4.0.0_d84c32d47042070f/node_modules/@visx/axis/esm/axis/AxisBottom.js +29 -0
  50. package/dist/node_modules/.bun/@visx_axis@4.0.0_d84c32d47042070f/node_modules/@visx/axis/esm/axis/AxisLeft.js +30 -0
  51. package/dist/node_modules/.bun/@visx_axis@4.0.0_d84c32d47042070f/node_modules/@visx/axis/esm/axis/AxisRenderer.js +66 -0
  52. package/dist/node_modules/.bun/@visx_axis@4.0.0_d84c32d47042070f/node_modules/@visx/axis/esm/axis/Ticks.js +39 -0
  53. package/dist/node_modules/.bun/@visx_axis@4.0.0_d84c32d47042070f/node_modules/@visx/axis/esm/constants/orientation.js +9 -0
  54. package/dist/node_modules/.bun/@visx_axis@4.0.0_d84c32d47042070f/node_modules/@visx/axis/esm/utils/createPoint.js +14 -0
  55. package/dist/node_modules/.bun/@visx_axis@4.0.0_d84c32d47042070f/node_modules/@visx/axis/esm/utils/getAxisRangePaddingConfig.js +13 -0
  56. package/dist/node_modules/.bun/@visx_axis@4.0.0_d84c32d47042070f/node_modules/@visx/axis/esm/utils/getLabelTransform.js +16 -0
  57. package/dist/node_modules/.bun/@visx_axis@4.0.0_d84c32d47042070f/node_modules/@visx/axis/esm/utils/getTickFormatter.js +8 -0
  58. package/dist/node_modules/.bun/@visx_axis@4.0.0_d84c32d47042070f/node_modules/@visx/axis/esm/utils/getTickPosition.js +14 -0
  59. package/dist/node_modules/.bun/@visx_grid@4.0.0_d84c32d47042070f/node_modules/@visx/grid/esm/grids/GridColumns.js +46 -0
  60. package/dist/node_modules/.bun/@visx_grid@4.0.0_d84c32d47042070f/node_modules/@visx/grid/esm/grids/GridRows.js +46 -0
  61. package/dist/node_modules/.bun/@visx_grid@4.0.0_d84c32d47042070f/node_modules/@visx/grid/esm/utils/getScaleBandwidth.js +6 -0
  62. package/dist/node_modules/.bun/@visx_group@4.0.0_d84c32d47042070f/node_modules/@visx/group/esm/Group.js +17 -0
  63. package/dist/node_modules/.bun/@visx_point@4.0.0/node_modules/@visx/point/esm/Point.js +20 -0
  64. package/dist/node_modules/.bun/@visx_scale@4.0.0/node_modules/@visx/scale/esm/operators/align.js +6 -0
  65. package/dist/node_modules/.bun/@visx_scale@4.0.0/node_modules/@visx/scale/esm/operators/base.js +6 -0
  66. package/dist/node_modules/.bun/@visx_scale@4.0.0/node_modules/@visx/scale/esm/operators/clamp.js +6 -0
  67. package/dist/node_modules/.bun/@visx_scale@4.0.0/node_modules/@visx/scale/esm/operators/constant.js +6 -0
  68. package/dist/node_modules/.bun/@visx_scale@4.0.0/node_modules/@visx/scale/esm/operators/domain.js +6 -0
  69. package/dist/node_modules/.bun/@visx_scale@4.0.0/node_modules/@visx/scale/esm/operators/exponent.js +6 -0
  70. package/dist/node_modules/.bun/@visx_scale@4.0.0/node_modules/@visx/scale/esm/operators/interpolate.js +10 -0
  71. package/dist/node_modules/.bun/@visx_scale@4.0.0/node_modules/@visx/scale/esm/operators/nice.js +37 -0
  72. package/dist/node_modules/.bun/@visx_scale@4.0.0/node_modules/@visx/scale/esm/operators/padding.js +6 -0
  73. package/dist/node_modules/.bun/@visx_scale@4.0.0/node_modules/@visx/scale/esm/operators/range.js +6 -0
  74. package/dist/node_modules/.bun/@visx_scale@4.0.0/node_modules/@visx/scale/esm/operators/reverse.js +9 -0
  75. package/dist/node_modules/.bun/@visx_scale@4.0.0/node_modules/@visx/scale/esm/operators/round.js +7 -0
  76. package/dist/node_modules/.bun/@visx_scale@4.0.0/node_modules/@visx/scale/esm/operators/scaleOperator.js +56 -0
  77. package/dist/node_modules/.bun/@visx_scale@4.0.0/node_modules/@visx/scale/esm/operators/unknown.js +6 -0
  78. package/dist/node_modules/.bun/@visx_scale@4.0.0/node_modules/@visx/scale/esm/operators/zero.js +9 -0
  79. package/dist/node_modules/.bun/@visx_scale@4.0.0/node_modules/@visx/scale/esm/scales/band.js +9 -0
  80. package/dist/node_modules/.bun/@visx_scale@4.0.0/node_modules/@visx/scale/esm/scales/point.js +9 -0
  81. package/dist/node_modules/.bun/@visx_scale@4.0.0/node_modules/@visx/scale/esm/utils/coerceNumber.js +10 -0
  82. package/dist/node_modules/.bun/@visx_scale@4.0.0/node_modules/@visx/scale/esm/utils/createColorInterpolator.js +29 -0
  83. package/dist/node_modules/.bun/@visx_scale@4.0.0/node_modules/@visx/scale/esm/utils/getTicks.js +7 -0
  84. package/dist/node_modules/.bun/@visx_scale@4.0.0/node_modules/@visx/scale/esm/utils/isUtcScale.js +7 -0
  85. package/dist/node_modules/.bun/@visx_scale@4.0.0/node_modules/@visx/scale/esm/utils/toString.js +6 -0
  86. package/dist/node_modules/.bun/@visx_shape@4.0.0_d84c32d47042070f/node_modules/@visx/shape/esm/shapes/Bar.js +15 -0
  87. package/dist/node_modules/.bun/@visx_shape@4.0.0_d84c32d47042070f/node_modules/@visx/shape/esm/shapes/Circle.js +15 -0
  88. package/dist/node_modules/.bun/@visx_shape@4.0.0_d84c32d47042070f/node_modules/@visx/shape/esm/shapes/Line.js +27 -0
  89. package/dist/node_modules/.bun/@visx_shape@4.0.0_d84c32d47042070f/node_modules/@visx/shape/esm/shapes/LinePath.js +24 -0
  90. package/dist/node_modules/.bun/@visx_shape@4.0.0_d84c32d47042070f/node_modules/@visx/shape/esm/util/D3ShapeFactories.js +9 -0
  91. package/dist/node_modules/.bun/@visx_shape@4.0.0_d84c32d47042070f/node_modules/@visx/shape/esm/util/setNumberOrNumberAccessor.js +6 -0
  92. package/dist/node_modules/.bun/@visx_text@4.0.0_d84c32d47042070f/node_modules/@visx/text/esm/Text.js +27 -0
  93. package/dist/node_modules/.bun/@visx_text@4.0.0_d84c32d47042070f/node_modules/@visx/text/esm/hooks/useText.js +68 -0
  94. package/dist/node_modules/.bun/@visx_text@4.0.0_d84c32d47042070f/node_modules/@visx/text/esm/util/getStringWidth.js +19 -0
  95. package/dist/node_modules/.bun/@visx_text@4.0.0_d84c32d47042070f/node_modules/@visx/text/esm/util/memoize.js +13 -0
  96. package/dist/node_modules/.bun/@visx_vendor@4.0.0/node_modules/@visx/vendor/esm/d3-interpolate.js +8 -0
  97. package/dist/node_modules/.bun/@visx_vendor@4.0.0/node_modules/@visx/vendor/esm/d3-scale.js +8 -0
  98. package/dist/node_modules/.bun/@visx_vendor@4.0.0/node_modules/@visx/vendor/esm/d3-shape.js +8 -0
  99. package/dist/node_modules/.bun/@visx_vendor@4.0.0/node_modules/@visx/vendor/esm/d3-time.js +8 -0
  100. package/dist/node_modules/.bun/balanced-match@0.4.2/node_modules/balanced-match/index.js +32 -0
  101. package/dist/node_modules/.bun/balanced-match@1.0.2/node_modules/balanced-match/index.js +33 -0
  102. package/dist/node_modules/.bun/classnames@2.5.1/node_modules/classnames/index.js +32 -0
  103. package/dist/node_modules/.bun/clsx@2.1.1/node_modules/clsx/dist/clsx.js +16 -0
  104. package/dist/node_modules/.bun/math-expression-evaluator@1.4.0/node_modules/math-expression-evaluator/src/formula_evaluator.js +37 -0
  105. package/dist/node_modules/.bun/math-expression-evaluator@1.4.0/node_modules/math-expression-evaluator/src/lexer.js +509 -0
  106. package/dist/node_modules/.bun/math-expression-evaluator@1.4.0/node_modules/math-expression-evaluator/src/math_function.js +108 -0
  107. package/dist/node_modules/.bun/math-expression-evaluator@1.4.0/node_modules/math-expression-evaluator/src/postfix.js +31 -0
  108. package/dist/node_modules/.bun/math-expression-evaluator@1.4.0/node_modules/math-expression-evaluator/src/postfix_evaluator.js +45 -0
  109. package/dist/node_modules/.bun/reduce-css-calc@1.3.0/node_modules/reduce-css-calc/index.js +49 -0
  110. package/dist/node_modules/.bun/reduce-function-call@1.0.3/node_modules/reduce-function-call/index.js +34 -0
  111. package/dist/plot/common/plot.d.ts +103 -0
  112. package/dist/plot/common/plot.js +227 -0
  113. package/dist/plot/dot.d.ts +47 -0
  114. package/dist/plot/dot.js +62 -0
  115. package/dist/plot/line.d.ts +47 -0
  116. package/dist/plot/line.js +84 -0
  117. package/dist/utils.d.ts +39 -0
  118. package/dist/utils.js +101 -0
  119. package/package.json +45 -36
  120. package/CHANGELOG.json +0 -17
  121. package/CHANGELOG.md +0 -1116
  122. package/lib/actions-button.js +0 -145
  123. package/lib/actions-button.js.map +0 -1
  124. package/lib/axes.js +0 -643
  125. package/lib/axes.js.map +0 -1
  126. package/lib/bars/bar.js +0 -58
  127. package/lib/bars/bar.js.map +0 -1
  128. package/lib/bars/common/bars.js +0 -277
  129. package/lib/bars/common/bars.js.map +0 -1
  130. package/lib/bars/common/correct-check-icon.js +0 -54
  131. package/lib/bars/common/correct-check-icon.js.map +0 -1
  132. package/lib/bars/histogram.js +0 -59
  133. package/lib/bars/histogram.js.map +0 -1
  134. package/lib/chart-setup.js +0 -382
  135. package/lib/chart-setup.js.map +0 -1
  136. package/lib/chart-type.js +0 -80
  137. package/lib/chart-type.js.map +0 -1
  138. package/lib/chart-types.js +0 -22
  139. package/lib/chart-types.js.map +0 -1
  140. package/lib/chart.js +0 -384
  141. package/lib/chart.js.map +0 -1
  142. package/lib/common/correctness-indicators.js +0 -156
  143. package/lib/common/correctness-indicators.js.map +0 -1
  144. package/lib/common/drag-handle.js +0 -160
  145. package/lib/common/drag-handle.js.map +0 -1
  146. package/lib/common/drag-icon.js +0 -52
  147. package/lib/common/drag-icon.js.map +0 -1
  148. package/lib/common/styles.js +0 -22
  149. package/lib/common/styles.js.map +0 -1
  150. package/lib/grid.js +0 -112
  151. package/lib/grid.js.map +0 -1
  152. package/lib/index.js +0 -42
  153. package/lib/index.js.map +0 -1
  154. package/lib/key-legend.js +0 -87
  155. package/lib/key-legend.js.map +0 -1
  156. package/lib/line/common/drag-handle.js +0 -146
  157. package/lib/line/common/drag-handle.js.map +0 -1
  158. package/lib/line/common/line.js +0 -214
  159. package/lib/line/common/line.js.map +0 -1
  160. package/lib/line/line-cross.js +0 -214
  161. package/lib/line/line-cross.js.map +0 -1
  162. package/lib/line/line-dot.js +0 -158
  163. package/lib/line/line-dot.js.map +0 -1
  164. package/lib/mark-label.js +0 -237
  165. package/lib/mark-label.js.map +0 -1
  166. package/lib/plot/common/plot.js +0 -349
  167. package/lib/plot/common/plot.js.map +0 -1
  168. package/lib/plot/dot.js +0 -110
  169. package/lib/plot/dot.js.map +0 -1
  170. package/lib/plot/line.js +0 -140
  171. package/lib/plot/line.js.map +0 -1
  172. package/lib/tool-menu.js +0 -106
  173. package/lib/tool-menu.js.map +0 -1
  174. package/lib/utils.js +0 -189
  175. package/lib/utils.js.map +0 -1
  176. package/src/__tests__/actions-button.test.jsx +0 -280
  177. package/src/__tests__/axes.test.jsx +0 -667
  178. package/src/__tests__/chart-setup.test.jsx +0 -532
  179. package/src/__tests__/chart-type.test.jsx +0 -23
  180. package/src/__tests__/chart.test.jsx +0 -86
  181. package/src/__tests__/grid.test.jsx +0 -37
  182. package/src/__tests__/key-legend.test.jsx +0 -223
  183. package/src/__tests__/mark-label.test.jsx +0 -33
  184. package/src/__tests__/tool-menu.test.jsx +0 -522
  185. package/src/__tests__/utils.js +0 -36
  186. package/src/__tests__/utils.test.js +0 -100
  187. package/src/actions-button.jsx +0 -115
  188. package/src/axes.jsx +0 -594
  189. package/src/bars/__tests__/bar.test.jsx +0 -45
  190. package/src/bars/__tests__/histogram.test.jsx +0 -45
  191. package/src/bars/__tests__/utils.js +0 -30
  192. package/src/bars/bar.js +0 -28
  193. package/src/bars/common/__tests__/bars.test.jsx +0 -68
  194. package/src/bars/common/__tests__/utils.js +0 -30
  195. package/src/bars/common/bars.jsx +0 -249
  196. package/src/bars/common/correct-check-icon.jsx +0 -25
  197. package/src/bars/histogram.js +0 -28
  198. package/src/chart-setup.jsx +0 -356
  199. package/src/chart-type.js +0 -59
  200. package/src/chart-types.js +0 -8
  201. package/src/chart.jsx +0 -357
  202. package/src/common/__tests__/correctness-indicators.test.jsx +0 -720
  203. package/src/common/__tests__/drag-handle.test.jsx +0 -58
  204. package/src/common/__tests__/utils.js +0 -30
  205. package/src/common/correctness-indicators.jsx +0 -128
  206. package/src/common/drag-handle.jsx +0 -125
  207. package/src/common/drag-icon.jsx +0 -36
  208. package/src/common/styles.js +0 -19
  209. package/src/grid.jsx +0 -80
  210. package/src/index.js +0 -7
  211. package/src/key-legend.jsx +0 -77
  212. package/src/line/__tests__/line-cross.test.jsx +0 -463
  213. package/src/line/__tests__/line-dot.test.jsx +0 -41
  214. package/src/line/__tests__/utils.js +0 -36
  215. package/src/line/common/__tests__/drag-handle.test.jsx +0 -62
  216. package/src/line/common/__tests__/line.test.jsx +0 -79
  217. package/src/line/common/__tests__/utils.js +0 -30
  218. package/src/line/common/drag-handle.jsx +0 -114
  219. package/src/line/common/line.jsx +0 -171
  220. package/src/line/line-cross.js +0 -144
  221. package/src/line/line-dot.js +0 -111
  222. package/src/mark-label.jsx +0 -238
  223. package/src/plot/__tests__/dot.test.jsx +0 -344
  224. package/src/plot/__tests__/line.test.jsx +0 -375
  225. package/src/plot/__tests__/utils.js +0 -30
  226. package/src/plot/common/__tests__/plot.test.jsx +0 -69
  227. package/src/plot/common/__tests__/utils.js +0 -30
  228. package/src/plot/common/plot.jsx +0 -358
  229. package/src/plot/dot.js +0 -74
  230. package/src/plot/line.js +0 -98
  231. package/src/tool-menu.jsx +0 -85
  232. package/src/utils.js +0 -201
@@ -1,667 +0,0 @@
1
- import React from 'react';
2
- import { fireEvent, render } from '@pie-lib/test-utils';
3
- import { createTheme, ThemeProvider } from '@mui/material/styles';
4
- import ChartAxes, { RawChartAxes, TickComponent } from '../axes';
5
- import { createBandScale, graphProps } from './utils';
6
-
7
- jest.mock('@visx/axis', () => ({
8
- AxisLeft: ({ children, ...props }) => (
9
- <g data-testid="axis-left" {...props}>
10
- {typeof children === 'function' ? children({ formattedValue: '5' }) : children}
11
- </g>
12
- ),
13
- AxisBottom: ({ children, tickValues, ...props }) => (
14
- <g data-testid="axis-bottom" {...props}>
15
- {typeof children === 'function'
16
- ? (tickValues || ['0-A', '1-B', '2-C']).map((v, i) => children({ formattedValue: v, index: i }))
17
- : children}
18
- </g>
19
- ),
20
- }));
21
-
22
- jest.mock('../mark-label', () => {
23
- return function MarkLabel({ mark, disabled, onChange, error, autoFocus, inputRef, correctnessIndicator }) {
24
- return (
25
- <div data-testid="mark-label">
26
- <input
27
- data-testid="mark-label-input"
28
- ref={inputRef}
29
- value={mark?.label || ''}
30
- disabled={disabled}
31
- onChange={(e) => onChange && onChange(e.target.value)}
32
- autoFocus={autoFocus}
33
- />
34
- {error && <span data-testid="mark-label-error">{error}</span>}
35
- {correctnessIndicator}
36
- </div>
37
- );
38
- };
39
- });
40
-
41
- jest.mock('@pie-lib/config-ui', () => ({
42
- AlertDialog: ({ open, title, text, onClose, onConfirm }) =>
43
- open ? (
44
- <div data-testid="alert-dialog">
45
- <h2>{title}</h2>
46
- <p>{text}</p>
47
- <button data-testid="alert-cancel" onClick={onClose}>
48
- Cancel
49
- </button>
50
- <button data-testid="alert-confirm" onClick={onConfirm}>
51
- Confirm
52
- </button>
53
- </div>
54
- ) : null,
55
- }));
56
-
57
- jest.mock('../common/correctness-indicators', () => ({
58
- TickCorrectnessIndicator: ({ correctness, interactive }) =>
59
- correctness && interactive ? (
60
- <div data-testid="tick-correctness-indicator">{correctness.value === 'correct' ? '✓' : '✗'}</div>
61
- ) : null,
62
- }));
63
-
64
- jest.mock('@pie-lib/math-rendering', () => ({
65
- renderMath: jest.fn((text) => text),
66
- }));
67
-
68
- const theme = createTheme();
69
-
70
- describe('ChartAxes', () => {
71
- const renderComponent = (extras) => {
72
- const defaults = {
73
- classes: {},
74
- className: 'className',
75
- graphProps: graphProps(),
76
- xBand: createBandScale(['a', 'b', 'c'], [0, 400]),
77
- categories: [],
78
- };
79
- const props = { ...defaults, ...extras };
80
- return render(
81
- <ThemeProvider theme={theme}>
82
- <svg>
83
- <ChartAxes {...props} />
84
- </svg>
85
- </ThemeProvider>,
86
- );
87
- };
88
-
89
- describe('rendering', () => {
90
- it('renders axes container', () => {
91
- const { container } = renderComponent();
92
- expect(container.firstChild).toBeInTheDocument();
93
- });
94
-
95
- it('renders SVG with axes group', () => {
96
- const { container } = renderComponent();
97
- const svg = container.querySelector('svg');
98
- expect(svg).toBeInTheDocument();
99
- const axesGroup = container.querySelector('g');
100
- expect(axesGroup).toBeInTheDocument();
101
- });
102
-
103
- it('renders axes elements', () => {
104
- const { container } = renderComponent();
105
- const groups = container.querySelectorAll('g');
106
- expect(groups.length).toBeGreaterThan(0);
107
- });
108
- });
109
-
110
- describe('edge cases', () => {
111
- it('handles missing xBand', () => {
112
- const { container } = renderComponent({ xBand: undefined });
113
- expect(container).toBeInTheDocument();
114
- });
115
-
116
- it('handles empty categories', () => {
117
- const { container } = renderComponent({ categories: [] });
118
- expect(container).toBeInTheDocument();
119
- });
120
-
121
- it('handles null categories', () => {
122
- const { container } = renderComponent({ categories: null });
123
- expect(container).toBeInTheDocument();
124
- });
125
- });
126
- });
127
-
128
- describe('RawChartAxes', () => {
129
- const renderComponent = (extras) => {
130
- const defaults = {
131
- classes: {},
132
- className: 'className',
133
- graphProps: graphProps(),
134
- xBand: createBandScale(['a', 'b', 'c'], [0, 400]),
135
- categories: [],
136
- };
137
- const props = { ...defaults, ...extras };
138
- return render(
139
- <ThemeProvider theme={theme}>
140
- <svg>
141
- <RawChartAxes {...props} />
142
- </svg>
143
- </ThemeProvider>,
144
- );
145
- };
146
-
147
- describe('rendering', () => {
148
- it('renders raw axes container', () => {
149
- const { container } = renderComponent();
150
- expect(container.firstChild).toBeInTheDocument();
151
- });
152
-
153
- it('renders SVG with axes group', () => {
154
- const { container } = renderComponent();
155
- const svg = container.querySelector('svg');
156
- expect(svg).toBeInTheDocument();
157
- const axesGroup = container.querySelector('g');
158
- expect(axesGroup).toBeInTheDocument();
159
- });
160
-
161
- it('renders both axes when leftAxis is true', () => {
162
- const { getByTestId } = renderComponent({ leftAxis: true });
163
- expect(getByTestId('axis-left')).toBeInTheDocument();
164
- expect(getByTestId('axis-bottom')).toBeInTheDocument();
165
- });
166
-
167
- it('renders only bottom axis when leftAxis is false', () => {
168
- const { queryByTestId, getByTestId } = renderComponent({ leftAxis: false });
169
- expect(queryByTestId('axis-left')).not.toBeInTheDocument();
170
- expect(getByTestId('axis-bottom')).toBeInTheDocument();
171
- });
172
- });
173
- });
174
-
175
- describe('TickComponent', () => {
176
- const defaultCategories = [
177
- { value: 1, label: 'Category A', editable: true, interactive: true },
178
- { value: 2, label: 'Category B', editable: true, interactive: true },
179
- ];
180
-
181
- const renderComponent = (extras) => {
182
- const defaults = {
183
- graphProps: graphProps(),
184
- xBand: createBandScale(['a', 'b', 'c'], [0, 400]),
185
- categories: defaultCategories,
186
- formattedValue: '0-Category A',
187
- bandWidth: 100,
188
- barWidth: 100,
189
- x: 50,
190
- y: 50,
191
- top: 0,
192
- onChangeCategory: jest.fn(),
193
- };
194
- const props = { ...defaults, ...extras };
195
- return render(
196
- <ThemeProvider theme={theme}>
197
- <svg>
198
- <TickComponent {...props} />
199
- </svg>
200
- </ThemeProvider>,
201
- );
202
- };
203
-
204
- describe('rendering', () => {
205
- it('renders tick component', () => {
206
- const { container } = renderComponent();
207
- const svg = container.querySelector('svg');
208
- expect(svg).toBeInTheDocument();
209
- expect(container.querySelector('g')).toBeInTheDocument();
210
- });
211
-
212
- it('renders with categories', () => {
213
- const { container } = renderComponent({
214
- formattedValue: '0-test',
215
- categories: [{ value: 1, label: 'test', editable: false, interactive: false }],
216
- });
217
- const svg = container.querySelector('svg');
218
- expect(svg).toBeInTheDocument();
219
- expect(container.querySelector('g')).toBeInTheDocument();
220
- });
221
-
222
- it('renders MarkLabel component', () => {
223
- const { getAllByTestId } = renderComponent();
224
- const markLabels = getAllByTestId('mark-label');
225
- expect(markLabels.length).toBeGreaterThan(0);
226
- });
227
-
228
- it('renders foreignObject for labels', () => {
229
- const { container } = renderComponent();
230
- const foreignObject = container.querySelector('foreignObject');
231
- expect(foreignObject).toBeInTheDocument();
232
- });
233
-
234
- it('does not render when formattedValue is null', () => {
235
- const { container } = renderComponent({ formattedValue: null });
236
- const foreignObject = container.querySelector('foreignObject');
237
- expect(foreignObject).not.toBeInTheDocument();
238
- });
239
-
240
- it('does not render when formattedValue is undefined', () => {
241
- const { container } = renderComponent({ formattedValue: undefined });
242
- const foreignObject = container.querySelector('foreignObject');
243
- expect(foreignObject).not.toBeInTheDocument();
244
- });
245
-
246
- it('renders hidden label for longest category', () => {
247
- const { getAllByTestId } = renderComponent();
248
- const markLabels = getAllByTestId('mark-label');
249
- expect(markLabels.length).toBeGreaterThan(0);
250
- });
251
- });
252
-
253
- describe('category label editing', () => {
254
- it('allows editing category label', () => {
255
- const onChangeCategory = jest.fn();
256
- const { getAllByTestId } = renderComponent({ onChangeCategory });
257
-
258
- const inputs = getAllByTestId('mark-label-input');
259
- const input = inputs[inputs.length - 1];
260
- fireEvent.change(input, { target: { value: 'New Label' } });
261
-
262
- expect(onChangeCategory).toHaveBeenCalled();
263
- });
264
-
265
- it('calls changeCategory with correct parameters', () => {
266
- const onChangeCategory = jest.fn();
267
- const { getAllByTestId } = renderComponent({ onChangeCategory });
268
-
269
- const inputs = getAllByTestId('mark-label-input');
270
- const input = inputs[inputs.length - 1];
271
- fireEvent.change(input, { target: { value: 'Updated' } });
272
-
273
- expect(onChangeCategory).toHaveBeenCalledWith(0, expect.objectContaining({ label: 'Updated' }));
274
- });
275
-
276
- it('disables editing when editable is false', () => {
277
- const categories = [{ value: 1, label: 'test', editable: false, interactive: true }];
278
- const { getAllByTestId } = renderComponent({ categories, formattedValue: '0-test' });
279
-
280
- const inputs = getAllByTestId('mark-label-input');
281
- const input = inputs[inputs.length - 1];
282
- expect(input).toBeDisabled();
283
- });
284
-
285
- it('enables editing in define chart mode', () => {
286
- const categories = [{ value: 1, label: 'test', editable: true, interactive: true }];
287
- const { getAllByTestId } = renderComponent({
288
- categories,
289
- formattedValue: '0-test',
290
- defineChart: true,
291
- });
292
-
293
- const inputs = getAllByTestId('mark-label-input');
294
- const input = inputs[inputs.length - 1];
295
- expect(input).not.toBeDisabled();
296
- });
297
-
298
- it('respects editable property when not in define chart mode', () => {
299
- const categories = [{ value: 1, label: 'test', editable: true, interactive: true }];
300
- const { getAllByTestId } = renderComponent({
301
- categories,
302
- formattedValue: '0-test',
303
- defineChart: false,
304
- });
305
-
306
- const inputs = getAllByTestId('mark-label-input');
307
- const input = inputs[inputs.length - 1];
308
- expect(input).not.toBeDisabled();
309
- });
310
- });
311
-
312
- describe('interactive checkbox', () => {
313
- it('shows warning when disabling interactive with correct answer', () => {
314
- const categories = [
315
- {
316
- value: 1,
317
- label: 'test',
318
- editable: true,
319
- interactive: true,
320
- correctness: { value: 'correct' },
321
- },
322
- ];
323
- const component = new TickComponent({
324
- categories,
325
- onChangeCategory: jest.fn(),
326
- });
327
-
328
- component.setState = jest.fn();
329
- component.changeInteractive(0, false);
330
-
331
- expect(component.setState).toHaveBeenCalledWith(
332
- expect.objectContaining({
333
- dialog: expect.objectContaining({
334
- open: true,
335
- title: 'Warning',
336
- }),
337
- }),
338
- );
339
- });
340
-
341
- it('changes interactive without warning when enabling', () => {
342
- const onChangeCategory = jest.fn();
343
- const categories = [{ value: 1, label: 'test', editable: true, interactive: false }];
344
- const component = new TickComponent({
345
- categories,
346
- onChangeCategory,
347
- });
348
-
349
- component.changeInteractive(0, true);
350
-
351
- expect(onChangeCategory).toHaveBeenCalledWith(0, expect.objectContaining({ interactive: true }));
352
- });
353
- });
354
-
355
- describe('editable checkbox', () => {
356
- it('shows warning when disabling editable with correct answer name', () => {
357
- const categories = [
358
- {
359
- value: 1,
360
- label: 'test',
361
- editable: true,
362
- interactive: true,
363
- correctness: { value: 'correct' },
364
- },
365
- ];
366
- const component = new TickComponent({
367
- categories,
368
- onChangeCategory: jest.fn(),
369
- });
370
-
371
- component.setState = jest.fn();
372
- component.changeEditable(0, false);
373
-
374
- expect(component.setState).toHaveBeenCalledWith(
375
- expect.objectContaining({
376
- dialog: expect.objectContaining({
377
- open: true,
378
- title: 'Warning',
379
- }),
380
- }),
381
- );
382
- });
383
-
384
- it('changes editable without warning when enabling', () => {
385
- const onChangeCategory = jest.fn();
386
- const categories = [{ value: 1, label: 'test', editable: false, interactive: true }];
387
- const component = new TickComponent({
388
- categories,
389
- onChangeCategory,
390
- });
391
-
392
- component.changeEditable(0, true);
393
-
394
- expect(onChangeCategory).toHaveBeenCalledWith(0, expect.objectContaining({ editable: true }));
395
- });
396
- });
397
-
398
- describe('splitText method', () => {
399
- it('splits text into chunks', () => {
400
- const component = new TickComponent({ categories: [] });
401
- const result = component.splitText('This is a long text', 10);
402
-
403
- expect(result.length).toBeGreaterThan(1);
404
- });
405
-
406
- it('splits at word boundaries', () => {
407
- const component = new TickComponent({ categories: [] });
408
- const result = component.splitText('Hello world test', 11);
409
-
410
- expect(result[0]).toBe('Hello world');
411
- });
412
-
413
- it('handles text shorter than max', () => {
414
- const component = new TickComponent({ categories: [] });
415
- const result = component.splitText('Short', 20);
416
-
417
- expect(result).toEqual(['Short']);
418
- });
419
-
420
- it('handles empty text', () => {
421
- const component = new TickComponent({ categories: [] });
422
- const result = component.splitText('', 10);
423
-
424
- expect(result).toEqual([]);
425
- });
426
-
427
- it('handles null text', () => {
428
- const component = new TickComponent({ categories: [] });
429
- const result = component.splitText(null, 10);
430
-
431
- expect(result).toEqual([]);
432
- });
433
-
434
- it('forces split when no spaces', () => {
435
- const component = new TickComponent({ categories: [] });
436
- const result = component.splitText('verylongwordwithoutspaces', 10);
437
-
438
- expect(result.length).toBeGreaterThan(1);
439
- expect(result[0].length).toBeLessThanOrEqual(10);
440
- });
441
- });
442
-
443
- describe('correctness display', () => {
444
- it('renders correctness indicator when showCorrectness is true', () => {
445
- const categories = [
446
- {
447
- value: 1,
448
- label: 'test',
449
- editable: true,
450
- interactive: true,
451
- correctness: { value: 'correct', label: 'Correct!' },
452
- },
453
- ];
454
- const { getByTestId } = renderComponent({
455
- categories,
456
- formattedValue: '0-test',
457
- showCorrectness: true,
458
- });
459
-
460
- expect(getByTestId('tick-correctness-indicator')).toBeInTheDocument();
461
- });
462
-
463
- it('does not render correctness indicator when showCorrectness is false', () => {
464
- const categories = [
465
- {
466
- value: 1,
467
- label: 'test',
468
- editable: true,
469
- interactive: true,
470
- correctness: { value: 'correct', label: 'Correct!' },
471
- },
472
- ];
473
- const { queryByTestId } = renderComponent({
474
- categories,
475
- formattedValue: '0-test',
476
- showCorrectness: false,
477
- });
478
-
479
- expect(queryByTestId('tick-correctness-indicator')).not.toBeInTheDocument();
480
- });
481
-
482
- it('does not render correctness indicator when not interactive', () => {
483
- const categories = [
484
- {
485
- value: 1,
486
- label: 'test',
487
- editable: true,
488
- interactive: false,
489
- correctness: { value: 'correct', label: 'Correct!' },
490
- },
491
- ];
492
- const { queryByTestId } = renderComponent({
493
- categories,
494
- formattedValue: '0-test',
495
- showCorrectness: true,
496
- });
497
-
498
- expect(queryByTestId('tick-correctness-indicator')).not.toBeInTheDocument();
499
- });
500
- });
501
-
502
- describe('error display', () => {
503
- it('renders error message for first category', () => {
504
- const error = { 0: 'Error message' };
505
- const { getByTestId } = renderComponent({
506
- error,
507
- formattedValue: '0-test',
508
- });
509
-
510
- expect(getByTestId('mark-label-error')).toBeInTheDocument();
511
- });
512
-
513
- it('renders distinct error messages', () => {
514
- const error = { 0: 'Error 1', 1: 'Error 1', 2: 'Error 2' };
515
- const { container } = renderComponent({
516
- error,
517
- formattedValue: '0-test',
518
- });
519
-
520
- const errorText = container.querySelector('text');
521
- expect(errorText).toBeInTheDocument();
522
- });
523
-
524
- it('does not render error when no error prop', () => {
525
- const { queryByTestId } = renderComponent({ error: null });
526
- expect(queryByTestId('mark-label-error')).not.toBeInTheDocument();
527
- });
528
- });
529
-
530
- describe('autoFocus handling', () => {
531
- it('handles autoFocus prop', () => {
532
- const onAutoFocusUsed = jest.fn();
533
- const { rerender } = renderComponent({
534
- autoFocus: false,
535
- onAutoFocusUsed,
536
- });
537
-
538
- rerender(
539
- <ThemeProvider theme={theme}>
540
- <svg>
541
- <TickComponent
542
- {...{
543
- graphProps: graphProps(),
544
- xBand: createBandScale(['a', 'b', 'c'], [0, 400]),
545
- categories: defaultCategories,
546
- formattedValue: '0-Category A',
547
- bandWidth: 100,
548
- barWidth: 100,
549
- x: 50,
550
- y: 50,
551
- top: 0,
552
- onChangeCategory: jest.fn(),
553
- autoFocus: true,
554
- onAutoFocusUsed,
555
- }}
556
- />
557
- </svg>
558
- </ThemeProvider>,
559
- );
560
-
561
- expect(onAutoFocusUsed).toHaveBeenCalled();
562
- });
563
- });
564
-
565
- describe('define chart mode', () => {
566
- it('renders interactive checkboxes when changeInteractiveEnabled', () => {
567
- const chartingOptions = {
568
- changeInteractive: { authoringLabel: 'Allow students to change' },
569
- };
570
- const { container } = renderComponent({
571
- defineChart: true,
572
- chartingOptions,
573
- changeInteractiveEnabled: true,
574
- formattedValue: '0-test',
575
- });
576
-
577
- const text = container.querySelector('text');
578
- expect(text).toBeInTheDocument();
579
- });
580
-
581
- it('renders editable checkboxes when changeEditableEnabled', () => {
582
- const chartingOptions = {
583
- changeEditable: { authoringLabel: 'Allow label editing' },
584
- };
585
- const { container } = renderComponent({
586
- defineChart: true,
587
- chartingOptions,
588
- changeEditableEnabled: true,
589
- formattedValue: '0-test',
590
- });
591
-
592
- const text = container.querySelector('text');
593
- expect(text).toBeInTheDocument();
594
- });
595
-
596
- it('splits long authoring labels', () => {
597
- const chartingOptions = {
598
- changeInteractive: { authoringLabel: 'This is a very long label that needs to be split' },
599
- };
600
- const { container } = renderComponent({
601
- defineChart: true,
602
- chartingOptions,
603
- changeInteractiveEnabled: true,
604
- formattedValue: '0-test',
605
- });
606
-
607
- const tspans = container.querySelectorAll('tspan');
608
- expect(tspans.length).toBeGreaterThan(1);
609
- });
610
- });
611
-
612
- describe('edge cases', () => {
613
- it('handles missing category', () => {
614
- const { container } = renderComponent({
615
- categories: [],
616
- formattedValue: '0-missing',
617
- });
618
- expect(container).toBeInTheDocument();
619
- });
620
-
621
- it('handles invalid formattedValue format', () => {
622
- const { container } = renderComponent({
623
- formattedValue: 'invalid',
624
- });
625
- expect(container).toBeInTheDocument();
626
- });
627
-
628
- it('handles missing graphProps', () => {
629
- const { container } = renderComponent({
630
- graphProps: null,
631
- });
632
- expect(container).toBeInTheDocument();
633
- });
634
-
635
- it('handles zero barWidth', () => {
636
- const { container } = renderComponent({
637
- barWidth: 0,
638
- });
639
- expect(container).toBeInTheDocument();
640
- });
641
-
642
- it('handles negative coordinates', () => {
643
- const { container } = renderComponent({
644
- x: -10,
645
- y: -20,
646
- });
647
- expect(container).toBeInTheDocument();
648
- });
649
- });
650
-
651
- describe('componentDidUpdate', () => {
652
- it('calls onAutoFocusUsed when autoFocus changes to true', () => {
653
- const onAutoFocusUsed = jest.fn();
654
- const component = new TickComponent({
655
- autoFocus: false,
656
- onAutoFocusUsed,
657
- });
658
-
659
- component.componentDidUpdate({ autoFocus: false });
660
- expect(onAutoFocusUsed).not.toHaveBeenCalled();
661
-
662
- component.props = { autoFocus: true, onAutoFocusUsed };
663
- component.componentDidUpdate({ autoFocus: false });
664
- expect(onAutoFocusUsed).toHaveBeenCalled();
665
- });
666
- });
667
- });