@cdc/core 4.24.5 → 4.24.9-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 (109) hide show
  1. package/assets/icon-gear-multi.svg +23 -0
  2. package/components/AdvancedEditor/AdvancedEditor.tsx +93 -0
  3. package/components/AdvancedEditor/advanced-editor-styles.css +3 -0
  4. package/components/AdvancedEditor/index.ts +1 -0
  5. package/components/Alert/components/Alert.styles.css +15 -0
  6. package/components/Alert/components/Alert.tsx +39 -0
  7. package/components/Alert/index.tsx +3 -0
  8. package/components/DataTable/DataTable.tsx +127 -32
  9. package/components/DataTable/DataTableStandAlone.tsx +4 -25
  10. package/components/DataTable/components/DataTableEditorPanel.tsx +4 -4
  11. package/components/DataTable/components/ExpandCollapse.tsx +1 -1
  12. package/components/DataTable/helpers/chartCellMatrix.tsx +6 -12
  13. package/components/DataTable/helpers/getChartCellValue.ts +9 -5
  14. package/components/DataTable/helpers/getDataSeriesColumns.ts +10 -7
  15. package/components/DataTable/helpers/getRowType.ts +6 -0
  16. package/components/DataTable/helpers/mapCellMatrix.tsx +3 -3
  17. package/components/DataTable/types/TableConfig.ts +2 -1
  18. package/components/EditorPanel/ColumnsEditor.tsx +3 -30
  19. package/components/EditorPanel/DataTableEditor.tsx +66 -22
  20. package/components/EditorPanel/FieldSetWrapper.tsx +51 -0
  21. package/components/EditorPanel/FootnotesEditor.tsx +77 -0
  22. package/components/EditorPanel/Inputs.tsx +13 -4
  23. package/components/EditorPanel/VizFilterEditor/NestedDropdownEditor.tsx +268 -0
  24. package/components/EditorPanel/VizFilterEditor/VizFilterEditor.tsx +306 -0
  25. package/components/EditorPanel/VizFilterEditor/components/FilterOrder.tsx +40 -0
  26. package/components/EditorPanel/VizFilterEditor/index.ts +1 -0
  27. package/components/EditorWrapper/EditorWrapper.tsx +3 -4
  28. package/components/EditorWrapper/index.ts +1 -0
  29. package/components/Filters.tsx +520 -0
  30. package/components/Footnotes/Footnotes.tsx +25 -0
  31. package/components/Footnotes/FootnotesStandAlone.tsx +45 -0
  32. package/components/Footnotes/footnotes.css +5 -0
  33. package/components/Footnotes/index.ts +1 -0
  34. package/components/Layout/components/Responsive.tsx +14 -4
  35. package/components/Layout/components/Sidebar/components/Sidebar.tsx +14 -5
  36. package/components/Layout/components/Sidebar/components/sidebar.styles.scss +23 -20
  37. package/components/Layout/components/Visualization/index.tsx +19 -6
  38. package/components/Layout/components/Visualization/visualizations.scss +32 -26
  39. package/components/Layout/styles/editor.scss +0 -8
  40. package/components/Legend/Legend.Gradient.tsx +133 -0
  41. package/components/LegendShape.tsx +28 -0
  42. package/components/MultiSelect/MultiSelect.tsx +41 -11
  43. package/components/MultiSelect/multiselect.styles.css +0 -3
  44. package/components/NestedDropdown/NestedDropdown.tsx +47 -52
  45. package/components/NestedDropdown/nesteddropdown.styles.css +19 -25
  46. package/components/Table/Table.tsx +8 -5
  47. package/components/Table/components/Cell.tsx +2 -2
  48. package/components/Table/components/Row.tsx +25 -7
  49. package/components/_stories/Footnotes.stories.tsx +17 -0
  50. package/components/_stories/Layout.Debug.stories.tsx +91 -0
  51. package/components/_stories/_mocks/bar-chart-suppressed.json +474 -0
  52. package/components/_stories/styles.scss +14 -1
  53. package/components/createBarElement.jsx +4 -4
  54. package/components/inputs/InputSelect.tsx +17 -6
  55. package/components/ui/Icon.tsx +22 -16
  56. package/components/ui/Title/Title.scss +0 -8
  57. package/helpers/DataTransform.ts +2 -2
  58. package/helpers/addValuesToFilters.ts +135 -0
  59. package/helpers/cove/accessibility.ts +17 -4
  60. package/helpers/cove/fontSettings.ts +2 -0
  61. package/helpers/coveUpdateWorker.ts +30 -9
  62. package/helpers/filterVizData.ts +49 -0
  63. package/helpers/formatConfigBeforeSave.ts +110 -0
  64. package/helpers/gatherQueryParams.ts +24 -7
  65. package/helpers/getGradientLegendWidth.ts +15 -0
  66. package/helpers/getTextWidth.ts +18 -0
  67. package/helpers/lineChartHelpers.js +2 -1
  68. package/helpers/pivotData.ts +18 -0
  69. package/helpers/queryStringUtils.ts +29 -0
  70. package/helpers/scaling.ts +7 -0
  71. package/helpers/tests/addValuesToFilters.test.ts +55 -0
  72. package/helpers/tests/filterVizData.test.ts +31 -0
  73. package/helpers/tests/gatherQueryParams.test.ts +22 -0
  74. package/helpers/tests/invertValue.test.ts +35 -0
  75. package/helpers/tests/updateFieldFactory.test.ts +1 -0
  76. package/helpers/updateFieldFactory.ts +1 -1
  77. package/helpers/updatePaletteNames.ts +19 -0
  78. package/helpers/{useDataVizClasses.js → useDataVizClasses.ts} +3 -2
  79. package/helpers/ver/4.24.5.ts +3 -3
  80. package/helpers/ver/4.24.7.ts +123 -0
  81. package/helpers/ver/4.24.9.ts +63 -0
  82. package/helpers/ver/tests/4.24.9.test.ts +22 -0
  83. package/helpers/ver/versionNeedsUpdate.ts +9 -0
  84. package/package.json +6 -4
  85. package/styles/_button-section.scss +7 -2
  86. package/styles/_data-table.scss +0 -1
  87. package/styles/_global.scss +6 -2
  88. package/styles/base.scss +4 -0
  89. package/styles/filters.scss +4 -0
  90. package/styles/v2/themes/_color-definitions.scss +1 -0
  91. package/types/Annotation.ts +46 -0
  92. package/types/Axis.ts +3 -2
  93. package/types/ConfigureData.ts +1 -1
  94. package/types/Dimensions.ts +1 -0
  95. package/types/Footnotes.ts +17 -0
  96. package/types/General.ts +5 -0
  97. package/types/Runtime.ts +2 -7
  98. package/types/Table.ts +6 -0
  99. package/types/Visualization.ts +31 -9
  100. package/types/VizFilter.ts +39 -7
  101. package/components/AdvancedEditor.jsx +0 -74
  102. package/components/EditorPanel/VizFilterEditor.tsx +0 -234
  103. package/components/Filters.jsx +0 -461
  104. package/components/LegendCircle.jsx +0 -17
  105. package/helpers/queryStringUtils.js +0 -26
  106. package/helpers/updatePaletteNames.js +0 -16
  107. package/types/BaseVisualizationType.ts +0 -1
  108. /package/components/{Waiting.jsx → Waiting.tsx} +0 -0
  109. /package/helpers/ver/{4.23.4.ts → 4.24.4.ts} +0 -0
