@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
@@ -3,9 +3,9 @@
3
3
 
4
4
  /* Color palette in editor panel context */
5
5
  .editor-panel .header .color-palette li {
6
- width: 1.5em;
7
- height: 1.5em;
8
6
  display: inline-block;
7
+ height: 1.5em;
8
+ width: 1.5em;
9
9
  }
10
10
 
11
11
  .editor-panel .color-palette {
@@ -13,12 +13,12 @@
13
13
  }
14
14
 
15
15
  .editor-panel .color-palette li {
16
- width: 1.5em;
17
- height: 1.5em;
16
+ border: rgba(0, 0, 0, 0.3) 3px solid;
17
+ cursor: pointer;
18
18
  display: inline-block;
19
+ height: 1.5em;
19
20
  margin-right: 0.5em;
20
- cursor: pointer;
21
- border: rgba(0, 0, 0, 0.3) 3px solid;
21
+ width: 1.5em;
22
22
  }
23
23
 
24
24
  .editor-panel .color-palette li.active {
@@ -26,24 +26,24 @@
26
26
  }
27
27
 
28
28
  .editor-panel .color-palette a {
29
- display: inline-block;
30
29
  border-bottom: 1px solid rgba(0, 0, 0, 0.8);
30
+ display: inline-block;
31
31
  }
32
32
 
33
33
  .editor-panel .color-palette.series-list {
34
+ border: none;
34
35
  flex-direction: column;
35
36
  padding: 0;
36
- border: none;
37
37
  }
38
38
 
39
39
  .editor-panel .color-palette.series-list li {
40
- padding: 0.3em 0.5em;
41
- display: flex;
42
40
  align-items: center;
41
+ border: 0;
42
+ display: flex;
43
+ height: auto;
43
44
  justify-content: space-between;
45
+ padding: 0.3em 0.5em;
44
46
  width: auto;
45
- height: auto;
46
- border: 0;
47
47
  }
48
48
 
49
49
  .editor-panel .color-palette.series-list li:not(:last-child) {
@@ -61,10 +61,10 @@
61
61
  }
62
62
 
63
63
  .editor-panel .guidance-link svg {
64
- width: 60px;
65
64
  color: var(--blue);
66
- margin-right: 1rem;
67
65
  height: 60px;
66
+ margin-right: 1rem;
67
+ width: 60px;
68
68
  }
69
69
 
70
70
  .editor-panel .guidance-link svg path {
@@ -72,18 +72,18 @@
72
72
  }
73
73
 
74
74
  .editor-panel .warning {
75
- color: #d8000c;
76
75
  background-color: #ffd2d2;
77
- padding: 0.75em 1em;
78
- margin: 1em 0;
79
- font-size: 0.8em;
80
76
  border: #d8000c 1px solid;
81
77
  border-radius: 0.4em;
78
+ color: #d8000c;
79
+ font-size: 0.8em;
80
+ margin: 1em 0;
81
+ padding: 0.75em 1em;
82
82
  }
83
83
 
84
84
  .editor-panel .warning strong {
85
- font-weight: 600;
86
85
  display: block;
86
+ font-weight: 600;
87
87
  }
88
88
 
89
89
  .editor-panel .advanced {
@@ -96,18 +96,18 @@
96
96
  }
97
97
 
98
98
  .editor-panel .advanced .advanced-toggle-link {
99
- padding-top: 1em;
99
+ cursor: pointer;
100
100
  display: block;
101
+ padding-top: 1em;
101
102
  text-align: left;
102
- cursor: pointer;
103
103
  text-decoration: underline;
104
104
  }
105
105
 
106
106
  .editor-panel .advanced .advanced-toggle-link span {
107
- text-decoration: none;
108
107
  display: inline-block;
109
108
  font-family: monospace;
110
109
  padding-right: 5px;
110
+ text-decoration: none;
111
111
  }
112
112
 
113
113
  .editor-panel .advanced .advanced-toggle-link:hover {
@@ -115,29 +115,29 @@
115
115
  }
116
116
 
117
117
  .editor-panel .advanced textarea {
118
- height: 400px;
119
- width: 100%;
118
+ box-sizing: border-box;
119
+ font-family: monospace;
120
120
  font-size: 0.9em;
121
+ height: 400px;
121
122
  padding: 0.5em;
122
- font-family: monospace;
123
- box-sizing: border-box;
123
+ width: 100%;
124
124
  }
