@spothero/ui 15.1.0 → 15.1.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 (85) hide show
  1. package/package.json +2 -3
  2. package/styles/Alert/Alert.jsx +0 -45
  3. package/styles/Alert/Alert.spec.js +0 -85
  4. package/styles/AutoSuggestInput/AutoSuggestInput.jsx +0 -429
  5. package/styles/AutoSuggestInput/AutoSuggestInput.spec.js +0 -132
  6. package/styles/AutoSuggestInput/AutoSuggestItem.jsx +0 -61
  7. package/styles/AutoSuggestInput/AutoSuggestList.jsx +0 -85
  8. package/styles/Badge/Badge.jsx +0 -24
  9. package/styles/Badge/Badge.spec.js +0 -43
  10. package/styles/Chart/Chart.jsx +0 -185
  11. package/styles/Chart/Chart.spec.js +0 -369
  12. package/styles/Checkbox/Checkbox.jsx +0 -159
  13. package/styles/Checkbox/Checkbox.spec.js +0 -142
  14. package/styles/DateTime/DatePicker.jsx +0 -281
  15. package/styles/DateTime/DatePicker.spec.js +0 -186
  16. package/styles/DateTime/DatePickerCalendar.jsx +0 -170
  17. package/styles/DateTime/DatePickerCalendarNavigation.jsx +0 -44
  18. package/styles/DateTime/DatePickerCalendarWithRange.jsx +0 -218
  19. package/styles/DateTime/DateTimePicker.jsx +0 -266
  20. package/styles/DateTime/DateTimePicker.spec.js +0 -60
  21. package/styles/DateTime/DateTimeRangePicker.jsx +0 -629
  22. package/styles/DateTime/DateTimeRangePicker.spec.js +0 -425
  23. package/styles/DateTime/TimePicker.jsx +0 -158
  24. package/styles/DateTime/TimePicker.spec.js +0 -148
  25. package/styles/DateTime/date-time-assertions.js +0 -89
  26. package/styles/DateTime/index.js +0 -6
  27. package/styles/ErrorBoundary/ErrorBoundary.jsx +0 -76
  28. package/styles/ErrorBoundary/ErrorBoundary.spec.js +0 -72
  29. package/styles/Flyout/Flyout.jsx +0 -147
  30. package/styles/Flyout/Flyout.spec.js +0 -117
  31. package/styles/Form/Form.jsx +0 -151
  32. package/styles/Form/Form.spec.js +0 -148
  33. package/styles/Form/FormElementError.jsx +0 -18
  34. package/styles/Form/FormGroup.jsx +0 -32
  35. package/styles/Form/FormGroupError.jsx +0 -24
  36. package/styles/Form/index.js +0 -4
  37. package/styles/GooglePlacesSearchInput/GooglePlacesSearchInput.jsx +0 -215
  38. package/styles/GooglePlacesSearchInput/GooglePlacesSearchInput.spec.js +0 -213
  39. package/styles/GooglePlacesSearchInput/PoweredByGoogle.jsx +0 -43
  40. package/styles/GooglePlacesSearchInput/index.js +0 -2
  41. package/styles/HorizontalRule/HorizontalRule.jsx +0 -36
  42. package/styles/HorizontalRule/HorizontalRule.spec.js +0 -94
  43. package/styles/Label/Label.jsx +0 -22
  44. package/styles/Label/Label.spec.js +0 -11
  45. package/styles/Notification/Notification.jsx +0 -117
  46. package/styles/Notification/Notification.spec.js +0 -154
  47. package/styles/Notification/NotificationContainer.jsx +0 -90
  48. package/styles/Notification/NotificationPropTypes.js +0 -20
  49. package/styles/Notification/index.js +0 -2
  50. package/styles/PasswordControl/PasswordControl.jsx +0 -197
  51. package/styles/PasswordControl/PasswordControl.spec.js +0 -236
  52. package/styles/Portal/Portal.jsx +0 -65
  53. package/styles/Portal/Portal.spec.js +0 -45
  54. package/styles/PulseLoader/PulseLoader.jsx +0 -71
  55. package/styles/PulseLoader/PulseLoader.spec.js +0 -63
  56. package/styles/Radio/Radio.jsx +0 -114
  57. package/styles/Radio/Radio.spec.js +0 -128
  58. package/styles/Radio/RadioGroup.jsx +0 -105
  59. package/styles/Radio/index.js +0 -2
  60. package/styles/RenderInBody/RenderInBody.jsx +0 -56
  61. package/styles/RenderInBody/RenderInBody.spec.js +0 -24
  62. package/styles/Select/Select.jsx +0 -251
  63. package/styles/Select/Select.spec.js +0 -254
  64. package/styles/Select/SelectItemPropTypes.js +0 -19
  65. package/styles/Select/index.js +0 -2
  66. package/styles/SelectControlled/SelectControlled.jsx +0 -250
  67. package/styles/SelectControlled/SelectControlled.spec.js +0 -290
  68. package/styles/SelectControlled/index.js +0 -1
  69. package/styles/Sprite/Sprite.jsx +0 -16
  70. package/styles/Sprite/Sprite.spec.js +0 -11
  71. package/styles/Tabs/Tab.jsx +0 -38
  72. package/styles/Tabs/TabContent.jsx +0 -46
  73. package/styles/Tabs/TabNavigation.jsx +0 -64
  74. package/styles/Tabs/TabPanel.jsx +0 -30
  75. package/styles/Tabs/Tabs.jsx +0 -87
  76. package/styles/Tabs/Tabs.spec.js +0 -201
  77. package/styles/Tabs/index.js +0 -5
  78. package/styles/TextArea/TextArea.jsx +0 -137
  79. package/styles/TextArea/TextArea.spec.js +0 -111
  80. package/styles/TextInput/TextInput.jsx +0 -159
  81. package/styles/TextInput/TextInput.spec.js +0 -263
  82. package/styles/TextInput/TextInputPropTypes.js +0 -88
  83. package/styles/TextInput/index.js +0 -2
  84. package/styles/Tooltip/Tooltip.jsx +0 -230
  85. package/styles/Tooltip/Tooltip.spec.js +0 -170
