@cdc/core 4.22.10 → 4.23.1
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/README.md +1 -1
- package/components/AdvancedEditor.js +52 -67
- package/components/ErrorBoundary.jsx +10 -11
- package/components/GlobalContext.jsx +2 -6
- package/components/LegendCircle.jsx +3 -4
- package/components/Loading.jsx +14 -12
- package/components/Waiting.jsx +14 -5
- package/components/elements/Button.jsx +34 -45
- package/components/elements/Card.jsx +1 -1
- package/components/inputs/InputCheckbox.jsx +32 -35
- package/components/inputs/InputGroup.jsx +38 -17
- package/components/inputs/InputSelect.jsx +27 -23
- package/components/inputs/InputText.jsx +9 -25
- package/components/inputs/InputToggle.jsx +29 -33
- package/components/managers/DataDesigner.jsx +87 -64
- package/components/ui/Accordion.jsx +18 -30
- package/components/ui/Icon.jsx +34 -35
- package/components/ui/LoadSpin.jsx +6 -11
- package/components/ui/Modal.jsx +40 -44
- package/components/ui/Overlay.jsx +12 -23
- package/components/ui/OverlayFrame.jsx +1 -5
- package/components/ui/Tooltip.jsx +8 -28
- package/data/colorPalettes.js +29 -266
- package/data/dataDesignerTables.js +107 -107
- package/data/themes.js +13 -13
- package/helpers/CoveMediaControls.js +139 -0
- package/helpers/DataTransform.js +92 -92
- package/helpers/cacheBustingString.js +3 -3
- package/helpers/events.js +5 -6
- package/helpers/fetchRemoteData.js +33 -33
- package/helpers/getViewport.js +15 -15
- package/helpers/numberFromString.js +7 -7
- package/helpers/updatePaletteNames.js +15 -17
- package/helpers/useDataVizClasses.js +38 -35
- package/helpers/validateFipsCodeLength.js +41 -56
- package/package.json +4 -2
- package/styles/_button-section.scss +35 -0
- package/styles/_data-table.scss +39 -27
- package/styles/_global.scss +29 -24
- package/styles/_mixins.scss +12 -12
- package/styles/_reset.scss +85 -16
- package/styles/_variables.scss +5 -5
- package/styles/base.scss +100 -48
- package/styles/heading-colors.scss +6 -2
- package/styles/loading.scss +62 -60
- package/styles/v2/base/_file-selector.scss +2 -2
- package/styles/v2/base/_general.scss +1 -1
- package/styles/v2/base/_reset.scss +2 -2
- package/styles/v2/base/index.scss +4 -4
- package/styles/v2/components/accordion.scss +13 -13
- package/styles/v2/components/button.scss +3 -3
- package/styles/v2/components/card.scss +1 -1
- package/styles/v2/components/data-designer.scss +7 -6
- package/styles/v2/components/editor.scss +52 -51
- package/styles/v2/components/guidance-block.scss +6 -6
- package/styles/v2/components/input/_input-check-radio.scss +7 -7
- package/styles/v2/components/input/_input-group.scss +2 -2
- package/styles/v2/components/input/_input-slider.scss +2 -3
- package/styles/v2/components/input/index.scss +6 -6
- package/styles/v2/components/loadspin.scss +1 -1
- package/styles/v2/components/modal.scss +2 -2
- package/styles/v2/components/overlay.scss +4 -4
- package/styles/v2/layout/_alert.scss +8 -8
- package/styles/v2/layout/_component.scss +1 -1
- package/styles/v2/layout/_data-table.scss +12 -11
- package/styles/v2/layout/_progression.scss +8 -6
- package/styles/v2/layout/index.scss +5 -5
- package/styles/v2/main.scss +7 -7
- package/styles/v2/themes/_color-definitions.scss +77 -24
- package/styles/v2/themes/index.scss +1 -1
- package/styles/v2/utils/_animations.scss +2 -2
- package/styles/v2/utils/_breakpoints.scss +53 -12
- package/styles/v2/utils/_variables.scss +5 -5
- package/styles/v2/utils/index.scss +8 -8
- package/styles/waiting.scss +22 -23
package/README.md
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
# `core`
|
|
2
2
|
|
|
3
|
-
This is an internal package that is only consumed by external facing packages in COVE. It houses shared components, styles and assets.
|
|
3
|
+
This is an internal package that is only consumed by external facing packages in COVE. It houses shared components, styles and assets.
|
|
@@ -1,74 +1,59 @@
|
|
|
1
1
|
import React, { useState, useEffect } from 'react'
|
|
2
2
|
import MapIcon from '../assets/map-folded.svg'
|
|
3
|
-
import ChartIcon from '../assets/icon-chart-bar.svg'
|
|
4
|
-
import MarkupIncludeIcon from '../assets/icon-code.svg'
|
|
5
|
-
|
|
3
|
+
import ChartIcon from '../assets/icon-chart-bar.svg'
|
|
4
|
+
import MarkupIncludeIcon from '../assets/icon-code.svg'
|
|
6
5
|
|
|
7
6
|
export const AdvancedEditor = ({ loadConfig, state, convertStateToConfig }) => {
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
value={configTextboxValue}
|
|
59
|
-
onChange={(event) => setConfigTextbox(event.target.value)}
|
|
60
|
-
/>
|
|
61
|
-
<button
|
|
62
|
-
className='btn full-width'
|
|
63
|
-
onClick={() => loadConfig(JSON.parse(configTextboxValue))}
|
|
64
|
-
>
|
|
65
|
-
Apply
|
|
66
|
-
</button>
|
|
67
|
-
</React.Fragment>
|
|
68
|
-
)}
|
|
69
|
-
</div>
|
|
70
|
-
</>
|
|
71
|
-
)
|
|
7
|
+
const [advancedToggle, setAdvancedToggle] = useState(false)
|
|
8
|
+
const [configTextboxValue, setConfigTextbox] = useState({})
|
|
9
|
+
|
|
10
|
+
useEffect(() => {
|
|
11
|
+
const parsedData = convertStateToConfig()
|
|
12
|
+
const formattedData = JSON.stringify(parsedData, undefined, 2)
|
|
13
|
+
|
|
14
|
+
setConfigTextbox(formattedData)
|
|
15
|
+
}, [state])
|
|
16
|
+
|
|
17
|
+
const typeLookup = {
|
|
18
|
+
chart: ['Charts', 'https://www.cdc.gov/wcms/4.0/cdc-wp/data-presentation/bar-chart.html', <ChartIcon />],
|
|
19
|
+
map: ['Maps', 'https://www.cdc.gov/wcms/4.0/cdc-wp/data-presentation/data-map.html', <MapIcon />],
|
|
20
|
+
'markup-include': ['Markup Include', 'https://www.cdc.gov/wcms/4.0/cdc-wp/data-presentation/Markup-Include.html', <MarkupIncludeIcon />]
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
if (!state.type) return
|
|
24
|
+
return (
|
|
25
|
+
<>
|
|
26
|
+
<a href={typeLookup[state.type][1]} target='_blank' rel='noopener noreferrer' className='guidance-link'>
|
|
27
|
+
{typeLookup[state.type][2]}
|
|
28
|
+
<div>
|
|
29
|
+
<span className='heading-3'>Get Help with {typeLookup[state.type][0]}</span>
|
|
30
|
+
<p>Examples and documentation</p>
|
|
31
|
+
</div>
|
|
32
|
+
</a>
|
|
33
|
+
<div className='advanced'>
|
|
34
|
+
<span className='advanced-toggle-link' onClick={() => setAdvancedToggle(!advancedToggle)}>
|
|
35
|
+
<span>{advancedToggle ? `— ` : `+ `}</span>Advanced Options
|
|
36
|
+
</span>
|
|
37
|
+
{advancedToggle && (
|
|
38
|
+
<React.Fragment>
|
|
39
|
+
<section className='error-box py-2 px-3 my-2'>
|
|
40
|
+
<div>
|
|
41
|
+
<strong className='pt-1'>Warning</strong>
|
|
42
|
+
<p>This can cause serious errors in your visualization.</p>
|
|
43
|
+
</div>
|
|
44
|
+
</section>
|
|
45
|
+
<p className='pb-2'>
|
|
46
|
+
This tool displays the actual <acronym title='JavaScript Object Notation'>JSON</acronym> configuration that is generated by this editor and allows you to edit properties directly and apply them.
|
|
47
|
+
</p>
|
|
48
|
+
<textarea value={configTextboxValue} onChange={event => setConfigTextbox(event.target.value)} />
|
|
49
|
+
<button className='btn full-width' onClick={() => loadConfig(JSON.parse(configTextboxValue))}>
|
|
50
|
+
Apply
|
|
51
|
+
</button>
|
|
52
|
+
</React.Fragment>
|
|
53
|
+
)}
|
|
54
|
+
</div>
|
|
55
|
+
</>
|
|
56
|
+
)
|
|
72
57
|
}
|
|
73
58
|
|
|
74
59
|
export default AdvancedEditor
|
|
@@ -1,33 +1,32 @@
|
|
|
1
|
-
import React from 'react'
|
|
1
|
+
import React from 'react'
|
|
2
2
|
|
|
3
3
|
class ErrorBoundary extends React.Component {
|
|
4
4
|
constructor(props) {
|
|
5
|
-
super(props)
|
|
6
|
-
this.state = { hasError: false }
|
|
7
|
-
|
|
5
|
+
super(props)
|
|
6
|
+
this.state = { hasError: false }
|
|
8
7
|
}
|
|
9
8
|
|
|
10
9
|
static getDerivedStateFromError(error) {
|
|
11
10
|
// Update state so the next render will show the fallback UI.
|
|
12
|
-
return { hasError: true }
|
|
11
|
+
return { hasError: true }
|
|
13
12
|
}
|
|
14
13
|
|
|
15
14
|
componentDidCatch(error, errorInfo) {
|
|
16
15
|
// You can also log the error to an error reporting service
|
|
17
|
-
console.warn(error, errorInfo)
|
|
16
|
+
console.warn(error, errorInfo)
|
|
18
17
|
}
|
|
19
18
|
|
|
20
19
|
render() {
|
|
21
20
|
if (this.state.hasError) {
|
|
22
|
-
if(this.props.component) {
|
|
23
|
-
return <h1>Something went wrong with component {this.props.component}.</h1
|
|
21
|
+
if (this.props.component) {
|
|
22
|
+
return <h1>Something went wrong with component {this.props.component}.</h1>
|
|
24
23
|
}
|
|
25
24
|
// You can render any custom fallback UI
|
|
26
|
-
return <h1>Something went wrong.</h1
|
|
25
|
+
return <h1>Something went wrong.</h1>
|
|
27
26
|
}
|
|
28
27
|
|
|
29
|
-
return this.props.children
|
|
28
|
+
return this.props.children
|
|
30
29
|
}
|
|
31
30
|
}
|
|
32
31
|
|
|
33
|
-
export default ErrorBoundary
|
|
32
|
+
export default ErrorBoundary
|
|
@@ -4,7 +4,7 @@ export const GlobalContext = createContext({})
|
|
|
4
4
|
export const useGlobalContext = () => useContext(GlobalContext)
|
|
5
5
|
|
|
6
6
|
export const GlobalContextProvider = ({ children }) => {
|
|
7
|
-
const [
|
|
7
|
+
const [globalContextData, setGlobalContextData] = useState({})
|
|
8
8
|
|
|
9
9
|
const openOverlay = (obj, disableBgClose = false) => {
|
|
10
10
|
let payload = { object: obj, show: true, disableBgClose: disableBgClose }
|
|
@@ -33,9 +33,5 @@ export const GlobalContextProvider = ({ children }) => {
|
|
|
33
33
|
}
|
|
34
34
|
}
|
|
35
35
|
|
|
36
|
-
return
|
|
37
|
-
<GlobalContext.Provider value={globalSettings}>
|
|
38
|
-
{children}
|
|
39
|
-
</GlobalContext.Provider>
|
|
40
|
-
)
|
|
36
|
+
return <GlobalContext.Provider value={globalSettings}>{children}</GlobalContext.Provider>
|
|
41
37
|
}
|
|
@@ -1,7 +1,6 @@
|
|
|
1
|
-
import React from 'react'
|
|
2
|
-
|
|
3
|
-
export default function LegendCircle({fill}) {
|
|
1
|
+
import React from 'react'
|
|
4
2
|
|
|
3
|
+
export default function LegendCircle({ fill }) {
|
|
5
4
|
const styles = {
|
|
6
5
|
marginRight: '5px',
|
|
7
6
|
borderRadius: '300px',
|
|
@@ -13,5 +12,5 @@ export default function LegendCircle({fill}) {
|
|
|
13
12
|
backgroundColor: fill
|
|
14
13
|
}
|
|
15
14
|
|
|
16
|
-
return <span className=
|
|
15
|
+
return <span className='legend-item' style={styles} />
|
|
17
16
|
}
|
package/components/Loading.jsx
CHANGED
|
@@ -1,15 +1,17 @@
|
|
|
1
|
-
import React from 'react'
|
|
2
|
-
import '../styles/loading.scss'
|
|
1
|
+
import React from 'react'
|
|
2
|
+
import '../styles/loading.scss'
|
|
3
3
|
|
|
4
|
-
export default function Loading({viewport =
|
|
4
|
+
export default function Loading({ viewport = 'lg' }) {
|
|
5
5
|
return (
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
6
|
+
<section className='loading' aria-live='assertive'>
|
|
7
|
+
<span className='sr-only' style={{ display: 'none' }}>
|
|
8
|
+
Content is loading.
|
|
9
|
+
</span>
|
|
10
|
+
<div className={`la-ball-beat la-dark ${viewport}`}>
|
|
11
|
+
<div />
|
|
12
|
+
<div />
|
|
13
|
+
<div />
|
|
14
|
+
</div>
|
|
15
|
+
</section>
|
|
16
|
+
)
|
|
15
17
|
}
|
package/components/Waiting.jsx
CHANGED
|
@@ -1,11 +1,20 @@
|
|
|
1
|
-
import React from 'react'
|
|
2
|
-
import '../styles/waiting.scss'
|
|
1
|
+
import React from 'react'
|
|
2
|
+
import '../styles/waiting.scss'
|
|
3
3
|
|
|
4
4
|
export default ({ requiredColumns, className }) => (
|
|
5
5
|
<section className={className}>
|
|
6
|
-
<section className=
|
|
6
|
+
<section className='waiting-container'>
|
|
7
7
|
<h3>Configuration Required</h3>
|
|
8
|
-
<p>
|
|
8
|
+
<p>
|
|
9
|
+
Set{' '}
|
|
10
|
+
{requiredColumns.map((col, i) => (
|
|
11
|
+
<span key={`missing-column-${i}`}>
|
|
12
|
+
<strong>{col}</strong>
|
|
13
|
+
{i + 1 < requiredColumns.length && ', '}
|
|
14
|
+
</span>
|
|
15
|
+
))}{' '}
|
|
16
|
+
columns in editor.
|
|
17
|
+
</p>
|
|
9
18
|
</section>
|
|
10
19
|
</section>
|
|
11
|
-
)
|
|
20
|
+
)
|
|
@@ -5,35 +5,18 @@ import LoadSpin from '../ui/LoadSpin'
|
|
|
5
5
|
|
|
6
6
|
import '../../styles/v2/components/button.scss'
|
|
7
7
|
|
|
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
|
-
|
|
8
|
+
const Button = ({ style, role, hoverStyle = {}, fluid = false, loading = false, loadingText = 'Loading...', flexCenter, active = false, onClick, children, ...attributes }) => {
|
|
21
9
|
const buttonRef = useRef(null)
|
|
22
10
|
|
|
23
|
-
const [
|
|
24
|
-
const [
|
|
25
|
-
const [
|
|
26
|
-
const [
|
|
11
|
+
const [buttonState, setButtonState] = useState('out')
|
|
12
|
+
const [customStyles, setCustomStyles] = useState({ ...style })
|
|
13
|
+
const [childrenWidth, setChildrenWidth] = useState()
|
|
14
|
+
const [loadtextWidth, setLoadtextWidth] = useState()
|
|
27
15
|
|
|
28
16
|
const attributesObj = {
|
|
29
17
|
...attributes,
|
|
30
18
|
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 : ''),
|
|
19
|
+
className: 'cove-button' + (flexCenter || 'loader' === role ? ' cove-button--flex-center' : '') + (fluid ? ' fluid' : '') + (loading ? ' loading' : '') + (attributes.className ? ' ' + attributes.className : ''),
|
|
37
20
|
onMouseOver: () => setButtonState('in'),
|
|
38
21
|
onMouseOut: () => setButtonState('out'),
|
|
39
22
|
onFocus: () => setButtonState('in'),
|
|
@@ -77,43 +60,49 @@ const Button = ({
|
|
|
77
60
|
return buttonState === 'in'
|
|
78
61
|
? setCustomStyles(stateStyles => ({ ...stateStyles, ...hoverStyle }))
|
|
79
62
|
: buttonState === 'out'
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
}, [
|
|
63
|
+
? active //If button state is out, check if its 'active'; we want to keep hover styles applied to 'active' buttons
|
|
64
|
+
? null //Button is active, so leave the 'hover' styles in place
|
|
65
|
+
: setCustomStyles({ ...style }) //Button is not 'active', so reset display styles back to default
|
|
66
|
+
: false //Button state is neither 'in' nor 'out' - do nothing
|
|
67
|
+
}, [buttonState, active])
|
|
85
68
|
|
|
86
69
|
return (
|
|
87
|
-
<button
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
{
|
|
70
|
+
<button
|
|
71
|
+
{...attributesObj}
|
|
72
|
+
onClick={e => {
|
|
73
|
+
e.preventDefault()
|
|
74
|
+
return loading || onClick()
|
|
75
|
+
}}
|
|
76
|
+
disabled={loading || attributesObj.disabled}
|
|
77
|
+
ref={buttonRef}
|
|
78
|
+
>
|
|
79
|
+
{children && (
|
|
95
80
|
<>
|
|
96
|
-
{'loader' === role &&
|
|
81
|
+
{'loader' === role && (
|
|
97
82
|
<>
|
|
98
|
-
<span className=
|
|
99
|
-
<div className=
|
|
100
|
-
|
|
83
|
+
<span className='cove-button__text' style={loading ? { width: loadtextWidth + 'px' } : { width: childrenWidth + 'px' }}>
|
|
84
|
+
<div className='cove-button__text--loading' style={loading ? { opacity: 1 } : null}>
|
|
85
|
+
{loadingText}
|
|
86
|
+
</div>
|
|
87
|
+
<div className='cove-button__text--children' style={loading ? { opacity: 0 } : null}>
|
|
88
|
+
{children}
|
|
89
|
+
</div>
|
|
101
90
|
</span>
|
|
102
|
-
<div className=
|
|
103
|
-
<LoadSpin className=
|
|
91
|
+
<div className='cove-button__load-spin' style={loading ? { width: '28px', opacity: 1 } : null}>
|
|
92
|
+
<LoadSpin className='ml-1' size={20} />
|
|
104
93
|
</div>
|
|
105
94
|
</>
|
|
106
|
-
}
|
|
95
|
+
)}
|
|
107
96
|
{role !== 'loader' && children}
|
|
108
97
|
</>
|
|
109
|
-
}
|
|
98
|
+
)}
|
|
110
99
|
</button>
|
|
111
100
|
)
|
|
112
101
|
}
|
|
113
102
|
|
|
114
103
|
Button.propTypes = {
|
|
115
104
|
/** Specify special role type for button */
|
|
116
|
-
role: PropTypes.oneOf([
|
|
105
|
+
role: PropTypes.oneOf(['loader']),
|
|
117
106
|
/** Provide object with styles that overwrite base styles when hovered */
|
|
118
107
|
hoverStyle: PropTypes.object,
|
|
119
108
|
/** Enables button to stretch to the full width of the content */
|
|
@@ -2,7 +2,7 @@ import React from 'react'
|
|
|
2
2
|
|
|
3
3
|
import '../../styles/v2/components/card.scss'
|
|
4
4
|
|
|
5
|
-
const Card = ({children, className, ...attributes}) => {
|
|
5
|
+
const Card = ({ children, className, ...attributes }) => {
|
|
6
6
|
return (
|
|
7
7
|
<div className={`cove-card${className ? ' ' + className : ''}`} {...attributes}>
|
|
8
8
|
{children}
|
|
@@ -4,8 +4,8 @@ import PropTypes from 'prop-types'
|
|
|
4
4
|
import Check from '../../assets/icon-check.svg'
|
|
5
5
|
import '../../styles/v2/components/input/index.scss'
|
|
6
6
|
|
|
7
|
-
const InputCheckbox = memo(
|
|
8
|
-
{
|
|
7
|
+
const InputCheckbox = memo(
|
|
8
|
+
({
|
|
9
9
|
label,
|
|
10
10
|
size = 'small',
|
|
11
11
|
activeColor = null,
|
|
@@ -16,46 +16,43 @@ const InputCheckbox = memo((
|
|
|
16
16
|
updateField,
|
|
17
17
|
value: stateValue,
|
|
18
18
|
|
|
19
|
-
i = null,
|
|
19
|
+
i = null,
|
|
20
|
+
min = null,
|
|
21
|
+
max = null,
|
|
20
22
|
...attributes
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
const [ value, setValue ] = useState(stateValue)
|
|
25
|
-
|
|
26
|
-
let name = subsection ? `${section}-${subsection}-${fieldName}` : `${section}-${subsection}-${fieldName}`
|
|
27
|
-
if(fieldName === 'border') {
|
|
28
|
-
console.table({fieldName, value, stateValue})
|
|
29
|
-
|
|
30
|
-
}
|
|
23
|
+
}) => {
|
|
24
|
+
const [value, setValue] = useState(stateValue)
|
|
31
25
|
|
|
32
|
-
|
|
33
|
-
if (
|
|
34
|
-
|
|
26
|
+
let name = subsection ? `${section}-${subsection}-${fieldName}` : `${section}-${subsection}-${fieldName}`
|
|
27
|
+
if (fieldName === 'border') {
|
|
28
|
+
console.table({ fieldName, value, stateValue })
|
|
35
29
|
}
|
|
36
|
-
}, [ stateValue ])
|
|
37
30
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
31
|
+
useEffect(() => {
|
|
32
|
+
if (stateValue !== undefined && stateValue !== value) {
|
|
33
|
+
setValue(stateValue)
|
|
34
|
+
}
|
|
35
|
+
}, [stateValue])
|
|
36
|
+
|
|
37
|
+
useEffect(() => {
|
|
38
|
+
if (stateValue !== undefined && stateValue !== value && updateField) {
|
|
39
|
+
updateField(section, subsection, fieldName, value, i)
|
|
40
|
+
}
|
|
41
|
+
}, [value])
|
|
43
42
|
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
<Check className="cove-input__checkbox-check" style={{fill: activeCheckColor || '#025eaa'}}/>
|
|
43
|
+
return (
|
|
44
|
+
<div className='input-group'>
|
|
45
|
+
{label && <label>{label}</label>}
|
|
46
|
+
<div className={'cove-input__checkbox' + (size === 'small' ? '--small' : size === 'large' ? '--large' : '') + (value ? ' active' : '')} onClick={() => setValue(!value)}>
|
|
47
|
+
<div className={`cove-input__checkbox-box${activeColor ? ' custom-color' : ''}`} style={value && activeColor ? { backgroundColor: activeColor } : null}>
|
|
48
|
+
<Check className='cove-input__checkbox-check' style={{ fill: activeCheckColor || '#025eaa' }} />
|
|
49
|
+
</div>
|
|
50
|
+
<input className='cove-input--hidden' type='checkbox' name={name} checked={value || false} readOnly />
|
|
53
51
|
</div>
|
|
54
|
-
<input className="cove-input--hidden" type="checkbox" name={name} checked={value || false} readOnly/>
|
|
55
52
|
</div>
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
53
|
+
)
|
|
54
|
+
}
|
|
55
|
+
)
|
|
59
56
|
|
|
60
57
|
InputCheckbox.propTypes = {
|
|
61
58
|
label: PropTypes.string,
|
|
@@ -2,17 +2,21 @@ import React, { useState, useEffect, useLayoutEffect, useRef } from 'react'
|
|
|
2
2
|
import PropTypes from 'prop-types'
|
|
3
3
|
|
|
4
4
|
const InputGroup = ({ label, flow, children, clear, className, style, ...attributes }) => {
|
|
5
|
-
const [
|
|
6
|
-
const [
|
|
5
|
+
const [styles, setStyles] = useState({})
|
|
6
|
+
const [labelWidth, setLabelWidth] = useState(null)
|
|
7
7
|
|
|
8
8
|
const groupLabelRef = useRef(null)
|
|
9
|
-
const groupLabel =
|
|
9
|
+
const groupLabel = (
|
|
10
|
+
<div className='cove-input-group__label' ref={groupLabelRef}>
|
|
11
|
+
{label}
|
|
12
|
+
</div>
|
|
13
|
+
)
|
|
10
14
|
|
|
11
15
|
useLayoutEffect(() => {
|
|
12
16
|
if (!clear) return
|
|
13
17
|
if (!groupLabelRef.current) return
|
|
14
18
|
setLabelWidth(groupLabelRef.current.offsetWidth)
|
|
15
|
-
}, [
|
|
19
|
+
}, [clear, groupLabelRef])
|
|
16
20
|
|
|
17
21
|
useLayoutEffect(() => {
|
|
18
22
|
if (!clear) return
|
|
@@ -22,29 +26,46 @@ const InputGroup = ({ label, flow, children, clear, className, style, ...attribu
|
|
|
22
26
|
if ('right' === flow) {
|
|
23
27
|
setStyles(() => ({ paddingRight: labelWidth + 'px' }))
|
|
24
28
|
}
|
|
25
|
-
}, [
|
|
26
|
-
|
|
29
|
+
}, [clear, flow, labelWidth])
|
|
27
30
|
|
|
28
31
|
return (
|
|
29
32
|
<div className={`cove-input-group${clear ? ' clear' : ''}${className ? ' ' + className : ''}`} flow={flow} {...attributes}>
|
|
30
|
-
{label && flow ?
|
|
31
|
-
|
|
32
|
-
{'
|
|
33
|
-
|
|
34
|
-
|
|
33
|
+
{label && flow ? (
|
|
34
|
+
<>
|
|
35
|
+
{'left' === flow && (
|
|
36
|
+
<>
|
|
37
|
+
{' '}
|
|
38
|
+
{groupLabel}
|
|
39
|
+
{children}{' '}
|
|
40
|
+
</>
|
|
41
|
+
)}
|
|
42
|
+
{'right' === flow && (
|
|
43
|
+
<>
|
|
44
|
+
{' '}
|
|
45
|
+
{children}
|
|
46
|
+
{groupLabel}{' '}
|
|
47
|
+
</>
|
|
48
|
+
)}
|
|
49
|
+
{'center' === flow && children.length > 1 && (
|
|
50
|
+
<>
|
|
51
|
+
{' '}
|
|
52
|
+
{children[0]}
|
|
53
|
+
{groupLabel}
|
|
54
|
+
{children[1]}{' '}
|
|
55
|
+
</>
|
|
56
|
+
)}
|
|
57
|
+
</>
|
|
58
|
+
) : (
|
|
35
59
|
children
|
|
36
|
-
}
|
|
60
|
+
)}
|
|
37
61
|
</div>
|
|
38
62
|
)
|
|
39
63
|
}
|
|
40
64
|
|
|
41
65
|
InputGroup.propTypes = {
|
|
42
66
|
/* Text to display for the input group */
|
|
43
|
-
label: PropTypes.oneOfType([
|
|
44
|
-
|
|
45
|
-
PropTypes.object
|
|
46
|
-
]),
|
|
47
|
-
flow: PropTypes.oneOf([ 'left', 'center', 'right' ])
|
|
67
|
+
label: PropTypes.oneOfType([PropTypes.string, PropTypes.object]),
|
|
68
|
+
flow: PropTypes.oneOf(['left', 'center', 'right'])
|
|
48
69
|
}
|
|
49
70
|
|
|
50
71
|
export default InputGroup
|
|
@@ -2,44 +2,48 @@ import React, { memo } from 'react'
|
|
|
2
2
|
|
|
3
3
|
import '../../styles/v2/components/input/index.scss'
|
|
4
4
|
|
|
5
|
-
const InputSelect = memo((
|
|
6
|
-
{
|
|
7
|
-
label,
|
|
8
|
-
value,
|
|
9
|
-
options,
|
|
10
|
-
fieldName,
|
|
11
|
-
section = null,
|
|
12
|
-
subsection = null,
|
|
13
|
-
required = false,
|
|
14
|
-
updateField,
|
|
15
|
-
initial: initialValue,
|
|
16
|
-
...attributes
|
|
17
|
-
}
|
|
18
|
-
) => {
|
|
19
|
-
|
|
5
|
+
const InputSelect = memo(({ label, value, options, fieldName, section = null, subsection = null, required = false, updateField, initial: initialValue, ...attributes }) => {
|
|
20
6
|
let optionsJsx = ''
|
|
21
7
|
|
|
22
8
|
if (Array.isArray(options)) {
|
|
23
9
|
//Handle basic array
|
|
24
|
-
optionsJsx = options.map(optionName =>
|
|
10
|
+
optionsJsx = options.map(optionName => (
|
|
11
|
+
<option value={optionName} key={optionName}>
|
|
12
|
+
{optionName}
|
|
13
|
+
</option>
|
|
14
|
+
))
|
|
25
15
|
} else {
|
|
26
16
|
//Handle object with value/name pairs
|
|
27
17
|
optionsJsx = []
|
|
28
|
-
for (const [
|
|
29
|
-
optionsJsx.push(
|
|
18
|
+
for (const [optionValue, optionName] of Object.entries(options)) {
|
|
19
|
+
optionsJsx.push(
|
|
20
|
+
<option value={optionValue} key={optionValue}>
|
|
21
|
+
{optionName}
|
|
22
|
+
</option>
|
|
23
|
+
)
|
|
30
24
|
}
|
|
31
25
|
}
|
|
32
26
|
|
|
33
27
|
if (initialValue) {
|
|
34
|
-
optionsJsx.unshift(
|
|
28
|
+
optionsJsx.unshift(
|
|
29
|
+
<option value='' key='initial'>
|
|
30
|
+
{initialValue}
|
|
31
|
+
</option>
|
|
32
|
+
)
|
|
35
33
|
}
|
|
36
34
|
|
|
37
35
|
return (
|
|
38
36
|
<label>
|
|
39
|
-
{label && <span className=
|
|
40
|
-
<select
|
|
41
|
-
|
|
42
|
-
|
|
37
|
+
{label && <span className='edit-label cove-input__label'>{label}</span>}
|
|
38
|
+
<select
|
|
39
|
+
className={required && !value ? 'warning' : ''}
|
|
40
|
+
name={fieldName}
|
|
41
|
+
value={value}
|
|
42
|
+
onChange={event => {
|
|
43
|
+
updateField(section, subsection, fieldName, event.target.value)
|
|
44
|
+
}}
|
|
45
|
+
{...attributes}
|
|
46
|
+
>
|
|
43
47
|
{optionsJsx}
|
|
44
48
|
</select>
|
|
45
49
|
</label>
|