125
125
 
126
126
  .editor-panel .heading-2 {
127
127
  background: #565656;
128
+ border-bottom: #565656 3px solid;
128
129
  color: #fff;
129
130
  font-size: 1.1em;
130
131
  padding: 0.6em 1em;
131
132
  position: relative;
132
- border-bottom: #565656 3px solid;
133
133
  z-index: 3;
134
134
  }
135
135
 
136
136
  .editor-panel label {
137
- text-transform: uppercase;
138
137
  display: block;
139
138
  font-size: 0.8em;
140
139
  font-weight: 600;
140
+ text-transform: uppercase;
141
141
  }
142
142
 
143
143
  .editor-panel label:not(:first-child) {
@@ -145,8 +145,8 @@
145
145
  }
146
146
 
147
147
  .editor-panel label span.edit-label {
148
- margin-bottom: 0.3em;
149
148
  display: block;
149
+ margin-bottom: 0.3em;
150
150
  }
151
151
 
152
152
  .editor-panel label span.column-heading {
@@ -158,25 +158,25 @@
158
158
  }
159
159
 
160
160
  .editor-panel label.checkbox span {
161
- text-transform: none;
162
161
  font-size: 1em;
163
162
  font-weight: 400;
163
+ text-transform: none;
164
164
  }
165
165
 
166
166
  .editor-panel label.checkbox input {
167
- margin-top: 0;
168
167
  margin-right: 0.5em;
168
+ margin-top: 0;
169
169
  }
170
170
 
171
171
  .editor-panel input[type='checkbox'],
172
172
  .editor-panel input[type='radio'] {
173
+ cursor: pointer;
173
174
  display: inline-block;
174
- width: auto !important;
175
175
  height: auto !important;
176
- padding: 0;
177
176
  margin-right: 0.5em;
178
- cursor: pointer;
177
+ padding: 0;
179
178
  user-select: none;
179
+ width: auto !important;
180
180
  }
181
181
 
182
182
  .editor-panel input[type='text'],
@@ -193,8 +193,8 @@
193
193
 
194
194
  .editor-panel .primary-fieldset {
195
195
  border-top: rgba(0, 0, 0, 0.3) 2px solid;
196
- padding-top: 2em;
197
196
  margin-top: 2em;
197
+ padding-top: 2em;
198
198
  }
199
199
 
200
200
  .editor-panel ul.column-edit {
@@ -223,28 +223,28 @@
223
223
 
224
224
  .editor-panel .edit-block {
225
225
  border: 1px solid rgba(0, 0, 0, 0.3);
226
- padding: 1em;
227
226
  margin-top: 1em;
227
+ padding: 1em;
228
228
  position: relative;
229
229
  }
230
230
 
231
231
  .editor-panel .edit-block .remove-column {
232
- position: absolute;
233
- top: 0;
234
- right: 0;
235
- border: 0;
236
232
  background: rgba(0, 0, 0, 0.1);
233
+ border: 0;
237
234
  color: #000;
235
+ cursor: pointer;
238
236
  font-size: 0.8em;
239
237
  padding: 0.3em;
240
- cursor: pointer;
238
+ position: absolute;
239
+ right: 0;
240
+ top: 0;
241
241
  }
242
242
 
243
243
  .editor-panel span.subtext {
244
- text-transform: none;
245
244
  display: block;
246
245
  font-size: 0.8em;
247
246
  font-weight: 400;
247
+ text-transform: none;
248
248
  }
249
249
 
250
250
  .editor-panel .sort-list {
@@ -252,12 +252,12 @@
252
252
  }
253
253
 
254
254
  .editor-panel .sort-list li {
255
- border: 1px solid rgba(0, 0, 0, 0.2);
256
- padding: 0.3em;
257
- display: flex;
258
255
  align-items: center;
256
+ border: 1px solid rgba(0, 0, 0, 0.2);
259
257
  cursor: move;
258
+ display: flex;
260
259
  margin-bottom: 0.3em;
260
+ padding: 0.3em;
261
261
  }
262
262
 
263
263
  .editor-panel .sort-list li svg {
@@ -265,8 +265,8 @@
265
265
  }
266
266
 
267
267
  .editor-panel .info {
268
- margin-top: 1em;
269
268
  font-size: 0.9em;
269
+ margin-top: 1em;
270
270
  }
271
271
 
272
272
  /* React Tags Component styles (third-party library) */
@@ -275,8 +275,8 @@
275
275
  }
