@cdc/core 1.1.3 → 9.22.9

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 (114) hide show
  1. package/assets/filtered-text.svg +1 -0
  2. package/assets/icon-caret-down.svg +3 -0
  3. package/assets/icon-caret-filled-down.svg +3 -0
  4. package/assets/icon-caret-filled-up.svg +3 -0
  5. package/assets/icon-caret-up.svg +3 -0
  6. package/assets/icon-chart-bar-paired.svg +15 -0
  7. package/assets/icon-chart-bar-stacked.svg +10 -0
  8. package/assets/icon-chart-bar.svg +3 -0
  9. package/assets/icon-chart-line.svg +3 -0
  10. package/assets/icon-chart-pie.svg +3 -0
  11. package/assets/icon-check.svg +3 -0
  12. package/assets/icon-close.svg +3 -1
  13. package/assets/icon-code.svg +2 -2
  14. package/assets/icon-dashboard.svg +34 -0
  15. package/assets/icon-databite.svg +3 -0
  16. package/assets/icon-edit.svg +3 -0
  17. package/assets/icon-file-upload.svg +3 -0
  18. package/assets/icon-filter-bars.svg +5 -0
  19. package/assets/icon-gear.svg +6 -0
  20. package/assets/icon-grid.svg +2 -3
  21. package/assets/icon-info.svg +1 -1
  22. package/assets/icon-link.svg +3 -0
  23. package/assets/{alabama-graphic.svg → icon-map-alabama.svg} +2 -2
  24. package/assets/icon-map-usa.svg +3 -0
  25. package/assets/icon-map-world.svg +3 -0
  26. package/assets/icon-minus.svg +3 -0
  27. package/assets/icon-move.svg +8 -0
  28. package/assets/icon-plus.svg +3 -0
  29. package/assets/icon-question-circle.svg +3 -0
  30. package/assets/icon-tools.svg +8 -0
  31. package/assets/icon-upload.svg +3 -0
  32. package/assets/icon-warning-circle.svg +3 -0
  33. package/assets/{icon-warning.svg → icon-warning-triangle.svg} +1 -1
  34. package/components/AdvancedEditor.js +1 -1
  35. package/components/{ErrorBoundary.js → ErrorBoundary.jsx} +0 -0
  36. package/components/{LegendCircle.js → LegendCircle.jsx} +0 -0
  37. package/components/{Loading.js → Loading.jsx} +0 -0
  38. package/components/{Waiting.js → Waiting.jsx} +0 -0
  39. package/components/elements/Button.jsx +122 -3
  40. package/components/elements/Card.jsx +13 -0
  41. package/components/inputs/InputCheckbox.jsx +11 -3
  42. package/components/inputs/InputGroup.jsx +50 -0
  43. package/components/inputs/InputSelect.jsx +2 -2
  44. package/components/inputs/InputText.jsx +17 -18
  45. package/components/inputs/InputToggle.jsx +18 -18
  46. package/components/managers/DataDesigner.jsx +171 -0
  47. package/components/ui/Icon.jsx +50 -12
  48. package/components/ui/LoadSpin.jsx +24 -0
  49. package/components/ui/Modal.jsx +7 -2
  50. package/components/ui/Overlay.jsx +3 -1
  51. package/components/ui/Tooltip.jsx +18 -9
  52. package/data/colorPalettes.js +170 -124
  53. package/data/dataDesignerTables.js +148 -0
  54. package/{components → helpers}/DataTransform.js +3 -3
  55. package/helpers/fetchRemoteData.js +43 -0
  56. package/package.json +3 -2
  57. package/styles/_data-table.scss +13 -13
  58. package/styles/_global.scss +14 -0
  59. package/styles/_reset.scss +11 -1
  60. package/styles/base.scss +17 -1
  61. package/styles/v2/base/_file-selector.scss +20 -0
  62. package/styles/v2/base/_general.scss +9 -22
  63. package/styles/v2/base/_heading.scss +20 -0
  64. package/styles/v2/base/_reset.scss +2 -1
  65. package/styles/v2/base/index.scss +5 -1
  66. package/styles/v2/components/button.scss +27 -66
  67. package/styles/v2/components/card.scss +7 -0
  68. package/styles/v2/components/data-designer.scss +100 -0
  69. package/styles/v2/components/editor.scss +2 -1
  70. package/styles/v2/components/guidance-block.scss +74 -0
  71. package/styles/v2/components/icon.scss +0 -4
  72. package/styles/v2/components/input/_input-check-radio.scss +97 -0
  73. package/styles/v2/components/input/_input-group.scss +74 -0
  74. package/styles/v2/components/input/_input-slider.scss +184 -0
  75. package/styles/v2/components/input/_input.scss +66 -0
  76. package/styles/v2/components/input/index.scss +7 -0
  77. package/styles/v2/components/loadspin.scss +100 -0
  78. package/styles/v2/components/modal.scss +13 -6
  79. package/styles/v2/components/overlay.scss +2 -0
  80. package/styles/v2/layout/_alert.scss +11 -10
  81. package/styles/v2/layout/_component.scss +8 -1
  82. package/styles/v2/layout/_data-table.scss +71 -150
  83. package/styles/v2/layout/_progression.scss +4 -2
  84. package/styles/v2/layout/index.scss +0 -2
  85. package/styles/v2/main.scss +52 -2
  86. package/styles/v2/themes/_color-definitions.scss +31 -1
  87. package/styles/v2/utils/_align.scss +17 -0
  88. package/styles/v2/utils/_breakpoints.scss +18 -0
  89. package/styles/v2/utils/_grid.scss +47 -0
  90. package/styles/v2/utils/_mixins.scss +0 -16
  91. package/styles/v2/utils/_spacers.scss +31 -0
  92. package/styles/v2/utils/_variables.scss +7 -0
  93. package/styles/v2/utils/index.scss +7 -2
  94. package/assets/asc.svg +0 -1
  95. package/assets/chart-bar-solid.svg +0 -1
  96. package/assets/chart-line-solid.svg +0 -1
  97. package/assets/chart-pie-solid.svg +0 -1
  98. package/assets/check.svg +0 -3
  99. package/assets/dashboard.svg +0 -11
  100. package/assets/data-bite-graphic.svg +0 -3
  101. package/assets/desc.svg +0 -1
  102. package/assets/file-upload-solid.svg +0 -1
  103. package/assets/horizontal-stacked-bar.svg +0 -1
  104. package/assets/link.svg +0 -1
  105. package/assets/minus.svg +0 -1
  106. package/assets/paired-bar.svg +0 -11
  107. package/assets/plus.svg +0 -1
  108. package/assets/question-circle.svg +0 -1
  109. package/assets/upload-solid.svg +0 -1
  110. package/assets/usa-graphic.svg +0 -3
  111. package/assets/world-graphic.svg +0 -3
  112. package/styles/v2/components/input.scss +0 -372
  113. package/styles/v2/layout/_header.scss +0 -13
  114. package/styles/v2/layout/_link.scss +0 -46
