@cdc/core 4.26.2 → 4.26.3
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/LICENSE +201 -0
- package/_stories/Gallery.Charts.stories.tsx +1 -1
- package/_stories/Gallery.DataBite.stories.tsx +1 -1
- package/_stories/Gallery.Maps.stories.tsx +1 -1
- package/_stories/PageART.stories.tsx +1 -1
- package/_stories/PageBRFSS.stories.tsx +1 -1
- package/_stories/PageCancerRegistries.stories.tsx +1 -1
- package/_stories/PageEasternEquineEncephalitis.stories.tsx +3 -3
- package/_stories/PageExcessiveAlcoholUse.stories.tsx +1 -1
- package/_stories/PageMaternalMortality.stories.tsx +1 -1
- package/_stories/PageOralHealth.stories.tsx +1 -1
- package/_stories/PageRespiratory.stories.tsx +4 -4
- package/_stories/PageSmokingTobacco.stories.tsx +1 -1
- package/_stories/PageStateDiabetesProfiles.stories.tsx +1 -1
- package/_stories/PageWastewater.stories.tsx +4 -4
- package/_stories/VegaImport.stories.tsx +3 -3
- package/assets/callout-flag.svg +7 -0
- package/components/AdvancedEditor/EmbedEditor.tsx +1 -1
- package/components/Alert/components/Alert.styles.css +2 -2
- package/components/ComboBox/combobox.styles.css +48 -48
- package/components/CustomColorsEditor/CustomColorsEditor.css +53 -53
- package/components/DataTable/DataTable.tsx +46 -18
- package/components/DataTable/DataTableStandAlone.tsx +1 -0
- package/components/DataTable/components/ChartHeader.tsx +21 -12
- package/components/DataTable/components/MapHeader.tsx +34 -28
- package/components/DataTable/components/SortIcon/sort-icon.css +5 -5
- package/components/DataTable/data-table.css +50 -52
- package/components/DataTable/helpers/applyCustomOrder.ts +17 -0
- package/components/DataTable/helpers/getChartCellValue.ts +10 -7
- package/components/DataTable/helpers/getMapDataTableColumnKeys.ts +22 -0
- package/components/DataTable/helpers/mapCellMatrix.tsx +33 -23
- package/components/DataTable/helpers/tests/mapCellMatrix.test.ts +33 -0
- package/components/DownloadButton.tsx +14 -6
- package/components/EditorPanel/ColumnsEditor.tsx +38 -31
- package/components/EditorPanel/CustomSortOrder.tsx +94 -0
- package/components/EditorPanel/DataTableEditor.tsx +139 -23
- package/components/EditorPanel/EditorPanel.styles.css +71 -71
- package/components/EditorPanel/EditorPanel.tsx +3 -8
- package/components/EditorPanel/EditorPanelDispatch.tsx +4 -4
- package/components/EditorPanel/FootnotesEditor.tsx +2 -2
- package/components/EditorPanel/VizFilterEditor/NestedDropdownEditor.tsx +7 -6
- package/components/EditorPanel/VizFilterEditor/VizFilterEditor.tsx +12 -10
- package/components/EditorPanel/components/MarkupVariablesEditor.tsx +160 -106
- package/components/EditorPanel/components/PanelMarkup.tsx +5 -1
- package/{styles/v2/components → components/EditorPanel}/editor.scss +67 -13
- package/components/EditorPanel/sections/StyleTreatmentSection.tsx +99 -0
- package/components/EditorPanel/sections/VisualSection.tsx +11 -0
- package/components/EditorWrapper/editor-wrapper.style.css +1 -1
- package/components/Filters/Filters.tsx +3 -5
- package/components/Filters/components/Tabs.tsx +19 -7
- package/{styles → components/Filters}/filters.scss +3 -3
- package/components/Footnotes/FootnotesStandAlone.tsx +4 -2
- package/components/HeaderThemeSelector/HeaderThemeSelector.css +61 -5
- package/components/Layout/components/Responsive.tsx +14 -6
- package/components/Layout/components/Sidebar/components/Sidebar.tsx +1 -1
- package/components/Layout/components/Sidebar/components/sidebar.styles.scss +12 -18
- package/components/Layout/components/Visualization/index.tsx +39 -38
- package/components/Layout/components/Visualization/visualizations.scss +232 -15
- package/components/Layout/components/VisualizationContainer.test.tsx +67 -0
- package/components/Layout/components/VisualizationContainer.tsx +37 -0
- package/components/Layout/components/VisualizationContent.test.tsx +182 -0
- package/components/Layout/components/VisualizationContent.tsx +75 -0
- package/components/Layout/index.tsx +5 -5
- package/components/Layout/styles/editor-utils.scss +3 -3
- package/components/Layout/styles/editor.scss +4 -4
- package/components/Legend/Legend.Gradient.tsx +7 -1
- package/components/Loader/loader.styles.css +2 -2
- package/components/Loading.jsx +1 -1
- package/components/MediaControls.tsx +10 -2
- package/components/MultiSelect/multiselect.styles.css +19 -19
- package/components/NestedDropdown/nesteddropdown.styles.css +15 -15
- package/components/PaletteSelector/PaletteSelector.css +15 -15
- package/components/RichTooltip/richTooltip.css +6 -6
- package/components/Table/table.styles.css +2 -2
- package/components/Waiting.tsx +1 -1
- package/components/_stories/Filters.stories.tsx +1 -1
- package/components/_stories/styles.scss +0 -1
- package/components/elements/Button.jsx +1 -1
- package/components/elements/Card.jsx +1 -1
- package/{styles/v2/components → components/elements}/button.scss +9 -8
- package/components/inputs/InputCheckbox.jsx +1 -1
- package/components/inputs/InputSelect.tsx +1 -1
- package/components/inputs/InputText.jsx +1 -1
- package/components/inputs/InputToggle.tsx +1 -1
- package/{styles/v2/components/input → components/inputs}/_input-check-radio.scss +2 -2
- package/{styles/v2/components/input → components/inputs}/_input-group.scss +3 -3
- package/{styles/v2/components/input → components/inputs}/_input-slider.scss +2 -2
- package/{styles/v2/components/input → components/inputs}/_input.scss +5 -5
- package/{styles/v2/components/input → components/inputs}/index.scss +2 -2
- package/{styles → components}/loading.scss +1 -1
- package/components/managers/DataDesigner.tsx +1 -1
- package/{styles/v2/components → components/managers}/data-designer.scss +6 -7
- package/components/ui/Accordion.jsx +1 -1
- package/components/ui/Icon.tsx +1 -1
- package/components/ui/LoadSpin.jsx +1 -1
- package/components/ui/Modal.jsx +1 -1
- package/components/ui/Overlay.jsx +1 -1
- package/components/ui/Title/index.test.tsx +34 -0
- package/components/ui/Title/index.tsx +24 -7
- package/components/ui/Title/title.styles.css +119 -25
- package/components/ui/Tooltip.tsx +1 -1
- package/components/ui/_stories/Title.stories.tsx +1 -1
- package/{styles/v2/components → components/ui}/accordion.scss +3 -3
- package/components/ui/accordion.styles.css +11 -11
- package/{styles/v2/components → components/ui}/modal.scss +2 -2
- package/{styles/v2/components → components/ui}/overlay.scss +6 -6
- package/{styles/v2/components → components}/ui/tooltip.scss +1 -1
- package/{styles → components}/waiting.scss +9 -3
- package/devTemplate/dev.js +50 -0
- package/dist/cove-main.css +528 -231
- package/dist/cove-main.css.map +1 -1
- package/generateViteConfig.js +2 -2
- package/helpers/backfillDefaults.ts +35 -0
- package/helpers/constants.ts +12 -0
- package/helpers/cove/date.ts +32 -3
- package/helpers/cove/number.ts +29 -15
- package/helpers/coveUpdateWorker.ts +12 -8
- package/helpers/displayDataAsText.ts +1 -1
- package/helpers/embed/embedHelper.js +13 -2
- package/helpers/embed/index.ts +0 -4
- package/helpers/extractDataAndMetadata.ts +20 -0
- package/helpers/fetchRemoteData.ts +14 -8
- package/helpers/labelHash.ts +9 -0
- package/helpers/markupProcessor.ts +56 -38
- package/helpers/prepareScreenshot.ts +6 -3
- package/helpers/testing.ts +1 -1
- package/helpers/tests/abbreviateNumber.test.ts +59 -0
- package/helpers/tests/backfillDefaults.test.ts +253 -0
- package/helpers/tests/date.test.ts +46 -0
- package/helpers/tests/extractDataAndMetadata.test.ts +93 -0
- package/helpers/tests/markupProcessor.test.ts +315 -124
- package/helpers/tests/number.test.ts +42 -0
- package/helpers/tests/prepareScreenshot.test.ts +28 -28
- package/helpers/tests/testStandaloneBuild.ts +36 -26
- package/helpers/tests/useDataVizClasses.test.ts +66 -0
- package/helpers/tests/visualizationWrapperUsage.test.ts +57 -0
- package/helpers/useDataVizClasses.ts +13 -7
- package/helpers/ver/4.24.4.ts +24 -0
- package/helpers/ver/4.26.3.ts +44 -0
- package/helpers/ver/4.26.4.ts +31 -0
- package/helpers/ver/tests/4.26.3.test.ts +168 -0
- package/helpers/ver/tests/4.26.4.test.ts +88 -0
- package/helpers/ver/tests/coveUpdateWorker.test.ts +57 -0
- package/package.json +2 -2
- package/styles/_global.scss +7 -7
- package/styles/_reset.scss +2 -2
- package/styles/{v2/base → base}/_file-selector.scss +4 -4
- package/styles/{v2/base → base}/_general.scss +2 -4
- package/styles/{v2/base → base}/index.scss +1 -1
- package/styles/base.scss +107 -165
- package/styles/cove-main.scss +3 -6
- package/styles/layout/_component.scss +110 -0
- package/styles/{v2/layout → layout}/_data-table.scss +7 -7
- package/styles/layout/_wrapper-padding.scss +27 -0
- package/styles/{v2/main.scss → main.scss} +3 -1
- package/styles/{v2/themes → themes}/_color-definitions.scss +46 -41
- package/styles/{_accessibility.scss → utils/_accessibility.scss} +1 -1
- package/styles/{_global-variables.scss → utils/_properties.scss} +133 -112
- package/styles/{v2/utils → utils}/index.scss +2 -1
- package/types/Axis.ts +2 -0
- package/types/ComponentStyles.ts +1 -0
- package/types/ConfigureData.ts +1 -0
- package/types/MarkupInclude.ts +1 -0
- package/types/MarkupVariable.ts +2 -1
- package/types/Palette.ts +1 -0
- package/types/Table.ts +9 -0
- package/types/Visualization.ts +1 -0
- package/styles/_common-components.css +0 -73
- package/styles/_variables.scss +0 -63
- package/styles/v2/layout/_component.scss +0 -21
- package/styles/v2/utils/_variables.scss +0 -9
- package/{styles/v2/components/card.scss → components/elements/card.css} +2 -2
- /package/{styles/v2/components → components/ui}/icon.scss +0 -0
- /package/{styles/v2/components → components/ui}/loadspin.scss +0 -0
- /package/styles/{v2/base → base}/_heading.scss +0 -0
- /package/styles/{v2/base → base}/_reset.scss +0 -0
- /package/styles/{v2/layout → layout}/_alert.scss +0 -0
- /package/styles/{v2/layout → layout}/_progression.scss +0 -0
- /package/styles/{v2/layout → layout}/_tooltip.scss +0 -0
- /package/styles/{v2/layout → layout}/index.scss +0 -0
- /package/styles/{v2/themes → themes}/index.scss +0 -0
- /package/styles/{v2/utils → utils}/_align.scss +0 -0
- /package/styles/{v2/utils → utils}/_animations.scss +0 -0
- /package/styles/{v2/utils → utils}/_breakpoints.scss +0 -0
- /package/styles/{v2/utils → utils}/_grid.scss +0 -0
- /package/styles/{v2/utils → utils}/_mixins.scss +0 -0
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import { useCallback, useMemo } from 'react'
|
|
2
|
+
import { DragDropContext, Droppable, Draggable } from '@hello-pangea/dnd'
|
|
3
|
+
import _ from 'lodash'
|
|
4
|
+
|
|
5
|
+
type CustomSortOrderProps = {
|
|
6
|
+
column: string
|
|
7
|
+
data: Record<string, any>[]
|
|
8
|
+
customOrder?: string[]
|
|
9
|
+
updateField: Function
|
|
10
|
+
/** Optional transform for display labels (e.g. displayGeoName for maps) */
|
|
11
|
+
displayTransform?: (value: string) => string
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Editor component for drag-and-drop custom sort ordering.
|
|
16
|
+
* Shows unique values from the selected column and allows reordering via DnD.
|
|
17
|
+
*/
|
|
18
|
+
const CustomSortOrder: React.FC<CustomSortOrderProps> = ({
|
|
19
|
+
column,
|
|
20
|
+
data,
|
|
21
|
+
customOrder,
|
|
22
|
+
updateField,
|
|
23
|
+
displayTransform
|
|
24
|
+
}) => {
|
|
25
|
+
// Compute unique values from the selected column
|
|
26
|
+
const uniqueValues = useMemo(() => {
|
|
27
|
+
if (!column || !data?.length) return []
|
|
28
|
+
const values = data.map(row => String(row[column] ?? '')).filter(v => v !== '')
|
|
29
|
+
return _.uniq(values)
|
|
30
|
+
}, [column, data])
|
|
31
|
+
|
|
32
|
+
// Use customOrder if set, otherwise fall back to natural unique order
|
|
33
|
+
const orderedValues = useMemo(() => {
|
|
34
|
+
if (customOrder?.length) {
|
|
35
|
+
// Include any new values from data that aren't in customOrder
|
|
36
|
+
const extra = uniqueValues.filter(v => !customOrder.includes(v))
|
|
37
|
+
return [...customOrder.filter(v => uniqueValues.includes(v)), ...extra]
|
|
38
|
+
}
|
|
39
|
+
return uniqueValues
|
|
40
|
+
}, [customOrder, uniqueValues])
|
|
41
|
+
|
|
42
|
+
const handleDragEnd = useCallback(
|
|
43
|
+
({ source, destination }) => {
|
|
44
|
+
if (!destination || source.index === destination.index) return
|
|
45
|
+
const reordered = [...orderedValues]
|
|
46
|
+
const [moved] = reordered.splice(source.index, 1)
|
|
47
|
+
reordered.splice(destination.index, 0, moved)
|
|
48
|
+
updateField('table', 'defaultSort', 'customOrder', reordered)
|
|
49
|
+
},
|
|
50
|
+
[orderedValues, updateField]
|
|
51
|
+
)
|
|
52
|
+
|
|
53
|
+
if (!orderedValues.length) return null
|
|
54
|
+
|
|
55
|
+
return (
|
|
56
|
+
<div>
|
|
57
|
+
<DragDropContext onDragEnd={handleDragEnd}>
|
|
58
|
+
<Droppable droppableId='custom_sort_order'>
|
|
59
|
+
{provided => (
|
|
60
|
+
<ul
|
|
61
|
+
{...provided.droppableProps}
|
|
62
|
+
className='sort-list'
|
|
63
|
+
ref={provided.innerRef}
|
|
64
|
+
style={{ marginTop: '0.5em', paddingLeft: 0, listStyle: 'none' }}
|
|
65
|
+
>
|
|
66
|
+
{orderedValues.map((value, index) => (
|
|
67
|
+
<Draggable key={value} draggableId={`customSort-${value}`} index={index}>
|
|
68
|
+
{(provided, snapshot) => (
|
|
69
|
+
<li style={{ marginBottom: '2px' }}>
|
|
70
|
+
<div
|
|
71
|
+
className={snapshot.isDragging ? 'currently-dragging' : ''}
|
|
72
|
+
style={{
|
|
73
|
+
...provided.draggableProps.style
|
|
74
|
+
}}
|
|
75
|
+
ref={provided.innerRef}
|
|
76
|
+
{...provided.draggableProps}
|
|
77
|
+
{...provided.dragHandleProps}
|
|
78
|
+
>
|
|
79
|
+
{displayTransform ? displayTransform(value) : value}
|
|
80
|
+
</div>
|
|
81
|
+
</li>
|
|
82
|
+
)}
|
|
83
|
+
</Draggable>
|
|
84
|
+
))}
|
|
85
|
+
{provided.placeholder}
|
|
86
|
+
</ul>
|
|
87
|
+
)}
|
|
88
|
+
</Droppable>
|
|
89
|
+
</DragDropContext>
|
|
90
|
+
</div>
|
|
91
|
+
)
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
export default CustomSortOrder
|
|
@@ -7,6 +7,7 @@ import { UpdateFieldFunc } from '../../types/UpdateFieldFunc'
|
|
|
7
7
|
import { Visualization } from '../../types/Visualization'
|
|
8
8
|
import _ from 'lodash'
|
|
9
9
|
import { Column } from '../../types/Column'
|
|
10
|
+
import CustomSortOrder from './CustomSortOrder'
|
|
10
11
|
|
|
11
12
|
interface DataTableProps {
|
|
12
13
|
config: Partial<Visualization>
|
|
@@ -27,7 +28,7 @@ const DataTableEditor: React.FC<DataTableProps> = ({ config, updateField, isDash
|
|
|
27
28
|
}, [config.columns])
|
|
28
29
|
|
|
29
30
|
const groupPivotColumns = useMemo(() => {
|
|
30
|
-
const columns: string[] = config.data.flatMap(Object.keys)
|
|
31
|
+
const columns: string[] = (config.data ?? []).flatMap(Object.keys)
|
|
31
32
|
const cols = _.uniq(columns).filter(key => {
|
|
32
33
|
return true
|
|
33
34
|
})
|
|
@@ -39,6 +40,56 @@ const DataTableEditor: React.FC<DataTableProps> = ({ config, updateField, isDash
|
|
|
39
40
|
updateField('table', null, 'groupBy', value)
|
|
40
41
|
}
|
|
41
42
|
|
|
43
|
+
const changeSortColumn = (value: string) => {
|
|
44
|
+
if (value === '' || value === PLACEHOLDER) {
|
|
45
|
+
// Clear entire defaultSort when column is deselected
|
|
46
|
+
updateField('table', null, 'defaultSort', {})
|
|
47
|
+
return
|
|
48
|
+
}
|
|
49
|
+
// Set column and reset to ascending, clear custom order
|
|
50
|
+
updateField('table', null, 'defaultSort', { column: value, sortDirection: 'asc' })
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
const changeSortDirection = (value: string) => {
|
|
54
|
+
const newDefaultSort = { ...config.table.defaultSort, sortDirection: value }
|
|
55
|
+
// Clear customOrder when switching away from custom
|
|
56
|
+
if (value !== 'custom') {
|
|
57
|
+
delete newDefaultSort.customOrder
|
|
58
|
+
} else if (!newDefaultSort.customOrder?.length) {
|
|
59
|
+
// Auto-populate customOrder with unique values so the table updates immediately
|
|
60
|
+
const col = newDefaultSort.column
|
|
61
|
+
const dataCol = config.type === 'map' && config.columns?.[col]?.name ? config.columns[col].name : col
|
|
62
|
+
if (dataCol && config.data?.length) {
|
|
63
|
+
newDefaultSort.customOrder = _.uniq(config.data.map(row => String(row[dataCol] ?? '')).filter(v => v !== ''))
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
updateField('table', null, 'defaultSort', newDefaultSort)
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
// Build sort column options based on visualization type
|
|
70
|
+
// Maps use config.columns keys (geo, primary, etc.); other types use data column names
|
|
71
|
+
const sortColumnOptions = useMemo(() => {
|
|
72
|
+
if (config.type === 'map' && config.columns) {
|
|
73
|
+
return Object.keys(config.columns)
|
|
74
|
+
.filter(key => config.columns[key].dataTable !== false && config.columns[key].name)
|
|
75
|
+
.map(key => ({
|
|
76
|
+
label: config.columns[key].label || config.columns[key].name || key,
|
|
77
|
+
value: key
|
|
78
|
+
}))
|
|
79
|
+
}
|
|
80
|
+
return dataColumns.map(col => ({ label: col, value: col }))
|
|
81
|
+
}, [config.type, config.columns, dataColumns])
|
|
82
|
+
|
|
83
|
+
// For custom sort, resolve the actual data column name to get unique values
|
|
84
|
+
const customSortDataColumn = useMemo(() => {
|
|
85
|
+
const col = config.table?.defaultSort?.column
|
|
86
|
+
if (!col) return ''
|
|
87
|
+
if (config.type === 'map' && config.columns?.[col]?.name) {
|
|
88
|
+
return config.columns[col].name
|
|
89
|
+
}
|
|
90
|
+
return col
|
|
91
|
+
}, [config.type, config.columns, config.table?.defaultSort?.column])
|
|
92
|
+
|
|
42
93
|
const excludeColumns = (section, subSection, fieldName, excludedColNames: string[]) => {
|
|
43
94
|
const newColumns = _.cloneDeep(config.columns)
|
|
44
95
|
|
|
@@ -234,6 +285,49 @@ const DataTableEditor: React.FC<DataTableProps> = ({ config, updateField, isDash
|
|
|
234
285
|
updateField={updateField}
|
|
235
286
|
/>
|
|
236
287
|
)}
|
|
288
|
+
<Select
|
|
289
|
+
value={config.table.defaultSort?.column || ''}
|
|
290
|
+
fieldName='column'
|
|
291
|
+
section='table'
|
|
292
|
+
subsection='defaultSort'
|
|
293
|
+
label='Default Sort Column'
|
|
294
|
+
initial={PLACEHOLDER}
|
|
295
|
+
options={sortColumnOptions}
|
|
296
|
+
updateField={(_section, _subSection, _fieldName, value) => changeSortColumn(value)}
|
|
297
|
+
tooltip={
|
|
298
|
+
<Tooltip style={{ textTransform: 'none' }}>
|
|
299
|
+
<Tooltip.Target>
|
|
300
|
+
<Icon display='question' style={{ marginLeft: '0.5rem' }} />
|
|
301
|
+
</Tooltip.Target>
|
|
302
|
+
<Tooltip.Content>
|
|
303
|
+
<p>Choose a column to sort the data table by when it first loads.</p>
|
|
304
|
+
</Tooltip.Content>
|
|
305
|
+
</Tooltip>
|
|
306
|
+
}
|
|
307
|
+
/>
|
|
308
|
+
{config.table.defaultSort?.column && (
|
|
309
|
+
<Select
|
|
310
|
+
value={config.table.defaultSort?.sortDirection || 'asc'}
|
|
311
|
+
fieldName='sortDirection'
|
|
312
|
+
section='table'
|
|
313
|
+
subsection='defaultSort'
|
|
314
|
+
label='Sort Direction'
|
|
315
|
+
options={[
|
|
316
|
+
{ label: 'Ascending', value: 'asc' },
|
|
317
|
+
{ label: 'Descending', value: 'desc' },
|
|
318
|
+
{ label: 'Custom', value: 'custom' }
|
|
319
|
+
]}
|
|
320
|
+
updateField={(_section, _subSection, _fieldName, value) => changeSortDirection(value)}
|
|
321
|
+
/>
|
|
322
|
+
)}
|
|
323
|
+
{config.table.defaultSort?.column && config.table.defaultSort?.sortDirection === 'custom' && (
|
|
324
|
+
<CustomSortOrder
|
|
325
|
+
column={customSortDataColumn}
|
|
326
|
+
data={config.data}
|
|
327
|
+
customOrder={config.table.defaultSort.customOrder}
|
|
328
|
+
updateField={updateField}
|
|
329
|
+
/>
|
|
330
|
+
)}
|
|
237
331
|
<CheckBox
|
|
238
332
|
value={config.table.download}
|
|
239
333
|
fieldName='download'
|
|
@@ -259,6 +353,16 @@ const DataTableEditor: React.FC<DataTableProps> = ({ config, updateField, isDash
|
|
|
259
353
|
section='table'
|
|
260
354
|
updateField={updateField}
|
|
261
355
|
/>
|
|
356
|
+
<div className='ms-4 mt-2' style={{ maxWidth: 'calc(100% - 1.5rem)' }}>
|
|
357
|
+
<TextField
|
|
358
|
+
value={config.table.downloadDataLabel}
|
|
359
|
+
section='table'
|
|
360
|
+
fieldName='downloadDataLabel'
|
|
361
|
+
label='Download Data Link Text'
|
|
362
|
+
placeholder='Download Data (CSV)'
|
|
363
|
+
updateField={updateField}
|
|
364
|
+
/>
|
|
365
|
+
</div>
|
|
262
366
|
</>
|
|
263
367
|
)}
|
|
264
368
|
{isDashboard && config.type !== 'table' && (
|
|
@@ -289,28 +393,40 @@ const DataTableEditor: React.FC<DataTableProps> = ({ config, updateField, isDash
|
|
|
289
393
|
/>
|
|
290
394
|
)}
|
|
291
395
|
{config.type !== 'table' && config.table.showDownloadImgButton && (
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
<Tooltip
|
|
302
|
-
<
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
<
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
396
|
+
<>
|
|
397
|
+
<CheckBox
|
|
398
|
+
value={config.table.includeContextInDownload}
|
|
399
|
+
fieldName='includeContextInDownload'
|
|
400
|
+
className='ms-4'
|
|
401
|
+
label='Include Heading & Context'
|
|
402
|
+
section='table'
|
|
403
|
+
updateField={updateField}
|
|
404
|
+
tooltip={
|
|
405
|
+
<Tooltip style={{ textTransform: 'none' }}>
|
|
406
|
+
<Tooltip.Target>
|
|
407
|
+
<Icon display='question' style={{ marginLeft: '0.5rem' }} />
|
|
408
|
+
</Tooltip.Target>
|
|
409
|
+
<Tooltip.Content>
|
|
410
|
+
<p>
|
|
411
|
+
When enabled, the image download will include the section heading (H2 or H3) and any explanatory
|
|
412
|
+
paragraphs that appear immediately before the visualization. Be sure to test the image download on
|
|
413
|
+
the published page to ensure the correct context is included.
|
|
414
|
+
</p>
|
|
415
|
+
</Tooltip.Content>
|
|
416
|
+
</Tooltip>
|
|
417
|
+
}
|
|
418
|
+
/>
|
|
419
|
+
<div className='ms-4 mt-2' style={{ maxWidth: 'calc(100% - 1.5rem)' }}>
|
|
420
|
+
<TextField
|
|
421
|
+
value={config.table.downloadImageLabel}
|
|
422
|
+
section='table'
|
|
423
|
+
fieldName='downloadImageLabel'
|
|
424
|
+
label='Download Image Link Text'
|
|
425
|
+
placeholder={`Download ${config.type === 'map' ? 'Map' : 'Chart'} (PNG)`}
|
|
426
|
+
updateField={updateField}
|
|
427
|
+
/>
|
|
428
|
+
</div>
|
|
429
|
+
</>
|
|
314
430
|
)}
|
|
315
431
|
<label>
|
|
316
432
|
<span className='edit-label column-heading'>Table Cell Min Width</span>
|
|
@@ -3,9 +3,9 @@
|
|
|
3
3
|
|
|
4
4
|
/* Color palette in editor panel context */
|
|
5
5
|
.editor-panel .header .color-palette li {
|
|
6
|
-
width: 1.5em;
|
|
7
|
-
height: 1.5em;
|
|
8
6
|
display: inline-block;
|
|
7
|
+
height: 1.5em;
|
|
8
|
+
width: 1.5em;
|
|
9
9
|
}
|
|
10
10
|
|
|
11
11
|
.editor-panel .color-palette {
|
|
@@ -13,12 +13,12 @@
|
|
|
13
13
|
}
|
|
14
14
|
|
|
15
15
|
.editor-panel .color-palette li {
|
|
16
|
-
|
|
17
|
-
|
|
16
|
+
border: rgba(0, 0, 0, 0.3) 3px solid;
|
|
17
|
+
cursor: pointer;
|
|
18
18
|
display: inline-block;
|
|
19
|
+
height: 1.5em;
|
|
19
20
|
margin-right: 0.5em;
|
|
20
|
-
|
|
21
|
-
border: rgba(0, 0, 0, 0.3) 3px solid;
|
|
21
|
+
width: 1.5em;
|
|
22
22
|
}
|
|
23
23
|
|
|
24
24
|
.editor-panel .color-palette li.active {
|
|
@@ -26,24 +26,24 @@
|
|
|
26
26
|
}
|
|
27
27
|
|
|
28
28
|
.editor-panel .color-palette a {
|
|
29
|
-
display: inline-block;
|
|
30
29
|
border-bottom: 1px solid rgba(0, 0, 0, 0.8);
|
|
30
|
+
display: inline-block;
|
|
31
31
|
}
|
|
32
32
|
|
|
33
33
|
.editor-panel .color-palette.series-list {
|
|
34
|
+
border: none;
|
|
34
35
|
flex-direction: column;
|
|
35
36
|
padding: 0;
|
|
36
|
-
border: none;
|
|
37
37
|
}
|
|
38
38
|
|
|
39
39
|
.editor-panel .color-palette.series-list li {
|
|
40
|
-
padding: 0.3em 0.5em;
|
|
41
|
-
display: flex;
|
|
42
40
|
align-items: center;
|
|
41
|
+
border: 0;
|
|
42
|
+
display: flex;
|
|
43
|
+
height: auto;
|
|
43
44
|
justify-content: space-between;
|
|
45
|
+
padding: 0.3em 0.5em;
|
|
44
46
|
width: auto;
|
|
45
|
-
height: auto;
|
|
46
|
-
border: 0;
|
|
47
47
|
}
|
|
48
48
|
|
|
49
49
|
.editor-panel .color-palette.series-list li:not(:last-child) {
|
|
@@ -61,10 +61,10 @@
|
|
|
61
61
|
}
|
|
62
62
|
|
|
63
63
|
.editor-panel .guidance-link svg {
|
|
64
|
-
width: 60px;
|
|
65
64
|
color: var(--blue);
|
|
66
|
-
margin-right: 1rem;
|
|
67
65
|
height: 60px;
|
|
66
|
+
margin-right: 1rem;
|
|
67
|
+
width: 60px;
|
|
68
68
|
}
|
|
69
69
|
|
|
70
70
|
.editor-panel .guidance-link svg path {
|
|
@@ -72,18 +72,18 @@
|
|
|
72
72
|
}
|
|
73
73
|
|
|
74
74
|
.editor-panel .warning {
|
|
75
|
-
color: #d8000c;
|
|
76
75
|
background-color: #ffd2d2;
|
|
77
|
-
padding: 0.75em 1em;
|
|
78
|
-
margin: 1em 0;
|
|
79
|
-
font-size: 0.8em;
|
|
80
76
|
border: #d8000c 1px solid;
|
|
81
77
|
border-radius: 0.4em;
|
|
78
|
+
color: #d8000c;
|
|
79
|
+
font-size: 0.8em;
|
|
80
|
+
margin: 1em 0;
|
|
81
|
+
padding: 0.75em 1em;
|
|
82
82
|
}
|
|
83
83
|
|
|
84
84
|
.editor-panel .warning strong {
|
|
85
|
-
font-weight: 600;
|
|
86
85
|
display: block;
|
|
86
|
+
font-weight: 600;
|
|
87
87
|
}
|
|
88
88
|
|
|
89
89
|
.editor-panel .advanced {
|
|
@@ -96,18 +96,18 @@
|
|
|
96
96
|
}
|
|
97
97
|
|
|
98
98
|
.editor-panel .advanced .advanced-toggle-link {
|
|
99
|
-
|
|
99
|
+
cursor: pointer;
|
|
100
100
|
display: block;
|
|
101
|
+
padding-top: 1em;
|
|
101
102
|
text-align: left;
|
|
102
|
-
cursor: pointer;
|
|
103
103
|
text-decoration: underline;
|
|
104
104
|
}
|
|
105
105
|
|
|
106
106
|
.editor-panel .advanced .advanced-toggle-link span {
|
|
107
|
-
text-decoration: none;
|
|
108
107
|
display: inline-block;
|
|
109
108
|
font-family: monospace;
|
|
110
109
|
padding-right: 5px;
|
|
110
|
+
text-decoration: none;
|
|
111
111
|
}
|
|
112
112
|
|
|
113
113
|
.editor-panel .advanced .advanced-toggle-link:hover {
|
|
@@ -115,29 +115,29 @@
|
|
|
115
115
|
}
|
|
116
116
|
|
|
117
117
|
.editor-panel .advanced textarea {
|
|
118
|
-
|
|
119
|
-
|
|
118
|
+
box-sizing: border-box;
|
|
119
|
+
font-family: monospace;
|
|
120
120
|
font-size: 0.9em;
|
|
121
|
+
height: 400px;
|
|
121
122
|
padding: 0.5em;
|
|
122
|
-
|
|
123
|
-
box-sizing: border-box;
|
|
123
|
+
width: 100%;
|
|
124
124
|
}
|
|
125
125
|
|
|
126
126
|
.editor-panel .heading-2 {
|
|
127
127
|
background: #565656;
|
|
128
|
+
border-bottom: #565656 3px solid;
|
|
128
129
|
color: #fff;
|
|
129
130
|
font-size: 1.1em;
|
|
130
131
|
padding: 0.6em 1em;
|
|
131
132
|
position: relative;
|
|
132
|
-
border-bottom: #565656 3px solid;
|
|
133
133
|
z-index: 3;
|
|
134
134
|
}
|
|
135
135
|
|
|
136
136
|
.editor-panel label {
|
|
137
|
-
text-transform: uppercase;
|
|
138
137
|
display: block;
|
|
139
138
|
font-size: 0.8em;
|
|
140
139
|
font-weight: 600;
|
|
140
|
+
text-transform: uppercase;
|
|
141
141
|
}
|
|
142
142
|
|
|
143
143
|
.editor-panel label:not(:first-child) {
|
|
@@ -145,8 +145,8 @@
|
|
|
145
145
|
}
|
|
146
146
|
|
|
147
147
|
.editor-panel label span.edit-label {
|
|
148
|
-
margin-bottom: 0.3em;
|
|
149
148
|
display: block;
|
|
149
|
+
margin-bottom: 0.3em;
|
|
150
150
|
}
|
|
151
151
|
|
|
152
152
|
.editor-panel label span.column-heading {
|
|
@@ -158,25 +158,25 @@
|
|
|
158
158
|
}
|
|
159
159
|
|
|
160
160
|
.editor-panel label.checkbox span {
|
|
161
|
-
text-transform: none;
|
|
162
161
|
font-size: 1em;
|
|
163
162
|
font-weight: 400;
|
|
163
|
+
text-transform: none;
|
|
164
164
|
}
|
|
165
165
|
|
|
166
166
|
.editor-panel label.checkbox input {
|
|
167
|
-
margin-top: 0;
|
|
168
167
|
margin-right: 0.5em;
|
|
168
|
+
margin-top: 0;
|
|
169
169
|
}
|
|
170
170
|
|
|
171
171
|
.editor-panel input[type='checkbox'],
|
|
172
172
|
.editor-panel input[type='radio'] {
|
|
173
|
+
cursor: pointer;
|
|
173
174
|
display: inline-block;
|
|
174
|
-
width: auto !important;
|
|
175
175
|
height: auto !important;
|
|
176
|
-
padding: 0;
|
|
177
176
|
margin-right: 0.5em;
|
|
178
|
-
|
|
177
|
+
padding: 0;
|
|
179
178
|
user-select: none;
|
|
179
|
+
width: auto !important;
|
|
180
180
|
}
|
|
181
181
|
|
|
182
182
|
.editor-panel input[type='text'],
|
|
@@ -193,8 +193,8 @@
|
|
|
193
193
|
|
|
194
194
|
.editor-panel .primary-fieldset {
|
|
195
195
|
border-top: rgba(0, 0, 0, 0.3) 2px solid;
|
|
196
|
-
padding-top: 2em;
|
|
197
196
|
margin-top: 2em;
|
|
197
|
+
padding-top: 2em;
|
|
198
198
|
}
|
|
199
199
|
|
|
200
200
|
.editor-panel ul.column-edit {
|
|
@@ -223,28 +223,28 @@
|
|
|
223
223
|
|
|
224
224
|
.editor-panel .edit-block {
|
|
225
225
|
border: 1px solid rgba(0, 0, 0, 0.3);
|
|
226
|
-
padding: 1em;
|
|
227
226
|
margin-top: 1em;
|
|
227
|
+
padding: 1em;
|
|
228
228
|
position: relative;
|
|
229
229
|
}
|
|
230
230
|
|
|
231
231
|
.editor-panel .edit-block .remove-column {
|
|
232
|
-
position: absolute;
|
|
233
|
-
top: 0;
|
|
234
|
-
right: 0;
|
|
235
|
-
border: 0;
|
|
236
232
|
background: rgba(0, 0, 0, 0.1);
|
|
233
|
+
border: 0;
|
|
237
234
|
color: #000;
|
|
235
|
+
cursor: pointer;
|
|
238
236
|
font-size: 0.8em;
|
|
239
237
|
padding: 0.3em;
|
|
240
|
-
|
|
238
|
+
position: absolute;
|
|
239
|
+
right: 0;
|
|
240
|
+
top: 0;
|
|
241
241
|
}
|
|
242
242
|
|
|
243
243
|
.editor-panel span.subtext {
|
|
244
|
-
text-transform: none;
|
|
245
244
|
display: block;
|
|
246
245
|
font-size: 0.8em;
|
|
247
246
|
font-weight: 400;
|
|
247
|
+
text-transform: none;
|
|
248
248
|
}
|
|
249
249
|
|
|
250
250
|
.editor-panel .sort-list {
|
|
@@ -252,12 +252,12 @@
|
|
|
252
252
|
}
|
|
253
253
|
|
|
254
254
|
.editor-panel .sort-list li {
|
|
255
|
-
border: 1px solid rgba(0, 0, 0, 0.2);
|
|
256
|
-
padding: 0.3em;
|
|
257
|
-
display: flex;
|
|
258
255
|
align-items: center;
|
|
256
|
+
border: 1px solid rgba(0, 0, 0, 0.2);
|
|
259
257
|
cursor: move;
|
|
258
|
+
display: flex;
|
|
260
259
|
margin-bottom: 0.3em;
|
|
260
|
+
padding: 0.3em;
|
|
261
261
|
}
|
|
262
262
|
|
|
263
263
|
.editor-panel .sort-list li svg {
|
|
@@ -265,8 +265,8 @@
|
|
|
265
265
|
}
|
|
266
266
|
|
|
267
267
|
.editor-panel .info {
|
|
268
|
-
margin-top: 1em;
|
|
269
268
|
font-size: 0.9em;
|
|
269
|
+
margin-top: 1em;
|
|
270
270
|
}
|
|
271
271
|
|
|
272
272
|
/* React Tags Component styles (third-party library) */
|
|
@@ -275,8 +275,8 @@
|
|
|
275
275
|
}
|
|
276
276
|
|
|
277
277
|
.editor-panel .react-tags {
|
|
278
|
-
position: relative;
|
|
279
278
|
cursor: text;
|
|
279
|
+
position: relative;
|
|
280
280
|
}
|
|
281
281
|
|
|
282
282
|
.editor-panel .react-tags input.react-tags__search-input {
|
|
@@ -296,20 +296,20 @@
|
|
|
296
296
|
}
|
|
297
297
|
|
|
298
298
|
.editor-panel .react-tags__selected-tag {
|
|
299
|
-
|
|
300
|
-
box-sizing: border-box;
|
|
299
|
+
background: #f1f1f1;
|
|
301
300
|
border: 1px solid #d1d1d1;
|
|
302
301
|
border-radius: 2px;
|
|
303
|
-
|
|
304
|
-
|
|
302
|
+
box-sizing: border-box;
|
|
303
|
+
display: inline-block;
|
|
305
304
|
font-size: 0.8em;
|
|
306
|
-
margin-right: 0.3em;
|
|
307
305
|
margin-bottom: 0.3em;
|
|
306
|
+
margin-right: 0.3em;
|
|
307
|
+
padding: 0.4em 0.6em;
|
|
308
308
|
}
|
|
309
309
|
|
|
310
310
|
.editor-panel .react-tags__selected-tag:after {
|
|
311
|
-
content: '\2715';
|
|
312
311
|
color: #aaa;
|
|
312
|
+
content: '\2715';
|
|
313
313
|
margin-left: 8px;
|
|
314
314
|
}
|
|
315
315
|
|
|
@@ -330,12 +330,12 @@
|
|
|
330
330
|
}
|
|
331
331
|
|
|
332
332
|
.editor-panel .react-tags__search input {
|
|
333
|
-
|
|
333
|
+
font-size: inherit;
|
|
334
|
+
line-height: inherit;
|
|
334
335
|
margin: 0;
|
|
336
|
+
max-width: 100%;
|
|
335
337
|
outline: none;
|
|
336
338
|
padding: 0.5em 0.3em;
|
|
337
|
-
font-size: inherit;
|
|
338
|
-
line-height: inherit;
|
|
339
339
|
}
|
|
340
340
|
|
|
341
341
|
.editor-panel .react-tags__search input::-ms-clear {
|
|
@@ -343,9 +343,9 @@
|
|
|
343
343
|
}
|
|
344
344
|
|
|
345
345
|
.editor-panel .react-tags__suggestions {
|
|
346
|
+
left: 0;
|
|
346
347
|
position: absolute;
|
|
347
348
|
top: 100%;
|
|
348
|
-
left: 0;
|
|
349
349
|
width: 100%;
|
|
350
350
|
}
|
|
351
351
|
|
|
@@ -356,13 +356,13 @@
|
|
|
356
356
|
}
|
|
357
357
|
|
|
358
358
|
.editor-panel .react-tags__suggestions ul {
|
|
359
|
-
margin: 4px -1px;
|
|
360
|
-
padding: 0;
|
|
361
|
-
list-style: none;
|
|
362
359
|
background: white;
|
|
363
360
|
border: 1px solid #d1d1d1;
|
|
364
361
|
border-radius: 2px;
|
|
365
362
|
box-shadow: 0 2px 6px rgba(0, 0, 0, 0.2);
|
|
363
|
+
list-style: none;
|
|
364
|
+
margin: 4px -1px;
|
|
365
|
+
padding: 0;
|
|
366
366
|
}
|
|
367
367
|
|
|
368
368
|
.editor-panel .react-tags__suggestions li {
|
|
@@ -371,14 +371,14 @@
|
|
|
371
371
|
}
|
|
372
372
|
|
|
373
373
|
.editor-panel .react-tags__suggestions li mark {
|
|
374
|
-
text-decoration: underline;
|
|
375
374
|
background: none;
|
|
376
375
|
font-weight: 600;
|
|
376
|
+
text-decoration: underline;
|
|
377
377
|
}
|
|
378
378
|
|
|
379
379
|
.editor-panel .react-tags__suggestions li:hover {
|
|
380
|
-
cursor: pointer;
|
|
381
380
|
background: #eee;
|
|
381
|
+
cursor: pointer;
|
|
382
382
|
}
|
|
383
383
|
|
|
384
384
|
.editor-panel .react-tags__suggestions li.is-active {
|
|
@@ -386,23 +386,23 @@
|
|
|
386
386
|
}
|
|
387
387
|
|
|
388
388
|
.editor-panel .react-tags__suggestions li.is-disabled {
|
|
389
|
-
opacity: 0.5;
|
|
390
389
|
cursor: auto;
|
|
390
|
+
opacity: 0.5;
|
|
391
391
|
}
|
|
392
392
|
|
|
393
393
|
.editor-toggle {
|
|
394
|
-
position: fixed;
|
|
395
|
-
top: 1em;
|
|
396
|
-
right: 1em;
|
|
397
394
|
background: var(--blue);
|
|
398
|
-
color: white;
|
|
399
395
|
border: 0;
|
|
400
396
|
border-radius: 0.5em;
|
|
401
|
-
|
|
402
|
-
font-size: 1em;
|
|
397
|
+
color: white;
|
|
403
398
|
cursor: pointer;
|
|
404
|
-
z-index: 9999999999;
|
|
405
399
|
display: none;
|
|
400
|
+
font-size: 1em;
|
|
401
|
+
padding: 0.5em 1em;
|
|
402
|
+
position: fixed;
|
|
403
|
+
right: 1em;
|
|
404
|
+
top: 1em;
|
|
405
|
+
z-index: 9999999999;
|
|
406
406
|
}
|
|
407
407
|
|
|
408
408
|
.editor-toggle.active {
|
|
@@ -429,8 +429,8 @@
|
|
|
429
429
|
}
|
|
430
430
|
|
|
431
431
|
:is(span).edit-label {
|
|
432
|
-
margin-bottom: 0.3em;
|
|
433
432
|
display: block;
|
|
433
|
+
margin-bottom: 0.3em;
|
|
434
434
|
}
|
|
435
435
|
|
|
436
436
|
.react-tooltip {
|