@cdc/core 4.24.12 → 4.25.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (68) hide show
  1. package/components/DataTable/DataTable.tsx +26 -36
  2. package/components/DataTable/DataTableStandAlone.tsx +3 -3
  3. package/components/DataTable/components/ChartHeader.tsx +3 -2
  4. package/components/DataTable/components/ExpandCollapse.tsx +1 -4
  5. package/components/DataTable/data-table.css +2 -7
  6. package/components/DataTable/helpers/customSort.ts +2 -2
  7. package/components/DataTable/helpers/mapCellMatrix.tsx +83 -60
  8. package/components/DataTable/types/TableConfig.ts +0 -1
  9. package/components/EditorPanel/FootnotesEditor.tsx +49 -7
  10. package/components/EditorPanel/VizFilterEditor/VizFilterEditor.tsx +15 -2
  11. package/components/Filters/Filters.tsx +42 -36
  12. package/components/Filters/helpers/handleSorting.ts +5 -0
  13. package/components/Footnotes/Footnotes.tsx +1 -1
  14. package/components/Layout/components/Visualization/index.tsx +18 -4
  15. package/components/Layout/components/Visualization/visualizations.scss +1 -1
  16. package/components/Legend/Legend.Gradient.tsx +1 -4
  17. package/components/Legend/index.tsx +1 -1
  18. package/components/LegendShape.tsx +2 -3
  19. package/components/MediaControls.jsx +32 -8
  20. package/components/NestedDropdown/NestedDropdown.tsx +7 -12
  21. package/components/NestedDropdown/nesteddropdown.styles.css +11 -5
  22. package/components/Table/Table.tsx +0 -6
  23. package/components/Table/components/Row.tsx +2 -5
  24. package/components/_stories/DataTable.stories.tsx +1 -2
  25. package/components/elements/Button.jsx +38 -19
  26. package/components/elements/Confirm.tsx +45 -0
  27. package/components/elements/Error.tsx +24 -0
  28. package/components/managers/DataDesigner.tsx +198 -143
  29. package/components/ui/Title/Title.scss +12 -5
  30. package/components/ui/Title/index.tsx +1 -1
  31. package/dist/cove-main.css +77 -591
  32. package/dist/cove-main.css.map +1 -1
  33. package/helpers/DataTransform.ts +55 -63
  34. package/helpers/addValuesToFilters.ts +45 -16
  35. package/helpers/cove/accessibility.ts +24 -0
  36. package/helpers/cove/fontSettings.ts +1 -1
  37. package/helpers/cove/number.ts +1 -7
  38. package/helpers/coveUpdateWorker.ts +5 -1
  39. package/helpers/displayDataAsText.ts +64 -0
  40. package/helpers/filterVizData.ts +2 -2
  41. package/helpers/formatConfigBeforeSave.ts +16 -1
  42. package/helpers/isOlderVersion.ts +20 -0
  43. package/helpers/missingRequiredSections.ts +20 -0
  44. package/helpers/tests/addValuesToFilters.test.ts +19 -1
  45. package/helpers/useDataVizClasses.ts +8 -4
  46. package/helpers/ver/4.24.10.ts +12 -0
  47. package/helpers/ver/4.24.11.ts +18 -0
  48. package/helpers/ver/4.25.1.ts +18 -0
  49. package/package.json +2 -2
  50. package/styles/_button-section.scss +2 -5
  51. package/styles/_global-variables.scss +17 -7
  52. package/styles/_global.scss +8 -12
  53. package/styles/_reset.scss +4 -5
  54. package/styles/_typography.scss +0 -20
  55. package/styles/_variables.scss +0 -3
  56. package/styles/base.scss +44 -5
  57. package/styles/cove-main.scss +1 -1
  58. package/styles/filters.scss +5 -6
  59. package/styles/v2/base/_general.scss +3 -2
  60. package/styles/v2/components/button.scss +0 -1
  61. package/styles/v2/main.scss +3 -4
  62. package/styles/v2/utils/index.scss +0 -1
  63. package/types/BoxPlot.ts +1 -0
  64. package/types/Runtime.ts +1 -0
  65. package/types/Table.ts +0 -1
  66. package/types/Version.ts +1 -1
  67. package/types/VizFilter.ts +2 -1
  68. package/styles/v2/utils/_spacers.scss +0 -31
