@cdc/data-bite 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.
@@ -0,0 +1,59 @@
1
+ {
2
+ "type": "data-bite",
3
+ "data": [
4
+ {
5
+ "Category": "Total",
6
+ "Value": 1234
7
+ },
8
+ {
9
+ "Category": "Group A",
10
+ "Value": 5678
11
+ },
12
+ {
13
+ "Category": "Group B",
14
+ "Value": 9012
15
+ },
16
+ {
17
+ "Category": "Group C",
18
+ "Value": 3456
19
+ }
20
+ ],
21
+ "dataBite": "",
22
+ "dataFunction": "Mean (Average)",
23
+ "dataColumn": "Value",
24
+ "bitePosition": "Left",
25
+ "biteFontSize": 36,
26
+ "fontSize": "medium",
27
+ "biteBody": "Highlight a statistic, data point, or key fact about a topic using the relevant layout option:",
28
+ "imageData": {
29
+ "display": "none",
30
+ "url": "",
31
+ "alt": "",
32
+ "options": []
33
+ },
34
+ "dataFormat": {
35
+ "roundToPlace": 0,
36
+ "commas": true,
37
+ "prefix": "",
38
+ "suffix": ""
39
+ },
40
+ "biteStyle": "tp5",
41
+ "filters": [],
42
+ "subtext": "*This is an optional subtext or citation.",
43
+ "title": "Data / Fact",
44
+ "theme": "theme-blue",
45
+ "shadow": false,
46
+ "visual": {
47
+ "border": false,
48
+ "accent": false,
49
+ "background": false,
50
+ "hideBackgroundColor": false,
51
+ "borderColorTheme": false,
52
+ "showTitle": true
53
+ },
54
+ "general": {
55
+ "isCompactStyle": false
56
+ },
57
+ "markupVariables": [],
58
+ "enableMarkupVariables": false
59
+ }
package/index.html CHANGED
@@ -1,34 +1 @@
1
- <!DOCTYPE html>
2
- <html lang="en">
3
- <head>
4
- <meta charset="utf-8" />
5
- <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no" />
6
- <style>
7
- body {
8
- margin: 0;
9
- border-top: none !important;
10
- }
11
-
12
- /* Add 1rem padding to mimic DFE when editor is not visible */
13
- .cdc-open-viz-module:not(.isEditor) {
14
- padding: 1rem;
15
- }
16
- </style>
17
- <link rel="stylesheet prefetch" href="https://www.cdc.gov/TemplatePackage/5.0/css/app.min.css?_=71669" />
18
- </head>
19
- <body>
20
- <!-- Original -->
21
- <!-- <div class="react-container" data-config="/examples/sankey-example-data.json"></div> -->
22
-
23
- <!-- DATA PRESENTATION GALLERY: https://www.cdc.gov/wcms/4.0/cdc-wp/data-presentation/data_bites.html#examples -->
24
- <!-- <div class="react-container" data-config="/examples/gallery/calculated-average.json"></div> -->
25
- <!-- <div class="react-container" data-config="/examples/gallery/calculated-with-pic.json"></div> -->
26
- <!-- <div class="react-container" data-config="/examples/gallery/max-value.json"></div> -->
27
- <!-- <div class="react-container" data-config="/examples/gallery/sum-of-data.json"></div> -->
28
-
29
- <!-- TP5 Style Example -->
30
- <div class="react-container" data-config="/examples/tp5-style.json"></div>
31
-
32
- <script type="module" src="./src/index.jsx"></script>
33
- </body>
34
- </html>
1
+ <!-- index.html is generated by @cdc/core/generateViteConfig.js using the files in @cdc/core/devTemplate/ -->
package/package.json CHANGED
@@ -1,49 +1,47 @@
1
1
  {
2
2
  "name": "@cdc/data-bite",
3
- "version": "4.26.1",
3
+ "version": "4.26.3",
4
4
  "description": "React component for displaying a single piece of data in a card module",
5
- "moduleName": "CdcDataBite",
6
- "main": "dist/cdcdatabite",
7
- "type": "module",
8
- "scripts": {
9
- "start": "vite --open",
10
- "build": "vite build",
11
- "preview": "vite preview",
12
- "graph": "nx graph",
13
- "prepublishOnly": "lerna run --scope @cdc/data-bite build",
14
- "test": "vitest run --reporter verbose",
15
- "test-watch": "vitest watch --reporter verbose",
16
- "test-watch:ui": "vitest --ui"
17
- },
18
- "repository": {
19
- "type": "git",
20
- "url": "git+https://github.com/CDCgov/cdc-open-viz",
21
- "directory": "packages/data-bite"
22
- },
23
- "author": "cooms13 <dmo7@cdc.gov>",
24
- "bugs": {
25
- "url": "https://github.com/CDCgov/cdc-open-viz/issues"
26
- },
27
5
  "license": "Apache-2.0",
28
- "homepage": "https://github.com/CDCgov/cdc-open-viz#readme",
6
+ "author": "cooms13 <dmo7@cdc.gov>",
7
+ "bugs": "https://github.com/CDCgov/cdc-open-viz/issues",
29
8
  "dependencies": {
30
- "@cdc/core": "^4.26.1",
31
- "chroma-js": "3.1.2",
32
- "html-react-parser": "5.2.3",
33
- "lodash": "^4.17.21",
9
+ "@cdc/core": "^4.26.3",
10
+ "chroma-js": "^3.1.2",
11
+ "html-react-parser": "^5.2.3",
12
+ "lodash": "^4.17.23",
34
13
  "react-accessible-accordion": "^5.0.1",
35
14
  "resize-observer-polyfill": "^1.5.1"
36
15
  },
37
- "peerDependencies": {
38
- "react": "^18.2.0",
39
- "react-dom": "^18.2.0"
40
- },
41
16
  "devDependencies": {
42
17
  "@rollup/plugin-dsv": "^3.0.2",
43
- "@vitejs/plugin-react": "^4.3.4",
18
+ "@vitejs/plugin-react": "^5.1.2",
44
19
  "sass": "^1.89.2",
45
20
  "vite-plugin-css-injected-by-js": "^2.4.0",
46
21
  "vite-plugin-svgr": "^4.2.0"
47
22
  },
48
- "gitHead": "7e3b27098c4eb7a24bc9c3654ad53f88d6419f16"
23
+ "gitHead": "d50e45a074fbefa56cac904917e707d57f237737",
24
+ "homepage": "https://github.com/CDCgov/cdc-open-viz#readme",
25
+ "main": "dist/cdcdatabite",
26
+ "moduleName": "CdcDataBite",
27
+ "peerDependencies": {
28
+ "react": "^18.2.0",
29
+ "react-dom": "^18.2.0"
30
+ },
31
+ "repository": {
32
+ "type": "git",
33
+ "url": "git+https://github.com/CDCgov/cdc-open-viz",
34
+ "directory": "packages/data-bite"
35
+ },
36
+ "scripts": {
37
+ "build": "vite build",
38
+ "graph": "nx graph",
39
+ "prepublishOnly": "lerna run --scope @cdc/data-bite build",
40
+ "preview": "vite preview",
41
+ "start": "vite --open",
42
+ "test": "vitest run --reporter verbose",
43
+ "test-watch": "vitest watch --reporter verbose",
44
+ "test-watch:ui": "vitest --ui"
45
+ },
46
+ "type": "module"
49
47
  }
