@cdc/core 4.25.11 → 4.26.2

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 (147) hide show
  1. package/.claude/agents/qa-test-developer.md +126 -0
  2. package/CLAUDE.local.md +67 -0
  3. package/_stories/Gallery.Charts.stories.tsx +300 -0
  4. package/_stories/Gallery.DataBite.stories.tsx +79 -0
  5. package/_stories/Gallery.Maps.stories.tsx +239 -0
  6. package/_stories/Gallery.WaffleChart.stories.tsx +187 -0
  7. package/_stories/PageART.stories.tsx +193 -0
  8. package/_stories/PageBRFSS.stories.tsx +294 -0
  9. package/_stories/PageCancerRegistries.stories.tsx +199 -0
  10. package/_stories/PageEasternEquineEncephalitis.stories.tsx +216 -0
  11. package/_stories/PageExcessiveAlcoholUse.stories.tsx +201 -0
  12. package/_stories/PageMaternalMortality.stories.tsx +193 -0
  13. package/_stories/PageOralHealth.stories.tsx +201 -0
  14. package/_stories/PageRespiratory.stories.tsx +332 -0
  15. package/_stories/PageSmokingTobacco.stories.tsx +200 -0
  16. package/_stories/PageStateDiabetesProfiles.stories.tsx +201 -0
  17. package/_stories/PageWastewater.stories.tsx +477 -0
  18. package/_stories/VegaImport.stories.tsx +401 -0
  19. package/_stories/vega-fixtures/bars-with-line.json +444 -0
  20. package/_stories/vega-fixtures/bars.json +58 -0
  21. package/_stories/vega-fixtures/combo-bar-rolling-mean.json +88 -0
  22. package/_stories/vega-fixtures/combo.json +68 -0
  23. package/_stories/vega-fixtures/grouped-horizontal-bars.json +83 -0
  24. package/_stories/vega-fixtures/grouped-horizontal-bars2.json +231 -0
  25. package/_stories/vega-fixtures/horizontal-bar.json +427 -0
  26. package/_stories/vega-fixtures/horizontal-bars-with-bad-colors.json +197 -0
  27. package/_stories/vega-fixtures/horizontal-bars2.json +58 -0
  28. package/_stories/vega-fixtures/lines.json +227 -0
  29. package/_stories/vega-fixtures/measles-bars.json +348 -0
  30. package/_stories/vega-fixtures/measles-map.json +11101 -0
  31. package/_stories/vega-fixtures/measles-stacked-bars.json +2147 -0
  32. package/_stories/vega-fixtures/multi-dataset.json +255 -0
  33. package/_stories/vega-fixtures/no-data.json +14 -0
  34. package/_stories/vega-fixtures/pie-chart.json +94 -0
  35. package/_stories/vega-fixtures/repeat-spec.json +47 -0
  36. package/_stories/vega-fixtures/stacked-area.json +222 -0
  37. package/_stories/vega-fixtures/stacked-bar-with-rect.json +3412 -0
  38. package/_stories/vega-fixtures/stacked-bars-with-line.json +364 -0
  39. package/_stories/vega-fixtures/stacked-bars.json +212 -0
  40. package/_stories/vega-fixtures/stacked-horizontal-bars.json +140 -0
  41. package/_stories/vega-fixtures/warning-combo.json +59 -0
  42. package/_stories/vega-fixtures/warning-scatter-and-line.json +1182 -0
  43. package/assets/icon-chart-area.svg +1 -0
  44. package/assets/icon-chart-radar.svg +23 -0
  45. package/assets/icon-magnifying-glass.svg +5 -0
  46. package/assets/icon-warming-stripes.svg +13 -0
  47. package/assets/logo2.svg +31 -0
  48. package/components/AdvancedEditor/AdvancedEditor.tsx +4 -0
  49. package/components/AdvancedEditor/EmbedEditor.tsx +513 -0
  50. package/components/ComboBox/ComboBox.tsx +345 -0
  51. package/components/ComboBox/combobox.styles.css +185 -0
  52. package/components/ComboBox/index.ts +1 -0
  53. package/components/CustomColorsEditor/CustomColorsEditor.tsx +3 -10
  54. package/components/DataTable/DataTable.tsx +132 -58
  55. package/components/DataTable/data-table.css +216 -215
  56. package/components/DataTable/helpers/getSeriesName.ts +6 -0
  57. package/components/DataTable/helpers/mapCellMatrix.tsx +14 -6
  58. package/components/EditorPanel/ColumnsEditor.tsx +37 -19
  59. package/components/EditorPanel/DataTableEditor.tsx +51 -25
  60. package/components/EditorPanel/EditorPanel.styles.css +16 -0
  61. package/components/EditorPanel/EditorPanel.tsx +144 -0
  62. package/components/EditorPanel/EditorPanelDispatch.tsx +75 -0
  63. package/components/EditorPanel/FieldSetWrapper.tsx +66 -23
  64. package/components/EditorPanel/Inputs.tsx +33 -7
  65. package/components/EditorPanel/VizFilterEditor/NestedDropdownEditor.tsx +14 -6
  66. package/components/EditorPanel/VizFilterEditor/VizFilterEditor.tsx +240 -175
  67. package/components/EditorPanel/VizFilterEditor/components/FilterOrder.tsx +33 -29
  68. package/components/EditorPanel/sections/VisualSection.tsx +169 -0
  69. package/components/Filters/Filters.tsx +31 -5
  70. package/components/Filters/helpers/getNestedOptions.ts +2 -1
  71. package/components/Filters/helpers/handleSorting.ts +1 -1
  72. package/components/Layout/components/Sidebar/components/sidebar.styles.scss +84 -2
  73. package/components/Layout/components/Visualization/index.tsx +27 -1
  74. package/components/Layout/components/Visualization/visualizations.scss +7 -0
  75. package/components/Legend/Legend.Gradient.tsx +1 -1
  76. package/components/MediaControls.tsx +53 -28
  77. package/components/_stories/CustomColorsEditor.stories.tsx +37 -0
  78. package/components/_stories/DataTable.stories.tsx +1 -0
  79. package/components/ui/Icon.tsx +3 -1
  80. package/components/ui/Title/index.tsx +30 -2
  81. package/components/ui/Title/title.styles.css +42 -0
  82. package/data/colorPalettes.ts +18 -5
  83. package/data/mapColorPalettes.ts +10 -0
  84. package/devTemplate/dev.js +235 -0
  85. package/devTemplate/index.html +30 -0
  86. package/devTemplate/preview.html +1503 -0
  87. package/devTemplate/sidebar.css +151 -0
  88. package/dist/cove-main.css +2803 -4448
  89. package/dist/cove-main.css.map +1 -1
  90. package/generateViteConfig.js +118 -2
  91. package/helpers/DataTransform.ts +1 -5
  92. package/helpers/addValuesToFilters.ts +6 -1
  93. package/helpers/cove/date.ts +33 -1
  94. package/helpers/cove/string.ts +29 -0
  95. package/helpers/coveUpdateWorker.ts +21 -12
  96. package/helpers/embed/embedCodeGenerator.ts +80 -0
  97. package/helpers/embed/embedHelper.js +158 -0
  98. package/helpers/embed/filterUtils.ts +121 -0
  99. package/helpers/embed/index.ts +21 -0
  100. package/helpers/embed/urlValidation.ts +119 -0
  101. package/helpers/filterVizData.ts +6 -1
  102. package/helpers/getFileExtension.ts +0 -6
  103. package/helpers/getUniqueValues.ts +19 -0
  104. package/helpers/hashObj.ts +25 -0
  105. package/helpers/isRightAlignedTableValue.js +5 -0
  106. package/helpers/metrics/helpers.ts +1 -0
  107. package/helpers/metrics/types.ts +3 -0
  108. package/helpers/palettes/colorDistributions.ts +1 -1
  109. package/helpers/palettes/utils.ts +12 -12
  110. package/helpers/parseCsvWithQuotes.ts +15 -14
  111. package/helpers/pivotData.ts +2 -2
  112. package/helpers/prepareScreenshot.ts +288 -0
  113. package/helpers/queryStringUtils.ts +29 -0
  114. package/helpers/testing.ts +44 -0
  115. package/helpers/tests/DataTransform.test.ts +125 -0
  116. package/helpers/tests/date.test.ts +64 -0
  117. package/helpers/tests/prepareScreenshot.test.ts +414 -0
  118. package/helpers/tests/queryStringUtils.test.ts +381 -0
  119. package/helpers/tests/testStandaloneBuild.ts +23 -5
  120. package/helpers/useDataVizClasses.ts +0 -1
  121. package/helpers/vegaConfig.ts +1 -1
  122. package/helpers/vegaConfigImport.ts +160 -0
  123. package/helpers/ver/4.26.1.ts +80 -0
  124. package/helpers/ver/4.26.2.ts +84 -0
  125. package/helpers/ver/tests/4.26.1.test.ts +105 -0
  126. package/helpers/ver/tests/4.26.2.test.ts +298 -0
  127. package/helpers/viewports.ts +2 -0
  128. package/hooks/useDataColumns.ts +63 -0
  129. package/hooks/useFilterManagement.ts +94 -0
  130. package/hooks/useLegendSeparators.ts +26 -0
  131. package/hooks/useListManagement.ts +192 -0
  132. package/package.json +29 -33
  133. package/styles/_button-section.scss +0 -3
  134. package/styles/v2/components/editor.scss +9 -9
  135. package/styles/v2/utils/_grid.scss +8 -3
  136. package/types/Annotation.ts +10 -11
  137. package/types/Axis.ts +1 -0
  138. package/types/ForecastingSeriesKey.ts +1 -0
  139. package/types/General.ts +2 -0
  140. package/types/MarkupInclude.ts +1 -0
  141. package/types/Palette.ts +21 -0
  142. package/types/Series.ts +3 -0
  143. package/types/Table.ts +1 -0
  144. package/types/Visualization.ts +7 -0
  145. package/types/VizFilter.ts +1 -0
  146. package/LICENSE +0 -201
  147. package/_stories/StoryRenderingTests.stories.tsx +0 -164
