@cdc/core 1.1.2 → 1.1.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.
Files changed (63) hide show
  1. package/assets/alabama-graphic.svg +23 -0
  2. package/assets/check.svg +3 -0
  3. package/assets/dashboard.svg +11 -0
  4. package/assets/file-upload-solid.svg +1 -0
  5. package/assets/horizontal-stacked-bar.svg +1 -0
  6. package/assets/icon-code.svg +3 -0
  7. package/assets/icon-grid.svg +4 -0
  8. package/assets/icon-info.svg +3 -0
  9. package/assets/icon-warning.svg +3 -0
  10. package/assets/link.svg +1 -0
  11. package/assets/map-folded.svg +1 -0
  12. package/assets/paired-bar.svg +11 -0
  13. package/assets/upload-solid.svg +1 -0
  14. package/assets/usa-region-graphic.svg +393 -0
  15. package/components/AdvancedEditor.js +74 -0
  16. package/components/GlobalContext.jsx +41 -0
  17. package/components/Loading.js +3 -2
  18. package/components/elements/Button.jsx +12 -0
  19. package/components/inputs/InputCheckbox.jsx +59 -0
  20. package/components/inputs/InputSelect.jsx +49 -0
  21. package/components/inputs/InputText.jsx +68 -0
  22. package/components/inputs/InputToggle.jsx +95 -0
  23. package/components/ui/Accordion.jsx +64 -0
  24. package/components/ui/Icon.jsx +63 -0
  25. package/components/ui/Modal.jsx +87 -0
  26. package/components/ui/Overlay.jsx +84 -0
  27. package/components/ui/OverlayFrame.jsx +16 -0
  28. package/components/ui/Tooltip.jsx +55 -0
  29. package/data/colorPalettes.js +240 -0
  30. package/helpers/events.js +15 -0
  31. package/helpers/numberFromString.js +4 -3
  32. package/helpers/updatePaletteNames.js +18 -0
  33. package/helpers/validateFipsCodeLength.js +67 -0
  34. package/package.json +16 -2
  35. package/styles/_data-table.scss +8 -2
  36. package/styles/_global.scss +5 -3
  37. package/styles/v2/base/_general.scss +46 -0
  38. package/styles/v2/base/_reset.scss +81 -0
  39. package/styles/v2/base/_typography.scss +0 -0
  40. package/styles/v2/base/index.scss +3 -0
  41. package/styles/v2/components/accordion.scss +156 -0
  42. package/styles/v2/components/button.scss +178 -0
  43. package/styles/v2/components/editor.scss +487 -0
  44. package/styles/v2/components/icon.scss +23 -0
  45. package/styles/v2/components/input.scss +372 -0
  46. package/styles/v2/components/modal.scss +64 -0
  47. package/styles/v2/components/overlay.scss +80 -0
  48. package/styles/v2/layout/_alert.scss +36 -0
  49. package/styles/v2/layout/_component.scss +31 -0
  50. package/styles/v2/layout/_data-table.scss +278 -0
  51. package/styles/v2/layout/_header.scss +13 -0
  52. package/styles/v2/layout/_link.scss +46 -0
  53. package/styles/v2/layout/_progression.scss +80 -0
  54. package/styles/v2/layout/_tooltip.scss +132 -0
  55. package/styles/v2/layout/index.scss +7 -0
  56. package/styles/v2/main.scss +15 -0
  57. package/styles/v2/themes/_color-definitions.scss +129 -0
  58. package/styles/v2/themes/index.scss +1 -0
  59. package/styles/v2/utils/_animations.scss +63 -0
  60. package/styles/v2/utils/_functions.scss +0 -0
  61. package/styles/v2/utils/_mixins.scss +29 -0
  62. package/styles/v2/utils/_variables.scss +2 -0
  63. package/styles/v2/utils/index.scss +4 -0
