@cdc/core 4.23.6 → 4.23.8
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-chart-forecast.svg +1 -0
- package/assets/icon-chart-forest-plot.svg +1 -0
- package/assets/icon-chart-stacked-area.svg +1 -0
- package/assets/icon-filter-dropdowns.svg +1 -0
- package/components/DataTable.jsx +54 -23
- package/components/managers/DataDesigner.jsx +165 -29
- package/components/ui/Icon.jsx +4 -2
- package/components/ui/Tooltip.jsx +10 -22
- package/helpers/DataTransform.js +20 -0
- package/helpers/cove/number.js +43 -10
- package/package.json +2 -2
- package/styles/_data-table.scss +14 -0
- package/styles/v2/components/ui/tooltip.scss +90 -73
- package/styles/v2/layout/_data-table.scss +1 -10
- /package/assets/{filtered-text.svg → icon-filtered-text.svg} +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?><svg id="a" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 96.31 82.55"><path d="M89.56,65.41H16.36V8.8c0-1.1-.9-2-2-2h-5.48c-1.1,0-2,.9-2,2V72.89c0,1.1,.9,2,2,2H89.56c1.1,0,2-.9,2-2v-5.48c0-1.1-.9-2-2-2Z"/><path d="M54.66,55.34c-17.76,0-33.46-17.8-34.12-18.56l-.98-1.13v-4.55l3.25,3.72c.15,.18,15.47,17.53,31.86,17.53h0c7.31,0,12.37-1.68,17.27-3.3,4.31-1.42,8.77-2.9,14.44-3.05l1.5-.04v3l-1.42,.04c-5.24,.14-9.29,1.48-13.59,2.9-5.13,1.69-10.43,3.45-18.22,3.45h0Z"/><path d="M87.84,59.04c-4.73-1.24-7.41-1.66-13.05-1.93-2.82-.14-5.22,.16-8,.5-2.73,.33-5.81,.71-10.06,.79-13.13,.27-23.77-4.63-37.17-17.31v-1.57c13.19,12.48,24.31,18.13,37.15,17.88,4.2-.08,7.26-.46,9.96-.79,2.83-.34,5.27-.64,8.17-.5,5.73,.28,8.2,.62,13,1.88v1.05Z"/><path d="M57.02,49.28c-19.55,0-30.91-14.65-37.69-23.41v-1.54c6.67,8.61,18.64,23.95,37.69,23.95,5.87,0,14.11-3.23,18.39-6.23,2.43-1.7,3.84-2.77,4.87-3.55,2.24-1.7,2.7-2.05,7.71-4.44l-.03,1.12c-4.92,2.34-4.91,2.47-7.08,4.12-1.04,.79-2.45,1.86-4.9,3.57-4.4,3.08-12.9,6.41-18.96,6.41Z"/></svg>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?><svg id="a" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 96.31 82.55"><defs><style>.b{stroke-width:3px;}.b,.c,.d{stroke-linecap:round;}.b,.c,.d,.e{stroke:#000;}.c,.d,.e{fill:none;}.d{stroke-dasharray:0 0 0 4.07;}.e{stroke-width:2px;}</style></defs><path d="M14.15,8.39v63.29c0,.87,.89,1.59,1.98,1.59h5.42c1.09,0,1.98-.72,1.98-1.59l-.13-63.29c0-.87-.89-1.59-1.98-1.59h-5.28c-1.09,0-1.98,.72-1.98,1.59Z"/><g><line class="c" x1="53.51" y1="10.09" x2="53.51" y2="10.09"/><line class="d" x1="53.51" y1="14.16" x2="53.51" y2="69.05"/><line class="c" x1="53.51" y1="71.08" x2="53.51" y2="71.08"/></g><g><path class="b" d="M29.78,16.97h34.43"/><path class="b" d="M29.78,21.48V12.45"/><path class="b" d="M65.64,21.48V12.45"/></g><g><path class="b" d="M50.62,33.5h28.85"/><path class="b" d="M50.62,38.02v-9.03"/><path class="b" d="M80.67,38.02v-9.03"/></g><g><path class="b" d="M28.21,50.03h19.26"/><path class="b" d="M28.21,54.55v-9.03"/><path class="b" d="M48.27,54.55v-9.03"/></g><g><path class="b" d="M40.69,66.57h33.99"/><path class="b" d="M40.69,71.08v-9.03"/><path class="b" d="M76.1,71.08v-9.03"/></g><circle class="e" cx="47.47" cy="16.97" r="2.2"/><circle class="e" cx="65.64" cy="33.5" r="2.2"/><circle class="e" cx="38.49" cy="50.03" r="2.2"/><circle class="e" cx="58.31" cy="66.57" r="2.2"/></svg>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?><svg id="a" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 96.31 82.55"><defs><style>.b{fill:none;}.b,.c{stroke:#000;stroke-linejoin:round;}</style></defs><path d="M89.93,65.41H16.73V8.8c0-1.1-.9-2-2-2h-5.48c-1.1,0-2,.9-2,2V72.89c0,1.1,.9,2,2,2H89.93c1.1,0,2-.9,2-2v-5.48c0-1.1-.9-2-2-2Z"/><polygon points="22.7 54.03 22.7 59.31 89.66 59.31 89.66 37.5 70.66 47.11 52.54 42.02 43.1 48.03 35.85 44.59 22.7 54.03"/><polygon class="b" points="22.7 47.3 22.7 59.31 89.66 59.31 89.66 25.48 70.66 35.35 52.54 35.3 43.1 40.03 36.46 31.3 22.7 47.3"/><polygon class="c" points="70.66 23.24 52.54 15.09 43.1 21.1 35.85 25.48 22.7 27.11 22.7 47.3 36.46 31.3 43.1 40.03 52.54 35.3 70.66 35.35 89.66 25.48 89.66 10.58 70.66 23.24"/></svg>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?><svg id="a" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 96.31 82.55"><path d="M87.87,5.89H11.35c-1.56,0-2.84,1.28-2.84,2.84v14.78c0,1.56,1.28,2.84,2.84,2.84l76.52-.19c1.56,0,2.84-1.28,2.84-2.84V8.73c0-1.56-1.28-2.84-2.84-2.84ZM25.95,14.33l-5.19,5.19c-.29,.29-.77,.29-1.06,0l-5.19-5.19c-.29-.29-.29-.77,0-1.06h11.43c.29,.29,.29,.77,0,1.06Zm60.97,10.22H32.18V7.7h54.73V24.55Z"/><path transform="translate(0, 30)" d="M87.87,5.89H11.35c-1.56,0-2.84,1.28-2.84,2.84v14.78c0,1.56,1.28,2.84,2.84,2.84l76.52-.19c1.56,0,2.84-1.28,2.84-2.84V8.73c0-1.56-1.28-2.84-2.84-2.84ZM25.95,14.33l-5.19,5.19c-.29,.29-.77,.29-1.06,0l-5.19-5.19c-.29-.29-.29-.77,0-1.06h11.43c.29,.29,.29,.77,0,1.06Zm60.97,10.22H32.18V7.7h54.73V24.55Z"/></svg>
|
package/components/DataTable.jsx
CHANGED
|
@@ -13,14 +13,6 @@ import { formatNumber } from '@cdc/core/helpers/cove/number'
|
|
|
13
13
|
|
|
14
14
|
import Loading from '@cdc/core/components/Loading'
|
|
15
15
|
|
|
16
|
-
// FILE REVIEW
|
|
17
|
-
// TODO: Remove eslint-disable jsx/a11y/non-interactive-tabindex and handle appropriately
|
|
18
|
-
// TODO: Move ExternalIcon to core Icon component
|
|
19
|
-
// TODO: use destructuring
|
|
20
|
-
// TODO: @tturnerswdev33 - It looks like there's an unused variable setFilteredCountryCode that was added
|
|
21
|
-
// TODO: @tturnerswdev33 - change function declarations to arrow functions
|
|
22
|
-
// TODO: @tturnerswdev33 - move caption so that useMemo is not rendered conditionally
|
|
23
|
-
|
|
24
16
|
/* eslint-disable jsx-a11y/no-noninteractive-tabindex, jsx-a11y/no-static-element-interactions */
|
|
25
17
|
const DataTable = props => {
|
|
26
18
|
const { config, tableTitle, indexTitle, vizTitle, rawData, runtimeData, headerColor, expandDataTable, columns, displayDataAsText, applyLegendToRow, displayGeoName, navigationHandler, viewport, formatLegendLocation, tabbingId, isDebug } = props
|
|
@@ -153,15 +145,13 @@ const DataTable = props => {
|
|
|
153
145
|
const DownloadButton = memo(() => {
|
|
154
146
|
if (rawData !== undefined) {
|
|
155
147
|
let csvData
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
csvData = Papa.unparse(rawData)
|
|
159
|
-
} else if ((config.general.geoType !== 'single-state' && config.general.geoType !== 'us-county') || config.general.type === 'us-geocode') {
|
|
160
|
-
// Unparse + Add column for full Geo name
|
|
161
|
-
csvData = Papa.unparse(rawData.map(row => ({ FullGeoName: displayGeoName(row[config.columns.geo.name]), ...row })))
|
|
162
|
-
} else {
|
|
148
|
+
// only use fullGeoName on County maps and no other
|
|
149
|
+
if (config.general.geoType === 'us-county') {
|
|
163
150
|
// Unparse + Add column for full Geo name along with State
|
|
164
151
|
csvData = Papa.unparse(rawData.map(row => ({ FullGeoName: formatLegendLocation(row[config.columns.geo.name]), ...row })))
|
|
152
|
+
} else {
|
|
153
|
+
// Just Unparse
|
|
154
|
+
csvData = Papa.unparse(rawData)
|
|
165
155
|
}
|
|
166
156
|
|
|
167
157
|
const blob = new Blob([csvData], { type: 'text/csv;charset=utf-8;' })
|
|
@@ -213,16 +203,19 @@ const DataTable = props => {
|
|
|
213
203
|
|
|
214
204
|
const rows = Object.keys(runtimeData).sort((a, b) => {
|
|
215
205
|
let sortVal
|
|
216
|
-
if (config.
|
|
206
|
+
if (config.type === 'map' && config.columns) {
|
|
217
207
|
sortVal = customSort(runtimeData[a][config.columns[sortBy.column].name], runtimeData[b][config.columns[sortBy.column].name])
|
|
218
208
|
}
|
|
209
|
+
if (config.type === 'chart') {
|
|
210
|
+
sortVal = customSort(runtimeData[a][sortBy.column], runtimeData[b][sortBy.column])
|
|
211
|
+
}
|
|
219
212
|
if (!sortBy.asc) return sortVal
|
|
220
213
|
if (sortVal === 0) return 0
|
|
221
214
|
if (sortVal < 0) return 1
|
|
222
215
|
return -1
|
|
223
216
|
})
|
|
224
217
|
|
|
225
|
-
|
|
218
|
+
const genMapRows = rows => {
|
|
226
219
|
const allrows = rows.map(row => {
|
|
227
220
|
return (
|
|
228
221
|
<tr role='row'>
|
|
@@ -316,6 +309,7 @@ const DataTable = props => {
|
|
|
316
309
|
}
|
|
317
310
|
|
|
318
311
|
const genChartHeader = (columns, data) => {
|
|
312
|
+
if (!data) return
|
|
319
313
|
return (
|
|
320
314
|
<tr>
|
|
321
315
|
{dataSeriesColumns().map(column => {
|
|
@@ -345,6 +339,7 @@ const DataTable = props => {
|
|
|
345
339
|
{...(sortBy.column === column ? (sortBy.asc ? { 'aria-sort': 'ascending' } : { 'aria-sort': 'descending' }) : null)}
|
|
346
340
|
>
|
|
347
341
|
{text}
|
|
342
|
+
{sortBy.column === column && <span className={'sort-icon'}>{!sortBy.asc ? upIcon : downIcon}</span>}
|
|
348
343
|
<button>
|
|
349
344
|
<span className='cdcdataviz-sr-only'>{`Sort by ${text} in ${sortBy.column === column ? (!sortBy.asc ? 'descending' : 'ascending') : 'descending'} `} order</span>
|
|
350
345
|
</button>
|
|
@@ -355,6 +350,24 @@ const DataTable = props => {
|
|
|
355
350
|
)
|
|
356
351
|
}
|
|
357
352
|
|
|
353
|
+
// if its additional column, return formatting params
|
|
354
|
+
const isAdditionalColumn = column => {
|
|
355
|
+
let inthere = false
|
|
356
|
+
let formattingParams = {}
|
|
357
|
+
Object.keys(config.columns).forEach(keycol => {
|
|
358
|
+
if (config.columns[keycol].name === column) {
|
|
359
|
+
inthere = true
|
|
360
|
+
formattingParams = {
|
|
361
|
+
addColPrefix: config.columns[keycol].prefix,
|
|
362
|
+
addColSuffix: config.columns[keycol].suffix,
|
|
363
|
+
addColRoundTo: config.columns[keycol].roundToPlace ? config.columns[keycol].roundToPlace : '',
|
|
364
|
+
addColCommas: config.columns[keycol].commas
|
|
365
|
+
}
|
|
366
|
+
}
|
|
367
|
+
})
|
|
368
|
+
return formattingParams
|
|
369
|
+
}
|
|
370
|
+
|
|
358
371
|
const genChartRows = rows => {
|
|
359
372
|
const allRows = rows.map(row => {
|
|
360
373
|
return (
|
|
@@ -367,10 +380,9 @@ const DataTable = props => {
|
|
|
367
380
|
// not the prettiest, but helper functions work nicely here.
|
|
368
381
|
cellValue = <>{config.xAxis.type === 'date' ? formatDate(config.xAxis.dateDisplayFormat, parseDate(config.xAxis.dateParseFormat, labelValue)) : labelValue}</>
|
|
369
382
|
} else {
|
|
370
|
-
let resolvedAxis = ''
|
|
383
|
+
let resolvedAxis = 'left'
|
|
371
384
|
let leftAxisItems = config.series.filter(item => item?.axis === 'Left')
|
|
372
385
|
let rightAxisItems = config.series.filter(item => item?.axis === 'Right')
|
|
373
|
-
console.log('column', column)
|
|
374
386
|
|
|
375
387
|
leftAxisItems.map(leftSeriesItem => {
|
|
376
388
|
if (leftSeriesItem.dataKey === column) resolvedAxis = 'left'
|
|
@@ -380,7 +392,12 @@ const DataTable = props => {
|
|
|
380
392
|
if (rightSeriesItem.dataKey === column) resolvedAxis = 'right'
|
|
381
393
|
})
|
|
382
394
|
|
|
383
|
-
|
|
395
|
+
let addColParams = isAdditionalColumn(column)
|
|
396
|
+
if (addColParams) {
|
|
397
|
+
cellValue = formatNumber(runtimeData[row][column], resolvedAxis, false, config, addColParams)
|
|
398
|
+
} else {
|
|
399
|
+
cellValue = formatNumber(runtimeData[row][column], resolvedAxis, false, config)
|
|
400
|
+
}
|
|
384
401
|
}
|
|
385
402
|
|
|
386
403
|
return (
|
|
@@ -395,6 +412,17 @@ const DataTable = props => {
|
|
|
395
412
|
return allRows
|
|
396
413
|
}
|
|
397
414
|
|
|
415
|
+
const upIcon = (
|
|
416
|
+
<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 10 5'>
|
|
417
|
+
<path d='M0 5l5-5 5 5z' />
|
|
418
|
+
</svg>
|
|
419
|
+
)
|
|
420
|
+
const downIcon = (
|
|
421
|
+
<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 10 5'>
|
|
422
|
+
<path d='M0 0l5 5 5-5z' />
|
|
423
|
+
</svg>
|
|
424
|
+
)
|
|
425
|
+
|
|
398
426
|
const limitHeight = {
|
|
399
427
|
maxHeight: config.table.limitHeight && `${config.table.height}px`,
|
|
400
428
|
overflowY: 'scroll'
|
|
@@ -418,7 +446,7 @@ const DataTable = props => {
|
|
|
418
446
|
[config.runtime.seriesKeys]) // eslint-disable-line
|
|
419
447
|
|
|
420
448
|
if (config.visualizationType !== 'Box Plot') {
|
|
421
|
-
|
|
449
|
+
const genMapHeader = columns => {
|
|
422
450
|
return (
|
|
423
451
|
<tr>
|
|
424
452
|
{Object.keys(columns)
|
|
@@ -433,9 +461,11 @@ const DataTable = props => {
|
|
|
433
461
|
if (config.type === 'map' && (text === undefined || text === '')) {
|
|
434
462
|
text = 'Location'
|
|
435
463
|
}
|
|
464
|
+
|
|
436
465
|
return (
|
|
437
466
|
<th
|
|
438
467
|
key={`col-header-${column}`}
|
|
468
|
+
id={column}
|
|
439
469
|
tabIndex='0'
|
|
440
470
|
title={text}
|
|
441
471
|
role='columnheader'
|
|
@@ -452,6 +482,7 @@ const DataTable = props => {
|
|
|
452
482
|
{...(sortBy.column === column ? (sortBy.asc ? { 'aria-sort': 'ascending' } : { 'aria-sort': 'descending' }) : null)}
|
|
453
483
|
>
|
|
454
484
|
{text}
|
|
485
|
+
{sortBy.column === column && <span className={'sort-icon'}>{!sortBy.asc ? upIcon : downIcon}</span>}
|
|
455
486
|
<button>
|
|
456
487
|
<span className='cdcdataviz-sr-only'>{`Sort by ${text} in ${sortBy.column === column ? (!sortBy.asc ? 'descending' : 'ascending') : 'descending'} `} order</span>
|
|
457
488
|
</button>
|
|
@@ -530,7 +561,7 @@ const DataTable = props => {
|
|
|
530
561
|
)
|
|
531
562
|
} else {
|
|
532
563
|
// Render Data Table for Box Plots
|
|
533
|
-
|
|
564
|
+
const genBoxplotHeader = categories => {
|
|
534
565
|
let columns = ['Measures', ...categories]
|
|
535
566
|
return (
|
|
536
567
|
<tr>
|
|
@@ -584,7 +615,7 @@ const DataTable = props => {
|
|
|
584
615
|
if (Number(rowid) === 10) return plot.values.length > 0 ? plot.values.toString() : '-'
|
|
585
616
|
return <p>-</p>
|
|
586
617
|
}
|
|
587
|
-
|
|
618
|
+
const genBoxplotRows = rows => {
|
|
588
619
|
// get list of data keys for each row
|
|
589
620
|
let dataKeys = rows.map(row => {
|
|
590
621
|
return row[0]
|
|
@@ -7,8 +7,7 @@ import { DATA_TABLE_VERTICAL, DATA_TABLE_HORIZONTAL, DATA_TABLE_SINGLE_ROW, DATA
|
|
|
7
7
|
import '../../styles/v2/components/data-designer.scss'
|
|
8
8
|
|
|
9
9
|
const DataDesigner = props => {
|
|
10
|
-
const { configureData, updateDescriptionProp, visualizationKey, dataKey } = props
|
|
11
|
-
|
|
10
|
+
const { configureData, updateDescriptionProp, visualizationKey, dataKey, config, setConfig } = props
|
|
12
11
|
|
|
13
12
|
return (
|
|
14
13
|
<div className='cove-data-designer__container'>
|
|
@@ -166,66 +165,203 @@ const DataDesigner = props => {
|
|
|
166
165
|
</select>
|
|
167
166
|
</div>
|
|
168
167
|
<div className='mb-2'>
|
|
169
|
-
<div className='mb-1'>Which properties in the dataset represent the numeric value?
|
|
168
|
+
<div className='mb-1'>Which properties in the dataset represent the numeric value? (all remaining properties will be treated as filters)</div>
|
|
170
169
|
{configureData.dataDescription.valueKeys && configureData.dataDescription.valueKeys.length > 0 && (
|
|
171
|
-
<ul className=
|
|
170
|
+
<ul className='value-list'>
|
|
172
171
|
{configureData.dataDescription.valueKeys.map((valueKey, index) => (
|
|
173
|
-
<li key={`value-keys-list-${index}`}>
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
172
|
+
<li key={`value-keys-list-${index}`}>
|
|
173
|
+
{valueKey}
|
|
174
|
+
<button
|
|
175
|
+
onClick={() => {
|
|
176
|
+
let newValueKeys = configureData.dataDescription.valueKeys
|
|
177
|
+
newValueKeys.splice(index, 1)
|
|
178
|
+
updateDescriptionProp(visualizationKey, dataKey, 'valueKeys', newValueKeys)
|
|
179
|
+
}}
|
|
180
|
+
>
|
|
181
|
+
X
|
|
182
|
+
</button>
|
|
183
|
+
</li>
|
|
178
184
|
))}
|
|
179
185
|
</ul>
|
|
180
186
|
)}
|
|
181
187
|
<select
|
|
182
188
|
onChange={e => {
|
|
183
|
-
if(e.target.value && (!configureData.dataDescription.valueKeys || configureData.dataDescription.valueKeys.indexOf(e.target.value) === -1)){
|
|
189
|
+
if (e.target.value && (!configureData.dataDescription.valueKeys || configureData.dataDescription.valueKeys.indexOf(e.target.value) === -1)) {
|
|
184
190
|
updateDescriptionProp(visualizationKey, dataKey, 'valueKeys', [...(configureData.dataDescription.valueKeys || []), e.target.value])
|
|
185
191
|
}
|
|
186
192
|
}}
|
|
187
193
|
>
|
|
188
194
|
<option value=''>Choose an option</option>
|
|
189
|
-
{Object.keys(configureData.data[0])
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
195
|
+
{Object.keys(configureData.data[0])
|
|
196
|
+
.filter(value => !configureData.dataDescription.valueKeys || configureData.dataDescription.valueKeys.indexOf(value) === -1)
|
|
197
|
+
.map((value, index) => (
|
|
198
|
+
<option value={value} key={`value-keys-option-${index}`}>
|
|
199
|
+
{value}
|
|
200
|
+
</option>
|
|
201
|
+
))}
|
|
194
202
|
</select>
|
|
195
203
|
</div>
|
|
196
204
|
<div className='mb-2'>
|
|
197
|
-
<div className='mb-1'>(Optional) Which properties in the dataset should be ignored?
|
|
205
|
+
<div className='mb-1'>(Optional) Which properties in the dataset should be ignored? (will not be used or treated as filters)</div>
|
|
198
206
|
{configureData.dataDescription.ignoredKeys && configureData.dataDescription.ignoredKeys.length > 0 && (
|
|
199
|
-
<ul className=
|
|
207
|
+
<ul className='value-list'>
|
|
200
208
|
{configureData.dataDescription.ignoredKeys.map((ignoredKey, index) => (
|
|
201
|
-
<li key={`value-keys-list-${index}`}>
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
209
|
+
<li key={`value-keys-list-${index}`}>
|
|
210
|
+
{ignoredKey}
|
|
211
|
+
<button
|
|
212
|
+
onClick={() => {
|
|
213
|
+
let newIgnoredKeys = configureData.dataDescription.ignoredKeys
|
|
214
|
+
newIgnoredKeys.splice(index, 1)
|
|
215
|
+
updateDescriptionProp(visualizationKey, dataKey, 'ignoredKeys', newIgnoredKeys)
|
|
216
|
+
}}
|
|
217
|
+
>
|
|
218
|
+
X
|
|
219
|
+
</button>
|
|
220
|
+
</li>
|
|
206
221
|
))}
|
|
207
222
|
</ul>
|
|
208
223
|
)}
|
|
209
224
|
<select
|
|
210
225
|
onChange={e => {
|
|
211
|
-
if(e.target.value){
|
|
226
|
+
if (e.target.value) {
|
|
212
227
|
updateDescriptionProp(visualizationKey, dataKey, 'ignoredKeys', [...(configureData.dataDescription.ignoredKeys || []), e.target.value])
|
|
213
228
|
}
|
|
214
|
-
e.target.value = ''
|
|
229
|
+
e.target.value = ''
|
|
215
230
|
}}
|
|
216
231
|
>
|
|
217
232
|
<option value=''>Choose an option</option>
|
|
218
|
-
{Object.keys(configureData.data[0])
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
233
|
+
{Object.keys(configureData.data[0])
|
|
234
|
+
.filter(value => !configureData.dataDescription.ignoredKeys || configureData.dataDescription.ignoredKeys.indexOf(value) === -1)
|
|
235
|
+
.map((value, index) => (
|
|
236
|
+
<option value={value} key={`ignored-keys-option-${index}`}>
|
|
237
|
+
{value}
|
|
238
|
+
</option>
|
|
239
|
+
))}
|
|
223
240
|
</select>
|
|
224
241
|
</div>
|
|
225
242
|
</>
|
|
226
243
|
)}
|
|
227
244
|
</>
|
|
228
245
|
)}
|
|
246
|
+
|
|
247
|
+
{config?.visualizationType === 'Forest Plot' && (
|
|
248
|
+
<>
|
|
249
|
+
<div className='mb-2'>
|
|
250
|
+
<div className='mb-1'>Which column represents the date/category column?</div>
|
|
251
|
+
<select
|
|
252
|
+
onChange={e => {
|
|
253
|
+
setConfig({
|
|
254
|
+
...config,
|
|
255
|
+
xAxis: {
|
|
256
|
+
...config.xAxis,
|
|
257
|
+
dataKey: e.target.value
|
|
258
|
+
}
|
|
259
|
+
})
|
|
260
|
+
}}
|
|
261
|
+
defaultValue={'Select'}
|
|
262
|
+
>
|
|
263
|
+
<option value=''>Choose an option</option>
|
|
264
|
+
{Object.keys(configureData.data[0]).map((value, index) => (
|
|
265
|
+
<option value={value} key={index}>
|
|
266
|
+
{value}
|
|
267
|
+
</option>
|
|
268
|
+
))}
|
|
269
|
+
</select>
|
|
270
|
+
</div>
|
|
271
|
+
|
|
272
|
+
<div className='mb-2'>
|
|
273
|
+
<div className='mb-1'>Which column represents your estimate field?</div>
|
|
274
|
+
<select
|
|
275
|
+
onChange={e => {
|
|
276
|
+
setConfig({
|
|
277
|
+
...config,
|
|
278
|
+
forestPlot: {
|
|
279
|
+
...config.forestPlot,
|
|
280
|
+
estimateField: e.target.value
|
|
281
|
+
}
|
|
282
|
+
})
|
|
283
|
+
}}
|
|
284
|
+
defaultValue={'Select'}
|
|
285
|
+
>
|
|
286
|
+
<option value=''>Choose an option</option>
|
|
287
|
+
{Object.keys(configureData.data[0]).map((value, index) => (
|
|
288
|
+
<option value={value} key={index}>
|
|
289
|
+
{value}
|
|
290
|
+
</option>
|
|
291
|
+
))}
|
|
292
|
+
</select>
|
|
293
|
+
</div>
|
|
294
|
+
|
|
295
|
+
<div className='mb-2'>
|
|
296
|
+
<div className='mb-1'>Which column represents the low confidence interval?</div>
|
|
297
|
+
<select
|
|
298
|
+
onChange={e => {
|
|
299
|
+
setConfig({
|
|
300
|
+
...config,
|
|
301
|
+
forestPlot: {
|
|
302
|
+
...config.forestPlot,
|
|
303
|
+
lower: e.target.value
|
|
304
|
+
}
|
|
305
|
+
})
|
|
306
|
+
}}
|
|
307
|
+
defaultValue={'Select'}
|
|
308
|
+
>
|
|
309
|
+
<option value=''>Choose an option</option>
|
|
310
|
+
{Object.keys(configureData.data[0]).map((value, index) => (
|
|
311
|
+
<option value={value} key={index}>
|
|
312
|
+
{value}
|
|
313
|
+
</option>
|
|
314
|
+
))}
|
|
315
|
+
</select>
|
|
316
|
+
</div>
|
|
317
|
+
|
|
318
|
+
<div className='mb-2'>
|
|
319
|
+
<div className='mb-1'>Which column represents the high confidence interval?</div>
|
|
320
|
+
<select
|
|
321
|
+
onChange={e => {
|
|
322
|
+
setConfig({
|
|
323
|
+
...config,
|
|
324
|
+
forestPlot: {
|
|
325
|
+
...config.forestPlot,
|
|
326
|
+
upper: e.target.value
|
|
327
|
+
}
|
|
328
|
+
})
|
|
329
|
+
}}
|
|
330
|
+
defaultValue={'Select'}
|
|
331
|
+
>
|
|
332
|
+
<option value=''>Choose an option</option>
|
|
333
|
+
{Object.keys(configureData.data[0]).map((value, index) => (
|
|
334
|
+
<option value={value} key={index}>
|
|
335
|
+
{value}
|
|
336
|
+
</option>
|
|
337
|
+
))}
|
|
338
|
+
</select>
|
|
339
|
+
</div>
|
|
340
|
+
|
|
341
|
+
<div className='mb-2'>
|
|
342
|
+
<div className='mb-1'>Which shape do you want to use in your forest plot?</div>
|
|
343
|
+
<select
|
|
344
|
+
onChange={e => {
|
|
345
|
+
setConfig({
|
|
346
|
+
...config,
|
|
347
|
+
forestPlot: {
|
|
348
|
+
...config.forestPlot,
|
|
349
|
+
shape: e.target.value
|
|
350
|
+
}
|
|
351
|
+
})
|
|
352
|
+
}}
|
|
353
|
+
defaultValue={'Select'}
|
|
354
|
+
>
|
|
355
|
+
<option value=''>Choose an option</option>
|
|
356
|
+
{['text', 'circle', 'square', 'diamond'].map((value, index) => (
|
|
357
|
+
<option value={value} key={index}>
|
|
358
|
+
{value}
|
|
359
|
+
</option>
|
|
360
|
+
))}
|
|
361
|
+
</select>
|
|
362
|
+
</div>
|
|
363
|
+
</>
|
|
364
|
+
)}
|
|
229
365
|
</>
|
|
230
366
|
)}
|
|
231
367
|
{configureData.dataDescription && configureData.formattedData && <div>Data configured successfully</div>}
|
package/components/ui/Icon.jsx
CHANGED
|
@@ -27,7 +27,8 @@ import iconWarningCircle from '../../assets/icon-warning-circle.svg'
|
|
|
27
27
|
import iconWarningTriangle from '../../assets/icon-warning-triangle.svg'
|
|
28
28
|
import iconGear from '../../assets/icon-gear.svg'
|
|
29
29
|
import iconTools from '../../assets/icon-tools.svg'
|
|
30
|
-
import iconText from '../../assets/filtered-text.svg'
|
|
30
|
+
import iconText from '../../assets/icon-filtered-text.svg'
|
|
31
|
+
import iconDropdowns from '../../assets/icon-filter-dropdowns.svg'
|
|
31
32
|
import iconPlus from '../../assets/icon-plus.svg'
|
|
32
33
|
import iconMinus from '../../assets/icon-minus.svg'
|
|
33
34
|
|
|
@@ -62,7 +63,8 @@ const iconHash = {
|
|
|
62
63
|
tools: iconTools,
|
|
63
64
|
plus: iconPlus,
|
|
64
65
|
minus: iconMinus,
|
|
65
|
-
'filtered-text': iconText
|
|
66
|
+
'filtered-text': iconText,
|
|
67
|
+
'filter-dropdowns': iconDropdowns
|
|
66
68
|
}
|
|
67
69
|
|
|
68
70
|
const Icon = ({ display = null, base, alt = '', size, color, style, ...attributes }) => {
|
|
@@ -9,42 +9,30 @@ import '../../styles/v2/components/ui/tooltip.scss'
|
|
|
9
9
|
const TooltipTarget = () => null
|
|
10
10
|
const TooltipContent = () => null
|
|
11
11
|
|
|
12
|
-
const Tooltip = ({
|
|
13
|
-
place = 'top',
|
|
14
|
-
trigger = 'hover',
|
|
15
|
-
float = false,
|
|
16
|
-
shadow = true,
|
|
17
|
-
border = false,
|
|
18
|
-
children,
|
|
19
|
-
style,
|
|
20
|
-
...attributes
|
|
21
|
-
}) => {
|
|
22
|
-
|
|
12
|
+
const Tooltip = ({ place = 'top', trigger = 'hover', float = false, shadow = true, border = false, children, style, ...attributes }) => {
|
|
23
13
|
const tooltipTargetChildren = children.find(el => el.type === TooltipTarget)
|
|
24
14
|
const tooltipContentChildren = children.find(el => el.type === TooltipContent)
|
|
25
15
|
|
|
26
16
|
const uid = 'tooltip-' + useId()
|
|
27
17
|
|
|
28
|
-
const generateTriggerEvent =
|
|
18
|
+
const generateTriggerEvent = trigger => {
|
|
29
19
|
const eventList = {
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
20
|
+
hover: null,
|
|
21
|
+
focus: 'focus',
|
|
22
|
+
click: 'click focus'
|
|
33
23
|
}
|
|
34
24
|
return eventList[trigger]
|
|
35
25
|
}
|
|
36
26
|
|
|
37
27
|
return (
|
|
38
|
-
<span className=
|
|
39
|
-
<a id={uid} className=
|
|
40
|
-
data-tooltip-float={float}
|
|
41
|
-
data-tooltip-place={place}
|
|
42
|
-
data-tooltip-events={generateTriggerEvent()}
|
|
43
|
-
>
|
|
28
|
+
<span className='cove-tooltip' style={style} {...attributes}>
|
|
29
|
+
<a id={uid} className='cove-tooltip--target' data-tooltip-float={float} data-tooltip-place={place} data-tooltip-events={generateTriggerEvent()}>
|
|
44
30
|
{tooltipTargetChildren ? tooltipTargetChildren.props.children : null}
|
|
45
31
|
</a>
|
|
32
|
+
{/* prettier-ignore */}
|
|
46
33
|
<ReactTooltip
|
|
47
|
-
id={uid}
|
|
34
|
+
id={uid}
|
|
35
|
+
anchorId={uid}
|
|
48
36
|
className={'cove-tooltip__content' + (' place-' + place) + (!float ? ' cove-tooltip__content--animated' : '') + (trigger === 'click' ? ' interactive' : '') + (border ? (' cove-tooltip--border') : '') + (shadow ? ' has-shadow' : '')}
|
|
49
37
|
globalEventOff="click"
|
|
50
38
|
>
|
package/helpers/DataTransform.js
CHANGED
|
@@ -250,6 +250,26 @@ export class DataTransform {
|
|
|
250
250
|
if (testing) console.log('## cleanedData =', cleanedupData)
|
|
251
251
|
return cleanedupData
|
|
252
252
|
}
|
|
253
|
+
|
|
254
|
+
// clean out %, $, commas from numbers when needing to do sorting!
|
|
255
|
+
cleanDataPoint(data, testing = false) {
|
|
256
|
+
if (testing) console.log('clean', data)
|
|
257
|
+
let cleaned = ''
|
|
258
|
+
|
|
259
|
+
// remove comma and dollar signs
|
|
260
|
+
if (testing) console.log('typeof data is ', typeof data)
|
|
261
|
+
let tmp = ''
|
|
262
|
+
if (typeof data === 'string') {
|
|
263
|
+
tmp = data!== null && data !== '' ? data.replace(/[,\$\%]/g, '') : ''
|
|
264
|
+
} else {
|
|
265
|
+
tmp = data !== null && data !== '' ? data : ''
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
cleaned = tmp
|
|
269
|
+
|
|
270
|
+
if (testing) console.log('## cleanedData =', cleaned)
|
|
271
|
+
return cleaned
|
|
272
|
+
}
|
|
253
273
|
}
|
|
254
274
|
|
|
255
275
|
export default DataTransform
|
package/helpers/cove/number.js
CHANGED
|
@@ -19,7 +19,7 @@ const abbreviateNumber = num => {
|
|
|
19
19
|
}
|
|
20
20
|
|
|
21
21
|
// Format numeric data based on settings in config
|
|
22
|
-
const formatNumber = (num, axis, shouldAbbreviate = false, config = null) => {
|
|
22
|
+
const formatNumber = (num, axis, shouldAbbreviate = false, config = null, addColParams = null) => {
|
|
23
23
|
if (!config) console.error('no config found in formatNumber')
|
|
24
24
|
// if num is NaN return num
|
|
25
25
|
if (isNaN(num) || !num) return num
|
|
@@ -30,22 +30,41 @@ const formatNumber = (num, axis, shouldAbbreviate = false, config = null) => {
|
|
|
30
30
|
if (isNegative) {
|
|
31
31
|
num = Math.abs(num)
|
|
32
32
|
}
|
|
33
|
-
|
|
33
|
+
|
|
34
34
|
// destructure dataFormat values
|
|
35
35
|
let {
|
|
36
36
|
dataFormat: { commas, abbreviated, roundTo, prefix, suffix, rightRoundTo, bottomRoundTo, rightPrefix, rightSuffix, bottomPrefix, bottomSuffix, bottomAbbreviated }
|
|
37
37
|
} = config
|
|
38
38
|
|
|
39
|
+
// destructure Additional Col dataformat values
|
|
40
|
+
const { addColCommas, addColRoundTo, addColPrefix, addColSuffix } = addColParams
|
|
41
|
+
|
|
39
42
|
// check if value contains comma and remove it. later will add comma below.
|
|
40
43
|
if (String(num).indexOf(',') !== -1) num = num.replaceAll(',', '')
|
|
41
44
|
|
|
42
45
|
let original = num
|
|
43
46
|
let stringFormattingOptions
|
|
44
47
|
if (axis === 'left') {
|
|
48
|
+
let roundToPlace
|
|
49
|
+
if (addColRoundTo !== undefined) {
|
|
50
|
+
// if its an Additional Column
|
|
51
|
+
roundToPlace = addColRoundTo ? Number(addColRoundTo) : 0
|
|
52
|
+
} else {
|
|
53
|
+
roundToPlace = roundTo ? Number(roundTo) : 0
|
|
54
|
+
}
|
|
55
|
+
// Need to prevent negative values in rounding
|
|
56
|
+
if (roundToPlace < 0) roundToPlace = 0
|
|
57
|
+
let useCommas
|
|
58
|
+
if (addColCommas !== undefined) {
|
|
59
|
+
// if its an Additional Column
|
|
60
|
+
useCommas = addColCommas ? true : false
|
|
61
|
+
} else {
|
|
62
|
+
useCommas = config.dataFormat.commas ? true : false
|
|
63
|
+
}
|
|
45
64
|
stringFormattingOptions = {
|
|
46
|
-
useGrouping:
|
|
47
|
-
minimumFractionDigits:
|
|
48
|
-
maximumFractionDigits:
|
|
65
|
+
useGrouping: useCommas,
|
|
66
|
+
minimumFractionDigits: roundToPlace,
|
|
67
|
+
maximumFractionDigits: roundToPlace
|
|
49
68
|
}
|
|
50
69
|
}
|
|
51
70
|
|
|
@@ -104,8 +123,12 @@ const formatNumber = (num, axis, shouldAbbreviate = false, config = null) => {
|
|
|
104
123
|
num = abbreviateNumber(parseFloat(num))
|
|
105
124
|
}
|
|
106
125
|
|
|
107
|
-
if (
|
|
108
|
-
result
|
|
126
|
+
if (addColPrefix !== undefined && axis === 'left') {
|
|
127
|
+
result = addColPrefix + result
|
|
128
|
+
} else {
|
|
129
|
+
if (prefix && axis === 'left') {
|
|
130
|
+
result = prefix + result
|
|
131
|
+
}
|
|
109
132
|
}
|
|
110
133
|
|
|
111
134
|
if (rightPrefix && axis === 'right') {
|
|
@@ -118,8 +141,12 @@ const formatNumber = (num, axis, shouldAbbreviate = false, config = null) => {
|
|
|
118
141
|
|
|
119
142
|
result += num
|
|
120
143
|
|
|
121
|
-
if (
|
|
122
|
-
result +=
|
|
144
|
+
if (addColSuffix !== undefined && axis === 'left') {
|
|
145
|
+
result += addColSuffix
|
|
146
|
+
} else {
|
|
147
|
+
if (suffix && axis === 'left') {
|
|
148
|
+
result += suffix
|
|
149
|
+
}
|
|
123
150
|
}
|
|
124
151
|
|
|
125
152
|
if (rightSuffix && axis === 'right') {
|
|
@@ -136,4 +163,10 @@ const formatNumber = (num, axis, shouldAbbreviate = false, config = null) => {
|
|
|
136
163
|
return String(result)
|
|
137
164
|
}
|
|
138
165
|
|
|
139
|
-
|
|
166
|
+
const getFontSize = (size = 'medium') => {
|
|
167
|
+
const fontSize = { small: 16, medium: 18, large: 20 }
|
|
168
|
+
|
|
169
|
+
return fontSize[size]
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
export { formatNumber, getFontSize }
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cdc/core",
|
|
3
|
-
"version": "4.23.
|
|
3
|
+
"version": "4.23.8",
|
|
4
4
|
"description": "Core components, styles, hooks, and helpers, for the CDC Open Visualization project",
|
|
5
5
|
"moduleName": "CdcCore",
|
|
6
6
|
"main": "dist/cdccore",
|
|
@@ -30,5 +30,5 @@
|
|
|
30
30
|
"react": "^18.2.0",
|
|
31
31
|
"react-dom": "^18.2.0"
|
|
32
32
|
},
|
|
33
|
-
"gitHead": "
|
|
33
|
+
"gitHead": "ba0a072a40c430baf121ad5ece0165f52a414b86"
|
|
34
34
|
}
|
package/styles/_data-table.scss
CHANGED
|
@@ -94,6 +94,7 @@ table.data-table {
|
|
|
94
94
|
background-size: 10px 5px;
|
|
95
95
|
}
|
|
96
96
|
|
|
97
|
+
/* doesnt work
|
|
97
98
|
th.sort-asc,
|
|
98
99
|
td.sort-asc {
|
|
99
100
|
background-image: url(../assets/icon-caret-filled-up.svg);
|
|
@@ -103,6 +104,19 @@ table.data-table {
|
|
|
103
104
|
td.sort-desc {
|
|
104
105
|
background-image: url(../assets/icon-caret-filled-down.svg);
|
|
105
106
|
}
|
|
107
|
+
*/
|
|
108
|
+
|
|
109
|
+
// format the white triangle sort icon in data table headers
|
|
110
|
+
.sort-icon {
|
|
111
|
+
fill: white;
|
|
112
|
+
width: 30px;
|
|
113
|
+
float: right;
|
|
114
|
+
align-self: center;
|
|
115
|
+
position: absolute;
|
|
116
|
+
right: 10px;
|
|
117
|
+
top: 50%;
|
|
118
|
+
transform: translateY(-50%);
|
|
119
|
+
}
|
|
106
120
|
|
|
107
121
|
th:last-child,
|
|
108
122
|
td:last-child {
|
|
@@ -1,17 +1,34 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
1
|
+
// Reusable variables, nice for JS manipulations
|
|
2
|
+
:root {
|
|
3
|
+
--cove-tooltip-bg: #fff;
|
|
4
|
+
--cove-tooltip-color: black;
|
|
5
|
+
--cove-tooltip-font-size: 14px;
|
|
6
|
+
--cove-tooltip-border-color: #bdbdbd;
|
|
7
|
+
--cove-tooltip-heading-fontWeight: bold;
|
|
8
|
+
--cove-tooltip-animation: 500ms cubic-bezier(0.16, 1, 0.3, 1) 50ms 1 forwards;
|
|
9
|
+
--cove-tooltip-maxWidth: 280px;
|
|
10
|
+
}
|
|
9
11
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
+
// Namespace to cove project, inconveniently using two different classes.
|
|
13
|
+
.cove,
|
|
14
|
+
.cdc-open-viz-module {
|
|
15
|
+
// todo: move to a utils folder.
|
|
16
|
+
.capitalize {
|
|
17
|
+
text-transform: capitalize;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
// react-tooltip library
|
|
21
|
+
.react-tooltip {
|
|
22
|
+
.styles-module_arrow,
|
|
23
|
+
.react-tooltip-arrow {
|
|
24
|
+
border-bottom: var(--cove-tooltip-border-color) 1px solid;
|
|
25
|
+
border-right: var(--cove-tooltip-border-color) 1px solid;
|
|
26
|
+
backface-visibility: hidden;
|
|
27
|
+
}
|
|
12
28
|
}
|
|
13
29
|
|
|
14
|
-
|
|
30
|
+
// editor-panel
|
|
31
|
+
.editor-panel {
|
|
15
32
|
.cove-label + .cove-tooltip {
|
|
16
33
|
top: 1px;
|
|
17
34
|
margin-left: 0.5rem;
|
|
@@ -30,6 +47,61 @@ $cove-tooltip-animation: 500ms cubic-bezier(0.16, 1, 0.3, 1) 50ms 1 forwards;
|
|
|
30
47
|
line-height: inherit;
|
|
31
48
|
}
|
|
32
49
|
}
|
|
50
|
+
|
|
51
|
+
// begin actual tooltip styles
|
|
52
|
+
.react-tooltip,
|
|
53
|
+
.tooltip {
|
|
54
|
+
color: var(--cove-tooltip-color);
|
|
55
|
+
border: 1px solid var(--cove-tooltip-border-color);
|
|
56
|
+
padding: 0.3rem 0.5rem;
|
|
57
|
+
z-index: 1000;
|
|
58
|
+
opacity: 1;
|
|
59
|
+
|
|
60
|
+
.interactive {
|
|
61
|
+
a {
|
|
62
|
+
pointer-events: all;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
ul {
|
|
67
|
+
list-style: none;
|
|
68
|
+
|
|
69
|
+
li {
|
|
70
|
+
font-size: var(--cove-tooltip-font-size) !important;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
// under the heading
|
|
74
|
+
> li.tooltip-body {
|
|
75
|
+
border-top: 1px solid black;
|
|
76
|
+
padding-top: 5px;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
li.tooltip-body:first-of-type {
|
|
80
|
+
padding-top: 5px;
|
|
81
|
+
border-top: 1px solid black;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
// undo previous except first class
|
|
85
|
+
> li.tooltip-body ~ li.tooltip-body {
|
|
86
|
+
border-top: initial;
|
|
87
|
+
padding-top: initial;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
.tooltip-heading {
|
|
92
|
+
display: block;
|
|
93
|
+
font-weight: var(--cove-tooltip-heading-fontWeight) !important;
|
|
94
|
+
padding-bottom: 3px;
|
|
95
|
+
padding-top: 3px;
|
|
96
|
+
font-size: var(--cove-tooltip-font-size) !important;
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
.cove-tooltip {
|
|
102
|
+
display: inline-block;
|
|
103
|
+
position: relative;
|
|
104
|
+
line-height: 1em;
|
|
33
105
|
}
|
|
34
106
|
|
|
35
107
|
.cove-tooltip--target {
|
|
@@ -45,16 +117,15 @@ $cove-tooltip-animation: 500ms cubic-bezier(0.16, 1, 0.3, 1) 50ms 1 forwards;
|
|
|
45
117
|
}
|
|
46
118
|
|
|
47
119
|
.cove-tooltip__content {
|
|
48
|
-
max-width:
|
|
120
|
+
max-width: var(--cove-tooltip-maxWidth);
|
|
49
121
|
padding: 10px 8px;
|
|
50
122
|
font-size: 0.875rem;
|
|
51
123
|
line-height: 1.125rem;
|
|
52
124
|
text-align: left;
|
|
53
|
-
color:
|
|
54
|
-
background-color:
|
|
125
|
+
color: var(--cove-tooltip-color);
|
|
126
|
+
background-color: var(--cove-tooltip-bg);
|
|
55
127
|
border-radius: 5px;
|
|
56
128
|
user-select: none;
|
|
57
|
-
opacity: 0;
|
|
58
129
|
cursor: default;
|
|
59
130
|
z-index: 1;
|
|
60
131
|
|
|
@@ -64,7 +135,7 @@ $cove-tooltip-animation: 500ms cubic-bezier(0.16, 1, 0.3, 1) 50ms 1 forwards;
|
|
|
64
135
|
}
|
|
65
136
|
|
|
66
137
|
&.cove-tooltip__content--animated[class*='styles-module_show__'] {
|
|
67
|
-
animation: tooltip-btt
|
|
138
|
+
animation: tooltip-btt var(--cove-tooltip-animation);
|
|
68
139
|
}
|
|
69
140
|
}
|
|
70
141
|
|
|
@@ -74,7 +145,7 @@ $cove-tooltip-animation: 500ms cubic-bezier(0.16, 1, 0.3, 1) 50ms 1 forwards;
|
|
|
74
145
|
}
|
|
75
146
|
|
|
76
147
|
&.cove-tooltip__content--animated[class*='styles-module_show__'] {
|
|
77
|
-
animation: tooltip-ltr
|
|
148
|
+
animation: tooltip-ltr var(--cove-tooltip-animation);
|
|
78
149
|
}
|
|
79
150
|
}
|
|
80
151
|
|
|
@@ -84,7 +155,7 @@ $cove-tooltip-animation: 500ms cubic-bezier(0.16, 1, 0.3, 1) 50ms 1 forwards;
|
|
|
84
155
|
}
|
|
85
156
|
|
|
86
157
|
&.cove-tooltip__content--animated[class*='styles-module_show__'] {
|
|
87
|
-
animation: tooltip-ttb
|
|
158
|
+
animation: tooltip-ttb var(--cove-tooltip-animation);
|
|
88
159
|
}
|
|
89
160
|
}
|
|
90
161
|
|
|
@@ -94,61 +165,7 @@ $cove-tooltip-animation: 500ms cubic-bezier(0.16, 1, 0.3, 1) 50ms 1 forwards;
|
|
|
94
165
|
}
|
|
95
166
|
|
|
96
167
|
&.cove-tooltip__content--animated[class*='styles-module_show__'] {
|
|
97
|
-
animation: tooltip-rtl
|
|
168
|
+
animation: tooltip-rtl var(--cove-tooltip-animation);
|
|
98
169
|
}
|
|
99
170
|
}
|
|
100
171
|
}
|
|
101
|
-
|
|
102
|
-
.interactive {
|
|
103
|
-
a {
|
|
104
|
-
pointer-events: all;
|
|
105
|
-
}
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
@keyframes tooltip-ltr {
|
|
109
|
-
0% {
|
|
110
|
-
opacity: 0;
|
|
111
|
-
transform: translateX(-8px);
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
100% {
|
|
115
|
-
opacity: 1;
|
|
116
|
-
transform: translateX(0);
|
|
117
|
-
}
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
@keyframes tooltip-rtl {
|
|
121
|
-
0% {
|
|
122
|
-
opacity: 0;
|
|
123
|
-
transform: translateX(8px);
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
100% {
|
|
127
|
-
opacity: 1;
|
|
128
|
-
transform: translateX(0);
|
|
129
|
-
}
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
@keyframes tooltip-ttb {
|
|
133
|
-
0% {
|
|
134
|
-
opacity: 0;
|
|
135
|
-
transform: translateY(-8px);
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
100% {
|
|
139
|
-
opacity: 1;
|
|
140
|
-
transform: translateY(0);
|
|
141
|
-
}
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
@keyframes tooltip-btt {
|
|
145
|
-
0% {
|
|
146
|
-
opacity: 0;
|
|
147
|
-
transform: translateY(8px);
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
100% {
|
|
151
|
-
opacity: 1;
|
|
152
|
-
transform: translateY(0);
|
|
153
|
-
}
|
|
154
|
-
}
|
|
@@ -150,16 +150,6 @@
|
|
|
150
150
|
background-size: 10px 5px;
|
|
151
151
|
}
|
|
152
152
|
|
|
153
|
-
.sort-asc {
|
|
154
|
-
//TODO find fix
|
|
155
|
-
//background-image: url(~@cdc/core/assets/icon-caret-filled-up.svg);
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
.sort-desc {
|
|
159
|
-
//TODO find fix
|
|
160
|
-
//background-image: url(~@cdc/core/assets/icon-caret-filled-down.svg);
|
|
161
|
-
}
|
|
162
|
-
|
|
163
153
|
.resizer {
|
|
164
154
|
cursor: e-resize;
|
|
165
155
|
width: 10px;
|
|
@@ -171,6 +161,7 @@
|
|
|
171
161
|
}
|
|
172
162
|
}
|
|
173
163
|
|
|
164
|
+
|
|
174
165
|
.cove-data-table__footer {
|
|
175
166
|
margin-top: 1rem;
|
|
176
167
|
}
|
|
File without changes
|