@@ -41,18 +41,25 @@ export const filterOrderOptions: { label: string; value: OrderBy }[] = [
41
41
  {
42
42
  label: 'Custom',
43
43
  value: 'cust'
44
- }
44
+ },
45
+ { label: 'Order By Data Column', value: 'column' }
45
46
  ]
46
47
 
47
- const hasStandardFilterBehavior = ['chart', 'table']
48
-
49
48
  export const useFilters = props => {
50
49
  const [showApplyButton, setShowApplyButton] = useState(false)
51
50
 
52
51
  // Desconstructing: notice, adding more descriptive visualizationConfig name over config
53
52
  // visualizationConfig feels more robust for all vis types so that its not confused with config/state/etc.
54
- const { config: visualizationConfig, setConfig, filteredData, setFilteredData, excludedData, getUniqueValues } = props
55
- const { type, data } = visualizationConfig
53
+ const {
54
+ config: visualizationConfig,
55
+ setConfig,
56
+ filteredData,
57
+ setFilteredData,
58
+ excludedData,
59
+ getUniqueValues,
60
+ standaloneMap
61
+ } = props
62
+ const { data } = visualizationConfig
56
63
 
57
64
  /**
58
65
  * Re-orders a filter based on two indices and updates the runtime filters array and filters state
@@ -72,9 +79,7 @@ export const useFilters = props => {
72
79
  const [movedItem] = updatedValues.splice(idx1, 1)
73
80
  updatedValues.splice(idx2, 0, movedItem)
74
81
 
75
- const filtersCopy = hasStandardFilterBehavior.includes(visualizationConfig.type)
76
- ? [...visualizationConfig.filters]
77
- : [...filteredData]
82
+ const filtersCopy = !standaloneMap ? [...visualizationConfig.filters] : [...filteredData]
78
83
  const filterItem = { ...filtersCopy[filterIndex] }
79
84
 
80
85
  // Overwrite filterItem.values since thats what we map through in the editor panel
@@ -86,7 +91,7 @@ export const useFilters = props => {
86
91
  // Update the filters
87
92
  filtersCopy[filterIndex] = filterItem
88
93
 
89
- if (visualizationConfig.type === 'map') {
94
+ if (standaloneMap) {
90
95
  setFilteredData(filtersCopy)
91
96
  }
92
97
 
@@ -94,13 +99,13 @@ export const useFilters = props => {
94
99
  }
95
100
 
96
101
  const changeFilterActive = (index, value) => {
97
- let newFilters = visualizationConfig.type === 'map' ? [...filteredData] : [...visualizationConfig.filters]
102
+ let newFilters = standaloneMap ? [...filteredData] : [...visualizationConfig.filters]
98
103
 
104
+ const newFilter = newFilters[index]
99
105
  if (visualizationConfig.filterBehavior === 'Apply Button') {
100
- newFilters[index].queuedActive = value
106
+ newFilter.queuedActive = value
101
107
  setShowApplyButton(true)
102
108
  } else {
103
- const newFilter = newFilters[index]
104
109
  if (newFilter.filterStyle !== 'nested-dropdown') {
105
110
  newFilter.active = value
106
111
  } else {
@@ -120,7 +125,7 @@ export const useFilters = props => {
120
125
  queryParams[newFilter?.subGrouping?.setByQueryParameter] = newFilter.subGrouping.active
121
126
  updateQueryString(queryParams)
122
127
  }
123
- setFilteredData(newFilters[index])
128
+ setFilteredData(newFilters)
124
129
  }
125
130
 
126
131
  if (!visualizationConfig.dynamicSeries) {
@@ -132,15 +137,12 @@ export const useFilters = props => {
132
137
  }
133
138
 
134
139
  // Used for setting active filter, fromHash breaks the filteredData functionality.
135
- if (visualizationConfig.type === 'map' && visualizationConfig.filterBehavior === 'Filter Change') {
140
+ if (standaloneMap && visualizationConfig.filterBehavior === 'Filter Change') {
136
141
  setFilteredData(newFilters)
137
142
  }
138
143
 
139
144
  // If we're on a chart and not using the apply button
140
- if (
141
- hasStandardFilterBehavior.includes(visualizationConfig.type) &&
142
- visualizationConfig.filterBehavior === 'Filter Change'
143
- ) {
145
+ if (!standaloneMap && visualizationConfig.filterBehavior === 'Filter Change') {
144
146
  const newFilteredData = filterVizData(newFilters, excludedData)
145
147
  setFilteredData(newFilteredData)
146
148
 
@@ -204,11 +206,9 @@ export const useFilters = props => {
204
206
 
205
207
  setConfig({ ...visualizationConfig, filters: newFilters })
206
208
 
207
- if (type === 'map') {
209
+ if (standaloneMap) {
208
210
  setFilteredData(newFilters, excludedData)
209
- }
210
-
211
- if (hasStandardFilterBehavior.includes(visualizationConfig.type)) {
211
+ } else {
212
212
  setFilteredData(filterVizData(newFilters, excludedData))
213
213
  }
214
214
 
@@ -240,7 +240,7 @@ export const useFilters = props => {
240
240
 
241
241
  setConfig({ ...visualizationConfig, filters: newFilters })
242
242
 
243
- if (type === 'map') {
243
+ if (standaloneMap) {
244
244
  setFilteredData(newFilters, excludedData)
245
245
  } else {
246
246
  setFilteredData(filterVizData(newFilters, excludedData))
@@ -274,13 +274,12 @@ type FilterProps = {
274
274
  setFilteredData: Function
275
275
  // updating function for setting fitlerBehavior
276
276
  setConfig: Function
277
- // exclusions
278
- exclusions: any[]
277
+ standaloneMap?: boolean
279
278
  }
280
279
 
281
280
  const Filters = (props: FilterProps) => {
282
- const { config: visualizationConfig, filteredData, dimensions } = props
283
- const { filters, type, general, theme, filterBehavior } = visualizationConfig
281
+ const { config: visualizationConfig, filteredData, dimensions, standaloneMap } = props
282
+ const { filters, general, theme, filterBehavior } = visualizationConfig
284
283
  const [mobileFilterStyle, setMobileFilterStyle] = useState(false)
285
284
  const [selectedFilter, setSelectedFilter] = useState<EventTarget>(null)
286
285
  const id = useId()
@@ -363,7 +362,7 @@ const Filters = (props: FilterProps) => {
363
362
 
364
363
  const vizFiltersWithValues = useMemo(() => {
365
364
  // Here charts is using config.filters where maps is using a runtime value
366
- let vizfilters = type === 'map' ? filteredData : filters
365
+ let vizfilters = standaloneMap ? filteredData : filters
367
366
  if (!vizfilters) return []
368
367
  if (vizfilters.fromHash) delete vizfilters.fromHash // support for Maps config
369
368
  return addValuesToFilters(vizfilters as VizFilter[], visualizationConfig.data)
@@ -437,16 +436,23 @@ const Filters = (props: FilterProps) => {
437
436
 
438
437
  const classList = [
439
438
  'single-filters',
440
- 'form-group mr-3',
439
+ 'form-group',
441
440
  mobileFilterStyle ? 'single-filters--dropdown' : `single-filters--${filterStyle}`
442
441
  ]
443
442
  const mobileExempt = ['nested-dropdown', 'multi-select'].includes(filterStyle)
444
443
  const showDefaultDropdown = (filterStyle === 'dropdown' || mobileFilterStyle) && !mobileExempt
444
+ const [nestedActiveGroup, nestedActiveSubGroup] = useMemo<string[]>(() => {
445
+ if (filterStyle !== 'nested-dropdown') return []
446
+ return (singleFilter.queuedActive || [singleFilter.active, singleFilter.subGrouping?.active]) as [
447
+ string,
448
+ string
449
+ ]
450
+ }, [singleFilter])
445
451
  return (
446
452
  <div className={classList.join(' ')} key={outerIndex}>
447
453
  <>
448
454
  {label && (
449
- <label className='font-weight-bold mt-1 mb-0' htmlFor={`filter-${outerIndex}`}>
455
+ <label className='font-weight-bold mb-2' htmlFor={`filter-${outerIndex}`}>
450
456
  {label}
451
457
  </label>
452
458
  )}
@@ -464,8 +470,8 @@ const Filters = (props: FilterProps) => {
464
470
  )}
465
471
  {filterStyle === 'nested-dropdown' && (
466
472
  <NestedDropdown
467
- activeGroup={(singleFilter.active as string) || (singleFilter.queuedActive || [])[0]}
468
- activeSubGroup={(singleFilter.subGrouping?.active as string) || (singleFilter.queuedActive || [])[1]}
473
+ activeGroup={nestedActiveGroup}
474
+ activeSubGroup={nestedActiveSubGroup}
469
475
  filterIndex={outerIndex}
470
476
  options={getNestedOptions(singleFilter)}
471
477
  listLabel={label}
@@ -492,18 +498,18 @@ const Filters = (props: FilterProps) => {
492
498
  const getClasses = () => {
493
499
  const { visualizationType, legend } = visualizationConfig || {}
494
500
  const baseClass = 'filters-section'
495
- const conditionalClass = type === 'map' ? general.headerColor : visualizationType === 'Spark Line' ? null : theme
501
+ const conditionalClass = standaloneMap ? general.headerColor : visualizationType === 'Spark Line' ? null : theme
496
502
  const legendClass = legend && !legend.hide && legend.position === 'top' ? 'mb-0' : null
497
503
 
498
- return [baseClass, conditionalClass, legendClass].filter(Boolean)
504
+ return [baseClass, conditionalClass, legendClass, 'w-100'].filter(Boolean)
499
505
  }
500
506
 
501
507
  return (
502
508
  <section className={getClasses().join(' ')}>
503
509
  {visualizationConfig.filterIntro && (
504
- <p className='filters-section__intro-text'>{visualizationConfig.filterIntro}</p>
510
+ <p className='filters-section__intro-text mb-3'>{visualizationConfig.filterIntro}</p>
505
511
  )}
506
- <div className='d-flex flex-wrap w-100 filters-section__wrapper'>
512
+ <div className='d-flex flex-wrap w-100 mb-4 pb-2 filters-section__wrapper'>
507
513
  {' '}
508
514
  <>
509
515
  <Style />
@@ -7,6 +7,11 @@ export const handleSorting = singleFilter => {
7
7
  return singleFilter
8
8
  }
9
9
 
10
+ if (singleFilter.order === 'column') {
11
+ // sorting is done in the generateValuesForFilter function
12
+ return singleFilter
13
+ }
14
+
10
15
  const sort = (a, b) => {
11
16
  const asc = singleFilter.order !== 'desc'
12
17
  return String(asc ? a : b).localeCompare(String(asc ? b : a), 'en', { numeric: true })
@@ -12,7 +12,7 @@ const Footnotes: React.FC<FootnotesProps> = ({ footnotes }) => {
12
12
  {footnotes.map((note, i) => {
13
13
  return (
14
14
  <li key={note.symbol + i} className='mb-1'>
15
- {note.symbol && <span className='mr-1'>{note.symbol}</span>}
15
+ {note.symbol && <span className='me-1'>{note.symbol}</span>}
16
16
  {note.text}
17
17
  </li>
18
18
  )
@@ -17,10 +17,17 @@ type VisualizationWrapper = {
17
17
  }
18
18
 
19
19
  const Visualization: React.FC<VisualizationWrapper> = forwardRef((props, ref) => {
20
- const { config = {}, isEditor = false, currentViewport = 'lg', imageId = '', showEditorPanel = true, className } = props
20
+ const {
21
+ config = {},
22
+ isEditor = false,
23
+ currentViewport = 'lg',
24
+ imageId = '',
25
+ showEditorPanel = true,
26
+ className
27
+ } = props
21
28
 
22
29
  const getWrappingClasses = () => {
23
- let classes = ['cdc-open-viz-module', `${currentViewport}`, `font-${config?.fontSize}`, `${config?.theme}`]
30
+ let classes = ['cdc-open-viz-module', `${currentViewport}`, `${config?.theme}`]
24
31
 
25
32
  if (className) {
26
33
  classes.push(className)
@@ -40,7 +47,7 @@ const Visualization: React.FC<VisualizationWrapper> = forwardRef((props, ref) =>
40
47
  }
41
48
 
42
49
  if (config.type === 'filtered-text') {
43
- classes.push('type-filtered-text')
50
+ classes.push('type-filtered-text', `font-${config.fontSize}`)
44
51
  classes = classes.filter(item => item !== 'cove-component__content')
45
52
  return classes
46
53
  }
@@ -67,7 +74,14 @@ const Visualization: React.FC<VisualizationWrapper> = forwardRef((props, ref) =>
67
74
  }
68
75
 
69
76
  if (config.type === 'waffle-chart') {
70
- classes.push('cove', 'cdc-open-viz-module', 'type-waffle-chart', currentViewport, config.theme, 'font-' + config.overallFontSize)
77
+ classes.push(
78
+ 'cove',
79
+ 'cdc-open-viz-module',
80
+ 'type-waffle-chart',
81
+ currentViewport,
82
+ config.theme,
83
+ 'font-' + config.overallFontSize
84
+ )
71
85
 
72
86
  if (isEditor) {
73
87
  classes.push('is-editor')
@@ -1,6 +1,6 @@
1
1
  .cdc-open-viz-module {
2
2
  .cdc-chart-inner-container .cove-component__content {
3
- padding: 25px 15px 25px 0 !important;
3
+ padding: 0 15px 27px 0 !important;
4
4
  }
5
5
  &.isEditor {
6
6
  overflow: auto;
@@ -92,10 +92,7 @@ const LegendGradient = ({
92
92
 
93
93
  if (style === 'gradient') {
94
94
  return (
95
- <svg
96
- style={{ overflow: 'visible', width: '100%', marginTop: 10, marginBottom: hideBorder ? 10 : 0 }}
97
- height={newHeight}
98
- >
95
+ <svg className={'w-100 overflow-visible'} height={newHeight}>
99
96
  {/* background border*/}
