bright-components 9.30.0 → 9.33.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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
  });