@cdc/waffle-chart 4.26.2 → 4.26.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "@cdc/waffle-chart",
3
- "version": "4.26.2",
3
+ "version": "4.26.3",
4
4
  "description": "React component for displaying a single piece of data in a card module",
5
5
  "license": "Apache-2.0",
6
6
  "author": "rshelnutt <qyu6@cdc.gov>",
7
7
  "bugs": "https://github.com/CDCgov/cdc-open-viz/issues",
8
8
  "dependencies": {
9
- "@cdc/core": "^4.26.2",
9
+ "@cdc/core": "^4.26.3",
10
10
  "@visx/shape": "^3.12.0",
11
11
  "@visx/text": "^3.12.0",
12
12
  "html-react-parser": "^5.2.3",
@@ -20,7 +20,7 @@
20
20
  "vite-plugin-css-injected-by-js": "^2.4.0",
21
21
  "vite-plugin-svgr": "^4.2.0"
22
22
  },
23
- "gitHead": "be3413e8e1149abf94225108f86a7910f56e0616",
23
+ "gitHead": "d50e45a074fbefa56cac904917e707d57f237737",
24
24
  "homepage": "https://github.com/CDCgov/cdc-open-viz#readme",
25
25
  "main": "dist/cdcwafflechart",
26
26
  "moduleName": "CdcWaffleChart",
@@ -25,13 +25,14 @@ import { publish } from '@cdc/core/helpers/events'
25
25
  import chartReducer from './store/chart.reducer'
26
26
  import coveUpdateWorker from '@cdc/core/helpers/coveUpdateWorker'
27
27
  import useDataVizClasses from '@cdc/core/helpers/useDataVizClasses'
28
+ import { processMarkupVariables } from '@cdc/core/helpers/markupProcessor'
28
29
 
29
30
  import './scss/main.scss'
30
31
  import Title from '@cdc/core/components/ui/Title'
31
- import Layout from '@cdc/core/components/Layout'
32
+ import { VisualizationContainer, VisualizationContent } from '@cdc/core/components/Layout'
32
33
 
33
34
  // images
34
- import CalloutFlag from './images/callout-flag.svg?url'
35
+ import CalloutFlag from '@cdc/core/assets/callout-flag.svg?url'
35
36
 
36
37
  // TP5 Style Constants
37
38
  const TP5_NODE_WIDTH = 13
