@cdc/data-bite 4.25.8 → 4.25.11

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.
@@ -1,35 +1,59 @@
1
- import type { Meta, StoryObj } from '@storybook/react'
2
- import DataBite from '../CdcDataBite'
3
- import { Config } from '../types/Config'
4
-
5
- const meta: Meta<typeof DataBite> = {
6
- title: 'Components/Templates/Data Bite',
7
- component: DataBite
8
- }
9
-
10
- type Story = StoryObj<typeof DataBite>
11
-
12
- export const Data_Bite_Circle_Average: Story = {
13
- args: {
14
- configUrl: 'https://www.cdc.gov/wcms/4.0/cdc-wp/data-presentation/examples/Data_Bite_Circle_Average.json'
15
- }
16
- }
17
-
18
- export const Data_Bite_Text_Max_Pic: Story = {
19
- args: {
20
- configUrl: 'https://www.cdc.gov/wcms/4.0/cdc-wp/data-presentation/examples/Data_Bite_Text_Max_Pic.json'
21
- }
22
- }
23
-
24
- export const Data_Bite_Circle_Sum: Story = {
25
- args: {
26
- configUrl: 'https://www.cdc.gov/wcms/4.0/cdc-wp/data-presentation/examples/Data_Bite_Circle_Sum.json'
27
- }
28
- }
29
- export const Data_Bite_Text_Average_Pic: Story = {
30
- args: {
31
- configUrl: 'https://www.cdc.gov/wcms/4.0/cdc-wp/data-presentation/examples/Data_Bite_Text_Average_Pic.json'
32
- }
33
- }
34
-
35
- export default meta
1
+ import type { Meta, StoryObj } from '@storybook/react-vite'
2
+ import DataBite from '../CdcDataBite'
3
+
4
+ const meta: Meta<typeof DataBite> = {
5
+ title: 'Components/Templates/Data Bite',
6
+ component: DataBite,
7
+ parameters: {
8
+ docs: {
9
+ description: {
10
+ component:
11
+ 'Data Bite component for displaying key statistics and metrics. For comprehensive editor testing, see the "Editor Tests" section below.'
12
+ }
13
+ }
14
+ }
15
+ }
16
+
17
+ export default meta
18
+ type Story = StoryObj<typeof DataBite>
19
+
20
+ // Gallery stories for visual documentation
21
+ export const Data_Bite_Circle_Average: Story = {
22
+ args: {
23
+ configUrl: 'https://www.cdc.gov/wcms/4.0/cdc-wp/data-presentation/examples/Data_Bite_Circle_Average.json'
24
+ }
25
+ }
26
+
27
+ export const Data_Bite_Text_Max_Pic: Story = {
28
+ args: {
29
+ configUrl: 'https://www.cdc.gov/wcms/4.0/cdc-wp/data-presentation/examples/Data_Bite_Text_Max_Pic.json'
30
+ }
31
+ }
32
+
33
+ export const Data_Bite_Circle_Sum: Story = {
34
+ args: {
35
+ configUrl: 'https://www.cdc.gov/wcms/4.0/cdc-wp/data-presentation/examples/Data_Bite_Circle_Sum.json'
36
+ }
37
+ }
38
+
39
+ export const Data_Bite_Text_Average_Pic: Story = {
40
+ args: {
41
+ configUrl: 'https://www.cdc.gov/wcms/4.0/cdc-wp/data-presentation/examples/Data_Bite_Text_Average_Pic.json'
42
+ }
43
+ }
44
+
45
+ // Simple editor mode story for basic rendering
46
+ export const Editor_Mode_Basic: Story = {
47
+ args: {
48
+ configUrl: '/tests/fixtures/test-config.json',
49
+ isEditor: true
50
+ },
51
+ parameters: {
52
+ docs: {
53
+ description: {
54
+ story:
55
+ 'Basic editor mode rendering. For comprehensive editor testing with interactions, see "Data Bite/Editor Tests" stories.'
56
+ }
57
+ }
58
+ }
59
+ }
@@ -1,4 +1,6 @@
1
- import { memo, useContext, useEffect, useState } from 'react'
1
+ import React, { memo, useContext, useEffect, useState } from 'react'
2
+ import { DATA_FUNCTIONS, DATA_OPERATORS } from '@cdc/core/helpers/constants'
3
+ import cloneConfig from '@cdc/core/helpers/cloneConfig'
2
4
  import _ from 'lodash'
