@cdc/core 4.25.3 → 4.25.5-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/assets/icon-close.svg +1 -1
- package/components/DataTable/DataTable.tsx +18 -13
- package/components/DataTable/components/CellAnchor.tsx +1 -1
- package/components/DataTable/components/ChartHeader.tsx +2 -1
- package/components/DataTable/components/MapHeader.tsx +1 -0
- package/components/DataTable/helpers/chartCellMatrix.tsx +2 -1
- package/components/DataTable/helpers/mapCellMatrix.tsx +17 -7
- package/components/DownloadButton.tsx +17 -2
- package/components/EditorPanel/DataTableEditor.tsx +1 -1
- package/components/EditorPanel/Inputs.tsx +12 -4
- package/components/EditorPanel/VizFilterEditor/NestedDropdownEditor.tsx +2 -1
- package/components/EditorPanel/VizFilterEditor/VizFilterEditor.tsx +3 -1
- package/components/Filters/Filters.tsx +168 -429
- package/components/Filters/components/Dropdown.tsx +39 -0
- package/components/Filters/components/Tabs.tsx +82 -0
- package/components/Filters/helpers/getChangedFilters.ts +31 -0
- package/components/Filters/helpers/getNestedOptions.ts +2 -2
- package/components/Filters/helpers/getNewRuntime.ts +35 -0
- package/components/Filters/helpers/handleSorting.ts +2 -2
- package/components/Filters/helpers/tests/getChangedFilters.test.ts +92 -0
- package/components/Filters/helpers/tests/getNestedOptions.test.ts +31 -0
- package/components/Filters/helpers/tests/getNewRuntime.test.ts +82 -0
- package/components/Filters/index.ts +1 -1
- package/components/Layout/components/Visualization/index.tsx +3 -3
- package/components/Legend/Legend.Gradient.tsx +66 -23
- package/components/MultiSelect/multiselect.styles.css +2 -0
- package/components/NestedDropdown/NestedDropdown.tsx +2 -2
- package/components/RichTooltip/RichTooltip.tsx +37 -0
- package/components/RichTooltip/richTooltip.css +16 -0
- package/components/Table/Table.tsx +142 -142
- package/components/Table/components/Row.tsx +1 -1
- package/components/Table/table.styles.css +10 -0
- package/components/_stories/DataTable.stories.tsx +9 -2
- package/components/_stories/Table.stories.tsx +1 -1
- package/components/_stories/styles.scss +0 -4
- package/components/ui/Accordion.jsx +8 -1
- package/components/ui/Title/index.tsx +4 -1
- package/components/ui/Title/{Title.scss → title.styles.css} +0 -2
- package/components/ui/_stories/Colors.stories.mdx +220 -0
- package/components/ui/_stories/IconGallery.stories.mdx +14 -0
- package/components/ui/_stories/Title.stories.tsx +29 -4
- package/components/ui/accordion.styles.css +3 -0
- package/data/colorPalettes.js +0 -1
- package/dist/cove-main.css +3 -8
- package/dist/cove-main.css.map +1 -1
- package/helpers/constants.ts +6 -0
- package/helpers/cove/accessibility.ts +7 -8
- package/helpers/coveUpdateWorker.ts +5 -1
- package/helpers/filterOrderOptions.ts +17 -0
- package/helpers/isNumber.ts +20 -0
- package/helpers/isRightAlignedTableValue.js +1 -1
- package/helpers/pivotData.ts +16 -11
- package/helpers/tests/pivotData.test.ts +74 -0
- package/helpers/ver/4.25.3.ts +25 -2
- package/helpers/ver/4.25.4.ts +33 -0
- package/helpers/ver/tests/4.25.4.test.ts +24 -0
- package/helpers/viewports.ts +4 -0
- package/package.json +2 -3
- package/styles/_global-variables.scss +3 -0
- package/styles/_reset.scss +0 -6
- package/styles/v2/main.scss +0 -5
- package/types/General.ts +1 -0
- package/types/Legend.ts +1 -0
- package/LICENSE +0 -201
- package/components/ui/_stories/Colors.stories.tsx +0 -92
- package/components/ui/_stories/Icon.stories.tsx +0 -29
- package/helpers/cove/fontSettings.ts +0 -2
- package/helpers/isNumber.js +0 -24
- package/helpers/isNumberLog.js +0 -18
package/assets/icon-close.svg
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor">
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" height="1em" width="1em" viewBox="0 0 24 24" fill="currentColor">
|
|
2
2
|
<path d="M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12 19 6.41z"/>
|
|
3
3
|
</svg>
|
|
@@ -27,7 +27,6 @@ import _ from 'lodash'
|
|
|
27
27
|
import { getDataSeriesColumns } from './helpers/getDataSeriesColumns'
|
|
28
28
|
|
|
29
29
|
export type DataTableProps = {
|
|
30
|
-
applyLegendToRow?: Function
|
|
31
30
|
colorScale?: Function
|
|
32
31
|
columns?: Record<string, Column>
|
|
33
32
|
config: TableConfig
|
|
@@ -35,7 +34,7 @@ export type DataTableProps = {
|
|
|
35
34
|
defaultSortBy?: string
|
|
36
35
|
displayGeoName?: (row: string) => string
|
|
37
36
|
expandDataTable: boolean
|
|
38
|
-
formatLegendLocation?: (row: string) => string
|
|
37
|
+
formatLegendLocation?: (row: string, runtimeLookup: string) => string
|
|
39
38
|
groupBy?: string
|
|
40
39
|
headerColor?: string
|
|
41
40
|
imageRef?: string
|
|
@@ -58,20 +57,20 @@ export type DataTableProps = {
|
|
|
58
57
|
/* eslint-disable jsx-a11y/no-noninteractive-tabindex, jsx-a11y/no-static-element-interactions */
|
|
59
58
|
const DataTable = (props: DataTableProps) => {
|
|
60
59
|
const {
|
|
60
|
+
columns,
|
|
61
61
|
config,
|
|
62
62
|
dataConfig,
|
|
63
63
|
defaultSortBy,
|
|
64
64
|
displayGeoName,
|
|
65
|
-
tableTitle,
|
|
66
|
-
vizTitle,
|
|
67
|
-
rawData,
|
|
68
|
-
runtimeData: parentRuntimeData,
|
|
69
|
-
headerColor,
|
|
70
65
|
expandDataTable,
|
|
71
|
-
columns,
|
|
72
|
-
viewport,
|
|
73
66
|
formatLegendLocation,
|
|
67
|
+
headerColor,
|
|
68
|
+
rawData,
|
|
69
|
+
runtimeData: parentRuntimeData,
|
|
74
70
|
tabbingId,
|
|
71
|
+
tableTitle,
|
|
72
|
+
viewport,
|
|
73
|
+
vizTitle,
|
|
75
74
|
wrapColumns
|
|
76
75
|
} = props
|
|
77
76
|
const runtimeData = useMemo(() => {
|
|
@@ -248,9 +247,14 @@ const DataTable = (props: DataTableProps) => {
|
|
|
248
247
|
const csvData = config.table?.downloadVisibleDataOnly ? visibleData : rawData
|
|
249
248
|
|
|
250
249
|
// only use fullGeoName on County maps and no other
|
|
251
|
-
if (config.general?.geoType === 'us-county') {
|
|
250
|
+
if (config.general?.geoType === 'us-county' || config.table.showFullGeoNameInCSV) {
|
|
252
251
|
// Add column for full Geo name along with State
|
|
253
|
-
return csvData.map(row =>
|
|
252
|
+
return csvData.map(row => {
|
|
253
|
+
return {
|
|
254
|
+
FullGeoName: formatLegendLocation(row[config.columns.geo.name]),
|
|
255
|
+
...row
|
|
256
|
+
}
|
|
257
|
+
})
|
|
254
258
|
} else {
|
|
255
259
|
return csvData
|
|
256
260
|
}
|
|
@@ -275,7 +279,7 @@ const DataTable = (props: DataTableProps) => {
|
|
|
275
279
|
|
|
276
280
|
const childrenMatrix =
|
|
277
281
|
config.type === 'map'
|
|
278
|
-
? mapCellMatrix({ rows, wrapColumns,
|
|
282
|
+
? mapCellMatrix({ ...props, rows, wrapColumns, runtimeData, viewport })
|
|
279
283
|
: chartCellMatrix({ rows, ...props, runtimeData, isVertical, sortBy, hasRowType, viewport })
|
|
280
284
|
|
|
281
285
|
// If every value in a column is a number, record the column index so the header and cells can be right-aligned
|
|
@@ -352,7 +356,8 @@ const DataTable = (props: DataTableProps) => {
|
|
|
352
356
|
}`,
|
|
353
357
|
'aria-live': 'assertive',
|
|
354
358
|
'aria-rowcount': config?.data?.length ? config.data.length : -1,
|
|
355
|
-
hidden: !expanded
|
|
359
|
+
hidden: !expanded,
|
|
360
|
+
cellMinWidth: 100
|
|
356
361
|
}}
|
|
357
362
|
rightAlignedCols={rightAlignedCols}
|
|
358
363
|
/>
|
|
@@ -6,7 +6,7 @@ const CellAnchor = ({ markup, row, columns, navigationHandler, mapZoomHandler })
|
|
|
6
6
|
if (columns.navigate && row[columns.navigate.name]) {
|
|
7
7
|
return (
|
|
8
8
|
<span
|
|
9
|
-
onClick={() => navigationHandler(row[columns.navigate.name])}
|
|
9
|
+
onClick={() => navigationHandler('_blank', row[columns.navigate.name])}
|
|
10
10
|
className='table-link'
|
|
11
11
|
title='Click for more information (Opens in a new window)'
|
|
12
12
|
role='link'
|
|
@@ -4,6 +4,7 @@ import { getDataSeriesColumns } from '../helpers/getDataSeriesColumns'
|
|
|
4
4
|
import ScreenReaderText from '@cdc/core/components/elements/ScreenReaderText'
|
|
5
5
|
import { SortIcon } from './SortIcon'
|
|
6
6
|
import { getNewSortBy } from '../helpers/getNewSortBy'
|
|
7
|
+
import parse from 'html-react-parser'
|
|
7
8
|
|
|
8
9
|
type ChartHeaderProps = { data; isVertical; config; setSortBy; sortBy; hasRowType?; viewport; rightAlignedCols }
|
|
9
10
|
|
|
@@ -75,7 +76,7 @@ const ChartHeader = ({
|
|
|
75
76
|
return (
|
|
76
77
|
<tr>
|
|
77
78
|
{dataSeriesColumns.map((column, index) => {
|
|
78
|
-
const text = getSeriesName(column, config)
|
|
79
|
+
const text = parse(getSeriesName(column, config))
|
|
79
80
|
const newSortBy = getNewSortBy(sortBy, column, index)
|
|
80
81
|
const sortByAsc = sortBy.column === column ? sortBy.asc : undefined
|
|
81
82
|
const isSortedCol = column === sortBy.column && !hasRowType
|
|
@@ -36,6 +36,7 @@ const MapHeader = ({ columns, config, indexTitle, sortBy, setSortBy, rightAligne
|
|
|
36
36
|
return (
|
|
37
37
|
<th
|
|
38
38
|
style={{
|
|
39
|
+
minWidth: (config.table.cellMinWidth || 0) + 'px',
|
|
39
40
|
textAlign: rightAlignedCols && rightAlignedCols[index] ? 'right' : '',
|
|
40
41
|
paddingRight: '1.3em'
|
|
41
42
|
}}
|
|
@@ -7,6 +7,7 @@ import { getDataSeriesColumns } from './getDataSeriesColumns'
|
|
|
7
7
|
import { ReactNode } from 'react'
|
|
8
8
|
import { CellMatrix, GroupCellMatrix } from '../../Table/types/CellMatrix'
|
|
9
9
|
import { getRowType } from './getRowType'
|
|
10
|
+
import parse from 'html-react-parser'
|
|
10
11
|
|
|
11
12
|
type ChartRowsProps = DataTableProps & {
|
|
12
13
|
rows: string[]
|
|
@@ -84,7 +85,7 @@ const chartCellArray = ({
|
|
|
84
85
|
? [
|
|
85
86
|
<>
|
|
86
87
|
{colorScale && colorScale(seriesName) && <LegendShape fill={colorScale(seriesName)} />}
|
|
87
|
-
{seriesName}
|
|
88
|
+
{parse(seriesName)}
|
|
88
89
|
</>
|
|
89
90
|
]
|
|
90
91
|
: []
|
|
@@ -4,6 +4,7 @@ import { DataTableProps } from '../DataTable'
|
|
|
4
4
|
import { ReactNode } from 'react'
|
|
5
5
|
import { displayDataAsText } from '@cdc/core/helpers/displayDataAsText'
|
|
6
6
|
import _ from 'lodash'
|
|
7
|
+
import { applyLegendToRow } from '@cdc/map/src/helpers/applyLegendToRow'
|
|
7
8
|
|
|
8
9
|
type MapRowsProps = DataTableProps & {
|
|
9
10
|
rows: string[]
|
|
@@ -72,27 +73,36 @@ const mapCellArray = ({
|
|
|
72
73
|
columns,
|
|
73
74
|
runtimeData,
|
|
74
75
|
config,
|
|
75
|
-
applyLegendToRow,
|
|
76
76
|
displayGeoName,
|
|
77
77
|
formatLegendLocation,
|
|
78
78
|
navigationHandler,
|
|
79
|
-
setFilteredCountryCode
|
|
79
|
+
setFilteredCountryCode,
|
|
80
|
+
legendMemo,
|
|
81
|
+
legendSpecialClassLastMemo,
|
|
82
|
+
runtimeLegend
|
|
80
83
|
}: MapRowsProps): ReactNode[][] => {
|
|
84
|
+
const { allowMapZoom, geoType, type } = config.general
|
|
81
85
|
return rows.map(row =>
|
|
82
86
|
Object.keys(columns)
|
|
83
87
|
.filter(column => columns[column].dataTable === true && columns[column].name)
|
|
84
88
|
.map(column => {
|
|
85
89
|
if (column === 'geo') {
|
|
86
90
|
const rowObj = runtimeData[row]
|
|
87
|
-
|
|
91
|
+
if (!rowObj) {
|
|
92
|
+
throw new Error('No row object found')
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
const legendColor = applyLegendToRow(rowObj, config, runtimeLegend, legendMemo, legendSpecialClassLastMemo)
|
|
96
|
+
|
|
97
|
+
if (!legendColor) {
|
|
98
|
+
console.error('No legend color found') // eslint-disable-line no-console
|
|
99
|
+
}
|
|
88
100
|
const labelValue = getGeoLabel(config, row, formatLegendLocation, displayGeoName)
|
|
89
101
|
const mapZoomHandler =
|
|
90
|
-
|
|
91
|
-
? () => setFilteredCountryCode(row)
|
|
92
|
-
: undefined
|
|
102
|
+
type === 'bubble' && allowMapZoom && geoType === 'world' ? () => setFilteredCountryCode(row) : undefined
|
|
93
103
|
return (
|
|
94
104
|
<div className='col-12'>
|
|
95
|
-
<LegendShape fill={legendColor[0]} />
|
|
105
|
+
{legendColor && legendColor.length > 0 && <LegendShape fill={legendColor[0]} />}
|
|
96
106
|
<CellAnchor
|
|
97
107
|
markup={labelValue}
|
|
98
108
|
row={rowObj}
|
|
@@ -9,7 +9,12 @@ type DownloadButtonProps = {
|
|
|
9
9
|
|
|
10
10
|
const DownloadButton = ({ rawData, fileName, headerColor, skipId }: DownloadButtonProps) => {
|
|
11
11
|
const csvData = Papa.unparse(rawData)
|
|
12
|
-
|
|
12
|
+
// Prepend a Byte Order Mark (BOM) to the CSV data.
|
|
13
|
+
// The BOM is a special marker that helps applications like Excel recognize the file as UTF-8 encoded.
|
|
14
|
+
// Adding the BOM ensures that Excel interprets special characters correctly.
|
|
15
|
+
const bom = '\uFEFF'
|
|
16
|
+
const utf8EncodedCsvData = new TextEncoder().encode(bom + csvData)
|
|
17
|
+
const blob = new Blob([utf8EncodedCsvData], { type: 'text/csv;charset=utf-8;' })
|
|
13
18
|
|
|
14
19
|
const saveBlob = () => {
|
|
15
20
|
//@ts-ignore
|
|
@@ -20,7 +25,17 @@ const DownloadButton = ({ rawData, fileName, headerColor, skipId }: DownloadButt
|
|
|
20
25
|
}
|
|
21
26
|
|
|
22
27
|
return (
|
|
23
|
-
<a
|
|
28
|
+
<a
|
|
29
|
+
download={fileName}
|
|
30
|
+
type='button'
|
|
31
|
+
onClick={saveBlob}
|
|
32
|
+
href={URL.createObjectURL(blob)}
|
|
33
|
+
aria-label='Download this data in a CSV file format.'
|
|
34
|
+
className={`${headerColor} no-border`}
|
|
35
|
+
id={`${skipId}`}
|
|
36
|
+
data-html2canvas-ignore
|
|
37
|
+
role='button'
|
|
38
|
+
>
|
|
24
39
|
Download Data (CSV)
|
|
25
40
|
</a>
|
|
26
41
|
)
|
|
@@ -196,7 +196,7 @@ const DataTableEditor: React.FC<DataTableProps> = ({ config, updateField, isDash
|
|
|
196
196
|
/>
|
|
197
197
|
)}
|
|
198
198
|
{config?.visualizationType !== 'Sankey' && (
|
|
199
|
-
<label>
|
|
199
|
+
<label onClick={e => e.preventDefault()}>
|
|
200
200
|
<span className='edit-label column-heading mt-1'>Exclude Columns </span>
|
|
201
201
|
<MultiSelect
|
|
202
202
|
key={excludedColumns.join('') + 'excluded'}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { memo, useEffect, useState } from 'react'
|
|
2
2
|
import { useDebounce } from 'use-debounce'
|
|
3
|
-
import { DROPDOWN_STYLES } from '../Filters/
|
|
3
|
+
import { DROPDOWN_STYLES } from '../Filters/components/Dropdown'
|
|
4
4
|
|
|
5
5
|
export type Input = {
|
|
6
6
|
label: string
|
|
@@ -118,9 +118,17 @@ const CheckBox = memo((props: CheckboxProps) => {
|
|
|
118
118
|
return <></>
|
|
119
119
|
}
|
|
120
120
|
return (
|
|
121
|
-
<label
|
|
121
|
+
<label
|
|
122
|
+
className='checkbox column-heading'
|
|
123
|
+
onClick={e => {
|
|
124
|
+
if (!['SPAN', 'INPUT'].includes(e.target.nodeName)) {
|
|
125
|
+
e.preventDefault()
|
|
126
|
+
}
|
|
127
|
+
}}
|
|
128
|
+
>
|
|
122
129
|
<input
|
|
123
130
|
type='checkbox'
|
|
131
|
+
className='edit-checkbox'
|
|
124
132
|
name={fieldName}
|
|
125
133
|
checked={value}
|
|
126
134
|
onChange={e => {
|
|
@@ -161,7 +169,7 @@ const Select = memo((props: SelectProps) => {
|
|
|
161
169
|
initial: initialValue,
|
|
162
170
|
...attributes
|
|
163
171
|
} = props
|
|
164
|
-
const optionsJsx = options
|
|
172
|
+
const optionsJsx = options?.map((option, index) => {
|
|
165
173
|
if (typeof option === 'string') {
|
|
166
174
|
return (
|
|
167
175
|
<option value={option} key={index}>
|
|
@@ -178,7 +186,7 @@ const Select = memo((props: SelectProps) => {
|
|
|
178
186
|
})
|
|
179
187
|
|
|
180
188
|
if (initialValue) {
|
|
181
|
-
optionsJsx
|
|
189
|
+
optionsJsx?.unshift(
|
|
182
190
|
<option value='' key='initial'>
|
|
183
191
|
{initialValue}
|
|
184
192
|
</option>
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import _ from 'lodash'
|
|
2
2
|
import { SubGrouping, VizFilter, OrderBy } from '../../../types/VizFilter'
|
|
3
|
-
import {
|
|
3
|
+
import { handleSorting } from '../../Filters/helpers/handleSorting'
|
|
4
|
+
import { filterOrderOptions } from '../../../helpers/filterOrderOptions'
|
|
4
5
|
import FilterOrder from './components/FilterOrder'
|
|
5
6
|
import { Visualization } from '../../../types/Visualization'
|
|
6
7
|
import { useMemo } from 'react'
|
|
@@ -5,7 +5,9 @@ import { Visualization } from '../../../types/Visualization'
|
|
|
5
5
|
import { UpdateFieldFunc } from '../../../types/UpdateFieldFunc'
|
|
6
6
|
import _ from 'lodash'
|
|
7
7
|
import { MultiSelectFilter, VizFilter, VizFilterStyle } from '../../../types/VizFilter'
|
|
8
|
-
import {
|
|
8
|
+
import { handleSorting } from '../../Filters/helpers/handleSorting'
|
|
9
|
+
import { filterOrderOptions } from '../../../helpers/filterOrderOptions'
|
|
10
|
+
import { filterStyleOptions } from '../../Filters'
|
|
9
11
|
import FieldSetWrapper from '../FieldSetWrapper'
|
|
10
12
|
|
|
11
13
|
import FilterOrder from './components/FilterOrder'
|