@cdc/core 4.24.2 → 4.24.4
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/assets/icon-command.svg +3 -0
- package/assets/icon-rotate-left.svg +3 -0
- package/assets/icon-sankey.svg +1 -0
- package/assets/icon-table.svg +1 -0
- package/components/AdvancedEditor.jsx +9 -0
- package/components/DataTable/DataTable.tsx +37 -13
- package/components/DataTable/DataTableStandAlone.tsx +15 -0
- package/components/DataTable/components/CellAnchor.tsx +3 -1
- package/components/DataTable/components/ChartHeader.tsx +48 -12
- package/components/DataTable/components/DataTableEditorPanel.tsx +42 -0
- package/components/DataTable/components/ExpandCollapse.tsx +22 -16
- package/components/DataTable/components/MapHeader.tsx +10 -5
- package/components/DataTable/helpers/chartCellMatrix.tsx +2 -2
- package/components/DataTable/helpers/customColumns.ts +4 -2
- package/components/DataTable/helpers/getChartCellValue.ts +4 -2
- package/components/DataTable/helpers/getDataSeriesColumns.ts +9 -1
- package/components/DataTable/helpers/mapCellMatrix.tsx +2 -2
- package/components/DataTable/types/TableConfig.ts +7 -7
- package/components/EditorPanel/ColumnsEditor.tsx +312 -0
- package/components/EditorPanel/DataTableEditor.tsx +42 -27
- package/components/Filters.jsx +35 -17
- package/components/Layout/components/Responsive.tsx +184 -0
- package/components/Layout/components/Sidebar/components/Sidebar.tsx +47 -0
- package/components/Layout/components/Sidebar/components/sidebar.styles.scss +902 -0
- package/components/Layout/components/Sidebar/index.tsx +3 -0
- package/components/Layout/components/Visualization/index.tsx +79 -0
- package/components/Layout/components/Visualization/visualizations.scss +33 -0
- package/components/Layout/index.tsx +11 -0
- package/components/Layout/styles/editor-grid-view.scss +156 -0
- package/components/Layout/styles/editor-utils.scss +197 -0
- package/components/Layout/styles/editor.scss +144 -0
- package/components/LegendCircle.jsx +4 -3
- package/components/MediaControls.jsx +1 -1
- package/components/MultiSelect/MultiSelect.tsx +39 -20
- package/components/MultiSelect/multiselect.styles.css +44 -27
- package/components/NestedDropdown/NestedDropdown.tsx +257 -0
- package/components/NestedDropdown/index.ts +1 -0
- package/components/NestedDropdown/nesteddropdown.styles.css +70 -0
- package/components/Table/Table.tsx +8 -6
- package/components/Table/components/Row.tsx +6 -2
- package/components/Table/types/RowType.ts +3 -0
- package/components/Waiting.jsx +11 -1
- package/components/_stories/MultiSelect.stories.tsx +10 -1
- package/components/_stories/NestedDropdown.stories.tsx +58 -0
- package/components/_stories/styles.scss +1 -0
- package/components/createBarElement.jsx +120 -0
- package/components/elements/ScreenReaderText.tsx +8 -0
- package/components/elements/SkipTo.tsx +46 -0
- package/components/managers/DataDesigner.tsx +18 -18
- package/components/ui/Icon.tsx +9 -1
- package/components/ui/Title/Title.scss +7 -1
- package/components/ui/Title/index.tsx +3 -3
- package/components/ui/Tooltip.jsx +1 -1
- package/data/colorPalettes.js +1 -6
- package/helpers/cove/accessibility.ts +23 -0
- package/helpers/cove/date.ts +19 -0
- package/helpers/{coveUpdateWorker.js → coveUpdateWorker.ts} +9 -5
- package/helpers/isDomainExternal.js +14 -0
- package/helpers/queryStringUtils.js +26 -0
- package/helpers/tests/updateFieldFactory.test.ts +89 -0
- package/helpers/updateFieldFactory.ts +38 -0
- package/helpers/useDataVizClasses.js +7 -7
- package/helpers/ver/4.24.3.ts +56 -0
- package/package.json +4 -3
- package/styles/_data-table.scss +8 -13
- package/styles/_global.scss +7 -4
- package/styles/_variables.scss +3 -0
- package/styles/base.scss +4 -14
- package/styles/v2/base/index.scss +1 -1
- package/styles/v2/components/ui/tooltip.scss +0 -21
- package/types/Axis.ts +3 -0
- package/types/BaseVisualizationType.ts +1 -0
- package/types/ConfidenceInterval.ts +1 -0
- package/types/ConfigureData.ts +8 -0
- package/types/DataDescription.ts +9 -0
- package/types/Legend.ts +18 -0
- package/types/Region.ts +10 -0
- package/types/Runtime.ts +2 -0
- package/types/Table.ts +2 -1
- package/types/UpdateFieldFunc.ts +1 -1
- package/types/Visualization.ts +19 -10
- package/components/DataTable/components/SkipNav.tsx +0 -7
- package/helpers/cove/date.js +0 -9
- package/helpers/ver/4.23.js +0 -10
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
import React, { useState, useRef, useEffect, useCallback } from 'react'
|
|
2
|
+
import '../styles/editor-utils.scss'
|
|
3
|
+
import '../styles/editor.scss'
|
|
4
|
+
|
|
5
|
+
import Icon from '../../ui/Icon'
|
|
6
|
+
|
|
7
|
+
const breakpoints = [
|
|
8
|
+
'360', // xxs (mobile) 0 - 360
|
|
9
|
+
'480', // xs
|
|
10
|
+
'768', // sm
|
|
11
|
+
'960', // md
|
|
12
|
+
'1170', // lg
|
|
13
|
+
'1280' // xl
|
|
14
|
+
]
|
|
15
|
+
|
|
16
|
+
const os = navigator.userAgent.indexOf('Win') !== -1 ? 'Win' : navigator.userAgent.indexOf('Mac') !== -1 ? 'MacOS' : null
|
|
17
|
+
|
|
18
|
+
const Responsive = ({ children, isEditor }) => {
|
|
19
|
+
const [displayPanel, setDisplayPanel] = useState(false)
|
|
20
|
+
const [displayGrid, setDisplayGrid] = useState(false)
|
|
21
|
+
const [viewportPreview, setViewportPreview] = useState(null)
|
|
22
|
+
const [rotateAnimation, setRotateAnimation] = useState(false)
|
|
23
|
+
const [showConfirm, setShowConfirm] = useState(false)
|
|
24
|
+
const [previewDimensions, setPreviewDimensions] = useState<{ width: number; height: number }>(null)
|
|
25
|
+
|
|
26
|
+
const resetIcon = useRef(null)
|
|
27
|
+
const editorPanelRef = useRef(null)
|
|
28
|
+
const componentContainerRef = useRef(null)
|
|
29
|
+
|
|
30
|
+
const viewportPreviewController = useCallback(
|
|
31
|
+
breakpoint => {
|
|
32
|
+
return setViewportPreview(prevState => (prevState !== breakpoint ? breakpoint : null))
|
|
33
|
+
},
|
|
34
|
+
[viewportPreview]
|
|
35
|
+
)
|
|
36
|
+
|
|
37
|
+
const onKeypress = key => {
|
|
38
|
+
if (key.code === 'KeyL' && key.ctrlKey) setDisplayPanel(display => !display)
|
|
39
|
+
const viewportCommandKey = os === 'MacOS' ? key.metaKey : key.altKey
|
|
40
|
+
if (viewportCommandKey) {
|
|
41
|
+
let keyIndex = key.key
|
|
42
|
+
|
|
43
|
+
// Validates that the hotkey pressed is a number, and that
|
|
44
|
+
// the number is within the range of the provided breakpoint list range.
|
|
45
|
+
if (!isNaN(keyIndex)) {
|
|
46
|
+
if (keyIndex <= breakpoints.length) {
|
|
47
|
+
key.preventDefault()
|
|
48
|
+
viewportPreviewController(breakpoints[keyIndex - 1])
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
if (!viewportCommandKey) {
|
|
54
|
+
if (key.code === 'KeyG') setDisplayGrid(display => !display)
|
|
55
|
+
if (key.code === 'KeyR') resetPreview()
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
// Set and clean up the event listener for the hotkeys
|
|
60
|
+
useEffect(() => {
|
|
61
|
+
document.addEventListener('keydown', onKeypress)
|
|
62
|
+
return () => document.removeEventListener('keydown', onKeypress)
|
|
63
|
+
}, [])
|
|
64
|
+
|
|
65
|
+
//Reset Viewport Preview
|
|
66
|
+
const resetPreview = useCallback(() => {
|
|
67
|
+
if (!rotateAnimation && resetIcon.current) {
|
|
68
|
+
setViewportPreview(null)
|
|
69
|
+
setRotateAnimation(true)
|
|
70
|
+
setDisplayGrid(false)
|
|
71
|
+
resetIcon.current.style.transition = 'transform 800ms cubic-bezier(0.16, 1, 0.3, 1)'
|
|
72
|
+
resetIcon.current.style.transform = 'rotate(-360deg)'
|
|
73
|
+
|
|
74
|
+
const timeoutShow = setTimeout(() => {
|
|
75
|
+
setRotateAnimation(false)
|
|
76
|
+
resetIcon.current.style.transition = null
|
|
77
|
+
resetIcon.current.style.transform = 'rotate(0deg)'
|
|
78
|
+
resetIcon.current.style.transform = null
|
|
79
|
+
}, 400)
|
|
80
|
+
|
|
81
|
+
return () => clearTimeout(timeoutShow)
|
|
82
|
+
}
|
|
83
|
+
}, [rotateAnimation])
|
|
84
|
+
|
|
85
|
+
// Toggle the grid display with the viewport preview
|
|
86
|
+
useEffect(() => {
|
|
87
|
+
return viewportPreview ? setDisplayGrid(true) : setDisplayGrid(false)
|
|
88
|
+
}, [viewportPreview])
|
|
89
|
+
|
|
90
|
+
// Observe and set editor component widths
|
|
91
|
+
useEffect(() => {
|
|
92
|
+
if (!componentContainerRef.current) return
|
|
93
|
+
|
|
94
|
+
let resizeObserver = new ResizeObserver(entries => {
|
|
95
|
+
for (let entry of entries) {
|
|
96
|
+
let { width, height } = entry.contentRect
|
|
97
|
+
setPreviewDimensions({ width, height })
|
|
98
|
+
}
|
|
99
|
+
})
|
|
100
|
+
|
|
101
|
+
resizeObserver.observe(componentContainerRef.current)
|
|
102
|
+
|
|
103
|
+
return () => {
|
|
104
|
+
if (!resizeObserver) return
|
|
105
|
+
resizeObserver.disconnect()
|
|
106
|
+
resizeObserver = null
|
|
107
|
+
}
|
|
108
|
+
})
|
|
109
|
+
|
|
110
|
+
const onBackClick = () => setDisplayPanel(!displayPanel)
|
|
111
|
+
|
|
112
|
+
if (!isEditor || !displayPanel) return children
|
|
113
|
+
|
|
114
|
+
return (
|
|
115
|
+
<div className='cove-editor__content' data-grid={displayGrid || null}>
|
|
116
|
+
<div className='cove-editor__content-wrap--x' style={viewportPreview ? { maxWidth: viewportPreview + 'px', minWidth: 'unset' } : null}>
|
|
117
|
+
<div className='cove-editor__content-wrap--y'>
|
|
118
|
+
<div className='cove-editor-utils__breakpoints--px'>
|
|
119
|
+
{displayGrid && displayPanel && (
|
|
120
|
+
<>
|
|
121
|
+
{Math.round(previewDimensions.width)}
|
|
122
|
+
<span className='mx-1' style={{ fontSize: '0.675rem' }}>
|
|
123
|
+
✕
|
|
124
|
+
</span>
|
|
125
|
+
{Math.round(previewDimensions.height)}
|
|
126
|
+
</>
|
|
127
|
+
)}
|
|
128
|
+
</div>
|
|
129
|
+
<div className='cove-editor__grid-caret--top' ref={componentContainerRef}>
|
|
130
|
+
<div className='cove-editor__grid-caret--bottom'>{children}</div>
|
|
131
|
+
</div>
|
|
132
|
+
</div>
|
|
133
|
+
</div>
|
|
134
|
+
<div className='cove-editor-utils__hotkeys'>
|
|
135
|
+
<div className='cove-editor-utils__hotkeys--left'>
|
|
136
|
+
<p className={displayPanel ? 'hotkey--active' : null}>Editor</p>
|
|
137
|
+
<p className={displayGrid ? 'hotkey--active' : null}>Grid</p>
|
|
138
|
+
<p className={rotateAnimation ? 'hotkey--active' : null}>Reset</p>
|
|
139
|
+
<p className={viewportPreview ? 'hotkey--active' : null}>View</p>
|
|
140
|
+
</div>
|
|
141
|
+
<div className='cove-editor-utils__hotkeys--right'>
|
|
142
|
+
<p className={displayPanel ? 'hotkey--active' : null}>esc</p>
|
|
143
|
+
<p className={displayGrid ? 'hotkey--active' : null}>G</p>
|
|
144
|
+
<p className={rotateAnimation ? 'hotkey--active' : null}>R</p>
|
|
145
|
+
<p className={viewportPreview ? 'hotkey--active' : null}>
|
|
146
|
+
{os === 'MacOS' ? <Icon style={{ marginRight: '0.25rem' }} display='command' size={12} /> : 'Alt'} + {viewportPreview ? breakpoints.indexOf(viewportPreview) + 1 : `[1 - ${breakpoints.length}]`}
|
|
147
|
+
</p>
|
|
148
|
+
</div>
|
|
149
|
+
</div>
|
|
150
|
+
|
|
151
|
+
<div className='cove-editor-utils__breakpoints'>
|
|
152
|
+
<ul className={`cove-editor-utils__breakpoints-list${viewportPreview ? ' has-active' : ''}`}>
|
|
153
|
+
<button
|
|
154
|
+
className='cove-editor-utils__breakpoints-item'
|
|
155
|
+
onClick={() => {
|
|
156
|
+
setDisplayGrid(display => !display)
|
|
157
|
+
}}
|
|
158
|
+
>
|
|
159
|
+
<div className='cove-editor-utils__breakpoints-grid'>
|
|
160
|
+
<Icon display='grid' />
|
|
161
|
+
</div>
|
|
162
|
+
</button>
|
|
163
|
+
{breakpoints.map((breakpoint, index) => (
|
|
164
|
+
<button className={`cove-editor-utils__breakpoints-item${viewportPreview === breakpoint ? ' active' : ''}`} onClick={() => viewportPreviewController(breakpoint)} key={index}>
|
|
165
|
+
{breakpoint}px
|
|
166
|
+
</button>
|
|
167
|
+
))}
|
|
168
|
+
<button
|
|
169
|
+
className='cove-editor-utils__breakpoints-item'
|
|
170
|
+
onClick={() => {
|
|
171
|
+
resetPreview()
|
|
172
|
+
}}
|
|
173
|
+
>
|
|
174
|
+
<div className='cove-editor-utils__breakpoints-reset' ref={resetIcon}>
|
|
175
|
+
<Icon display='rotateLeft' />
|
|
176
|
+
</div>
|
|
177
|
+
</button>
|
|
178
|
+
</ul>
|
|
179
|
+
</div>
|
|
180
|
+
</div>
|
|
181
|
+
)
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
export default Responsive
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import React from 'react'
|
|
2
|
+
import './sidebar.styles.scss'
|
|
3
|
+
|
|
4
|
+
type SidebarProps = {
|
|
5
|
+
// whether or not the viz is within a dashboard
|
|
6
|
+
isDashboard: boolean
|
|
7
|
+
// show/hide the sidebar
|
|
8
|
+
displayPanel: boolean
|
|
9
|
+
// sidebarTitle
|
|
10
|
+
title: string
|
|
11
|
+
// inner content
|
|
12
|
+
children: React.ReactNode
|
|
13
|
+
// on arrow toggle
|
|
14
|
+
onBackClick: () => void
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
const Sidebar: React.FC<SidebarProps> = props => {
|
|
18
|
+
const { displayPanel = false, isDashboard = false, title = 'Configure Visualization', children, onBackClick } = props
|
|
19
|
+
|
|
20
|
+
const getSectionClasses = () => {
|
|
21
|
+
const sectionClasses = ['editor-panel', 'cove', 'sidebar']
|
|
22
|
+
if (!displayPanel) sectionClasses.push('hidden')
|
|
23
|
+
if (isDashboard) sectionClasses.push('dashboard')
|
|
24
|
+
return sectionClasses
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
const getButtonClasses = () => {
|
|
28
|
+
const buttonClasses = []
|
|
29
|
+
if (displayPanel) buttonClasses.push('editor-panel__toggle')
|
|
30
|
+
if (!displayPanel) buttonClasses.push('collapsed', 'editor-panel__toggle')
|
|
31
|
+
return buttonClasses
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
return (
|
|
35
|
+
<>
|
|
36
|
+
<button className={getButtonClasses().join(' ')} title={displayPanel ? `Collapse Editor` : `Expand Editor`} onClick={onBackClick}></button>
|
|
37
|
+
<section className={getSectionClasses().join(' ')}>
|
|
38
|
+
<h2 className='editor-panel__title'>{title}</h2>
|
|
39
|
+
<section className='form-container' data-html2canvas-ignore>
|
|
40
|
+
{children}
|
|
41
|
+
</section>
|
|
42
|
+
</section>
|
|
43
|
+
</>
|
|
44
|
+
)
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
export default Sidebar
|