100
97
  <rect x={0} y={0} width={legendWidth + MARGIN * 2} height={boxHeight + MARGIN * 2} fill='#d3d3d3' />
101
98
  {/* Define the gradient */}
@@ -28,7 +28,7 @@ const ResetButton = props => {
28
28
  if (config.runtime.disabledAmt === 0) return <></>
29
29
 
30
30
  return (
31
- <button onClick={handleReset} className={legendClasses.resetButton.join(' ') || ''}>
31
+ <button onClick={handleReset} className={legendClasses.showAllButton.join(' ') || ''}>
32
32
  Reset
33
33
  </button>
34
34
  )
@@ -10,9 +10,8 @@ interface LegendShapeProps {
10
10
  const LegendShape: React.FC<LegendShapeProps> = props => {
11
11
  const { fill, borderColor, display = 'inline-block', shape = 'circle' } = props
12
12
  const dimensions = { width: '1em', height: '1em' }
13
- const marginRight = ['circle', 'square'].includes(shape) ? '5px' : '0'
13
+ const isCircleOrSquare = ['circle', 'square'].includes(shape)
14
14
  const styles = {
15
- marginRight: marginRight,
16
15
  borderRadius: shape === 'circle' ? '50%' : '0px',
17
16
  verticalAlign: 'middle',
18
17
  display: display,
@@ -22,7 +21,7 @@ const LegendShape: React.FC<LegendShapeProps> = props => {
22
21
  backgroundColor: fill
23
22
  }
24
23
 
25
- return <span className='legend-item' style={styles} />
24
+ return <span className={`legend-item ${isCircleOrSquare ? 'me-2' : ''}`} style={styles} />
26
25
  }
27
26
 
28
27
  export default LegendShape
@@ -42,13 +42,30 @@ const generateMedia = (state, type, elementToCapture) => {
42
42
  // Apparently some packages use state.title where others use state.general.title
43
43
  const handleFileName = state => {
44
44
  // dashboard titles
45
- if (state?.dashboard?.title) return state.dashboard.title.replace(/\s+/g, '-').toLowerCase() + '-' + date.getDate() + date.getMonth() + date.getFullYear()
45
+ if (state?.dashboard?.title)
46
+ return (
47
+ state.dashboard.title.replace(/\s+/g, '-').toLowerCase() +
48
+ '-' +
49
+ date.getDate() +
50
+ date.getMonth() +
51
+ date.getFullYear()
52
+ )
46
53
 
47
54
  // map titles
48
- if (state?.general?.title) return state.general.title.replace(/\s+/g, '-').toLowerCase() + '-' + date.getDate() + date.getMonth() + date.getFullYear()
55
+ if (state?.general?.title)
56
+ return (
57
+ state.general.title.replace(/\s+/g, '-').toLowerCase() +
58
+ '-' +
59
+ date.getDate() +
60
+ date.getMonth() +
61
+ date.getFullYear()
62
+ )
49
63
 
50
64
  // chart titles
51
- if (state?.title) return state.title.replace(/\s+/g, '-').toLowerCase() + '-' + date.getDate() + date.getMonth() + date.getFullYear()
65
+ if (state?.title)
66
+ return (
67
+ state.title.replace(/\s+/g, '-').toLowerCase() + '-' + date.getDate() + date.getMonth() + date.getFullYear()
68
+ )
52
69
 
53
70
  return 'no-title'
54
71
  }
@@ -59,7 +76,10 @@ const generateMedia = (state, type, elementToCapture) => {
59
76
 
60
77
  switch (type) {
61
78
  case 'image':
62
- html2canvas(baseSvg, {ignoreElements: el => el.className?.indexOf && el.className.search(/download-buttons|download-links|data-table-container/) !== -1}).then(canvas => {
79
+ html2canvas(baseSvg, {
80
+ ignoreElements: el =>
81
+ el.className?.indexOf && el.className.search(/download-buttons|download-links|data-table-container/) !== -1
82
+ }).then(canvas => {
63
83
  saveImageAs(canvas.toDataURL(), filename + '.png')
64
84
  })
65
85
  return
@@ -98,9 +118,14 @@ const handleTheme = state => {
98
118
 
99
119
  // Download CSV
100
120
  const Button = ({ state, text, type, title, elementToCapture }) => {
101
- const buttonClasses = ['btn', 'btn-download', `${handleTheme(state)}`]
121
+ const buttonClasses = ['btn', 'btn-primary']
102
122
  return (
103
- <button className={buttonClasses.join(' ')} title={title} onClick={() => generateMedia(state, type, elementToCapture)} style={{ lineHeight: '1.4em' }}>
123
+ <button
124
+ className={buttonClasses.join(' ')}
125
+ title={title}
126
+ onClick={() => generateMedia(state, type, elementToCapture)}
127
+ style={{ lineHeight: '1.4em' }}
128
+ >
104
129
  {buttonText[type]}
105
130
  </button>
106
131
  )
@@ -108,7 +133,7 @@ const Button = ({ state, text, type, title, elementToCapture }) => {
108
133
 
109
134
  // Link to CSV/JSON data
110
135
  const Link = ({ config, dashboardDataConfig }) => {
111
- let dataConfig = dashboardDataConfig || config;
136
+ let dataConfig = dashboardDataConfig || config
112
137
  // Handles Maps & Charts
113
138
  if (dataConfig.dataFileSourceType === 'url' && dataConfig.dataFileName && config.table.showDownloadUrl) {
114
139
  return (
@@ -126,7 +151,6 @@ const Link = ({ config, dashboardDataConfig }) => {
126
151
  ) : null
127
152
  }
128
153
 
129
- // TODO: convert to standardized COVE section
130
154
  const Section = ({ children, classes }) => {
131
155
  return (
132
156
  <section className={classes.join(' ')}>
@@ -124,25 +124,21 @@ const NestedDropdown: React.FC<NestedDropdownProps> = ({
124
124
  }) => {
125
125
  const dropdownId = useId()
126
126
 
127
- const [userSearchTerm, setUserSearchTerm] = useState('')
128
- const [inputValue, setInputValue] = useState('')
127
+ const [userSearchTerm, setUserSearchTerm] = useState(null)
129
128
 
130
- const initialInputValue = useMemo(() => {
129
+ const inputValue = useMemo(() => {
131
130
  // value from props
132
131
  return activeSubGroup ? `${activeGroup} - ${activeSubGroup}` : ''
133
- }, [activeSubGroup])
132
+ }, [activeGroup, activeSubGroup])
134
133
  const [inputHasFocus, setInputHasFocus] = useState(false)
135
134
  const [isListOpened, setIsListOpened] = useState(false)
136
-
137
135
  const searchInput = useRef(null)
138
136
  const searchDropdown = useRef(null)
139
137
 
140
138
  const chooseSelectedSubGroup = (tierOne: string | number, tierTwo: string | number) => {
141
139
  searchInput.current.focus()
142
- const selectedItemValue = `${tierOne} - ${tierTwo}`
143
- setUserSearchTerm('')
140
+ setUserSearchTerm(null)
144
141
  setIsListOpened(false)
145
- setInputValue(selectedItemValue)
146
142
  handleSelectedItems([String(tierOne), String(tierTwo)])
147
143
  }
148
144
 
@@ -220,14 +216,13 @@ const NestedDropdown: React.FC<NestedDropdownProps> = ({
220
216
  }
221
217
 
222
218
  const filterOptions = useMemo(() => {
223
- return filterSearchTerm(userSearchTerm, options)
219
+ return filterSearchTerm(userSearchTerm || '', options)
224
220
  }, [userSearchTerm, options])
225
221
 
226
222
  const handleSearchTermChange = e => {
227
223
  const newSearchTerm = e.target.value
228
224
  setIsListOpened(true)
229
225
  setUserSearchTerm(newSearchTerm)
230
- setInputValue(newSearchTerm)
231
226
  }
232
227
 
233
228
  const handleOnBlur = e => {
@@ -265,7 +260,7 @@ const NestedDropdown: React.FC<NestedDropdownProps> = ({
265
260
  aria-haspopup='true'
266
261
  aria-hidden='false'
267
262
  tabIndex={0}
268
- value={inputValue || initialInputValue}
263
+ value={userSearchTerm !== null ? userSearchTerm : inputValue}
269
264
  onChange={handleSearchTermChange}
270
265
  placeholder={loading ? 'Loading...' : '- Select -'}
271
266
  disabled={loading || !options.length}
@@ -303,7 +298,7 @@ const NestedDropdown: React.FC<NestedDropdownProps> = ({
303
298
  chooseSelectedSubGroup(groupValue, subGroupValue)
304
299
  }}
305
300
  userSelectedLabel={activeGroup + activeSubGroup}
306
- userSearchTerm={userSearchTerm}
301
+ userSearchTerm={userSearchTerm || ''}
307
302
  />
308
303
  )
309
304
  })
@@ -10,23 +10,31 @@
10
10
  list-style: none;
11
11
  }
12
12
 
13
+ * {
14
+ font-family: var(--app-font-secondary) !important;
15
+ font-size: var(--filter-select-font-size) !important;
16
+ }
17
+
13
18
  .search-input {
19
+ color: var(--cool-gray-90);
20
+ font-weight: 300;
21
+
14
22
  border: none;
15
23
  position: relative;
16
24
  display: inline-block;
17
25
  width: 100%;
18
26
  padding: 0;
19
27
  &::placeholder {
20
- color: var(--darkGray);
28
+ color: var(--cool-gray-90);
21
29
  }
22
30
  }
23
31
 
24
32
  .main-nested-dropdown-container,
25
33
  .nested-dropdown-input-container {
26
- border: 1px solid var(--lightGray);
34
+ border: 1px solid var(--cool-gray-10);
27
35
  min-width: 200px;
28
36
  cursor: pointer;
29
- padding: 0.375rem 0.75rem;
37
+ padding: 0.4rem 0.75rem;
30
38
  font-size: 1em;
31
39
  }
32
40
 
@@ -53,7 +61,6 @@
53
61
  border-radius: 0.25rem;
54
62
  position: relative;
55
63
  & > span.list-arrow {
56
- color: var(--mediumGray);
57
64
  position: absolute;
58
65
  top: 9px;
59
66
  right: 1px;
@@ -63,7 +70,6 @@
63
70
  &.disabled {
64
71
  background-color: var(--lightestGray);
65
72
  & > :is(input) {
66
- color: var(--darkGray);
67
73
  background-color: var(--lightestGray);
68
74
  }
69
75
  }
@@ -22,7 +22,6 @@ type TableProps = {
22
22
  }
23
23
  wrapColumns?: boolean
24
24
  hasRowType?: boolean // if it has row type then the first column is the row type which will explain how to render the row
25
- fontSize: 'small' | 'medium' | 'large'
26
25
  viewport: 'lg' | 'md' | 'sm' | 'xs' | 'xxs'
27
26
  preliminaryData?: PreliminaryDataItem[]
28
27
  }
@@ -39,7 +38,6 @@ const Table = ({
39
38
  tableOptions,
40
39
  wrapColumns,
41
40
  hasRowType,
42
- fontSize,
43
41
  viewport,
44
42
  preliminaryData
45
43
  }: TableProps) => {
@@ -71,7 +69,6 @@ const Table = ({
71
69
  childRow={row}
72
70
  wrapColumns={wrapColumns}
73
71
  cellMinWidth={tableOptions.cellMinWidth}
74
- fontSize={fontSize}
75
72
  viewport={viewport}
76
73
  />
77
74
  )
@@ -92,7 +89,6 @@ const Table = ({
92
89
  childRow={childRow}
93
90
  wrapColumns={wrapColumns}
94
91
  cellMinWidth={tableOptions.cellMinWidth}
95
- fontSize={fontSize}
96
92
  viewport={viewport}
97
93
  />
98
94
  )
@@ -110,7 +106,6 @@ const Table = ({
110
106
  isTotal={true}
111
107
  wrapColumns={wrapColumns}
112
108
  cellMinWidth={tableOptions.cellMinWidth}
113
- fontSize={fontSize}
114
109
  viewport={viewport}
115
110
  />
116
111
  )
@@ -125,7 +120,6 @@ const Table = ({
125
120
  childRow={childRowCopy}
126
121
  wrapColumns={wrapColumns}
127
122
  cellMinWidth={tableOptions.cellMinWidth}
128
- fontSize={fontSize}
129
123
  viewport={viewport}
130
124
  />
131
125
  )
@@ -8,18 +8,15 @@ type RowProps = {
8
8
  wrapColumns: boolean
9
9
  isTotal?: boolean
10
10
  cellMinWidth?: number
11
- fontSize: 'small' | 'medium' | 'large'
12
11
  viewport: 'lg' | 'md' | 'sm' | 'xs' | 'xxs'
13
12
  style?: object
14
13
  preliminaryData?: PreliminaryDataItem[]
15
14
  }
16
15
 
17
16
  const Row: FC<RowProps> = props => {
18
- const { childRow, rowKey, wrapColumns, cellMinWidth = 0, isTotal, fontSize, viewport, preliminaryData } = props
17
+ const { childRow, rowKey, wrapColumns, cellMinWidth = 0, isTotal, viewport, preliminaryData } = props
19
18
  const whiteSpace = wrapColumns ? 'unset' : 'nowrap'
20
19
  const minWidth = cellMinWidth + 'px'
21
- const fontSizes = { small: 16, medium: 18, large: 20 }
22
- const cellFontSize = ['xs', 'xxs'].includes(viewport) ? '12px' : `${fontSizes[fontSize]}px`
23
20
 
24
21
  return (
25
22
  <tr>
@@ -34,7 +31,7 @@ const Row: FC<RowProps> = props => {
34
31
  <Cell
35
32
  ariaLabel={style?.color ? 'suppressed data' : ''}
36
33
  key={rowKey + '__' + i}
37
- style={{ whiteSpace, minWidth, fontSize: cellFontSize, ...style }}
34
+ style={{ whiteSpace, minWidth, ...style }}
38
35
  isBold={isTotal}
39
36
  >
40
37
  {child}
@@ -45,8 +45,7 @@ export const CityState: Story = {
45
45
  tabbingId: '#asdf',
46
46
  columns: CityStateExample.columns,
47
47
  applyLegendToRow: () => ['#000'],
48
- displayGeoName,
49
- displayDataAsText: d => d
48
+ displayGeoName
50
49
  }
51
50
  }
52
51