@@ -0,0 +1,55 @@
1
+ import React from 'react'
2
+ import ReactTooltip from 'react-tooltip'
3
+
4
+ const TooltipTarget = () => null
5
+ const TooltipContent = () => null
6
+
7
+ const Tooltip = ({
8
+ position = 'top',
9
+ trigger = 'hover',
10
+ float = false,
11
+ shadow = true,
12
+ border = null,
13
+ borderColor = '#bdbdbd',
14
+ hideOnScroll = true,
15
+ children,
16
+ style,
17
+ ...attributes
18
+ }) => {
19
+
20
+ const tooltipTargetChildren = children.find(el => el.type === TooltipTarget)
21
+ const tooltipContentChildren = children.find(el => el.type === TooltipContent)
22
+
23
+ const uid = 'tooltip-' + Math.floor(Math.random() * 100000)
24
+
25
+ return (
26
+ <span className="cove-tooltip" style={style} {...attributes}>
27
+ <a className="cove-tooltip--target"
28
+ data-for={uid}
29
+ data-place={position}
30
+ data-event={trigger !== 'click' ? null : 'click focus'}
31
+ data-effect={float ? 'float' : 'solid'}
32
+ data-scroll-hide={hideOnScroll}
33
+ data-tip
34
+ >
35
+ {tooltipTargetChildren ? tooltipTargetChildren.props.children : null}
36
+ </a>
37
+ <ReactTooltip
38
+ id={uid}
39
+ className={'cove-tooltip__content' + (trigger === 'click' ? ' interactive' : '') + (border ? (' cove-tooltip--border-' + border) : '') + (shadow ? ' has-shadow' : '')}
40
+ type="light"
41
+ effect="solid"
42
+ border={!!border}
43
+ borderColor={borderColor}
44
+ globalEventOff="click"
45
+ >
46
+ {tooltipContentChildren ? tooltipContentChildren.props.children : null}
47
+ </ReactTooltip>
48
+ </span>
49
+ )
50
+ }
51
+
52
+ Tooltip.Target = TooltipTarget
53
+ Tooltip.Content = TooltipContent
54
+
55
+ export default Tooltip
@@ -0,0 +1,240 @@
1
+ import { updatePaletteNames} from "../helpers/updatePaletteNames";
2
+
3
+ const colorPalettesMap = {
4
+ yelloworangered: [
5
+ '#ffffcc',
6
+ '#ffeda0',
7
+ '#fed976',
8
+ '#feb24c',
9
+ '#fd8d3c',
10
+ '#fc4e2a',
11
+ '#e31a1c',
12
+ '#bd0026',
13
+ '#800026',
14
+ ],
15
+ yelloworangebrown: [
16
+ '#ffffe5',
17
+ '#fff7bc',
18
+ '#fee391',
19
+ '#fec44f',
20
+ '#fe9929',
21
+ '#ec7014',
22
+ '#cc4c02',
23
+ '#993404',
24
+ '#662506',
25
+ ],
26
+ pinkpurple: [
27
+ '#fff7f3',
28
+ '#fde0dd',
29
+ '#fcc5c0',
30
+ '#fa9fb5',
31
+ '#f768a1',
32
+ '#dd3497',
33
+ '#ae017e',
34
+ '#7a0177',
35
+ '#49006a',
36
+ ],
37
+ bluegreen: [
38
+ '#fff7fb',
39
+ '#ece2f0',
40
+ '#d0d1e6',
41
+ '#a6bddb',
42
+ '#67a9cf',
43
+ '#3690c0',
44
+ '#02818a',
45
+ '#016c59',
46
+ '#014636',
47
+ ],
48
+ orangered: [
49
+ '#fff7ec',
50
+ '#fee8c8',
51
+ '#fdd49e',
52
+ '#fdbb84',
53
+ '#fc8d59',
54
+ '#ef6548',
55
+ '#d7301f',
56
+ '#b30000',
57
+ '#7f0000',
58
+ ],
59
+ red: [
60
+ '#fff5f0',
61
+ '#fee0d2',
62
+ '#fcbba1',
63
+ '#fc9272',
64
+ '#fb6a4a',
65
+ '#ef3b2c',
66
+ '#cb181d',
67
+ '#a50f15',
68
+ '#67000d',
69
+ ],
70
+ greenblue: [
71
+ '#f7fcf0',
72
+ '#e0f3db',
73
+ '#ccebc5',
74
+ '#a8ddb5',
75
+ '#7bccc4',
76
+ '#4eb3d3',
77
+ '#2b8cbe',
78
+ '#0868ac',
79
+ '#084081',
80
+ ],
81
+ yellowpurple: [
82
+ '#FFF0B0',
83
+ '#F5CC76',
84
+ '#EDAE4B',
85
+ '#E3683C',
86
+ '#BF2A48',
87
+ '#6D2059',
88
+ '#8F0C4B',
89
+ '#310958',
90
+ '#0E0943',
91
+ ],
92
+ qualitative1: [
93
+ '#a6cee3',
94
+ '#1f78b4',
95
+ '#b2df8a',
96
+ '#33a02c',
97
+ '#fb9a99',
98
+ '#e31a1c',
99
+ '#6a3d9a',
100
+ '#cab2d6',
101
+ '#E31A90',
102
+ '#15017A',
103
+ '#C2C0FC',
104
+ ],
105
+
106
+ qualitative2: [
107
+ '#7fc97f',
108
+ '#beaed4',
109
+ '#ff9',
110
+ '#386cb0',
111
+ '#f0027f',
112
+ '#bf5b17',
113
+ '#666',
114
+ '#fedab8',
115
+ ],
116
+
117
+ qualitative3: [
118
+ '#1b9e77',
119
+ '#d95f02',
120
+ '#7570b3',
121
+ '#e7298a',
122
+ '#66a61e',
123
+ '#e6ab02',
124
+ '#a6761d',
125
+ '#666',
126
+ ],
127
+
128
+ qualitative4: [
129
+ '#e41a1c',
130
+ '#377eb8',
131
+ '#4daf4a',
132
+ '#984ea3',
133
+ '#ff7f00',
134
+ '#ff3',
135
+ '#a65628',
136
+ '#f781bf',
137
+ ],
138
+
139
+ qualitative9: [
140
+ '#497d0c',
141
+ '#84BC49',
142
+ '#88c3ea',
143
+ '#fcad90',
144
+ '#f26b4f',
145
+ '#c31b1f',
146
+ '#c31b1f',
147
+ ],
148
+
149
+
150
+
151
+ 'sequential-blue-2(MPX)':[
152
+ '#F5FEFF',
153
+ '#E1FBFF',
154
+ '#C0F2FD',
155
+ '#94E2ED',
156
+ '#5EBAD4',
157
+ '#3695BE',
158
+ '#2273A0',
159
+ '#0E5181',
160
+ '#093460',
161
+ ],
162
+
163
+ 'sequential-orange(MPX)':[
164
+ '#FFFDF0',
165
+ '#FFF7DC',
166
+ '#FFE9C2',
167
+ '#FFD097',
168
+ '#F7A866',
169
+ '#EB7723',
170
+ '#B95117',
171
+ '#853209',
172
+ '#661F00'
173
+ ]
174
+
175
+ };
176
+
177
+ // * ============= Palettes for Chart project ========== * //
178
+
179
+ const colorPalettes2 = {
180
+ 'qualitative-bold': [
181
+ '#377eb8',
182
+ '#ff7f00',
183
+ '#4daf4a',
184
+ '#984ea3',
185
+ '#e41a1c',
186
+ '#ffff33',
187
+ '#a65628',
188
+ '#f781bf',
189
+ '#3399CC',
190
+ ],
191
+
192
+ 'qualitative-soft': [
193
+ '#A6CEE3',
194
+ '#1F78B4',
195
+ '#B2DF8A',
196
+ '#33A02C',
197
+ '#FB9A99',
198
+ '#E31A1C',
199
+ '#FDBF6F',
200
+ '#FF7F00',
201
+ '#ACA9EB',
202
+ ],
203
+
204
+ 'sequential-blue': [
205
+ '#C6DBEF',
206
+ '#9ECAE1',
207
+ '#6BAED6',
208
+ '#4292C6',
209
+ '#2171B5',
210
+ '#084594',
211
+ ],
212
+ 'sequential-blue-2-(MPX)':[
213
+ '#D5F6F9',
214
+ '#99E2ED',
215
+ '#5FB6D1',
216
+ '#3189B0',
217
+ '#116091',
218
+ '#0A3E72'
219
+ ],
220
+ 'sequential-orange-(MPX)':[
221
+ '#FFEFCF',
222
+ '#FFD49C',
223
+ '#F7A866',
224
+ '#EB7723',
225
+ '#B95117',
226
+ '#862B0B'
227
+ ],
228
+ 'sequential-green': [
229
+ '#C7E9C0',
230
+ '#A1D99B',
231
+ '#74C476',
232
+ '#41AB5D',
233
+ '#238B45',
234
+ '#005A32',
235
+ ]
236
+ };
237
+
238
+ export const colorPalettesChart = updatePaletteNames(colorPalettes2) // adds reverse keyword to eact palette
239
+ const colorPalettes = updatePaletteNames(colorPalettesMap) // adds reverse keyword to eact palette
240
+ export default colorPalettes;
@@ -0,0 +1,15 @@
1
+
2
+ function subscribe(eventName, listener) {
3
+ document.addEventListener(eventName, listener);
4
+ }
5
+
6
+ function unsubscribe(eventName, listener) {
7
+ document.removeEventListener(eventName, listener);
8
+ }
9
+
10
+ function publish(eventName, data) {
11
+ const event = new CustomEvent(eventName, { detail: data });
12
+ document.dispatchEvent(event);
13
+ }
14
+
15
+ export { publish, subscribe, unsubscribe};
@@ -1,10 +1,11 @@
1
- export default function numberFromString(value = '') {
1
+ export default function numberFromString(value = '', state = null) {
2
2
  // Only do this to values that are ONLY numbers - without this parseFloat strips all the other text
3
- let nonNumeric = /[^\d.]/g
3
+ if (typeof value === 'string' && state?.legend?.type === 'category') return value;
4
4
 
5
+ let nonNumeric = /[^\d.-]/g
5
6
  if( false === Number.isNaN( parseFloat(value) ) && null === String(value).match(nonNumeric) ) {
6
7
  return parseFloat(value)
7
8
  }
8
9
 
9
10
  return value
10
- }
11
+ }
@@ -0,0 +1,18 @@
1
+
2
+
3
+ export function updatePaletteNames (colorPalettes){
4
+ // this function adds REVERSE keyword to each palette
5
+ delete colorPalettes.qualitative9 // delete palette before reversing
6
+ let palettereversed={}
7
+ for (const [paletteName, hexCodeArr] of Object.entries(colorPalettes)) {
8
+ const paletteStr = String(paletteName);
9
+
10
+ if (!paletteStr.endsWith('reverse') ){
11
+ let palette = paletteStr.concat('reverse'); // add to the end of the string "reverse"
12
+ palettereversed[palette] = [...hexCodeArr].reverse(); // reverses arrays elements and create new keys on object
13
+ }else{
14
+ palettereversed = {...colorPalettes}
15
+ }
16
+ }
17
+ return {...palettereversed,...colorPalettes}
18
+ }
@@ -0,0 +1,67 @@
1
+ /**
2
+ * validateFipsCodeLength
3
+ *
4
+ * When stateOrData is an object...
5
+ * This is used for validating maps fips codes during runtime where we
6
+ * In this scenario a user is able to choose the column their Fips Codes are in.
7
+ *
8
+ * When stateOrData is an array...
9
+ * The user hasn't chose which column has their FIPS codes in it. We still
10
+ * want to present the FIPS Codes in a friendly format so we attempt to add leading zeros.
11
+ *
12
+ * @param {object|array} stateOrData
13
+ * @returns {object|array} stateOrData
14
+ */
15
+ export default function validateFipsCodeLength(stateOrData) {
16
+
17
+ // FIPS are within obj.
18
+ if (!Array.isArray(stateOrData)) {
19
+ if (stateOrData.general.geoType === 'us-county' || stateOrData.general.geoType === 'single-state' || stateOrData.general.geoType === 'us' && stateOrData?.data) {
20
+
21
+ stateOrData?.data.forEach(dataPiece => {
22
+ if (dataPiece[stateOrData.columns.geo.name]) {
23
+
24
+ if (!isNaN(parseInt(dataPiece[stateOrData.columns.geo.name])) && dataPiece[stateOrData.columns.geo.name].length === 4) {
25
+ dataPiece[stateOrData.columns.geo.name] = 0 + dataPiece[stateOrData.columns.geo.name]
26
+ }
27
+ dataPiece[stateOrData.columns.geo.name] = dataPiece[stateOrData.columns.geo.name].toString()
28
+ }
29
+ })
30
+ }
31
+ }
32
+
33
+ // Only includes data - get column name from somewhere else
34
+ if (Array.isArray(stateOrData)) {
35
+
36
+ let columns = Object.keys(stateOrData[0])
37
+
38
+ let potentialColumnNames = [
39
+ 'fips',
40
+ 'FIPS',
41
+ 'fips codes',
42
+ 'FIPS CODES',
43
+ 'Fips Codes',
44
+ 'fips Codes',
45
+ 'Fips codes',
46
+ 'FIPS Codes'
47
+ ]
48
+
49
+ const fipsCol = columns.filter(columnName => potentialColumnNames.includes(columnName));
50
+
51
+ if (!fipsCol.length) return; // no column name to reference, leave the fips alone.
52
+
53
+ stateOrData?.forEach(dataPiece => {
54
+
55
+ if (dataPiece[fipsCol]) {
56
+
57
+ // specific to county fips codes.
58
+ if (!isNaN(parseInt(dataPiece[fipsCol])) && dataPiece[fipsCol].length === 4) {
59
+ dataPiece[fipsCol] = 0 + dataPiece[fipsCol]
60
+ }
61
+ dataPiece[fipsCol] = dataPiece[fipsCol].toString()
62
+ }
63
+ })
64
+ }
65
+
66
+ return stateOrData;
67
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cdc/core",
3
- "version": "1.1.2",
3
+ "version": "1.1.3",
4
4
  "description": "Core elements of the CDC Open Visualization project",
5
5
  "author": "Daniel Immke <npm@daniel.do>",
6
6
  "homepage": "https://github.com/CDCgov/cdc-open-viz#readme",
@@ -15,5 +15,19 @@
15
15
  "bugs": {
16
16
  "url": "https://github.com/CDCgov/cdc-open-viz/issues"
17
17
  },
18
- "gitHead": "8790a2336ff2453d0d6f09ecec56b5e4beaa7377"
18
+ "peerDependencies": {
19
+ "react": "^17.0.2",
20
+ "react-dom": ">=16"
21
+ },
22
+ "dependencies": {
23
+ "prop-types": "^15.8.1",
24
+ "react-accessible-accordion": "^3.3.4",
25
+ "react-select": "^5.3.1",
26
+ "react-tooltip": "4.2.8",
27
+ "use-debounce": "^6.0.1"
28
+ },
29
+ "resolutions": {
30
+ "@types/react": "17.x"
31
+ },
32
+ "gitHead": "ff89a7aea74c533413c62ef8859cc011e6b3cbfa"
19
33
  }
