@cdc/markup-include 4.26.3 → 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.
@@ -0,0 +1,11 @@
1
+ {
2
+ "type": "markup-include",
3
+ "version": "4.26.4",
4
+ "theme": "theme-blue",
5
+ "contentEditor": {
6
+ "inlineHTML": "<p>Markup include minimum example.</p>",
7
+ "srcUrl": "",
8
+ "title": "Markup Include",
9
+ "useInlineHTML": true
10
+ }
11
+ }
package/package.json CHANGED
@@ -1,14 +1,14 @@
1
1
  {
2
2
  "name": "@cdc/markup-include",
3
- "version": "4.26.3",
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.3",
9
+ "@cdc/core": "^4.26.5",
10
10
  "axios": "^1.13.2",
11
- "dompurify": "^3.3.1",
11
+ "dompurify": "^3.4.0",
12
12
  "lodash": "^4.17.23",
13
13
  "react-accessible-accordion": "^5.0.1"
14
14
  },
@@ -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": "d50e45a074fbefa56cac904917e707d57f237737",
22
+ "gitHead": "61c025165d96b45a6002c34582c5a622a9d865a9",
23
23
  "homepage": "https://github.com/CDCgov/cdc-open-viz#readme",
24
24
  "main": "dist/cdcmarkupinclude",
25
25
  "moduleName": "CdcMarkupInclude",
@@ -1,13 +1,15 @@
1
1
  import { useEffect, useCallback, useRef, useReducer, useMemo } from 'react'
2
2
  // external
3
3
  import DOMPurify from 'dompurify'
4
- import axios from 'axios'
4
+ import parse from 'html-react-parser'
5
5
 
6
6
  // cdc
7
7
  import { MarkupIncludeConfig } from '@cdc/core/types/MarkupInclude'
8
8
  import { publish } from '@cdc/core/helpers/events'
9
9
  import { processMarkupVariables } from '@cdc/core/helpers/markupProcessor'
10
10
  import { addValuesToFilters } from '@cdc/core/helpers/addValuesToFilters'
11
+ import { hasVisibleVizFilters } from '@cdc/core/helpers/filterVisibility'
12
+ import { resolveDataColor } from '@cdc/core/helpers/dataColors'
11
13
  import ConfigContext from './ConfigContext'
12
14
  import coveUpdateWorker from '@cdc/core/helpers/coveUpdateWorker'
13
15
  import fetchRemoteData from '@cdc/core/helpers/fetchRemoteData'
@@ -30,6 +32,7 @@ type CdcMarkupIncludeProps = {
30
32
  datasets: Datasets
31
33
  isDashboard: boolean
32
34
  isEditor: boolean
35
+ rawData?: any[]
33
36
  setConfig: any
34
37
  interactionLabel?: string
35
38
  }
