@cdc/core 4.26.1 → 4.26.3

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 (249) hide show
  1. package/.claude/agents/qa-test-developer.md +126 -0
  2. package/CLAUDE.local.md +67 -0
  3. package/LICENSE +201 -0
  4. package/_stories/Gallery.Charts.stories.tsx +35 -42
  5. package/_stories/Gallery.DataBite.stories.tsx +15 -8
  6. package/_stories/Gallery.Maps.stories.tsx +37 -28
  7. package/_stories/Gallery.WaffleChart.stories.tsx +1 -1
  8. package/_stories/PageART.stories.tsx +5 -4
  9. package/_stories/PageBRFSS.stories.tsx +21 -16
  10. package/_stories/PageCancerRegistries.stories.tsx +15 -15
  11. package/_stories/PageEasternEquineEncephalitis.stories.tsx +33 -19
  12. package/_stories/PageExcessiveAlcoholUse.stories.tsx +148 -143
  13. package/_stories/PageMaternalMortality.stories.tsx +5 -4
  14. package/_stories/PageOralHealth.stories.tsx +15 -10
  15. package/_stories/PageRespiratory.stories.tsx +4 -4
  16. package/_stories/PageSmokingTobacco.stories.tsx +15 -10
  17. package/_stories/PageStateDiabetesProfiles.stories.tsx +15 -10
  18. package/_stories/PageWastewater.stories.tsx +44 -30
  19. package/_stories/VegaImport.stories.tsx +401 -0
  20. package/_stories/vega-fixtures/bars-with-line.json +444 -0
  21. package/_stories/vega-fixtures/bars.json +58 -0
  22. package/_stories/vega-fixtures/combo-bar-rolling-mean.json +88 -0
  23. package/_stories/vega-fixtures/combo.json +68 -0
  24. package/_stories/vega-fixtures/grouped-horizontal-bars.json +83 -0
  25. package/_stories/vega-fixtures/grouped-horizontal-bars2.json +231 -0
  26. package/_stories/vega-fixtures/horizontal-bar.json +427 -0
  27. package/_stories/vega-fixtures/horizontal-bars-with-bad-colors.json +197 -0
  28. package/_stories/vega-fixtures/horizontal-bars2.json +58 -0
  29. package/_stories/vega-fixtures/lines.json +227 -0
  30. package/_stories/vega-fixtures/measles-bars.json +348 -0
  31. package/_stories/vega-fixtures/measles-map.json +11101 -0
  32. package/_stories/vega-fixtures/measles-stacked-bars.json +2147 -0
  33. package/_stories/vega-fixtures/multi-dataset.json +255 -0
  34. package/_stories/vega-fixtures/no-data.json +14 -0
  35. package/_stories/vega-fixtures/pie-chart.json +94 -0
  36. package/_stories/vega-fixtures/repeat-spec.json +47 -0
  37. package/_stories/vega-fixtures/stacked-area.json +222 -0
  38. package/_stories/vega-fixtures/stacked-bar-with-rect.json +3412 -0
  39. package/_stories/vega-fixtures/stacked-bars-with-line.json +364 -0
  40. package/_stories/vega-fixtures/stacked-bars.json +212 -0
  41. package/_stories/vega-fixtures/stacked-horizontal-bars.json +140 -0
  42. package/_stories/vega-fixtures/warning-combo.json +59 -0
  43. package/_stories/vega-fixtures/warning-scatter-and-line.json +1182 -0
  44. package/assets/callout-flag.svg +7 -0
  45. package/assets/icon-chart-area.svg +1 -0
  46. package/assets/icon-chart-radar.svg +23 -0
  47. package/assets/logo2.svg +31 -0
  48. package/components/AdvancedEditor/EmbedEditor.tsx +270 -38
  49. package/components/Alert/components/Alert.styles.css +2 -2
  50. package/components/ComboBox/combobox.styles.css +48 -48
  51. package/components/CustomColorsEditor/CustomColorsEditor.css +53 -53
  52. package/components/CustomColorsEditor/CustomColorsEditor.tsx +3 -10
  53. package/components/DataTable/DataTable.tsx +46 -18
  54. package/components/DataTable/DataTableStandAlone.tsx +1 -0
  55. package/components/DataTable/components/ChartHeader.tsx +21 -12
  56. package/components/DataTable/components/MapHeader.tsx +34 -28
  57. package/components/DataTable/components/SortIcon/sort-icon.css +5 -5
  58. package/components/DataTable/data-table.css +50 -52
  59. package/components/DataTable/helpers/applyCustomOrder.ts +17 -0
  60. package/components/DataTable/helpers/getChartCellValue.ts +10 -7
  61. package/components/DataTable/helpers/getMapDataTableColumnKeys.ts +22 -0
  62. package/components/DataTable/helpers/getSeriesName.ts +6 -0
  63. package/components/DataTable/helpers/mapCellMatrix.tsx +33 -23
  64. package/components/DataTable/helpers/tests/mapCellMatrix.test.ts +33 -0
  65. package/components/DownloadButton.tsx +14 -6
  66. package/components/EditorPanel/ColumnsEditor.tsx +38 -31
  67. package/components/EditorPanel/CustomSortOrder.tsx +94 -0
  68. package/components/EditorPanel/DataTableEditor.tsx +139 -23
  69. package/components/EditorPanel/EditorPanel.styles.css +71 -71
  70. package/components/EditorPanel/EditorPanel.tsx +3 -8
  71. package/components/EditorPanel/EditorPanelDispatch.tsx +4 -4
  72. package/components/EditorPanel/FootnotesEditor.tsx +2 -2
  73. package/components/EditorPanel/VizFilterEditor/NestedDropdownEditor.tsx +21 -12
  74. package/components/EditorPanel/VizFilterEditor/VizFilterEditor.tsx +16 -10
  75. package/components/EditorPanel/VizFilterEditor/components/FilterOrder.tsx +33 -29
  76. package/components/EditorPanel/components/MarkupVariablesEditor.tsx +160 -106
  77. package/components/EditorPanel/components/PanelMarkup.tsx +5 -1
  78. package/{styles/v2/components → components/EditorPanel}/editor.scss +76 -22
  79. package/components/EditorPanel/sections/StyleTreatmentSection.tsx +99 -0
  80. package/components/EditorPanel/sections/VisualSection.tsx +11 -0
  81. package/components/EditorWrapper/editor-wrapper.style.css +1 -1
  82. package/components/Filters/Filters.tsx +3 -5
  83. package/components/Filters/components/Tabs.tsx +19 -7
  84. package/{styles → components/Filters}/filters.scss +3 -3
  85. package/components/Footnotes/FootnotesStandAlone.tsx +4 -2
  86. package/components/HeaderThemeSelector/HeaderThemeSelector.css +61 -5
  87. package/components/Layout/components/Responsive.tsx +14 -6
  88. package/components/Layout/components/Sidebar/components/Sidebar.tsx +1 -1
  89. package/components/Layout/components/Sidebar/components/sidebar.styles.scss +14 -20
  90. package/components/Layout/components/Visualization/index.tsx +50 -38
  91. package/components/Layout/components/Visualization/visualizations.scss +232 -15
  92. package/components/Layout/components/VisualizationContainer.test.tsx +67 -0
  93. package/components/Layout/components/VisualizationContainer.tsx +37 -0
  94. package/components/Layout/components/VisualizationContent.test.tsx +182 -0
  95. package/components/Layout/components/VisualizationContent.tsx +75 -0
  96. package/components/Layout/index.tsx +5 -5
  97. package/components/Layout/styles/editor-utils.scss +3 -3
  98. package/components/Layout/styles/editor.scss +4 -4
  99. package/components/Legend/Legend.Gradient.tsx +7 -1
  100. package/components/Loader/loader.styles.css +2 -2
  101. package/components/Loading.jsx +1 -1
  102. package/components/MediaControls.tsx +10 -3
  103. package/components/MultiSelect/multiselect.styles.css +19 -19
  104. package/components/NestedDropdown/nesteddropdown.styles.css +15 -15
  105. package/components/PaletteSelector/PaletteSelector.css +15 -15
  106. package/components/RichTooltip/richTooltip.css +6 -6
  107. package/components/Table/table.styles.css +2 -2
  108. package/components/Waiting.tsx +1 -1
  109. package/components/_stories/CustomColorsEditor.stories.tsx +37 -0
  110. package/components/_stories/DataTable.stories.tsx +1 -0
  111. package/components/_stories/Filters.stories.tsx +1 -1
  112. package/components/_stories/styles.scss +0 -1
  113. package/components/elements/Button.jsx +1 -1
  114. package/components/elements/Card.jsx +1 -1
  115. package/{styles/v2/components → components/elements}/button.scss +9 -8
  116. package/components/inputs/InputCheckbox.jsx +1 -1
  117. package/components/inputs/InputSelect.tsx +1 -1
  118. package/components/inputs/InputText.jsx +1 -1
  119. package/components/inputs/InputToggle.tsx +1 -1
  120. package/{styles/v2/components/input → components/inputs}/_input-check-radio.scss +2 -2
  121. package/{styles/v2/components/input → components/inputs}/_input-group.scss +3 -3
  122. package/{styles/v2/components/input → components/inputs}/_input-slider.scss +2 -2
  123. package/{styles/v2/components/input → components/inputs}/_input.scss +5 -5
  124. package/{styles/v2/components/input → components/inputs}/index.scss +2 -2
  125. package/{styles → components}/loading.scss +1 -1
  126. package/components/managers/DataDesigner.tsx +1 -1
  127. package/{styles/v2/components → components/managers}/data-designer.scss +6 -7
  128. package/components/ui/Accordion.jsx +1 -1
  129. package/components/ui/Icon.tsx +1 -1
  130. package/components/ui/LoadSpin.jsx +1 -1
  131. package/components/ui/Modal.jsx +1 -1
  132. package/components/ui/Overlay.jsx +1 -1
  133. package/components/ui/Title/index.test.tsx +34 -0
  134. package/components/ui/Title/index.tsx +24 -7
  135. package/components/ui/Title/title.styles.css +119 -25
  136. package/components/ui/Tooltip.tsx +1 -1
  137. package/components/ui/_stories/Title.stories.tsx +1 -1
  138. package/{styles/v2/components → components/ui}/accordion.scss +3 -3
  139. package/components/ui/accordion.styles.css +11 -11
  140. package/{styles/v2/components → components/ui}/modal.scss +2 -2
  141. package/{styles/v2/components → components/ui}/overlay.scss +6 -6
  142. package/{styles/v2/components → components}/ui/tooltip.scss +1 -1
  143. package/{styles → components}/waiting.scss +9 -3
  144. package/data/colorPalettes.ts +18 -5
  145. package/data/mapColorPalettes.ts +10 -0
  146. package/devTemplate/dev.js +285 -0
  147. package/devTemplate/index.html +30 -0
  148. package/devTemplate/preview.html +1503 -0
  149. package/devTemplate/sidebar.css +151 -0
  150. package/dist/cove-main.css +2530 -3901
  151. package/dist/cove-main.css.map +1 -1
  152. package/generateViteConfig.js +111 -2
  153. package/helpers/DataTransform.ts +1 -5
  154. package/helpers/backfillDefaults.ts +35 -0
  155. package/helpers/constants.ts +12 -0
  156. package/helpers/cove/date.ts +64 -3
  157. package/helpers/cove/number.ts +29 -15
  158. package/helpers/cove/string.ts +29 -0
  159. package/helpers/coveUpdateWorker.ts +14 -8
  160. package/helpers/displayDataAsText.ts +1 -1
  161. package/helpers/embed/embedCodeGenerator.ts +80 -0
  162. package/helpers/embed/embedHelper.js +169 -0
  163. package/helpers/embed/filterUtils.ts +121 -0
  164. package/helpers/embed/index.ts +17 -0
  165. package/helpers/embed/urlValidation.ts +119 -0
  166. package/helpers/extractDataAndMetadata.ts +20 -0
  167. package/helpers/fetchRemoteData.ts +14 -8
  168. package/helpers/filterVizData.ts +6 -1
  169. package/helpers/getFileExtension.ts +0 -6
  170. package/helpers/labelHash.ts +9 -0
  171. package/helpers/markupProcessor.ts +56 -38
  172. package/helpers/metrics/types.ts +3 -0
  173. package/helpers/palettes/colorDistributions.ts +1 -1
  174. package/helpers/palettes/utils.ts +12 -12
  175. package/helpers/parseCsvWithQuotes.ts +15 -14
  176. package/helpers/prepareScreenshot.ts +33 -10
  177. package/helpers/testing.ts +44 -0
  178. package/helpers/tests/DataTransform.test.ts +125 -0
  179. package/helpers/tests/abbreviateNumber.test.ts +59 -0
  180. package/helpers/tests/backfillDefaults.test.ts +253 -0
  181. package/helpers/tests/date.test.ts +110 -0
  182. package/helpers/tests/extractDataAndMetadata.test.ts +93 -0
  183. package/helpers/tests/markupProcessor.test.ts +315 -124
  184. package/helpers/tests/number.test.ts +42 -0
  185. package/helpers/tests/prepareScreenshot.test.ts +28 -28
  186. package/helpers/tests/testStandaloneBuild.ts +36 -26
  187. package/helpers/tests/useDataVizClasses.test.ts +66 -0
  188. package/helpers/tests/visualizationWrapperUsage.test.ts +57 -0
  189. package/helpers/useDataVizClasses.ts +13 -7
  190. package/helpers/vegaConfig.ts +1 -1
  191. package/helpers/vegaConfigImport.ts +160 -0
  192. package/helpers/ver/4.24.4.ts +24 -0
  193. package/helpers/ver/4.26.1.ts +1 -1
  194. package/helpers/ver/4.26.2.ts +84 -0
  195. package/helpers/ver/4.26.3.ts +44 -0
  196. package/helpers/ver/4.26.4.ts +31 -0
  197. package/helpers/ver/tests/4.26.1.test.ts +105 -0
  198. package/helpers/ver/tests/4.26.2.test.ts +298 -0
  199. package/helpers/ver/tests/4.26.3.test.ts +168 -0
  200. package/helpers/ver/tests/4.26.4.test.ts +88 -0
  201. package/helpers/ver/tests/coveUpdateWorker.test.ts +57 -0
  202. package/helpers/viewports.ts +2 -0
  203. package/package.json +27 -32
  204. package/styles/_global.scss +7 -7
  205. package/styles/_reset.scss +2 -2
  206. package/styles/{v2/base → base}/_file-selector.scss +4 -4
  207. package/styles/{v2/base → base}/_general.scss +2 -4
  208. package/styles/{v2/base → base}/index.scss +1 -1
  209. package/styles/base.scss +107 -165
  210. package/styles/cove-main.scss +3 -6
  211. package/styles/layout/_component.scss +110 -0
  212. package/styles/{v2/layout → layout}/_data-table.scss +7 -7
  213. package/styles/layout/_wrapper-padding.scss +27 -0
  214. package/styles/{v2/main.scss → main.scss} +3 -1
  215. package/styles/{v2/themes → themes}/_color-definitions.scss +46 -41
  216. package/styles/{_accessibility.scss → utils/_accessibility.scss} +1 -1
  217. package/styles/{v2/utils → utils}/_grid.scss +8 -3
  218. package/styles/{_global-variables.scss → utils/_properties.scss} +133 -112
  219. package/styles/{v2/utils → utils}/index.scss +2 -1
  220. package/types/Annotation.ts +10 -11
  221. package/types/Axis.ts +2 -0
  222. package/types/ComponentStyles.ts +1 -0
  223. package/types/ConfigureData.ts +1 -0
  224. package/types/General.ts +2 -0
  225. package/types/MarkupInclude.ts +1 -0
  226. package/types/MarkupVariable.ts +2 -1
  227. package/types/Palette.ts +22 -0
  228. package/types/Table.ts +9 -0
  229. package/types/Visualization.ts +7 -0
  230. package/_stories/StoryRenderingTests.stories.tsx +0 -164
  231. package/helpers/embedCodeGenerator.ts +0 -109
  232. package/styles/_common-components.css +0 -73
  233. package/styles/_variables.scss +0 -63
  234. package/styles/v2/layout/_component.scss +0 -21
  235. package/styles/v2/utils/_variables.scss +0 -9
  236. package/{styles/v2/components/card.scss → components/elements/card.css} +2 -2
  237. /package/{styles/v2/components → components/ui}/icon.scss +0 -0
  238. /package/{styles/v2/components → components/ui}/loadspin.scss +0 -0
  239. /package/styles/{v2/base → base}/_heading.scss +0 -0
  240. /package/styles/{v2/base → base}/_reset.scss +0 -0
  241. /package/styles/{v2/layout → layout}/_alert.scss +0 -0
  242. /package/styles/{v2/layout → layout}/_progression.scss +0 -0
  243. /package/styles/{v2/layout → layout}/_tooltip.scss +0 -0
  244. /package/styles/{v2/layout → layout}/index.scss +0 -0
  245. /package/styles/{v2/themes → themes}/index.scss +0 -0
  246. /package/styles/{v2/utils → utils}/_align.scss +0 -0
  247. /package/styles/{v2/utils → utils}/_animations.scss +0 -0
  248. /package/styles/{v2/utils → utils}/_breakpoints.scss +0 -0
  249. /package/styles/{v2/utils → utils}/_mixins.scss +0 -0
