@cdc/markup-include 4.26.4 → 4.26.5

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/package.json CHANGED
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "@cdc/markup-include",
3
- "version": "4.26.4",
3
+ "version": "4.26.5",
4
4
  "description": "React component for displaying HTML content from an outside link",
5
5
  "license": "Apache-2.0",
6
6
  "author": "Rob Shelnutt <rob@blackairplane.com>",
7
7
  "bugs": "https://github.com/CDCgov/cdc-open-viz/issues",
8
8
  "dependencies": {
9
- "@cdc/core": "^4.26.4",
9
+ "@cdc/core": "^4.26.5",
10
10
  "axios": "^1.13.2",
11
11
  "dompurify": "^3.4.0",
12
12
  "lodash": "^4.17.23",
@@ -19,7 +19,7 @@
19
19
  "vite-plugin-css-injected-by-js": "^2.4.0",
20
20
  "vite-plugin-svgr": "^4.2.0"
21
21
  },
22
- "gitHead": "6097de1ff814001880d9ac64bd66becdc092d63c",
22
+ "gitHead": "61c025165d96b45a6002c34582c5a622a9d865a9",
23
23
  "homepage": "https://github.com/CDCgov/cdc-open-viz#readme",
24
24
  "main": "dist/cdcmarkupinclude",
25
25
  "moduleName": "CdcMarkupInclude",
@@ -1,7 +1,6 @@
1
1
  import { useEffect, useCallback, useRef, useReducer, useMemo } from 'react'
2
2
  // external
3
3
  import DOMPurify from 'dompurify'
4
- import axios from 'axios'
5
4
  import parse from 'html-react-parser'
6
5
 
7
6
  // cdc
@@ -9,6 +8,7 @@ import { MarkupIncludeConfig } from '@cdc/core/types/MarkupInclude'
9
8
  import { publish } from '@cdc/core/helpers/events'
10
9
  import { processMarkupVariables } from '@cdc/core/helpers/markupProcessor'
11
10
  import { addValuesToFilters } from '@cdc/core/helpers/addValuesToFilters'
11
+ import { hasVisibleVizFilters } from '@cdc/core/helpers/filterVisibility'
12
12
  import { resolveDataColor } from '@cdc/core/helpers/dataColors'
13
13
  import ConfigContext from './ConfigContext'
14
14
  import coveUpdateWorker from '@cdc/core/helpers/coveUpdateWorker'