@@ -11,7 +11,7 @@ import Loading from '@cdc/core/components/Loading'
11
11
  import Title from '@cdc/core/components/ui/Title'
12
12
  import CircleCallout from './components/CircleCallout'
13
13
  import GradientBite from './components/GradientBite'
14
- import Layout from '@cdc/core/components/Layout'
14
+ import { VisualizationContainer, VisualizationContent } from '@cdc/core/components/Layout'
15
15
 
16
16
  // external
17
17
  import ResizeObserver from 'resize-observer-polyfill'
@@ -29,12 +29,13 @@ import { publish } from '@cdc/core/helpers/events'
29
29
  import useDataVizClasses from '@cdc/core/helpers/useDataVizClasses'
30
30
  import cacheBustingString from '@cdc/core/helpers/cacheBustingString'
31
31
  import coveUpdateWorker from '@cdc/core/helpers/coveUpdateWorker'
32
+ import { backfillDefaults } from '@cdc/core/helpers/backfillDefaults'
32
33
  import { Config } from './types/Config'
33
34
  import dataBiteReducer from './store/db.reducer'
34
35
  import { IMAGE_POSITION_LEFT, IMAGE_POSITION_RIGHT, IMAGE_POSITION_TOP, IMAGE_POSITION_BOTTOM } from './constants'
