@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
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@spothero/ui",
3
- "version": "15.1.0",
3
+ "version": "15.1.1",
4
4
  "description": "SpotHero's React component UI library.",
5
5
  "main": "v2/index.js",
6
6
  "repository": "https://github.com/spothero/fe-monorepo",
@@ -66,9 +66,8 @@
66
66
  "build:backlog": "NODE_ENV=production babel src -d backlog --ignore \"**/*.spec.js\",\"**/stories/**\",\"**/v2/**\"",
67
67
  "build": "npm run clean && npm run clone:styles && npm run build:backlog && npm run build:v1 && npm run build:v2",
68
68
  "build:storybook": "build-storybook -o ./docs",
69
- "prepublishOnly": "npm run build",
70
69
  "release": "npm-release",
71
- "release:storybook": "npm run build:storybook && push-dir --dir=docs --branch=gh-pages --allow-unclean"
70
+ "publish-storybook": "npm run build:storybook && push-dir --dir=docs --branch=gh-pages --allow-unclean"
72
71
  },
73
72
  "engines": {
74
73
  "node": ">=16.14.2",
@@ -1,45 +0,0 @@
1
- import React from 'react';
2
- import PropTypes from 'prop-types';
3
- import classNames from 'classnames';
4
-
5
- const Alert = ({className, children, type, size, inline}) => {
6
- const classes = classNames(
7
- 'Alert',
8
- {[`Alert-${type}`]: type},
9
- {[`Alert-${size}`]: size},
10
- {'Alert-inline': inline},
11
- className
12
- );
13
-
14
- return (
15
- <div className={classes}>
16
- <span className="Alert-content">{children}</span>
17
- </div>
18
- );
19
- };
20
-
21
- Alert.propTypes = {
22
- /** Additional class(es) to add to the component. */
23
- className: PropTypes.string,
24
- /** The content to render inside of the alert. */
25
- children: PropTypes.node.isRequired,
26
- /** Whether to show the alert inline instead of block. */
27
- inline: PropTypes.bool,
28
- /** The type of alert to show. */
29
- type: PropTypes.oneOf([
30
- 'danger',
31
- 'highlight',
32
- 'success',
33
- 'neutral',
34
- 'muted',
35
- ]),
36
- /** The size of the alert. */
37
- size: PropTypes.oneOf(['sm', 'md', 'lg']),
38
- };
39
-
40
- Alert.defaultProps = {
41
- type: 'neutral',
42
- size: 'md',
43
- };
44
-
45
- export default Alert;
@@ -1,85 +0,0 @@
1
- describe('<Alert />', () => {
2
- context('Colors', () => {
3
- context('Neutral', () => {
4
- beforeEach(() => {
5
- cy.visitStory('v1/Alert/Colors', 'Neutral');
6
- });
7
-
8
- it('Has neutral styles', () => {
9
- cy.get('.Alert').should('have.class', 'Alert-neutral');
10
- });
11
-
12
- it('Renders the correct children', () => {
13
- cy.get('.Alert').contains('This is an alert.');
14
- });
15
- });
16
-
17
- context('Highlight', () => {
18
- it('Has highlight styles', () => {
19
- cy.visitStory('v1/Alert/Colors', 'Highlight')
20
- .get('.Alert')
21
- .should('have.class', 'Alert-highlight');
22
- });
23
- });
24
-
25
- context('Danger', () => {
26
- it('Has danger styles', () => {
27
- cy.visitStory('v1/Alert/Colors', 'Danger')
28
- .get('.Alert')
29
- .should('have.class', 'Alert-danger');
30
- });
31
- });
32
-
33
- context('Success', () => {
34
- it('Has success styles', () => {
35
- cy.visitStory('v1/Alert/Colors', 'Success')
36
- .get('.Alert')
37
- .should('have.class', 'Alert-success');
38
- });
39
- });
40
-
41
- context('Muted', () => {
42
- it('Has muted styles', () => {
43
- cy.visitStory('v1/Alert/Colors', 'Muted')
44
- .get('.Alert')
45
- .should('have.class', 'Alert-muted');
46
- });
47
- });
48
- });
49
-
50
- context('Display', () => {
51
- context('Inline', () => {
52
- it('Has inline styles', () => {
53
- cy.visitStory('v1/Alert/Display', 'Inline')
54
- .get('.Alert')
55
- .should('have.class', 'Alert-inline');
56
- });
57
- });
58
- });
59
-
60
- context('Sizes', () => {
61
- context('Small', () => {
62
- it('Has small styles', () => {
63
- cy.visitStory('v1/Alert/Sizes', 'Small')
64
- .get('.Alert')
65
- .should('have.class', 'Alert-sm');
66
- });
67
- });
68
-
69
- context('Medium', () => {
70
- it('Has medium styles', () => {
71
- cy.visitStory('v1/Alert/Sizes', 'Medium')
72
- .get('.Alert')
73
- .should('have.class', 'Alert-md');
74
- });
75
- });
76
-
77
- context('Large', () => {
78
- it('Has large styles', () => {
79
- cy.visitStory('v1/Alert/Sizes', 'Large')
80
- .get('.Alert')
81
- .should('have.class', 'Alert-lg');
82
- });
83
- });
84
- });
85
- });
@@ -1,429 +0,0 @@
1
- import isEqual from 'lodash/isEqual';
2
- import React, {Component} from 'react';
3
- import PropTypes from 'prop-types';
4
- import classnames from 'classnames';
5
- import uuidV4 from 'uuid/v4';
6
- import IconTimesCircle from '@spothero/icons/times-circle';
7
- import TextInput from '../TextInput/TextInput';
8
- import TextInputPropTypes from '../TextInput/TextInputPropTypes';
9
- import AutoSuggestList from './AutoSuggestList';
10
- import Button from 'v1/components/Button/Button';
11
-
12
- /**
13
- * Calculates the difference between current scroll position and position of element, if outside visible window
14
- *
15
- * @param {object} elementAttributes
16
- * @param {number} elementAttributes.parentScrollTop Value of parent element `scrollTop` attribute
17
- * @param {number} elementAttributes.parentHeight Value of parent element `clientHeight` attribute
18
- * @param {number} elementAttributes.elementOffsetTop Value of element `offsetTop` attribute
19
- * @param {number} elementAttributes.elementHeight Value of element `clientHeight` attribute
20
- *
21
- * @returns {number} Pixel value of how far to scroll to view element
22
- */
23
- const getScrollDifferential = ({
24
- parentScrollTop,
25
- parentHeight,
26
- elementOffsetTop,
27
- elementHeight,
28
- }) => {
29
- if (elementOffsetTop < parentScrollTop) {
30
- return elementOffsetTop - parentScrollTop;
31
- }
32
-
33
- const parentLowerBound = parentScrollTop + parentHeight;
34
- const elementLowerBound = elementOffsetTop + elementHeight;
35
-
36
- if (elementLowerBound > parentLowerBound) {
37
- return elementLowerBound - parentLowerBound;
38
- }
39
-
40
- return 0;
41
- };
42
-
43
- export default class AutoSuggestInput extends Component {
44
- static propTypes = {
45
- ...TextInputPropTypes,
46
- /** Whether or not to highlight the first suggestion in the list when suggestions are presented. */
47
- autoActivateFirstSuggest: PropTypes.bool,
48
- /** The available suggestions. */
49
- suggestions: PropTypes.arrayOf(
50
- PropTypes.shape({
51
- label: PropTypes.oneOfType([
52
- PropTypes.string,
53
- PropTypes.element,
54
- ]).isRequired,
55
- id: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
56
- })
57
- ),
58
- /** A custom element to display at the bottom of the suggestion list */
59
- suggestionBoxFooter: PropTypes.element,
60
- /** Optional function to execute when a suggestion is selected. */
61
- onSuggestionSelect: PropTypes.func,
62
- /** Optional function to execute when input field is cleared. */
63
- onClear: PropTypes.func,
64
- };
65
- static defaultProps = {
66
- iconPosition: 'left',
67
- name: 'search',
68
- placeholder: 'Search',
69
- suggestions: [],
70
- };
71
-
72
- constructor(props) {
73
- super(props);
74
-
75
- const {defaultValue} = props;
76
-
77
- this.state = {
78
- suggestionsHidden: true,
79
- ignoreBlur: false,
80
- value: defaultValue || '',
81
- activeSuggestion: null,
82
- inputKey: uuidV4(),
83
- };
84
- }
85
-
86
- componentDidMount() {
87
- const {suggestions} = this.props;
88
-
89
- this._input?.node?.addEventListener('invalid', this._onInvalid);
90
-
91
- if (suggestions.length) {
92
- this._showSuggests();
93
- } else {
94
- this._hideSuggests();
95
- }
96
- }
97
-
98
- componentDidUpdate(prevProps, prevState) {
99
- const {suggestions, autoActivateFirstSuggest} = this.props;
100
- const {value} = this.state;
101
- const {suggestions: prevSuggestions} = prevProps;
102
-
103
- if (prevState.value !== value) {
104
- if (!value) {
105
- this._input?.node?.focus();
106
- }
107
- }
108
-
109
- if (!isEqual(prevSuggestions, suggestions)) {
110
- if (suggestions && suggestions.length) {
111
- this._showSuggests();
112
-
113
- if (autoActivateFirstSuggest) {
114
- this._activateSuggest({direction: 'next'});
115
- }
116
- } else {
117
- this._hideSuggests();
118
- }
119
- }
120
- }
121
-
122
- componentWillUnmount() {
123
- this._input?.node?.removeEventListener('invalid', this._onInvalid);
124
- }
125
-
126
- _onInvalid = evt => {
127
- evt.preventDefault();
128
-
129
- const {onInvalid} = this.props;
130
-
131
- if (onInvalid) {
132
- onInvalid(evt.currentTarget.validity);
133
- }
134
- };
135
-
136
- _onInputChange = evt => {
137
- this.setState({
138
- value: evt.target.value,
139
- });
140
-
141
- const {onChange} = this.props;
142
-
143
- if (onChange) {
144
- onChange(evt);
145
- }
146
- };
147
-
148
- _onInputKeyDown = evt => {
149
- switch (evt.which) {
150
- case 40:
151
- this._nextSuggest(evt);
152
- break;
153
-
154
- case 38:
155
- this._previousSuggest(evt);
156
- break;
157
-
158
- case 13:
159
- this._selectSuggest(evt);
160
- break;
161
-
162
- case 27:
163
- this._hideSuggests(evt);
164
- break;
165
- }
166
- };
167
-
168
- _onInputFocus = () => {
169
- const {onFocus} = this.props;
170
-
171
- if (onFocus) {
172
- onFocus();
173
- }
174
-
175
- this.setState({
176
- suggestionsHidden: false,
177
- });
178
- };
179
-
180
- _onInputBlur = () => {
181
- if (!this.state.ignoreBlur) {
182
- this._hideSuggests();
183
- }
184
- };
185
-
186
- _onSuggestionMouseDown = () => {
187
- this.setState({
188
- ignoreBlur: true,
189
- });
190
- };
191
-
192
- _onSuggestionMouseOut = () => {
193
- this.setState({
194
- ignoreBlur: false,
195
- });
196
- };
197
-
198
- _onSelectSuggestion = ({suggestion = false}) => {
199
- const {onSuggestionSelect} = this.props;
200
- let selectedSuggestion = suggestion;
201
-
202
- if (!selectedSuggestion) {
203
- selectedSuggestion = {};
204
- selectedSuggestion.label = this.state.value;
205
- }
206
-
207
- this.setState({
208
- suggestionsHidden: true,
209
- value: selectedSuggestion.label,
210
- inputKey: uuidV4(),
211
- });
212
-
213
- onSuggestionSelect?.(selectedSuggestion);
214
- };
215
-
216
- _onClear = () => {
217
- const {onClear} = this.props;
218
-
219
- this.setState({
220
- value: '',
221
- inputKey: uuidV4(),
222
- });
223
-
224
- if (onClear) {
225
- onClear();
226
- }
227
- };
228
-
229
- _nextSuggest() {
230
- this._activateSuggest({
231
- direction: 'next',
232
- isArrowPress: true,
233
- });
234
- }
235
-
236
- _previousSuggest() {
237
- this._activateSuggest({
238
- direction: 'prev',
239
- isArrowPress: true,
240
- });
241
- }
242
-
243
- _selectSuggest = evt => {
244
- evt.preventDefault();
245
-
246
- this._onSelectSuggestion({
247
- suggestion: this.state.activeSuggestion,
248
- });
249
- };
250
-
251
- _showSuggests() {
252
- if (this.state.suggestionsHidden) {
253
- this.setState({
254
- suggestionsHidden: false,
255
- });
256
- }
257
- }
258
-
259
- _hideSuggests() {
260
- const {onBlur} = this.props;
261
-
262
- if (onBlur) {
263
- onBlur();
264
- }
265
-
266
- if (!this.state.suggestionsHidden) {
267
- this.setState({
268
- suggestionsHidden: true,
269
- });
270
- }
271
- }
272
-
273
- _activateSuggest({direction, isArrowPress = false}) {
274
- const {suggestions} = this.props;
275
- const {activeSuggestion} = this.state;
276
- const suggestionsCount = suggestions.length - 1;
277
- const next = direction === 'next';
278
- const newState = {};
279
- let newActiveSuggestion = null;
280
- let newIndex = 0;
281
- let i = 0;
282
-
283
- for (i; i <= suggestionsCount; i++) {
284
- if (suggestions[i] === activeSuggestion) {
285
- newIndex = next ? i + 1 : i - 1;
286
- }
287
- }
288
-
289
- if (!activeSuggestion) {
290
- newIndex = next ? 0 : suggestionsCount;
291
- }
292
-
293
- if (newIndex < 0) {
294
- newIndex = suggestionsCount;
295
- } else if (newIndex > suggestionsCount) {
296
- newIndex = 0;
297
- }
298
-
299
- if (newIndex >= 0 && newIndex <= suggestionsCount) {
300
- newActiveSuggestion = suggestions[newIndex];
301
- }
302
-
303
- newState.activeSuggestion = newActiveSuggestion;
304
-
305
- if (isArrowPress) {
306
- newState.value = newActiveSuggestion
307
- ? newActiveSuggestion.label
308
- : '';
309
- }
310
-
311
- if (this._list) {
312
- const activeChild = this._list.querySelector(
313
- '.AutoSuggestInput-item-active'
314
- );
315
-
316
- let nextActiveChild = next
317
- ? activeChild?.nextSibling
318
- : activeChild?.previousSibling;
319
-
320
- nextActiveChild = nextActiveChild
321
- ? nextActiveChild
322
- : next
323
- ? this._list.firstElementChild
324
- : this._list.lastElementChild;
325
-
326
- if (nextActiveChild) {
327
- const scrollDiff = getScrollDifferential({
328
- parentScrollTop: this._list.scrollTop,
329
- parentHeight: this._list.clientHeight,
330
- elementOffsetTop: nextActiveChild.offsetTop,
331
- elementHeight: nextActiveChild.clientHeight,
332
- });
333
-
334
- if (scrollDiff) {
335
- this._list.scrollTo(
336
- nextActiveChild.offsetLeft,
337
- this._list.scrollTop + scrollDiff
338
- );
339
- }
340
- }
341
- }
342
-
343
- this.setState(newState);
344
- }
345
-
346
- /**
347
- * Getter for the input DOM element.
348
- *
349
- * @public
350
- * @returns {Element} - The input element.
351
- */
352
- get node() {
353
- return this._input?.node;
354
- }
355
-
356
- render() {
357
- const {
358
- className,
359
- suggestions,
360
- suggestionBoxFooter,
361
- additionalInputProps,
362
- ...textInputProps
363
- } = this.props;
364
- const {
365
- value,
366
- inputKey,
367
- activeSuggestion,
368
- suggestionsHidden,
369
- } = this.state;
370
- const classes = classnames(
371
- 'AutoSuggestInput',
372
- {'AutoSuggestInput-suggestions-active': !suggestionsHidden},
373
- {
374
- 'AutoSuggestInput-no-suggestions':
375
- !suggestions || !suggestions.length,
376
- },
377
- className
378
- );
379
- const newAdditionalInputProps = {
380
- ...additionalInputProps,
381
- onKeyDown: this._onInputKeyDown,
382
- autoComplete: 'off',
383
- };
384
-
385
- return (
386
- <div
387
- ref={node => {
388
- this._container = node;
389
- }}
390
- className={classes}
391
- >
392
- <div className="FormElement-control">
393
- <TextInput
394
- key={inputKey}
395
- ref={node => {
396
- this._input = node;
397
- }}
398
- {...textInputProps}
399
- additionalInputProps={newAdditionalInputProps}
400
- defaultValue={value}
401
- onChange={this._onInputChange}
402
- onFocus={this._onInputFocus}
403
- onBlur={this._onInputBlur}
404
- />
405
- <AutoSuggestList
406
- ref={node => {
407
- this._list = node;
408
- }}
409
- hidden={suggestionsHidden}
410
- suggestions={suggestions || []}
411
- activeSuggestion={activeSuggestion}
412
- suggestionBoxFooter={suggestionBoxFooter}
413
- onSuggestionSelect={this._onSelectSuggestion}
414
- onSuggestionMouseDown={this._onSuggestionMouseDown}
415
- onSuggestionMouseOut={this._onSuggestionMouseOut}
416
- />
417
- {value && (
418
- <Button
419
- className="AutoSuggestInput-clear"
420
- onClick={this._onClear}
421
- >
422
- <IconTimesCircle />
423
- </Button>
424
- )}
425
- </div>
426
- </div>
427
- );
428
- }
429
- }