@@ -201,20 +201,18 @@ const CdcMarkupInclude: React.FC<CdcMarkupIncludeProps> = ({
201
201
  dispatch({ type: 'SET_URL_MARKUP', payload })
202
202
  } else {
203
203
  try {
204
- await axios.get(srcUrl).then(res => {
205
- if (res.data) {
206
- dispatch({ type: 'SET_URL_MARKUP', payload: res.data })
204
+ const res = await fetch(srcUrl)
205
+ if (!res.ok) {
206
+ dispatch({ type: 'SET_MARKUP_ERROR', payload: res.status })
207
+ dispatch({ type: 'SET_URL_MARKUP', payload: '' })
208
+ } else {
209
+ const data = await res.text()
210
+ if (data) {
211
+ dispatch({ type: 'SET_URL_MARKUP', payload: data })
207
212
  }
208
- })
209
- } catch (err) {
210
- if (err.response) {
211
- // Response with error
212
- dispatch({ type: 'SET_MARKUP_ERROR', payload: err.response.status })
213
- } else if (err.request) {
214
- // No response received
215
- dispatch({ type: 'SET_MARKUP_ERROR', payload: 200 })
216
213
  }
217
-
214
+ } catch {
215
+ dispatch({ type: 'SET_MARKUP_ERROR', payload: 200 })
218
216
  dispatch({ type: 'SET_URL_MARKUP', payload: '' })
219
217
  }
220
218
  }
@@ -346,7 +344,7 @@ const CdcMarkupInclude: React.FC<CdcMarkupIncludeProps> = ({
346
344
  shouldApplyTopPadding ? ' has-top-padding' : ''
347
345
  }${shouldApplySidePadding ? ' has-side-padding' : ''}`.trim()}
348
346
  filters={
349
- config.filters && config.filters.length > 0 ? (
347
+ hasVisibleVizFilters(config.filters) ? (
350
348
  <Filters
351
349
  config={config}
352
350
  setFilters={setFilters}
@@ -354,7 +352,7 @@ const CdcMarkupInclude: React.FC<CdcMarkupIncludeProps> = ({
354
352
  dimensions={[0, 0]}
355
353
  interactionLabel={interactionLabel || 'markup-include'}
356
354
  />
357
- ) : null
355
+ ) : undefined
358
356
  }
359
357
  header={
360
358
  !isTp5Style ? (
@@ -136,4 +136,44 @@ export const TP5_Test: Story = {
136
136
  }
137
137
  }
138
138
 
139
+ export const Bootstrap_Grid_Mockup: Story = {
140
+ args: {
141
+ config: {
142
+ ...primary,
143
+ contentEditor: {
144
+ ...primary.contentEditor,
145
+ showHeader: true,
146
+ title: 'Bootstrap grid include mock',
147
+ useInlineHTML: true,
148
+ inlineHTML: `
149
+ <div class="row">
150
+ <div class="col-8">
151
+ <p><strong>col-8</strong> block inside markup include content.</p>
152
+ </div>
153
+ <div class="col-3">
154
+ <p><strong>col-3</strong> block inside markup include content.</p>
155
+ </div>
156
+ </div>
157
+ `
158
+ }
159
+ } as any,
160
+ isEditor: false
161
+ },
162
+ play: async ({ canvasElement }) => {
163
+ await assertVisualizationRendered(canvasElement)
164
+
165
+ const shell = canvasElement.querySelector('.cove-visualization.type-markup-include')
166
+ const contentSection = canvasElement.querySelector('.cove-visualization__content-section')
167
+ const primaryColumn = canvasElement.querySelector('.col-8')
168
+ const secondaryColumn = canvasElement.querySelector('.col-3')
169
+
170
+ expect(shell).toBeTruthy()
171
+ expect(contentSection).toBeTruthy()
172
+ expect(primaryColumn).toBeTruthy()
173
+ expect(secondaryColumn).toBeTruthy()
174
+ expect(primaryColumn?.closest('.cove-visualization__content-section')).toBe(contentSection)
175
+ expect(secondaryColumn?.closest('.cove-visualization__content-section')).toBe(contentSection)
176
+ }
177
+ }
178
+
139
179
  export default meta
@@ -1,4 +1,4 @@
1
- .cove-visualization.markup-include {
1
+ .cove-visualization.type-markup-include {
2
2
  .spacing-wrapper {
3
3
  background-color: var(--lightGray) !important;
4
4
  }
@@ -7,14 +7,17 @@
7
7
  display: none;
8
8
  }
9
9
 
10
- c .markup-include-content-container.cove-visualization__inner {
11
- .markup-include-component.cove-visualization__body:not(.component--hide-background-color, .component--has-background) {
10
+ .markup-include-content-container.cove-visualization__inner {
11
+ .markup-include-component.cove-visualization__body:not(
12
+ .component--hide-background-color,
13
+ .component--has-background
14
+ ) {
12
15
  background-color: white;
13
16
  }
14
17
  }
15
18
  }
16
19
 
17
- .cove-visualization.markup-include.is-editor {
20
+ .cove-visualization.type-markup-include.is-editor {
18
21
  .cove-tooltip-variable {
19
22
  background: var(--orange-tertiary);
20
23
  display: inline;
@@ -32,7 +35,7 @@
32
35
  z-index: 9999;
33
36
  }
34
37
 
35
- &:hover>.cove-tooltip-value {
38
+ &:hover > .cove-tooltip-value {
36
39
  display: block;
37
40
  }
38
41
  }
@@ -40,4 +43,4 @@
40
43
  .cove-markup-include-variable-value {
41
44
  display: none !important;
42
45
  }
43
- }
46
+ }
@@ -16,6 +16,7 @@ import Tooltip from '@cdc/core/components/ui/Tooltip'
16
16
  import MarkupVariablesEditor from '@cdc/core/components/EditorPanel/components/MarkupVariablesEditor'
17
17
  import FootnotesEditor from '@cdc/core/components/EditorPanel/FootnotesEditor'
18
18
  import StyleTreatmentSection from '@cdc/core/components/EditorPanel/sections/StyleTreatmentSection'
19
+ import { Tp5VisualSection } from '@cdc/core/components/EditorPanel/sections/Tp5VisualSection'
19
20
  import { HeaderThemeSelector } from '@cdc/core/components/HeaderThemeSelector'
20
21
  import { DataColorSelector } from '@cdc/core/components/DataColorSelector'
21
22
  import { DATA_COLOR_PRESETS } from '@cdc/core/helpers/dataColors'
@@ -289,13 +290,7 @@ const EditorPanel: React.FC<MarkupIncludeEditorPanelProps> = ({ datasets }) => {
289
290
  />
290
291
  )}
291
292
  {isTp5Style ? (
292
- <CheckBox
293
- value={visual?.whiteBackground}
294
- section='visual'
295
- fieldName='whiteBackground'
296
- label='Use White Background Style'
297
- updateField={updateField}
298
- />
293
+ <Tp5VisualSection config={config} updateField={updateField} />
299
294
  ) : (
300
295
  <StyleTreatmentSection
301
296
  styleTreatment={styleTreatment}
@@ -395,7 +390,8 @@ const EditorPanel: React.FC<MarkupIncludeEditorPanelProps> = ({ datasets }) => {
395
390
  <Accordion.Section title='Markup Variables'>
396
391
  <MarkupVariablesEditor
397
392
  markupVariables={config.markupVariables || []}
398
- data={markupEditorData}
393
+ data={Array.isArray(data) ? data : []}
394
+ editorData={markupEditorData}
399
395
  datasets={datasets}
400
396
  config={config}
401
397
  onChange={handleMarkupVariablesChange}
package/src/index.tsx CHANGED
@@ -9,14 +9,17 @@ import CdcMarkupInclude from './CdcMarkupInclude'
9
9
 
10
10
  let isEditor = window.location.href.includes('editor=true')
11
11
 
12
- let domContainer = document.getElementsByClassName('react-container')[0]
12
+ let domContainer = document.getElementsByClassName('react-container')[0] as HTMLElement & { coveConfig?: any }
13
+ let configUrl = domContainer.dataset.configUrl
14
+ let injectedConfig = domContainer.coveConfig
13
15
 
14
16
  ReactDOM.createRoot(domContainer).render(
15
17
  <React.StrictMode>
16
18
  <GlobalContextProvider>
17
19
  <CdcMarkupInclude
18
- configUrl={domContainer.attributes['data-config'].value}
19
- interactionLabel={domContainer.attributes['data-config'].value}
20
+ config={injectedConfig}
21
+ configUrl={injectedConfig ? undefined : configUrl}
22
+ interactionLabel={configUrl}
20
23
  isEditor={isEditor}
21
24
  />
22
25
  </GlobalContextProvider>
@@ -1,4 +1,5 @@
1
1
  @import '@cdc/core/styles/layout/wrapper-padding';
2
+ @import '@cdc/core/styles/layout/callout';
2
3
 
3
4
  .cove-visualization.type-markup-include {
4
5
  .cove-visualization__body {
@@ -13,12 +14,6 @@
13
14
 
14
15
  .markup-include-tp5 {
15
16
  gap: 0.7rem;
16
- box-shadow: 0 2px 4px rgb(159 159 159 / 10%);
17
- border: 1px solid var(--colors-cyan-15, #dff2f6) !important;
18
- margin: 0 !important;
19
- padding: 1.25rem;
20
- border-radius: 0.25rem;
21
- background-color: var(--colors-cyan-10, #eff9fa);
22
17
  }
23
18
 
24
19
  .cdc-callout__heading {
@@ -2,13 +2,18 @@ import path from 'node:path'
2
2
  import fs from 'node:fs'
3
3
  import vm from 'node:vm'
4
4
  import React from 'react'
5
- import { render, screen } from '@testing-library/react'
5
+ import { render, screen, waitFor } from '@testing-library/react'
6
6
  import { testStandaloneBuild } from '@cdc/core/helpers/tests/testStandaloneBuild.ts'
7
7
  import { describe, it, expect, vi } from 'vitest'
8
8
  import CdcMarkupInclude from '../CdcMarkupInclude'
9
9
 
10
10
  vi.mock('@cdc/core/components/EditorPanel/components/MarkupVariablesEditor', () => ({
11
- default: ({ data }) => <div data-testid='markup-variables-editor-data'>{JSON.stringify(data)}</div>
11
+ default: ({ data, editorData }) => (
12
+ <div>
13
+ <div data-testid='markup-variables-editor-data'>{JSON.stringify(data)}</div>
14
+ <div data-testid='markup-variables-editor-editor-data'>{JSON.stringify(editorData)}</div>
15
+ </div>
16
+ )
12
17
  }))
13
18
 
14
19
  const extractMarkedExampleConfig = (content, label) => {
@@ -28,7 +33,7 @@ describe('Markup Include', () => {
28
33
  expect(result).toBe(true)
29
34
  }, 300000)
30
35
 
31
- it('uses dashboard rawData for markup variable editor choices when editing', async () => {
36
+ it('uses dashboard rawData for markup variable editor choices while preserving render data when editing', async () => {
32
37
  const filteredData = [{ category: 'Filtered only' }]
33
38
  const fullData = [{ category: 'Value A' }, { category: 'Value B' }]
34
39
 
@@ -65,7 +70,102 @@ describe('Markup Include', () => {
65
70
  />
66
71
  )
67
72
 
68
- expect(JSON.parse((await screen.findByTestId('markup-variables-editor-data')).textContent)).toEqual(fullData)
73
+ expect(JSON.parse((await screen.findByTestId('markup-variables-editor-data')).textContent)).toEqual(filteredData)
74
+ expect(JSON.parse((await screen.findByTestId('markup-variables-editor-editor-data')).textContent)).toEqual(fullData)
75
+ })
76
+
77
+ it('does not render the visualization filters section when every markup include filter is hidden', async () => {
78
+ const { container } = render(
79
+ <CdcMarkupInclude
80
+ config={{
81
+ type: 'markup-include',
82
+ theme: 'theme-blue',
83
+ data: [{ state: 'Alabama' }],
84
+ filters: [
85
+ {
86
+ columnName: 'state',
87
+ values: ['Alabama'],
88
+ showDropdown: false,
89
+ id: 1,
90
+ parents: [],
91
+ active: 'Alabama',
92
+ filterStyle: 'dropdown',
93
+ label: 'State',
94
+ order: 'asc',
95
+ type: 'url'
96
+ }
97
+ ],
98
+ markupVariables: [],
99
+ contentEditor: {
100
+ title: '',
101
+ inlineHTML: '<p>Example</p>',
102
+ useInlineHTML: true,
103
+ srcUrl: ''
104
+ },
105
+ visual: {
106
+ border: false,
107
+ accent: false,
108
+ background: false,
109
+ hideBackgroundColor: false,
110
+ borderColorTheme: false
111
+ }
112
+ }}
113
+ datasets={{}}
114
+ isDashboard={true}
115
+ />
116
+ )
117
+
118
+ await waitFor(() => expect(container.querySelector('.markup-include-content-container')).toBeInTheDocument())
119
+
120
+ expect(container.querySelector('.cove-visualization__filters-section')).not.toBeInTheDocument()
121
+ })
122
+
123
+ it('keeps included bootstrap column markup inside the shared content section', async () => {
124
+ const { container } = render(
125
+ <CdcMarkupInclude
126
+ config={{
127
+ type: 'markup-include',
128
+ theme: 'theme-blue',
129
+ markupVariables: [],
130
+ contentEditor: {
131
+ title: 'Grid mock',
132
+ inlineHTML: `
133
+ <div class="row">
134
+ <div class="col-8"><p>Primary content</p></div>
135
+ <div class="col-3"><p>Secondary content</p></div>
136
+ </div>
137
+ `,
138
+ useInlineHTML: true,
139
+ srcUrl: ''
140
+ },
141
+ visual: {
142
+ border: false,
143
+ accent: false,
144
+ background: false,
145
+ hideBackgroundColor: false,
146
+ borderColorTheme: false
147
+ }
148
+ }}
149
+ datasets={{}}
150
+ isDashboard={true}
151
+ />
152
+ )
153
+
154
+ await waitFor(() => expect(container.querySelector('.markup-include-content-container')).toBeInTheDocument())
155
+
156
+ const shell = container.querySelector('.cove-visualization.type-markup-include')
157
+ const contentSection = container.querySelector('.cove-visualization__content-section')
158
+ const primaryColumn = container.querySelector('.col-8')
159
+ const secondaryColumn = container.querySelector('.col-3')
160
+
161
+ expect(shell).toBeInTheDocument()
162
+ expect(contentSection).toBeInTheDocument()
163
+ expect(primaryColumn).toBeInTheDocument()
164
+ expect(secondaryColumn).toBeInTheDocument()
165
+ expect(primaryColumn?.closest('.cove-visualization__content-section')).toBe(contentSection)
166
+ expect(secondaryColumn?.closest('.cove-visualization__content-section')).toBe(contentSection)
167
+ expect(primaryColumn?.parentElement).not.toBe(shell)
168
+ expect(secondaryColumn?.parentElement).not.toBe(shell)
69
169
  })
70
170
 
71
171
  it('keeps the minimal example in sync with the README docs', () => {