@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.
Files changed (84) hide show
  1. package/assets/icon-command.svg +3 -0
  2. package/assets/icon-rotate-left.svg +3 -0
  3. package/assets/icon-sankey.svg +1 -0
  4. package/assets/icon-table.svg +1 -0
  5. package/components/AdvancedEditor.jsx +9 -0
  6. package/components/DataTable/DataTable.tsx +37 -13
  7. package/components/DataTable/DataTableStandAlone.tsx +15 -0
  8. package/components/DataTable/components/CellAnchor.tsx +3 -1
  9. package/components/DataTable/components/ChartHeader.tsx +48 -12
  10. package/components/DataTable/components/DataTableEditorPanel.tsx +42 -0
  11. package/components/DataTable/components/ExpandCollapse.tsx +22 -16
  12. package/components/DataTable/components/MapHeader.tsx +10 -5
  13. package/components/DataTable/helpers/chartCellMatrix.tsx +2 -2
  14. package/components/DataTable/helpers/customColumns.ts +4 -2
  15. package/components/DataTable/helpers/getChartCellValue.ts +4 -2
  16. package/components/DataTable/helpers/getDataSeriesColumns.ts +9 -1
  17. package/components/DataTable/helpers/mapCellMatrix.tsx +2 -2
  18. package/components/DataTable/types/TableConfig.ts +7 -7
  19. package/components/EditorPanel/ColumnsEditor.tsx +312 -0
  20. package/components/EditorPanel/DataTableEditor.tsx +42 -27
  21. package/components/Filters.jsx +35 -17
  22. package/components/Layout/components/Responsive.tsx +184 -0
  23. package/components/Layout/components/Sidebar/components/Sidebar.tsx +47 -0
  24. package/components/Layout/components/Sidebar/components/sidebar.styles.scss +902 -0
  25. package/components/Layout/components/Sidebar/index.tsx +3 -0
  26. package/components/Layout/components/Visualization/index.tsx +79 -0
  27. package/components/Layout/components/Visualization/visualizations.scss +33 -0
  28. package/components/Layout/index.tsx +11 -0
  29. package/components/Layout/styles/editor-grid-view.scss +156 -0
  30. package/components/Layout/styles/editor-utils.scss +197 -0
  31. package/components/Layout/styles/editor.scss +144 -0
  32. package/components/LegendCircle.jsx +4 -3
  33. package/components/MediaControls.jsx +1 -1
  34. package/components/MultiSelect/MultiSelect.tsx +39 -20
  35. package/components/MultiSelect/multiselect.styles.css +44 -27
  36. package/components/NestedDropdown/NestedDropdown.tsx +257 -0
  37. package/components/NestedDropdown/index.ts +1 -0
  38. package/components/NestedDropdown/nesteddropdown.styles.css +70 -0
  39. package/components/Table/Table.tsx +8 -6
  40. package/components/Table/components/Row.tsx +6 -2
  41. package/components/Table/types/RowType.ts +3 -0
  42. package/components/Waiting.jsx +11 -1
  43. package/components/_stories/MultiSelect.stories.tsx +10 -1
  44. package/components/_stories/NestedDropdown.stories.tsx +58 -0
  45. package/components/_stories/styles.scss +1 -0
  46. package/components/createBarElement.jsx +120 -0
  47. package/components/elements/ScreenReaderText.tsx +8 -0
  48. package/components/elements/SkipTo.tsx +46 -0
  49. package/components/managers/DataDesigner.tsx +18 -18
  50. package/components/ui/Icon.tsx +9 -1
  51. package/components/ui/Title/Title.scss +7 -1
  52. package/components/ui/Title/index.tsx +3 -3
  53. package/components/ui/Tooltip.jsx +1 -1
  54. package/data/colorPalettes.js +1 -6
  55. package/helpers/cove/accessibility.ts +23 -0
  56. package/helpers/cove/date.ts +19 -0
  57. package/helpers/{coveUpdateWorker.js → coveUpdateWorker.ts} +9 -5
  58. package/helpers/isDomainExternal.js +14 -0
  59. package/helpers/queryStringUtils.js +26 -0
  60. package/helpers/tests/updateFieldFactory.test.ts +89 -0
  61. package/helpers/updateFieldFactory.ts +38 -0
  62. package/helpers/useDataVizClasses.js +7 -7
  63. package/helpers/ver/4.24.3.ts +56 -0
  64. package/package.json +4 -3
  65. package/styles/_data-table.scss +8 -13
  66. package/styles/_global.scss +7 -4
  67. package/styles/_variables.scss +3 -0
  68. package/styles/base.scss +4 -14
  69. package/styles/v2/base/index.scss +1 -1
  70. package/styles/v2/components/ui/tooltip.scss +0 -21
  71. package/types/Axis.ts +3 -0
  72. package/types/BaseVisualizationType.ts +1 -0
  73. package/types/ConfidenceInterval.ts +1 -0
  74. package/types/ConfigureData.ts +8 -0
  75. package/types/DataDescription.ts +9 -0
  76. package/types/Legend.ts +18 -0
  77. package/types/Region.ts +10 -0
  78. package/types/Runtime.ts +2 -0
  79. package/types/Table.ts +2 -1
  80. package/types/UpdateFieldFunc.ts +1 -1
  81. package/types/Visualization.ts +19 -10
  82. package/components/DataTable/components/SkipNav.tsx +0 -7
  83. package/helpers/cove/date.js +0 -9
  84. 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