@cdc/map 4.26.2 → 4.26.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 (118) hide show
  1. package/CONFIG.md +235 -0
  2. package/README.md +70 -24
  3. package/dist/cdcmap-CY9IcPSi.es.js +6 -0
  4. package/dist/cdcmap-DlpiY3fQ.es.js +4 -0
  5. package/dist/cdcmap.js +31260 -27946
  6. package/examples/{testing-layer-2.json → __data__/testing-layer-2.json} +1 -1
  7. package/examples/{testing-layer.json → __data__/testing-layer.json} +1 -1
  8. package/examples/county-hsa-toggle.json +51993 -0
  9. package/examples/custom-map-layers.json +2 -2
  10. package/examples/default-county.json +3 -3
  11. package/examples/minimal-example.json +69 -0
  12. package/examples/private/annotation-bug.json +642 -0
  13. package/examples/private/css-issue.json +314 -0
  14. package/examples/private/region-breaking.json +1639 -0
  15. package/examples/private/test1.json +27247 -0
  16. package/package.json +4 -4
  17. package/src/CdcMap.tsx +3 -14
  18. package/src/CdcMapComponent.tsx +302 -164
  19. package/src/_stories/CdcMap.Defaults.smoke.stories.tsx +76 -0
  20. package/src/_stories/CdcMap.Editor.ColumnsSectionTests.stories.tsx +601 -0
  21. package/src/_stories/CdcMap.Editor.DataTableSectionTests.stories.tsx +404 -0
  22. package/src/_stories/CdcMap.Editor.FiltersSectionTests.stories.tsx +229 -0
  23. package/src/_stories/CdcMap.Editor.GeneralSectionTests.stories.tsx +262 -0
  24. package/src/_stories/CdcMap.Editor.LegendSectionTests.stories.tsx +541 -0
  25. package/src/_stories/CdcMap.Editor.MultiCountryWorldMapTests.stories.tsx +359 -0
  26. package/src/_stories/CdcMap.Editor.PatternSettingsSectionTests.stories.tsx +516 -0
  27. package/src/_stories/CdcMap.Editor.SmallMultiplesSectionTests.stories.tsx +165 -0
  28. package/src/_stories/CdcMap.Editor.TextAnnotationsSectionTests.stories.tsx +145 -0
  29. package/src/_stories/CdcMap.Editor.TypeSectionTests.stories.tsx +312 -0
  30. package/src/_stories/CdcMap.Editor.VisualSectionTests.stories.tsx +359 -0
  31. package/src/_stories/CdcMap.Editor.ZoomControlsTests.stories.tsx +88 -0
  32. package/src/_stories/{CdcMap.stories.tsx → CdcMap.smoke.stories.tsx} +23 -1
  33. package/src/_stories/Map.HTMLInDataTable.stories.tsx +385 -0
  34. package/src/_stories/_mock/legends/legend-tests.json +3 -3
  35. package/src/_stories/_mock/multi-state-show-unselected.json +82 -0
  36. package/src/cdcMapComponent.styles.css +2 -2
  37. package/src/components/Annotation/Annotation.Draggable.styles.css +4 -4
  38. package/src/components/Annotation/AnnotationDropdown.styles.css +1 -1
  39. package/src/components/Annotation/AnnotationList.styles.css +13 -13
  40. package/src/components/Annotation/AnnotationList.tsx +1 -1
  41. package/src/components/EditorPanel/components/EditorPanel.tsx +905 -416
  42. package/src/components/EditorPanel/components/HexShapeSettings.tsx +1 -1
  43. package/src/components/EditorPanel/components/Panels/Panel.Annotate.tsx +112 -117
  44. package/src/components/EditorPanel/components/Panels/Panel.PatternSettings-style.css +1 -1
  45. package/src/components/EditorPanel/components/Panels/Panel.PatternSettings.tsx +31 -15
  46. package/src/components/EditorPanel/components/editorPanel.styles.css +55 -25
  47. package/src/components/Legend/components/Legend.tsx +12 -7
  48. package/src/components/Legend/components/LegendGroup/legend.group.css +5 -5
  49. package/src/components/Legend/components/LegendItem.Hex.tsx +4 -2
  50. package/src/components/Legend/components/index.scss +2 -3
  51. package/src/components/NavigationMenu.tsx +2 -1
  52. package/src/components/SmallMultiples/SmallMultiples.css +5 -5
  53. package/src/components/SmallMultiples/SynchronizedTooltip.tsx +1 -1
  54. package/src/components/UsaMap/components/SingleState/SingleState.StateOutput.tsx +32 -17
  55. package/src/components/UsaMap/components/TerritoriesSection.tsx +3 -2
  56. package/src/components/UsaMap/components/Territory/Territory.Rectangle.tsx +13 -8
  57. package/src/components/UsaMap/components/UsaMap.County.tsx +629 -231
  58. package/src/components/UsaMap/components/UsaMap.Region.styles.css +1 -1
  59. package/src/components/UsaMap/components/UsaMap.SingleState.styles.css +2 -2
  60. package/src/components/UsaMap/components/UsaMap.State.tsx +14 -9
  61. package/src/components/UsaMap/data/cb_2019_us_county_20m.json +75817 -1
  62. package/src/components/UsaMap/data/hsa_fips_mapping.json +3144 -0
  63. package/src/components/WorldMap/WorldMap.tsx +10 -13
  64. package/src/components/WorldMap/data/world-topo-updated.json +1 -0
  65. package/src/components/WorldMap/data/world-topo.json +1 -1
  66. package/src/components/WorldMap/worldMap.styles.css +1 -1
  67. package/src/components/ZoomControls.tsx +49 -18
  68. package/src/components/zoomControls.styles.css +27 -11
  69. package/src/data/initial-state.js +15 -5
  70. package/src/data/legacy-defaults.ts +8 -0
  71. package/src/data/supported-counties.json +1 -1
  72. package/src/data/supported-geos.js +19 -0
  73. package/src/helpers/colors.ts +2 -1
  74. package/src/helpers/countyTerritories.ts +38 -0
  75. package/src/helpers/dataTableHelpers.ts +85 -0
  76. package/src/helpers/displayGeoName.ts +19 -11
  77. package/src/helpers/getMapContainerClasses.ts +8 -2
  78. package/src/helpers/getMatchingPatternForRow.ts +67 -0
  79. package/src/helpers/getPatternForRow.ts +11 -18
  80. package/src/helpers/tests/countyTerritories.test.ts +87 -0
  81. package/src/helpers/tests/dataTableHelpers.test.ts +78 -0
  82. package/src/helpers/tests/displayGeoName.test.ts +17 -0
  83. package/src/helpers/tests/getMatchingPatternForRow.test.ts +150 -0
  84. package/src/helpers/tests/getPatternForRow.test.ts +140 -2
  85. package/src/helpers/urlDataHelpers.ts +7 -1
  86. package/src/hooks/useApplyTooltipsToGeo.tsx +7 -4
  87. package/src/hooks/useMapLayers.tsx +1 -1
  88. package/src/hooks/useResizeObserver.ts +36 -22
  89. package/src/hooks/useTooltip.test.tsx +64 -0
  90. package/src/hooks/useTooltip.ts +46 -15
  91. package/src/scss/editor-panel.scss +1 -1
  92. package/src/scss/main.scss +140 -6
  93. package/src/scss/map.scss +9 -4
  94. package/src/store/map.actions.ts +5 -0
  95. package/src/store/map.reducer.ts +13 -0
  96. package/src/test/CdcMap.test.jsx +26 -2
  97. package/src/types/MapConfig.ts +28 -4
  98. package/src/types/MapContext.ts +5 -1
  99. package/topojson-updater/README.txt +1 -1
  100. package/dist/cdcmap-Cf9_fbQf.es.js +0 -6
  101. package/examples/__data__/city-state-data.json +0 -668
  102. package/examples/city-state.json +0 -434
  103. package/examples/default-world-data.json +0 -1450
  104. package/examples/new-cities.json +0 -656
  105. package/src/_stories/CdcMap.Editor.stories.tsx +0 -3475
  106. package/src/helpers/componentHelpers.ts +0 -8
  107. package/topojson-updater/package-lock.json +0 -223
  108. /package/src/_stories/{CdcMap.ColumnWrap.stories.tsx → CdcMap.ColumnWrap.smoke.stories.tsx} +0 -0
  109. /package/src/_stories/{CdcMap.DistrictOfColumbia.stories.tsx → CdcMap.DistrictOfColumbia.smoke.stories.tsx} +0 -0
  110. /package/src/_stories/{CdcMap.Filters.stories.tsx → CdcMap.Filters.smoke.stories.tsx} +0 -0
  111. /package/src/_stories/{CdcMap.Legend.Gradient.stories.tsx → CdcMap.Legend.Gradient.smoke.stories.tsx} +0 -0
  112. /package/src/_stories/{CdcMap.Legend.stories.tsx → CdcMap.Legend.smoke.stories.tsx} +0 -0
  113. /package/src/_stories/{CdcMap.Patterns.stories.tsx → CdcMap.Patterns.smoke.stories.tsx} +0 -0
  114. /package/src/_stories/{CdcMap.SmallMultiples.stories.tsx → CdcMap.SmallMultiples.smoke.stories.tsx} +0 -0
  115. /package/src/_stories/{CdcMap.Table.stories.tsx → CdcMap.Table.smoke.stories.tsx} +0 -0
  116. /package/src/_stories/{CdcMap.ZeroColor.stories.tsx → CdcMap.ZeroColor.smoke.stories.tsx} +0 -0
  117. /package/src/_stories/{GoogleMap.stories.tsx → GoogleMap.smoke.stories.tsx} +0 -0
  118. /package/src/_stories/{UsaMap.NoData.stories.tsx → UsaMap.NoData.smoke.stories.tsx} +0 -0