276
276
 
277
277
  .editor-panel .react-tags {
278
- position: relative;
279
278
  cursor: text;
279
+ position: relative;
280
280
  }
281
281
 
282
282
  .editor-panel .react-tags input.react-tags__search-input {
@@ -296,20 +296,20 @@
296
296
  }
297
297
 
298
298
  .editor-panel .react-tags__selected-tag {
299
- display: inline-block;
300
- box-sizing: border-box;
299
+ background: #f1f1f1;
301
300
  border: 1px solid #d1d1d1;
302
301
  border-radius: 2px;
303
- background: #f1f1f1;
304
- padding: 0.4em 0.6em;
302
+ box-sizing: border-box;
303
+ display: inline-block;
305
304
  font-size: 0.8em;
306
- margin-right: 0.3em;
307
305
  margin-bottom: 0.3em;
306
+ margin-right: 0.3em;
307
+ padding: 0.4em 0.6em;
308
308
  }
309
309
 
310
310
  .editor-panel .react-tags__selected-tag:after {
311
- content: '\2715';
312
311
  color: #aaa;
312
+ content: '\2715';
313
313
  margin-left: 8px;
314
314
  }
315
315
 
@@ -330,12 +330,12 @@
330
330
  }
331
331
 
332
332
  .editor-panel .react-tags__search input {
333
- max-width: 100%;
333
+ font-size: inherit;
334
+ line-height: inherit;
334
335
  margin: 0;
336
+ max-width: 100%;
335
337
  outline: none;
336
338
  padding: 0.5em 0.3em;
337
- font-size: inherit;
338
- line-height: inherit;
339
339
  }
340
340
 
341
341
  .editor-panel .react-tags__search input::-ms-clear {
@@ -343,9 +343,9 @@
343
343
  }
344
344
 
345
345
  .editor-panel .react-tags__suggestions {
346
+ left: 0;
346
347
  position: absolute;
347
348
  top: 100%;
348
- left: 0;
349
349
  width: 100%;
350
350
  }
351
351
 
@@ -356,13 +356,13 @@
356
356
  }
357
357
 
358
358
  .editor-panel .react-tags__suggestions ul {
359
- margin: 4px -1px;
360
- padding: 0;
361
- list-style: none;
362
359
  background: white;
363
360
  border: 1px solid #d1d1d1;
364
361
  border-radius: 2px;
365
362
  box-shadow: 0 2px 6px rgba(0, 0, 0, 0.2);
363
+ list-style: none;
364
+ margin: 4px -1px;
365
+ padding: 0;
366
366
  }
367
367
 
368
368
  .editor-panel .react-tags__suggestions li {
@@ -371,14 +371,14 @@
371
371
  }
372
372
 
373
373
  .editor-panel .react-tags__suggestions li mark {
374
- text-decoration: underline;
375
374
  background: none;
376
375
  font-weight: 600;
376
+ text-decoration: underline;
377
377
  }
378
378
 
379
379
  .editor-panel .react-tags__suggestions li:hover {
380
- cursor: pointer;
381
380
  background: #eee;
381
+ cursor: pointer;
382
382
  }
383
383
 
384
384
  .editor-panel .react-tags__suggestions li.is-active {
@@ -386,23 +386,23 @@
386
386
  }
387
387
 
388
388
  .editor-panel .react-tags__suggestions li.is-disabled {
389
- opacity: 0.5;
390
389
  cursor: auto;
390
+ opacity: 0.5;
391
391
  }
392
392
 
393
393
  .editor-toggle {
394
- position: fixed;
395
- top: 1em;
396
- right: 1em;
397
394
  background: var(--blue);
398
- color: white;
399
395
  border: 0;
400
396
  border-radius: 0.5em;
401
- padding: 0.5em 1em;
402
- font-size: 1em;
397
+ color: white;
403
398
  cursor: pointer;
404
- z-index: 9999999999;
405
399
  display: none;
400
+ font-size: 1em;
401
+ padding: 0.5em 1em;
402
+ position: fixed;
403
+ right: 1em;
404
+ top: 1em;
405
+ z-index: 9999999999;
406
406
  }
407
407
 
