bright-components 9.30.0 → 9.33.0

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.
@@ -174,6 +174,7 @@ function (_React$Component) {
174
174
  dayPickerOpen: open || false
175
175
  };
176
176
  (0, _reactAutobind.default)(_assertThisInitialized(_this));
177
+ _this.containerRef = _react.default.createRef();
177
178
  return _this;
178
179
  }
179
180
 
@@ -245,6 +246,8 @@ function (_React$Component) {
245
246
  };
246
247
 
247
248
  _proto.toggleDayPicker = function toggleDayPicker() {
249
+ var _this2 = this;
250
+
248
251
  var _this$props2 = this.props,
249
252
  disabled = _this$props2.disabled,
250
253
  GA = _this$props2.GA;
@@ -260,6 +263,13 @@ function (_React$Component) {
260
263
 
261
264
  this.setState({
262
265
  dayPickerOpen: !dayPickerOpen
266
+ }, function () {
267
+ if (_this2.containerRef.current) {
268
+ _this2.containerRef.current.scrollIntoView({
269
+ behavior: 'smooth',
270
+ block: 'nearest'
271
+ });
272
+ }
263
273
  });
264
274
  };
265
275
 
@@ -329,7 +339,8 @@ function (_React$Component) {
329
339
  })), dayPickerOpen && _react.default.createElement(DayRangeContainer, {
330
340
  panelAbsoluteOnDesktop: panelAbsoluteOnDesktop,
331
341
  style: otherStyles,
332
- width: width
342
+ width: width,
343
+ ref: this.containerRef
333
344
  }, _react.default.createElement(_DayPickerPanel.default, {
334
345
  month: this.getDefaultMonth(),
335
346
  year: this.getDefaultYear(),
@@ -0,0 +1,31 @@
1
+ "use strict";
2
+
3
+ exports.__esModule = true;
4
+ exports.default = void 0;
5
+
6
+ var _react = _interopRequireDefault(require("react"));
7
+
8
+ var _propTypes = require("prop-types");
9
+
10
+ var _reactIconBase = _interopRequireDefault(require("react-icon-base"));
11
+
12
+ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
13
+
14
+ function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
15
+
16
+ var CrossThickIcon = function CrossThickIcon(props) {
17
+ return _react.default.createElement(_reactIconBase.default, _extends({
18
+ viewBox: "0 0 33 32"
19
+ }, props), _react.default.createElement("path", {
20
+ d: "M23.58 20.585L18.997 16l4.585-4.585a2.003 2.003 0 000-2.829 2.001 2.001 0 00-2.83 0l-4.584 4.585-4.585-4.585a2 2 0 10-2.829 2.829L13.338 16l-4.585 4.585a2 2 0 102.829 2.829l4.585-4.585 4.585 4.585a2 2 0 002.829-2.829z"
21
+ }));
22
+ };
23
+
24
+ CrossThickIcon.propTypes = {
25
+ size: _propTypes.number
26
+ };
27
+ CrossThickIcon.defaultProps = {
28
+ size: 40
29
+ };
30
+ var _default = CrossThickIcon;
31
+ exports.default = _default;
@@ -0,0 +1,31 @@
1
+ "use strict";
2
+
3
+ exports.__esModule = true;
4
+ exports.default = void 0;
5
+
6
+ var _react = _interopRequireDefault(require("react"));
7
+
8
+ var _propTypes = require("prop-types");
9
+
10
+ var _reactIconBase = _interopRequireDefault(require("react-icon-base"));
11
+
12
+ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
13
+
14
+ function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
15
+
16
+ var TickThickIcon = function TickThickIcon(props) {
17
+ return _react.default.createElement(_reactIconBase.default, _extends({
18
+ viewBox: "0 0 33 32"
19
+ }, props), _react.default.createElement("path", {
20
+ d: "M26.167 4a2 2 0 00-1.638.854L11.895 22.9l-4.313-4.314a2 2 0 10-2.83 2.829l6 6a2 2 0 003.04-.25L27.805 7.146A2.001 2.001 0 0026.167 4z"
21
+ }));
22
+ };
23
+
24
+ TickThickIcon.propTypes = {
25
+ size: _propTypes.number
26
+ };
27
+ TickThickIcon.defaultProps = {
28
+ size: 40
29
+ };
30
+ var _default = TickThickIcon;
31
+ exports.default = _default;
@@ -144,7 +144,7 @@ var convertHours = function convertHours(hour) {
144
144
  return hour > 12 ? hour - 12 : hour;
145
145
  };
146
146
 
147
- var TimeOverlay = function TimeOverlay(_ref) {
147
+ var TimeOverlay = (0, _react.forwardRef)(function (_ref, ref) {
148
148
  var value = _ref.value,
149
149
  onChange = _ref.onChange,
150
150
  onHide = _ref.onHide,
@@ -181,7 +181,9 @@ var TimeOverlay = function TimeOverlay(_ref) {
181
181
  hours = _millisecondsToDurati.hours,
182
182
  minutes = _millisecondsToDurati.minutes;
183
183
 
184
- return _react.default.createElement(Overlay, null, _react.default.createElement(Content, null, _react.default.createElement(_UnitInput.default, {
184
+ return _react.default.createElement(Overlay, {
185
+ ref: ref
186
+ }, _react.default.createElement(Content, null, _react.default.createElement(_UnitInput.default, {
185
187
  unit: "hours",
186
188
  value: hours,
187
189
  onChange: function onChange(i) {
@@ -230,8 +232,7 @@ var TimeOverlay = function TimeOverlay(_ref) {
230
232
  },
231
233
  "data-e2e": "time-apply"
232
234
  }, "Apply")));
233
- };
234
-
235
+ });
235
236
  var timeShape = (0, _propTypes.shape)({
236
237
  hours: _propTypes.number,
237
238
  minutes: _propTypes.number
@@ -98,6 +98,7 @@ var TimePicker = function TimePicker(_ref) {
98
98
  var nodeRef = (0, _useClickOutside.default)(function () {
99
99
  return setPickerVisible(false);
100
100
  });
101
+ var myRef = (0, _react.useRef)();
101
102
 
102
103
  var _useState3 = (0, _react.useState)((0, _durationToTimeString.default)(value)),
103
104
  internalValue = _useState3[0],
@@ -107,6 +108,12 @@ var TimePicker = function TimePicker(_ref) {
107
108
  // keep internal value in sync with prop change
108
109
  setInternalValue((0, _durationToTimeString.default)(value));
109
110
  }, [value]);
111
+ (0, _react.useEffect)(function () {
112
+ if (myRef.current) myRef.current.scrollIntoView({
113
+ behavior: 'smooth',
114
+ block: 'nearest'
115
+ });
116
+ }, [pickerVisible]);
110
117
 
111
118
  var changeHandler = function changeHandler(_ref2) {
112
119
  var newHours = _ref2.hours,
@@ -216,7 +223,8 @@ var TimePicker = function TimePicker(_ref) {
216
223
  hourIncrements: hourIncrements,
217
224
  minuteIncrements: minuteIncrements,
218
225
  min: min,
219
- max: max
226
+ max: max,
227
+ ref: myRef
220
228
  })));
221
229
  };
222
230
 
@@ -133,10 +133,10 @@ WithDayPicker.defaultProps = {
133
133
  inModal: false,
134
134
  view: 'calendar',
135
135
  month: today.getMonth(),
136
- year: today.getYear(),
136
+ year: today.getFullYear(),
137
137
  yearRange: {
138
- min: today.getYear() - 1,
139
- max: today.getYear() + 1
138
+ min: today.getFullYear() - 1,
139
+ max: today.getFullYear() + 1
140
140
  },
141
141
  onClear: undefined,
142
142
  yearsToDisplay: null,
@@ -146,8 +146,9 @@ var withConfirmation = function withConfirmation(WrappedComponent) {
146
146
  disabled: loading,
147
147
  onClick: !href ? this.onButtonClick : this.close,
148
148
  href: href || undefined,
149
- as: href ? 'a' : 'button'
149
+ as: href ? 'a' : undefined
150
150
  }), error ? 'Try again' : yesLabel), _react.default.createElement(_OutlineButton.default, {
151
+ disabled: loading,
151
152
  onClick: this.close
152
153
  }, error ? 'Cancel' : noLabel))));
153
154
  };
@@ -38,6 +38,7 @@ beforeEach(function () {
38
38
  originalConsole.error.apply(originalConsole, args);
39
39
  }
40
40
  });
41
+ Element.prototype.scrollIntoView = jest.fn();
41
42
 
42
43
  _reactGa.default.initialize('foo', {
43
44
  testMode: true
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "bright-components",
3
- "version": "9.30.0",
3
+ "version": "9.33.0",
4
4
  "private": false,
5
5
  "main": "./dist",
6
6
  "repository": {
@@ -111,6 +111,8 @@ class DayPicker extends React.Component {
111
111
  dayPickerOpen: open || false
112
112
  };
113
113
  autobind(this);
114
+
115
+ this.containerRef = React.createRef();
114
116
  }
115
117
 
116
118
  getDefaultMonth() {
@@ -188,7 +190,14 @@ class DayPicker extends React.Component {
188
190
  });
189
191
  }
190
192
 
191
- this.setState({ dayPickerOpen: !dayPickerOpen });
193
+ this.setState({ dayPickerOpen: !dayPickerOpen }, () => {
194
+ if (this.containerRef.current) {
195
+ this.containerRef.current.scrollIntoView({
196
+ behavior: 'smooth',
197
+ block: 'nearest'
198
+ });
199
+ }
200
+ });
192
201
  }
193
202
 
194
203
  clearValue() {
@@ -261,6 +270,7 @@ class DayPicker extends React.Component {
261
270
  panelAbsoluteOnDesktop={panelAbsoluteOnDesktop}
262
271
  style={otherStyles}
263
272
  width={width}
273
+ ref={this.containerRef}
264
274
  >
265
275
  <DayPickerPanel
266
276
  month={this.getDefaultMonth()}
@@ -0,0 +1,5 @@
1
+ CrossThick example
2
+
3
+ ```js
4
+ <CrossThickIcon />
5
+ ```
@@ -0,0 +1,19 @@
1
+ import React from 'react';
2
+ import { number } from 'prop-types';
3
+ import IconBase from 'react-icon-base';
4
+
5
+ const CrossThickIcon = props => (
6
+ <IconBase viewBox="0 0 33 32" {...props}>
7
+ <path d="M23.58 20.585L18.997 16l4.585-4.585a2.003 2.003 0 000-2.829 2.001 2.001 0 00-2.83 0l-4.584 4.585-4.585-4.585a2 2 0 10-2.829 2.829L13.338 16l-4.585 4.585a2 2 0 102.829 2.829l4.585-4.585 4.585 4.585a2 2 0 002.829-2.829z" />
8
+ </IconBase>
9
+ );
10
+
11
+ CrossThickIcon.propTypes = {
12
+ size: number
13
+ };
14
+
15
+ CrossThickIcon.defaultProps = {
16
+ size: 40
17
+ };
18
+
19
+ export default CrossThickIcon;
@@ -0,0 +1,5 @@
1
+ TickThick example
2
+
3
+ ```js
4
+ <TickThickIcon />
5
+ ```
@@ -0,0 +1,19 @@
1
+ import React from 'react';
2
+ import { number } from 'prop-types';
3
+ import IconBase from 'react-icon-base';
4
+
5
+ const TickThickIcon = props => (
6
+ <IconBase viewBox="0 0 33 32" {...props}>
7
+ <path d="M26.167 4a2 2 0 00-1.638.854L11.895 22.9l-4.313-4.314a2 2 0 10-2.83 2.829l6 6a2 2 0 003.04-.25L27.805 7.146A2.001 2.001 0 0026.167 4z" />
8
+ </IconBase>
9
+ );
10
+
11
+ TickThickIcon.propTypes = {
12
+ size: number
13
+ };
14
+
15
+ TickThickIcon.defaultProps = {
16
+ size: 40
17
+ };
18
+
19
+ export default TickThickIcon;
@@ -3,7 +3,6 @@ import { render, fireEvent } from '@testing-library/react';
3
3
  import DurationPicker from '.';
4
4
 
5
5
  describe('<DurationPicker />', () => {
6
- Element.prototype.scrollIntoView = jest.fn();
7
6
  describe('on initial render', () => {
8
7
  it('should display the time in the expected format', () => {
9
8
  const { getByRole } = render(
@@ -1,4 +1,4 @@
1
- import React, { useState } from 'react';
1
+ import React, { useState, forwardRef } from 'react';
2
2
  import { arrayOf, func, number, oneOfType, shape, string } from 'prop-types';
3
3
  import millisecondsToDuration from 'utils/time/millisecondsToDuration';
4
4
  import styled from 'styled-components';
@@ -85,114 +85,119 @@ const convertHours = hour => {
85
85
  return hour > 12 ? hour - 12 : hour;
86
86
  };
87
87
 
88
- const TimeOverlay = ({
89
- value,
90
- onChange,
91
- onHide,
92
- hourIncrements,
93
- minuteIncrements,
94
- min,
95
- max,
96
- GA
97
- }) => {
98
- const sanitizeValue = unsanitizedValue =>
99
- getBoundedValue(
100
- unsanitizedValue,
101
- durationToMilliseconds(min),
102
- durationToMilliseconds(max)
103
- );
104
-
105
- const [internalValue, setInternalValue] = useState(
106
- sanitizeValue(durationToMilliseconds(value))
107
- );
108
-
109
- const setHandler = (unitValue, unit) => {
110
- const proposedDate = new Date(internalValue);
111
-
112
- if (unit === 'minutes') {
113
- proposedDate.setUTCMinutes(
114
- roundTo(minuteIncrements)(getBoundedValue(unitValue, 0, 59))
88
+ const TimeOverlay = forwardRef(
89
+ (
90
+ {
91
+ value,
92
+ onChange,
93
+ onHide,
94
+ hourIncrements,
95
+ minuteIncrements,
96
+ min,
97
+ max,
98
+ GA
99
+ },
100
+ ref
101
+ ) => {
102
+ const sanitizeValue = unsanitizedValue =>
103
+ getBoundedValue(
104
+ unsanitizedValue,
105
+ durationToMilliseconds(min),
106
+ durationToMilliseconds(max)
115
107
  );
116
- }
117
108
 
118
- if (unit === 'hours') {
119
- proposedDate.setUTCHours(
120
- roundTo(hourIncrements)(getBoundedValue(unitValue, 0, 23))
121
- );
122
- }
123
-
124
- const appliedValue = sanitizeValue(proposedDate.getTime());
125
- setInternalValue(appliedValue);
126
- };
127
-
128
- const { hours, minutes } = millisecondsToDuration(internalValue);
129
-
130
- return (
131
- <Overlay>
132
- <Content>
133
- <UnitInput
134
- unit="hours"
135
- value={hours}
136
- onChange={i => setHandler(i, 'hours')}
137
- increment={hourIncrements}
138
- min={min.hours}
139
- max={max.hours}
140
- />
141
- <UnitInput
142
- unit="minutes"
143
- value={minutes}
144
- onChange={i => setHandler(i, 'minutes')}
145
- increment={minuteIncrements}
146
- min={hours === min.hours ? min.minutes : 0}
147
- max={hours === max.hours ? max.minutes : 59}
148
- />
149
- </Content>
150
- <DialogButtonGroup>
151
- <OutlineButton
152
- type="button"
153
- onClick={() => {
154
- onHide();
155
- if (GA) {
156
- event({
157
- category: GA.category,
158
- action: `${GA.action} (Cancel)`
159
- });
160
- }
161
- }}
162
- >
163
- Cancel
164
- </OutlineButton>
165
- <DisplayValue>
166
- <TwentyFourHourValue>
167
- {formatTimePart(hours)}:{formatTimePart(minutes)}
168
- </TwentyFourHourValue>
169
- <TwelveHourValue>
170
- {convertHours(hours)}.{formatTimePart(minutes)}
171
- {hours > 11 ? 'pm' : 'am'}{' '}
172
- </TwelveHourValue>
173
- </DisplayValue>
174
- <BrandButton
175
- type="button"
176
- onClick={() => {
177
- onChange({ hours, minutes });
178
- onHide();
179
-
180
- if (GA) {
181
- event({
182
- category: GA.category,
183
- action: `${GA.action} (Apply)`,
184
- label: `${hours} hrs ${minutes} mins`
185
- });
186
- }
187
- }}
188
- data-e2e="time-apply"
189
- >
190
- Apply
191
- </BrandButton>
192
- </DialogButtonGroup>
193
- </Overlay>
194
- );
195
- };
109
+ const [internalValue, setInternalValue] = useState(
110
+ sanitizeValue(durationToMilliseconds(value))
111
+ );
112
+
113
+ const setHandler = (unitValue, unit) => {
114
+ const proposedDate = new Date(internalValue);
115
+
116
+ if (unit === 'minutes') {
117
+ proposedDate.setUTCMinutes(
118
+ roundTo(minuteIncrements)(getBoundedValue(unitValue, 0, 59))
119
+ );
120
+ }
121
+
122
+ if (unit === 'hours') {
123
+ proposedDate.setUTCHours(
124
+ roundTo(hourIncrements)(getBoundedValue(unitValue, 0, 23))
125
+ );
126
+ }
127
+
128
+ const appliedValue = sanitizeValue(proposedDate.getTime());
129
+ setInternalValue(appliedValue);
130
+ };
131
+
132
+ const { hours, minutes } = millisecondsToDuration(internalValue);
133
+
134
+ return (
135
+ <Overlay ref={ref}>
136
+ <Content>
137
+ <UnitInput
138
+ unit="hours"
139
+ value={hours}
140
+ onChange={i => setHandler(i, 'hours')}
141
+ increment={hourIncrements}
142
+ min={min.hours}
143
+ max={max.hours}
144
+ />
145
+ <UnitInput
146
+ unit="minutes"
147
+ value={minutes}
148
+ onChange={i => setHandler(i, 'minutes')}
149
+ increment={minuteIncrements}
150
+ min={hours === min.hours ? min.minutes : 0}
151
+ max={hours === max.hours ? max.minutes : 59}
152
+ />
153
+ </Content>
154
+ <DialogButtonGroup>
155
+ <OutlineButton
156
+ type="button"
157
+ onClick={() => {
158
+ onHide();
159
+ if (GA) {
160
+ event({
161
+ category: GA.category,
162
+ action: `${GA.action} (Cancel)`
163
+ });
164
+ }
165
+ }}
166
+ >
167
+ Cancel
168
+ </OutlineButton>
169
+ <DisplayValue>
170
+ <TwentyFourHourValue>
171
+ {formatTimePart(hours)}:{formatTimePart(minutes)}
172
+ </TwentyFourHourValue>
173
+ <TwelveHourValue>
174
+ {convertHours(hours)}.{formatTimePart(minutes)}
175
+ {hours > 11 ? 'pm' : 'am'}{' '}
176
+ </TwelveHourValue>
177
+ </DisplayValue>
178
+ <BrandButton
179
+ type="button"
180
+ onClick={() => {
181
+ onChange({ hours, minutes });
182
+ onHide();
183
+
184
+ if (GA) {
185
+ event({
186
+ category: GA.category,
187
+ action: `${GA.action} (Apply)`,
188
+ label: `${hours} hrs ${minutes} mins`
189
+ });
190
+ }
191
+ }}
192
+ data-e2e="time-apply"
193
+ >
194
+ Apply
195
+ </BrandButton>
196
+ </DialogButtonGroup>
197
+ </Overlay>
198
+ );
199
+ }
200
+ );
196
201
 
197
202
  const timeShape = shape({
198
203
  hours: number,
@@ -1,4 +1,4 @@
1
- import React, { useEffect, useState } from 'react';
1
+ import React, { useEffect, useState, useRef } from 'react';
2
2
  import { arrayOf, func, number, oneOfType, shape, string } from 'prop-types';
3
3
  import styled from 'styled-components';
4
4
  import ClockIcon from 'components/Icons/Clock';
@@ -54,6 +54,7 @@ const TimePicker = ({
54
54
  const [pickerVisible, setPickerVisible] = useState(false);
55
55
  const [hasFocus, setFocus] = useState(false);
56
56
  const nodeRef = useClickOutside(() => setPickerVisible(false));
57
+ const myRef = useRef();
57
58
 
58
59
  const [internalValue, setInternalValue] = useState(
59
60
  durationToTimeString(value)
@@ -64,6 +65,14 @@ const TimePicker = ({
64
65
  setInternalValue(durationToTimeString(value));
65
66
  }, [value]);
66
67
 
68
+ useEffect(() => {
69
+ if (myRef.current)
70
+ myRef.current.scrollIntoView({
71
+ behavior: 'smooth',
72
+ block: 'nearest'
73
+ });
74
+ }, [pickerVisible]);
75
+
67
76
  const changeHandler = ({ hours: newHours, minutes: newMinutes }) => {
68
77
  const proposedDate = new Date(
69
78
  durationToMs(value || { hours: 0, minutes: 0 })
@@ -180,6 +189,7 @@ const TimePicker = ({
180
189
  minuteIncrements={minuteIncrements}
181
190
  min={min}
182
191
  max={max}
192
+ ref={myRef}
183
193
  />
184
194
  )}
185
195
  </Container>
@@ -101,10 +101,10 @@ WithDayPicker.defaultProps = {
101
101
  inModal: false,
102
102
  view: 'calendar',
103
103
  month: today.getMonth(),
104
- year: today.getYear(),
104
+ year: today.getFullYear(),
105
105
  yearRange: {
106
- min: today.getYear() - 1,
107
- max: today.getYear() + 1
106
+ min: today.getFullYear() - 1,
107
+ max: today.getFullYear() + 1
108
108
  },
109
109
  onClear: undefined,
110
110
  yearsToDisplay: null,
@@ -133,7 +133,6 @@ const withConfirmation = WrappedComponent => {
133
133
  </P>
134
134
  </Alert>
135
135
  )}
136
-
137
136
  <Button
138
137
  {...buttonProps}
139
138
  loading={loading}
@@ -142,12 +141,15 @@ const withConfirmation = WrappedComponent => {
142
141
  !href ? this.onButtonClick : this.close
143
142
  }
144
143
  href={href || undefined}
145
- as={href ? 'a' : 'button'}
144
+ as={href ? 'a' : undefined}
146
145
  >
147
146
  {error ? 'Try again' : yesLabel}
148
147
  </Button>
149
148
 
150
- <OutlineButton onClick={this.close}>
149
+ <OutlineButton
150
+ disabled={loading}
151
+ onClick={this.close}
152
+ >
151
153
  {error ? 'Cancel' : noLabel}
152
154
  </OutlineButton>
153
155
  </Container>
package/src/setupTests.js CHANGED
@@ -21,6 +21,8 @@ beforeEach(() => {
21
21
  }
22
22
  };
23
23
 
24
+ Element.prototype.scrollIntoView = jest.fn();
25
+
24
26
  ReactGA.initialize('foo', { testMode: true });
25
27
  jest.clearAllMocks();
26
28
  });