@@ -72,6 +73,59 @@ const WaffleChart = ({ config, isEditor, link = '', showConfigConfirm, updateCon
72
73
  roundToPlace
73
74
  } = config
74
75
 
76
+ const processedTextFields = useMemo(() => {
77
+ if (!config.enableMarkupVariables || !config.markupVariables?.length) {
78
+ return {
79
+ title,
80
+ content,
81
+ subtext,
82
+ valueDescription: config.valueDescription
83
+ }
84
+ }
85
+
86
+ const markupOptions = {
87
+ isEditor,
88
+ showNoDataMessage: false,
89
+ allowHideSection: false,
90
+ filters: config.filters || [],
91
+ locale: config.locale,
92
+ dataMetadata: config.dataMetadata
93
+ }
94
+
95
+ return {
96
+ title: title
97
+ ? processMarkupVariables(title, config.data || [], config.markupVariables, markupOptions).processedContent
98
+ : title,
99
+ content: content
100
+ ? processMarkupVariables(content, config.data || [], config.markupVariables, markupOptions).processedContent
101
+ : content,
102
+ subtext: subtext
103
+ ? processMarkupVariables(subtext, config.data || [], config.markupVariables, markupOptions).processedContent
104
+ : subtext,
105
+ valueDescription: config.valueDescription
106
+ ? processMarkupVariables(config.valueDescription, config.data || [], config.markupVariables, markupOptions)
107
+ .processedContent
108
+ : config.valueDescription
109
+ }
110
+ }, [
111
+ config.enableMarkupVariables,
112
+ config.markupVariables,
113
+ config.data,
114
+ config.filters,
115
+ config.locale,
116
+ config.dataMetadata,
117
+ config.valueDescription,
118
+ title,
119
+ content,
120
+ subtext,
121
+ isEditor
122
+ ])
123
+
124
+ const processedTitle = processedTextFields.title
125
+ const processedContent = processedTextFields.content
126
+ const processedSubtext = processedTextFields.subtext
127
+ const processedValueDescription = processedTextFields.valueDescription
128
+
75
129
  const gaugeColor = config.visual.colors[config.theme]
76
130
  let dataFontSize = config.fontSize ? { fontSize: config.fontSize + 'px' } : null
77
131
 
@@ -351,7 +405,7 @@ const WaffleChart = ({ config, isEditor, link = '', showConfigConfirm, updateCon
351
405
  return setRatio() + 2
352
406
  }, [nodeWidth, nodeSpacer, config.visualizationType])
353
407
 
354
- const { innerContainerClasses, contentClasses } = useDataVizClasses(config)
408
+ const { contentClasses } = useDataVizClasses(config)
355
409
 
356
410
  const xScale = scaleLinear({
357
411
  domain: [0, waffleDenominator],
@@ -397,141 +451,141 @@ const WaffleChart = ({ config, isEditor, link = '', showConfigConfirm, updateCon
397
451
  <Error updateConfig={updateConfig} config={config} />
398
452
  )}
399
453
  {config.newViz && showConfigConfirm && <Confirm updateConfig={updateConfig} config={config} />}
400
- <div className='cove-component__content-wrap p-0'>
401
- {(config.visualizationType === 'Gauge' || config.visualizationType === 'TP5 Gauge') && (
402
- <div className={`cove-gauge-chart${config.overallFontSize ? ' font-' + config.overallFontSize : ''}`}>
403
- <div className='cove-gauge-chart__chart'>
404
- {config.visualizationType === 'TP5 Gauge' ? (
405
- <>
406
- <div
407
- className={`cove-gauge-chart__body d-flex flex-row align-items-start flex-grow-1${
408
- !content ? ' justify-content-center' : ''
409
- }`}
410
- >
411
- <div className='cove-gauge-chart__value-section flex-shrink-0'>
412
- <div className='cove-waffle-chart__data--primary' style={dataFontSize}>
413
- {prefix ? prefix : ' '}
414
- {config.showPercent ? dataPercentage : waffleNumerator}
415
- {suffix ? suffix + ' ' : ' '} {config.valueDescription}{' '}
416
- {config.showDenominator && waffleDenominator ? waffleDenominator : ' '}
417
- </div>
418
- </div>
419
- <div className='cove-gauge-chart__content flex-grow-1 d-flex flex-column min-w-0'>
420
- {content ? (
421
- <div className='cove-waffle-chart__data--text'>{parse(content)}</div>
422
- ) : (
423
- <div className='cove-waffle-chart__data--text' aria-hidden='true'>
424
- &nbsp;
425
- </div>
426
- )}
454
+ {(config.visualizationType === 'Gauge' || config.visualizationType === 'TP5 Gauge') && (
455
+ <div className={`cove-gauge-chart${config.overallFontSize ? ' font-' + config.overallFontSize : ''}`}>
456
+ <div className='cove-gauge-chart__chart'>
457
+ {config.visualizationType === 'TP5 Gauge' ? (
458
+ <>
459
+ <div
460
+ className={`cove-gauge-chart__body d-flex flex-row align-items-start flex-grow-1${
461
+ !processedContent ? ' justify-content-center' : ''
462
+ }`}
463
+ >
464
+ <div className='cove-gauge-chart__value-section flex-shrink-0'>
465
+ <div className='cove-waffle-chart__data--primary' style={dataFontSize}>
466
+ {prefix ? prefix : ' '}
467
+ {config.showPercent ? dataPercentage : waffleNumerator}
468
+ {suffix ? suffix + ' ' : ' '} {processedValueDescription}{' '}
469
+ {config.showDenominator && waffleDenominator ? waffleDenominator : ' '}
427
470
  </div>
428
471
  </div>
429
- <svg
430
- height={config.gauge.height + 2}
431
- width={'100%'}
432
- className='mt-2'
433
- style={{ overflow: 'visible', padding: '1px' }}
434
- >
435
- <Group>
436
- <Bar
437
- x={0}
438
- y={0}
439
- width={config.gauge.width}
440
- height={config.gauge.height}
441
- fill='#dff2f6'
442
- stroke='#007A99'
443
- strokeWidth={1}
444
- rx={10}
445
- ry={10}
446
- />
447
- <Bar
448
- x={0}
449
- y={0}
450
- width={xScale(waffleNumerator)}
451
- height={config.gauge.height}
452
- fill='#007A99'
453
- rx={10}
454
- ry={10}
455
- />
456
- </Group>
457
- </svg>
458
- {subtext && (
459
- <div className='cove-waffle-chart__subtext subtext fst-italic mt-2'>{parse(subtext)}</div>
460
- )}
461
- </>
462
- ) : (
463
- <>
464
- <div className='cove-waffle-chart__data--primary' style={dataFontSize}>
465
- {prefix ? prefix : ' '}
466
- {config.showPercent ? dataPercentage : waffleNumerator}
467
- {suffix ? suffix + ' ' : ' '} {config.valueDescription}{' '}
468
- {config.showDenominator && waffleDenominator ? waffleDenominator : ' '}
469
- </div>
470
- <div className='cove-waffle-chart__data--text'>{parse(content)}</div>
471
- <svg height={config.gauge.height} width={'100%'}>
472
- <Group>
473
- <Bar
474
- x={0}
475
- y={0}
476
- width={config.gauge.width}
477
- height={config.gauge.height}
478
- fill='#e0e0e0'
479
- stroke='#999'
480
- strokeWidth={1}
481
- rx={4}
482
- ry={4}
483
- />
484
- <Bar
485
- x={0}
486
- y={0}
487
- width={xScale(waffleNumerator)}
488
- height={config.gauge.height}
489
- fill={gaugeColor}
490
- rx={4}
491
- ry={4}
492
- />
493
- </Group>
494
- </svg>
495
- <div className={'cove-waffle-chart__subtext subtext'}>{parse(subtext)}</div>
496
- </>
497
- )}
498
- </div>
499
- </div>
500
- )}
501
- {config.visualizationType !== 'Gauge' && config.visualizationType !== 'TP5 Gauge' && (
502
- <div
503
- className={`cove-waffle-chart${orientation === 'vertical' ? ' cove-waffle-chart--verical' : ''}${
504
- config.overallFontSize ? ' font-' + config.overallFontSize : ''
505
- }`}
506
- >
507
- <div className='cove-waffle-chart__chart' style={{ width: setRatio() }}>
508
- <svg width={setSvgSize()} height={setSvgSize()} style={{ display: 'block' }}>
509
- <Group top={1} left={1}>
510
- {buildWaffle()}
511
- </Group>
512
- </svg>
513
- </div>
514
- {(dataPercentage || content) && (
515
- <div className='cove-waffle-chart__data'>
516
- {dataPercentage && (
517
- <div className='cove-waffle-chart__data--primary' style={dataFontSize}>
518
- {prefix ? prefix : null}
519
- {dataPercentage}
520
- {suffix ? suffix : null}
472
+ <div className='cove-gauge-chart__content flex-grow-1 d-flex flex-column min-w-0'>
473
+ {processedContent ? (
474
+ <div className='cove-waffle-chart__data--text'>{parse(processedContent)}</div>
475
+ ) : (
476
+ <div className='cove-waffle-chart__data--text' aria-hidden='true'>
477
+ &nbsp;
478
+ </div>
479
+ )}
521
480
  </div>
481
+ </div>
482
+ <svg
483
+ height={config.gauge.height + 2}
484
+ width={'100%'}
485
+ className='mt-2'
486
+ style={{ overflow: 'visible', padding: '1px' }}
487
+ >
488
+ <Group>
489
+ <Bar
490
+ x={0}
491
+ y={0}
492
+ width={config.gauge.width}
493
+ height={config.gauge.height}
494
+ fill='#dff2f6'
495
+ stroke='#007A99'
496
+ strokeWidth={1}
497
+ rx={10}
498
+ ry={10}
499
+ />
500
+ <Bar
501
+ x={0}
502
+ y={0}
503
+ width={xScale(waffleNumerator)}
504
+ height={config.gauge.height}
505
+ fill='#007A99'
506
+ rx={10}
507
+ ry={10}
508
+ />
509
+ </Group>
510
+ </svg>
511
+ {processedSubtext && (
512
+ <div className='cove-waffle-chart__subtext subtext fst-italic mt-2'>{parse(processedSubtext)}</div>
522
513
  )}
523
- {content && <div className='cove-waffle-chart__data--text'>{parse(content)}</div>}
524
-
525
- {subtext && <div className='cove-waffle-chart__subtext subtext fst-italic'>{parse(subtext)}</div>}
526
- </div>
514
+ </>
515
+ ) : (
516
+ <>
517
+ <div className='cove-waffle-chart__data--primary' style={dataFontSize}>
518
+ {prefix ? prefix : ' '}
519
+ {config.showPercent ? dataPercentage : waffleNumerator}
520
+ {suffix ? suffix + ' ' : ' '} {processedValueDescription}{' '}
521
+ {config.showDenominator && waffleDenominator ? waffleDenominator : ' '}
522
+ </div>
523
+ <div className='cove-waffle-chart__data--text'>{parse(processedContent)}</div>
524
+ <svg height={config.gauge.height} width={'100%'}>
525
+ <Group>
526
+ <Bar
527
+ x={0}
528
+ y={0}
529
+ width={config.gauge.width}
530
+ height={config.gauge.height}
531
+ fill='#e0e0e0'
532
+ stroke='#999'
533
+ strokeWidth={1}
534
+ rx={4}
535
+ ry={4}
536
+ />
537
+ <Bar
538
+ x={0}
539
+ y={0}
540
+ width={xScale(waffleNumerator)}
541
+ height={config.gauge.height}
542
+ fill={gaugeColor}
543
+ rx={4}
544
+ ry={4}
545
+ />
546
+ </Group>
547
+ </svg>
548
+ <div className={'cove-waffle-chart__subtext subtext'}>{parse(processedSubtext)}</div>
549
+ </>
527
550
  )}
528
551
  </div>
529
- )}
530
- </div>
552
+ </div>
553
+ )}
554
+ {config.visualizationType !== 'Gauge' && config.visualizationType !== 'TP5 Gauge' && (
555
+ <div
556
+ className={`cove-waffle-chart${orientation === 'vertical' ? ' cove-waffle-chart--verical' : ''}${
557
+ config.overallFontSize ? ' font-' + config.overallFontSize : ''
558
+ }`}
559
+ >
560
+ <div className='cove-waffle-chart__chart' style={{ width: setRatio() }}>
561
+ <svg width={setSvgSize()} height={setSvgSize()} style={{ display: 'block' }}>
562
+ <Group top={1} left={1}>
563
+ {buildWaffle()}
564
+ </Group>
565
+ </svg>
566
+ </div>
567
+ {(dataPercentage || processedContent) && (
568
+ <div className='cove-waffle-chart__data'>
569
+ {dataPercentage && (
570
+ <div className='cove-waffle-chart__data--primary' style={dataFontSize}>
571
+ {prefix ? prefix : null}
572
+ {dataPercentage}
573
+ {suffix ? suffix : null}
574
+ </div>
575
+ )}
576
+ {processedContent && <div className='cove-waffle-chart__data--text'>{parse(processedContent)}</div>}
577
+
578
+ {processedSubtext && (
579
+ <div className='cove-waffle-chart__subtext subtext fst-italic'>{parse(processedSubtext)}</div>
580
+ )}
581
+ </div>
582
+ )}
583
+ </div>
584
+ )}
531
585
  </>
532
586
  )
533
587
 
534
- // TP5 Style: render with callout wrapper inside cove-component__content
588
+ // TP5 Style: render with callout wrapper inside cove-visualization__body
535
589
  if (config.visualizationType === 'TP5 Waffle' || config.visualizationType === 'TP5 Gauge') {
536
590
  const calloutClasses = ['cdc-callout', 'd-flex', 'flex-column']
537
591
  if (!config.visual?.whiteBackground) {
@@ -539,34 +593,40 @@ const WaffleChart = ({ config, isEditor, link = '', showConfigConfirm, updateCon
539
593
  }
540
594
 
541
595
  return (
542
- <div className='cove-component__content border-0'>
596
+ <VisualizationContent
597
+ bodyClassName={['no-borders', ...contentClasses].filter(Boolean).join(' ')}
598
+ footer={link && link}
599
+ >
543
600
  <div className={calloutClasses.join(' ')}>
544
601
  {!config.visual?.whiteBackground && (
545
602
  <img src={CalloutFlag} alt='' className='cdc-callout__flag' aria-hidden='true' />
546
603
  )}
547
- {config.showTitle && title && title.trim() && (
548
- <h3 className='cdc-callout__heading fw-bold flex-shrink-0'>{parse(title)}</h3>
604
+ {config.showTitle && processedTitle && processedTitle.trim() && (
605
+ <h3 className='cdc-callout__heading fw-bold flex-shrink-0'>{parse(processedTitle)}</h3>
549
606
  )}
550
607
  <div className='w-100 mw-100 overflow-hidden'>{renderChartContent()}</div>
551
608
  </div>
552
- {link && link}
553
- </div>
609
+ </VisualizationContent>
554
610
  )
555
611
  }
556
612
 
557
613
  // Original Style: Regular title and content
558
614
  return (
559
- <div className='cove-component__content'>
560
- <Title
561
- showTitle={config.showTitle}
562
- title={title}
563
- titleStyle='legacy'
564
- config={config}
565
- classes={['chart-title', `${config.theme}`, 'mb-0']}
566
- />
567
- <div className={contentClasses.join(' ')}>{renderChartContent()}</div>
568
- {link && link}
569
- </div>
615
+ <VisualizationContent
616
+ bodyClassName={contentClasses.join(' ')}
617
+ header={
618
+ <Title
619
+ showTitle={config.showTitle}
620
+ title={processedTitle}
621
+ titleStyle='legacy'
622
+ config={config}
623
+ classes={['chart-title', `${config.theme}`, 'mb-0']}
624
+ />
625
+ }
626
+ footer={link && link}
627
+ >
628
+ {renderChartContent()}
629
+ </VisualizationContent>
570
630
  )
571
631
  }
572
632
 
@@ -608,7 +668,9 @@ const CdcWaffleChart = ({
608
668
  let responseData = response.data ?? {}
609
669
 
610
670
  if (response.dataUrl) {
611
- responseData = await fetchRemoteData(response.dataUrl)
671
+ const { data, dataMetadata } = await fetchRemoteData(response.dataUrl)
672
+ responseData = data
673
+ response.dataMetadata = dataMetadata
612
674
  }
613
675
 
614
676
  response.data = responseData
@@ -658,17 +720,12 @@ const CdcWaffleChart = ({
658
720
 
659
721
  if (loading === false) {
660
722
  content = (
661
- <>
662
- {isEditor && <EditorPanel showConfigConfirm={showConfigConfirm} />}
663
- <Layout.Responsive isEditor={isEditor}>
664
- <WaffleChart
665
- config={config}
666
- isEditor={isEditor}
667
- showConfigConfirm={showConfigConfirm}
668
- updateConfig={updateConfig}
669
- />
670
- </Layout.Responsive>
671
- </>
723
+ <WaffleChart
724
+ config={config}
725
+ isEditor={isEditor}
726
+ showConfigConfirm={showConfigConfirm}
727
+ updateConfig={updateConfig}
728
+ />
672
729
  )
673
730
  }
674
731
 
@@ -677,14 +734,15 @@ const CdcWaffleChart = ({
677
734
  <ConfigContext.Provider
678
735
  value={{ config, updateConfig, loading, data: config.data, setParentConfig, isDashboard, outerContainerRef }}
679
736
  >
680
- <Layout.VisualizationWrapper
737
+ <VisualizationContainer
681
738
  config={config}
682
739
  isEditor={isEditor}
740
+ currentViewport={currentViewport}
683
741
  ref={outerContainerRef}
684
- showEditorPanel={config?.showEditorPanel}
742
+ editorPanel={<EditorPanel showConfigConfirm={showConfigConfirm} />}
685
743
  >
686
744
  {content}
687
- </Layout.VisualizationWrapper>
745
+ </VisualizationContainer>
688
746
  </ConfigContext.Provider>
689
747
  </ErrorBoundary>
690
748
  )
@@ -87,12 +87,12 @@ export const GeneralSectionTests: Story = {
87
87
  // Poll for header text update
88
88
  await performAndAssert(
89
89
  'Title Update',
90
- () => canvasElement.querySelector('.cove-component__header h2')?.textContent?.trim() || '',
90
+ () => canvasElement.querySelector('.cove-visualization__header h2')?.textContent?.trim() || '',
91
91
  async () => {}, // action already performed above
92
92
  (before, after) => after === 'Updated Waffle Chart Title E2E'
93
93
  )
94
94
 
95
- const chartTitleHeader = canvasElement.querySelector('.cove-component__header h2')
95
+ const chartTitleHeader = canvasElement.querySelector('.cove-visualization__header h2')
96
96
  expect(chartTitleHeader).toBeTruthy()
97
97
  expect(chartTitleHeader.textContent.trim()).toBe('Updated Waffle Chart Title E2E')
98
98
 
@@ -120,7 +120,7 @@ export const GeneralSectionTests: Story = {
120
120
  )
121
121
  expect(showTitleCheckbox.checked).toBe(!wasChecked)
122
122
 
123
- const chartTitleHeaderAfterToggle = canvasElement.querySelector('.cove-component__header')
123
+ const chartTitleHeaderAfterToggle = canvasElement.querySelector('.cove-visualization__header')
124
124
  if (showTitleCheckbox.checked) {
125
125
  expect(chartTitleHeaderAfterToggle).toBeTruthy()
126
126
  expect(chartTitleHeaderAfterToggle).not.toHaveStyle('display: none')
@@ -435,7 +435,7 @@ export const VisualSectionTests: Story = {
435
435
  await openAccordion(canvas, 'Chart Settings')
436
436
  // Core helper functions used throughout the visual tests
437
437
  const waffleRoot = () => canvasElement.querySelector('.cove-waffle-chart') as HTMLElement
438
- const contentContainer = () => canvasElement.querySelector('.cove-component__content > div') as HTMLElement
438
+ const contentContainer = () => canvasElement.querySelector('.cove-visualization__body') as HTMLElement
439
439
  expect(waffleRoot()).toBeTruthy()
440
440
 
441
441
  // ============================================================================
@@ -658,7 +658,7 @@ export const VisualSectionTests: Story = {
658
658
 
659
659
  // ============================================================================
660
660
  // TEST 9: Theme Border Color Toggle
661
- // Expectation: Class 'component--has-borderColorTheme' toggles.
661
+ // Expectation: Class 'component--has-border-color-theme' toggles.
662
662
  // ============================================================================
663
663
  // Find border color theme checkbox by exact label text
664
664
  const borderColorThemeCheckbox = canvas.getByLabelText('Use Border Color Theme') as HTMLInputElement
@@ -671,7 +671,8 @@ export const VisualSectionTests: Story = {
671
671
  async () => {
672
672
  await userEvent.click(borderColorThemeCheckbox)
673
673
  },
674
- (before, after) => before !== after && (after.includes('borderColorTheme') || before.includes('borderColorTheme'))
674
+ (before, after) =>
675
+ before !== after && (after.includes('border-color-theme') || before.includes('border-color-theme'))
675
676
  )
676
677
 
677
678
  // ============================================================================
@@ -712,7 +713,7 @@ export const VisualSectionTests: Story = {
712
713
 
713
714
  // ============================================================================
714
715
  // TEST 12: Hide Background Color Toggle
715
- // Expectation: Class 'component--hideBackgroundColor' toggles.
716
+ // Expectation: Class 'component--hide-background-color' toggles.
716
717
  // ============================================================================
717
718
  // Find hide background checkbox by exact label text
718
719
  const hideBackgroundCheckbox = canvas.getByLabelText('Hide Background Color') as HTMLInputElement
@@ -1,5 +1,4 @@
1
1
  import React, { useEffect, memo, useContext } from 'react'
2
- import _ from 'lodash'
3
2
 
4
3
  import ConfigContext from '../ConfigContext'
5
4
 
@@ -14,8 +13,9 @@ import { updateFieldFactory } from '@cdc/core/helpers/updateFieldFactory'
14
13
  import { useFilterManagement } from '@cdc/core/hooks/useFilterManagement'
15
14
  import { useDataColumns } from '@cdc/core/hooks/useDataColumns'
16
15
  import { VisualSection } from '@cdc/core/components/EditorPanel/sections/VisualSection'
16
+ import PanelMarkup from '@cdc/core/components/EditorPanel/components/PanelMarkup'
17
17
 
18
- import '@cdc/core/styles/v2/components/editor.scss'
18
+ import '@cdc/core/components/EditorPanel/editor.scss'
19
19
  import WarningImage from '../images/warning.svg'
20
20
 
21
21
  import { DATA_OPERATORS, DATA_FUNCTIONS } from '../CdcWaffleChart'
@@ -120,6 +120,28 @@ const EditorPanel = memo(props => {
120
120
  </Tooltip>
121
121
  }
122
122
  />
123
+ <Select
124
+ value={config.locale}
125
+ fieldName='locale'
126
+ label='Language for dates and numbers'
127
+ updateField={updateField}
128
+ options={[
129
+ { value: 'en-US', label: 'English (en-US)' },
130
+ { value: 'es-MX', label: 'Spanish (es-MX)' }
131
+ ]}
132
+ tooltip={
133
+ <Tooltip style={{ textTransform: 'none' }}>
134
+ <Tooltip.Target>
135
+ <Icon display='question' style={{ marginLeft: '0.5rem' }} />
136
+ </Tooltip.Target>
137
+ <Tooltip.Content>
138
+ <p>
139
+ Change the language (locale) for this visualization to alter the way dates and numbers are formatted.
140
+ </p>
141
+ </Tooltip.Content>
142
+ </Tooltip>
143
+ }
144
+ />
123
145
  </Accordion.Section>
124
146
 
125
147
  <Accordion.Section
@@ -431,6 +453,18 @@ const EditorPanel = memo(props => {
431
453
  />
432
454
  </Accordion.Section>
433
455
  )}
456
+ <Accordion.Section title='Markup Variables'>
457
+ <PanelMarkup
458
+ name='Markup Variables'
459
+ markupVariables={config.markupVariables || []}
460
+ data={data}
461
+ enableMarkupVariables={config.enableMarkupVariables || false}
462
+ onMarkupVariablesChange={variables => updateField(null, null, 'markupVariables', variables)}
463
+ onToggleEnable={enabled => updateField(null, null, 'enableMarkupVariables', enabled)}
464
+ withAccordion={false}
465
+ dataMetadata={config.dataMetadata}
466
+ />
467
+ </Accordion.Section>
434
468
  </Accordion>
435
469
  )
436
470
 
@@ -53,5 +53,7 @@ export default {
53
53
  'theme-green': '#4b830d',
54
54
  'theme-amber': '#fbab18'
55
55
  }
56
- }
56
+ },
57
+ markupVariables: [],
58
+ enableMarkupVariables: false
57
59
  }
@@ -1,16 +1,9 @@
1
- @import '@cdc/core/styles/accessibility';
1
+ @import '@cdc/core/styles/utils/accessibility';
2
2
  @import 'waffle-chart';
3
3
 
4
- .cdc-open-viz-module.type-waffle-chart {
5
- .cove-component__content:not(.component--has-background, .component--hideBackgroundColor) {
4
+ .cove-visualization.type-waffle-chart {
5
+ .cove-visualization__body:not(.component--has-background, .component--hide-background-color) {
6
6
  background-color: white;
7
7
  }
8
8
 
9
- &.is-editor .cove-component {
10
- padding-left: 350px;
11
- }
12
-
13
- &.is-editor .cove-editor__content .cove-component {
14
- padding-left: 0px;
15
- }
16
9
  }