408
408
  .editor-toggle.active {
@@ -429,8 +429,8 @@
429
429
  }
430
430
 
431
431
  :is(span).edit-label {
432
- margin-bottom: 0.3em;
433
432
  display: block;
433
+ margin-bottom: 0.3em;
434
434
  }
435
435
 
436
436
  .react-tooltip {
@@ -1,7 +1,7 @@
1
1
  import { useState, useEffect, useCallback, useRef, ReactNode } from 'react'
2
2
  import { cloneConfig } from '../../helpers/cloneConfig'
3
3
  import ErrorBoundary from '../ErrorBoundary'
4
- import Layout from '../Layout'
4
+ import { Sidebar } from '../Layout'
5
5
  import './EditorPanel.styles.css'
6
6
 
7
7
  export interface BaseEditorPanelProps<TConfig = any> {
@@ -101,7 +101,6 @@ export function EditorPanel<TConfig = any>({
101
101
 
102
102
  /**
103
103
  * Toggle the editor panel visibility and update config to reflect the change.
104
- * In dashboard context, also sets editing to false to return to dashboard editor.
105
104
  */
106
105
  const onBackClick = () => {
107
106
  const newDisplayPanel = !displayPanel
@@ -110,10 +109,6 @@ export function EditorPanel<TConfig = any>({
110
109
  ...config,
111
110
  showEditorPanel: newDisplayPanel
112
111
  }
113
- // If in dashboard mode, set editing to false to return to dashboard editor
114
- if (isDashboard) {
115
- (newConfig as any).editing = false
116
- }
117
112
 
118
113
  // Update local config - the useEffect will handle syncing to parent
119
114
  updateConfig(newConfig)
@@ -124,7 +119,7 @@ export function EditorPanel<TConfig = any>({
124
119
 
125
120
  return (
126
121
  <ErrorBoundary component='EditorPanel'>
127
- <Layout.Sidebar
122
+ <Sidebar
128
123
  displayPanel={displayPanel}
129
124
  isDashboard={isDashboard || false}
130
125
  title={title}
@@ -136,7 +131,7 @@ export function EditorPanel<TConfig = any>({
136
131
  displayPanel,
137
132
  convertStateToConfig
138
133
  })}
139
- </Layout.Sidebar>
134
+ </Sidebar>
140
135
  </ErrorBoundary>
141
136
  )
142
137
  }
@@ -1,6 +1,6 @@
1
1
  import { ReactNode } from 'react'
2
2
  import ErrorBoundary from '../ErrorBoundary'
3
- import Layout from '../Layout'
3
+ import { Sidebar } from '../Layout'
4
4
 
5
5
  export interface EditorPanelDispatchProps<TState = any, TAction = any> {
6
6
  state: TState
@@ -22,7 +22,7 @@ export interface EditorPanelDispatchChildProps<TState = any, TAction = any> {
22
22
  *
23
23
  * Provides common wrapper functionality including:
24
24
  * - ErrorBoundary for error handling
25
- * - Layout.Sidebar for consistent panel display
25
+ * - Sidebar for consistent panel display
26
26
  * - State management for panel visibility
27
27
  *
28
28
  * @example
@@ -62,14 +62,14 @@ export function EditorPanelDispatch<TState = any, TAction = any>({
62
62
 
63
63
  return (
64
64
  <ErrorBoundary component='EditorPanel'>
65
- <Layout.Sidebar
65
+ <Sidebar
66
66
  title={title}
67
67
  onBackClick={onBackClick}
68
68
  displayPanel={showEditorPanel}
69
69
  isDashboard={isDashboard}
70
70
  >
71
71
  {children({ state, dispatch })}
72
- </Layout.Sidebar>
72
+ </Sidebar>
73
73
  </ErrorBoundary>
74
74
  )
75
75
  }
@@ -32,8 +32,8 @@ const FootnotesEditor: React.FC<FootnotesEditorProps> = ({ config, updateField,
32
32
  if (dataSetChanged || noCachedData) {
33
33
  setLoadingAPIData(true)
34
34
  try {
35
- newData = await fetchRemoteData(dataUrl)
36
- newData = transform.autoStandardize(newData)
35
+ const result = await fetchRemoteData(dataUrl)
36
+ newData = transform.autoStandardize(result.data)
37
37
  } catch (e) {
38
38
  setErrorMessage('There was an issue loading the data source. Please check the datasource URL and try again.')
39
39
  }
@@ -1,4 +1,5 @@
1
- import _ from 'lodash'
1
+ import cloneDeep from 'lodash/cloneDeep'
2
+ import uniq from 'lodash/uniq'
2
3
  import { SubGrouping, VizFilter, OrderBy } from '../../../types/VizFilter'
3
4
  import { handleSorting } from '../../Filters/helpers/handleSorting'
4
5
  import { filterOrderOptions } from '../../../helpers/filterOrderOptions'
@@ -16,6 +17,7 @@ type NestedDropdownEditorProps = {
16
17
  updateField: Function
17
18
  updateFilterStyle: Function
18
19
  handleGroupingCustomOrder: (index1: number, index2: number) => void
20
+ onNestedDragAreaHover?: (isHovering: boolean) => void
19
21
  }
20
22
 
21
23
  const NestedDropdownEditor: React.FC<NestedDropdownEditorProps> = ({
@@ -25,7 +27,8 @@ const NestedDropdownEditor: React.FC<NestedDropdownEditorProps> = ({
25
27
  handleNameChange: handleGroupColumnNameChange,
26
28
  filterIndex,
27
29
  rawData,
28
- updateField
30
+ updateField,
31
+ onNestedDragAreaHover
29
32
  }) => {
30
33
  const filter = config.filters[filterIndex]
31
34
  const subGrouping = filter?.subGrouping
@@ -43,12 +46,12 @@ const NestedDropdownEditor: React.FC<NestedDropdownEditorProps> = ({
43
46
 
44
47
  const handleGroupingOrderBy = (order: OrderBy) => {
45
48
  const groupSortObject = {
46
- values: _.cloneDeep(filter.values),
49
+ values: cloneDeep(filter.values),
47
50
  order
48
51
  }
49
52
  const newOrderedValues = handleSorting(groupSortObject).values
50
53
 
51
- const newAllFilters = _.cloneDeep(config.filters)
54
+ const newAllFilters = cloneDeep(config.filters)
52
55
  newAllFilters[filterIndex] = { ...filter, values: newOrderedValues, order }
53
56
  if (order === 'cust') {
54
57
  newAllFilters[filterIndex].orderedValues = newOrderedValues
@@ -66,7 +69,7 @@ const NestedDropdownEditor: React.FC<NestedDropdownEditorProps> = ({
66
69
  const filterGroups = filter.orderedValues?.length ? filter.orderedValues : filter.values
67
70
 
68
71
  const valuesLookup = filterGroups.reduce((acc, groupName) => {
69
- const values: string[] = _.uniq(
72
+ const values: string[] = uniq(
70
73
  rawData
71
74
  .map(d => {
72
75
  return d[filter.columnName] === groupName ? d[value] : ''
@@ -113,10 +116,10 @@ const NestedDropdownEditor: React.FC<NestedDropdownEditorProps> = ({
113
116
  subGroupingFitlerOrder: string[],
114
117
  groupName: string
115
118
  ) => {
116
- const updatedGroupOrderedValues = _.cloneDeep(subGroupingFitlerOrder)
119
+ const updatedGroupOrderedValues = cloneDeep(subGroupingFitlerOrder)
117
120
  const [movedItem] = updatedGroupOrderedValues.splice(currentIndex, 1)
118
121
  updatedGroupOrderedValues.splice(newIndex, 0, movedItem)
119
- const newSubGrouping = _.cloneDeep(subGrouping)
122
+ const newSubGrouping = cloneDeep(subGrouping)
120
123
  newSubGrouping.valuesLookup[groupName].values = updatedGroupOrderedValues
121
124
  newSubGrouping.valuesLookup[groupName].orderedValues = updatedGroupOrderedValues
122
125
  updateSubGroupingFilterProperty({ ...newSubGrouping, order: 'cust' })
@@ -159,7 +162,10 @@ const NestedDropdownEditor: React.FC<NestedDropdownEditorProps> = ({
159
162
  <Select
160
163
  label='Filter Grouping'
161
164
  value={filter.columnName}
162
- options={[{ value: '', label: '- Select Option -' }, ...columnNameOptions.map(opt => ({ value: opt, label: opt }))]}
165
+ options={[
166
+ { value: '', label: '- Select Option -' },
167
+ ...columnNameOptions.map(opt => ({ value: opt, label: opt }))
168
+ ]}
163
169
  onChange={e => handleGroupColumnNameChange(e.target.value)}
164
170
  />
165
171
 
@@ -168,9 +174,7 @@ const NestedDropdownEditor: React.FC<NestedDropdownEditorProps> = ({
168
174
  value={subGrouping?.columnName ?? ''}
169
175
  options={[
170
176
  { value: '', label: '- Select Option -' },
171
- ...columnNameOptions
172
- .filter(option => option !== filter.columnName)
173
- .map(opt => ({ value: opt, label: opt }))
177
+ ...columnNameOptions.filter(option => option !== filter.columnName).map(opt => ({ value: opt, label: opt }))
174
178
  ]}
175
179
  onChange={e => {
176
180
  handleSubGroupColumnNameChange(e.target.value)
@@ -222,7 +226,11 @@ const NestedDropdownEditor: React.FC<NestedDropdownEditorProps> = ({
222
226
  onChange={e => handleGroupingOrderBy(e.target.value as OrderBy)}
223
227
  />
224
228
  {filter.order === 'cust' && (
225
- <FilterOrder orderedValues={filter.orderedValues} handleFilterOrder={handleGroupingCustomOrder} />
229
+ <FilterOrder
230
+ orderedValues={filter.orderedValues}
231
+ handleFilterOrder={handleGroupingCustomOrder}
232
+ onNestedDragAreaHover={onNestedDragAreaHover}
233
+ />
226
234
  )}
227
235
  </div>
228
236
 
@@ -247,6 +255,7 @@ const NestedDropdownEditor: React.FC<NestedDropdownEditorProps> = ({
247
255
  handleFilterOrder={(sourceIndex, destinationIndex) => {
248
256
  handleSubGroupingCustomOrder(sourceIndex, destinationIndex, orderedSubGroupValues, groupName)
249
257
  }}
258
+ onNestedDragAreaHover={onNestedDragAreaHover}
250
259
  />
251
260
  </div>
252
261
  )
@@ -3,7 +3,9 @@ import Tooltip from '../../ui/Tooltip'
3
3
  import Icon from '../../ui/Icon'
4
4
  import { Visualization } from '../../../types/Visualization'
5
5
  import { UpdateFieldFunc } from '../../../types/UpdateFieldFunc'
6
- import _ from 'lodash'
6
+ import cloneDeep from 'lodash/cloneDeep'
7
+ import flatten from 'lodash/flatten'
8
+ import uniq from 'lodash/uniq'
7
9
  import { MultiSelectFilter, VizFilter, VizFilterStyle } from '../../../types/VizFilter'
8
10
  import { handleSorting } from '../../Filters/helpers/handleSorting'
9
11
  import { filterOrderOptions } from '../../../helpers/filterOrderOptions'
@@ -25,8 +27,9 @@ type VizFilterProps = {
25
27
 
26
28
  const VizFilterEditor: React.FC<VizFilterProps> = ({ config, updateField, rawData, hasFootnotes }) => {
27
29
  const openControls = useState({})
30
+ const [isNestedDragHovered, setIsNestedDragHovered] = useState(false)
28
31
  const dataColumns = useMemo(() => {
29
- return _.uniq(_.flatten(rawData?.map(row => Object.keys(row))))
32
+ return uniq(flatten(rawData?.map(row => Object.keys(row))))
30
33
  }, [rawData])
31
34
 
32
35
  // Helper function to get filter values from various sources
@@ -34,13 +37,13 @@ const VizFilterEditor: React.FC<VizFilterProps> = ({ config, updateField, rawDat
34
37
  if (filter.values && filter.values.length > 0) return filter.values
35
38
  if (filter.orderedValues && filter.orderedValues.length > 0) return filter.orderedValues
36
39
  if (filter.columnName && rawData && rawData.length > 0) {
37
- return _.uniq(rawData.map(row => row[filter.columnName]))
40
+ return uniq(rawData.map(row => row[filter.columnName]))
38
41
  }
39
42
  return []
40
43
  }
41
44
 
42
45
  const removeFilter = index => {
43
- let filters = _.cloneDeep(config.filters)
46
+ let filters = cloneDeep(config.filters)
44
47
 
45
48
  filters.splice(index, 1)
46
49
 
@@ -52,7 +55,7 @@ const VizFilterEditor: React.FC<VizFilterProps> = ({ config, updateField, rawDat
52
55
  }
53
56
 
54
57
  const updateFilterDefaultValue = (index, value) => {
55
- const filters = _.cloneDeep(config.filters)
58
+ const filters = cloneDeep(config.filters)
56
59
  const currentFilter = { ...filters[index], orderedValues: filters[index].values }
57
60
  currentFilter.defaultValue = value
58
61
  currentFilter.active = value
@@ -61,7 +64,7 @@ const VizFilterEditor: React.FC<VizFilterProps> = ({ config, updateField, rawDat
61
64
  }
62
65
 
63
66
  const updateFilterStyle = (index, style: VizFilterStyle) => {
64
- const filters = _.cloneDeep(config.filters)
67
+ const filters = cloneDeep(config.filters)
65
68
  const currentFilter = { ...filters[index], orderedValues: filters[index].values }
66
69
  currentFilter.filterStyle = style
67
70
  if (style === 'multi-select') {
@@ -77,8 +80,8 @@ const VizFilterEditor: React.FC<VizFilterProps> = ({ config, updateField, rawDat
77
80
  }
78
81
 
79
82
  const handleNameChange = (filterIndex, columnName) => {
80
- const values = _.uniq(rawData.map(row => row[columnName]))
81
- const copiedFilter = { ..._.cloneDeep(config.filters[filterIndex]), columnName, values }
83
+ const values = uniq(rawData.map(row => row[columnName]))
84
+ const copiedFilter = { ...cloneDeep(config.filters[filterIndex]), columnName, values }
82
85
  handleSorting(copiedFilter) // sorts dropdown values in place
83
86
  copiedFilter.active = copiedFilter.values[0]
84
87
  const newFilters = config.filters.map((filter, index) => {
@@ -108,7 +111,7 @@ const VizFilterEditor: React.FC<VizFilterProps> = ({ config, updateField, rawDat
108
111
  const [movedItem] = updatedValues.splice(idx1, 1)
109
112
  updatedValues.splice(idx2, 0, movedItem)
110
113
 
111
- const filtersCopy = _.cloneDeep(config.filters)
114
+ const filtersCopy = cloneDeep(config.filters)
112
115
  const filterItem = { ...filtersCopy[filterIndex] }
113
116
 
114
117
  // Overwrite filterItem.values since thats what we map through in the editor panel
@@ -131,7 +134,7 @@ const VizFilterEditor: React.FC<VizFilterProps> = ({ config, updateField, rawDat
131
134
 
132
135
  const handleFilterReorder = (idx1: number, idx2: number) => {
133
136
  if (idx1 === undefined || idx2 === undefined || idx1 === idx2) return
134
- const filters = _.cloneDeep(config.filters)
137
+ const filters = cloneDeep(config.filters)
135
138
  const [movedFilter] = filters.splice(idx1, 1)
136
139
  filters.splice(idx2, 0, movedFilter)
137
140
  updateField(null, null, 'filters', filters)
@@ -196,6 +199,7 @@ const VizFilterEditor: React.FC<VizFilterProps> = ({ config, updateField, rawDat
196
199
  key={filter.id || `filter-${filterIndex}`}
197
200
  draggableId={`filter-${filter.id || filterIndex}`}
198
201
  index={filterIndex}
202
+ isDragDisabled={isNestedDragHovered}
199
203
  >
200
204
  {(provided, snapshot) => (
201
205
  <div
@@ -305,6 +309,7 @@ const VizFilterEditor: React.FC<VizFilterProps> = ({ config, updateField, rawDat
305
309
  handleFilterOrder={(index1, index2) =>
306
310
  handleFilterOrder(index1, index2, filterIndex)
307
311
  }
312
+ onNestedDragAreaHover={setIsNestedDragHovered}
308
313
  />
309
314
  )}
310
315
  {filter.order === 'column' && (
@@ -354,6 +359,7 @@ const VizFilterEditor: React.FC<VizFilterProps> = ({ config, updateField, rawDat
354
359
  handleNameChange={value => handleNameChange(filterIndex, value)}
355
360
  updateField={updateField}
356
361
  updateFilterStyle={updateFilterStyle}
362
+ onNestedDragAreaHover={setIsNestedDragHovered}
357
363
  />
358
364
  )}
359
365
  {hasFootnotes && (