@@ -239,7 +239,7 @@ const HexSettingShapeColumns = props => {
239
239
  <button
240
240
  className='cove-button cove-button--warn'
241
241
  style={{ background: 'none', border: '1px solid red', color: 'red', marginTop: '15px' }}
242
- onClick={(e, itemIndex) => {
242
+ onClick={() => {
243
243
  let newGroups = [
244
244
  ...config.hexMap.shapeGroups.slice(0, shapeGroupIndex),
245
245
  ...config.hexMap.shapeGroups.slice(shapeGroupIndex + 1)
@@ -1,18 +1,26 @@
1
1
  import React, { useContext } from 'react'
2
+ import cloneDeep from 'lodash/cloneDeep'
2
3
 
3
4
  // CDC Core
4
5
  import { approvedCurveTypes } from '@cdc/core/helpers/lineChartHelpers'
5
6
  import Accordion from '@cdc/core/components/ui/Accordion'
6
7
  import Button from '@cdc/core/components/elements/Button'
8
+ import GroupedList from '@cdc/core/components/EditorPanel/GroupedList'
7
9
  import { MapContext } from '../../../../types/MapContext'
8
10
  import ConfigContext from '../../../../context'
9
- import { Select } from '@cdc/core/components/EditorPanel/Inputs'
10
- import { setConfig } from 'dompurify'
11
+ import { CheckBox, Select } from '@cdc/core/components/EditorPanel/Inputs'
12
+ import {
13
+ Accordion as AccessibleAccordion,
14
+ AccordionItem,
15
+ AccordionItemButton,
16
+ AccordionItemHeading,
17
+ AccordionItemPanel
18
+ } from 'react-accessible-accordion'
11
19
  // types
12
20
  // styles
13
21
 
14
22
  const PanelAnnotate: React.FC = props => {
15
- const { config, setConfig, dimensions, isDraggingAnnotation } = useContext<MapContext>(ConfigContext)
23
+ const { config, setConfig, dimensions } = useContext<MapContext>(ConfigContext)
16
24
 
17
25
  /**
18
26
  * Get the current SVG/canvas dimensions for saving with annotations.
@@ -99,48 +107,68 @@ const PanelAnnotate: React.FC = props => {
99
107
  return (
100
108
  <Accordion>
101
109
  <Accordion.Section title={props.name}>
102
- <label>
103
- Show Annotation Dropdown
104
- <input
105
- type='checkbox'
106
- checked={config?.general?.showAnnotationDropdown}
107
- onClick={e => {
108
- setConfig({
109
- ...config,
110
- general: {
111
- ...config.general,
112
- showAnnotationDropdown: e.target.checked
113
- }
114
- })
115
- }}
116
- />
117
- </label>
110
+ <CheckBox
111
+ value={config?.general?.showAnnotationDropdown || false}
112
+ section='general'
113
+ subsection={null}
114
+ fieldName='showAnnotationDropdown'
115
+ label='Show Annotation Dropdown'
116
+ updateField={(_section, _subsection, _fieldName, value) => {
117
+ setConfig({
118
+ ...config,
119
+ general: {
120
+ ...config.general,
121
+ showAnnotationDropdown: value
122
+ }
123
+ })
124
+ }}
125
+ />
118
126
 
119
- <label>
120
- Annotation Dropdown Title:
121
- <input
122
- type='text'
123
- style={{ marginBottom: '10px' }}
124
- value={config?.general?.annotationDropdownText}
125
- onChange={e => {
126
- setConfig({
127
- ...config,
128
- general: {
129
- ...config.general,
130
- annotationDropdownText: e.target.value
131
- }
132
- })
133
- }}
134
- />
135
- </label>
127
+ {config.general.showAnnotationDropdown && (
128
+ <label>
129
+ Annotation Dropdown Title:
130
+ <input
131
+ type='text'
132
+ style={{ marginBottom: '10px' }}
133
+ value={config?.general?.annotationDropdownText}
134
+ onChange={e => {
135
+ setConfig({
136
+ ...config,
137
+ general: {
138
+ ...config.general,
139
+ annotationDropdownText: e.target.value
140
+ }
141
+ })
142
+ }}
143
+ />
144
+ </label>
145
+ )}
136
146
 
137
- {config?.annotations &&
138
- config?.annotations.map((annotation, index) => (
139
- <Accordion>
140
- <Accordion.Section
141
- title={annotation.text ? annotation.text.substring(0, 15) + '...' : `Annotation ${index + 1}`}
142
- >
143
- <div className='annotation-group'>
147
+ <GroupedList
148
+ items={config?.annotations}
149
+ label='Text Annotations'
150
+ droppableId='map-annotations-order'
151
+ draggable={false}
152
+ renderItem={(annotation, index) => (
153
+ <AccessibleAccordion key={`annotation-${index}`} allowZeroExpanded>
154
+ <AccordionItem className='series-item series-item--chart'>
155
+ <AccordionItemHeading className='series-item__title'>
156
+ <AccordionItemButton className='accordion__button'>
157
+ {annotation.text ? annotation.text.substring(0, 15) + '...' : `Annotation ${index + 1}`}
158
+ </AccordionItemButton>
159
+ </AccordionItemHeading>
160
+ <AccordionItemPanel>
161
+ <div className='series-item__panel-actions'>
162
+ <Button
163
+ type='button'
164
+ variant='danger'
165
+ size='sm'
166
+ className='grouped-list__remove'
167
+ onClick={() => handleRemoveAnnotation(index)}
168
+ >
169
+ Delete Annotation
170
+ </Button>
171
+ </div>
144
172
  <label>
145
173
  Annotation Text:
146
174
  <textarea
@@ -149,36 +177,6 @@ const PanelAnnotate: React.FC = props => {
149
177
  onChange={e => handleAnnotationUpdate(e.target.value, 'text', index)}
150
178
  />
151
179
  </label>
152
- {/* <label>
153
- Vertical Anchor
154
- <input
155
- type='checkbox'
156
- checked={config?.annotations[index].anchor.vertical}
157
- onClick={e => {
158
- const updatedAnnotations = [...config?.annotations]
159
- updatedAnnotations[index].anchor.vertical = e.target.checked
160
- updateConfig({
161
- ...config,
162
- annotations: updatedAnnotations
163
- })
164
- }}
165
- />
166
- </label>
167
- <label>
168
- Horizontal Anchor
169
- <input
170
- type='checkbox'
171
- checked={config?.annotations[index].anchor.horizontal}
172
- onClick={e => {
173
- const updatedAnnotations = [...config?.annotations]
174
- updatedAnnotations[index].anchor.horizontal = e.target.checked
175
- updateConfig({
176
- ...config,
177
- annotations: updatedAnnotations
178
- })
179
- }}
180
- />
181
- </label> */}
182
180
 
183
181
  <label>
184
182
  Opacity
@@ -186,7 +184,7 @@ const PanelAnnotate: React.FC = props => {
186
184
  <input
187
185
  type='range'
188
186
  onChange={e => {
189
- const updatedAnnotations = [...config?.annotations]
187
+ const updatedAnnotations = cloneDeep(config?.annotations)
190
188
  updatedAnnotations[index].opacity = e.target.value
191
189
  setConfig({
192
190
  ...config,
@@ -197,36 +195,36 @@ const PanelAnnotate: React.FC = props => {
197
195
  />
198
196
  </label>
199
197
 
200
- <label>
201
- Edit Subject
202
- <input
203
- type='checkbox'
204
- checked={config?.annotations[index]?.edit?.subject}
205
- onClick={e => {
206
- const updatedAnnotations = [...config?.annotations]
207
- updatedAnnotations[index].edit.subject = e.target.checked
208
- setConfig({
209
- ...config,
210
- annotations: updatedAnnotations
211
- })
212
- }}
213
- />
214
- </label>
215
- <label>
216
- Edit Label
217
- <input
218
- type='checkbox'
219
- checked={config?.annotations[index]?.edit?.label}
220
- onClick={e => {
221
- const updatedAnnotations = [...config?.annotations]
222
- updatedAnnotations[index].edit.label = e.target.checked
223
- setConfig({
224
- ...config,
225
- annotations: updatedAnnotations
226
- })
227
- }}
228
- />
229
- </label>
198
+ <CheckBox
199
+ value={config?.annotations[index]?.edit?.subject || false}
200
+ section='annotations'
201
+ subsection={null}
202
+ fieldName={`${index}.edit.subject`}
203
+ label='Edit Subject'
204
+ updateField={(_section, _subsection, _fieldName, value) => {
205
+ const updatedAnnotations = cloneDeep(config?.annotations)
206
+ updatedAnnotations[index].edit.subject = value
207
+ setConfig({
208
+ ...config,
209
+ annotations: updatedAnnotations
210
+ })
211
+ }}
212
+ />
213
+ <CheckBox
214
+ value={config?.annotations[index]?.edit?.label || false}
215
+ section='annotations'
216
+ subsection={null}
217
+ fieldName={`${index}.edit.label`}
218
+ label='Edit Label'
219
+ updateField={(_section, _subsection, _fieldName, value) => {
220
+ const updatedAnnotations = cloneDeep(config?.annotations)
221
+ updatedAnnotations[index].edit.label = value
222
+ setConfig({
223
+ ...config,
224
+ annotations: updatedAnnotations
225
+ })
226
+ }}
227
+ />
230
228
 
231
229
  <Select
232
230
  label='Connection Type'
@@ -236,7 +234,7 @@ const PanelAnnotate: React.FC = props => {
236
234
  label: side
237
235
  }))}
238
236
  onChange={event => {
239
- const updatedAnnotations = [...config?.annotations]
237
+ const updatedAnnotations = cloneDeep(config?.annotations)
240
238
  updatedAnnotations[index].connectionType = event.target.value
241
239
  setConfig({
242
240
  ...config,
@@ -254,7 +252,7 @@ const PanelAnnotate: React.FC = props => {
254
252
  label: value
255
253
  }))}
256
254
  onChange={event => {
257
- const updatedAnnotations = [...config?.annotations]
255
+ const updatedAnnotations = cloneDeep(config?.annotations)
258
256
  updatedAnnotations[index].lineType = event.target.value
259
257
  setConfig({
260
258
  ...config,
@@ -272,7 +270,7 @@ const PanelAnnotate: React.FC = props => {
272
270
  label: option
273
271
  }))}
274
272
  onChange={event => {
275
- const updatedAnnotations = [...config?.annotations]
273
+ const updatedAnnotations = cloneDeep(config?.annotations)
276
274
  updatedAnnotations[index].marker = event.target.value
277
275
  setConfig({
278
276
  ...config,
@@ -280,18 +278,15 @@ const PanelAnnotate: React.FC = props => {
280
278
  })
281
279
  }}
282
280
  />
283
-
284
- <Button className='btn btn-danger' onClick={() => handleRemoveAnnotation(index)}>
285
- Delete Annotation
286
- </Button>
287
- </div>
288
- </Accordion.Section>
289
- </Accordion>
290
- ))}
281
+ </AccordionItemPanel>
282
+ </AccordionItem>
283
+ </AccessibleAccordion>
284
+ )}
285
+ />
291
286
  {config?.annotations?.length < 3 && (
292
- <button className='btn btn-primary full-width' onClick={handleAddAnnotation}>
287
+ <Button variant='editor-primary' onClick={handleAddAnnotation}>
293
288
  Add Annotation
294
- </button>
289
+ </Button>
295
290
  )}
296
291
  </Accordion.Section>
297
292
  </Accordion>
@@ -1,4 +1,4 @@
1
- .cdc-open-viz-module {
1
+ .cove-visualization {
2
2
  .pattern-input__color {
3
3
  margin-top: 1rem;
4
4
  }
@@ -10,12 +10,13 @@ import ConfigContext from '../../../../context'
10
10
  import { useLegendMemoContext } from '../../../../context/LegendMemoContext'
11
11
  import { type MapContext } from '../../../../types/MapContext'
12
12
  import Button from '@cdc/core/components/elements/Button'
13
+ import GroupedList from '@cdc/core/components/EditorPanel/GroupedList'
13
14
  import Tooltip from '@cdc/core/components/ui/Tooltip'
14
15
  import Icon from '@cdc/core/components/ui/Icon'
15
16
  import { Select } from '@cdc/core/components/EditorPanel/Inputs'
16
17
  import './Panel.PatternSettings-style.css'
17
18
  import Alert from '@cdc/core/components/Alert'
18
- import _ from 'lodash'
19
+ import cloneDeep from 'lodash/cloneDeep'
19
20
  import { cloneConfig } from '@cdc/core/helpers/cloneConfig'
20
21
 
21
22
  // topojson helpers for checking color contrasts
@@ -65,7 +66,7 @@ const PatternSettings = ({ name }: PanelProps) => {
65
66
 
66
67
  /** Updates the map config with a new pattern item */
67
68
  const handleAddGeoPattern = () => {
68
- const patterns = _.cloneDeep(config.map.patterns)
69
+ const patterns = cloneDeep(config.map.patterns)
69
70
  patterns.push({ dataKey: '', pattern: defaultPattern, contrastCheck: true })
70
71
  setConfig({
71
72
  ...config,
@@ -178,9 +179,12 @@ const PatternSettings = ({ name }: PanelProps) => {
178
179
  />
179
180
  )}
180
181
  <br />
181
-
182
- {patterns &&
183
- patterns.map((pattern, patternIndex) => {
182
+ <GroupedList
183
+ items={patterns}
184
+ label='Geo Patterns'
185
+ droppableId='map-geo-patterns'
186
+ draggable={false}
187
+ renderItem={(pattern, patternIndex) => {
184
188
  const dataValueOptions = [...new Set(data?.map(d => d?.[pattern?.dataKey]))]
185
189
  const dataKeyOptions = Object.keys(data[0])
186
190
  dataValueOptions.unshift('Select')
@@ -191,14 +195,25 @@ const PatternSettings = ({ name }: PanelProps) => {
191
195
 
192
196
  return (
193
197
  <Accordion allowZeroExpanded key={`accordion-pattern--${patternIndex}`}>
194
- <AccordionItem>
195
- <AccordionItemHeading>
196
- <AccordionItemButton>
198
+ <AccordionItem className='series-item series-item--chart'>
199
+ <AccordionItemHeading className='series-item__title'>
200
+ <AccordionItemButton className='accordion__button'>
197
201
  {pattern.dataKey ? `${pattern.dataKey}: ${pattern.dataValue ?? 'No Value'}` : 'Select Column'}
198
202
  </AccordionItemButton>
199
203
  </AccordionItemHeading>
200
204
  <AccordionItemPanel>
201
205
  <>
206
+ <div className='series-item__panel-actions'>
207
+ <Button
208
+ type='button'
209
+ variant='danger'
210
+ size='sm'
211
+ className='grouped-list__remove'
212
+ onClick={() => handleRemovePattern(patternIndex)}
213
+ >
214
+ Remove Pattern
215
+ </Button>
216
+ </div>
202
217
  {pattern.contrastCheck ?? true ? (
203
218
  <Alert type='success' message='This pattern passes contrast checks' />
204
219
  ) : (
@@ -217,6 +232,9 @@ const PatternSettings = ({ name }: PanelProps) => {
217
232
  handlePatternFieldUpdate('dataKey', value, patternIndex)
218
233
  }
219
234
  />
235
+ <p className='edit-label mb-2'>
236
+ Leave Data Key as &quot;Select&quot; to match this value across all columns.
237
+ </p>
220
238
  <label htmlFor={`pattern-dataValue--${patternIndex}`}>
221
239
  Data Value:
222
240
  <input
@@ -231,7 +249,7 @@ const PatternSettings = ({ name }: PanelProps) => {
231
249
  <input
232
250
  type='text'
233
251
  onChange={e => handlePatternFieldUpdate('label', e.target.value, patternIndex)}
234
- id={`pattern-dataValue--${patternIndex}`}
252
+ id={`pattern-label--${patternIndex}`}
235
253
  value={pattern.label === '' ? '' : pattern.label}
236
254
  />
237
255
  </label>
@@ -276,18 +294,16 @@ const PatternSettings = ({ name }: PanelProps) => {
276
294
  />
277
295
  </label>
278
296
  </div>
279
- <Button onClick={e => handleRemovePattern(patternIndex)} className='btn btn-danger'>
280
- Remove Pattern
281
- </Button>
282
297
  </>
283
298
  </AccordionItemPanel>
284
299
  </AccordionItem>
285
300
  </Accordion>
286
301
  )
287
- })}
288
- <button className='btn btn-primary full-width mt-2' onClick={handleAddGeoPattern}>
302
+ }}
303
+ />
304
+ <Button variant='editor-primary' onClick={handleAddGeoPattern}>
289
305
  Add Geo Pattern
290
- </button>
306
+ </Button>
291
307
  </AccordionItemPanel>
292
308
  </AccordionItem>
293
309
  )
@@ -1,60 +1,72 @@
1
1
  .geo-buttons {
2
- list-style: none;
3
2
  color: var(--mediumGray);
4
3
  display: grid;
5
- button { width: 100% !important; }
4
+ list-style: none;
5
+
6
+ button {
7
+ width: 100% !important;
8
+ }
9
+
6
10
  svg {
11
+ box-sizing: border-box;
7
12
  display: block;
8
- max-width: 80px;
9
- max-height: 40px;
10
13
  margin: 0.5em auto;
11
- box-sizing: border-box;
14
+ max-height: 40px;
15
+ max-width: 80px;
16
+
12
17
  path {
13
18
  fill: currentColor;
14
19
  }
15
20
  }
21
+
16
22
  button {
23
+ align-items: center;
17
24
  background: transparent;
18
- padding: 0.3em 0.75em;
19
- display: flex;
20
25
  border: var(--lightGray) 1px solid;
21
- width: 40%;
22
- align-items: center;
23
- margin-right: 1em;
24
26
  cursor: pointer;
25
- overflow: hidden;
27
+ display: flex;
26
28
  flex-direction: column;
29
+ margin-right: 1em;
30
+ overflow: hidden;
31
+ padding: 0.3em 0.75em;
27
32
  transition: 0.2s all;
33
+ width: 40%;
34
+
28
35
  svg {
29
36
  display: block;
30
37
  height: 25px;
31
38
  margin: 0.5em auto;
32
39
  max-width: 100%;
33
40
  }
41
+
34
42
  span {
35
- text-transform: none;
36
43
  font-size: 1em;
44
+ text-transform: none;
37
45
  }
46
+
38
47
  &:hover {
39
48
  background: #f2f2f2;
40
49
  transition: 0.2s all;
41
50
  }
51
+
42
52
  &.active {
43
53
  background: #fff;
44
54
  border-color: #005eaa;
45
55
  color: #005eaa;
46
56
  position: relative;
57
+
47
58
  path {
48
59
  fill: #005eaa;
49
60
  }
61
+
50
62
  &:before {
51
- content: ' ';
52
- width: 5px;
53
63
  background: #005eaa;
54
- left: 0;
55
- top: 0;
56
64
  bottom: 0;
65
+ content: ' ';
66
+ left: 0;
57
67
  position: absolute;
68
+ top: 0;
69
+ width: 5px;
58
70
  }
59
71
  }
60
72
  }
@@ -62,34 +74,52 @@
62
74
 
63
75
  .editor-toggle {
64
76
  background: #f2f2f2;
77
+ border: 0;
65
78
  border-radius: 60px;
79
+ box-shadow: rgba(0, 0, 0, 0.5) 0 1px 2px;
66
80
  color: #000;
81
+ cursor: pointer;
67
82
  font-size: 1em;
68
- border: 0;
83
+ height: 25px;
84
+ left: 307px;
69
85
  position: fixed;
70
- z-index: 100;
71
86
  transition: 0.1s background;
72
- cursor: pointer;
73
87
  width: 25px;
74
- height: 25px;
75
- left: 307px;
76
- box-shadow: rgba(0, 0, 0, 0.5) 0 1px 2px;
88
+ z-index: 100;
89
+
77
90
  &:before {
78
- top: 43%;
91
+ content: '\00ab';
79
92
  left: 50%;
80
- transform: translate(-50%, -50%);
81
93
  position: absolute;
82
- content: '\00ab';
94
+ top: 43%;
95
+ transform: translate(-50%, -50%);
83
96
  }
97
+
84
98
  &.collapsed {
85
99
  left: 1em;
86
100
  margin-left: 0;
101
+
87
102
  &:before {
88
103
  content: '\00bb';
89
104
  }
90
105
  }
106
+
91
107
  &:hover {
92
108
  background: rgba(255, 255, 255, 1);
93
109
  }
94
110
  }
95
111
 
112
+ .editor-panel-action-button {
113
+ margin-top: 1rem;
114
+ }
115
+
116
+ .column-section__header {
117
+ align-items: center;
118
+ display: flex;
119
+ gap: 0.5rem;
120
+ margin-bottom: 1rem;
121
+ }
122
+
123
+ .column-section__title {
124
+ font-weight: 600;
125
+ }
@@ -56,7 +56,8 @@ const Legend = forwardRef<HTMLDivElement, LegendProps>((props, ref) => {
56
56
  const isLegendGradient = legend.style === 'gradient'
57
57
  const boxDynamicallyHidden = isBelowBreakpoint('md', viewport)
58
58
  const legendWrapping =
59
- (legend.position === 'left' || legend.position === 'right') && isBelowBreakpoint('md', viewport)
59
+ (legend.position === 'left' || legend.position === 'right') &&
60
+ (viewport === 'md' || isBelowBreakpoint('md', viewport))
60
61
  const legendOnBottom = legend.position === 'bottom' || legendWrapping
61
62
  const needsTopMargin = legend.hideBorder && legendOnBottom
62
63
 
@@ -144,7 +145,7 @@ const Legend = forwardRef<HTMLDivElement, LegendProps>((props, ref) => {
144
145
  }}
145
146
  >
146
147
  <LegendShape shape={config.legend.style === 'boxes' ? 'square' : 'circle'} fill={item.color} />
147
- <span>{item.label}</span>
148
+ <span className='cove-prose'>{item.label}</span>
148
149
  </button>
149
150
  </li>
150
151
  )
@@ -274,7 +275,7 @@ const Legend = forwardRef<HTMLDivElement, LegendProps>((props, ref) => {
274
275
 
275
276
  return (
276
277
  <ErrorBoundary component='Sidebar'>
277
- <div className={`legends ${needsTopMargin ? 'mt-4' : ''}`}>
278
+ <div className={`legends ${needsTopMargin ? 'mt-4' : ''} ${legendWrapping ? 'legend-wrapped-bottom' : ''}`}>
278
279
  <aside
279
280
  id={skipId || 'legend'}
280
281
  className={legendClasses.aside.join(' ') || ''}
@@ -287,24 +288,28 @@ const Legend = forwardRef<HTMLDivElement, LegendProps>((props, ref) => {
287
288
  {(legend.title || legend.description || legend.dynamicDescription) && (
288
289
  <div className='mb-3'>
289
290
  {legend.title && (
290
- <h3 className={legendClasses.title.join(' ') || ''}>
291
+ <h3 className={`${legendClasses.title.join(' ') || ''} cove-prose`.trim()}>
291
292
  {parse(
292
293
  config.enableMarkupVariables && config.markupVariables?.length > 0
293
294
  ? processMarkupVariables(legend.title, config.data || [], config.markupVariables, {
294
295
  isEditor: false,
295
- filters: config.filters || []
296
+ filters: config.filters || [],
297
+ locale: config.locale,
298
+ dataMetadata: config.dataMetadata
296
299
  }).processedContent
297
300
  : legend.title
298
301
  )}
299
302
  </h3>
300
303
  )}
301
304
  {legend.dynamicDescription === false && legend.description && (
302
- <p className={legendClasses.description.join(' ') || ''}>
305
+ <p className={`${legendClasses.description.join(' ') || ''} cove-prose`.trim()}>
303
306
  {parse(
304
307
  config.enableMarkupVariables && config.markupVariables?.length > 0
305
308
  ? processMarkupVariables(legend.description, config.data || [], config.markupVariables, {
306
309
  isEditor: false,
307
- filters: config.filters || []
310
+ filters: config.filters || [],
311
+ locale: config.locale,
312
+ dataMetadata: config.dataMetadata
308
313
  }).processedContent
309
314
  : legend.description
310
315
  )}
@@ -1,15 +1,15 @@
1
1
  .group-label {
2
- font-weight: 500;
3
2
  font-family: Nunito, sans-serif;
4
3
  font-size: 1rem;
4
+ font-weight: 500;
5
5
  margin-bottom: 0.5rem;
6
6
  }
7
7
  .group-list-item {
8
- list-style: none;
9
- font-weight: 400;
8
+ cursor: pointer;
10
9
  font-size: 0.889rem;
10
+ font-weight: 400;
11
+ list-style: none;
11
12
  margin-top: 0.5rem !important;
12
- cursor: pointer;
13
13
  }
14
14
 
15
15
  .group-container {
@@ -21,7 +21,7 @@
21
21
  }
22
22
 
23
23
  .legend-group-item-not-disable {
24
+ border-radius: 1px;
24
25
  outline: 1px solid #005ea2;
25
26
  outline-offset: 5px;
26
- border-radius: 1px;
27
27
  }