@@ -1,12 +1,12 @@
1
1
  import React, { useState, useEffect } from 'react'
2
2
  import PropTypes from 'prop-types'
3
3
 
4
- import '../../styles/v2/components/input.scss'
4
+ import '../../styles/v2/components/input/index.scss'
5
5
 
6
- const InputToggle = (
6
+ const InputSlider = (
7
7
  {
8
8
  label,
9
- toggleType = 'flat',
9
+ sliderType = 'flat',
10
10
  size = 'medium',
11
11
  activeColor = null,
12
12
  section = null,
@@ -33,14 +33,14 @@ const InputToggle = (
33
33
  return str
34
34
  }
35
35
 
36
- const toggleTypeClass = () => {
36
+ const sliderTypeClass = () => {
37
37
  const typeArr = {
38
- 'flat': ' toggle--flat',
39
- 'block': ' toggle--block',
40
- 'pill': ' toggle--pill',
41
- '3d': ' toggle--3d'
38
+ 'flat': ' slider--flat',
39
+ 'block': ' slider--block',
40
+ 'pill': ' slider--pill',
41
+ '3d': ' slider--3d'
42
42
  }
43
- return typeArr[toggleType] || ''
43
+ return typeArr[sliderType] || ''
44
44
  }
45
45
 
46
46
  useEffect(() => {
@@ -58,23 +58,23 @@ const InputToggle = (
58
58
  return (
59
59
  <div className="input-group">
60
60
  {label && <label>{label}</label>}
61
- <div className={'cove-input__toggle' + (size === 'small' ? '--small' : size === 'large' ? '--large' : '') + (toggleTypeClass()) + (value ? ' active' : '')} onClick={() => setValue(!value)}>
62
- <div className="cove-input__toggle-button"/>
63
- <div className="cove-input__toggle-track" style={value && activeColor ? { backgroundColor: activeColor } : null }/>
61
+ <div className={'cove-input__slider' + (size === 'small' ? '--small' : size === 'large' ? '--large' : '') + (sliderTypeClass()) + (value ? ' active' : '')} onClick={() => setValue(!value)}>
62
+ <div className="cove-input__slider-button"/>
63
+ <div className="cove-input__slider-track" style={value && activeColor ? { backgroundColor: activeColor } : null }/>
64
64
  <input className="cove-input--hidden" type="checkbox" name={name()} checked={value || false} readOnly/>
65
65
  </div>
66
66
  </div>
67
67
  )
68
68
  }
69
69
 
70
- InputToggle.propTypes = {
70
+ InputSlider.propTypes = {
71
71
  /** Add label to the input field */
72
72
  label: PropTypes.string,
73
- /** Select the preferred display style of the toggle slider */
74
- toggleType: PropTypes.oneOf(['flat', 'block', 'pill', '3d']),
75
- /** Select the preferred size of the toggle slider */
73
+ /** Select the preferred display style of the slider */
74
+ sliderType: PropTypes.oneOf(['flat', 'block', 'pill', '3d']),
75
+ /** Select the preferred size of the slider */
76
76
  size: PropTypes.oneOf(['small', 'medium', 'large']),
77
- /** Select the preferred color for the toggle slider when active */
77
+ /** Select the preferred color for the slider when active */
78
78
  activeColor: PropTypes.string,
79
79
  /** Parent key value of nested target config option
80
80
  *
@@ -92,4 +92,4 @@ InputToggle.propTypes = {
92
92
  stateValue: PropTypes.object
93
93
  }
94
94
 
95
- export default InputToggle
95
+ export default InputSlider
@@ -0,0 +1,171 @@
1
+ import React from 'react'
2
+
3
+ import Button from '../elements/Button'
4
+ import Card from '../elements/Card'
5
+
6
+ import { DATA_TABLE_VERTICAL, DATA_TABLE_HORIZONTAL, DATA_TABLE_SINGLE_ROW, DATA_TABLE_MULTI_ROW } from '../../data/dataDesignerTables'
7
+ import '../../styles/v2/components/data-designer.scss'
8
+
9
+ const DataDesigner = (props) => {
10
+ const { configureData, updateDescriptionProp, visualizationKey, dataKey } = props;
11
+
12
+ return (
13
+ <div className="cove-data-designer__container">
14
+ <div className="mb-2">
15
+ <div className="cove-heading--3 fw-bold mb-1">Describe Data</div>
16
+ <div className="cove-heading--3 fw-normal mb-1">Data Orientation</div>
17
+ <div className="grid grid-gap-2 mb-4">
18
+ <div className="column">
19
+ <button
20
+ className={'cove-data-designer__button' + (configureData.dataDescription && configureData.dataDescription.horizontal === false ? ' active' : '')}
21
+ onClick={() => {
22
+ updateDescriptionProp(visualizationKey, dataKey, 'horizontal', false)
23
+ }}>
24
+ <Card>
25
+ <strong className="cove-heading--3">Vertical</strong>
26
+ <p className="mb-1">Values for map geography or chart date/category axis are contained in a
27
+ single <em>column</em>.
28
+ </p>
29
+ {DATA_TABLE_VERTICAL}
30
+ </Card>
31
+ </button>
32
+ </div>
33
+ <div className="column">
34
+ <button
35
+ className={'cove-data-designer__button' + (configureData.dataDescription && configureData.dataDescription.horizontal === true ? ' active' : '')}
36
+ onClick={() => {
37
+ updateDescriptionProp(visualizationKey, dataKey, 'horizontal', true)
38
+ }}>
39
+ <Card>
40
+ <strong className="cove-heading--3">Horizontal</strong>
41
+ <p className="mb-1">Values for map geography or chart date/category axis are contained in a single <em>row</em>
42
+ </p>
43
+ {DATA_TABLE_HORIZONTAL}
44
+ </Card>
45
+ </button>
46
+ </div>
47
+ </div>
48
+ </div>
49
+ {configureData.dataDescription && (
50
+ <>
51
+ <div className="mb-2">
52
+ <div className="mb-1">Are there multiple series represented in your data?</div>
53
+ <div>
54
+ <Button
55
+ style={{ backgroundColor: '#00345d' }}
56
+ hoverStyle={{ backgroundColor: '#015daa' }}
57
+ className="mr-1"
58
+ onClick={() => {
59
+ updateDescriptionProp(visualizationKey, dataKey, 'series', true)
60
+ }}
61
+ active={configureData.dataDescription.series === true}
62
+ >
63
+ Yes
64
+ </Button>
65
+ <Button
66
+ style={{ backgroundColor: '#00345d' }}
67
+ hoverStyle={{ backgroundColor: '#015daa' }}
68
+ onClick={() => {
69
+ updateDescriptionProp(visualizationKey, dataKey, 'series', false)
70
+ }}
71
+ active={configureData.dataDescription.series === false}
72
+ >
73
+ No
74
+ </Button>
75
+ </div>
76
+ </div>
77
+ {configureData.dataDescription.horizontal === true && configureData.dataDescription.series === true && (
78
+ <div className="mb-2">
79
+ <div className="mb-1">Which property in the dataset represents which series the row is describing?</div>
80
+ <select onChange={(e) => {
81
+ updateDescriptionProp(visualizationKey, dataKey, 'seriesKey', e.target.value)
82
+ }} defaultValue={configureData.dataDescription.seriesKey}>
83
+ <option value="">Choose an option</option>
84
+ {Object.keys(configureData.data[0]).map((value, index) => <option value={value} key={index}>{value}</option>)}
85
+ </select>
86
+ </div>
87
+ )}
88
+ {configureData.dataDescription.horizontal === false && configureData.dataDescription.series === true && (
89
+ <>
90
+ <div className="mb-2">
91
+ <div className="mb-1">Are the series values in your data represented in a
92
+ single row, or across multiple rows?
93
+ </div>
94
+ <div className="grid grid-gap-2 mb-4">
95
+ <div className="column">
96
+ <button
97
+ className={'cove-data-designer__button' + (configureData.dataDescription.singleRow === true ? ' active' : '')}
98
+ onClick={() => {
99
+ updateDescriptionProp(visualizationKey, dataKey, 'singleRow', true)
100
+ }}>
101
+ <Card>
102
+ <strong className="cove-heading--3">Single Row</strong>
103
+ <p className="mb-1">Each row contains the data for an individual series in itself.</p>
104
+ {DATA_TABLE_SINGLE_ROW}
105
+ </Card>
106
+ </button>
107
+ </div>
108
+ <div className="column">
109
+ <button
110
+ className={'cove-data-designer__button' + (configureData.dataDescription.singleRow === false ? ' active' : '')}
111
+ onClick={() => {
112
+ updateDescriptionProp(visualizationKey, dataKey, 'singleRow', false)
113
+ }}>
114
+ <Card>
115
+ <strong className="cove-heading--3">Multiple Rows</strong>
116
+ <p className="mb-1">Each series data is broken out into multiple rows.</p>
117
+ {DATA_TABLE_MULTI_ROW}
118
+ </Card>
119
+ </button>
120
+ </div>
121
+ </div>
122
+ </div>
123
+ {configureData.dataDescription.singleRow === false && (
124
+ <>
125
+ <div className="mb-2">
126
+ <div className="mb-1">Which property in the dataset represents which series the row is describing?</div>
127
+ <select onChange={(e) => {
128
+ updateDescriptionProp(visualizationKey, dataKey, 'seriesKey', e.target.value)
129
+ }} defaultValue={configureData.dataDescription.seriesKey}>
130
+ <option value="">Choose an option</option>
131
+ {Object.keys(configureData.data[0]).map((value, index) => (
132
+ <option value={value} key={index}>{value}</option>
133
+ ))}
134
+ </select>
135
+ </div>
136
+ <div className="mb-2">
137
+ <div className="mb-1">Which property in the dataset represents the values for the category/date axis or map geography?</div>
138
+ <select onChange={(e) => {
139
+ updateDescriptionProp(visualizationKey, dataKey, 'xKey', e.target.value)
140
+ }} defaultValue={configureData.dataDescription.xKey}>
141
+ <option value="">Choose an option</option>
142
+ {Object.keys(configureData.data[0]).map((value, index) => (
143
+ <option value={value} key={index}>{value}</option>
144
+ ))}
145
+ </select>
146
+ </div>
147
+ <div className="mb-2">
148
+ <div className="mb-1">Which property in the dataset represents the numeric value?</div>
149
+ <select onChange={(e) => {
150
+ updateDescriptionProp(visualizationKey, dataKey, 'valueKey', e.target.value)
151
+ }} defaultValue={configureData.dataDescription.valueKey}>
152
+ <option value="">Choose an option</option>
153
+ {Object.keys(configureData.data[0]).map((value, index) => (
154
+ <option value={value} key={index}>{value}</option>
155
+ ))}
156
+ </select>
157
+ </div>
158
+ </>
159
+ )}
160
+ </>
161
+ )}
162
+ </>
163
+ )}
164
+ {configureData.dataDescription && configureData.formattedData && (
165
+ <div>Data configured successfully</div>
166
+ )}
167
+ </div>
168
+ )
169
+ }
170
+
171
+ export default DataDesigner
@@ -1,24 +1,62 @@
1
1
  import React from 'react'
2
2
  import PropTypes from 'prop-types'
3
3
 
4
+ import iconCaretUp from '../../assets/icon-caret-up.svg'
5
+ import iconCaretDown from '../../assets/icon-caret-down.svg'
6
+ import iconCaretFilledUp from '../../assets/icon-caret-filled-up.svg'
7
+ import iconCaretFilledDown from '../../assets/icon-caret-filled-down.svg'
8
+ import iconChartBar from '../../assets/icon-chart-bar.svg'
9
+ import iconChartLine from '../../assets/icon-chart-line.svg'
10
+ import iconChartPie from '../../assets/icon-chart-pie.svg'
4
11
  import iconClose from '../../assets/icon-close.svg'
5
- import iconQuestion from '../../assets/question-circle.svg'
6
- import iconLink from '../../assets/link.svg'
7
- import iconUpload from '../../assets/upload-solid.svg'
8
- import iconFileUpload from '../../assets/file-upload-solid.svg'
9
- import iconWarning from '../../assets/icon-warning.svg'
12
+ import iconCode from '../../assets/icon-code.svg'
13
+ import iconDataBite from '../../assets/icon-databite.svg'
14
+ import iconEdit from '../../assets/icon-edit.svg'
15
+ import iconFileUpload from '../../assets/icon-file-upload.svg'
16
+ import iconFilterBars from '../../assets/icon-filter-bars.svg'
17
+ import iconGrid from '../../assets/icon-grid.svg'
10
18
  import iconInfo from '../../assets/icon-info.svg'
19
+ import iconLink from '../../assets/icon-link.svg'
20
+ import iconMapAl from '../../assets/icon-map-alabama.svg'
21
+ import iconMapUsa from '../../assets/icon-map-usa.svg'
22
+ import iconMapWorld from '../../assets/icon-map-world.svg'
23
+ import iconMove from '../../assets/icon-move.svg'
24
+ import iconQuestion from '../../assets/icon-question-circle.svg'
25
+ import iconUpload from '../../assets/icon-upload.svg'
26
+ import iconWarningCircle from '../../assets/icon-warning-circle.svg'
27
+ import iconWarningTriangle from '../../assets/icon-warning-triangle.svg'
28
+ import iconGear from '../../assets/icon-gear.svg'
29
+ import iconTools from '../../assets/icon-tools.svg'
11
30
 
12
31
  import '../../styles/v2/components/icon.scss'
13
32
 
14
33
  const iconHash = {
15
- "close": iconClose,
16
- "question": iconQuestion,
17
- "link": iconLink,
18
- "upload": iconUpload,
19
- "fileUpload": iconFileUpload,
20
- "warning": iconWarning,
21
- "info": iconInfo
34
+ 'caretUp': iconCaretUp,
35
+ 'caretDown': iconCaretDown,
36
+ 'caretFilledUp': iconCaretFilledUp,
37
+ 'caretFilledDown': iconCaretFilledDown,
38
+ 'chartBar': iconChartBar,
39
+ 'chartLine': iconChartLine,
40
+ 'chartPie': iconChartPie,
41
+ 'close': iconClose,
42
+ 'code': iconCode,
43
+ 'databite': iconDataBite,
44
+ 'edit': iconEdit,
45
+ 'fileUpload': iconFileUpload,
46
+ 'filterBars': iconFilterBars,
47
+ 'grid': iconGrid,
48
+ 'info': iconInfo,
49
+ 'link': iconLink,
50
+ 'mapAl': iconMapAl,
51
+ 'mapUsa': iconMapUsa,
52
+ 'mapWorld': iconMapWorld,
53
+ 'move': iconMove,
54
+ 'question': iconQuestion,
55
+ 'upload': iconUpload,
56
+ 'warningCircle': iconWarningCircle,
57
+ 'warningTriangle': iconWarningTriangle,
58
+ 'gear': iconGear,
59
+ 'tools': iconTools
22
60
  }
23
61
 
24
62
  const Icon = ({ display = null, base, alt = '', size, color, style, ...attributes }) => {
@@ -0,0 +1,24 @@
1
+ import React from 'react'
2
+ import '../../styles/v2/components/loadspin.scss'
3
+
4
+ const LoadSpin = ({
5
+ color = '#fff',
6
+ opacity = 100,
7
+ size = 100,
8
+ className
9
+ }) => {
10
+ const n = 8
11
+ return (
12
+ <>
13
+ <div className={`cove-loadspin${className ? ' ' + className : ''}`} style={{width: size, height: size}}>
14
+ <div className="cove-loadspin__roller" style={{opacity: opacity / 100, transform: `scale(${size/80})`}}>
15
+ {
16
+ [...Array(n)].map((elem, index) => <div key={index} style={{backgroundColor: color}}/>)
17
+ }
18
+ </div>
19
+ </div>
20
+ </>
21
+ )
22
+ }
23
+
24
+ export default LoadSpin
@@ -42,12 +42,17 @@ const Modal = ({
42
42
  <div className="cove-modal__header" style={{
43
43
  backgroundColor: headerBgColor,
44
44
  boxShadow: dividerBorder(modalHeaderChildren && showDividerTop),
45
- padding: !modalHeaderChildren ? '0' : null
45
+ padding: !modalHeaderChildren ? '0' : null,
46
+ minHeight: !modalHeaderChildren ? 'unset' : null
46
47
  }}>
47
48
  {modalHeaderChildren && modalHeaderChildren.props.children}
48
49
  {showClose &&
49
50
  <button className="cove-modal--close"
50
- onClick={(e) => override ? override.actions.toggleOverlay(false) : overlay ? overlay?.actions.toggleOverlay(false) : e.preventDefault()}>
51
+ onClick={(e) => {
52
+ if (override) return override.actions.toggleOverlay(false)
53
+ if (overlay) return overlay?.actions.toggleOverlay(false)
54
+ e.preventDefault()
55
+ }}>
51
56
  <Icon display="close"/>
52
57
  </button>
53
58
  }
@@ -13,10 +13,11 @@ const Overlay = ({ disableBgClose, children, override = null }) => {
13
13
  const [ overlayAnimationState, setOverlayAnimationState ] = useState(null)
14
14
  const [ overlayErrorState, setOverlayErrorState ] = useState(false)
15
15
 
16
- const overlayDisplay = overlay?.show || override?.show
16
+ const overlayDisplay = override ? override?.show : overlay?.show
17
17
 
18
18
  //Animate In effect
19
19
  useEffect(() => {
20
+ if (overlayDisplay === undefined) return
20
21
  if (overlayDisplay === false) return //Reject
21
22
 
22
23
  document.body.style.overflow = 'hidden'
@@ -32,6 +33,7 @@ const Overlay = ({ disableBgClose, children, override = null }) => {
32
33
 
33
34
  //Animate Out effect
34
35
  useEffect(() => {
36
+ if (overlayDisplay === undefined) return
35
37
  if (overlayDisplay === true) return //Reject
36
38
 
37
39
  setOverlayAnimationState('animate-out')
@@ -6,7 +6,7 @@ const TooltipContent = () => null
6
6
 
7
7
  const Tooltip = ({
8
8
  position = 'top',
9
- trigger = 'hover',
9
+ trigger = 'hover focus',
10
10
  float = false,
11
11
  shadow = true,
12
12
  border = null,
@@ -20,20 +20,29 @@ const Tooltip = ({
20
20
  const tooltipTargetChildren = children.find(el => el.type === TooltipTarget)
21
21
  const tooltipContentChildren = children.find(el => el.type === TooltipContent)
22
22
 
23
+
23
24
  const uid = 'tooltip-' + Math.floor(Math.random() * 100000)
24
25
 
25
26
  return (
26
27
  <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
28
+ <button className="cove-tooltip--target"
29
+ data-for={uid}
30
+ data-place={position}
31
+ data-event={trigger}
32
+ data-effect={float ? 'float' : 'solid'}
33
+ data-scroll-hide={hideOnScroll}
34
+ data-tip
35
+ onClick={e => {
36
+ e.preventDefault()
37
+ }}
38
+ onMouseEnter={ e => ReactTooltip.show(e.target)}
39
+ onMouseLeave={e => ReactTooltip.hide(e.target)}
40
+ onFocus={(e) => ReactTooltip.show(e.target)}
41
+ onBlur={(e) => ReactTooltip.hide(e.target)}
42
+ style={{ background: 'transparent', border: 'none' }}
34
43
  >
35
44
  {tooltipTargetChildren ? tooltipTargetChildren.props.children : null}
36
- </a>
45
+ </button>
37
46
  <ReactTooltip
38
47
  id={uid}
39
48
  className={'cove-tooltip__content' + (trigger === 'click' ? ' interactive' : '') + (border ? (' cove-tooltip--border-' + border) : '') + (shadow ? ' has-shadow' : '')}