@cdc/core 1.1.4 → 9.22.9
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/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 +1 -1
- package/components/{ErrorBoundary.js → ErrorBoundary.jsx} +0 -0
- package/components/{LegendCircle.js → LegendCircle.jsx} +0 -0
- package/components/{Loading.js → Loading.jsx} +0 -0
- package/components/{Waiting.js → Waiting.jsx} +0 -0
- package/components/elements/Button.jsx +122 -3
- package/components/elements/Card.jsx +13 -0
- package/components/inputs/InputCheckbox.jsx +11 -3
- package/components/inputs/InputGroup.jsx +50 -0
- package/components/inputs/InputSelect.jsx +2 -2
- package/components/inputs/InputText.jsx +17 -18
- package/components/inputs/InputToggle.jsx +18 -18
- package/components/managers/DataDesigner.jsx +171 -0
- package/components/ui/Icon.jsx +50 -12
- package/components/ui/LoadSpin.jsx +24 -0
- package/components/ui/Modal.jsx +7 -2
- package/components/ui/Overlay.jsx +3 -1
- package/components/ui/Tooltip.jsx +18 -9
- package/data/colorPalettes.js +170 -124
- package/data/dataDesignerTables.js +148 -0
- package/{components → helpers}/DataTransform.js +3 -3
- package/helpers/fetchRemoteData.js +43 -0
- package/package.json +3 -2
- package/styles/_data-table.scss +13 -13
- package/styles/_global.scss +14 -0
- package/styles/_reset.scss +11 -1
- package/styles/base.scss +17 -1
- 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 +2 -1
- package/styles/v2/base/index.scss +5 -1
- package/styles/v2/components/button.scss +27 -66
- package/styles/v2/components/card.scss +7 -0
- package/styles/v2/components/data-designer.scss +100 -0
- package/styles/v2/components/editor.scss +2 -1
- 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 +184 -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 +13 -6
- package/styles/v2/components/overlay.scss +2 -0
- package/styles/v2/layout/_alert.scss +11 -10
- package/styles/v2/layout/_component.scss +8 -1
- package/styles/v2/layout/_data-table.scss +71 -150
- package/styles/v2/layout/_progression.scss +4 -2
- package/styles/v2/layout/index.scss +0 -2
- package/styles/v2/main.scss +52 -2
- package/styles/v2/themes/_color-definitions.scss +31 -1
- package/styles/v2/utils/_align.scss +17 -0
- package/styles/v2/utils/_breakpoints.scss +18 -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 +7 -2
- 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/styles/v2/components/input.scss +0 -372
- package/styles/v2/layout/_header.scss +0 -13
- package/styles/v2/layout/_link.scss +0 -46
|
@@ -1,12 +1,131 @@
|
|
|
1
|
-
import React from 'react'
|
|
1
|
+
import React, { useState, useEffect, useRef } from 'react'
|
|
2
|
+
import PropTypes from 'prop-types'
|
|
3
|
+
|
|
4
|
+
import LoadSpin from '../ui/LoadSpin'
|
|
2
5
|
|
|
3
6
|
import '../../styles/v2/components/button.scss'
|
|
4
7
|
|
|
5
|
-
const Button = ({
|
|
8
|
+
const Button = ({
|
|
9
|
+
style,
|
|
10
|
+
role,
|
|
11
|
+
hoverStyle = {},
|
|
12
|
+
fluid = false,
|
|
13
|
+
loading = false,
|
|
14
|
+
loadingText = "Loading...",
|
|
15
|
+
flexCenter,
|
|
16
|
+
active = false,
|
|
17
|
+
onClick,
|
|
18
|
+
children, ...attributes
|
|
19
|
+
}) => {
|
|
20
|
+
|
|
21
|
+
const buttonRef = useRef(null)
|
|
22
|
+
|
|
23
|
+
const [ buttonState, setButtonState ] = useState('out')
|
|
24
|
+
const [ customStyles, setCustomStyles ] = useState({ ...style })
|
|
25
|
+
const [ childrenWidth, setChildrenWidth ] = useState()
|
|
26
|
+
const [ loadtextWidth, setLoadtextWidth ] = useState()
|
|
27
|
+
|
|
28
|
+
const attributesObj = {
|
|
29
|
+
...attributes,
|
|
30
|
+
style: customStyles,
|
|
31
|
+
className:
|
|
32
|
+
'cove-button' +
|
|
33
|
+
(flexCenter || 'loader' === role ? ' cove-button--flex-center' : '') +
|
|
34
|
+
(fluid ? ' fluid' : '') +
|
|
35
|
+
(loading ? ' loading' : '') +
|
|
36
|
+
(attributes.className ? ' ' + attributes.className : ''),
|
|
37
|
+
onMouseOver: () => setButtonState('in'),
|
|
38
|
+
onMouseOut: () => setButtonState('out'),
|
|
39
|
+
onFocus: () => setButtonState('in'),
|
|
40
|
+
onBlur: () => setButtonState('out')
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
useEffect(() => {
|
|
44
|
+
if ('loader' === role && buttonRef.current) {
|
|
45
|
+
//Create ghost object and text nodes for children
|
|
46
|
+
const ghostSpan = document.createElement('span')
|
|
47
|
+
const ghostContent = document.createTextNode(children)
|
|
48
|
+
ghostSpan.style.opacity = '0'
|
|
49
|
+
ghostSpan.style.visibility = 'hidden'
|
|
50
|
+
|
|
51
|
+
//Create ghost object and text nodes for loading value
|
|
52
|
+
const ghostLoaderSpan = document.createElement('span')
|
|
53
|
+
const ghostLoaderContent = document.createTextNode(loadingText)
|
|
54
|
+
ghostLoaderSpan.style.opacity = '0'
|
|
55
|
+
ghostLoaderSpan.style.visibility = 'hidden'
|
|
56
|
+
|
|
57
|
+
//Append data to ghost objects
|
|
58
|
+
ghostSpan.appendChild(ghostContent)
|
|
59
|
+
ghostLoaderSpan.appendChild(ghostLoaderContent)
|
|
60
|
+
|
|
61
|
+
//Append objects to document
|
|
62
|
+
buttonRef.current.parentNode.insertBefore(ghostSpan, buttonRef.current)
|
|
63
|
+
buttonRef.current.parentNode.insertBefore(ghostLoaderSpan, buttonRef.current)
|
|
64
|
+
|
|
65
|
+
//Register ghost width values in state
|
|
66
|
+
setChildrenWidth(ghostSpan.offsetWidth + 2) //Toss in a 2px to account for subpixel offset
|
|
67
|
+
setLoadtextWidth(ghostLoaderSpan.offsetWidth + 2) //Toss in a 2px to account for subpixel offset
|
|
68
|
+
|
|
69
|
+
//Remove ghost objects form document
|
|
70
|
+
buttonRef.current.parentNode.removeChild(ghostSpan)
|
|
71
|
+
buttonRef.current.parentNode.removeChild(ghostLoaderSpan)
|
|
72
|
+
}
|
|
73
|
+
}, [])
|
|
74
|
+
|
|
75
|
+
useEffect(() => {
|
|
76
|
+
//Adjust button styles depending on cursor, focus, and active, states
|
|
77
|
+
return buttonState === 'in'
|
|
78
|
+
? setCustomStyles(stateStyles => ({ ...stateStyles, ...hoverStyle }))
|
|
79
|
+
: buttonState === 'out'
|
|
80
|
+
? active //If button state is out, check if its 'active'; we want to keep hover styles applied to 'active' buttons
|
|
81
|
+
? null //Button is active, so leave the 'hover' styles in place
|
|
82
|
+
: setCustomStyles({ ...style }) //Button is not 'active', so reset display styles back to default
|
|
83
|
+
: false //Button state is neither 'in' nor 'out' - do nothing
|
|
84
|
+
}, [ buttonState, active ])
|
|
6
85
|
|
|
7
86
|
return (
|
|
8
|
-
<button
|
|
87
|
+
<button {...attributesObj}
|
|
88
|
+
onClick={(e) => {
|
|
89
|
+
e.preventDefault()
|
|
90
|
+
return loading || onClick()
|
|
91
|
+
}}
|
|
92
|
+
disabled={loading || attributesObj.disabled}
|
|
93
|
+
ref={buttonRef}>
|
|
94
|
+
{children &&
|
|
95
|
+
<>
|
|
96
|
+
{'loader' === role &&
|
|
97
|
+
<>
|
|
98
|
+
<span className="cove-button__text" style={loading ? { width: loadtextWidth + 'px' } : { width: childrenWidth + 'px' }}>
|
|
99
|
+
<div className="cove-button__text--loading" style={loading ? { opacity: 1 } : null}>{loadingText}</div>
|
|
100
|
+
<div className="cove-button__text--children" style={loading ? { opacity: 0 } : null}>{children}</div>
|
|
101
|
+
</span>
|
|
102
|
+
<div className="cove-button__load-spin" style={loading ? { width: '28px', opacity: 1 } : null}>
|
|
103
|
+
<LoadSpin className="ml-1" size={20}/>
|
|
104
|
+
</div>
|
|
105
|
+
</>
|
|
106
|
+
}
|
|
107
|
+
{role !== 'loader' && children}
|
|
108
|
+
</>
|
|
109
|
+
}
|
|
110
|
+
</button>
|
|
9
111
|
)
|
|
10
112
|
}
|
|
11
113
|
|
|
114
|
+
Button.propTypes = {
|
|
115
|
+
/** Specify special role type for button */
|
|
116
|
+
role: PropTypes.oneOf([ 'loader' ]),
|
|
117
|
+
/** Provide object with styles that overwrite base styles when hovered */
|
|
118
|
+
hoverStyle: PropTypes.object,
|
|
119
|
+
/** Enables button to stretch to the full width of the content */
|
|
120
|
+
fluid: PropTypes.bool,
|
|
121
|
+
/** Displays loading spinner on button while condition is true **/
|
|
122
|
+
loading: PropTypes.bool,
|
|
123
|
+
/** Set text to appear during loading animation **/
|
|
124
|
+
loadingText: PropTypes.string,
|
|
125
|
+
/** Displays button as flex and centers all direct children nodes. Useful for aligning icons and text **/
|
|
126
|
+
flexCenter: PropTypes.bool,
|
|
127
|
+
/** When value condition is true, retains any custom, inline `style={}` defined **/
|
|
128
|
+
active: PropTypes.bool
|
|
129
|
+
}
|
|
130
|
+
|
|
12
131
|
export default Button
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import React from 'react'
|
|
2
|
+
|
|
3
|
+
import '../../styles/v2/components/card.scss'
|
|
4
|
+
|
|
5
|
+
const Card = ({children, className, ...attributes}) => {
|
|
6
|
+
return (
|
|
7
|
+
<div className={`cove-card${className ? ' ' + className : ''}`} {...attributes}>
|
|
8
|
+
{children}
|
|
9
|
+
</div>
|
|
10
|
+
)
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export default Card
|
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
import React, { useState, useEffect, memo } from 'react'
|
|
2
|
+
import PropTypes from 'prop-types'
|
|
2
3
|
|
|
3
|
-
import Check from '../../assets/check.svg'
|
|
4
|
-
import '../../styles/v2/components/input.scss'
|
|
4
|
+
import Check from '../../assets/icon-check.svg'
|
|
5
|
+
import '../../styles/v2/components/input/index.scss'
|
|
5
6
|
|
|
6
7
|
const InputCheckbox = memo((
|
|
7
8
|
{
|
|
8
9
|
label,
|
|
9
|
-
size = '
|
|
10
|
+
size = 'small',
|
|
10
11
|
activeColor = null,
|
|
11
12
|
activeCheckColor = null,
|
|
12
13
|
section = null,
|
|
@@ -56,4 +57,11 @@ const InputCheckbox = memo((
|
|
|
56
57
|
)
|
|
57
58
|
})
|
|
58
59
|
|
|
60
|
+
InputCheckbox.propTypes = {
|
|
61
|
+
label: PropTypes.string,
|
|
62
|
+
size: PropTypes.oneOf(['small', 'medium', 'large']),
|
|
63
|
+
activeColor: PropTypes.string,
|
|
64
|
+
activeCheckColor: PropTypes.string
|
|
65
|
+
}
|
|
66
|
+
|
|
59
67
|
export default InputCheckbox
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import React, { useState, useEffect, useLayoutEffect, useRef } from 'react'
|
|
2
|
+
import PropTypes from 'prop-types'
|
|
3
|
+
|
|
4
|
+
const InputGroup = ({ label, flow, children, clear, className, style, ...attributes }) => {
|
|
5
|
+
const [ styles, setStyles ] = useState({})
|
|
6
|
+
const [ labelWidth, setLabelWidth ] = useState(null)
|
|
7
|
+
|
|
8
|
+
const groupLabelRef = useRef(null)
|
|
9
|
+
const groupLabel = <div className="cove-input-group__label" ref={groupLabelRef}>{label}</div>
|
|
10
|
+
|
|
11
|
+
useLayoutEffect(() => {
|
|
12
|
+
if (!clear) return
|
|
13
|
+
if (!groupLabelRef.current) return
|
|
14
|
+
setLabelWidth(groupLabelRef.current.offsetWidth)
|
|
15
|
+
}, [ clear, groupLabelRef ])
|
|
16
|
+
|
|
17
|
+
useLayoutEffect(() => {
|
|
18
|
+
if (!clear) return
|
|
19
|
+
if ('left' === flow) {
|
|
20
|
+
setStyles(() => ({ paddingLeft: labelWidth + 'px' }))
|
|
21
|
+
}
|
|
22
|
+
if ('right' === flow) {
|
|
23
|
+
setStyles(() => ({ paddingRight: labelWidth + 'px' }))
|
|
24
|
+
}
|
|
25
|
+
}, [ clear, flow, labelWidth ])
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
return (
|
|
29
|
+
<div className={`cove-input-group${clear ? ' clear' : ''}${className ? ' ' + className : ''}`} flow={flow} {...attributes}>
|
|
30
|
+
{label && flow ? <>
|
|
31
|
+
{'left' === flow && <> {groupLabel}{children} </>}
|
|
32
|
+
{'right' === flow && <> {children}{groupLabel} </>}
|
|
33
|
+
{'center' === flow && children.length > 1 && <> {children[0]}{groupLabel}{children[1]} </>}
|
|
34
|
+
</> :
|
|
35
|
+
children
|
|
36
|
+
}
|
|
37
|
+
</div>
|
|
38
|
+
)
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
InputGroup.propTypes = {
|
|
42
|
+
/* Text to display for the input group */
|
|
43
|
+
label: PropTypes.oneOfType([
|
|
44
|
+
PropTypes.string,
|
|
45
|
+
PropTypes.object
|
|
46
|
+
]),
|
|
47
|
+
flow: PropTypes.oneOf([ 'left', 'center', 'right' ])
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
export default InputGroup
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import React, { memo } from 'react'
|
|
2
2
|
|
|
3
|
-
import '../../styles/v2/components/input.scss'
|
|
3
|
+
import '../../styles/v2/components/input/index.scss'
|
|
4
4
|
|
|
5
5
|
const InputSelect = memo((
|
|
6
6
|
{
|
|
@@ -36,7 +36,7 @@ const InputSelect = memo((
|
|
|
36
36
|
|
|
37
37
|
return (
|
|
38
38
|
<label>
|
|
39
|
-
{label && <span className="edit-label">{label}</span>}
|
|
39
|
+
{label && <span className="edit-label cove-input__label">{label}</span>}
|
|
40
40
|
<select className={required && !value ? 'warning' : ''} name={fieldName} value={value} onChange={(event) => {
|
|
41
41
|
updateField(section, subsection, fieldName, event.target.value)
|
|
42
42
|
}} {...attributes}>
|
|
@@ -1,7 +1,7 @@
|
|
|
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
6
|
const InputText = memo((
|
|
7
7
|
{
|
|
@@ -13,8 +13,9 @@ const InputText = memo((
|
|
|
13
13
|
value: stateValue,
|
|
14
14
|
type = 'input',
|
|
15
15
|
tooltip,
|
|
16
|
+
placeholder,
|
|
16
17
|
i = null, min = null, max = null,
|
|
17
|
-
...attributes
|
|
18
|
+
className, ...attributes
|
|
18
19
|
}
|
|
19
20
|
) => {
|
|
20
21
|
|
|
@@ -41,27 +42,25 @@ const InputText = memo((
|
|
|
41
42
|
}
|
|
42
43
|
}
|
|
43
44
|
|
|
44
|
-
let
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
45
|
+
let inputAttrs = {
|
|
46
|
+
className: `cove-input${className ? ' ' + className : ''}`,
|
|
47
|
+
type,
|
|
48
|
+
name,
|
|
49
|
+
placeholder,
|
|
50
|
+
onChange,
|
|
51
|
+
value,
|
|
52
|
+
...attributes
|
|
50
53
|
}
|
|
51
54
|
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
+
let formElement = 'textarea' === type
|
|
56
|
+
? (<textarea {...inputAttrs}/>)
|
|
57
|
+
: (<input {...inputAttrs}/>)
|
|
55
58
|
|
|
56
59
|
return (
|
|
57
|
-
|
|
58
|
-
{label &&
|
|
59
|
-
<>
|
|
60
|
-
<label>{label}{tooltip}</label>
|
|
61
|
-
</>
|
|
62
|
-
}
|
|
60
|
+
<>
|
|
61
|
+
{label && <label className="cove-input__label">{label}</label>}{tooltip}
|
|
63
62
|
{formElement}
|
|
64
|
-
|
|
63
|
+
</>
|
|
65
64
|
)
|
|
66
65
|
})
|
|
67
66
|
|
|
@@ -1,12 +1,12 @@
|
|
|
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
|
|
6
|
+
const InputSlider = (
|
|
7
7
|
{
|
|
8
8
|
label,
|
|
9
|
-
|
|
9
|
+
sliderType = 'flat',
|
|
10
10
|
size = 'medium',
|
|
11
11
|
activeColor = null,
|
|
12
12
|
section = null,
|
|
@@ -33,14 +33,14 @@ const InputToggle = (
|
|
|
33
33
|
return str
|
|
34
34
|
}
|
|
35
35
|
|
|
36
|
-
const
|
|
36
|
+
const sliderTypeClass = () => {
|
|
37
37
|
const typeArr = {
|
|
38
|
-
'flat': '
|
|
39
|
-
'block': '
|
|
40
|
-
'pill': '
|
|
41
|
-
'3d': '
|
|
38
|
+
'flat': ' slider--flat',
|
|
39
|
+
'block': ' slider--block',
|
|
40
|
+
'pill': ' slider--pill',
|
|
41
|
+
'3d': ' slider--3d'
|
|
42
42
|
}
|
|
43
|
-
return typeArr[
|
|
43
|
+
return typeArr[sliderType] || ''
|
|
44
44
|
}
|
|
45
45
|
|
|
46
46
|
useEffect(() => {
|
|
@@ -58,23 +58,23 @@ const InputToggle = (
|
|
|
58
58
|
return (
|
|
59
59
|
<div className="input-group">
|
|
60
60
|
{label && <label>{label}</label>}
|
|
61
|
-
<div className={'cove-
|
|
62
|
-
<div className="cove-
|
|
63
|
-
<div className="cove-
|
|
61
|
+
<div className={'cove-input__slider' + (size === 'small' ? '--small' : size === 'large' ? '--large' : '') + (sliderTypeClass()) + (value ? ' active' : '')} onClick={() => setValue(!value)}>
|
|
62
|
+
<div className="cove-input__slider-button"/>
|
|
63
|
+
<div className="cove-input__slider-track" style={value && activeColor ? { backgroundColor: activeColor } : null }/>
|
|
64
64
|
<input className="cove-input--hidden" type="checkbox" name={name()} checked={value || false} readOnly/>
|
|
65
65
|
</div>
|
|
66
66
|
</div>
|
|
67
67
|
)
|
|
68
68
|
}
|
|
69
69
|
|
|
70
|
-
|
|
70
|
+
InputSlider.propTypes = {
|
|
71
71
|
/** Add label to the input field */
|
|
72
72
|
label: PropTypes.string,
|
|
73
|
-
/** Select the preferred display style of the
|
|
74
|
-
|
|
75
|
-
/** Select the preferred size of the
|
|
73
|
+
/** Select the preferred display style of the slider */
|
|
74
|
+
sliderType: PropTypes.oneOf(['flat', 'block', 'pill', '3d']),
|
|
75
|
+
/** Select the preferred size of the slider */
|
|
76
76
|
size: PropTypes.oneOf(['small', 'medium', 'large']),
|
|
77
|
-
/** Select the preferred color for the
|
|
77
|
+
/** Select the preferred color for the slider when active */
|
|
78
78
|
activeColor: PropTypes.string,
|
|
79
79
|
/** Parent key value of nested target config option
|
|
80
80
|
*
|
|
@@ -92,4 +92,4 @@ InputToggle.propTypes = {
|
|
|
92
92
|
stateValue: PropTypes.object
|
|
93
93
|
}
|
|
94
94
|
|
|
95
|
-
export default
|
|
95
|
+
export default InputSlider
|
|
@@ -0,0 +1,171 @@
|
|
|
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
|
+
<Card>
|
|
25
|
+
<strong className="cove-heading--3">Vertical</strong>
|
|
26
|
+
<p className="mb-1">Values for map geography or chart date/category axis are contained in a
|
|
27
|
+
single <em>column</em>.
|
|
28
|
+
</p>
|
|
29
|
+
{DATA_TABLE_VERTICAL}
|
|
30
|
+
</Card>
|
|
31
|
+
</button>
|
|
32
|
+
</div>
|
|
33
|
+
<div className="column">
|
|
34
|
+
<button
|
|
35
|
+
className={'cove-data-designer__button' + (configureData.dataDescription && configureData.dataDescription.horizontal === true ? ' active' : '')}
|
|
36
|
+
onClick={() => {
|
|
37
|
+
updateDescriptionProp(visualizationKey, dataKey, 'horizontal', true)
|
|
38
|
+
}}>
|
|
39
|
+
<Card>
|
|
40
|
+
<strong className="cove-heading--3">Horizontal</strong>
|
|
41
|
+
<p className="mb-1">Values for map geography or chart date/category axis are contained in a single <em>row</em>
|
|
42
|
+
</p>
|
|
43
|
+
{DATA_TABLE_HORIZONTAL}
|
|
44
|
+
</Card>
|
|
45
|
+
</button>
|
|
46
|
+
</div>
|
|
47
|
+
</div>
|
|
48
|
+
</div>
|
|
49
|
+
{configureData.dataDescription && (
|
|
50
|
+
<>
|
|
51
|
+
<div className="mb-2">
|
|
52
|
+
<div className="mb-1">Are there multiple series represented in your data?</div>
|
|
53
|
+
<div>
|
|
54
|
+
<Button
|
|
55
|
+
style={{ backgroundColor: '#00345d' }}
|
|
56
|
+
hoverStyle={{ backgroundColor: '#015daa' }}
|
|
57
|
+
className="mr-1"
|
|
58
|
+
onClick={() => {
|
|
59
|
+
updateDescriptionProp(visualizationKey, dataKey, 'series', true)
|
|
60
|
+
}}
|
|
61
|
+
active={configureData.dataDescription.series === true}
|
|
62
|
+
>
|
|
63
|
+
Yes
|
|
64
|
+
</Button>
|
|
65
|
+
<Button
|
|
66
|
+
style={{ backgroundColor: '#00345d' }}
|
|
67
|
+
hoverStyle={{ backgroundColor: '#015daa' }}
|
|
68
|
+
onClick={() => {
|
|
69
|
+
updateDescriptionProp(visualizationKey, dataKey, 'series', false)
|
|
70
|
+
}}
|
|
71
|
+
active={configureData.dataDescription.series === false}
|
|
72
|
+
>
|
|
73
|
+
No
|
|
74
|
+
</Button>
|
|
75
|
+
</div>
|
|
76
|
+
</div>
|
|
77
|
+
{configureData.dataDescription.horizontal === true && configureData.dataDescription.series === true && (
|
|
78
|
+
<div className="mb-2">
|
|
79
|
+
<div className="mb-1">Which property in the dataset represents which series the row is describing?</div>
|
|
80
|
+
<select onChange={(e) => {
|
|
81
|
+
updateDescriptionProp(visualizationKey, dataKey, 'seriesKey', e.target.value)
|
|
82
|
+
}} defaultValue={configureData.dataDescription.seriesKey}>
|
|
83
|
+
<option value="">Choose an option</option>
|
|
84
|
+
{Object.keys(configureData.data[0]).map((value, index) => <option value={value} key={index}>{value}</option>)}
|
|
85
|
+
</select>
|
|
86
|
+
</div>
|
|
87
|
+
)}
|
|
88
|
+
{configureData.dataDescription.horizontal === false && configureData.dataDescription.series === true && (
|
|
89
|
+
<>
|
|
90
|
+
<div className="mb-2">
|
|
91
|
+
<div className="mb-1">Are the series values in your data represented in a
|
|
92
|
+
single row, or across multiple rows?
|
|
93
|
+
</div>
|
|
94
|
+
<div className="grid grid-gap-2 mb-4">
|
|
95
|
+
<div className="column">
|
|
96
|
+
<button
|
|
97
|
+
className={'cove-data-designer__button' + (configureData.dataDescription.singleRow === true ? ' active' : '')}
|
|
98
|
+
onClick={() => {
|
|
99
|
+
updateDescriptionProp(visualizationKey, dataKey, 'singleRow', true)
|
|
100
|
+
}}>
|
|
101
|
+
<Card>
|
|
102
|
+
<strong className="cove-heading--3">Single Row</strong>
|
|
103
|
+
<p className="mb-1">Each row contains the data for an individual series in itself.</p>
|
|
104
|
+
{DATA_TABLE_SINGLE_ROW}
|
|
105
|
+
</Card>
|
|
106
|
+
</button>
|
|
107
|
+
</div>
|
|
108
|
+
<div className="column">
|
|
109
|
+
<button
|
|
110
|
+
className={'cove-data-designer__button' + (configureData.dataDescription.singleRow === false ? ' active' : '')}
|
|
111
|
+
onClick={() => {
|
|
112
|
+
updateDescriptionProp(visualizationKey, dataKey, 'singleRow', false)
|
|
113
|
+
}}>
|
|
114
|
+
<Card>
|
|
115
|
+
<strong className="cove-heading--3">Multiple Rows</strong>
|
|
116
|
+
<p className="mb-1">Each series data is broken out into multiple rows.</p>
|
|
117
|
+
{DATA_TABLE_MULTI_ROW}
|
|
118
|
+
</Card>
|
|
119
|
+
</button>
|
|
120
|
+
</div>
|
|
121
|
+
</div>
|
|
122
|
+
</div>
|
|
123
|
+
{configureData.dataDescription.singleRow === false && (
|
|
124
|
+
<>
|
|
125
|
+
<div className="mb-2">
|
|
126
|
+
<div className="mb-1">Which property in the dataset represents which series the row is describing?</div>
|
|
127
|
+
<select onChange={(e) => {
|
|
128
|
+
updateDescriptionProp(visualizationKey, dataKey, 'seriesKey', e.target.value)
|
|
129
|
+
}} defaultValue={configureData.dataDescription.seriesKey}>
|
|
130
|
+
<option value="">Choose an option</option>
|
|
131
|
+
{Object.keys(configureData.data[0]).map((value, index) => (
|
|
132
|
+
<option value={value} key={index}>{value}</option>
|
|
133
|
+
))}
|
|
134
|
+
</select>
|
|
135
|
+
</div>
|
|
136
|
+
<div className="mb-2">
|
|
137
|
+
<div className="mb-1">Which property in the dataset represents the values for the category/date axis or map geography?</div>
|
|
138
|
+
<select onChange={(e) => {
|
|
139
|
+
updateDescriptionProp(visualizationKey, dataKey, 'xKey', e.target.value)
|
|
140
|
+
}} defaultValue={configureData.dataDescription.xKey}>
|
|
141
|
+
<option value="">Choose an option</option>
|
|
142
|
+
{Object.keys(configureData.data[0]).map((value, index) => (
|
|
143
|
+
<option value={value} key={index}>{value}</option>
|
|
144
|
+
))}
|
|
145
|
+
</select>
|
|
146
|
+
</div>
|
|
147
|
+
<div className="mb-2">
|
|
148
|
+
<div className="mb-1">Which property in the dataset represents the numeric value?</div>
|
|
149
|
+
<select onChange={(e) => {
|
|
150
|
+
updateDescriptionProp(visualizationKey, dataKey, 'valueKey', e.target.value)
|
|
151
|
+
}} defaultValue={configureData.dataDescription.valueKey}>
|
|
152
|
+
<option value="">Choose an option</option>
|
|
153
|
+
{Object.keys(configureData.data[0]).map((value, index) => (
|
|
154
|
+
<option value={value} key={index}>{value}</option>
|
|
155
|
+
))}
|
|
156
|
+
</select>
|
|
157
|
+
</div>
|
|
158
|
+
</>
|
|
159
|
+
)}
|
|
160
|
+
</>
|
|
161
|
+
)}
|
|
162
|
+
</>
|
|
163
|
+
)}
|
|
164
|
+
{configureData.dataDescription && configureData.formattedData && (
|
|
165
|
+
<div>Data configured successfully</div>
|
|
166
|
+
)}
|
|
167
|
+
</div>
|
|
168
|
+
)
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
export default DataDesigner
|
package/components/ui/Icon.jsx
CHANGED
|
@@ -1,24 +1,62 @@
|
|
|
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'
|
|
11
30
|
|
|
12
31
|
import '../../styles/v2/components/icon.scss'
|
|
13
32
|
|
|
14
33
|
const iconHash = {
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
34
|
+
'caretUp': iconCaretUp,
|
|
35
|
+
'caretDown': iconCaretDown,
|
|
36
|
+
'caretFilledUp': iconCaretFilledUp,
|
|
37
|
+
'caretFilledDown': iconCaretFilledDown,
|
|
38
|
+
'chartBar': iconChartBar,
|
|
39
|
+
'chartLine': iconChartLine,
|
|
40
|
+
'chartPie': iconChartPie,
|
|
41
|
+
'close': iconClose,
|
|
42
|
+
'code': iconCode,
|
|
43
|
+
'databite': iconDataBite,
|
|
44
|
+
'edit': iconEdit,
|
|
45
|
+
'fileUpload': iconFileUpload,
|
|
46
|
+
'filterBars': iconFilterBars,
|
|
47
|
+
'grid': iconGrid,
|
|
48
|
+
'info': iconInfo,
|
|
49
|
+
'link': iconLink,
|
|
50
|
+
'mapAl': iconMapAl,
|
|
51
|
+
'mapUsa': iconMapUsa,
|
|
52
|
+
'mapWorld': iconMapWorld,
|
|
53
|
+
'move': iconMove,
|
|
54
|
+
'question': iconQuestion,
|
|
55
|
+
'upload': iconUpload,
|
|
56
|
+
'warningCircle': iconWarningCircle,
|
|
57
|
+
'warningTriangle': iconWarningTriangle,
|
|
58
|
+
'gear': iconGear,
|
|
59
|
+
'tools': iconTools
|
|
22
60
|
}
|
|
23
61
|
|
|
24
62
|
const Icon = ({ display = null, base, alt = '', size, color, style, ...attributes }) => {
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import React from 'react'
|
|
2
|
+
import '../../styles/v2/components/loadspin.scss'
|
|
3
|
+
|
|
4
|
+
const LoadSpin = ({
|
|
5
|
+
color = '#fff',
|
|
6
|
+
opacity = 100,
|
|
7
|
+
size = 100,
|
|
8
|
+
className
|
|
9
|
+
}) => {
|
|
10
|
+
const n = 8
|
|
11
|
+
return (
|
|
12
|
+
<>
|
|
13
|
+
<div className={`cove-loadspin${className ? ' ' + className : ''}`} style={{width: size, height: size}}>
|
|
14
|
+
<div className="cove-loadspin__roller" style={{opacity: opacity / 100, transform: `scale(${size/80})`}}>
|
|
15
|
+
{
|
|
16
|
+
[...Array(n)].map((elem, index) => <div key={index} style={{backgroundColor: color}}/>)
|
|
17
|
+
}
|
|
18
|
+
</div>
|
|
19
|
+
</div>
|
|
20
|
+
</>
|
|
21
|
+
)
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export default LoadSpin
|