@@ -1,263 +0,0 @@
1
- describe('<TextInput />', () => {
2
- context('Display', () => {
3
- context('Default', () => {
4
- it('Should have placeholder, default value, label, help text, and custom class names', () => {
5
- cy.visitStory('v1/TextInput/Display', 'Default')
6
- .get('.TextInput')
7
- .should('exist')
8
- .and('have.class', 'custom-class1')
9
- .and('have.class', 'custom-class2')
10
- .find('input')
11
- .should('have.attr', 'name', 'license-plate')
12
- .and('have.attr', 'placeholder', 'License Plate')
13
- .and('have.value', 'ECTO-1')
14
- .get('.TextInput')
15
- .find('.Label')
16
- .contains('Add new license plate')
17
- .get('.TextInput')
18
- .find('.FormElement-help-text')
19
- .contains('Additional help node text');
20
- });
21
- });
22
-
23
- context('Disabled', () => {
24
- it('Is disabled', () => {
25
- cy.visitStory('v1/TextInput/Display', 'Disabled')
26
- .get('.TextInput')
27
- .find('input')
28
- .should('be.disabled');
29
- });
30
- });
31
-
32
- context('Read Only', () => {
33
- it('Is read only', () => {
34
- cy.visitStory('v1/TextInput/Display', 'ReadOnly')
35
- .get('.TextInput')
36
- .find('input')
37
- .should('have.attr', 'readonly');
38
- });
39
- });
40
-
41
- context('Icon', () => {
42
- it('Should render with an icon', () => {
43
- cy.visitStory('v1/TextInput/Display', 'Icon')
44
- .get('.TextInput')
45
- .should('have.class', 'FormElement-with-icon-right')
46
- .find('.Icon')
47
- .should('exist');
48
- });
49
- });
50
-
51
- context('Loading', () => {
52
- it('Should render with a loading spinner', () => {
53
- cy.visitStory('v1/TextInput/Display', 'Loading')
54
- .get('.TextInput')
55
- .find('.Loader')
56
- .should('exist');
57
- });
58
- });
59
-
60
- context('Inline', () => {
61
- it('Should render with inline styling', () => {
62
- cy.visitStory('v1/TextInput/Display', 'Inline')
63
- .get('.TextInput')
64
- .should('have.class', 'FormElement-inline');
65
- });
66
- });
67
-
68
- context('Auto Focus', () => {
69
- it('Receives focus after rendered', () => {
70
- cy.visitStory('v1/TextInput/Display', 'AutoFocus')
71
- .focused()
72
- .should('have.attr', 'name', 'license-plate');
73
- });
74
- });
75
- });
76
-
77
- context('Formatting', () => {
78
- describe('Mask', () => {
79
- it('Applies a mask over the input text', () => {
80
- cy.visitStory('v1/TextInput/Formatting', 'Mask')
81
- .get('.TextInput')
82
- .find('input')
83
- .click()
84
- .should('have.value', '+X-XXX-XXX-XXXX')
85
- .type('12345678899', {delay: 0})
86
- .blur()
87
- .should('have.value', '+1-234-567-8899');
88
- });
89
- });
90
-
91
- describe('Pattern', () => {
92
- it('Has pattern attribute and ensures the input text follows the specified regex pattern', () => {
93
- cy.visitStory('v1/TextInput/Formatting', 'Pattern')
94
- .get('.TextInput')
95
- .find('input')
96
- .should('have.attr', 'pattern', '[A-Za-z0-9]+')
97
- // should show error since value does not follow pattern
98
- .type('OÜTAT!M&', {delay: 0})
99
- .get('button[type=submit]')
100
- .click()
101
- .get('.TextInput')
102
- .find('.FormElementError')
103
- .should('exist')
104
- // should not show error since value follows pattern
105
- .get('.TextInput')
106
- .find('input')
107
- .clear()
108
- .type('oUtAT1M3', {delay: 0})
109
- .get('button[type=submit]')
110
- .click()
111
- .get('.TextInput')
112
- .find('.FormElementError')
113
- .should('not.exist');
114
- });
115
- });
116
-
117
- context('Max Length', () => {
118
- it('Has maxlength attribute and does not allow more characters', () => {
119
- // longstring is 53 characters long
120
- const longstring =
121
- 'myusernamemyusernamemyusernamemyusernamemyusernameabc';
122
-
123
- cy.visitStory('v1/TextInput/Formatting', 'MaxLength')
124
- .get('.TextInput')
125
- .find('input')
126
- .should('have.attr', 'maxlength', '50')
127
- .type(longstring, {delay: 0})
128
- .should('have.value', longstring.substring(0, 50));
129
- });
130
- });
131
-
132
- context('Min Max', () => {
133
- it('Has min and max attributes and does not consider input outside that range valid', () => {
134
- cy.visitStory('v1/TextInput/Formatting', 'MinMax')
135
- .get('.TextInput')
136
- .find('input')
137
- .should('have.attr', 'min', '1')
138
- .should('have.attr', 'max', '100')
139
- // should show error since value is below min
140
- .type('0', {delay: 0})
141
- .get('button[type=submit]')
142
- .click()
143
- .get('.TextInput')
144
- .find('.FormElementError')
145
- .should('exist')
146
- // should not show error since value is in range
147
- .get('.TextInput')
148
- .find('input')
149
- .clear()
150
- .type('42', {delay: 0})
151
- .get('button[type=submit]')
152
- .click()
153
- .get('.TextInput')
154
- .find('.FormElementError')
155
- .should('not.exist')
156
- // should show error since value is above max
157
- .get('.TextInput')
158
- .find('input')
159
- .clear()
160
- .type('4200', {delay: 0})
161
- .get('button[type=submit]')
162
- .click()
163
- .get('.TextInput')
164
- .find('.FormElementError')
165
- .should('exist');
166
- });
167
- });
168
- });
169
-
170
- context('Methods', () => {
171
- describe('On Change', () => {
172
- it('Executes the method when a change is detected', () => {
173
- cy.visitStory('v1/TextInput/Methods', 'OnChange', {
174
- onBeforeLoad: contentWindow => {
175
- contentWindow.onTextInputChange = evt => {
176
- console.log(`onTextInputChange`); // eslint-disable-line no-console
177
- };
178
-
179
- cy.stub(contentWindow, 'onTextInputChange').as(
180
- 'onTextInputChange'
181
- );
182
- },
183
- })
184
- .get('.TextInput')
185
- .find('input')
186
- .type('OUTATIME', {delay: 0})
187
- .get('@onTextInputChange')
188
- .should('be.called');
189
- });
190
- });
191
-
192
- describe('On Focus', () => {
193
- it('Executes the method when input is focused on', () => {
194
- cy.visitStory('v1/TextInput/Methods', 'OnFocus', {
195
- onBeforeLoad: contentWindow => {
196
- contentWindow.onTextInputFocus = evt => {
197
- console.log(`onTextInputFocus`); // eslint-disable-line no-console
198
- };
199
-
200
- cy.stub(contentWindow, 'onTextInputFocus').as(
201
- 'onTextInputFocus'
202
- );
203
- },
204
- })
205
- .get('.TextInput')
206
- .find('input')
207
- .focus()
208
- .get('@onTextInputFocus')
209
- .should('be.called');
210
- });
211
- });
212
-
213
- describe('On Blur', () => {
214
- it('Executes the method when input loses focus', () => {
215
- cy.visitStory('v1/TextInput/Methods', 'OnBlur', {
216
- onBeforeLoad: contentWindow => {
217
- contentWindow.onTextInputBlur = evt => {
218
- console.log(`onTextInputBlur`); // eslint-disable-line no-console
219
- };
220
-
221
- cy.stub(contentWindow, 'onTextInputBlur').as(
222
- 'onTextInputBlur'
223
- );
224
- },
225
- })
226
- .get('.TextInput')
227
- .find('input')
228
- .focus()
229
- .get('@onTextInputBlur')
230
- .should('not.be.called')
231
- .get('.TextInput')
232
- .find('input')
233
- .blur()
234
- .get('@onTextInputBlur')
235
- .should('be.called');
236
- });
237
- });
238
-
239
- describe('On Invalid', () => {
240
- it('Displays an error if the input is invalid', () => {
241
- cy.visitStory('v1/TextInput/Methods', 'OnInvalid')
242
- .get('.TextInput')
243
- .find('input')
244
- // Show error on empty field since this is required
245
- .should('have.value', '')
246
- .get('button[type=submit]')
247
- .click()
248
- .get('.TextInput')
249
- .find('.FormElementError')
250
- .should('exist')
251
- // Don't show error on field with content
252
- .get('.TextInput')
253
- .find('input')
254
- .type('MY PRSHE', {delay: 0})
255
- .get('button[type=submit]')
256
- .click()
257
- .get('.TextInput')
258
- .find('.FormElementError')
259
- .should('not.exist');
260
- });
261
- });
262
- });
263
- });
@@ -1,88 +0,0 @@
1
- import PropTypes from 'prop-types';
2
-
3
- const TextInputPropTypes = {
4
- /** Additional class(es) to add to the component. */
5
- className: PropTypes.string,
6
- /** A unique name which is used to identify this element. If belonging to a form this is used as the key for serialization and is required. */
7
- name: PropTypes.string,
8
- /** What HTML input type the underlying input should be set to. */
9
- type: PropTypes.oneOf([
10
- 'text',
11
- 'password',
12
- 'date',
13
- 'email',
14
- 'time',
15
- 'tel',
16
- 'search',
17
- 'number',
18
- 'hidden',
19
- ]),
20
- /** Text to display in the field before a user starts to type in the input. */
21
- placeholder: PropTypes.string,
22
- /** A custom label (typically a Label component) to display above the input. */
23
- label: PropTypes.element,
24
- /** A regular expression that the input value is checked against for validation. */
25
- pattern: PropTypes.string,
26
- /** Whether this field is required during validation. */
27
- required: PropTypes.bool,
28
- /** Disallows user interaction. */
29
- disabled: PropTypes.bool,
30
- /** Whether to show a loading animation inside of the component. */
31
- loading: PropTypes.bool,
32
- /** Whether the field should be auto focused when mounted. */
33
- autoFocus: PropTypes.bool,
34
- /** Whether the field should be focused when the component receives new props. */
35
- focus: PropTypes.bool,
36
- /** A custom validation error (typically a FormElementError component) to display when this component is part of a form and is invalid. */
37
- error: PropTypes.element,
38
- /** The default value to display in the input when mounted. */
39
- defaultValue: PropTypes.string,
40
- /** A custom icon (typically an Icon component) to show in the input field. */
41
- icon: PropTypes.element,
42
- /** If an icon is provided, whether it should appear on the left or right side of the input field. */
43
- iconPosition: PropTypes.oneOf(['left', 'right']),
44
- /** A custom help element to place below the input. */
45
- helpNode: PropTypes.node,
46
- /** Applies proper styling to display this field inline in a form. */
47
- inline: PropTypes.bool,
48
- /** Specifies that the input field is read-only. */
49
- readOnly: PropTypes.bool,
50
- /** Specifies the maximum number of characters allowed. */
51
- maxLength: PropTypes.number,
52
- /** Specifies the minimum value when type is `date` or `number`. */
53
- min: PropTypes.number,
54
- /** Specifies the maximum value when type is `date` or `number`. */
55
- max: PropTypes.number,
56
- /** A string to use as a mask. See <a href="https://github.com/sanniassin/react-input-mask#mask--string" target="_blank">react-input-mask</a>. */
57
- mask: PropTypes.string,
58
- /** Character to cover unfilled editable parts of mask. See <a href="https://github.com/sanniassin/react-input-mask#maskchar--string" target="_blank">react-input-mask</a>. */
59
- maskChar: PropTypes.string,
60
- /** Additional props to pass to the input element */
61
- additionalInputProps: PropTypes.object,
62
- /**
63
- * Function to execute when the input changes.
64
- *
65
- * @param {SyntheticEvent} evt - The React `SyntheticEvent`.
66
- */
67
- onChange: PropTypes.func,
68
- /**
69
- * Function to execute when the input is focused.
70
- *
71
- * @param {SyntheticEvent} evt - The React `SyntheticEvent`.
72
- */
73
- onFocus: PropTypes.func,
74
- /**
75
- * Function to execute when the input loses focused.
76
- *
77
- * @param {SyntheticEvent} evt - The React `SyntheticEvent`.
78
- */
79
- onBlur: PropTypes.func,
80
- /**
81
- * Function to execute when the element is marked as invalid by a validation check.
82
- *
83
- * @param {ValidityState} validationState - ValidityState object for more fine grained control over error handling in a parent component if desired.
84
- */
85
- onInvalid: PropTypes.func,
86
- };
87
-
88
- export default TextInputPropTypes;
@@ -1,2 +0,0 @@
1
- export {default as TextInput} from './TextInput';
2
- export {default as TextInputPropTypes} from './TextInputPropTypes';
@@ -1,230 +0,0 @@
1
- import bind from 'lodash/bind';
2
- import React, {Component} from 'react';
3
- import PropTypes from 'prop-types';
4
- import classNames from 'classnames';
5
- import IconTimes from '@spothero/icons/times';
6
- import DOMUtils from '@spothero/utils/dom';
7
- import Button from 'v1/components/Button/Button';
8
- import Portal from '../Portal/Portal';
9
-
10
- export default class Tooltip extends Component {
11
- static propTypes = {
12
- /** Additional class(es) to add to the component. */
13
- className: PropTypes.string,
14
- /** Additional class(es) to add to the containing Portal component. */
15
- containerClassName: PropTypes.string,
16
- /** The markup node to insert into the tooltip. */
17
- children: PropTypes.node.isRequired,
18
- /** Where to position the tooltip in relation to the triggering element. */
19
- position: PropTypes.oneOf(['top', 'right', 'bottom', 'left']),
20
- /** Whether to show the close button or not. */
21
- showClose: PropTypes.bool,
22
- /** The selector (.foo, #foo, etc...) for the element to attach the tooltip to. */
23
- triggerSelector: PropTypes.string.isRequired,
24
- /** Whether to reposition the tooltip when it moves, be it via window resize or scrolling or whatever moves it. */
25
- updateOnMove: PropTypes.bool,
26
- /** The offset of the tooltip from the triggering element. This is based on what the position is set to (`top` offsets up, etc). */
27
- tipOffset: PropTypes.number,
28
- /** Whether to automatically adjust the tooltip if its off the left or right side of the screen. */
29
- adjustArrow: PropTypes.bool,
30
- /** Whether to close the tooltip if the body outside of it is clicked. */
31
- closeOnBodyClick: PropTypes.bool,
32
- /** A function to execute after the tooltip has been hidden. Use this to manage state in a parent component to remove the tooltip from the DOM (see examples). */
33
- onHidden: PropTypes.func.isRequired,
34
- };
35
- static defaultProps = {
36
- position: 'top',
37
- showClose: true,
38
- tipOffset: 0,
39
- adjustArrow: true,
40
- };
41
-
42
- constructor(props) {
43
- super(props);
44
-
45
- this._isArrowAdjusted = false;
46
- }
47
-
48
- componentDidMount() {
49
- const {triggerSelector, updateOnMove, closeOnBodyClick} = this.props;
50
-
51
- this._trigger = DOMUtils.el(triggerSelector);
52
- this._positionTooltip();
53
-
54
- DOMUtils.addClass(this._container, 'Tooltip-showing');
55
-
56
- if (updateOnMove) {
57
- this._container.style.position = 'fixed';
58
-
59
- this._scrollInterval = setInterval(
60
- bind(this._positionTooltip, this),
61
- 100
62
- );
63
- }
64
-
65
- if (closeOnBodyClick) {
66
- document.addEventListener('click', this._onCloseClick, {
67
- capture: true,
68
- });
69
- }
70
- }
71
-
72
- componentWillUnmount() {
73
- const {updateOnMove, closeOnBodyClick} = this.props;
74
-
75
- if (updateOnMove) {
76
- clearInterval(this._scrollInterval);
77
- }
78
-
79
- if (closeOnBodyClick) {
80
- document.removeEventListener('click', this._onCloseClick);
81
- }
82
- }
83
-
84
- _onCloseClick = evt => {
85
- this.hide();
86
- };
87
-
88
- _positionTooltip() {
89
- if (!this._trigger) {
90
- return;
91
- }
92
-
93
- const {position, tipOffset, updateOnMove, adjustArrow} = this.props;
94
- const {
95
- top: clientTop,
96
- left: clientLeft,
97
- right: clientRight,
98
- bottom: clientBottom,
99
- width,
100
- height,
101
- } = this._trigger.getBoundingClientRect();
102
- const tooltipWidth = this._container.offsetWidth;
103
- const tooltipHeight = this._container.offsetHeight;
104
- const {
105
- top: documentTop,
106
- left: documentLeft,
107
- } = DOMUtils.getDocumentOffset(this._trigger);
108
- const top = updateOnMove ? clientTop : documentTop;
109
- const right = updateOnMove ? clientRight : documentLeft + width;
110
- const bottom = updateOnMove ? clientBottom : documentTop + height;
111
- const left = updateOnMove ? clientLeft : documentLeft;
112
- const containerMid =
113
- position === 'top' || position === 'bottom'
114
- ? tooltipWidth / 2
115
- : tooltipHeight / 2;
116
- const bodyWidth = document.body.clientWidth;
117
- const adjuster = 5;
118
- let newTop = 0;
119
- let newLeft = 0;
120
-
121
- switch (position) {
122
- case 'top':
123
- newTop = top - tooltipHeight - tipOffset;
124
- newLeft = left + width / 2 - containerMid;
125
- break;
126
-
127
- case 'right':
128
- newTop = top + height / 2 - containerMid;
129
- newLeft = right + tipOffset;
130
- break;
131
-
132
- case 'bottom':
133
- newTop = bottom + tipOffset;
134
- newLeft = left + width / 2 - containerMid;
135
- break;
136
-
137
- case 'left':
138
- newTop = top + height / 2 - containerMid;
139
- newLeft = left - tooltipWidth - tipOffset;
140
- break;
141
- }
142
-
143
- // adjust tooltip position if off the left side of the screen
144
- let adjustedLeft = newLeft < 0 ? adjuster : newLeft;
145
-
146
- // adjust tooltip position if off the right side of the screen
147
- if (tooltipWidth > bodyWidth - adjustedLeft) {
148
- adjustedLeft = bodyWidth - tooltipWidth - adjuster;
149
- }
150
-
151
- this._container.style.top = `${newTop}px`;
152
- this._container.style.left = `${adjustedLeft}px`;
153
-
154
- if (
155
- adjustArrow &&
156
- !this._isArrowAdjusted &&
157
- adjustedLeft !== newLeft &&
158
- (position === 'top' || position === 'bottom')
159
- ) {
160
- this._arrow.style.left = `${
161
- this._arrow.getBoundingClientRect().left +
162
- (newLeft - adjustedLeft)
163
- }px`;
164
-
165
- this._isArrowAdjusted = true;
166
- }
167
- }
168
-
169
- /**
170
- * Hides the Tooltip programmatically and fires the `onHidden` callback when done.
171
- *
172
- * @public
173
- * @returns {void}
174
- */
175
- hide() {
176
- if (DOMUtils.hasClass(this._container, 'Tooltip-showing')) {
177
- DOMUtils.removeClass(this._container, 'Tooltip-showing');
178
-
179
- setTimeout(() => {
180
- this.props.onHidden();
181
- }, 250);
182
- }
183
- }
184
-
185
- render() {
186
- const {
187
- className,
188
- containerClassName,
189
- position,
190
- showClose,
191
- children,
192
- } = this.props;
193
- const classes = classNames(
194
- 'Tooltip',
195
- `Tooltip-${position}`,
196
- {'Tooltip-no-close': !showClose},
197
- className
198
- );
199
-
200
- return (
201
- <Portal className={containerClassName}>
202
- <div
203
- ref={node => {
204
- this._container = node;
205
- }}
206
- className={classes}
207
- role="tooltip"
208
- >
209
- <div
210
- ref={node => {
211
- this._arrow = node;
212
- }}
213
- className="Tooltip-arrow"
214
- />
215
- <div className="Tooltip-content">
216
- {children}
217
- {showClose && (
218
- <Button
219
- className="Tooltip-close"
220
- onClick={this._onCloseClick}
221
- >
222
- <IconTimes />
223
- </Button>
224
- )}
225
- </div>
226
- </div>
227
- </Portal>
228
- );
229
- }
230
- }