@@ -0,0 +1,298 @@
1
+ import update_4_26_2 from '../4.26.2'
2
+ import { expect, describe, it } from 'vitest'
3
+
4
+ describe('update_4_26_2', () => {
5
+ describe('migrateAnnotationDimensions', () => {
6
+ it('should convert Y position from absolute pixels to percentage and delete savedDimensions', () => {
7
+ const config: any = {
8
+ type: 'chart',
9
+ version: '4.26.1',
10
+ heights: { vertical: 400 },
11
+ annotations: [
12
+ {
13
+ text: 'Test Annotation',
14
+ x: 50,
15
+ y: 200,
16
+ savedDimensions: [800, 560], // old format: will be deleted
17
+ dx: 10,
18
+ dy: -10
19
+ }
20
+ ]
21
+ }
22
+
23
+ const result = update_4_26_2(config)
24
+
25
+ // Y is now calculated as percentage of heights.vertical (400)
26
+ expect(result.annotations[0].y).toBe(50) // 200 / 400 * 100 = 50
27
+ expect(result.annotations[0].x).toBe(50)
28
+ // savedDimensions should be deleted to preserve old dx/dy behavior
29
+ expect(result.annotations[0].savedDimensions).toBeUndefined()
30
+ // dx/dy should be preserved unchanged
31
+ expect(result.annotations[0].dx).toBe(10)
32
+ expect(result.annotations[0].dy).toBe(-10)
33
+ expect(result.version).toBe('4.26.2')
34
+ })
35
+
36
+ it('should handle multiple annotations with different Y positions', () => {
37
+ const config: any = {
38
+ type: 'chart',
39
+ version: '4.26.1',
40
+ heights: { vertical: 500 },
41
+ annotations: [
42
+ {
43
+ text: 'Top',
44
+ x: 25,
45
+ y: 100,
46
+ savedDimensions: [1000, 700]
47
+ },
48
+ {
49
+ text: 'Middle',
50
+ x: 75,
51
+ y: 250,
52
+ savedDimensions: [1000, 700]
53
+ }
54
+ ]
55
+ }
56
+
57
+ const result = update_4_26_2(config)
58
+
59
+ // Y calculated as percentage of heights.vertical (500)
60
+ expect(result.annotations[0].y).toBe(20) // 100 / 500 * 100 = 20
61
+ expect(result.annotations[1].y).toBe(50) // 250 / 500 * 100 = 50
62
+ // savedDimensions should be deleted
63
+ expect(result.annotations[0].savedDimensions).toBeUndefined()
64
+ expect(result.annotations[1].savedDimensions).toBeUndefined()
65
+ })
66
+
67
+ it('should use default vertical height (300) when heights not specified', () => {
68
+ const config: any = {
69
+ type: 'chart',
70
+ version: '4.26.1',
71
+ annotations: [
72
+ {
73
+ text: 'No heights config',
74
+ x: 50,
75
+ y: 150,
76
+ savedDimensions: [800, 560]
77
+ }
78
+ ]
79
+ }
80
+
81
+ const result = update_4_26_2(config)
82
+
83
+ // Uses default vertical height of 300
84
+ expect(result.annotations[0].y).toBe(50) // 150 / 300 * 100 = 50
85
+ expect(result.annotations[0].savedDimensions).toBeUndefined()
86
+ })
87
+
88
+ it('should use horizontal height for horizontal orientation', () => {
89
+ const config: any = {
90
+ type: 'chart',
91
+ version: '4.26.1',
92
+ orientation: 'horizontal',
93
+ heights: { horizontal: 750 },
94
+ annotations: [
95
+ {
96
+ text: 'Horizontal chart annotation',
97
+ x: 50,
98
+ y: 375,
99
+ savedDimensions: [800, 900]
100
+ }
101
+ ]
102
+ }
103
+
104
+ const result = update_4_26_2(config)
105
+
106
+ // Uses heights.horizontal for horizontal charts
107
+ expect(result.annotations[0].y).toBe(50) // 375 / 750 * 100 = 50
108
+ expect(result.annotations[0].savedDimensions).toBeUndefined()
109
+ })
110
+
111
+ it('should handle dashboard configs with nested visualizations', () => {
112
+ const config: any = {
113
+ type: 'dashboard',
114
+ version: '4.26.1',
115
+ visualizations: {
116
+ chart1: {
117
+ type: 'chart',
118
+ heights: { vertical: 300 },
119
+ annotations: [
120
+ {
121
+ text: 'Chart 1 Annotation',
122
+ x: 30,
123
+ y: 150,
124
+ savedDimensions: [600, 450]
125
+ }
126
+ ]
127
+ }
128
+ }
129
+ }
130
+
131
+ const result = update_4_26_2(config)
132
+
133
+ expect(result.visualizations.chart1.annotations[0].y).toBe(50) // 150 / 300 * 100 = 50
134
+ expect(result.visualizations.chart1.annotations[0].savedDimensions).toBeUndefined()
135
+ })
136
+
137
+ it('should preserve all other annotation properties and delete xKey entirely', () => {
138
+ const config: any = {
139
+ type: 'chart',
140
+ version: '4.26.1',
141
+ heights: { vertical: 500 },
142
+ annotations: [
143
+ {
144
+ text: 'Complex Annotation',
145
+ x: 50,
146
+ y: 250,
147
+ savedDimensions: [1000, 700],
148
+ dx: 20,
149
+ dy: -30,
150
+ xKey: 1577836800000,
151
+ yKey: '42',
152
+ seriesKey: 'series1',
153
+ marker: 'arrow'
154
+ }
155
+ ]
156
+ }
157
+
158
+ const result = update_4_26_2(config)
159
+
160
+ const annotation = result.annotations[0]
161
+ expect(annotation.y).toBe(50) // 250 / 500 * 100 = 50
162
+ expect(annotation.text).toBe('Complex Annotation')
163
+ expect(annotation.dx).toBe(20)
164
+ expect(annotation.dy).toBe(-30)
165
+ // xKey is deleted entirely (not renamed to dataX) because old format
166
+ // stored timestamps but new dataX expects raw data values
167
+ expect(annotation.xKey).toBeUndefined()
168
+ expect(annotation.dataX).toBeUndefined()
169
+ expect(annotation.yKey).toBeUndefined()
170
+ // Non-empty seriesKey is preserved
171
+ expect(annotation.seriesKey).toBe('series1')
172
+ expect(annotation.savedDimensions).toBeUndefined()
173
+ })
174
+
175
+ it('should delete empty seriesKey', () => {
176
+ const config: any = {
177
+ type: 'chart',
178
+ version: '4.26.1',
179
+ heights: { vertical: 300 },
180
+ annotations: [
181
+ {
182
+ text: 'Annotation with empty seriesKey',
183
+ x: 50,
184
+ y: 150,
185
+ seriesKey: ''
186
+ }
187
+ ]
188
+ }
189
+
190
+ const result = update_4_26_2(config)
191
+
192
+ // Empty seriesKey should be deleted to prevent yScale(undefined) errors
193
+ expect(result.annotations[0].seriesKey).toBeUndefined()
194
+ })
195
+
196
+ it('should handle config with no annotations', () => {
197
+ const config: any = {
198
+ type: 'chart',
199
+ version: '4.26.1',
200
+ title: 'Chart without annotations'
201
+ }
202
+
203
+ const result = update_4_26_2(config)
204
+
205
+ expect(result.annotations).toBeUndefined()
206
+ expect(result.title).toBe('Chart without annotations')
207
+ })
208
+
209
+ it('should handle annotation without savedDimensions', () => {
210
+ const config: any = {
211
+ type: 'chart',
212
+ version: '4.26.1',
213
+ heights: { vertical: 300 },
214
+ annotations: [
215
+ {
216
+ text: 'No savedDimensions',
217
+ x: 50,
218
+ y: 150
219
+ }
220
+ ]
221
+ }
222
+
223
+ const result = update_4_26_2(config)
224
+
225
+ expect(result.annotations[0].y).toBe(50) // 150 / 300 * 100 = 50
226
+ expect(result.annotations[0].savedDimensions).toBeUndefined()
227
+ })
228
+ })
229
+
230
+ describe('combined migrations', () => {
231
+ it('should run all migrations together', () => {
232
+ const config: any = {
233
+ type: 'dashboard',
234
+ version: '4.26.1',
235
+ dashboard: {
236
+ sharedFilters: [
237
+ {
238
+ type: 'datafilter',
239
+ parents: 'parent-id'
240
+ }
241
+ ]
242
+ },
243
+ visualizations: {
244
+ chart1: {
245
+ type: 'chart',
246
+ heights: { vertical: 400 },
247
+ brush: { enabled: true },
248
+ annotations: [
249
+ {
250
+ x: 50,
251
+ y: 200,
252
+ savedDimensions: [800, 560]
253
+ }
254
+ ]
255
+ }
256
+ }
257
+ }
258
+
259
+ const result = update_4_26_2(config)
260
+
261
+ expect(result.visualizations.chart1.annotations[0].y).toBe(50) // 200 / 400 * 100 = 50
262
+ expect(result.visualizations.chart1.annotations[0].anchorMode).toBe('fixed')
263
+ expect(result.visualizations.chart1.annotations[0].savedDimensions).toBeUndefined()
264
+ expect(result.visualizations.chart1.annotations[0].dataX).toBeUndefined()
265
+ expect(result.version).toBe('4.26.2')
266
+ })
267
+
268
+ it('should migrate data model along with Y position', () => {
269
+ const config: any = {
270
+ type: 'chart',
271
+ version: '4.26.1',
272
+ heights: { vertical: 400 },
273
+ annotations: [
274
+ {
275
+ x: 50,
276
+ y: 200,
277
+ savedDimensions: [800, 560],
278
+ xKey: 1577836800000,
279
+ yKey: '42',
280
+ snapToNearestPoint: true
281
+ }
282
+ ]
283
+ }
284
+
285
+ const result = update_4_26_2(config)
286
+
287
+ const annotation = result.annotations[0]
288
+ expect(annotation.y).toBe(50) // 200 / 400 * 100 = 50
289
+ expect(annotation.anchorMode).toBe('fixed')
290
+ // xKey is deleted entirely (not renamed to dataX) - format incompatible
291
+ expect(annotation.dataX).toBeUndefined()
292
+ expect(annotation.xKey).toBeUndefined()
293
+ expect(annotation.yKey).toBeUndefined()
294
+ expect(annotation.snapToNearestPoint).toBeUndefined()
295
+ expect(annotation.savedDimensions).toBeUndefined()
296
+ })
297
+ })
298
+ })
@@ -0,0 +1,168 @@
1
+ import update_4_26_3 from '../4.26.3'
2
+ import { expect, describe, it } from 'vitest'
3
+
4
+ describe('update_4_26_3', () => {
5
+ it('should add locale "en-US" to a config without locale', () => {
6
+ const config: any = {
7
+ type: 'chart',
8
+ version: '4.26.2',
9
+ title: 'Test Chart'
10
+ }
11
+
12
+ const result = update_4_26_3(config)
13
+
14
+ expect(result.locale).toBe('en-US')
15
+ expect(result.version).toBe('4.26.3')
16
+ expect(result.title).toBe('Test Chart')
17
+ })
18
+
19
+ it('should not overwrite an existing locale', () => {
20
+ const config: any = {
21
+ type: 'chart',
22
+ version: '4.26.2',
23
+ locale: 'es-MX'
24
+ }
25
+
26
+ const result = update_4_26_3(config)
27
+
28
+ expect(result.locale).toBe('es-MX')
29
+ })
30
+
31
+ it('should add locale to dashboard child visualizations', () => {
32
+ const config: any = {
33
+ type: 'dashboard',
34
+ version: '4.26.2',
35
+ visualizations: {
36
+ chart1: {
37
+ type: 'chart',
38
+ title: 'Chart 1'
39
+ },
40
+ map1: {
41
+ type: 'map',
42
+ title: 'Map 1'
43
+ }
44
+ }
45
+ }
46
+
47
+ const result = update_4_26_3(config)
48
+
49
+ expect(result.locale).toBe('en-US')
50
+ expect(result.visualizations.chart1.locale).toBe('en-US')
51
+ expect(result.visualizations.map1.locale).toBe('en-US')
52
+ expect(result.version).toBe('4.26.3')
53
+ })
54
+
55
+ it('should not overwrite existing locale on dashboard child visualizations', () => {
56
+ const config: any = {
57
+ type: 'dashboard',
58
+ version: '4.26.2',
59
+ locale: 'es-MX',
60
+ visualizations: {
61
+ chart1: {
62
+ type: 'chart',
63
+ locale: 'es-MX'
64
+ }
65
+ }
66
+ }
67
+
68
+ const result = update_4_26_3(config)
69
+
70
+ expect(result.locale).toBe('es-MX')
71
+ expect(result.visualizations.chart1.locale).toBe('es-MX')
72
+ })
73
+
74
+ it('should not mutate the original config', () => {
75
+ const config: any = {
76
+ type: 'chart',
77
+ version: '4.26.2'
78
+ }
79
+
80
+ const result = update_4_26_3(config)
81
+
82
+ expect(config.locale).toBeUndefined()
83
+ expect(result.locale).toBe('en-US')
84
+ })
85
+
86
+ it('turns off extra visual settings for a standalone chart config', () => {
87
+ const config: any = {
88
+ type: 'chart',
89
+ version: '4.26.2',
90
+ visual: {
91
+ border: true,
92
+ borderColorTheme: true,
93
+ accent: true,
94
+ background: true,
95
+ hideBackgroundColor: true
96
+ }
97
+ }
98
+
99
+ const result = update_4_26_3(config)
100
+
101
+ expect(result.visual).toEqual({
102
+ border: false,
103
+ borderColorTheme: false,
104
+ accent: false,
105
+ background: false,
106
+ hideBackgroundColor: false
107
+ })
108
+ })
109
+
110
+ it('turns off extra visual settings for chart visualizations inside dashboards only', () => {
111
+ const config: any = {
112
+ type: 'dashboard',
113
+ version: '4.26.2',
114
+ visualizations: {
115
+ chart1: {
116
+ type: 'chart',
117
+ visual: {
118
+ border: true,
119
+ borderColorTheme: true,
120
+ accent: true,
121
+ background: true,
122
+ hideBackgroundColor: true
123
+ }
124
+ },
125
+ dataBite1: {
126
+ type: 'data-bite',
127
+ visual: {
128
+ borderColorTheme: true,
129
+ accent: true,
130
+ background: true,
131
+ hideBackgroundColor: true
132
+ }
133
+ }
134
+ }
135
+ }
136
+
137
+ const result = update_4_26_3(config)
138
+
139
+ expect(result.visualizations.chart1.visual).toEqual({
140
+ border: false,
141
+ borderColorTheme: false,
142
+ accent: false,
143
+ background: false,
144
+ hideBackgroundColor: false
145
+ })
146
+ expect(result.visualizations.dataBite1.visual).toEqual({
147
+ borderColorTheme: true,
148
+ accent: true,
149
+ background: true,
150
+ hideBackgroundColor: true
151
+ })
152
+ })
153
+
154
+ it('does not mutate the original config visual settings', () => {
155
+ const config: any = {
156
+ type: 'chart',
157
+ version: '4.26.2',
158
+ visual: {
159
+ accent: true
160
+ }
161
+ }
162
+
163
+ const result = update_4_26_3(config)
164
+
165
+ expect(config.visual.accent).toBe(true)
166
+ expect(result.visual.accent).toBe(false)
167
+ })
168
+ })
@@ -0,0 +1,88 @@
1
+ import update_4_26_4 from '../4.26.4'
2
+ import { describe, expect, it } from 'vitest'
3
+
4
+ describe('update_4_26_4', () => {
5
+ it('turns off extra visual settings for a standalone chart config', () => {
6
+ const config: any = {
7
+ type: 'chart',
8
+ version: '4.26.3',
9
+ visual: {
10
+ border: true,
11
+ borderColorTheme: true,
12
+ accent: true,
13
+ background: true,
14
+ hideBackgroundColor: true
15
+ }
16
+ }
17
+
18
+ const result = update_4_26_4(config)
19
+
20
+ expect(result.visual).toEqual({
21
+ border: false,
22
+ borderColorTheme: false,
23
+ accent: false,
24
+ background: false,
25
+ hideBackgroundColor: false
26
+ })
27
+ expect(result.version).toBe('4.26.4')
28
+ })
29
+
30
+ it('turns off extra visual settings for chart visualizations inside dashboards only', () => {
31
+ const config: any = {
32
+ type: 'dashboard',
33
+ version: '4.26.3',
34
+ visualizations: {
35
+ chart1: {
36
+ type: 'chart',
37
+ visual: {
38
+ border: true,
39
+ borderColorTheme: true,
40
+ accent: true,
41
+ background: true,
42
+ hideBackgroundColor: true
43
+ }
44
+ },
45
+ dataBite1: {
46
+ type: 'data-bite',
47
+ visual: {
48
+ borderColorTheme: true,
49
+ accent: true,
50
+ background: true,
51
+ hideBackgroundColor: true
52
+ }
53
+ }
54
+ }
55
+ }
56
+
57
+ const result = update_4_26_4(config)
58
+
59
+ expect(result.visualizations.chart1.visual).toEqual({
60
+ border: false,
61
+ borderColorTheme: false,
62
+ accent: false,
63
+ background: false,
64
+ hideBackgroundColor: false
65
+ })
66
+ expect(result.visualizations.dataBite1.visual).toEqual({
67
+ borderColorTheme: true,
68
+ accent: true,
69
+ background: true,
70
+ hideBackgroundColor: true
71
+ })
72
+ })
73
+
74
+ it('does not mutate the original config', () => {
75
+ const config: any = {
76
+ type: 'chart',
77
+ version: '4.26.3',
78
+ visual: {
79
+ accent: true
80
+ }
81
+ }
82
+
83
+ const result = update_4_26_4(config)
84
+
85
+ expect(config.visual.accent).toBe(true)
86
+ expect(result.visual.accent).toBe(false)
87
+ })
88
+ })
@@ -0,0 +1,57 @@
1
+ import { coveUpdateWorker } from '../../coveUpdateWorker'
2
+ import { expect, describe, it } from 'vitest'
3
+
4
+ const makeMultiDashConfig = (version: string) => ({
5
+ type: 'dashboard',
6
+ version,
7
+ dashboard: { title: 'Parent Dashboard' },
8
+ rows: [],
9
+ visualizations: {},
10
+ multiDashboards: [
11
+ {
12
+ type: 'dashboard',
13
+ dashboard: { title: 'Sub Dashboard' },
14
+ rows: [],
15
+ visualizations: {
16
+ chart1: {
17
+ type: 'chart',
18
+ title: 'My Chart',
19
+ brush: { enabled: true }
20
+ }
21
+ }
22
+ }
23
+ ]
24
+ })
25
+
26
+ describe('coveUpdateWorker', () => {
27
+ describe('multi-dashboard recursion', () => {
28
+ it('should NOT run 4.26.1 migration on sub-dashboards when parent is at 4.26.2', () => {
29
+ const config: any = makeMultiDashConfig('4.26.2')
30
+ const result = coveUpdateWorker(config)
31
+ const subDash = result.multiDashboards[0]
32
+
33
+ // 4.26.1 removeOldBrushKeys should NOT have run
34
+ expect(subDash.visualizations.chart1.brush).toEqual({ enabled: true })
35
+ // 4.26.1 migrateTitleStyle should NOT have run
36
+ expect(subDash.visualizations.chart1.titleStyle).toBeUndefined()
37
+ })
38
+
39
+ it('should run 4.26.1 migration on sub-dashboards when parent is at 4.26.0', () => {
40
+ const config: any = makeMultiDashConfig('4.26.0')
41
+ const result = coveUpdateWorker(config)
42
+ const subDash = result.multiDashboards[0]
43
+
44
+ // 4.26.1 removeOldBrushKeys SHOULD have run
45
+ expect(subDash.visualizations.chart1.brush).toBeUndefined()
46
+ // 4.26.1 migrateTitleStyle SHOULD have run
47
+ expect(subDash.visualizations.chart1.titleStyle).toBe('legacy')
48
+ })
49
+
50
+ it('should strip version from sub-dashboards after processing', () => {
51
+ const config: any = makeMultiDashConfig('4.25.0')
52
+ const result = coveUpdateWorker(config)
53
+
54
+ expect(result.multiDashboards[0].version).toBeUndefined()
55
+ })
56
+ })
57
+ })
@@ -15,4 +15,6 @@ export const isMobileTerritoryViewport = currentViewport => isBelowBreakpoint('s
15
15
 
16
16
  export const isMobileFontViewport = currentViewport => isBelowBreakpoint('sm', currentViewport)
17
17
 
18
+ export const isMobileAnnotationViewport = currentViewport => isBelowBreakpoint('sm', currentViewport)
19
+
18
20
  export const isMobileSmallMultiplesViewport = currentViewport => isBelowBreakpoint('md', currentViewport)
package/package.json CHANGED
@@ -1,54 +1,49 @@
1
1
  {
2
2
  "name": "@cdc/core",
3
- "version": "4.26.1",
3
+ "version": "4.26.3",
4
4
  "description": "Core components, styles, hooks, and helpers, for the CDC Open Visualization project",
5
- "moduleName": "CdcCore",
6
- "main": "dist/cdccore",
7
- "type": "module",
8
- "scripts": {
9
- "test": "vitest run --environment jsdom --reporter verbose",
10
- "test-watch": "vitest watch --reporter verbose",
11
- "test-watch:ui": "vitest --ui",
12
- "build": "sass styles/cove-main.scss dist/cove-main.css"
13
- },
14
- "repository": {
15
- "type": "git",
16
- "url": "git+https://github.com/CDCgov/cdc-open-viz.git"
17
- },
18
- "author": "Rob Shelnutt <rob@blackairplane.com>",
19
- "homepage": "https://github.com/CDCgov/cdc-open-viz#readme",
20
- "bugs": {
21
- "url": "https://github.com/CDCgov/cdc-open-viz/issues"
22
- },
23
5
  "license": "Apache-2.0",
6
+ "author": "Rob Shelnutt <rob@blackairplane.com>",
7
+ "bugs": "https://github.com/CDCgov/cdc-open-viz/issues",
24
8
  "dependencies": {
25
9
  "@hello-pangea/dnd": "^16.2.0",
26
- "chroma-js": "3.1.2",
27
- "dompurify": "^3.2.4",
28
- "html-react-parser": "5.2.3",
10
+ "chroma-js": "^3.1.2",
11
+ "dompurify": "^3.3.1",
12
+ "html-react-parser": "^5.2.3",
29
13
  "html2canvas": "^1.4.1",
30
14
  "json-edit-react": "^1.27.0",
31
- "papaparse": "5.5.2",
15
+ "papaparse": "^5.5.2",
32
16
  "prop-types": "^15.8.1",
33
17
  "react-accessible-accordion": "^5.0.1",
34
18
  "react-select": "^5.3.1",
35
19
  "react-tooltip": "5.8.2-beta.3",
36
20
  "resize-observer-polyfill": "^1.5.1",
37
- "use-debounce": "^10.0.5",
21
+ "use-debounce": "^10.1.0",
38
22
  "vega": "^6.1.0",
39
23
  "vega-lite": "^6.1.0"
40
24
  },
41
- "peerDependencies": {
42
- "react": "^18.2.0",
43
- "react-dom": "^18.2.0"
44
- },
45
- "gitHead": "7e3b27098c4eb7a24bc9c3654ad53f88d6419f16",
46
25
  "devDependencies": {
47
26
  "@rollup/plugin-dsv": "^3.0.2",
48
- "@vitejs/plugin-react": "^4.3.4",
27
+ "@vitejs/plugin-react": "^5.1.2",
49
28
  "sass": "^1.89.2",
50
- "vite": "^5.4.21",
29
+ "vite": "^7.3.1",
51
30
  "vite-plugin-css-injected-by-js": "^2.4.0",
52
31
  "vite-plugin-svgr": "^4.2.0"
53
- }
32
+ },
33
+ "gitHead": "d50e45a074fbefa56cac904917e707d57f237737",
34
+ "homepage": "https://github.com/CDCgov/cdc-open-viz#readme",
35
+ "main": "dist/cdccore",
36
+ "moduleName": "CdcCore",
37
+ "peerDependencies": {
38
+ "react": "^18.2.0",
39
+ "react-dom": "^18.2.0"
40
+ },
41
+ "repository": "CDCgov/cdc-open-viz.git",
42
+ "scripts": {
43
+ "build": "sass styles/cove-main.scss dist/cove-main.css",
44
+ "test": "vitest run --environment jsdom --reporter verbose",
45
+ "test-watch": "vitest watch --reporter verbose",
46
+ "test-watch:ui": "vitest --ui"
47
+ },
48
+ "type": "module"
54
49
  }