@@ -46,11 +46,17 @@ table.data-table {
46
46
  user-select: none;
47
47
  -moz-user-select: none;
48
48
  user-select: none;
49
+
50
+ button {
51
+ background: none;
52
+ font-size: initial;
53
+ color: #fff;
54
+ }
55
+
49
56
  tr {
50
57
  background: none;
51
58
  }
52
59
  }
53
-
54
60
  thead {
55
61
  color: #fff;
56
62
  background-color: $mediumGray;
@@ -246,4 +252,4 @@ table.data-table {
246
252
  &:hover {
247
253
  transition: .3s all;
248
254
  }
249
- }
255
+ }
@@ -85,7 +85,7 @@ strong {
85
85
  background-color: darken($red, 5%);
86
86
  }
87
87
  }
88
-
88
+
89
89
  &:hover {
90
90
  transition: .1s all;
91
91
  background: lighten(#005eaa, 5%);
@@ -100,9 +100,10 @@ strong {
100
100
  }
101
101
  }
102
102
 
103
- input[type="text"], input[role="combobox"], input[type="number"], input[type="search"], textarea {
103
+ input[type="text"], input[type="date"], input[role="combobox"], input[type="number"], input[type="search"], textarea {
104
104
  padding: .5em .5em;
105
105
  font-size: 1em;
106
+ font-weight: normal;
106
107
  font-family: sans-serif;
107
108
  border: rgba(0,0,0,.3) 1px solid !important;
108
109
  &:focus {
@@ -116,6 +117,7 @@ textarea {
116
117
  select {
117
118
  width: 100%;
118
119
  font-size: 1em;
120
+ font-weight: normal;
119
121
  text-transform: none;
120
122
  border: rgba(0, 0, 0, 0.3) 1px solid !important;
121
123
  }
@@ -164,4 +166,4 @@ select {
164
166
  font-weight: 600;
165
167
  font-size: 1.2rem;
166
168
  }
167
- }
169
+ }
@@ -0,0 +1,46 @@
1
+ .cove {
2
+ margin: 0;
3
+ font: 1em/1.6 system-ui, -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Oxygen, Ubuntu, Cantarell, Droid Sans, Helvetica Neue, Fira Sans, sans-serif;
4
+ font-weight: 400;
5
+ font-style: normal;
6
+ text-rendering: optimizeLegibility;
7
+ -webkit-font-smoothing: antialiased;
8
+ color: #111;
9
+
10
+ strong {
11
+ font-weight: 600;
12
+ }
13
+
14
+ .subtext {
15
+ margin-top: 1em;
16
+ }
17
+
18
+ .warning {
19
+ padding: .75em 1em;
20
+ margin: 1em 0;
21
+ background-color: #FFD2D2;
22
+ color: #D8000C;
23
+ font-size: .8em;
24
+ border: #D8000C 1px solid;
25
+ border-radius: .4em;
26
+
27
+ strong {
28
+ font-weight: 600;
29
+ display: block;
30
+ }
31
+ }
32
+
33
+ .sr-only,
34
+ .sr-only-focusable:not(:focus) {
35
+ position: absolute !important;
36
+ width: 1px !important;
37
+ height: 1px !important;
38
+ padding: 0 !important;
39
+ margin: -1px !important;
40
+ overflow: hidden !important;
41
+ clip: rect(0, 0, 0, 0) !important;
42
+ white-space: nowrap !important;
43
+ border: 0 !important;
44
+ display: flex;
45
+ }
46
+ }
@@ -0,0 +1,81 @@
1
+ *,
2
+ *::before,
3
+ *::after {
4
+ box-sizing: border-box;
5
+ }
6
+
7
+ body,
8
+ h1,
9
+ h2,
10
+ h3,
11
+ h4,
12
+ p,
13
+ figure,
14
+ blockquote,
15
+ dl,
16
+ dd {
17
+ margin: 0;
18
+ }
19
+
20
+ ul[role='list'],
21
+ ol[role='list'] {
22
+ list-style: none;
23
+ }
24
+
25
+ html:focus-within {
26
+ scroll-behavior: smooth;
27
+ }
28
+
29
+ body {
30
+ min-height: 100vh;
31
+ text-rendering: optimizeSpeed;
32
+ line-height: 1.5;
33
+ }
34
+
35
+ a:not([class]) {
36
+ text-decoration-skip-ink: auto;
37
+ }
38
+
39
+
40
+ img,
41
+ picture {
42
+ max-width: 100%;
43
+ display: block;
44
+ }
45
+
46
+ input,
47
+ button,
48
+ textarea,
49
+ select {
50
+ font: inherit;
51
+ }
52
+
53
+ sub, sup {
54
+ font-size: 75%;
55
+ line-height: 0;
56
+ position: relative;
57
+ vertical-align: baseline;
58
+ }
59
+
60
+ sup {
61
+ top: -0.5em;
62
+ }
63
+
64
+ sub {
65
+ bottom: -0.25em;
66
+ }
67
+
68
+ @media (prefers-reduced-motion: reduce) {
69
+ html:focus-within {
70
+ scroll-behavior: auto;
71
+ }
72
+
73
+ *,
74
+ *::before,
75
+ *::after {
76
+ animation-duration: 0.01ms !important;
77
+ animation-iteration-count: 1 !important;
78
+ transition-duration: 0.01ms !important;
79
+ scroll-behavior: auto !important;
80
+ }
81
+ }
File without changes
@@ -0,0 +1,3 @@
1
+ @import "reset";
2
+ @import "typography";
3
+ @import "general";