35
36
 
36
37
  // images
37
- import CalloutFlag from './images/callout-flag.svg?url'
38
+ import CalloutFlag from '@cdc/core/assets/callout-flag.svg?url'
38
39
 
39
40
  import {
40
41
  DATA_FUNCTION_COUNT,
@@ -43,6 +44,7 @@ import {
43
44
  DATA_FUNCTION_MEDIAN,
44
45
  DATA_FUNCTION_MODE,
45
46
  DATA_FUNCTION_MIN,
47
+ DATA_FUNCTION_PASSTHROUGH,
46
48
  DATA_FUNCTION_RANGE,
47
49
  DATA_FUNCTION_SUM
48
50
  } from '@cdc/core/helpers/constants'
@@ -71,8 +73,37 @@ const CdcDataBite = (props: CdcDataBiteProps) => {
71
73
  interactionLabel = ''
72
74
  } = props
73
75
 
76
+ // Ensure imageData and dataFormat sub-fields are always defined before the reducer initializes.
77
+ // Defaults must match initial-state.js — updateConfig() will enforce them again once loading completes.
78
+ const safeConfigObj = {
79
+ ...defaults,
80
+ ...configObj,
81
+ imageData: {
82
+ ...defaults.imageData,
83
+ ...(configObj?.imageData || {}),
84
+ display: configObj?.imageData?.display ?? 'none',
85
+ prefix: configObj?.imageData?.prefix ?? ''
86
+ },
87
+ dataFormat: {
88
+ ...defaults.dataFormat,
89
+ ...(configObj?.dataFormat || {}),
90
+ prefix: configObj?.dataFormat?.prefix ?? '',
91
+ suffix: configObj?.dataFormat?.suffix ?? '%',
92
+ roundToPlace: configObj?.dataFormat?.roundToPlace ?? 0,
93
+ commas: configObj?.dataFormat?.commas ?? true
94
+ },
95
+ visual: {
96
+ ...defaults.visual,
97
+ ...(configObj?.visual || {})
98
+ },
99
+ general: {
100
+ ...defaults.general,
101
+ ...(configObj?.general || {})
102
+ }
103
+ }
104
+
74
105
  const initialState = {
75
- config: configObj ?? defaults,
106
+ config: safeConfigObj ?? defaults,
76
107
  loading: true,
77
108
  currentViewport: 'lg',
78
109
  coveLoadedHasRan: false,
@@ -111,12 +142,7 @@ const CdcDataBite = (props: CdcDataBiteProps) => {
111
142
  })
112
143
 
113
144
  const updateConfig = newConfig => {
114
- // Deeper copy
115
- Object.keys(defaults).forEach(key => {
116
- if (newConfig[key] && 'object' === typeof newConfig[key] && !Array.isArray(newConfig[key])) {
117
- newConfig[key] = { ...defaults[key], ...newConfig[key] }
118
- }
119
- })
145
+ backfillDefaults(newConfig, defaults)
120
146
 
121
147
  //Enforce default values that need to be calculated at runtime
122
148
  newConfig.runtime = {}
@@ -154,7 +180,8 @@ const CdcDataBite = (props: CdcDataBiteProps) => {
154
180
 
155
181
  if (response.dataUrl) {
156
182
  response.dataUrl = `${response.dataUrl}?${cacheBustingString()}`
157
- let newData = await fetchRemoteData(response.dataUrl)
183
+ let { data: newData, dataMetadata } = await fetchRemoteData(response.dataUrl)
184
+ response.dataMetadata = dataMetadata
158
185
 
159
186
  if (newData && response.dataDescription) {
160
187
  newData = transform.autoStandardize(newData)
@@ -170,6 +197,12 @@ const CdcDataBite = (props: CdcDataBiteProps) => {
170
197
 
171
198
  const processedConfig = { ...coveUpdateWorker(response) }
172
199
 
200
+ // Migrate: borders always showed in previous versions regardless of config,
201
+ // so treat any existing config without an explicit border setting as having borders on.
202
+ if (processedConfig.visual && processedConfig.visual.border === false) {
203
+ processedConfig.visual.border = true
204
+ }
205
+
173
206
  updateConfig({ ...defaults, ...processedConfig })
174
207
  dispatch({ type: 'SET_LOADING', payload: false })
175
208
  }
@@ -184,7 +217,9 @@ const CdcDataBite = (props: CdcDataBiteProps) => {
184
217
  isEditor,
185
218
  showNoDataMessage: false,
186
219
  allowHideSection: false,
187
- filters: config.filters || []
220
+ filters: config.filters || [],
221
+ locale: config.locale,
222
+ dataMetadata: config.dataMetadata
188
223
  })
189
224
 
190
225
  return result.processedContent
@@ -313,8 +348,7 @@ const CdcDataBite = (props: CdcDataBiteProps) => {
313
348
  if (Number.isNaN(value) || typeof value === 'number') {
314
349
  value = String(value)
315
350
  }
316
- const language = 'en-US'
317
- let formattedValue = parseFloat(value).toLocaleString(language, {
351
+ let formattedValue = parseFloat(value).toLocaleString(config.locale, {
318
352
  useGrouping: true,
319
353
  maximumFractionDigits: 6
320
354
  })
@@ -342,6 +376,23 @@ const CdcDataBite = (props: CdcDataBiteProps) => {
342
376
  }
343
377
  })
344
378
 
379
+ if (dataFunction === DATA_FUNCTION_PASSTHROUGH) {
380
+ const sourceData = filteredData.length ? filteredData : config.data
381
+ if (sourceData && sourceData.length > 0) {
382
+ const rawValue = sourceData[0][dataColumn]
383
+ dataBite = rawValue !== undefined && rawValue !== null ? String(rawValue) : ''
384
+ }
385
+
386
+ if (typeof numberFromString(dataBite) === 'number') {
387
+ dataBite = applyPrecision(dataBite)
388
+ if (config.dataFormat.commas) {
389
+ dataBite = applyLocaleString(dataBite)
390
+ }
391
+ }
392
+
393
+ return includePrefixSuffix ? dataFormat.prefix + dataBite + dataFormat.suffix : dataBite
394
+ }
395
+
345
396
  let numericalData = []
346
397
  // Get the column's data
347
398
  if (filteredData.length) {
@@ -443,6 +494,9 @@ const CdcDataBite = (props: CdcDataBiteProps) => {
443
494
  }
444
495
 
445
496
  let body = <Loading />
497
+ const isCompactStyle = config.general?.isCompactStyle ?? false
498
+ const bodySubtext =
499
+ subtext && !isCompactStyle ? <p className='bite-subtext mt-0'>{parse(processContentWithMarkup(subtext))}</p> : null
446
500
 
447
501
  const DataImage = useCallback(() => {
448
502
  let operators = {
@@ -594,120 +648,118 @@ const CdcDataBite = (props: CdcDataBiteProps) => {
594
648
  }
595
649
 
596
650
  const showBite = undefined !== dataColumn && undefined !== dataFunction
651
+ const isTp5 = showBite && biteStyle === 'tp5'
652
+ const bodyClasses = [
653
+ ...innerContainerClasses,
654
+ ...contentClasses,
655
+ isTp5 ? 'bite__style--tp5' : '',
656
+ isTp5 && config.visual?.whiteBackground ? 'white-background-style' : '',
657
+ isTp5 && config.visual?.whiteBackground && config.visual?.border ? 'display-border' : '',
658
+ isTp5 && config.visual?.useWrap ? 'use-wrap' : '',
659
+ !config.visual?.border ? 'no-borders' : ''
660
+ ]
661
+ .filter(Boolean)
662
+ .join(' ')
597
663
  body = (
598
664
  <>
599
- {isEditor && <EditorPanel />}
600
- <Layout.Responsive isEditor={isEditor}>
601
- <div
602
- className={`cove-component__content ${showBite && 'tp5' === biteStyle ? 'bite__style--tp5' : ''} ${
603
- showBite && 'tp5' === biteStyle && config.visual?.whiteBackground ? 'white-background-style' : ''
604
- } ${
605
- showBite && 'tp5' === biteStyle && config.visual?.whiteBackground && config.visual?.border
606
- ? 'display-border'
607
- : ''
608
- }`}
609
- >
610
- {!config.newViz && config.runtime && config.runtime.editorErrorMessage && <Error />}
611
- {(!config.dataColumn || !config.dataFunction) && <Confirm />}
612
- {showBite && biteStyle === 'tp5' ? (
613
- <div
614
- className={`bite-content cdc-callout d-flex flex-column h-100 ${
615
- !config.visual?.whiteBackground ? 'dfe-block cdc-callout--data' : ''
616
- }`}
617
- >
618
- {/* Icon shows by default, hidden when white background is enabled */}
619
- {!config.visual?.whiteBackground && (
620
- <img src={CalloutFlag} alt='' className='cdc-callout__flag' aria-hidden='true' />
621
- )}
622
-
623
- {config.visual?.showTitle && title && title.trim() && (
624
- <h3 className='cdc-callout__heading fw-bold flex-shrink-0 d-flex align-items-start'>
625
- <span>{parse(processContentWithMarkup(title))}</span>
626
- </h3>
627
- )}
628
- <div className='cdc-callout__body d-flex flex-row align-content-start flex-grow-1'>
629
- {showBite && (
630
- <div className='cdc-callout__databite flex-shrink-0 me-3'>{calculateDataBite(true)}</div>
665
+ <VisualizationContent
666
+ bodyClassName={bodyClasses}
667
+ header={
668
+ !isTp5 ? (
669
+ <Title
670
+ showTitle={config.visual?.showTitle}
671
+ titleStyle='legacy'
672
+ config={config}
673
+ title={processContentWithMarkup(title)}
674
+ isDashboard={isDashboard}
675
+ classes={['bite-header', `${config.theme}`]}
676
+ />
677
+ ) : null
678
+ }
679
+ footer={link && link}
680
+ >
681
+ {!config.newViz && config.runtime && config.runtime.editorErrorMessage && <Error />}
682
+ {(!config.dataColumn || !config.dataFunction) && <Confirm />}
683
+ {showBite && biteStyle === 'tp5' ? (
684
+ <div
685
+ className={`bite-content cdc-callout d-flex flex-column h-100 ${
686
+ !config.visual?.whiteBackground ? 'dfe-block cdc-callout--data' : ''
687
+ }`}
688
+ >
689
+ {!config.visual?.whiteBackground && (
690
+ <img src={CalloutFlag} alt='' className='cdc-callout__flag' aria-hidden='true' />
691
+ )}
692
+
693
+ {config.visual?.showTitle && title && title.trim() && (
694
+ <h3 className='cdc-callout__heading fw-bold flex-shrink-0 d-flex align-items-start'>
695
+ <span>{parse(processContentWithMarkup(title))}</span>
696
+ </h3>
697
+ )}
698
+ <div className='cdc-callout__body d-flex flex-row align-content-start flex-grow-1'>
699
+ {showBite && <div className='cdc-callout__databite flex-shrink-0 me-3'>{calculateDataBite(true)}</div>}
700
+ <div className='cdc-callout__content flex-grow-1 d-flex flex-column min-w-0'>
701
+ <p className='mb-0'>{parse(processContentWithMarkup(biteBody))}</p>
702
+ {subtext && !isCompactStyle && (
703
+ <p className='bite-subtext fst-italic flex-shrink-0'>{parse(processContentWithMarkup(subtext))}</p>
631
704
  )}
632
- <div className='cdc-callout__content flex-grow-1 d-flex flex-column min-w-0'>
633
- <p className='mb-0'>{parse(processContentWithMarkup(biteBody))}</p>
634
- {subtext && !config.general.isCompactStyle && (
635
- <p className='bite-subtext fst-italic flex-shrink-0 mt-3'>
636
- {parse(processContentWithMarkup(subtext))}
637
- </p>
638
- )}
639
- </div>
640
705
  </div>
641
706
  </div>
642
- ) : (
643
- <>
644
- <Title
645
- showTitle={config.visual?.showTitle}
646
- titleStyle='legacy'
647
- config={config}
648
- title={processContentWithMarkup(title)}
649
- isDashboard={isDashboard}
650
- classes={['bite-header', `${config.theme}`]}
651
- />
652
- <div className={`bite ${biteClasses.join(' ')}`}>
653
- <div className={`bite-content-container ${contentClasses.join(' ')}`}>
654
- {showBite && 'graphic' === biteStyle && isTop && (
655
- <CircleCallout
656
- theme={config.theme}
657
- text={calculateDataBite()}
658
- biteFontSize={biteFontSize}
659
- dataFormat={dataFormat}
660
- />
661
- )}
662
- {isTop && <DataImage />}
663
- <div className={`bite-content`}>
664
- {showBite && 'title' === biteStyle && (
665
- <div className='bite-value' style={{ fontSize: biteFontSize + 'px' }}>
666
- {calculateDataBite()}
667
- </div>
668
- )}
669
- {showBite && 'split' === biteStyle && (
670
- <div className='bite-value' style={{ fontSize: biteFontSize + 'px' }}>
707
+ </div>
708
+ ) : (
709
+ <div className={`bite ${biteClasses.join(' ')}`}>
710
+ <div className='bite-content-container'>
711
+ {showBite && 'graphic' === biteStyle && isTop && (
712
+ <CircleCallout
713
+ theme={config.theme}
714
+ text={calculateDataBite()}
715
+ biteFontSize={biteFontSize}
716
+ dataFormat={dataFormat}
717
+ />
718
+ )}
719
+ {isTop && <DataImage />}
720
+ <div className={`bite-content`}>
721
+ {showBite && 'title' === biteStyle && (
722
+ <div className='bite-value' style={{ fontSize: biteFontSize + 'px' }}>
723
+ {calculateDataBite()}
724
+ </div>
725
+ )}
726
+ {showBite && 'split' === biteStyle && (
727
+ <div className='bite-value' style={{ fontSize: biteFontSize + 'px' }}>
728
+ {calculateDataBite()}
729
+ </div>
730
+ )}
731
+ <Fragment>
732
+ <div className='bite-content__text-wrap'>
733
+ <p className='bite-text'>
734
+ {showBite && 'body' === biteStyle && (
735
+ <span className='bite-value data-bite-body' style={{ fontSize: biteFontSize + 'px' }}>
736
+ {calculateDataBite()}
737
+ </span>
738
+ )}
739
+ {parse(processContentWithMarkup(biteBody))}
740
+ </p>
741
+ {showBite && 'end' === biteStyle && (
742
+ <span className='bite-value data-bite-body' style={{ fontSize: biteFontSize + 'px' }}>
671
743
  {calculateDataBite()}
672
- </div>
744
+ </span>
673
745
  )}
674
- <Fragment>
675
- <div className='bite-content__text-wrap'>
676
- <p className='bite-text'>
677
- {showBite && 'body' === biteStyle && (
678
- <span className='bite-value data-bite-body' style={{ fontSize: biteFontSize + 'px' }}>
679
- {calculateDataBite()}
680
- </span>
681
- )}
682
- {parse(processContentWithMarkup(biteBody))}
683
- </p>
684
- {showBite && 'end' === biteStyle && (
685
- <span className='bite-value data-bite-body' style={{ fontSize: biteFontSize + 'px' }}>
686
- {calculateDataBite()}
687
- </span>
688
- )}
689
- {subtext && !config.general.isCompactStyle && (
690
- <p className='bite-subtext'>{parse(processContentWithMarkup(subtext))}</p>
691
- )}
692
- </div>
693
- </Fragment>
746
+ {bodySubtext}
694
747
  </div>
695
- {isBottom && <DataImage />}
696
- {showBite && 'graphic' === biteStyle && !isTop && (
697
- <CircleCallout
698
- theme={config.theme}
699
- text={calculateDataBite()}
700
- biteFontSize={biteFontSize}
701
- dataFormat={dataFormat}
702
- />
703
- )}
704
- </div>
748
+ </Fragment>
705
749
  </div>
706
- </>
707
- )}
708
- </div>
709
- {link && link}
710
- </Layout.Responsive>
750
+ {isBottom && <DataImage />}
751
+ {showBite && 'graphic' === biteStyle && !isTop && (
752
+ <CircleCallout
753
+ theme={config.theme}
754
+ text={calculateDataBite()}
755
+ biteFontSize={biteFontSize}
756
+ dataFormat={dataFormat}
757
+ />
758
+ )}
759
+ </div>
760
+ </div>
761
+ )}
762
+ </VisualizationContent>
711
763
  </>
712
764
  )
713
765
  }
@@ -717,29 +769,36 @@ const CdcDataBite = (props: CdcDataBiteProps) => {
717
769
  value={{ config, updateConfig, loading, data: config.data, setParentConfig, isDashboard, isEditor }}
718
770
  >
719
771
  {biteStyle !== 'gradient' && (
720
- <Layout.VisualizationWrapper
772
+ <VisualizationContainer
721
773
  ref={outerContainerRef}
722
774
  config={config}
723
775
  isEditor={isEditor}
724
- showEditorPanel={config?.showEditorPanel}
776
+ currentViewport={currentViewport}
777
+ editorPanel={<EditorPanel />}
725
778
  >
726
779
  {body}
727
- </Layout.VisualizationWrapper>
780
+ </VisualizationContainer>
728
781
  )}
729
782
  {'gradient' === biteStyle && (
730
- <Layout.VisualizationWrapper
783
+ <VisualizationContainer
731
784
  ref={outerContainerRef}
732
785
  config={config}
733
786
  isEditor={isEditor}
734
- showEditorPanel={config?.showEditorPanel}
787
+ currentViewport={currentViewport}
788
+ editorPanel={<EditorPanel />}
735
789
  >
736
- {isEditor && <EditorPanel />}
737
- <Layout.Responsive isEditor={isEditor}>
790
+ <VisualizationContent
791
+ bodyClassName={[...innerContainerClasses, ...contentClasses, 'bite__style--gradient']
792
+ .filter(Boolean)
793
+ .join(' ')}
794
+ footer={link && link}
795
+ subtext={bodySubtext}
796
+ >
738
797
  {!config.newViz && config.runtime && config.runtime.editorErrorMessage && <Error />}
739
798
  {(!config.dataColumn || !config.dataFunction) && <Confirm />}
740
799
  <GradientBite label={config.title} value={calculateDataBite()} />
741
- </Layout.Responsive>
742
- </Layout.VisualizationWrapper>
800
+ </VisualizationContent>
801
+ </VisualizationContainer>
743
802
  )}
744
803
  </Context.Provider>
745
804
  )