@@ -45,6 +48,7 @@ const CdcMarkupInclude: React.FC<CdcMarkupIncludeProps> = ({
45
48
  datasets,
46
49
  isDashboard = true,
47
50
  isEditor = false,
51
+ rawData,
48
52
  setConfig: setParentConfig,
49
53
  interactionLabel = 'no link provided'
50
54
  }) => {
@@ -64,7 +68,7 @@ const CdcMarkupInclude: React.FC<CdcMarkupIncludeProps> = ({
64
68
  // Custom States
65
69
  const container = useRef()
66
70
 
67
- const { innerContainerClasses, contentClasses } = useDataVizClasses(config || {})
71
+ const { innerContainerClasses, contentClasses: rawContentClasses } = useDataVizClasses(config || {})
68
72
  const { contentEditor, theme, visual } = config || {}
69
73
  const {
70
74
  showNoDataMessage,
@@ -76,9 +80,45 @@ const CdcMarkupInclude: React.FC<CdcMarkupIncludeProps> = ({
76
80
 
77
81
  // Support markupVariables at root level or inside contentEditor
78
82
  const markupVariables = config?.markupVariables || contentEditorMarkupVariables || []
83
+ const editorData = useMemo(() => {
84
+ if (isDashboard && isEditor && Array.isArray(rawData) && rawData.length) {
85
+ return rawData
86
+ }
87
+
88
+ const assignedDatasetData = config?.dataKey ? datasets?.[config.dataKey]?.data : undefined
89
+ if (Array.isArray(assignedDatasetData) && assignedDatasetData.length) {
90
+ return assignedDatasetData
91
+ }
79
92
 
80
- const { inlineHTML, srcUrl, title, useInlineHTML } = contentEditor || {}
93
+ return data || []
94
+ }, [config?.dataKey, data, datasets, isDashboard, isEditor, rawData])
81
95
 
96
+ const { inlineHTML, srcUrl, title, useInlineHTML, style: contentStyle } = contentEditor || {}
97
+ const markupIncludeStyle = contentStyle || 'default'
98
+ const isTp5Style = markupIncludeStyle === 'tp5'
99
+
100
+ const dataColorResolution = useMemo(() => {
101
+ const dataArr = Array.isArray(data) ? data : []
102
+ return resolveDataColor({
103
+ data: dataArr,
104
+ dataColors: config?.dataColors
105
+ })
106
+ }, [data, config?.dataColors])
107
+
108
+ const contentClasses = isTp5Style
109
+ ? rawContentClasses.filter(
110
+ cls =>
111
+ cls !== 'component--has-accent' &&
112
+ cls !== 'component--has-background' &&
113
+ cls !== 'component--hide-background-color' &&
114
+ cls !== 'component--has-border-color-theme'
115
+ )
116
+ : rawContentClasses
117
+
118
+ const shouldApplyTopPadding =
119
+ !isTp5Style &&
120
+ (visual?.border || visual?.background || (contentEditor?.title && contentEditor?.titleStyle === 'legacy'))
121
+ const shouldApplySidePadding = !isTp5Style && (visual?.border || visual?.accent || visual?.background)
82
122
  // Default Functions
83
123
  const updateConfig = newConfig => {
84
124
  Object.keys(defaults).forEach(key => {
@@ -161,20 +201,18 @@ const CdcMarkupInclude: React.FC<CdcMarkupIncludeProps> = ({
161
201
  dispatch({ type: 'SET_URL_MARKUP', payload })
162
202
  } else {
163
203
  try {
164
- await axios.get(srcUrl).then(res => {
165
- if (res.data) {
166
- 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 })
167
212
  }
168
- })
169
- } catch (err) {
170
- if (err.response) {
171
- // Response with error
172
- dispatch({ type: 'SET_MARKUP_ERROR', payload: err.response.status })
173
- } else if (err.request) {
174
- // No response received
175
- dispatch({ type: 'SET_MARKUP_ERROR', payload: 200 })
176
213
  }
177
-
214
+ } catch {
215
+ dispatch({ type: 'SET_MARKUP_ERROR', payload: 200 })
178
216
  dispatch({ type: 'SET_URL_MARKUP', payload: '' })
179
217
  }
180
218
  }
@@ -265,13 +303,48 @@ const CdcMarkupInclude: React.FC<CdcMarkupIncludeProps> = ({
265
303
  const hideMarkupInclude = processedMarkup.shouldHideSection
266
304
  const _showNoDataMessage = processedMarkup.shouldShowNoDataMessage
267
305
 
306
+ const processedTitle = useMemo(() => {
307
+ if (!config?.enableMarkupVariables || !markupVariables?.length || !title) return title
308
+ return processMarkupVariables(title, data || [], markupVariables, {
309
+ isEditor,
310
+ showNoDataMessage,
311
+ allowHideSection,
312
+ filters: config?.filters || [],
313
+ datasets,
314
+ configDataKey: config?.dataKey,
315
+ locale: config?.locale,
316
+ dataMetadata: config?.dataMetadata
317
+ }).processedContent
318
+ }, [
319
+ title,
320
+ data,
321
+ markupVariables,
322
+ config?.enableMarkupVariables,
323
+ config?.filters,
324
+ config?.dataKey,
325
+ config?.locale,
326
+ config?.dataMetadata,
327
+ isEditor,
328
+ showNoDataMessage,
329
+ allowHideSection,
330
+ datasets
331
+ ])
332
+
268
333
  if (loading === false) {
334
+ const hasTp5Title = processedTitle && processedTitle.trim()
269
335
  content = !hideMarkupInclude && (
270
336
  <VisualizationContent
271
337
  innerClassName={`markup-include-content-container ${innerContainerClasses.join(' ')}`.trim()}
272
- bodyClassName={`markup-include-component ${contentClasses.join(' ')}`.trim()}
273
- message={
274
- config.filters && config.filters.length > 0 ? (
338
+ bodyClassName={`markup-include-component ${contentClasses.join(' ')}${
339
+ isTp5Style ? ' markup-include-component--tp5' : ''
340
+ }${isTp5Style && visual?.whiteBackground ? ' white-background-style' : ''}${
341
+ isTp5Style && visual?.whiteBackground && visual?.border ? ' display-border' : ''
342
+ }`.trim()}
343
+ bodyWrapClassName={`${isTp5Style ? 'markup-include-body-wrap--tp5' : ''}${
344
+ shouldApplyTopPadding ? ' has-top-padding' : ''
345
+ }${shouldApplySidePadding ? ' has-side-padding' : ''}`.trim()}
346
+ filters={
347
+ hasVisibleVizFilters(config.filters) ? (
275
348
  <Filters
276
349
  config={config}
277
350
  setFilters={setFilters}
@@ -279,41 +352,81 @@ const CdcMarkupInclude: React.FC<CdcMarkupIncludeProps> = ({
279
352
  dimensions={[0, 0]}
280
353
  interactionLabel={interactionLabel || 'markup-include'}
281
354
  />
282
- ) : null
355
+ ) : undefined
283
356
  }
284
357
  header={
285
- <Title
286
- title={title}
287
- isDashboard={isDashboard}
288
- titleStyle={contentEditor?.titleStyle}
289
- config={config}
290
- classes={[`${theme}`, 'mb-0']}
291
- noContent={!sanitizedHTML}
292
- />
358
+ !isTp5Style ? (
359
+ <Title
360
+ title={processedTitle}
361
+ isDashboard={isDashboard}
362
+ titleStyle={contentEditor?.titleStyle}
363
+ config={config}
364
+ classes={[`${theme}`, 'mb-0']}
365
+ noContent={!sanitizedHTML}
366
+ />
367
+ ) : null
293
368
  }
294
369
  footer={
295
370
  <FootnotesStandAlone
296
- config={configObj?.footnotes}
371
+ config={config?.footnotes}
297
372
  filters={config?.filters || []}
298
373
  markupVariables={markupVariables}
299
374
  enableMarkupVariables={config?.enableMarkupVariables}
300
375
  data={data}
301
376
  dataMetadata={config?.dataMetadata}
377
+ footerClassName={isTp5Style ? 'mt-3' : undefined}
302
378
  />
303
379
  }
304
380
  >
305
- {_showNoDataMessage && (
306
- <div className='no-data-message'>
307
- <p>{`${noDataMessageText}`}</p>
308
- </div>
309
- )}
310
- {!markupError && !_showNoDataMessage && (
311
- <div id={scopeId}>
312
- {scopedCSS && <style>{scopedCSS}</style>}
313
- <div dangerouslySetInnerHTML={{ __html: sanitizedHTML }} />
381
+ {isTp5Style ? (
382
+ <div
383
+ className={`markup-include-tp5 cdc-callout d-flex flex-column h-100 ${
384
+ dataColorResolution.state === 'resolved' ? 'cdc-callout--data-color' : ''
385
+ }`}
386
+ style={
387
+ dataColorResolution.state === 'resolved'
388
+ ? { backgroundColor: dataColorResolution.color, color: dataColorResolution.textColor }
389
+ : undefined
390
+ }
391
+ >
392
+ {hasTp5Title && (
393
+ <h3 className='cdc-callout__heading cove-prose fw-bold flex-shrink-0 d-flex align-items-start'>
394
+ <span>{parse(processedTitle.trim())}</span>
395
+ </h3>
396
+ )}
397
+ <div className='cdc-callout__body d-flex flex-row align-content-start flex-grow-1'>
398
+ <div className='cdc-callout__content flex-grow-1 d-flex flex-column min-w-0'>
399
+ {_showNoDataMessage && (
400
+ <div className='no-data-message'>
401
+ <p>{`${noDataMessageText}`}</p>
402
+ </div>
403
+ )}
404
+ {!markupError && !_showNoDataMessage && (
405
+ <div id={scopeId}>
406
+ {scopedCSS && <style>{scopedCSS}</style>}
407
+ <div className='cove-prose' dangerouslySetInnerHTML={{ __html: sanitizedHTML }} />
408
+ </div>
409
+ )}
410
+ {markupError && srcUrl && !_showNoDataMessage && <div className='warning'>{errorMessage}</div>}
411
+ </div>
412
+ </div>
314
413
  </div>
414
+ ) : (
415
+ <>
416
+ {_showNoDataMessage && (
417
+ <div className='no-data-message'>
418
+ <p>{`${noDataMessageText}`}</p>
419
+ </div>
420
+ )}
421
+ {!markupError && !_showNoDataMessage && (
422
+ <div id={scopeId}>
423
+ {scopedCSS && <style>{scopedCSS}</style>}
424
+ <div className='cove-prose' dangerouslySetInnerHTML={{ __html: sanitizedHTML }} />
425
+ </div>
426
+ )}
427
+ {markupError && srcUrl && !_showNoDataMessage && <div className='warning'>{errorMessage}</div>}
428
+ </>
315
429
  )}
316
- {markupError && srcUrl && !_showNoDataMessage && <div className='warning'>{errorMessage}</div>}
317
430
  </VisualizationContent>
318
431
  )
319
432
  }
@@ -331,9 +444,15 @@ const CdcMarkupInclude: React.FC<CdcMarkupIncludeProps> = ({
331
444
 
332
445
  return (
333
446
  <ErrorBoundary component='CdcMarkupInclude'>
334
- <ConfigContext.Provider value={{ config, updateConfig, loading, data: data, setParentConfig, isDashboard }}>
447
+ <ConfigContext.Provider
448
+ value={{ config, updateConfig, loading, data: data, editorData, setParentConfig, isDashboard }}
449
+ >
335
450
  {!config?.newViz && config?.runtime && config?.runtime.editorErrorMessage && <Error />}
336
- <VisualizationContainer config={config} isEditor={isEditor} editorPanel={<EditorPanel datasets={datasets} />}>
451
+ <VisualizationContainer
452
+ config={config as any}
453
+ isEditor={isEditor}
454
+ editorPanel={<EditorPanel datasets={datasets} />}
455
+ >
337
456
  {content}
338
457
  </VisualizationContainer>
339
458
  </ConfigContext.Provider>
@@ -4,6 +4,7 @@ import { MarkupIncludeConfig } from '@cdc/core/types/MarkupInclude'
4
4
  type ConfigCTX = {
5
5
  config: MarkupIncludeConfig
6
6
  data: Object[]
7
+ editorData?: Object[]
7
8
  isDashboard: boolean
8
9
  loading: boolean
9
10
  setParentConfig: Function
@@ -75,8 +75,10 @@ const testConfig = {
75
75
  contentEditor: {
76
76
  inlineHTML: '<h2>Test Markup Include</h2><p>{{test_variable}}</p>',
77
77
  showHeader: true,
78
+ style: 'default',
78
79
  srcUrl: '',
79
80
  title: 'Test Markup Include Title',
81
+ titleStyle: 'small',
80
82
  useInlineHTML: true,
81
83
  showNoDataMessage: false,
82
84
  noDataMessageText: 'No data available'
@@ -89,7 +91,6 @@ const testConfig = {
89
91
  legend: {},
90
92
  newViz: true,
91
93
  theme: 'theme-blue',
92
- titleStyle: 'small',
93
94
  showTitle: true,
94
95
  type: 'markup-include',
95
96
  visual: {
@@ -154,6 +155,50 @@ export const GeneralSectionTests: Story = {
154
155
  const headerElement = modernHeader || legacyHeader
155
156
  expect(headerElement).toBeTruthy()
156
157
  expect(headerElement!.textContent?.trim()).toBe('Updated Markup Include Title E2E')
158
+
159
+ // ============================================================================
160
+ // TEST 2: Switch to TP5 Style
161
+ // Expectation: TP5 container appears and legacy title wrapper is removed
162
+ // ============================================================================
163
+ const styleSelect = canvasElement.querySelector('select[name="style"]') as HTMLSelectElement
164
+ expect(styleSelect).toBeTruthy()
165
+
166
+ await performAndAssert(
167
+ 'Style Change to TP5',
168
+ () => ({
169
+ styleValue: styleSelect.value,
170
+ hasTp5Container: !!canvasElement.querySelector('.markup-include-component--tp5')
171
+ }),
172
+ async () => {
173
+ await userEvent.selectOptions(styleSelect, 'tp5')
174
+ },
175
+ (before, after) =>
176
+ before.styleValue !== after.styleValue &&
177
+ after.styleValue === 'tp5' &&
178
+ before.hasTp5Container !== after.hasTp5Container
179
+ )
180
+
181
+ // ============================================================================
182
+ // TEST 3: TP5 title visibility
183
+ // Expectation: TP5 heading hidden when title is empty, shown when title has value
184
+ // ============================================================================
185
+ await performAndAssert(
186
+ 'TP5 Title Hidden When Empty',
187
+ () => !!canvasElement.querySelector('.markup-include-tp5 .cdc-callout__heading span'),
188
+ async () => {
189
+ await userEvent.clear(titleInput)
190
+ },
191
+ (before, after) => before !== after && after === false
192
+ )
193
+
194
+ await performAndAssert(
195
+ 'TP5 Title Shows With Text',
196
+ () => canvasElement.querySelector('.markup-include-tp5 .cdc-callout__heading span')?.textContent?.trim() || '',
197
+ async () => {
198
+ await userEvent.type(titleInput, 'TP5 Title Test')
199
+ },
200
+ (before, after) => before !== after && after === 'TP5 Title Test'
201
+ )
157
202
  }
158
203
  }
159
204
 
@@ -0,0 +1,33 @@
1
+ import type { Meta, StoryObj } from '@storybook/react-vite'
2
+ import { expect } from 'storybook/test'
3
+ import { assertVisualizationRendered } from '@cdc/core/helpers/testing'
4
+ import CdcMarkupInclude from '../CdcMarkupInclude'
5
+ import MinimalExampleConfig from '../../examples/minimal-example.json'
6
+
7
+ const meta: Meta<typeof CdcMarkupInclude> = {
8
+ title: 'Components/Pages/Markup Include',
9
+ component: CdcMarkupInclude
10
+ }
11
+
12
+ export default meta
13
+ type Story = StoryObj<typeof CdcMarkupInclude>
14
+
15
+ export const Markup_Include_Minimal_Config: Story = {
16
+ args: {
17
+ config: MinimalExampleConfig,
18
+ isEditor: false
19
+ },
20
+ parameters: {
21
+ docs: {
22
+ description: {
23
+ story:
24
+ 'Minimum working consumer config. This story validates the source-of-truth minimal example used by the package README and CONFIG reference.'
25
+ }
26
+ }
27
+ },
28
+ play: async ({ canvasElement }) => {
29
+ await assertVisualizationRendered(canvasElement)
30
+ expect(canvasElement.textContent).toContain('Markup Include')
31
+ expect(canvasElement.textContent).toContain('Markup include minimum example.')
32
+ }
33
+ }
@@ -1,5 +1,7 @@
1
1
  import type { Meta, StoryObj } from '@storybook/react-vite'
2
+ import { expect } from 'storybook/test'
2
3
  import CdcMarkupInclude from '../CdcMarkupInclude'
4
+ import { assertVisualizationRendered } from '@cdc/core/helpers/testing'
3
5
  import primary from './_mock/primary.json'
4
6
  import noConditions from './_mock/no-conditions.json'
5
7
  import withConditions from './_mock/with-conditions.json'
@@ -48,6 +50,63 @@ export const icon_no_text: Story = {
48
50
  isEditor: false
49
51
  }
50
52
  }
53
+
54
+ export const Icon_Sizing: Story = {
55
+ args: {
56
+ config: {
57
+ ...primary,
58
+ contentEditor: {
59
+ ...primary.contentEditor,
60
+ showHeader: true,
61
+ title: 'SVG icon sizing',
62
+ useInlineHTML: true,
63
+ markupVariables: [
64
+ {
65
+ sourceType: 'icon',
66
+ name: 'link-external',
67
+ tag: '{{link-external}}',
68
+ iconId: 'link-external',
69
+ conditions: []
70
+ }
71
+ ],
72
+ inlineHTML: `
73
+ <p class="icon-sizing-inline">Rate <span class="icon-sizing-inline-target">{{link-external}}</span> increased</p>
74
+ <div
75
+ class="icon-sizing-parent-target"
76
+ data-cove-svg-size="parent-height"
77
+ style="height: 200px; background: #f8d7da; display: inline-flex; align-items: center;"
78
+ >
79
+ {{link-external}}
80
+ </div>
81
+ `
82
+ },
83
+ enableMarkupVariables: true
84
+ } as any,
85
+ isEditor: false
86
+ },
87
+ play: async ({ canvasElement }) => {
88
+ await assertVisualizationRendered(canvasElement)
89
+
90
+ const inlineIcon = canvasElement.querySelector('.icon-sizing-inline-target .cove-inline-svg') as HTMLElement | null
91
+ const parentIcon = canvasElement.querySelector('.icon-sizing-parent-target .cove-inline-svg') as HTMLElement | null
92
+ const parentContainer = canvasElement.querySelector('.icon-sizing-parent-target') as HTMLElement | null
93
+
94
+ expect(inlineIcon).toBeTruthy()
95
+ expect(parentIcon).toBeTruthy()
96
+ expect(parentContainer).toBeTruthy()
97
+
98
+ const inlineHeight = inlineIcon!.getBoundingClientRect().height
99
+ const parentHeight = parentIcon!.getBoundingClientRect().height
100
+ const containerHeight = parentContainer!.getBoundingClientRect().height
101
+
102
+ expect(inlineHeight).toBeGreaterThan(0)
103
+ expect(inlineHeight).toBeLessThan(50)
104
+ expect(parentHeight).toBeGreaterThan(inlineHeight * 3)
105
+ expect(parentHeight).toBeGreaterThan(180)
106
+ expect(Math.abs(parentHeight - containerHeight)).toBeLessThan(2)
107
+ }
108
+ }
109
+
51
110
  export const image_with_text: Story = {
52
111
  args: {
53
112
  config: imageWithText,
@@ -55,4 +114,66 @@ export const image_with_text: Story = {
55
114
  }
56
115
  }
57
116
 
117
+ export const TP5_Test: Story = {
118
+ args: {
119
+ config: {
120
+ ...primary,
121
+ contentEditor: {
122
+ ...primary.contentEditor,
123
+ style: 'tp5',
124
+ title: 'TP5 Markup Include Test',
125
+ useInlineHTML: true,
126
+ inlineHTML:
127
+ '<p>This is a TP5 style markup include test story.</p><p>Clear the title in the editor to verify TP5 title hide behavior.</p>'
128
+ },
129
+ visual: {
130
+ ...primary.visual,
131
+ border: true,
132
+ whiteBackground: true
133
+ }
134
+ },
135
+ isEditor: true
136
+ }
137
+ }
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
+
58
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
+ }