@@ -0,0 +1,126 @@
1
+ ---
2
+ name: qa-test-developer
3
+ description: "Use this agent when you need to add, update, or improve test coverage for components and features. This includes writing unit tests with Vitest, creating Playwright integration tests within Storybook, and coordinating visual regression testing with Backstop. Trigger this agent after implementing new components, fixing bugs, or when test coverage needs improvement.\\n\\nExamples:\\n\\n<example>\\nContext: User has just implemented a new chart component.\\nuser: \"I just created a new PieChart component in the chart package\"\\nassistant: \"I can see the new PieChart component. Let me use the qa-test-developer agent to add comprehensive test coverage for it.\"\\n<Task tool invocation to launch qa-test-developer agent>\\n</example>\\n\\n<example>\\nContext: User wants to ensure a bug fix is properly tested.\\nuser: \"I fixed a bug in the data-table sorting logic\"\\nassistant: \"Great fix! I'll use the qa-test-developer agent to add tests that verify this bug won't regress and ensure the sorting behavior is well-covered.\"\\n<Task tool invocation to launch qa-test-developer agent>\\n</example>\\n\\n<example>\\nContext: User is asking for test coverage on existing code.\\nuser: \"Can you add tests for the Dashboard layout components?\"\\nassistant: \"I'll launch the qa-test-developer agent to analyze the Dashboard components and create comprehensive unit and integration tests.\"\\n<Task tool invocation to launch qa-test-developer agent>\\n</example>\\n\\n<example>\\nContext: Proactive usage after significant code changes detected.\\nassistant: \"I notice significant changes were made to the map visualization rendering logic. Let me use the qa-test-developer agent to ensure proper test coverage for these changes.\"\\n<Task tool invocation to launch qa-test-developer agent>\\n</example>"
4
+ model: sonnet
5
+ memory: project
6
+ ---
7
+
8
+ You are an expert QA Developer specializing in React component testing within monorepo environments. You have deep expertise in Vitest for unit testing, Playwright for integration testing within Storybook, and visual regression testing with Backstop.js. Your goal is to create comprehensive, maintainable test suites that catch bugs early and document component behavior.
9
+
10
+ ## Your Core Responsibilities
11
+
12
+ 1. **Write Unit Tests with Vitest**
13
+ - Create tests in `*.test.{js,jsx,ts,tsx}` files alongside the components
14
+ - Use the jsdom environment configured in the project
15
+ - Import from `testing-setup.js` when DOM matchers are needed
16
+ - Test component rendering, props handling, state changes, and edge cases
17
+ - Mock external dependencies appropriately
18
+ - Follow the AAA pattern: Arrange, Act, Assert
19
+ - Aim for meaningful coverage, not just line coverage
20
+
21
+ 2. **Create Playwright Integration Tests in Storybook**
22
+ - Write interaction tests using Storybook's play functions
23
+ - Test user workflows and component interactions
24
+ - Verify accessibility requirements
25
+ - Test responsive behavior when relevant
26
+ - Use `@storybook/test` utilities for assertions
27
+ - Structure tests to run with `yarn test-storybook`
28
+
29
+ 3. **Coordinate Backstop Visual Regression Testing**
30
+ - **Always ask the user** if Backstop tests should be updated or created
31
+ - When approved, create or update Backstop scenarios
32
+ - Define appropriate viewports for responsive testing
33
+ - Set meaningful selectors and hide dynamic elements
34
+ - Document any visual baseline changes needed
35
+
36
+ ## Testing Patterns for This Codebase
37
+
38
+ ### Vitest Unit Test Structure
39
+ ```typescript
40
+ import { describe, it, expect, vi } from 'vitest';
41
+ import { render, screen } from '@testing-library/react';
42
+ import userEvent from '@testing-library/user-event';
43
+ import { ComponentName } from './ComponentName';
44
+
45
+ describe('ComponentName', () => {
46
+ it('should render with default props', () => {
47
+ render(<ComponentName />);
48
+ expect(screen.getByRole('...')).toBeInTheDocument();
49
+ });
50
+
51
+ it('should handle user interaction', async () => {
52
+ const user = userEvent.setup();
53
+ const onAction = vi.fn();
54
+ render(<ComponentName onAction={onAction} />);
55
+
56
+ await user.click(screen.getByRole('button'));
57
+ expect(onAction).toHaveBeenCalledTimes(1);
58
+ });
59
+ });
60
+ ```
61
+
62
+ ### Storybook Play Function Structure
63
+ ```typescript
64
+ import type { Meta, StoryObj } from '@storybook/react';
65
+ import { within, userEvent, expect } from '@storybook/test';
66
+
67
+ export const WithInteraction: StoryObj = {
68
+ play: async ({ canvasElement }) => {
69
+ const canvas = within(canvasElement);
70
+
71
+ await userEvent.click(canvas.getByRole('button'));
72
+ await expect(canvas.getByText('Expected Result')).toBeInTheDocument();
73
+ },
74
+ };
75
+ ```
76
+
77
+ ## Workflow
78
+
79
+ 1. **Analyze the Component/Feature**: Understand what needs testing by reading the implementation
80
+ 2. **Identify Test Scenarios**: List unit tests, integration tests, and potential visual tests
81
+ 3. **Write Unit Tests First**: Create comprehensive Vitest tests
82
+ 4. **Add Storybook Integration Tests**: Write play functions for user interaction flows
83
+ 5. **Ask About Backstop**: Explicitly ask the user if visual regression tests should be added/updated
84
+ 6. **Verify Tests Pass**: Run the tests to ensure they work correctly
85
+
86
+ ## Quality Standards
87
+
88
+ - Tests should be deterministic and not flaky
89
+ - Use meaningful test descriptions that document behavior
90
+ - Avoid testing implementation details; test behavior
91
+ - Mock at the boundaries (API calls, external services)
92
+ - Keep tests focused and independent
93
+ - Clean up after tests (no shared state pollution)
94
+
95
+ ## Before Completing
96
+
97
+ - Ensure all new tests pass: `vitest run` or `yarn test-storybook`
98
+ - Verify no existing tests were broken
99
+ - Confirm test file locations follow project conventions
100
+ - Ask about Backstop if visual changes are involved
101
+
102
+ **Update your agent memory** as you discover testing patterns, common test utilities used in this codebase, component testing quirks, and established testing conventions. This builds institutional knowledge for consistent test quality across the monorepo.
103
+
104
+ Examples of what to record:
105
+ - Common mocking patterns for specific dependencies
106
+ - Reusable test utilities in @cdc/core
107
+ - Components that require special testing setup
108
+ - Known flaky test patterns to avoid
109
+
110
+ # Persistent Agent Memory
111
+
112
+ You have a persistent Persistent Agent Memory directory at `/Users/adamdoe/Code/cdc-open-viz/packages/core/.claude/agent-memory/qa-test-developer/`. Its contents persist across conversations.
113
+
114
+ As you work, consult your memory files to build on previous experience. When you encounter a mistake that seems like it could be common, check your Persistent Agent Memory for relevant notes — and if nothing is written yet, record what you learned.
115
+
116
+ Guidelines:
117
+ - Record insights about problem constraints, strategies that worked or failed, and lessons learned
118
+ - Update or remove memories that turn out to be wrong or outdated
119
+ - Organize memory semantically by topic, not chronologically
120
+ - `MEMORY.md` is always loaded into your system prompt — lines after 200 will be truncated, so keep it concise and link to other files in your Persistent Agent Memory directory for details
121
+ - Use the Write and Edit tools to update your memory files
122
+ - Since this memory is project-scope and shared with your team via version control, tailor your memories to this project
123
+
124
+ ## MEMORY.md
125
+
126
+ Your MEMORY.md is currently empty. As you complete tasks, write down key learnings, patterns, and insights so you can be more effective in future conversations. Anything saved in MEMORY.md will be included in your system prompt next time.
@@ -0,0 +1,67 @@
1
+ # @cdc/core — Package Rules
2
+
3
+ ## Build
4
+ - Core has **no JavaScript build step**. The build script only compiles SCSS: `sass styles/cove-main.scss dist/cove-main.css`.
5
+ - All components, helpers, hooks, and types are imported **directly from source** by other packages. Never reference `dist/` for JS/TS imports.
6
+
7
+ ## Where to Put New Code
8
+
9
+ | What you're adding | Where it goes |
10
+ |---|---|
11
+ | Shared React component | `components/<ComponentName>/` (directory with index file) |
12
+ | Shared helper function | `helpers/<functionName>.ts` (flat file at top level) |
13
+ | Shared custom hook | `hooks/use<Name>.ts` |
14
+ | Shared TypeScript type | `types/<TypeName>.ts` |
15
+ | SCSS styles | `styles/` (`base/`, `components/`, `layout/`, `themes/`, `utils/`) |
16
+ | Color palette data | `data/colorPalettes.ts`, `data/mapColorPalettes.ts`, or `data/sharedPalettes.ts` |
17
+
18
+ ## Helpers Organization
19
+ - **Flat structure**: ~49 top-level files in `helpers/`.
20
+ - **Feature subdirectories** for complex domains:
21
+ - `cove/` — formatting utilities (accessibility, date, number, string)
22
+ - `embed/` — embed code generation, URL validation
23
+ - `metrics/` — analytics helpers
24
+ - `palettes/` — color palette migration and standardization
25
+ - `ver/` — version migration files (18+ migration scripts)
26
+ - `tests/` — shared test utilities (e.g., `testStandaloneBuild.ts`)
27
+ - Key constants in `helpers/constants.ts` — includes `USE_V2_MIGRATION`, `EDITOR_WIDTH`, `DATA_OPERATORS`, `DATA_FUNCTIONS`, color fallbacks.
28
+
29
+ ## Commonly Imported Exports
30
+ Other packages depend heavily on these — be careful when modifying:
31
+ - **Types**: `VizFilter`, `Column`, `Table`, `General`, `Version`, `Visualization`, `FilterBehavior`, `DataSet` (imported as `Datasets`), `Action`
32
+ - **Helpers**: `fetchRemoteData`, `filterVizData`, `DataTransform`, `getViewport`, `updateFieldFactory`, `coveUpdateWorker`, `cloneConfig`
33
+ - **Components**: `Loading`, `EditorPanel`, `Filters`, `DataTable`, `Layout`, `ErrorBoundary`, ui elements (`Modal`, `Accordion`, `Tooltip`)
34
+ - **Contexts**: `EditorContext` (+ `EditorDispatchContext`) — shared editor state used by `@cdc/editor`
35
+
36
+ ## Types Conventions
37
+ - 32 shared type files in `types/`.
38
+ - Other packages **extend** core types rather than duplicating (e.g., chart's `General` extends core's `General`).
39
+ - Use `import type` for type-only imports from core.
40
+ - Core's `Action<Type, Payload>` type is the base for all package action types.
41
+
42
+ ## Components (34 directories)
43
+ Largest/most complex:
44
+ - `DataTable/` (29 files) — shared data table with sorting, pagination, search
45
+ - `EditorPanel/` (16 files) — shared editor panel sections
46
+ - `Filters/` (13 files) — shared filter UI components
47
+ - `ui/` (15 files) — low-level UI primitives (Modal, Accordion, Tooltip, Icon)
48
+ - `elements/` — Button, Card, Confirm, Error, ScreenReaderText, SkipTo
49
+ - `inputs/` — InputCheckbox, InputGroup, InputSelect, InputText, InputToggle
50
+
51
+ ## Styles Architecture
52
+ - Entry point: `styles/cove-main.scss` (this is what the build compiles)
53
+ - Style system in `styles/` with: `base/`, `components/`, `layout/`, `themes/`, `utils/`
54
+ - Breakpoint mixin: `@import '@cdc/core/styles/utils/breakpoints'` — used by all packages
55
+ - Theme colors defined in `styles/themes/_color-definitions.scss`
56
+ - Use CSS custom properties (`var(--cool-gray-10)`) — never hardcode colors.
57
+
58
+ ## Shared Configuration Files
59
+ - `generateViteConfig.js` — all packages import this for build/dev/test config. Do not modify without understanding downstream impact on every package.
60
+ - `testing-setup.js` — provides Testing Library matchers, matchMedia mock, URL.createObjectURL mock, auto-cleanup. All packages use this via Vitest setup.
61
+ - `devTemplate/` — HTML/CSS/JS for package dev servers (example-switching sidebar).
62
+
63
+ ## Pitfalls
64
+ - Modifying any shared type (`types/*.ts`) can break multiple packages — check downstream imports first.
65
+ - `generateViteConfig.js` externals only include `react` and `react-dom`. If a new peer dependency is added, it must be added here too.
66
+ - The `data/` directory contains color palette definitions that affect every visualization — changes here are high-impact.
67
+ - `helpers/ver/` contains ordered version migration scripts. New migrations must maintain the correct sequence.
@@ -0,0 +1,300 @@
1
+ import type { Meta, StoryObj } from '@storybook/react-vite'
2
+ import { within, expect } from 'storybook/test'
3
+ import Chart from '@cdc/chart'
4
+
5
+ // Fallback step function for test descriptions
6
+ const step = async (description: string, fn: () => Promise<void> | void) => {
7
+ console.log(`▶ ${description}`)
8
+ await fn()
9
+ console.log(`✓ ${description}`)
10
+ }
11
+
12
+ const meta: Meta = {
13
+ title: 'Regression Tests/Gallery/Charts',
14
+ parameters: {
15
+ layout: 'fullscreen',
16
+ docs: {
17
+ description: {
18
+ component: 'Chart visualization examples from the CDC COVE Gallery'
19
+ }
20
+ }
21
+ },
22
+ tags: ['autodocs']
23
+ }
24
+
25
+ export default meta
26
+
27
+ type Story = StoryObj<typeof Chart>
28
+
29
+ // Helper function to test chart rendering
30
+ const testChartRendering = async (canvasElement: HTMLElement, storyName: string) => {
31
+ const canvas = within(canvasElement)
32
+
33
+ await step('Wait for chart to render', async () => {
34
+ const svgElement = await canvas.findByRole('img', { hidden: true }, { timeout: 10000 })
35
+ expect(svgElement).toBeInTheDocument()
36
+ })
37
+
38
+ await step('Verify chart SVG is present', async () => {
39
+ const chartSvg = canvasElement.querySelector('svg')
40
+ expect(chartSvg).toBeInTheDocument()
41
+ })
42
+
43
+ await step('Verify COVE module wrapper is present', async () => {
44
+ const coveModule = canvasElement.querySelector('.cdc-open-viz-module')
45
+ expect(coveModule).toBeInTheDocument()
46
+ })
47
+
48
+ console.log(` ${storyName} chart rendered successfully`)
49
+ }
50
+
51
+ // Bar Charts
52
+ export const Bar_Chart_Time_Based: Story = {
53
+ render: () => <Chart configUrl='https://www.cdc.gov/cove/examples/Example_Bar_Chart.json' />,
54
+ play: async ({ canvasElement }) => {
55
+ await testChartRendering(canvasElement, 'Bar Chart Time Based')
56
+ }
57
+ }
58
+
59
+ export const Bar_Chart_Categorical: Story = {
60
+ render: () => <Chart configUrl='https://www.cdc.gov/cove/examples/example-category-bar-char.json' />,
61
+ play: async ({ canvasElement }) => {
62
+ await testChartRendering(canvasElement, 'Bar Chart Categorical')
63
+ }
64
+ }
65
+
66
+ export const Bar_Chart_With_Highlighted_Value: Story = {
67
+ render: () => <Chart configUrl='https://www.cdc.gov/cove/examples/bar-chart-with-highlighte.json' />,
68
+ play: async ({ canvasElement }) => {
69
+ await testChartRendering(canvasElement, 'Bar Chart With Highlighted Value')
70
+ }
71
+ }
72
+
73
+ export const Bar_Chart_With_Confidence_Intervals: Story = {
74
+ render: () => <Chart configUrl='https://www.cdc.gov/cove/examples/Example_Bar_CI_1.json' />,
75
+ play: async ({ canvasElement }) => {
76
+ await testChartRendering(canvasElement, 'Bar Chart With Confidence Intervals')
77
+ }
78
+ }
79
+
80
+ export const Bar_Chart_With_Suppressed_Values: Story = {
81
+ render: () => <Chart configUrl='https://www.cdc.gov/cove/examples/bar-chart-with-suppressed-values.json' />,
82
+ play: async ({ canvasElement }) => {
83
+ await testChartRendering(canvasElement, 'Bar Chart With Suppressed Values')
84
+ }
85
+ }
86
+
87
+ export const Horizontal_Bar_Chart: Story = {
88
+ render: () => <Chart configUrl='https://www.cdc.gov/cove/examples/Horizontal_Bar_Chart_Viz.json' />,
89
+ play: async ({ canvasElement }) => {
90
+ await testChartRendering(canvasElement, 'Horizontal Bar Chart')
91
+ }
92
+ }
93
+
94
+ // Box and Whiskers Plots
95
+ export const Box_Plot_With_Outliers: Story = {
96
+ render: () => <Chart configUrl='https://www.cdc.gov/cove/examples/box-plot-outliers.json' />,
97
+ play: async ({ canvasElement }) => {
98
+ await testChartRendering(canvasElement, 'Box Plot With Outliers')
99
+ }
100
+ }
101
+
102
+ export const Horizontal_Box_Plot: Story = {
103
+ render: () => <Chart configUrl='https://www.cdc.gov/cove/examples/horizontal-box-plot.json' />,
104
+ play: async ({ canvasElement }) => {
105
+ await testChartRendering(canvasElement, 'Horizontal Box Plot')
106
+ }
107
+ }
108
+
109
+ // Bump Chart
110
+ export const Bump_Chart: Story = {
111
+ render: () => <Chart configUrl='https://www.cdc.gov/cove/examples/bump-chart.json' />,
112
+ play: async ({ canvasElement }) => {
113
+ await testChartRendering(canvasElement, 'Bump Chart')
114
+ }
115
+ }
116
+
117
+ // Combo Bar/Line Charts
118
+ export const Combo_Bar_And_Area: Story = {
119
+ render: () => <Chart configUrl='https://www.cdc.gov/cove/examples/Combo_Bar_Line_Viz.json' />,
120
+ play: async ({ canvasElement }) => {
121
+ await testChartRendering(canvasElement, 'Combo Bar And Area')
122
+ }
123
+ }
124
+
125
+ export const Epi_Style_Bar_Chart: Story = {
126
+ render: () => <Chart configUrl='https://www.cdc.gov/cove/examples/example-epi-style-bar-chart.json' />,
127
+ play: async ({ canvasElement }) => {
128
+ await testChartRendering(canvasElement, 'Epi Style Bar Chart')
129
+ }
130
+ }
131
+
132
+ // Deviation Bar Chart
133
+ export const Deviation_Bar_Chart: Story = {
134
+ render: () => <Chart configUrl='https://www.cdc.gov/cove/examples/example-deviation-bar-chart.json' />,
135
+ play: async ({ canvasElement }) => {
136
+ await testChartRendering(canvasElement, 'Deviation Bar Chart')
137
+ }
138
+ }
139
+
140
+ // Forecast Charts
141
+ export const Forecast_Chart_Single_CI: Story = {
142
+ render: () => <Chart configUrl='https://www.cdc.gov/cove/examples/forecast-chart-one-CI.json' />,
143
+ play: async ({ canvasElement }) => {
144
+ await testChartRendering(canvasElement, 'Forecast Chart Single CI')
145
+ }
146
+ }
147
+
148
+ export const Forecast_Chart_Multiple_CIs: Story = {
149
+ render: () => <Chart configUrl='https://www.cdc.gov/cove/examples/forecast-chart-2-CIs.json' />,
150
+ play: async ({ canvasElement }) => {
151
+ await testChartRendering(canvasElement, 'Forecast Chart Multiple CIs')
152
+ }
153
+ }
154
+
155
+ // Line Charts
156
+ export const Line_Chart_Standard: Story = {
157
+ render: () => <Chart configUrl='https://www.cdc.gov/cove/examples/Line_Chart_Viz.json' />,
158
+ play: async ({ canvasElement }) => {
159
+ await testChartRendering(canvasElement, 'Line Chart Standard')
160
+ }
161
+ }
162
+
163
+ export const Line_Chart_With_Regions: Story = {
164
+ render: () => <Chart configUrl='https://www.cdc.gov/cove/examples/Line_Chart_Regions_Viz.json' />,
165
+ play: async ({ canvasElement }) => {
166
+ await testChartRendering(canvasElement, 'Line Chart With Regions')
167
+ }
168
+ }
169
+
170
+ export const Line_Chart_Isolated: Story = {
171
+ render: () => <Chart configUrl='https://www.cdc.gov/cove/examples/Line_Chart_Isolated.json' />,
172
+ play: async ({ canvasElement }) => {
173
+ await testChartRendering(canvasElement, 'Line Chart Isolated')
174
+ }
175
+ }
176
+
177
+ export const Line_Chart_Line_Weights: Story = {
178
+ render: () => <Chart configUrl='https://www.cdc.gov/cove/examples/Line_Chart_Line_Weights.json' />,
179
+ play: async ({ canvasElement }) => {
180
+ await testChartRendering(canvasElement, 'Line Chart Line Weights')
181
+ }
182
+ }
183
+
184
+ export const Line_Chart_With_Open_Circles: Story = {
185
+ render: () => <Chart configUrl='https://www.cdc.gov/cove/examples/line-chart-with-open-circles.json' />,
186
+ play: async ({ canvasElement }) => {
187
+ await testChartRendering(canvasElement, 'Line Chart With Open Circles')
188
+ }
189
+ }
190
+
191
+ export const Line_Chart_With_Suppression: Story = {
192
+ render: () => <Chart configUrl='https://www.cdc.gov/cove/examples/line-chart-with-suppression.json' />,
193
+ play: async ({ canvasElement }) => {
194
+ await testChartRendering(canvasElement, 'Line Chart With Suppression')
195
+ }
196
+ }
197
+
198
+ // Lollipop Bar Chart
199
+ export const Lollipop_Horizontal_Bar_Chart: Story = {
200
+ render: () => <Chart configUrl='https://www.cdc.gov/cove/examples/lollipop-style-horizontal-bar-chart.json' />,
201
+ play: async ({ canvasElement }) => {
202
+ await testChartRendering(canvasElement, 'Lollipop Horizontal Bar Chart')
203
+ }
204
+ }
205
+
206
+ // Pie and Donut Charts
207
+ export const Pie_Chart: Story = {
208
+ render: () => <Chart configUrl='https://www.cdc.gov/cove/examples/Example_Pie_viz.json' />,
209
+ play: async ({ canvasElement }) => {
210
+ await testChartRendering(canvasElement, 'Pie Chart')
211
+ }
212
+ }
213
+
214
+ export const Donut_Chart: Story = {
215
+ render: () => <Chart configUrl='https://www.cdc.gov/cove/examples/Donut-Chart.json' />,
216
+ play: async ({ canvasElement }) => {
217
+ await testChartRendering(canvasElement, 'Donut Chart')
218
+ }
219
+ }
220
+
221
+ // Scatter Plots
222
+ export const Scatter_Plot_Negative_Trend: Story = {
223
+ render: () => <Chart configUrl='https://www.cdc.gov/cove/examples/scatter-plot-negative-trend.json' />,
224
+ play: async ({ canvasElement }) => {
225
+ await testChartRendering(canvasElement, 'Scatter Plot Negative Trend')
226
+ }
227
+ }
228
+
229
+ export const Scatter_Plot_Multi_Series: Story = {
230
+ render: () => <Chart configUrl='https://www.cdc.gov/cove/examples/scatter-plot-multi-series.json' />,
231
+ play: async ({ canvasElement }) => {
232
+ await testChartRendering(canvasElement, 'Scatter Plot Multi Series')
233
+ }
234
+ }
235
+
236
+ export const Scatter_Plot_Nonlinear_Trend: Story = {
237
+ render: () => <Chart configUrl='https://www.cdc.gov/cove/examples/scatter-plot-nonlinear-trend.json' />,
238
+ play: async ({ canvasElement }) => {
239
+ await testChartRendering(canvasElement, 'Scatter Plot Nonlinear Trend')
240
+ }
241
+ }
242
+
243
+ // Sparklines
244
+ export const Sparkline_2016_Outreach_Var2: Story = {
245
+ render: () => <Chart configUrl='https://www.cdc.gov/cove/examples/2016-outreach-2.json' />,
246
+ play: async ({ canvasElement }) => {
247
+ await testChartRendering(canvasElement, 'Sparkline 2016 Outreach Var2')
248
+ }
249
+ }
250
+
251
+ export const Sparkline_2016_Outreach_Var3: Story = {
252
+ render: () => <Chart configUrl='https://www.cdc.gov/cove/examples/2016-outreach-3.json' />,
253
+ play: async ({ canvasElement }) => {
254
+ await testChartRendering(canvasElement, 'Sparkline 2016 Outreach Var3')
255
+ }
256
+ }
257
+
258
+ export const Sparkline_2016_Outreach_Var4: Story = {
259
+ render: () => <Chart configUrl='https://www.cdc.gov/cove/examples/2016-outreach-4.json' />,
260
+ play: async ({ canvasElement }) => {
261
+ await testChartRendering(canvasElement, 'Sparkline 2016 Outreach Var4')
262
+ }
263
+ }
264
+
265
+ // Stacked Area Charts
266
+ export const Stacked_Area_Chart: Story = {
267
+ render: () => <Chart configUrl='https://www.cdc.gov/cove/examples/example-stacked-area-chart.json' />,
268
+ play: async ({ canvasElement }) => {
269
+ await testChartRendering(canvasElement, 'Stacked Area Chart')
270
+ }
271
+ }
272
+
273
+ export const Area_Chart_With_Annotations: Story = {
274
+ render: () => <Chart configUrl='https://www.cdc.gov/cove/examples/area-chart-with-annotations_1.json' />,
275
+ play: async ({ canvasElement }) => {
276
+ await testChartRendering(canvasElement, 'Area Chart With Annotations')
277
+ }
278
+ }
279
+
280
+ export const Area_Chart_With_Categorical_Axis: Story = {
281
+ render: () => <Chart configUrl='https://www.cdc.gov/cove/examples/example-area-chart-with-cat-axis.json' />,
282
+ play: async ({ canvasElement }) => {
283
+ await testChartRendering(canvasElement, 'Area Chart With Categorical Axis')
284
+ }
285
+ }
286
+
287
+ // Stacked Bar Charts
288
+ export const Stacked_Horizontal_Bar_Chart: Story = {
289
+ render: () => <Chart configUrl='https://www.cdc.gov/cove/examples/example-stacked-horizontal-chart.json' />,
290
+ play: async ({ canvasElement }) => {
291
+ await testChartRendering(canvasElement, 'Stacked Horizontal Bar Chart')
292
+ }
293
+ }
294
+
295
+ export const Stacked_Vertical_Bar_Chart: Story = {
296
+ render: () => <Chart configUrl='https://www.cdc.gov/cove/examples/Stacked_Bar_Viz.json' />,
297
+ play: async ({ canvasElement }) => {
298
+ await testChartRendering(canvasElement, 'Stacked Vertical Bar Chart')
299
+ }
300
+ }
@@ -0,0 +1,79 @@
1
+ import type { Meta, StoryObj } from '@storybook/react-vite'
2
+ import { within, expect, waitFor } from 'storybook/test'
3
+ import DataBite from '@cdc/data-bite'
4
+
5
+ // Fallback step function for test descriptions
6
+ const step = async (description: string, fn: () => Promise<void> | void) => {
7
+ console.log(`▶ ${description}`)
8
+ await fn()
9
+ console.log(`✓ ${description}`)
10
+ }
11
+
12
+ const meta: Meta = {
13
+ title: 'Regression Tests/Gallery/Data Bites',
14
+ parameters: {
15
+ layout: 'fullscreen',
16
+ docs: {
17
+ description: {
18
+ component: 'Data Bite visualization examples from the CDC COVE Gallery'
19
+ }
20
+ }
21
+ },
22
+ tags: ['autodocs']
23
+ }
24
+
25
+ export default meta
26
+
27
+ type Story = StoryObj<typeof DataBite>
28
+
29
+ // Helper function to test data bite rendering
30
+ const testDataBiteRendering = async (canvasElement: HTMLElement, storyName: string) => {
31
+ const canvas = within(canvasElement)
32
+
33
+ await step('Wait for data bite to render', async () => {
34
+ await waitFor(() => expect(canvasElement.querySelector('.bite-content')).toBeInTheDocument(), { timeout: 10000 })
35
+ })
36
+
37
+ await step('Verify COVE module wrapper is present', async () => {
38
+ const coveModule = canvasElement.querySelector('.cdc-open-viz-module')
39
+ expect(coveModule).toBeInTheDocument()
40
+ })
41
+
42
+ console.log(` ${storyName} data bite rendered successfully`)
43
+ }
44
+
45
+ export const Data_Bite_Circle_Average: Story = {
46
+ render: () => (
47
+ <DataBite configUrl='https://www.cdc.gov/wcms/4.0/cdc-wp/data-presentation/examples/Data_Bite_Circle_Average.json' />
48
+ ),
49
+ play: async ({ canvasElement }) => {
50
+ await testDataBiteRendering(canvasElement, 'Data Bite Circle Average')
51
+ }
52
+ }
53
+
54
+ export const Data_Bite_Text_Max_Pic: Story = {
55
+ render: () => (
56
+ <DataBite configUrl='https://www.cdc.gov/wcms/4.0/cdc-wp/data-presentation/examples/Data_Bite_Text_Max_Pic.json' />
57
+ ),
58
+ play: async ({ canvasElement }) => {
59
+ await testDataBiteRendering(canvasElement, 'Data Bite Text Max Pic')
60
+ }
61
+ }
62
+
63
+ export const Data_Bite_Circle_Sum: Story = {
64
+ render: () => (
65
+ <DataBite configUrl='https://www.cdc.gov/wcms/4.0/cdc-wp/data-presentation/examples/Data_Bite_Circle_Sum.json' />
66
+ ),
67
+ play: async ({ canvasElement }) => {
68
+ await testDataBiteRendering(canvasElement, 'Data Bite Circle Sum')
69
+ }
70
+ }
71
+
72
+ export const Data_Bite_Text_Average_Pic: Story = {
73
+ render: () => (
74
+ <DataBite configUrl='https://www.cdc.gov/wcms/4.0/cdc-wp/data-presentation/examples/Data_Bite_Text_Average_Pic.json' />
75
+ ),
76
+ play: async ({ canvasElement }) => {
77
+ await testDataBiteRendering(canvasElement, 'Data Bite Text Average Pic')
78
+ }
79
+ }