@@ -1,16 +1,16 @@
1
1
  import { useState, useEffect, useRef, useMemo } from 'react'
2
2
  import './nesteddropdown.styles.css'
3
3
  import Icon from '@cdc/core/components/ui/Icon'
4
+ import { VizFilter } from '../../types/VizFilter'
4
5
 
5
6
  const Options: React.FC<{
6
7
  currentOptions: (string | number)[]
7
8
  label: string
8
- handleSecondTierSelect: Function
9
- userSelectedTierTwoLabel: string
9
+ handleSubGroupSelect: Function
10
+ userSelectedLabel: string
10
11
  userSearchTerm: string
11
- }> = ({ currentOptions, label, handleSecondTierSelect, userSelectedTierTwoLabel, userSearchTerm }) => {
12
+ }> = ({ currentOptions = [], label, handleSubGroupSelect, userSelectedLabel, userSearchTerm }) => {
12
13
  const [isTierOneExpanded, setIsTierOneExpanded] = useState(true)
13
-
14
14
  const checkMark = <>&#10004;</>
15
15
 
16
16
  useEffect(() => {
@@ -29,23 +29,24 @@ const Options: React.FC<{
29
29
  if (currentItem.className === 'selectable-item') currentItem.parentNode.parentNode.focus()
30
30
  setIsTierOneExpanded(false)
31
31
  } else if (e.key === 'Enter') {
32
- currentItem.className === 'selectable-item' ? handleSecondTierSelect(currentItem.dataset.value) : setIsTierOneExpanded(!isTierOneExpanded)
32
+ currentItem.className === 'selectable-item' ? handleSubGroupSelect(currentItem.dataset.value) : setIsTierOneExpanded(!isTierOneExpanded)
33
33
  }
34
34
  }
35
35
 
36
36
  return (
37
37
  <>
38
38
  <li role='treeitem' key={label} tabIndex={0} aria-label={label} onClick={handleGroupClick} onKeyUp={handleKeyUp} className='nested-dropdown-group'>
39
- <span id={label}>{label} </span>
39
+ <span className={'font-weight-bold'}>{label} </span>
40
40
  {
41
41
  <span className='list-arrow' aria-hidden='true'>
42
42
  {isTierOneExpanded ? <Icon display='caretFilledUp' /> : <Icon display='caretFilledDown' />}
43
43
  </span>
44
44
  }
45
45
  <ul aria-expanded={isTierOneExpanded} role='group' tabIndex={-1} aria-labelledby={label} className={isTierOneExpanded ? '' : 'hide'}>
46
- {currentOptions.map(tierTwo => {
46
+ {currentOptions.map((tierTwo, tierTwoIndex) => {
47
47
  const regionID = label + tierTwo
48
- let isSelected = regionID === userSelectedTierTwoLabel
48
+ const isSelected = regionID === userSelectedLabel
49
+
49
50
  return (
50
51
  <li
51
52
  key={regionID}
@@ -56,10 +57,16 @@ const Options: React.FC<{
56
57
  aria-selected={isSelected}
57
58
  data-value={tierTwo}
58
59
  onClick={e => {
59
- handleSecondTierSelect(tierTwo)
60
+ handleSubGroupSelect(tierTwo)
60
61
  }}
61
62
  >
62
- {isSelected ? <span aria-hidden='true'>{checkMark}</span> : ''}
63
+ {isSelected ? (
64
+ <span className='check-mark' aria-hidden='true'>
65
+ {checkMark}
66
+ </span>
67
+ ) : (
68
+ ''
69
+ )}
63
70
 
64
71
  {tierTwo}
65
72
  </li>
@@ -72,42 +79,43 @@ const Options: React.FC<{
72
79
  }
73
80
 
74
81
  interface NestedDropdownProps {
75
- data: Record<string, string | number>[]
76
- tiers: [string, string] // index 0 is the parent index 1 is the child
82
+ isEditor?: boolean
83
+ currentFilter: VizFilter
77
84
  listLabel: string
78
85
  handleSelectedItems: Function
79
86
  }
80
87
 
81
- const NestedDropdown: React.FC<NestedDropdownProps> = ({ data, tiers: [firstTierLabel, secondTierLabel], listLabel, handleSelectedItems }) => {
82
- const optsMemo: Record<string, (string | number)[]> = {}
83
-
84
- data.forEach(value => {
85
- const tierOne = value[firstTierLabel]
86
- const tierTwo = value[secondTierLabel]
87
- if (optsMemo[tierOne]) {
88
- optsMemo[tierOne].push(tierTwo)
89
- } else {
90
- optsMemo[tierOne] = [tierTwo]
91
- }
92
- })
88
+ type OptionsMemo = [string, (string | number)[]][]
89
+
90
+ const NestedDropdown: React.FC<NestedDropdownProps> = ({ currentFilter, listLabel, handleSelectedItems }) => {
91
+ const optsMemo: OptionsMemo = useMemo(() => {
92
+ // keep custom ordered value order
93
+ const values = currentFilter.orderedValues?.filter(value => currentFilter.values.includes(value)) || currentFilter.values
94
+ return values.map(value => {
95
+ if (!currentFilter.subGrouping) return [value, []]
96
+ const { orderedValues, values } = currentFilter.subGrouping.valuesLookup[value]
97
+ const subFilterValues = orderedValues?.filter(value => values.includes(value)) || values
98
+ return [value, subFilterValues]
99
+ })
100
+ }, [currentFilter, currentFilter.subGrouping])
101
+ const groupFilterActive = currentFilter.active
102
+ const subGroupFilterActive = currentFilter.subGrouping?.active ?? ''
93
103
 
94
- const [userSelectedTierTwoLabel, setUserSelectedTierTwoLabel] = useState(null)
95
104
  const [userSearchTerm, setUserSearchTerm] = useState('')
96
- const [inputValue, setInputValue] = useState('')
105
+ const [inputValue, setInputValue] = useState(subGroupFilterActive !== '' ? `${groupFilterActive} - ${subGroupFilterActive}` : 'Select an Option')
97
106
  const [inputHasFocus, setInputHasFocus] = useState(false)
98
107
  const [isListOpened, setIsListOpened] = useState(false)
99
108
 
100
109
  const searchInput = useRef(null)
101
110
  const searchDropdown = useRef(null)
102
111
 
103
- const chooseSelectedSecondTier = (tierOne: string, tierTwo: string) => {
112
+ const chooseSelectedSubGroup = (tierOne: string, tierTwo: string) => {
104
113
  searchInput.current.focus()
105
- const selectedItemValue = tierTwo
106
- setUserSelectedTierTwoLabel(tierOne + tierTwo)
114
+ const selectedItemValue = `${tierOne} - ${tierTwo}`
107
115
  setUserSearchTerm('')
108
116
  setIsListOpened(false)
109
117
  setInputValue(selectedItemValue)
110
- handleSelectedItems(tierOne, tierTwo)
118
+ handleSelectedItems([tierOne, tierTwo])
111
119
  }
112
120
 
113
121
  const handleKeyUp = e => {
@@ -182,25 +190,12 @@ const NestedDropdown: React.FC<NestedDropdownProps> = ({ data, tiers: [firstTier
182
190
  }
183
191
  }
184
192
 
185
- const filterOptions: Record<string, (string | number)[]> = useMemo(() => {
193
+ const filterOptions: OptionsMemo = useMemo(() => {
186
194
  if (!userSearchTerm) return optsMemo
187
- const newOptions: Record<string, (string | number)[]> = {}
188
195
  const newRegex = new RegExp(`^${userSearchTerm}`, 'i')
189
- for (const tierOne in optsMemo) {
190
- if (tierOne.match(newRegex)) {
191
- newOptions[tierOne] = [...optsMemo[tierOne]]
192
- } else {
193
- const newSecondTierOptions = optsMemo[tierOne].filter(tierTwo => String(tierTwo).match(newRegex))
194
- if (newSecondTierOptions.length > 0) {
195
- newOptions[tierOne] = newSecondTierOptions
196
- }
197
- }
198
- }
199
- return newOptions
196
+ return optsMemo.filter(([tierOne, tierTwo]) => tierOne.match(newRegex) || tierTwo.some(value => String(value).match(newRegex)))
200
197
  }, [userSearchTerm])
201
198
 
202
- const filterOptionsKeys = Object.keys(filterOptions)
203
-
204
199
  const handleSearchTermChange = e => {
205
200
  const newSearchTerm = e.target.value
206
201
  setIsListOpened(true)
@@ -233,16 +228,16 @@ const NestedDropdown: React.FC<NestedDropdownProps> = ({ data, tiers: [firstTier
233
228
  </span>
234
229
  </div>
235
230
  <ul role='tree' key={listLabel} tabIndex={-1} aria-labelledby='main-nested-dropdown' aria-expanded={isListOpened} ref={searchDropdown} className={`main-nested-dropdown-container ${isListOpened ? '' : 'hide'}`}>
236
- {filterOptions && filterOptionsKeys.length > 0
237
- ? filterOptionsKeys.map((tierOne: string) => {
231
+ {filterOptions?.length
232
+ ? filterOptions.map(([groupName, options]) => {
238
233
  return (
239
234
  <Options
240
- currentOptions={filterOptions[tierOne]}
241
- label={tierOne}
242
- handleSecondTierSelect={(tierTwo: string) => {
243
- chooseSelectedSecondTier(tierOne, tierTwo)
235
+ currentOptions={options}
236
+ label={groupName}
237
+ handleSubGroupSelect={(subGroupValue: string) => {
238
+ chooseSelectedSubGroup(groupName, subGroupValue)
244
239
  }}
245
- userSelectedTierTwoLabel={userSelectedTierTwoLabel}
240
+ userSelectedLabel={groupFilterActive + subGroupFilterActive}
246
241
  userSearchTerm={userSearchTerm}
247
242
  />
248
243
  )
@@ -1,11 +1,6 @@
1
1
  .nested-dropdown {
2
- li {
2
+ .nested-dropdown-group {
3
3
  list-style: none;
4
- cursor: pointer;
5
-
6
- &:focus {
7
- border: 2px solid var(--orange);
8
- }
9
4
  }
10
5
 
11
6
  .search-input {
@@ -25,11 +20,24 @@
25
20
  cursor: pointer;
26
21
  }
27
22
 
28
- .selectable-item:hover {
29
- background-color: var(--lightGray);
23
+ .selectable-item {
24
+ list-style: none;
25
+ padding-left: 20px;
26
+ position: relative;
27
+ font-weight: normal;
28
+ white-space: nowrap;
29
+
30
+ & .check-mark {
31
+ position: absolute;
32
+ left: 0px;
33
+ }
34
+
35
+ &:hover {
36
+ background-color: var(--lightGray);
37
+ }
30
38
  }
31
39
 
32
- & > div {
40
+ .nested-dropdown-input-container {
33
41
  position: relative;
34
42
  & > span.list-arrow {
35
43
  position: absolute;
@@ -42,26 +50,12 @@
42
50
  }
43
51
  }
44
52
 
45
- & > ul {
53
+ & .main-nested-dropdown-container {
46
54
  max-height: 375px;
47
55
  overflow-y: scroll;
48
56
  position: absolute;
49
57
  z-index: 3;
50
- width: 375px;
51
-
52
- & > li {
53
- font-weight: bold;
54
-
55
- & > ul > li {
56
- position: relative;
57
- font-weight: normal;
58
- white-space: nowrap;
59
- & > span {
60
- position: absolute;
61
- left: -20px;
62
- }
63
- }
64
- }
58
+ width: 325px;
65
59
  }
66
60
 
67
61
  .hide {
@@ -3,6 +3,7 @@ import Row from './components/Row'
3
3
  import GroupRow from './components/GroupRow'
4
4
  import { CellMatrix, GroupCellMatrix } from './types/CellMatrix'
5
5
  import { RowType } from './types/RowType'
6
+ import { PreliminaryDataItem } from '@cdc/chart/src/types/ChartConfig'
6
7
 
7
8
  type TableProps = {
8
9
  childrenMatrix: CellMatrix | GroupCellMatrix
@@ -21,13 +22,15 @@ type TableProps = {
21
22
  hasRowType?: boolean // if it has row type then the first column is the row type which will explain how to render the row
22
23
  fontSize: 'small' | 'medium' | 'large'
23
24
  viewport: 'lg' | 'md' | 'sm' | 'xs' | 'xxs'
25
+ preliminaryData?: PreliminaryDataItem[]
24
26
  }
25
27
 
26
28
  type Position = 'sticky'
27
29
 
28
- const Table = ({ childrenMatrix, tableName, caption, stickyHeader, headContent, tableOptions, wrapColumns, hasRowType, fontSize, viewport }: TableProps) => {
30
+ const Table = ({ childrenMatrix, tableName, caption, stickyHeader, headContent, tableOptions, wrapColumns, hasRowType, fontSize, viewport, preliminaryData }: TableProps) => {
29
31
  const headStyle = stickyHeader ? { position: 'sticky' as Position, top: 0, zIndex: 2 } : {}
30
32
  const isGroupedMatrix = !Array.isArray(childrenMatrix)
33
+
31
34
  return (
32
35
  <table {...tableOptions}>
33
36
  <caption className='visually-hidden'>{caption}</caption>
@@ -39,7 +42,7 @@ const Table = ({ childrenMatrix, tableName, caption, stickyHeader, headContent,
39
42
  const rows = childrenMatrix[groupName].map((row, i) => {
40
43
  colSpan = row.length
41
44
  const key = `${tableName}-${groupName}-row-${i}`
42
- return <Row key={key} rowKey={key} childRow={row} wrapColumns={wrapColumns} cellMinWidth={tableOptions.cellMinWidth} fontSize={fontSize} viewport={viewport} />
45
+ return <Row preliminaryData={preliminaryData} key={key} rowKey={key} childRow={row} wrapColumns={wrapColumns} cellMinWidth={tableOptions.cellMinWidth} fontSize={fontSize} viewport={viewport} />
43
46
  })
44
47
  return [<GroupRow label={groupName} colSpan={colSpan} key={`${tableName}-${groupName}`} />, ...rows]
45
48
  })
@@ -49,17 +52,17 @@ const Table = ({ childrenMatrix, tableName, caption, stickyHeader, headContent,
49
52
  if (hasRowType) rowType = childRowCopy.shift()
50
53
  const key = `${tableName}-row-${i}`
51
54
  if (rowType === undefined) {
52
- return <Row key={key} rowKey={key} childRow={childRow} wrapColumns={wrapColumns} cellMinWidth={tableOptions.cellMinWidth} fontSize={fontSize} viewport={viewport} />
55
+ return <Row preliminaryData={preliminaryData} key={key} rowKey={key} childRow={childRow} wrapColumns={wrapColumns} cellMinWidth={tableOptions.cellMinWidth} fontSize={fontSize} viewport={viewport} />
53
56
  } else {
54
57
  switch (rowType) {
55
58
  case RowType.row_group:
56
59
  return <GroupRow label={childRowCopy[0]} colSpan={childRowCopy.length} key={key} />
57
60
  case RowType.total:
58
- return <Row key={key} rowKey={key} childRow={childRowCopy} isTotal={true} wrapColumns={wrapColumns} cellMinWidth={tableOptions.cellMinWidth} fontSize={fontSize} viewport={viewport} />
61
+ return <Row preliminaryData={preliminaryData} key={key} rowKey={key} childRow={childRowCopy} isTotal={true} wrapColumns={wrapColumns} cellMinWidth={tableOptions.cellMinWidth} fontSize={fontSize} viewport={viewport} />
59
62
  case RowType.row_group_total:
60
63
  return <GroupRow label={childRowCopy[0]} colSpan={1} key={key} data={childRowCopy.slice(1)} />
61
64
  default:
62
- return <Row key={key} rowKey={key} childRow={childRowCopy} wrapColumns={wrapColumns} cellMinWidth={tableOptions.cellMinWidth} fontSize={fontSize} viewport={viewport} />
65
+ return <Row preliminaryData={preliminaryData} key={key} rowKey={key} childRow={childRowCopy} wrapColumns={wrapColumns} cellMinWidth={tableOptions.cellMinWidth} fontSize={fontSize} viewport={viewport} />
63
66
  }
64
67
  }
65
68
  })}
@@ -1,6 +1,6 @@
1
- const Cell = ({ children, style, isBold = false }) => {
1
+ const Cell = ({ children, style, isBold = false, ariaLabel }) => {
2
2
  return (
3
- <td tabIndex={0} role='gridcell' style={style}>
3
+ <td aria-label={ariaLabel} tabIndex={0} role='gridcell' style={style}>
4
4
  {isBold ? <strong>{children}</strong> : children}
5
5
  </td>
6
6
  )
@@ -1,5 +1,6 @@
1
- import { ReactNode } from 'react'
1
+ import { ReactNode, FC } from 'react'
2
2
  import Cell from './Cell'
3
+ import { PreliminaryDataItem } from '@cdc/chart/src/types/ChartConfig'
3
4
 
4
5
  type RowProps = {
5
6
  childRow: ReactNode[]
@@ -9,20 +10,37 @@ type RowProps = {
9
10
  cellMinWidth?: number
10
11
  fontSize: 'small' | 'medium' | 'large'
11
12
  viewport: 'lg' | 'md' | 'sm' | 'xs' | 'xxs'
13
+ style?: object
14
+ preliminaryData?: PreliminaryDataItem[]
12
15
  }
13
16
 
14
- const Row = ({ childRow, rowKey, wrapColumns, cellMinWidth = 0, isTotal, fontSize, viewport }: RowProps) => {
17
+ const Row: FC<RowProps> = props => {
18
+ const { childRow, rowKey, wrapColumns, cellMinWidth = 0, isTotal, fontSize, viewport, preliminaryData } = props
15
19
  const whiteSpace = wrapColumns ? 'unset' : 'nowrap'
16
20
  const minWidth = cellMinWidth + 'px'
17
21
  const fontSizes = { small: 16, medium: 18, large: 20 }
18
22
  const cellFontSize = ['sm', 'xs', 'xxs'].includes(viewport) ? '11px' : `${fontSizes[fontSize]}px`
23
+
19
24
  return (
20
25
  <tr>
21
- {childRow.map((child, i) => (
22
- <Cell key={rowKey + '__' + i} style={{ whiteSpace, minWidth, fontSize: cellFontSize }} isBold={isTotal}>
23
- {child}
24
- </Cell>
25
- ))}
26
+ {childRow.map((child, i) => {
27
+ const style =
28
+ (preliminaryData?.some(
29
+ pd => pd.type === 'suppression' && child === pd.iconCode && pd.displayGray && pd.displayTable
30
+ ) && { color: '#777772' }) ||
31
+ {}
32
+
33
+ return (
34
+ <Cell
35
+ ariaLabel={style?.color ? 'suppressed data' : ''}
36
+ key={rowKey + '__' + i}
37
+ style={{ whiteSpace, minWidth, fontSize: cellFontSize, ...style }}
38
+ isBold={isTotal}
39
+ >
40
+ {child}
41
+ </Cell>
42
+ )
43
+ })}
26
44
  </tr>
27
45
  )
28
46
  }
@@ -0,0 +1,17 @@
1
+ import { Meta, StoryObj } from '@storybook/react'
2
+ import Footnotes from '../Footnotes'
3
+
4
+ const meta: Meta<typeof Footnotes> = {
5
+ title: 'Components/Organisms/Footnotes',
6
+ component: Footnotes
7
+ }
8
+
9
+ export default meta
10
+
11
+ type Story = StoryObj<typeof Footnotes>
12
+
13
+ export const Primary: Story = {
14
+ args: {
15
+ footnotes: [{ symbol: '*', text: 'This is a footnote' }, { symbol: '†', text: 'This is another footnote' }, { text: 'This is a third footnote' }]
16
+ }
17
+ }
@@ -0,0 +1,91 @@
1
+ import React from 'react'
2
+ import { Meta, StoryObj } from '@storybook/react'
3
+ import './styles.scss'
4
+ import CdcChart from '@cdc/chart'
5
+ import CdcMap from '@cdc/map'
6
+ import CdcMarkupInclude from '@cdc/markup-include'
7
+ import CdcFilteredText from '@cdc/filtered-text'
8
+ import CdcDashboard from '@cdc/dashboard'
9
+ import CdcWaffleChart from '@cdc/waffle-chart'
10
+ import config from './../../../chart/src/_stories/_mock/bar-chart-suppressed.json'
11
+ import mapConfig from './../../../map/examples/default-usa.json'
12
+ import markupConfig from './../../../markup-include/src/data/initial-state.js'
13
+ import filteredTextConfig from './_mocks/filtered-text-config.json'
14
+ import waffleChartConfig from './../../../waffle-chart/examples/gallery/count.json'
15
+ import dashboardConfig from './../../../dashboard/examples/full-dashboard.json'
16
+
17
+ // Determine the component based on config.type
18
+ const getComponent = config => {
19
+ switch (config.type) {
20
+ case 'map':
21
+ return CdcMap
22
+ case 'chart':
23
+ return CdcChart
24
+ case 'markup-include':
25
+ return CdcMarkupInclude
26
+ case 'waffle-chart':
27
+ return CdcWaffleChart
28
+ case 'dashboard':
29
+ return CdcDashboard
30
+ default:
31
+ return () => <div>Unknown component type</div>
32
+ }
33
+ }
34
+
35
+ const meta = {
36
+ title: 'Components/Templates/Layout/Debug',
37
+ component: args => {
38
+ const Component = getComponent(args.config)
39
+ return (
40
+ <div className=''>
41
+ <Component {...args} />
42
+ </div>
43
+ )
44
+ }
45
+ } as Meta
46
+
47
+ export default meta
48
+
49
+ type Story = StoryObj
50
+
51
+ export const Chart: Story = {
52
+ args: {
53
+ config,
54
+ isEditor: true
55
+ }
56
+ }
57
+
58
+ export const Map: Story = {
59
+ args: {
60
+ config: mapConfig,
61
+ isEditor: true
62
+ }
63
+ }
64
+
65
+ export const MarkupInclude: StoryObj<typeof CdcMarkupInclude> = {
66
+ args: {
67
+ config: markupConfig,
68
+ isEditor: true
69
+ }
70
+ }
71
+
72
+ export const WaffleChart: StoryObj<typeof CdcWaffleChart> = {
73
+ args: {
74
+ config: waffleChartConfig,
75
+ isEditor: true
76
+ }
77
+ }
78
+
79
+ export const Dashboard: StoryObj<typeof CdcDashboard> = {
80
+ args: {
81
+ config: dashboardConfig,
82
+ isEditor: true
83
+ }
84
+ }
85
+
86
+ // export const WaffleChart: StoryObj<typeof CdcWaffleChart> = {
87
+ // args: {
88
+ // config: waffleChartConfig,
89
+ // isEditor: true
90
+ // }
91
+ // }