@cdc/core 1.1.4 → 4.22.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.
- package/LICENSE +201 -0
- package/README.md +1 -1
- package/assets/filtered-text.svg +1 -0
- package/assets/icon-caret-down.svg +3 -0
- package/assets/icon-caret-filled-down.svg +3 -0
- package/assets/icon-caret-filled-up.svg +3 -0
- package/assets/icon-caret-up.svg +3 -0
- package/assets/icon-chart-bar-paired.svg +15 -0
- package/assets/icon-chart-bar-stacked.svg +10 -0
- package/assets/icon-chart-bar.svg +3 -0
- package/assets/icon-chart-line.svg +3 -0
- package/assets/icon-chart-pie.svg +3 -0
- package/assets/icon-check.svg +3 -0
- package/assets/icon-close.svg +3 -1
- package/assets/icon-code.svg +2 -2
- package/assets/icon-dashboard.svg +34 -0
- package/assets/icon-databite.svg +3 -0
- package/assets/icon-edit.svg +3 -0
- package/assets/icon-file-upload.svg +3 -0
- package/assets/icon-filter-bars.svg +5 -0
- package/assets/icon-gear.svg +6 -0
- package/assets/icon-grid.svg +2 -3
- package/assets/icon-info.svg +1 -1
- package/assets/icon-link.svg +3 -0
- package/assets/{alabama-graphic.svg → icon-map-alabama.svg} +2 -2
- package/assets/icon-map-usa.svg +3 -0
- package/assets/icon-map-world.svg +3 -0
- package/assets/icon-minus.svg +3 -0
- package/assets/icon-move.svg +8 -0
- package/assets/icon-plus.svg +3 -0
- package/assets/icon-question-circle.svg +3 -0
- package/assets/icon-tools.svg +8 -0
- package/assets/icon-upload.svg +3 -0
- package/assets/icon-warning-circle.svg +3 -0
- package/assets/{icon-warning.svg → icon-warning-triangle.svg} +1 -1
- package/components/AdvancedEditor.js +52 -67
- package/components/{ErrorBoundary.js → ErrorBoundary.jsx} +10 -11
- package/components/GlobalContext.jsx +2 -6
- package/components/{LegendCircle.js → LegendCircle.jsx} +4 -4
- package/components/Loading.jsx +17 -0
- package/components/Waiting.jsx +20 -0
- package/components/elements/Button.jsx +111 -3
- package/components/elements/Card.jsx +13 -0
- package/components/inputs/InputCheckbox.jsx +43 -38
- package/components/inputs/InputGroup.jsx +71 -0
- package/components/inputs/InputSelect.jsx +28 -24
- package/components/inputs/InputText.jsx +20 -37
- package/components/inputs/InputToggle.jsx +39 -43
- package/components/managers/DataDesigner.jsx +194 -0
- package/components/ui/Accordion.jsx +18 -30
- package/components/ui/Icon.jsx +59 -20
- package/components/ui/LoadSpin.jsx +19 -0
- package/components/ui/Modal.jsx +40 -39
- package/components/ui/Overlay.jsx +15 -24
- package/components/ui/OverlayFrame.jsx +1 -5
- package/components/ui/Tooltip.jsx +20 -31
- package/data/colorPalettes.js +36 -227
- package/data/dataDesignerTables.js +148 -0
- package/data/themes.js +13 -13
- package/helpers/DataTransform.js +162 -0
- package/helpers/cacheBustingString.js +5 -0
- package/helpers/events.js +5 -6
- package/helpers/fetchRemoteData.js +41 -0
- package/helpers/getViewport.js +15 -15
- package/helpers/numberFromString.js +7 -7
- package/helpers/updatePaletteNames.js +15 -17
- package/helpers/useDataVizClasses.js +40 -0
- package/helpers/validateFipsCodeLength.js +41 -56
- package/package.json +3 -2
- package/styles/_data-table.scss +45 -40
- package/styles/_global.scss +41 -22
- package/styles/_mixins.scss +12 -12
- package/styles/_reset.scss +95 -16
- package/styles/_variables.scss +5 -5
- package/styles/base.scss +104 -37
- package/styles/heading-colors.scss +6 -2
- package/styles/loading.scss +62 -60
- package/styles/v2/base/_file-selector.scss +20 -0
- package/styles/v2/base/_general.scss +9 -22
- package/styles/v2/base/_heading.scss +20 -0
- package/styles/v2/base/_reset.scss +4 -3
- package/styles/v2/base/index.scss +7 -3
- package/styles/v2/components/accordion.scss +13 -13
- package/styles/v2/components/button.scss +29 -68
- package/styles/v2/components/card.scss +7 -0
- package/styles/v2/components/data-designer.scss +101 -0
- package/styles/v2/components/editor.scss +52 -50
- package/styles/v2/components/guidance-block.scss +74 -0
- package/styles/v2/components/icon.scss +0 -4
- package/styles/v2/components/input/_input-check-radio.scss +97 -0
- package/styles/v2/components/input/_input-group.scss +74 -0
- package/styles/v2/components/input/_input-slider.scss +183 -0
- package/styles/v2/components/input/_input.scss +66 -0
- package/styles/v2/components/input/index.scss +7 -0
- package/styles/v2/components/loadspin.scss +100 -0
- package/styles/v2/components/modal.scss +15 -8
- package/styles/v2/components/overlay.scss +6 -4
- package/styles/v2/layout/_alert.scss +15 -14
- package/styles/v2/layout/_component.scss +8 -1
- package/styles/v2/layout/_data-table.scss +78 -156
- package/styles/v2/layout/_progression.scss +12 -8
- package/styles/v2/layout/index.scss +5 -7
- package/styles/v2/main.scss +52 -2
- package/styles/v2/themes/_color-definitions.scss +103 -20
- package/styles/v2/themes/index.scss +1 -1
- package/styles/v2/utils/_align.scss +17 -0
- package/styles/v2/utils/_animations.scss +2 -2
- package/styles/v2/utils/_breakpoints.scss +59 -0
- package/styles/v2/utils/_grid.scss +47 -0
- package/styles/v2/utils/_mixins.scss +0 -16
- package/styles/v2/utils/_spacers.scss +31 -0
- package/styles/v2/utils/_variables.scss +7 -0
- package/styles/v2/utils/index.scss +9 -4
- package/styles/waiting.scss +22 -23
- package/assets/asc.svg +0 -1
- package/assets/chart-bar-solid.svg +0 -1
- package/assets/chart-line-solid.svg +0 -1
- package/assets/chart-pie-solid.svg +0 -1
- package/assets/check.svg +0 -3
- package/assets/dashboard.svg +0 -11
- package/assets/data-bite-graphic.svg +0 -3
- package/assets/desc.svg +0 -1
- package/assets/file-upload-solid.svg +0 -1
- package/assets/horizontal-stacked-bar.svg +0 -1
- package/assets/link.svg +0 -1
- package/assets/minus.svg +0 -1
- package/assets/paired-bar.svg +0 -11
- package/assets/plus.svg +0 -1
- package/assets/question-circle.svg +0 -1
- package/assets/upload-solid.svg +0 -1
- package/assets/usa-graphic.svg +0 -3
- package/assets/world-graphic.svg +0 -3
- package/components/DataTransform.js +0 -162
- package/components/Loading.js +0 -15
- package/components/Waiting.js +0 -11
- package/styles/v2/components/input.scss +0 -372
- package/styles/v2/layout/_header.scss +0 -13
- package/styles/v2/layout/_link.scss +0 -46
|
@@ -1,39 +1,25 @@
|
|
|
1
1
|
import React, { useState, useEffect, memo } from 'react'
|
|
2
2
|
import { useDebounce } from 'use-debounce'
|
|
3
3
|
|
|
4
|
-
import '../../styles/v2/components/input.scss'
|
|
4
|
+
import '../../styles/v2/components/input/index.scss'
|
|
5
5
|
|
|
6
|
-
const InputText = memo((
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
section = null,
|
|
10
|
-
subsection = null,
|
|
11
|
-
fieldName,
|
|
12
|
-
updateField,
|
|
13
|
-
value: stateValue,
|
|
14
|
-
type = 'input',
|
|
15
|
-
tooltip,
|
|
16
|
-
i = null, min = null, max = null,
|
|
17
|
-
...attributes
|
|
18
|
-
}
|
|
19
|
-
) => {
|
|
20
|
-
|
|
21
|
-
const [ value, setValue ] = useState(stateValue)
|
|
22
|
-
const [ debouncedValue ] = useDebounce(value, 500)
|
|
6
|
+
const InputText = memo(({ label, section = null, subsection = null, fieldName, updateField, value: stateValue, type = 'input', tooltip, placeholder, i = null, min = null, max = null, className, ...attributes }) => {
|
|
7
|
+
const [value, setValue] = useState(stateValue)
|
|
8
|
+
const [debouncedValue] = useDebounce(value, 500)
|
|
23
9
|
|
|
24
10
|
useEffect(() => {
|
|
25
11
|
if ('string' === typeof debouncedValue && stateValue !== debouncedValue && updateField) {
|
|
26
12
|
updateField(section, subsection, fieldName, debouncedValue, i)
|
|
27
13
|
}
|
|
28
|
-
}, [
|
|
14
|
+
}, [debouncedValue, section, subsection, fieldName, i, stateValue, updateField])
|
|
29
15
|
|
|
30
16
|
let name = subsection ? `${section}-${subsection}-${fieldName}` : `${section}-${subsection}-${fieldName}`
|
|
31
17
|
|
|
32
|
-
const onChange =
|
|
18
|
+
const onChange = e => {
|
|
33
19
|
if ('number' !== type || min === null) {
|
|
34
20
|
setValue(e.target.value)
|
|
35
21
|
} else {
|
|
36
|
-
if (!e.target.value || (parseFloat(min) <= parseFloat(e.target.value) & parseFloat(max) >= parseFloat(e.target.value))) {
|
|
22
|
+
if (!e.target.value || (parseFloat(min) <= parseFloat(e.target.value)) & (parseFloat(max) >= parseFloat(e.target.value))) {
|
|
37
23
|
setValue(e.target.value)
|
|
38
24
|
} else {
|
|
39
25
|
setValue(min.toString())
|
|
@@ -41,27 +27,24 @@ const InputText = memo((
|
|
|
41
27
|
}
|
|
42
28
|
}
|
|
43
29
|
|
|
44
|
-
let
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
30
|
+
let inputAttrs = {
|
|
31
|
+
className: `cove-input${className ? ' ' + className : ''}`,
|
|
32
|
+
type,
|
|
33
|
+
name,
|
|
34
|
+
placeholder,
|
|
35
|
+
onChange,
|
|
36
|
+
value,
|
|
37
|
+
...attributes
|
|
50
38
|
}
|
|
51
39
|
|
|
52
|
-
|
|
53
|
-
formElement = <input type="number" name={name} onChange={onChange} {...attributes} value={value}/>
|
|
54
|
-
}
|
|
40
|
+
let formElement = 'textarea' === type ? <textarea {...inputAttrs} /> : <input {...inputAttrs} />
|
|
55
41
|
|
|
56
42
|
return (
|
|
57
|
-
|
|
58
|
-
{label &&
|
|
59
|
-
|
|
60
|
-
<label>{label}{tooltip}</label>
|
|
61
|
-
</>
|
|
62
|
-
}
|
|
43
|
+
<>
|
|
44
|
+
{label && <label className='cove-input__label'>{label}</label>}
|
|
45
|
+
{tooltip}
|
|
63
46
|
{formElement}
|
|
64
|
-
|
|
47
|
+
</>
|
|
65
48
|
)
|
|
66
49
|
})
|
|
67
50
|
|
|
@@ -1,80 +1,76 @@
|
|
|
1
1
|
import React, { useState, useEffect } from 'react'
|
|
2
2
|
import PropTypes from 'prop-types'
|
|
3
3
|
|
|
4
|
-
import '../../styles/v2/components/input.scss'
|
|
4
|
+
import '../../styles/v2/components/input/index.scss'
|
|
5
5
|
|
|
6
|
-
const
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
value: stateValue,
|
|
6
|
+
const InputSlider = ({
|
|
7
|
+
label,
|
|
8
|
+
sliderType = 'flat',
|
|
9
|
+
size = 'medium',
|
|
10
|
+
activeColor = null,
|
|
11
|
+
section = null,
|
|
12
|
+
subsection = null,
|
|
13
|
+
fieldName,
|
|
14
|
+
updateField,
|
|
15
|
+
value: stateValue,
|
|
17
16
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
const [
|
|
17
|
+
i = null,
|
|
18
|
+
min = null,
|
|
19
|
+
max = null,
|
|
20
|
+
...attributes
|
|
21
|
+
}) => {
|
|
22
|
+
const [value, setValue] = useState(stateValue)
|
|
24
23
|
|
|
25
24
|
let name = () => {
|
|
26
25
|
let str = ''
|
|
27
|
-
if (section)
|
|
28
|
-
|
|
29
|
-
if (
|
|
30
|
-
str += subsection + '-'
|
|
31
|
-
if (fieldName)
|
|
32
|
-
str += fieldName
|
|
26
|
+
if (section) str += section + '-'
|
|
27
|
+
if (subsection) str += subsection + '-'
|
|
28
|
+
if (fieldName) str += fieldName
|
|
33
29
|
return str
|
|
34
30
|
}
|
|
35
31
|
|
|
36
|
-
const
|
|
32
|
+
const sliderTypeClass = () => {
|
|
37
33
|
const typeArr = {
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
'3d': '
|
|
34
|
+
flat: ' slider--flat',
|
|
35
|
+
block: ' slider--block',
|
|
36
|
+
pill: ' slider--pill',
|
|
37
|
+
'3d': ' slider--3d'
|
|
42
38
|
}
|
|
43
|
-
return typeArr[
|
|
39
|
+
return typeArr[sliderType] || ''
|
|
44
40
|
}
|
|
45
41
|
|
|
46
42
|
useEffect(() => {
|
|
47
43
|
if (stateValue !== undefined && stateValue !== value) {
|
|
48
44
|
setValue(stateValue)
|
|
49
45
|
}
|
|
50
|
-
}, [
|
|
46
|
+
}, [stateValue])
|
|
51
47
|
|
|
52
48
|
useEffect(() => {
|
|
53
49
|
if (stateValue !== undefined && stateValue !== value && updateField) {
|
|
54
50
|
updateField(section, subsection, fieldName, value, i)
|
|
55
51
|
}
|
|
56
|
-
}, [
|
|
52
|
+
}, [value])
|
|
57
53
|
|
|
58
54
|
return (
|
|
59
|
-
<div className=
|
|
55
|
+
<div className='input-group'>
|
|
60
56
|
{label && <label>{label}</label>}
|
|
61
|
-
<div className={'cove-
|
|
62
|
-
<div className=
|
|
63
|
-
<div className=
|
|
64
|
-
<input className=
|
|
57
|
+
<div className={'cove-input__slider' + (size === 'small' ? '--small' : size === 'large' ? '--large' : '') + sliderTypeClass() + (value ? ' active' : '')} onClick={() => setValue(!value)}>
|
|
58
|
+
<div className='cove-input__slider-button' />
|
|
59
|
+
<div className='cove-input__slider-track' style={value && activeColor ? { backgroundColor: activeColor } : null} />
|
|
60
|
+
<input className='cove-input--hidden' type='checkbox' name={name()} checked={value || false} readOnly />
|
|
65
61
|
</div>
|
|
66
62
|
</div>
|
|
67
63
|
)
|
|
68
64
|
}
|
|
69
65
|
|
|
70
|
-
|
|
66
|
+
InputSlider.propTypes = {
|
|
71
67
|
/** Add label to the input field */
|
|
72
68
|
label: PropTypes.string,
|
|
73
|
-
/** Select the preferred display style of the
|
|
74
|
-
|
|
75
|
-
/** Select the preferred size of the
|
|
69
|
+
/** Select the preferred display style of the slider */
|
|
70
|
+
sliderType: PropTypes.oneOf(['flat', 'block', 'pill', '3d']),
|
|
71
|
+
/** Select the preferred size of the slider */
|
|
76
72
|
size: PropTypes.oneOf(['small', 'medium', 'large']),
|
|
77
|
-
/** Select the preferred color for the
|
|
73
|
+
/** Select the preferred color for the slider when active */
|
|
78
74
|
activeColor: PropTypes.string,
|
|
79
75
|
/** Parent key value of nested target config option
|
|
80
76
|
*
|
|
@@ -92,4 +88,4 @@ InputToggle.propTypes = {
|
|
|
92
88
|
stateValue: PropTypes.object
|
|
93
89
|
}
|
|
94
90
|
|
|
95
|
-
export default
|
|
91
|
+
export default InputSlider
|
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
import React from 'react'
|
|
2
|
+
|
|
3
|
+
import Button from '../elements/Button'
|
|
4
|
+
import Card from '../elements/Card'
|
|
5
|
+
|
|
6
|
+
import { DATA_TABLE_VERTICAL, DATA_TABLE_HORIZONTAL, DATA_TABLE_SINGLE_ROW, DATA_TABLE_MULTI_ROW } from '../../data/dataDesignerTables'
|
|
7
|
+
import '../../styles/v2/components/data-designer.scss'
|
|
8
|
+
|
|
9
|
+
const DataDesigner = props => {
|
|
10
|
+
const { configureData, updateDescriptionProp, visualizationKey, dataKey } = props
|
|
11
|
+
|
|
12
|
+
return (
|
|
13
|
+
<div className='cove-data-designer__container'>
|
|
14
|
+
<div className='mb-2'>
|
|
15
|
+
<div className='cove-heading--3 fw-bold mb-1'>Describe Data</div>
|
|
16
|
+
<div className='cove-heading--3 fw-normal mb-1'>Data Orientation</div>
|
|
17
|
+
<div className='grid grid-gap-2 mb-4'>
|
|
18
|
+
<div className='column'>
|
|
19
|
+
<button
|
|
20
|
+
className={'cove-data-designer__button' + (configureData.dataDescription && configureData.dataDescription.horizontal === false ? ' active' : '')}
|
|
21
|
+
onClick={() => {
|
|
22
|
+
updateDescriptionProp(visualizationKey, dataKey, 'horizontal', false)
|
|
23
|
+
}}
|
|
24
|
+
>
|
|
25
|
+
<Card>
|
|
26
|
+
<strong className='cove-heading--3'>Vertical</strong>
|
|
27
|
+
<p className='mb-1'>
|
|
28
|
+
Values for map geography or chart date/category axis are contained in a single <em>column</em>.
|
|
29
|
+
</p>
|
|
30
|
+
{DATA_TABLE_VERTICAL}
|
|
31
|
+
</Card>
|
|
32
|
+
</button>
|
|
33
|
+
</div>
|
|
34
|
+
<div className='column'>
|
|
35
|
+
<button
|
|
36
|
+
className={'cove-data-designer__button' + (configureData.dataDescription && configureData.dataDescription.horizontal === true ? ' active' : '')}
|
|
37
|
+
onClick={() => {
|
|
38
|
+
updateDescriptionProp(visualizationKey, dataKey, 'horizontal', true)
|
|
39
|
+
}}
|
|
40
|
+
>
|
|
41
|
+
<Card>
|
|
42
|
+
<strong className='cove-heading--3'>Horizontal</strong>
|
|
43
|
+
<p className='mb-1'>
|
|
44
|
+
Values for map geography or chart date/category axis are contained in a single <em>row</em>
|
|
45
|
+
</p>
|
|
46
|
+
{DATA_TABLE_HORIZONTAL}
|
|
47
|
+
</Card>
|
|
48
|
+
</button>
|
|
49
|
+
</div>
|
|
50
|
+
</div>
|
|
51
|
+
</div>
|
|
52
|
+
{configureData.dataDescription && (
|
|
53
|
+
<>
|
|
54
|
+
<div className='mb-2'>
|
|
55
|
+
<div className='mb-1'>Are there multiple series represented in your data?</div>
|
|
56
|
+
<div>
|
|
57
|
+
<Button
|
|
58
|
+
style={{ backgroundColor: '#00345d' }}
|
|
59
|
+
hoverStyle={{ backgroundColor: '#015daa' }}
|
|
60
|
+
className='mr-1'
|
|
61
|
+
onClick={() => {
|
|
62
|
+
updateDescriptionProp(visualizationKey, dataKey, 'series', true)
|
|
63
|
+
}}
|
|
64
|
+
active={configureData.dataDescription.series === true}
|
|
65
|
+
>
|
|
66
|
+
Yes
|
|
67
|
+
</Button>
|
|
68
|
+
<Button
|
|
69
|
+
style={{ backgroundColor: '#00345d' }}
|
|
70
|
+
hoverStyle={{ backgroundColor: '#015daa' }}
|
|
71
|
+
onClick={() => {
|
|
72
|
+
updateDescriptionProp(visualizationKey, dataKey, 'series', false)
|
|
73
|
+
}}
|
|
74
|
+
active={configureData.dataDescription.series === false}
|
|
75
|
+
>
|
|
76
|
+
No
|
|
77
|
+
</Button>
|
|
78
|
+
</div>
|
|
79
|
+
</div>
|
|
80
|
+
{configureData.dataDescription.horizontal === true && configureData.dataDescription.series === true && (
|
|
81
|
+
<div className='mb-2'>
|
|
82
|
+
<div className='mb-1'>Which property in the dataset represents which series the row is describing?</div>
|
|
83
|
+
<select
|
|
84
|
+
onChange={e => {
|
|
85
|
+
updateDescriptionProp(visualizationKey, dataKey, 'seriesKey', e.target.value)
|
|
86
|
+
}}
|
|
87
|
+
defaultValue={configureData.dataDescription.seriesKey}
|
|
88
|
+
>
|
|
89
|
+
<option value=''>Choose an option</option>
|
|
90
|
+
{Object.keys(configureData.data[0]).map((value, index) => (
|
|
91
|
+
<option value={value} key={index}>
|
|
92
|
+
{value}
|
|
93
|
+
</option>
|
|
94
|
+
))}
|
|
95
|
+
</select>
|
|
96
|
+
</div>
|
|
97
|
+
)}
|
|
98
|
+
{configureData.dataDescription.horizontal === false && configureData.dataDescription.series === true && (
|
|
99
|
+
<>
|
|
100
|
+
<div className='mb-2'>
|
|
101
|
+
<div className='mb-1'>Are the series values in your data represented in a single row, or across multiple rows?</div>
|
|
102
|
+
<div className='grid grid-gap-2 mb-4'>
|
|
103
|
+
<div className='column'>
|
|
104
|
+
<button
|
|
105
|
+
className={'cove-data-designer__button' + (configureData.dataDescription.singleRow === true ? ' active' : '')}
|
|
106
|
+
onClick={() => {
|
|
107
|
+
updateDescriptionProp(visualizationKey, dataKey, 'singleRow', true)
|
|
108
|
+
}}
|
|
109
|
+
>
|
|
110
|
+
<Card>
|
|
111
|
+
<strong className='cove-heading--3'>Single Row</strong>
|
|
112
|
+
<p className='mb-1'>Each row contains the data for an individual series in itself.</p>
|
|
113
|
+
{DATA_TABLE_SINGLE_ROW}
|
|
114
|
+
</Card>
|
|
115
|
+
</button>
|
|
116
|
+
</div>
|
|
117
|
+
<div className='column'>
|
|
118
|
+
<button
|
|
119
|
+
className={'cove-data-designer__button' + (configureData.dataDescription.singleRow === false ? ' active' : '')}
|
|
120
|
+
onClick={() => {
|
|
121
|
+
updateDescriptionProp(visualizationKey, dataKey, 'singleRow', false)
|
|
122
|
+
}}
|
|
123
|
+
>
|
|
124
|
+
<Card>
|
|
125
|
+
<strong className='cove-heading--3'>Multiple Rows</strong>
|
|
126
|
+
<p className='mb-1'>Each series data is broken out into multiple rows.</p>
|
|
127
|
+
{DATA_TABLE_MULTI_ROW}
|
|
128
|
+
</Card>
|
|
129
|
+
</button>
|
|
130
|
+
</div>
|
|
131
|
+
</div>
|
|
132
|
+
</div>
|
|
133
|
+
{configureData.dataDescription.singleRow === false && (
|
|
134
|
+
<>
|
|
135
|
+
<div className='mb-2'>
|
|
136
|
+
<div className='mb-1'>Which property in the dataset represents which series the row is describing?</div>
|
|
137
|
+
<select
|
|
138
|
+
onChange={e => {
|
|
139
|
+
updateDescriptionProp(visualizationKey, dataKey, 'seriesKey', e.target.value)
|
|
140
|
+
}}
|
|
141
|
+
defaultValue={configureData.dataDescription.seriesKey}
|
|
142
|
+
>
|
|
143
|
+
<option value=''>Choose an option</option>
|
|
144
|
+
{Object.keys(configureData.data[0]).map((value, index) => (
|
|
145
|
+
<option value={value} key={index}>
|
|
146
|
+
{value}
|
|
147
|
+
</option>
|
|
148
|
+
))}
|
|
149
|
+
</select>
|
|
150
|
+
</div>
|
|
151
|
+
<div className='mb-2'>
|
|
152
|
+
<div className='mb-1'>Which property in the dataset represents the values for the category/date axis or map geography?</div>
|
|
153
|
+
<select
|
|
154
|
+
onChange={e => {
|
|
155
|
+
updateDescriptionProp(visualizationKey, dataKey, 'xKey', e.target.value)
|
|
156
|
+
}}
|
|
157
|
+
defaultValue={configureData.dataDescription.xKey}
|
|
158
|
+
>
|
|
159
|
+
<option value=''>Choose an option</option>
|
|
160
|
+
{Object.keys(configureData.data[0]).map((value, index) => (
|
|
161
|
+
<option value={value} key={index}>
|
|
162
|
+
{value}
|
|
163
|
+
</option>
|
|
164
|
+
))}
|
|
165
|
+
</select>
|
|
166
|
+
</div>
|
|
167
|
+
<div className='mb-2'>
|
|
168
|
+
<div className='mb-1'>Which property in the dataset represents the numeric value?</div>
|
|
169
|
+
<select
|
|
170
|
+
onChange={e => {
|
|
171
|
+
updateDescriptionProp(visualizationKey, dataKey, 'valueKey', e.target.value)
|
|
172
|
+
}}
|
|
173
|
+
defaultValue={configureData.dataDescription.valueKey}
|
|
174
|
+
>
|
|
175
|
+
<option value=''>Choose an option</option>
|
|
176
|
+
{Object.keys(configureData.data[0]).map((value, index) => (
|
|
177
|
+
<option value={value} key={index}>
|
|
178
|
+
{value}
|
|
179
|
+
</option>
|
|
180
|
+
))}
|
|
181
|
+
</select>
|
|
182
|
+
</div>
|
|
183
|
+
</>
|
|
184
|
+
)}
|
|
185
|
+
</>
|
|
186
|
+
)}
|
|
187
|
+
</>
|
|
188
|
+
)}
|
|
189
|
+
{configureData.dataDescription && configureData.formattedData && <div>Data configured successfully</div>}
|
|
190
|
+
</div>
|
|
191
|
+
)
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
export default DataDesigner
|
|
@@ -1,11 +1,5 @@
|
|
|
1
1
|
import React, { Children } from 'react'
|
|
2
|
-
import {
|
|
3
|
-
Accordion as AccordionComponent,
|
|
4
|
-
AccordionItem,
|
|
5
|
-
AccordionItemHeading,
|
|
6
|
-
AccordionItemPanel,
|
|
7
|
-
AccordionItemButton,
|
|
8
|
-
} from 'react-accessible-accordion'
|
|
2
|
+
import { Accordion as AccordionComponent, AccordionItem, AccordionItemHeading, AccordionItemPanel, AccordionItemButton } from 'react-accessible-accordion'
|
|
9
3
|
import PropTypes from 'prop-types'
|
|
10
4
|
|
|
11
5
|
import Icon from './Icon'
|
|
@@ -16,37 +10,31 @@ import '../../styles/v2/components/accordion.scss'
|
|
|
16
10
|
//Define the "slots" to be populated by subcomponents
|
|
17
11
|
const AccordionSection = () => null
|
|
18
12
|
|
|
19
|
-
const Accordion = ({children}) => {
|
|
13
|
+
const Accordion = ({ children }) => {
|
|
20
14
|
const childNodes = Children.toArray(children)
|
|
21
15
|
const accordionSections = childNodes.filter(child => child?.type === AccordionSection)
|
|
22
16
|
|
|
23
17
|
return (
|
|
24
18
|
<AccordionComponent allowZeroExpanded={true}>
|
|
25
|
-
{accordionSections &&
|
|
26
|
-
|
|
27
|
-
<
|
|
28
|
-
<
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
? (
|
|
32
|
-
<Tooltip position=
|
|
19
|
+
{accordionSections &&
|
|
20
|
+
accordionSections.map((section, index) => (
|
|
21
|
+
<AccordionItem className='cove-accordion__item' key={index}>
|
|
22
|
+
<AccordionItemHeading className='cove-accordion__heading'>
|
|
23
|
+
<AccordionItemButton className='cove-accordion__button'>
|
|
24
|
+
{section.props.title}
|
|
25
|
+
{section.props.tooltipText ? (
|
|
26
|
+
<Tooltip position='bottom'>
|
|
33
27
|
<Tooltip.Target>
|
|
34
|
-
<Icon display=
|
|
28
|
+
<Icon display='question' size={14} />
|
|
35
29
|
</Tooltip.Target>
|
|
36
|
-
<Tooltip.Content>
|
|
37
|
-
{section.props.tooltipText}
|
|
38
|
-
</Tooltip.Content>
|
|
30
|
+
<Tooltip.Content>{section.props.tooltipText}</Tooltip.Content>
|
|
39
31
|
</Tooltip>
|
|
40
|
-
)
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
</
|
|
44
|
-
</
|
|
45
|
-
|
|
46
|
-
{section.props.children}
|
|
47
|
-
</AccordionItemPanel>
|
|
48
|
-
</AccordionItem>
|
|
49
|
-
))}
|
|
32
|
+
) : null}
|
|
33
|
+
</AccordionItemButton>
|
|
34
|
+
</AccordionItemHeading>
|
|
35
|
+
<AccordionItemPanel className='cove-accordion__panel'>{section.props.children}</AccordionItemPanel>
|
|
36
|
+
</AccordionItem>
|
|
37
|
+
))}
|
|
50
38
|
</AccordionComponent>
|
|
51
39
|
)
|
|
52
40
|
}
|
package/components/ui/Icon.jsx
CHANGED
|
@@ -1,24 +1,64 @@
|
|
|
1
1
|
import React from 'react'
|
|
2
2
|
import PropTypes from 'prop-types'
|
|
3
3
|
|
|
4
|
+
import iconCaretUp from '../../assets/icon-caret-up.svg'
|
|
5
|
+
import iconCaretDown from '../../assets/icon-caret-down.svg'
|
|
6
|
+
import iconCaretFilledUp from '../../assets/icon-caret-filled-up.svg'
|
|
7
|
+
import iconCaretFilledDown from '../../assets/icon-caret-filled-down.svg'
|
|
8
|
+
import iconChartBar from '../../assets/icon-chart-bar.svg'
|
|
9
|
+
import iconChartLine from '../../assets/icon-chart-line.svg'
|
|
10
|
+
import iconChartPie from '../../assets/icon-chart-pie.svg'
|
|
4
11
|
import iconClose from '../../assets/icon-close.svg'
|
|
5
|
-
import
|
|
6
|
-
import
|
|
7
|
-
import
|
|
8
|
-
import iconFileUpload from '../../assets/file-upload
|
|
9
|
-
import
|
|
12
|
+
import iconCode from '../../assets/icon-code.svg'
|
|
13
|
+
import iconDataBite from '../../assets/icon-databite.svg'
|
|
14
|
+
import iconEdit from '../../assets/icon-edit.svg'
|
|
15
|
+
import iconFileUpload from '../../assets/icon-file-upload.svg'
|
|
16
|
+
import iconFilterBars from '../../assets/icon-filter-bars.svg'
|
|
17
|
+
import iconGrid from '../../assets/icon-grid.svg'
|
|
10
18
|
import iconInfo from '../../assets/icon-info.svg'
|
|
19
|
+
import iconLink from '../../assets/icon-link.svg'
|
|
20
|
+
import iconMapAl from '../../assets/icon-map-alabama.svg'
|
|
21
|
+
import iconMapUsa from '../../assets/icon-map-usa.svg'
|
|
22
|
+
import iconMapWorld from '../../assets/icon-map-world.svg'
|
|
23
|
+
import iconMove from '../../assets/icon-move.svg'
|
|
24
|
+
import iconQuestion from '../../assets/icon-question-circle.svg'
|
|
25
|
+
import iconUpload from '../../assets/icon-upload.svg'
|
|
26
|
+
import iconWarningCircle from '../../assets/icon-warning-circle.svg'
|
|
27
|
+
import iconWarningTriangle from '../../assets/icon-warning-triangle.svg'
|
|
28
|
+
import iconGear from '../../assets/icon-gear.svg'
|
|
29
|
+
import iconTools from '../../assets/icon-tools.svg'
|
|
30
|
+
import iconText from '../../assets/filtered-text.svg'
|
|
11
31
|
|
|
12
32
|
import '../../styles/v2/components/icon.scss'
|
|
13
33
|
|
|
14
34
|
const iconHash = {
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
35
|
+
caretUp: iconCaretUp,
|
|
36
|
+
caretDown: iconCaretDown,
|
|
37
|
+
caretFilledUp: iconCaretFilledUp,
|
|
38
|
+
caretFilledDown: iconCaretFilledDown,
|
|
39
|
+
chartBar: iconChartBar,
|
|
40
|
+
chartLine: iconChartLine,
|
|
41
|
+
chartPie: iconChartPie,
|
|
42
|
+
close: iconClose,
|
|
43
|
+
code: iconCode,
|
|
44
|
+
databite: iconDataBite,
|
|
45
|
+
edit: iconEdit,
|
|
46
|
+
fileUpload: iconFileUpload,
|
|
47
|
+
filterBars: iconFilterBars,
|
|
48
|
+
grid: iconGrid,
|
|
49
|
+
info: iconInfo,
|
|
50
|
+
link: iconLink,
|
|
51
|
+
mapAl: iconMapAl,
|
|
52
|
+
mapUsa: iconMapUsa,
|
|
53
|
+
mapWorld: iconMapWorld,
|
|
54
|
+
move: iconMove,
|
|
55
|
+
question: iconQuestion,
|
|
56
|
+
upload: iconUpload,
|
|
57
|
+
warningCircle: iconWarningCircle,
|
|
58
|
+
warningTriangle: iconWarningTriangle,
|
|
59
|
+
gear: iconGear,
|
|
60
|
+
tools: iconTools,
|
|
61
|
+
'filtered-text': iconText
|
|
22
62
|
}
|
|
23
63
|
|
|
24
64
|
const Icon = ({ display = null, base, alt = '', size, color, style, ...attributes }) => {
|
|
@@ -35,14 +75,13 @@ const Icon = ({ display = null, base, alt = '', size, color, style, ...attribute
|
|
|
35
75
|
|
|
36
76
|
return (
|
|
37
77
|
<>
|
|
38
|
-
{base
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
}
|
|
78
|
+
{base ? (
|
|
79
|
+
<IconObj title={alt} />
|
|
80
|
+
) : (
|
|
81
|
+
<span className={`cove-icon${attributes.className ? ' ' + attributes.className : ''}`} style={styles} {...filteredAttrs}>
|
|
82
|
+
<IconObj title={alt} />
|
|
83
|
+
</span>
|
|
84
|
+
)}
|
|
46
85
|
</>
|
|
47
86
|
)
|
|
48
87
|
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import React from 'react'
|
|
2
|
+
import '../../styles/v2/components/loadspin.scss'
|
|
3
|
+
|
|
4
|
+
const LoadSpin = ({ color = '#fff', opacity = 100, size = 100, className }) => {
|
|
5
|
+
const n = 8
|
|
6
|
+
return (
|
|
7
|
+
<>
|
|
8
|
+
<div className={`cove-loadspin${className ? ' ' + className : ''}`} style={{ width: size, height: size }}>
|
|
9
|
+
<div className='cove-loadspin__roller' style={{ opacity: opacity / 100, transform: `scale(${size / 80})` }}>
|
|
10
|
+
{[...Array(n)].map((elem, index) => (
|
|
11
|
+
<div key={index} style={{ backgroundColor: color }} />
|
|
12
|
+
))}
|
|
13
|
+
</div>
|
|
14
|
+
</div>
|
|
15
|
+
</>
|
|
16
|
+
)
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export default LoadSpin
|