3
5
  import {
4
6
  Accordion,
@@ -8,16 +10,21 @@ import {
8
10
  AccordionItemPanel
9
11
  } from 'react-accessible-accordion'
10
12
 
13
+ import AdvancedEditor from '@cdc/core/components/AdvancedEditor'
11
14
  import Context from '../context'
12
15
  import WarningImage from '@cdc/core/assets/icon-warning-circle.svg'
13
16
  import Tooltip from '@cdc/core/components/ui/Tooltip'
14
17
  import Icon from '@cdc/core/components/ui/Icon'
15
18
  import ErrorBoundary from '@cdc/core/components/ErrorBoundary'
16
19
  import { updateFieldFactory } from '@cdc/core/helpers/updateFieldFactory'
17
- import { BITE_LOCATIONS, DATA_FUNCTIONS, IMAGE_POSITIONS, DATA_OPERATORS, HEADER_COLORS } from './../constants'
20
+ import { BITE_LOCATIONS, IMAGE_POSITIONS } from './../constants'
18
21
  import Layout from '@cdc/core/components/Layout'
19
22
  import { Select, TextField, CheckBox } from '@cdc/core/components/EditorPanel/Inputs'
20
23
  import Button from '@cdc/core/components/elements/Button'
24
+ import PanelMarkup from '@cdc/core/components/EditorPanel/components/PanelMarkup'
25
+ import { HeaderThemeSelector } from '@cdc/core/components/HeaderThemeSelector'
26
+
27
+ import '@cdc/core/styles/v2/components/editor.scss'
21
28
 
22
29
  const EditorPanel = memo(() => {
23
30
  const { config, updateConfig, loading, data, setParentConfig, isDashboard, isEditor } = useContext(Context)
@@ -51,7 +58,7 @@ const EditorPanel = memo(() => {
51
58
  }
52
59
 
53
60
  const convertStateToConfig = () => {
54
- let strippedState = _.cloneDeep(config)
61
+ let strippedState = cloneConfig(config)
55
62
  //if(false === missingRequiredSections()) {
56
63
  //strippedState.newViz
57
64
  //}
@@ -239,7 +246,8 @@ const EditorPanel = memo(() => {
239
246
  <Tooltip.Content>
240
247
  <p>
241
248
  Enter supporting text to display below the data visualization, if applicable. The following
242
- HTML tags are supported: strong, em, sup, and sub.
249
+ HTML tags are supported: strong, em, sup, and sub. You can also use markup variables like{' '}
250
+ {'{{variable-name}}'} to display dynamic data.
243
251
  </p>
244
252
  </Tooltip.Content>
245
253
  </Tooltip>
@@ -282,8 +290,8 @@ const EditorPanel = memo(() => {
282
290
  Array.isArray(DATA_FUNCTIONS)
283
291
  ? DATA_FUNCTIONS
284
292
  : DATA_FUNCTIONS
285
- ? Object.values(DATA_FUNCTIONS)
286
- : []
293
+ ? Object.values(DATA_FUNCTIONS)
294
+ : []
287
295
  }
288
296
  />
289
297
  </li>
@@ -405,7 +413,7 @@ const EditorPanel = memo(() => {
405
413
  <AccordionItemHeading>
406
414
  <AccordionItemButton>Visual</AccordionItemButton>
407
415
  </AccordionItemHeading>
408
- <AccordionItemPanel>
416
+ <AccordionItemPanel className='panel-visual accordion__panel accordion__panel--visual'>
409
417
  <TextField
410
418
  type='number'
411
419
  value={config.biteFontSize}
@@ -459,22 +467,11 @@ const EditorPanel = memo(() => {
459
467
  updateField={updateField}
460
468
  />
461
469
  </div>
462
- <label>
463
- <span className='edit-label'>Theme</span>
464
- <ul className='color-palette'>
465
- {HEADER_COLORS.map(palette => (
466
- <button
467
- title={palette}
468
- key={palette}
469
- onClick={e => {
470
- e.preventDefault()
471
- updateConfig({ ...config, theme: palette })
472
- }}
473
- className={config.theme === palette ? 'selected ' + palette : palette}
474
- />
475
- ))}
476
- </ul>
477
- </label>
470
+ <HeaderThemeSelector
471
+ selectedTheme={config.theme}
472
+ onThemeSelect={theme => updateConfig({ ...config, theme })}
473
+ label='Theme'
474
+ />
478
475
  </AccordionItemPanel>
479
476
  </AccordionItem>
480
477
 
@@ -568,19 +565,14 @@ const EditorPanel = memo(() => {
568
565
  <div className='accordion__panel-row align-center'>
569
566
  <div className='accordion__panel-col flex-auto'>If Value</div>
570
567
  <div className='accordion__panel-col flex-auto'>
571
- <select
568
+ <Select
569
+ label=''
572
570
  value={option.arguments[0]?.operator || ''}
571
+ options={DATA_OPERATORS}
573
572
  onChange={e => {
574
573
  updateDynamicImage('operator', index, 0, e.target.value)
575
574
  }}
576
- >
577
- <option value='' disabled />
578
- {DATA_OPERATORS.map((operator, index) => (
579
- <option value={operator} key={index}>
580
- {operator}
581
- </option>
582
- ))}
583
- </select>
575
+ />
584
576
  </div>
585
577
  <div className='accordion__panel-col flex-grow flex-shrink'>
586
578
  <input
@@ -595,9 +587,13 @@ const EditorPanel = memo(() => {
595
587
 
596
588
  <div className='accordion__panel-row mb-2 align-center'>
597
589
  <div className='accordion__panel-col flex-grow'>
598
- <select
599
- className='border-dashed text-center'
590
+ <Select
591
+ label=''
600
592
  value={option.secondArgument ? 'and' : 'then'}
593
+ options={[
594
+ { value: 'then', label: 'Then' },
595
+ { value: 'and', label: 'And' }
596
+ ]}
601
597
  onChange={e => {
602
598
  if ('then' === e.target.value) {
603
599
  updateDynamicImage('secondArgument', index, null, false)
@@ -607,10 +603,7 @@ const EditorPanel = memo(() => {
607
603
  updateDynamicImage('secondArgument', index, null, true)
608
604
  }
609
605
  }}
610
- >
611
- <option value={'then'}>Then</option>
612
- <option value={'and'}>And</option>
613
- </select>
606
+ />
614
607
  </div>
615
608
  </div>
616
609
 
@@ -619,19 +612,14 @@ const EditorPanel = memo(() => {
619
612
  <div className='accordion__panel-row align-center'>
620
613
  <div className='accordion__panel-col flex-auto'>If Value</div>
621
614
  <div className='accordion__panel-col flex-auto'>
622
- <select
615
+ <Select
616
+ label=''
623
617
  value={option.arguments[1]?.operator || ''}
618
+ options={DATA_OPERATORS}
624
619
  onChange={e => {
625
620
  setDynamicArgument(index, 'operator', e.target.value)
626
621
  }}
627
- >
628
- <option value='' disabled />
629
- {DATA_OPERATORS.map((operator, index) => (
630
- <option value={operator} key={index}>
631
- {operator}
632
- </option>
633
- ))}
634
- </select>
622
+ />
635
623
  </div>
636
624
  <div className='accordion__panel-col flex-grow flex-shrink'>
637
625
  <input
@@ -688,6 +676,24 @@ const EditorPanel = memo(() => {
688
676
  </AccordionItemPanel>
689
677
  </AccordionItem>
690
678
  )}
679
+
680
+ <AccordionItem>
681
+ <AccordionItemHeading>
682
+ <AccordionItemButton>Markup Variables</AccordionItemButton>
683
+ </AccordionItemHeading>
684
+ <AccordionItemPanel>
685
+ <PanelMarkup
686
+ name='Markup Variables'
687
+ markupVariables={config.markupVariables || []}
688
+ data={data}
689
+ enableMarkupVariables={config.enableMarkupVariables || false}
690
+ onMarkupVariablesChange={variables => updateField(null, null, 'markupVariables', variables)}
691
+ onToggleEnable={enabled => updateField(null, null, 'enableMarkupVariables', enabled)}
692
+ withAccordion={false}
693
+ />
694
+ </AccordionItemPanel>
695
+ </AccordionItem>
696
+ <AdvancedEditor loadConfig={updateConfig} config={config} convertStateToConfig={convertStateToConfig} />
691
697
  </Accordion>
692
698
  </form>
693
699
  </section>
package/src/constants.ts CHANGED
@@ -1,25 +1,3 @@
1
- export const DATA_FUNCTION_MAX = 'Max'
2
- export const DATA_FUNCTION_COUNT = 'Count'
3
- export const DATA_FUNCTION_MEAN = 'Mean (Average)'
4
- export const DATA_FUNCTION_MEDIAN = 'Median'
5
- export const DATA_FUNCTION_MIN = 'Min'
6
- export const DATA_FUNCTION_MODE = 'Mode'
7
- export const DATA_FUNCTION_RANGE = 'Range'
8
- export const DATA_FUNCTION_SUM = 'Sum'
9
- export const DATA_FUNCTIONS = [
10
- DATA_FUNCTION_COUNT,
11
- DATA_FUNCTION_MAX,
12
- DATA_FUNCTION_MEAN,
13
- DATA_FUNCTION_MEDIAN,
14
- DATA_FUNCTION_MIN,
15
- DATA_FUNCTION_MODE,
16
- DATA_FUNCTION_RANGE,
17
- DATA_FUNCTION_SUM
18
- ]
19
-
20
- export const BITE_LOCATION_TITLE = 'title'
21
- export const BITE_LOCATION_BODY = 'body'
22
- export const BITE_LOCATION_GRAPHIC = 'graphic'
23
1
  export const BITE_LOCATIONS = {
24
2
  graphic: 'Graphic',
25
3
  split: 'Split Graphic and Message',
@@ -34,33 +12,3 @@ export const IMAGE_POSITION_RIGHT = 'Right'
34
12
  export const IMAGE_POSITION_TOP = 'Top'
35
13
  export const IMAGE_POSITION_BOTTOM = 'Bottom'
36
14
  export const IMAGE_POSITIONS = [IMAGE_POSITION_LEFT, IMAGE_POSITION_RIGHT, IMAGE_POSITION_TOP, IMAGE_POSITION_BOTTOM]
37
-
38
- export const DATA_OPERATOR_LESS = '<'
39
- export const DATA_OPERATOR_GREATER = '>'
40
- export const DATA_OPERATOR_LESSEQUAL = '<='
41
- export const DATA_OPERATOR_GREATEREQUAL = '>='
42
- export const DATA_OPERATOR_EQUAL = '='
43
- export const DATA_OPERATOR_NOTEQUAL = '≠'
44
-
45
- export const DATA_OPERATORS = [
46
- DATA_OPERATOR_LESS,
47
- DATA_OPERATOR_GREATER,
48
- DATA_OPERATOR_LESSEQUAL,
49
- DATA_OPERATOR_GREATEREQUAL,
50
- DATA_OPERATOR_EQUAL,
51
- DATA_OPERATOR_NOTEQUAL
52
- ]
53
-
54
- export const HEADER_COLORS = [
55
- 'theme-blue',
56
- 'theme-purple',
57
- 'theme-brown',
58
- 'theme-teal',
59
- 'theme-pink',
60
- 'theme-orange',
61
- 'theme-slate',
62
- 'theme-indigo',
63
- 'theme-cyan',
64
- 'theme-green',
65
- 'theme-amber'
66
- ]
@@ -36,5 +36,7 @@ export default {
36
36
  },
37
37
  general: {
38
38
  isCompactStyle: false
39
- }
39
+ },
40
+ markupVariables: [],
41
+ enableMarkupVariables: false
40
42
  }
package/src/index.jsx CHANGED
@@ -2,7 +2,7 @@ import React from 'react'
2
2
  import ReactDOM from 'react-dom/client'
3
3
 
4
4
  import '@cdc/core/styles/cove-main.scss'
5
- import './coreStyles_databite.scss'
5
+ import '@cdc/core/components/EditorPanel/EditorPanel.styles.css'
6
6
 
7
7
  import CdcDataBite from './CdcDataBite'
8
8