@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.
- package/.claude/agents/qa-test-developer.md +126 -0
- package/CLAUDE.local.md +67 -0
- package/LICENSE +201 -0
- package/_stories/Gallery.Charts.stories.tsx +35 -42
- package/_stories/Gallery.DataBite.stories.tsx +15 -8
- package/_stories/Gallery.Maps.stories.tsx +37 -28
- package/_stories/Gallery.WaffleChart.stories.tsx +1 -1
- package/_stories/PageART.stories.tsx +5 -4
- package/_stories/PageBRFSS.stories.tsx +21 -16
- package/_stories/PageCancerRegistries.stories.tsx +15 -15
- package/_stories/PageEasternEquineEncephalitis.stories.tsx +33 -19
- package/_stories/PageExcessiveAlcoholUse.stories.tsx +148 -143
- package/_stories/PageMaternalMortality.stories.tsx +5 -4
- package/_stories/PageOralHealth.stories.tsx +15 -10
- package/_stories/PageRespiratory.stories.tsx +4 -4
- package/_stories/PageSmokingTobacco.stories.tsx +15 -10
- package/_stories/PageStateDiabetesProfiles.stories.tsx +15 -10
- package/_stories/PageWastewater.stories.tsx +44 -30
- package/_stories/VegaImport.stories.tsx +401 -0
- package/_stories/vega-fixtures/bars-with-line.json +444 -0
- package/_stories/vega-fixtures/bars.json +58 -0
- package/_stories/vega-fixtures/combo-bar-rolling-mean.json +88 -0
- package/_stories/vega-fixtures/combo.json +68 -0
- package/_stories/vega-fixtures/grouped-horizontal-bars.json +83 -0
- package/_stories/vega-fixtures/grouped-horizontal-bars2.json +231 -0
- package/_stories/vega-fixtures/horizontal-bar.json +427 -0
- package/_stories/vega-fixtures/horizontal-bars-with-bad-colors.json +197 -0
- package/_stories/vega-fixtures/horizontal-bars2.json +58 -0
- package/_stories/vega-fixtures/lines.json +227 -0
- package/_stories/vega-fixtures/measles-bars.json +348 -0
- package/_stories/vega-fixtures/measles-map.json +11101 -0
- package/_stories/vega-fixtures/measles-stacked-bars.json +2147 -0
- package/_stories/vega-fixtures/multi-dataset.json +255 -0
- package/_stories/vega-fixtures/no-data.json +14 -0
- package/_stories/vega-fixtures/pie-chart.json +94 -0
- package/_stories/vega-fixtures/repeat-spec.json +47 -0
- package/_stories/vega-fixtures/stacked-area.json +222 -0
- package/_stories/vega-fixtures/stacked-bar-with-rect.json +3412 -0
- package/_stories/vega-fixtures/stacked-bars-with-line.json +364 -0
- package/_stories/vega-fixtures/stacked-bars.json +212 -0
- package/_stories/vega-fixtures/stacked-horizontal-bars.json +140 -0
- package/_stories/vega-fixtures/warning-combo.json +59 -0
- package/_stories/vega-fixtures/warning-scatter-and-line.json +1182 -0
- package/assets/callout-flag.svg +7 -0
- package/assets/icon-chart-area.svg +1 -0
- package/assets/icon-chart-radar.svg +23 -0
- package/assets/logo2.svg +31 -0
- package/components/AdvancedEditor/EmbedEditor.tsx +270 -38
- package/components/Alert/components/Alert.styles.css +2 -2
- package/components/ComboBox/combobox.styles.css +48 -48
- package/components/CustomColorsEditor/CustomColorsEditor.css +53 -53
- package/components/CustomColorsEditor/CustomColorsEditor.tsx +3 -10
- package/components/DataTable/DataTable.tsx +46 -18
- package/components/DataTable/DataTableStandAlone.tsx +1 -0
- package/components/DataTable/components/ChartHeader.tsx +21 -12
- package/components/DataTable/components/MapHeader.tsx +34 -28
- package/components/DataTable/components/SortIcon/sort-icon.css +5 -5
- package/components/DataTable/data-table.css +50 -52
- package/components/DataTable/helpers/applyCustomOrder.ts +17 -0
- package/components/DataTable/helpers/getChartCellValue.ts +10 -7
- package/components/DataTable/helpers/getMapDataTableColumnKeys.ts +22 -0
- package/components/DataTable/helpers/getSeriesName.ts +6 -0
- package/components/DataTable/helpers/mapCellMatrix.tsx +33 -23
- package/components/DataTable/helpers/tests/mapCellMatrix.test.ts +33 -0
- package/components/DownloadButton.tsx +14 -6
- package/components/EditorPanel/ColumnsEditor.tsx +38 -31
- package/components/EditorPanel/CustomSortOrder.tsx +94 -0
- package/components/EditorPanel/DataTableEditor.tsx +139 -23
- package/components/EditorPanel/EditorPanel.styles.css +71 -71
- package/components/EditorPanel/EditorPanel.tsx +3 -8
- package/components/EditorPanel/EditorPanelDispatch.tsx +4 -4
- package/components/EditorPanel/FootnotesEditor.tsx +2 -2
- package/components/EditorPanel/VizFilterEditor/NestedDropdownEditor.tsx +21 -12
- package/components/EditorPanel/VizFilterEditor/VizFilterEditor.tsx +16 -10
- package/components/EditorPanel/VizFilterEditor/components/FilterOrder.tsx +33 -29
- package/components/EditorPanel/components/MarkupVariablesEditor.tsx +160 -106
- package/components/EditorPanel/components/PanelMarkup.tsx +5 -1
- package/{styles/v2/components → components/EditorPanel}/editor.scss +76 -22
- package/components/EditorPanel/sections/StyleTreatmentSection.tsx +99 -0
- package/components/EditorPanel/sections/VisualSection.tsx +11 -0
- package/components/EditorWrapper/editor-wrapper.style.css +1 -1
- package/components/Filters/Filters.tsx +3 -5
- package/components/Filters/components/Tabs.tsx +19 -7
- package/{styles → components/Filters}/filters.scss +3 -3
- package/components/Footnotes/FootnotesStandAlone.tsx +4 -2
- package/components/HeaderThemeSelector/HeaderThemeSelector.css +61 -5
- package/components/Layout/components/Responsive.tsx +14 -6
- package/components/Layout/components/Sidebar/components/Sidebar.tsx +1 -1
- package/components/Layout/components/Sidebar/components/sidebar.styles.scss +14 -20
- package/components/Layout/components/Visualization/index.tsx +50 -38
- package/components/Layout/components/Visualization/visualizations.scss +232 -15
- package/components/Layout/components/VisualizationContainer.test.tsx +67 -0
- package/components/Layout/components/VisualizationContainer.tsx +37 -0
- package/components/Layout/components/VisualizationContent.test.tsx +182 -0
- package/components/Layout/components/VisualizationContent.tsx +75 -0
- package/components/Layout/index.tsx +5 -5
- package/components/Layout/styles/editor-utils.scss +3 -3
- package/components/Layout/styles/editor.scss +4 -4
- package/components/Legend/Legend.Gradient.tsx +7 -1
- package/components/Loader/loader.styles.css +2 -2
- package/components/Loading.jsx +1 -1
- package/components/MediaControls.tsx +10 -3
- package/components/MultiSelect/multiselect.styles.css +19 -19
- package/components/NestedDropdown/nesteddropdown.styles.css +15 -15
- package/components/PaletteSelector/PaletteSelector.css +15 -15
- package/components/RichTooltip/richTooltip.css +6 -6
- package/components/Table/table.styles.css +2 -2
- package/components/Waiting.tsx +1 -1
- package/components/_stories/CustomColorsEditor.stories.tsx +37 -0
- package/components/_stories/DataTable.stories.tsx +1 -0
- package/components/_stories/Filters.stories.tsx +1 -1
- package/components/_stories/styles.scss +0 -1
- package/components/elements/Button.jsx +1 -1
- package/components/elements/Card.jsx +1 -1
- package/{styles/v2/components → components/elements}/button.scss +9 -8
- package/components/inputs/InputCheckbox.jsx +1 -1
- package/components/inputs/InputSelect.tsx +1 -1
- package/components/inputs/InputText.jsx +1 -1
- package/components/inputs/InputToggle.tsx +1 -1
- package/{styles/v2/components/input → components/inputs}/_input-check-radio.scss +2 -2
- package/{styles/v2/components/input → components/inputs}/_input-group.scss +3 -3
- package/{styles/v2/components/input → components/inputs}/_input-slider.scss +2 -2
- package/{styles/v2/components/input → components/inputs}/_input.scss +5 -5
- package/{styles/v2/components/input → components/inputs}/index.scss +2 -2
- package/{styles → components}/loading.scss +1 -1
- package/components/managers/DataDesigner.tsx +1 -1
- package/{styles/v2/components → components/managers}/data-designer.scss +6 -7
- package/components/ui/Accordion.jsx +1 -1
- package/components/ui/Icon.tsx +1 -1
- package/components/ui/LoadSpin.jsx +1 -1
- package/components/ui/Modal.jsx +1 -1
- package/components/ui/Overlay.jsx +1 -1
- package/components/ui/Title/index.test.tsx +34 -0
- package/components/ui/Title/index.tsx +24 -7
- package/components/ui/Title/title.styles.css +119 -25
- package/components/ui/Tooltip.tsx +1 -1
- package/components/ui/_stories/Title.stories.tsx +1 -1
- package/{styles/v2/components → components/ui}/accordion.scss +3 -3
- package/components/ui/accordion.styles.css +11 -11
- package/{styles/v2/components → components/ui}/modal.scss +2 -2
- package/{styles/v2/components → components/ui}/overlay.scss +6 -6
- package/{styles/v2/components → components}/ui/tooltip.scss +1 -1
- package/{styles → components}/waiting.scss +9 -3
- package/data/colorPalettes.ts +18 -5
- package/data/mapColorPalettes.ts +10 -0
- package/devTemplate/dev.js +285 -0
- package/devTemplate/index.html +30 -0
- package/devTemplate/preview.html +1503 -0
- package/devTemplate/sidebar.css +151 -0
- package/dist/cove-main.css +2530 -3901
- package/dist/cove-main.css.map +1 -1
- package/generateViteConfig.js +111 -2
- package/helpers/DataTransform.ts +1 -5
- package/helpers/backfillDefaults.ts +35 -0
- package/helpers/constants.ts +12 -0
- package/helpers/cove/date.ts +64 -3
- package/helpers/cove/number.ts +29 -15
- package/helpers/cove/string.ts +29 -0
- package/helpers/coveUpdateWorker.ts +14 -8
- package/helpers/displayDataAsText.ts +1 -1
- package/helpers/embed/embedCodeGenerator.ts +80 -0
- package/helpers/embed/embedHelper.js +169 -0
- package/helpers/embed/filterUtils.ts +121 -0
- package/helpers/embed/index.ts +17 -0
- package/helpers/embed/urlValidation.ts +119 -0
- package/helpers/extractDataAndMetadata.ts +20 -0
- package/helpers/fetchRemoteData.ts +14 -8
- package/helpers/filterVizData.ts +6 -1
- package/helpers/getFileExtension.ts +0 -6
- package/helpers/labelHash.ts +9 -0
- package/helpers/markupProcessor.ts +56 -38
- package/helpers/metrics/types.ts +3 -0
- package/helpers/palettes/colorDistributions.ts +1 -1
- package/helpers/palettes/utils.ts +12 -12
- package/helpers/parseCsvWithQuotes.ts +15 -14
- package/helpers/prepareScreenshot.ts +33 -10
- package/helpers/testing.ts +44 -0
- package/helpers/tests/DataTransform.test.ts +125 -0
- package/helpers/tests/abbreviateNumber.test.ts +59 -0
- package/helpers/tests/backfillDefaults.test.ts +253 -0
- package/helpers/tests/date.test.ts +110 -0
- package/helpers/tests/extractDataAndMetadata.test.ts +93 -0
- package/helpers/tests/markupProcessor.test.ts +315 -124
- package/helpers/tests/number.test.ts +42 -0
- package/helpers/tests/prepareScreenshot.test.ts +28 -28
- package/helpers/tests/testStandaloneBuild.ts +36 -26
- package/helpers/tests/useDataVizClasses.test.ts +66 -0
- package/helpers/tests/visualizationWrapperUsage.test.ts +57 -0
- package/helpers/useDataVizClasses.ts +13 -7
- package/helpers/vegaConfig.ts +1 -1
- package/helpers/vegaConfigImport.ts +160 -0
- package/helpers/ver/4.24.4.ts +24 -0
- package/helpers/ver/4.26.1.ts +1 -1
- package/helpers/ver/4.26.2.ts +84 -0
- package/helpers/ver/4.26.3.ts +44 -0
- package/helpers/ver/4.26.4.ts +31 -0
- package/helpers/ver/tests/4.26.1.test.ts +105 -0
- package/helpers/ver/tests/4.26.2.test.ts +298 -0
- package/helpers/ver/tests/4.26.3.test.ts +168 -0
- package/helpers/ver/tests/4.26.4.test.ts +88 -0
- package/helpers/ver/tests/coveUpdateWorker.test.ts +57 -0
- package/helpers/viewports.ts +2 -0
- package/package.json +27 -32
- package/styles/_global.scss +7 -7
- package/styles/_reset.scss +2 -2
- package/styles/{v2/base → base}/_file-selector.scss +4 -4
- package/styles/{v2/base → base}/_general.scss +2 -4
- package/styles/{v2/base → base}/index.scss +1 -1
- package/styles/base.scss +107 -165
- package/styles/cove-main.scss +3 -6
- package/styles/layout/_component.scss +110 -0
- package/styles/{v2/layout → layout}/_data-table.scss +7 -7
- package/styles/layout/_wrapper-padding.scss +27 -0
- package/styles/{v2/main.scss → main.scss} +3 -1
- package/styles/{v2/themes → themes}/_color-definitions.scss +46 -41
- package/styles/{_accessibility.scss → utils/_accessibility.scss} +1 -1
- package/styles/{v2/utils → utils}/_grid.scss +8 -3
- package/styles/{_global-variables.scss → utils/_properties.scss} +133 -112
- package/styles/{v2/utils → utils}/index.scss +2 -1
- package/types/Annotation.ts +10 -11
- package/types/Axis.ts +2 -0
- package/types/ComponentStyles.ts +1 -0
- package/types/ConfigureData.ts +1 -0
- package/types/General.ts +2 -0
- package/types/MarkupInclude.ts +1 -0
- package/types/MarkupVariable.ts +2 -1
- package/types/Palette.ts +22 -0
- package/types/Table.ts +9 -0
- package/types/Visualization.ts +7 -0
- package/_stories/StoryRenderingTests.stories.tsx +0 -164
- package/helpers/embedCodeGenerator.ts +0 -109
- package/styles/_common-components.css +0 -73
- package/styles/_variables.scss +0 -63
- package/styles/v2/layout/_component.scss +0 -21
- package/styles/v2/utils/_variables.scss +0 -9
- package/{styles/v2/components/card.scss → components/elements/card.css} +2 -2
- /package/{styles/v2/components → components/ui}/icon.scss +0 -0
- /package/{styles/v2/components → components/ui}/loadspin.scss +0 -0
- /package/styles/{v2/base → base}/_heading.scss +0 -0
- /package/styles/{v2/base → base}/_reset.scss +0 -0
- /package/styles/{v2/layout → layout}/_alert.scss +0 -0
- /package/styles/{v2/layout → layout}/_progression.scss +0 -0
- /package/styles/{v2/layout → layout}/_tooltip.scss +0 -0
- /package/styles/{v2/layout → layout}/index.scss +0 -0
- /package/styles/{v2/themes → themes}/index.scss +0 -0
- /package/styles/{v2/utils → utils}/_align.scss +0 -0
- /package/styles/{v2/utils → utils}/_animations.scss +0 -0
- /package/styles/{v2/utils → utils}/_breakpoints.scss +0 -0
- /package/styles/{v2/utils → utils}/_mixins.scss +0 -0
package/types/Visualization.ts
CHANGED
|
@@ -11,6 +11,7 @@ import { General } from './General'
|
|
|
11
11
|
import { Runtime } from './Runtime'
|
|
12
12
|
import { DashboardFilters } from '@cdc/dashboard/src/types/DashboardFilters'
|
|
13
13
|
import Footnotes from './Footnotes'
|
|
14
|
+
import { TwoColorConfig } from './Palette'
|
|
14
15
|
|
|
15
16
|
// This was originally created as a catchall for the different types of visualizations.
|
|
16
17
|
// Currently it includes properties that ares specific to one Visualization type.
|
|
@@ -27,6 +28,7 @@ type DeprecatedVisualizationType = {
|
|
|
27
28
|
filters: VizFilter[]
|
|
28
29
|
general: General
|
|
29
30
|
legend: Legend
|
|
31
|
+
locale: string
|
|
30
32
|
newViz: boolean
|
|
31
33
|
isResponsiveTicks: boolean
|
|
32
34
|
openModal?: boolean
|
|
@@ -44,6 +46,11 @@ type DeprecatedVisualizationType = {
|
|
|
44
46
|
visualizationType: string
|
|
45
47
|
xAxis: Axis
|
|
46
48
|
preliminaryData: { type: 'effect' | 'suppression'; value: string }[]
|
|
49
|
+
twoColor?: TwoColorConfig
|
|
50
|
+
/** @deprecated Legacy v1 palette name - use general.palette.name instead */
|
|
51
|
+
palette?: string
|
|
52
|
+
/** @deprecated Legacy v1 color name - use general.palette.name instead */
|
|
53
|
+
color?: string
|
|
47
54
|
}
|
|
48
55
|
|
|
49
56
|
type StatefulProperties = {
|
|
@@ -1,164 +0,0 @@
|
|
|
1
|
-
import type { Meta, StoryObj } from '@storybook/react-vite'
|
|
2
|
-
import { within, expect } from 'storybook/test'
|
|
3
|
-
import { performAndAssert } from '@cdc/core/helpers/testing'
|
|
4
|
-
|
|
5
|
-
const ChartRenderingValidator = () => (
|
|
6
|
-
<div data-testid='chart-rendering-validator'>
|
|
7
|
-
<h2>Simple COVE Visualization Tests</h2>
|
|
8
|
-
<p>This test validates all stories load and render.</p>
|
|
9
|
-
</div>
|
|
10
|
-
)
|
|
11
|
-
|
|
12
|
-
const meta: Meta<typeof ChartRenderingValidator> = {
|
|
13
|
-
title: 'Testing/Story Rendering Tests',
|
|
14
|
-
component: ChartRenderingValidator,
|
|
15
|
-
parameters: {
|
|
16
|
-
layout: 'fullscreen'
|
|
17
|
-
},
|
|
18
|
-
tags: ['!dev', '!autodocs']
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
export default meta
|
|
22
|
-
type Story = StoryObj<typeof ChartRenderingValidator>
|
|
23
|
-
|
|
24
|
-
/**
|
|
25
|
-
* Fetch all stories from Storybook's JSON API and filter for visualization stories
|
|
26
|
-
* @returns Promise that resolves to an array of story URLs to test
|
|
27
|
-
*/
|
|
28
|
-
const getVisualizationStoryUrls = async (): Promise<string[]> => {
|
|
29
|
-
let response
|
|
30
|
-
try {
|
|
31
|
-
response = await fetch('http://localhost:6006/index.json')
|
|
32
|
-
} catch (error) {
|
|
33
|
-
console.error('Error fetching visualization story URLs:', error)
|
|
34
|
-
return []
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
const data = await response.json()
|
|
38
|
-
|
|
39
|
-
const storyUrls: string[] = []
|
|
40
|
-
|
|
41
|
-
Object.values(data.entries).forEach((story: any) => {
|
|
42
|
-
if (story.type === 'story') {
|
|
43
|
-
const isVisualizationStory =
|
|
44
|
-
story.title.includes('Components/Templates/') &&
|
|
45
|
-
!story.name.toLowerCase().includes('test') &&
|
|
46
|
-
!story.title.includes('Guide')
|
|
47
|
-
|
|
48
|
-
if (isVisualizationStory) {
|
|
49
|
-
const iframeUrl = `http://localhost:6006/iframe.html?id=${story.id}`
|
|
50
|
-
storyUrls.push(iframeUrl)
|
|
51
|
-
}
|
|
52
|
-
}
|
|
53
|
-
})
|
|
54
|
-
return storyUrls
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
/**
|
|
58
|
-
* Convert iframe URL to Storybook story URL for better debugging
|
|
59
|
-
* @param iframeUrl - The iframe URL (e.g., 'http://localhost:6006/iframe.html?id=components-templates-chart--multiple-lines')
|
|
60
|
-
* @returns The Storybook story URL (e.g., 'http://localhost:6006/?path=/story/components-templates-chart--multiple-lines')
|
|
61
|
-
*/
|
|
62
|
-
const iframeUrlToStoryUrl = (iframeUrl: string): string => {
|
|
63
|
-
const url = new URL(iframeUrl)
|
|
64
|
-
const storyId = url.searchParams.get('id')
|
|
65
|
-
return `http://localhost:6006/?path=/story/${storyId}`
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
/**
|
|
69
|
-
* Test a single Storybook iframe URL for successful visualization rendering
|
|
70
|
-
* @param iframeUrl - The complete iframe URL to test (e.g., 'http://localhost:6006/iframe.html?id=...')
|
|
71
|
-
* @returns Promise that resolves with test results
|
|
72
|
-
*/
|
|
73
|
-
const testIframeVisualization = async (iframeUrl: string) => {
|
|
74
|
-
iframeUrl = iframeUrl
|
|
75
|
-
|
|
76
|
-
const iframe = document.createElement('iframe')
|
|
77
|
-
iframe.style.width = '1200px'
|
|
78
|
-
iframe.style.height = '800px'
|
|
79
|
-
iframe.src = iframeUrl
|
|
80
|
-
document.body.appendChild(iframe)
|
|
81
|
-
|
|
82
|
-
try {
|
|
83
|
-
await performAndAssert(
|
|
84
|
-
'Wait for iframe to load',
|
|
85
|
-
() => {
|
|
86
|
-
try {
|
|
87
|
-
const iframeDoc = iframe.contentDocument || iframe.contentWindow?.document
|
|
88
|
-
return {
|
|
89
|
-
loaded: !!iframeDoc && iframeDoc.readyState !== 'loading',
|
|
90
|
-
readyState: iframeDoc?.readyState || 'unknown'
|
|
91
|
-
}
|
|
92
|
-
} catch (error: any) {
|
|
93
|
-
return { loaded: false, readyState: 'error', error: error.message }
|
|
94
|
-
}
|
|
95
|
-
},
|
|
96
|
-
async () => {},
|
|
97
|
-
(before, after) => {
|
|
98
|
-
return after.loaded
|
|
99
|
-
}
|
|
100
|
-
)
|
|
101
|
-
|
|
102
|
-
await performAndAssert(
|
|
103
|
-
'Wait for SVG elements to render in iframe',
|
|
104
|
-
() => {
|
|
105
|
-
try {
|
|
106
|
-
const iframeDoc = iframe?.contentDocument || iframe?.contentWindow?.document
|
|
107
|
-
if (!iframeDoc) return { svgCount: 0, hasCoveModule: false, error: 'No document access' }
|
|
108
|
-
|
|
109
|
-
const svgCount = iframeDoc.querySelectorAll('svg').length
|
|
110
|
-
const hasCoveModule = !!iframeDoc.querySelector('.cdc-open-viz-module')
|
|
111
|
-
const isDataBite = !!iframeDoc.querySelector('.bite-content')
|
|
112
|
-
const isDataTable = !!iframeDoc.querySelector('.data-table')
|
|
113
|
-
|
|
114
|
-
return { svgCount, hasCoveModule, isDataBite, isDataTable, error: null }
|
|
115
|
-
} catch (error: any) {
|
|
116
|
-
return { svgCount: 0, hasCoveModule: false, isDataBite: false, isDataTable: false, error: error.message }
|
|
117
|
-
}
|
|
118
|
-
},
|
|
119
|
-
async () => {},
|
|
120
|
-
(before, after) => {
|
|
121
|
-
return (after.svgCount > 0 && after.hasCoveModule) || after.isDataBite || after.isDataTable
|
|
122
|
-
}
|
|
123
|
-
)
|
|
124
|
-
} finally {
|
|
125
|
-
if (iframe.parentNode) {
|
|
126
|
-
document.body.removeChild(iframe)
|
|
127
|
-
}
|
|
128
|
-
}
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
export const StoryRenderingTests: Story = {
|
|
132
|
-
play: async ({ canvasElement }) => {
|
|
133
|
-
const canvas = within(canvasElement)
|
|
134
|
-
expect(canvas.getByTestId('chart-rendering-validator')).toBeInTheDocument()
|
|
135
|
-
|
|
136
|
-
const storyUrls = await getVisualizationStoryUrls()
|
|
137
|
-
|
|
138
|
-
if (storyUrls.length === 0) {
|
|
139
|
-
console.warn('No visualization stories found to test')
|
|
140
|
-
return
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
const results: { iframeUrl: string; storyUrl: string; success: boolean; error?: string }[] = []
|
|
144
|
-
|
|
145
|
-
for (const [i, iframeUrl] of storyUrls.entries()) {
|
|
146
|
-
const storyUrl = iframeUrlToStoryUrl(iframeUrl)
|
|
147
|
-
|
|
148
|
-
try {
|
|
149
|
-
await testIframeVisualization(iframeUrl)
|
|
150
|
-
results.push({ iframeUrl, storyUrl, success: true })
|
|
151
|
-
} catch (error: any) {
|
|
152
|
-
if (i > 0) {
|
|
153
|
-
results.push({ iframeUrl, storyUrl, success: false, error: error.message })
|
|
154
|
-
}
|
|
155
|
-
}
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
const failed = results.filter(r => !r.success).length
|
|
159
|
-
|
|
160
|
-
if (failed > 0) {
|
|
161
|
-
throw new Error(`${failed} out of ${storyUrls.length} visualization stories failed to render`)
|
|
162
|
-
}
|
|
163
|
-
}
|
|
164
|
-
}
|
|
@@ -1,109 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Generates iframe embed code for COVE visualizations
|
|
3
|
-
* Used by editor's "Share with Partners" feature
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
interface EmbedCodeOptions {
|
|
7
|
-
configUrl: string
|
|
8
|
-
width?: string
|
|
9
|
-
height?: string
|
|
10
|
-
embedBaseUrl?: string
|
|
11
|
-
helperScriptUrl?: string
|
|
12
|
-
/** Additional URL parameters (e.g., filter values, hide flags) */
|
|
13
|
-
urlParams?: Record<string, string>
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
/**
|
|
17
|
-
* Detect if we're in development mode
|
|
18
|
-
*/
|
|
19
|
-
export function isDevMode(): boolean {
|
|
20
|
-
if (typeof window === 'undefined') return false
|
|
21
|
-
return window.location.hostname === 'localhost' || window.location.hostname === '127.0.0.1'
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
/**
|
|
25
|
-
* Get default embed base URL based on environment
|
|
26
|
-
* Returns full absolute URL including protocol and host
|
|
27
|
-
*/
|
|
28
|
-
export function getDefaultEmbedBaseUrl(): string {
|
|
29
|
-
if (isDevMode()) {
|
|
30
|
-
return 'http://localhost:8080'
|
|
31
|
-
}
|
|
32
|
-
return 'https://www.cdc.gov/TemplatePackage/contrib/widgets/openVizWrapper/dist/embed/embed.html'
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
/**
|
|
36
|
-
* Get embed path (without protocol/host) for same-origin usage
|
|
37
|
-
* Use this for preview iframes on the same domain
|
|
38
|
-
*/
|
|
39
|
-
export function getEmbedPath(): string {
|
|
40
|
-
if (isDevMode()) {
|
|
41
|
-
return '/'
|
|
42
|
-
}
|
|
43
|
-
return '/TemplatePackage/contrib/widgets/openVizWrapper/dist/embed/embed.html'
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
/**
|
|
47
|
-
* Get default embed helper script URL based on environment
|
|
48
|
-
*/
|
|
49
|
-
export function getDefaultHelperScriptUrl(): string {
|
|
50
|
-
if (isDevMode()) {
|
|
51
|
-
return 'http://localhost:8080/src/embed-helper/index.js'
|
|
52
|
-
}
|
|
53
|
-
return 'https://www.cdc.gov/TemplatePackage/contrib/widgets/openVizWrapper/dist/embed/embed-helper.js'
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
/**
|
|
57
|
-
* Get default generator base URL based on environment
|
|
58
|
-
*/
|
|
59
|
-
export function getDefaultGeneratorBaseUrl(): string {
|
|
60
|
-
if (isDevMode()) {
|
|
61
|
-
return 'http://localhost:8080/generator.html'
|
|
62
|
-
}
|
|
63
|
-
return 'https://www.cdc.gov/TemplatePackage/contrib/widgets/openVizWrapper/dist/embed/generator.html'
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
/**
|
|
67
|
-
* Generate basic iframe embed code for partners
|
|
68
|
-
*
|
|
69
|
-
* @param options.configUrl - URL to the published config JSON
|
|
70
|
-
* @param options.width - iframe width (default: "100%")
|
|
71
|
-
* @param options.height - iframe height (default: "300")
|
|
72
|
-
* @param options.embedBaseUrl - Base URL for embed page (auto-detected by environment)
|
|
73
|
-
* @param options.helperScriptUrl - URL for embed-helper.js (auto-detected by environment)
|
|
74
|
-
* @param options.urlParams - Additional URL parameters (e.g., filter values, hide flags)
|
|
75
|
-
* @returns HTML string with iframe and script tag
|
|
76
|
-
*/
|
|
77
|
-
export function generateEmbedCode(options: EmbedCodeOptions): string {
|
|
78
|
-
const {
|
|
79
|
-
configUrl,
|
|
80
|
-
width = '100%',
|
|
81
|
-
height = '300',
|
|
82
|
-
embedBaseUrl = getDefaultEmbedBaseUrl(),
|
|
83
|
-
helperScriptUrl = getDefaultHelperScriptUrl(),
|
|
84
|
-
urlParams = {}
|
|
85
|
-
} = options
|
|
86
|
-
|
|
87
|
-
// Construct embed page URL with config parameter and any additional params
|
|
88
|
-
const params = new URLSearchParams()
|
|
89
|
-
params.set('configUrl', configUrl)
|
|
90
|
-
|
|
91
|
-
// Add any additional URL parameters (filters, hide flags, etc.)
|
|
92
|
-
Object.entries(urlParams).forEach(([key, value]) => {
|
|
93
|
-
if (value) params.set(key, value)
|
|
94
|
-
})
|
|
95
|
-
|
|
96
|
-
const embedUrl = `${embedBaseUrl}?${params.toString()}`
|
|
97
|
-
|
|
98
|
-
// Generate iframe code
|
|
99
|
-
const iframeCode = `<iframe src="${embedUrl}"
|
|
100
|
-
data-cove-embed
|
|
101
|
-
width="${width}"
|
|
102
|
-
height="${height}"
|
|
103
|
-
frameborder="0"
|
|
104
|
-
title="CDC Data Visualization"
|
|
105
|
-
></iframe>
|
|
106
|
-
<script src="${helperScriptUrl}"></script>`
|
|
107
|
-
|
|
108
|
-
return iframeCode
|
|
109
|
-
}
|
|
@@ -1,73 +0,0 @@
|
|
|
1
|
-
/* Common component styles shared across packages */
|
|
2
|
-
/* This file combines loader, warning-icon, and checkbox-group styles */
|
|
3
|
-
|
|
4
|
-
/* Shared loader component */
|
|
5
|
-
/* Used across: chart, dashboard, data-bite, waffle-chart packages */
|
|
6
|
-
.loader {
|
|
7
|
-
width: 100%;
|
|
8
|
-
text-align: center;
|
|
9
|
-
display: inline-block;
|
|
10
|
-
animation: spin 1s linear infinite;
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
.loader::before {
|
|
14
|
-
content: '\21BB';
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
/* Shared warning icon component */
|
|
18
|
-
/* TODO: Currently different panel classes on different packages */
|
|
19
|
-
.accordion__button svg.warning-icon,
|
|
20
|
-
.cove-accordion__button svg.warning-icon {
|
|
21
|
-
position: absolute;
|
|
22
|
-
right: 35px;
|
|
23
|
-
left: auto;
|
|
24
|
-
top: 50%;
|
|
25
|
-
transform: translateY(-50%);
|
|
26
|
-
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
.warning-icon {
|
|
30
|
-
color: #d72f00;
|
|
31
|
-
width: 15px;
|
|
32
|
-
height: 15px;
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
.warning-icon path {
|
|
36
|
-
fill: #d8000c;
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
/* Shared checkbox group component */
|
|
40
|
-
/* Used across: chart, data-bite, markup-include packages */
|
|
41
|
-
.checkbox-group {
|
|
42
|
-
padding: 16px;
|
|
43
|
-
border: 1px solid #c4c4c4;
|
|
44
|
-
border-radius: 8px;
|
|
45
|
-
margin-top: 8px;
|
|
46
|
-
margin-bottom: 24px;
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
.cove-accordion__panel.panel-visual .checkbox-group label.checkbox,
|
|
50
|
-
.cove-accordion__panel.panel-visual .reverse-labels label.checkbox,
|
|
51
|
-
.panel-visual .checkbox-group label.checkbox,
|
|
52
|
-
.panel-visual .reverse-labels label.checkbox {
|
|
53
|
-
display: flex !important;
|
|
54
|
-
align-items: center !important;
|
|
55
|
-
width: 100% !important;
|
|
56
|
-
margin-bottom: 8px !important;
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
.cove-accordion__panel.panel-visual .checkbox-group label.checkbox input[type="checkbox"],
|
|
60
|
-
.cove-accordion__panel.panel-visual .reverse-labels label.checkbox input[type="checkbox"],
|
|
61
|
-
.panel-visual .checkbox-group label.checkbox input[type="checkbox"],
|
|
62
|
-
.panel-visual .reverse-labels label.checkbox input[type="checkbox"] {
|
|
63
|
-
flex-shrink: 0 !important;
|
|
64
|
-
margin-right: 8px !important;
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
.cove-accordion__panel.panel-visual .checkbox-group label.checkbox span,
|
|
68
|
-
.cove-accordion__panel.panel-visual .reverse-labels label.checkbox span,
|
|
69
|
-
.panel-visual .checkbox-group label.checkbox span,
|
|
70
|
-
.panel-visual .reverse-labels label.checkbox span {
|
|
71
|
-
flex: 1 !important;
|
|
72
|
-
display: inline-block !important;
|
|
73
|
-
}
|
package/styles/_variables.scss
DELETED
|
@@ -1,63 +0,0 @@
|
|
|
1
|
-
$baseColor: #333;
|
|
2
|
-
$blue: #005eaa;
|
|
3
|
-
$lightestGray: #f2f2f2;
|
|
4
|
-
$lightGray: #c7c7c7;
|
|
5
|
-
$mediumGray: #565656;
|
|
6
|
-
$darkGray: #333;
|
|
7
|
-
$red: #d8000c;
|
|
8
|
-
$white: #fff;
|
|
9
|
-
|
|
10
|
-
$primary: #005eaa !default;
|
|
11
|
-
$secondary: #88c3ea !default;
|
|
12
|
-
$tertiary: #c0e9ff !default;
|
|
13
|
-
$quaternary: #edf9ff !default;
|
|
14
|
-
|
|
15
|
-
$purple-primary: #712177 !default;
|
|
16
|
-
$purple-secondary: #b890bb !default;
|
|
17
|
-
$purple-tertiary: #e3d3e4 !default;
|
|
18
|
-
$purple-quaternary: #f7f2f7 !default;
|
|
19
|
-
|
|
20
|
-
$brown-primary: #705043 !default;
|
|
21
|
-
$brown-secondary: #ad907b !default;
|
|
22
|
-
$brown-tertiary: #d7ccc8 !default;
|
|
23
|
-
$brown-quaternary: #f2ebe8 !default;
|
|
24
|
-
|
|
25
|
-
$teal-primary: #00695c !default;
|
|
26
|
-
$teal-secondary: #4ebaaa !default;
|
|
27
|
-
$teal-tertiary: #ceece7 !default;
|
|
28
|
-
$teal-quaternary: #ebf7f5 !default;
|
|
29
|
-
|
|
30
|
-
$pink-primary: #af4448 !default;
|
|
31
|
-
$pink-secondary: #e57373 !default;
|
|
32
|
-
$pink-tertiary: #ffc2c2 !default;
|
|
33
|
-
$pink-quaternary: #ffe7e7 !default;
|
|
34
|
-
|
|
35
|
-
$orange-primary: #bb4d00 !default;
|
|
36
|
-
$orange-secondary: #ffad42 !default;
|
|
37
|
-
$orange-tertiary: #ffe97d !default;
|
|
38
|
-
$orange-quaternary: #fff4cf !default;
|
|
39
|
-
|
|
40
|
-
$slate-primary: #29434e !default;
|
|
41
|
-
$slate-secondary: #7e9ba5 !default;
|
|
42
|
-
$slate-tertiary: #b6c6d2 !default;
|
|
43
|
-
$slate-quaternary: #e2e8ed !default;
|
|
44
|
-
|
|
45
|
-
$indigo-primary: #26418f !default;
|
|
46
|
-
$indigo-secondary: #92a6dd !default;
|
|
47
|
-
$indigo-tertiary: #dee8ff !default;
|
|
48
|
-
$indigo-quaternary: #f2f6ff !default;
|
|
49
|
-
|
|
50
|
-
$cyan-primary: #006778 !default;
|
|
51
|
-
$cyan-secondary: #65b0bd !default;
|
|
52
|
-
$cyan-tertiary: #cce5e9 !default;
|
|
53
|
-
$cyan-quaternary: #ebf5f6 !default;
|
|
54
|
-
|
|
55
|
-
$green-primary: #4b830d !default;
|
|
56
|
-
$green-secondary: #84bc49 !default;
|
|
57
|
-
$green-tertiary: #dcedc8 !default;
|
|
58
|
-
$green-quaternary: #f1f8e9 !default;
|
|
59
|
-
|
|
60
|
-
$amber-primary: #fbab18 !default;
|
|
61
|
-
$amber-secondary: #ffd54f !default;
|
|
62
|
-
$amber-tertiary: #ffecb3 !default;
|
|
63
|
-
$amber-quaternary: #fff7e1 !default;
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
.cove-component {
|
|
2
|
-
border-radius: 3px;
|
|
3
|
-
}
|
|
4
|
-
|
|
5
|
-
.cove-component__content {
|
|
6
|
-
border: solid 1px #ccc;
|
|
7
|
-
border-top: none;
|
|
8
|
-
border-radius: 0 0 3px 3px;
|
|
9
|
-
|
|
10
|
-
&.no-borders {
|
|
11
|
-
border: none !important;
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
.cove-component__content:not(.component--hideBackgroundColor) {
|
|
15
|
-
background: $lightestGray;
|
|
16
|
-
}
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
.cove-component__content-wrap {
|
|
20
|
-
padding: 0 1rem 1rem;
|
|
21
|
-
}
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|