bright-components 10.1.0 → 10.2.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.
- package/dist/components/Checkbox/index.js +6 -4
- package/dist/components/DayPicker/NewDayPicker/index.js +207 -0
- package/dist/components/DayPicker/index.js +30 -7
- package/dist/components/DayPickerPanel/index.js +1 -1
- package/dist/components/Modal/ModalBody/index.js +1 -0
- package/dist/components/Modal/index.js +2 -1
- package/dist/components/Time/TimePicker/index.js +1 -0
- package/dist/setupTests.js +5 -0
- package/package.json +3 -2
- package/src/components/Checkbox/index.js +2 -2
- package/src/components/DayPicker/NewDayPicker/index.js +208 -0
- package/src/components/DayPicker/examples.md +17 -0
- package/src/components/DayPicker/index.js +43 -17
- package/src/components/DayPicker/test.js +297 -1
- package/src/components/DayPickerPanel/index.js +1 -1
- package/src/components/DayPickerPanel/test.js +1 -1
- package/src/components/DurationInput/test.js +5 -3
- package/src/components/EmployeePicker/FilterBar/test.js +1 -1
- package/src/components/Modal/ModalBody/index.js +1 -0
- package/src/components/Modal/index.js +2 -1
- package/src/components/Modal/test.js +0 -1
- package/src/components/ResponsiveTabs/test.js +3 -3
- package/src/components/Time/TimePicker/index.js +1 -0
- package/src/components/Time/TimePicker/test.js +29 -28
- package/src/setupTests.js +2 -0
@@ -53,15 +53,17 @@ const Checkmark = _styledComponents.default.span`
|
|
53
53
|
position: relative;
|
54
54
|
top: ${_ref3 => {
|
55
55
|
let {
|
56
|
-
outline
|
56
|
+
outline,
|
57
|
+
disabled
|
57
58
|
} = _ref3;
|
58
|
-
return outline ? '-4px' : '-2px';
|
59
|
+
return outline && !disabled ? '-4px' : '-2px';
|
59
60
|
}};
|
60
61
|
left: ${_ref4 => {
|
61
62
|
let {
|
62
|
-
outline
|
63
|
+
outline,
|
64
|
+
disabled
|
63
65
|
} = _ref4;
|
64
|
-
return outline ? '-2px' : '0';
|
66
|
+
return outline && !disabled ? '-2px' : '0';
|
65
67
|
}};
|
66
68
|
display: block;
|
67
69
|
width: 16px;
|
@@ -0,0 +1,207 @@
|
|
1
|
+
"use strict";
|
2
|
+
|
3
|
+
exports.__esModule = true;
|
4
|
+
exports.default = void 0;
|
5
|
+
|
6
|
+
var _react = _interopRequireWildcard(require("react"));
|
7
|
+
|
8
|
+
var _dateFns = require("date-fns");
|
9
|
+
|
10
|
+
var _styledComponents = _interopRequireDefault(require("styled-components"));
|
11
|
+
|
12
|
+
var _Input = _interopRequireDefault(require("../../Input"));
|
13
|
+
|
14
|
+
var _ErrorMessage = _interopRequireDefault(require("../../ErrorMessage"));
|
15
|
+
|
16
|
+
var _propTypes = require("prop-types");
|
17
|
+
|
18
|
+
var _colors = _interopRequireDefault(require("../../../constants/colors"));
|
19
|
+
|
20
|
+
var _spacing = _interopRequireDefault(require("../../../constants/spacing"));
|
21
|
+
|
22
|
+
var _Calendar = _interopRequireDefault(require("../../Icons/Calendar"));
|
23
|
+
|
24
|
+
var _reactGa = require("react-ga");
|
25
|
+
|
26
|
+
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
27
|
+
|
28
|
+
function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
|
29
|
+
|
30
|
+
function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
|
31
|
+
|
32
|
+
function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }
|
33
|
+
|
34
|
+
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }
|
35
|
+
|
36
|
+
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
|
37
|
+
|
38
|
+
const HiddenBox = (0, _styledComponents.default)(_Input.default.withComponent('div'))`
|
39
|
+
display: flex;
|
40
|
+
align-items: center;
|
41
|
+
${props => props.error && `
|
42
|
+
margin-bottom: 0px !important;
|
43
|
+
border-bottom-left-radius: 0px;
|
44
|
+
border-bottom-right-radius: 0px;
|
45
|
+
border-color: ${_colors.default.borderError} !important;
|
46
|
+
`};
|
47
|
+
input {
|
48
|
+
height: 2.5rem !important;
|
49
|
+
min-height: 2.5rem !important;
|
50
|
+
border: 0 !important;
|
51
|
+
margin: 0 !important;
|
52
|
+
padding: 0 !important;
|
53
|
+
box-shadow: none !important;
|
54
|
+
}
|
55
|
+
`;
|
56
|
+
HiddenBox.displayName = 'HiddenBox';
|
57
|
+
const OpenCalendarIcon = (0, _styledComponents.default)(_Calendar.default)`
|
58
|
+
cursor: ${props => props.disabled ? 'not-allowed' : 'pointer'};
|
59
|
+
margin-left: ${_spacing.default.s1};
|
60
|
+
color: ${_colors.default.primary};
|
61
|
+
`;
|
62
|
+
OpenCalendarIcon.displayName = 'OpenCalendarIcon';
|
63
|
+
const formats = {
|
64
|
+
CA: {
|
65
|
+
placeholderDate: 'YY/MM/DD',
|
66
|
+
dateFormat: 'yy/MM/dd'
|
67
|
+
},
|
68
|
+
default: {
|
69
|
+
placeholderDate: 'DD/MM/YY',
|
70
|
+
dateFormat: 'dd/MM/yy'
|
71
|
+
}
|
72
|
+
};
|
73
|
+
|
74
|
+
const makeInnerDate = (date, dateFormat) => {
|
75
|
+
if (date.from) {
|
76
|
+
return (0, _dateFns.format)(date.from, dateFormat);
|
77
|
+
}
|
78
|
+
|
79
|
+
return '';
|
80
|
+
};
|
81
|
+
|
82
|
+
const NewDisplay = _ref => {
|
83
|
+
let {
|
84
|
+
placeholder,
|
85
|
+
datesToDisplay,
|
86
|
+
range,
|
87
|
+
allowClear,
|
88
|
+
yearRange,
|
89
|
+
onSelectedDate,
|
90
|
+
locale,
|
91
|
+
clearValue,
|
92
|
+
disabled,
|
93
|
+
error,
|
94
|
+
toggleDayPicker,
|
95
|
+
GA: {
|
96
|
+
category,
|
97
|
+
actionId
|
98
|
+
},
|
99
|
+
recordValue,
|
100
|
+
dayPickerOpen
|
101
|
+
} = _ref;
|
102
|
+
const {
|
103
|
+
placeholderDate,
|
104
|
+
dateFormat
|
105
|
+
} = formats[locale] || formats.default;
|
106
|
+
const [hasFocus, setHasFocus] = (0, _react.useState)(false);
|
107
|
+
const [hasError, setHasError] = (0, _react.useState)(false);
|
108
|
+
const [innerDate, setInnerDate] = (0, _react.useState)(makeInnerDate(range, dateFormat));
|
109
|
+
return _react.default.createElement(_react.default.Fragment, null, _react.default.createElement(HiddenBox, {
|
110
|
+
error: error,
|
111
|
+
"data-testid": "input-selector"
|
112
|
+
}, _react.default.createElement(_Input.default, {
|
113
|
+
"data-testid": "new input",
|
114
|
+
placeholder: hasFocus ? placeholderDate : placeholder,
|
115
|
+
value: hasFocus ? innerDate : datesToDisplay,
|
116
|
+
fullWidth: true,
|
117
|
+
disabled: disabled,
|
118
|
+
onFocus: () => {
|
119
|
+
setInnerDate(makeInnerDate(range, dateFormat));
|
120
|
+
setHasFocus(true);
|
121
|
+
setHasError(false);
|
122
|
+
},
|
123
|
+
onBlur: _ref2 => {
|
124
|
+
let {
|
125
|
+
target: {
|
126
|
+
value
|
127
|
+
}
|
128
|
+
} = _ref2;
|
129
|
+
setHasFocus(false);
|
130
|
+
if (dayPickerOpen) toggleDayPicker();
|
131
|
+
|
132
|
+
if (!value && (allowClear || !range.from)) {
|
133
|
+
return range.from ? clearValue() : null;
|
134
|
+
}
|
135
|
+
|
136
|
+
const newDate = {
|
137
|
+
from: (0, _dateFns.parse)(value, dateFormat, new Date()),
|
138
|
+
to: (0, _dateFns.parse)(value, dateFormat, new Date())
|
139
|
+
};
|
140
|
+
const fromYear = (0, _dateFns.getYear)(newDate.from);
|
141
|
+
const toYear = (0, _dateFns.getYear)(newDate.to);
|
142
|
+
|
143
|
+
if (!(0, _dateFns.isValid)(newDate.from) || !(0, _dateFns.isValid)(newDate.to) || fromYear < yearRange.min || toYear > yearRange.max) {
|
144
|
+
setHasError(!((0, _dateFns.isValid)(newDate.from) && (0, _dateFns.isValid)(newDate.to)) ? 'invalid' : 'range');
|
145
|
+
return range.from ? onSelectedDate(allowClear ? '' : range) : null;
|
146
|
+
}
|
147
|
+
|
148
|
+
if (category) {
|
149
|
+
const label = `${(0, _dateFns.format)(newDate.from, 'EEE dd MMM')} ${(0, _dateFns.format)(newDate.from, 'yyyy')}`;
|
150
|
+
(0, _reactGa.event)(_objectSpread({
|
151
|
+
category,
|
152
|
+
action: `${actionId} - Set via Typing`
|
153
|
+
}, recordValue ? {
|
154
|
+
label
|
155
|
+
} : {}));
|
156
|
+
}
|
157
|
+
|
158
|
+
return onSelectedDate(newDate);
|
159
|
+
},
|
160
|
+
onChange: _ref3 => {
|
161
|
+
let {
|
162
|
+
target: {
|
163
|
+
value
|
164
|
+
}
|
165
|
+
} = _ref3;
|
166
|
+
setInnerDate(value.replace(/.*\/$/g, text => value.length < innerDate.length ? value.slice(0, -1) : text).replace(/(\d\d)(\d)/g, '$1/$2').replace(/^(\d\/)$/g, '0$1').replace(/\d\d$/g, text => value.length > innerDate.length && value.length < 7 ? `${text}/` : text).replace(/^(\d\d\/)(\d\/)$/g, '$10$2').replace(/[^\d/]/g, '').replace(/^(.{0,8})(.*)$/g, '$1').replace(/\/\/$/g, '/'));
|
167
|
+
}
|
168
|
+
}), _react.default.createElement(OpenCalendarIcon, {
|
169
|
+
"data-testid": "calendarIcon",
|
170
|
+
size: 22,
|
171
|
+
disabled: disabled,
|
172
|
+
onClick: () => {
|
173
|
+
setHasError(false);
|
174
|
+
toggleDayPicker();
|
175
|
+
}
|
176
|
+
})), hasError && _react.default.createElement(_ErrorMessage.default, {
|
177
|
+
showIcon: false
|
178
|
+
}, hasError === 'invalid' ? 'Date is invalid' : `Year is outside of range. Must be between ${yearRange.min} - ${yearRange.max}`));
|
179
|
+
};
|
180
|
+
|
181
|
+
NewDisplay.propTypes = {
|
182
|
+
placeholder: _propTypes.string.isRequired,
|
183
|
+
datesToDisplay: _propTypes.string.isRequired,
|
184
|
+
range: (0, _propTypes.shape)({
|
185
|
+
from: (0, _propTypes.instanceOf)(Date),
|
186
|
+
to: (0, _propTypes.instanceOf)(Date)
|
187
|
+
}).isRequired,
|
188
|
+
allowClear: _propTypes.bool.isRequired,
|
189
|
+
yearRange: (0, _propTypes.shape)({
|
190
|
+
min: _propTypes.number,
|
191
|
+
max: _propTypes.number
|
192
|
+
}).isRequired,
|
193
|
+
onSelectedDate: _propTypes.func.isRequired,
|
194
|
+
locale: _propTypes.string.isRequired,
|
195
|
+
clearValue: _propTypes.func.isRequired,
|
196
|
+
disabled: _propTypes.bool.isRequired,
|
197
|
+
error: _propTypes.bool.isRequired,
|
198
|
+
toggleDayPicker: _propTypes.func.isRequired,
|
199
|
+
GA: (0, _propTypes.shape)({
|
200
|
+
category: _propTypes.string,
|
201
|
+
actionId: _propTypes.string
|
202
|
+
}).isRequired,
|
203
|
+
recordValue: _propTypes.bool.isRequired,
|
204
|
+
dayPickerOpen: _propTypes.bool.isRequired
|
205
|
+
};
|
206
|
+
var _default = NewDisplay;
|
207
|
+
exports.default = _default;
|
@@ -33,6 +33,8 @@ var _breakpoints = _interopRequireDefault(require("../../constants/breakpoints")
|
|
33
33
|
|
34
34
|
var _Calendar = _interopRequireDefault(require("../Icons/Calendar"));
|
35
35
|
|
36
|
+
var _NewDayPicker = _interopRequireDefault(require("./NewDayPicker"));
|
37
|
+
|
36
38
|
function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
|
37
39
|
|
38
40
|
function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
|
@@ -271,15 +273,17 @@ class DayPicker extends _react.default.Component {
|
|
271
273
|
closeButton,
|
272
274
|
panelAbsoluteOnDesktop,
|
273
275
|
onSelectedDate,
|
274
|
-
isDateSelect
|
276
|
+
isDateSelect,
|
277
|
+
typeable
|
275
278
|
} = _this$props,
|
276
|
-
rest = _objectWithoutProperties(_this$props, ["allowClear", "placeholder", "dateRange", "yearRange", "yearsToDisplay", "style", "error", "disabled", "shortcuts", "disabledDays", "GA", "recordValue", "legacyInputStyle", "closeButton", "panelAbsoluteOnDesktop", "onSelectedDate", "isDateSelect"]);
|
279
|
+
rest = _objectWithoutProperties(_this$props, ["allowClear", "placeholder", "dateRange", "yearRange", "yearsToDisplay", "style", "error", "disabled", "shortcuts", "disabledDays", "GA", "recordValue", "legacyInputStyle", "closeButton", "panelAbsoluteOnDesktop", "onSelectedDate", "isDateSelect", "typeable"]);
|
277
280
|
|
278
281
|
const {
|
279
282
|
dayPickerOpen
|
280
283
|
} = this.state;
|
281
284
|
const {
|
282
|
-
range
|
285
|
+
range,
|
286
|
+
locale
|
283
287
|
} = this.props;
|
284
288
|
const fromDate = range.from ? (0, _dateFns.format)(range.from, this.getDisplayFormat()) : '';
|
285
289
|
const toDate = range.to ? (0, _dateFns.format)(range.to, friendlyShortWithYear) : '';
|
@@ -290,7 +294,7 @@ class DayPicker extends _react.default.Component {
|
|
290
294
|
} = style,
|
291
295
|
otherStyles = _objectWithoutProperties(style, ["width"]);
|
292
296
|
|
293
|
-
return _react.default.createElement(DayPickerInputContainer, rest, _react.default.createElement(InputBox, {
|
297
|
+
return _react.default.createElement(DayPickerInputContainer, rest, !typeable || dateRange ? _react.default.createElement(InputBox, {
|
294
298
|
onClick: this.toggleDayPicker,
|
295
299
|
error: error,
|
296
300
|
disabled: disabled,
|
@@ -299,7 +303,22 @@ class DayPicker extends _react.default.Component {
|
|
299
303
|
}, datesToDisplay ? _react.default.createElement("span", null, datesToDisplay) : _react.default.createElement(Placeholder, null, placeholder), _react.default.createElement(OpenCalendarIcon, {
|
300
304
|
size: 22,
|
301
305
|
disabled: disabled
|
302
|
-
}))
|
306
|
+
})) : _react.default.createElement(_NewDayPicker.default, {
|
307
|
+
placeholder: placeholder,
|
308
|
+
datesToDisplay: datesToDisplay,
|
309
|
+
range: range,
|
310
|
+
allowClear: allowClear,
|
311
|
+
yearRange: yearRange,
|
312
|
+
onSelectedDate: onSelectedDate,
|
313
|
+
locale: locale,
|
314
|
+
clearValue: this.clearValue,
|
315
|
+
disabled: disabled,
|
316
|
+
error: error,
|
317
|
+
toggleDayPicker: this.toggleDayPicker,
|
318
|
+
GA: GA,
|
319
|
+
recordValue: recordValue,
|
320
|
+
dayPickerOpen: dayPickerOpen
|
321
|
+
}), dayPickerOpen && _react.default.createElement(DayRangeContainer, {
|
303
322
|
panelAbsoluteOnDesktop: panelAbsoluteOnDesktop,
|
304
323
|
style: otherStyles,
|
305
324
|
width: width,
|
@@ -360,7 +379,9 @@ DayPicker.propTypes = {
|
|
360
379
|
legacyInputStyle: _propTypes.bool,
|
361
380
|
closeButton: _propTypes.bool,
|
362
381
|
panelAbsoluteOnDesktop: _propTypes.bool,
|
363
|
-
isDateSelect: _propTypes.bool
|
382
|
+
isDateSelect: _propTypes.bool,
|
383
|
+
typeable: _propTypes.bool,
|
384
|
+
locale: _propTypes.string
|
364
385
|
};
|
365
386
|
DayPicker.defaultProps = {
|
366
387
|
recordValue: false,
|
@@ -385,7 +406,9 @@ DayPicker.defaultProps = {
|
|
385
406
|
legacyInputStyle: false,
|
386
407
|
closeButton: false,
|
387
408
|
panelAbsoluteOnDesktop: true,
|
388
|
-
isDateSelect: false
|
409
|
+
isDateSelect: false,
|
410
|
+
typeable: false,
|
411
|
+
locale: 'GB'
|
389
412
|
};
|
390
413
|
|
391
414
|
var _default = (0, _reactOnclickoutside.default)(DayPicker);
|
@@ -207,7 +207,7 @@ class DayPickerPanel extends _react.default.Component {
|
|
207
207
|
to
|
208
208
|
}
|
209
209
|
} = this.state;
|
210
|
-
const actionEvent = selectedDay ? 'Set' : 'Apply';
|
210
|
+
const actionEvent = selectedDay ? 'Set via Date Picker' : 'Apply';
|
211
211
|
|
212
212
|
if (category) {
|
213
213
|
const label = dateRange ? `${(0, _dateFns.format)(from, friendlyShort)} - ${(0, _dateFns.format)(to || from, friendlyShort)} ${(0, _dateFns.format)(to || from, 'yyyy')}` : `${(0, _dateFns.format)(from, friendlyShort)} ${(0, _dateFns.format)(from, 'yyyy')}`;
|
@@ -11,6 +11,7 @@ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { de
|
|
11
11
|
|
12
12
|
const ModalBody = _styledComponents.default.div`
|
13
13
|
padding: ${props => props.noPadding ? '0px' : _spacing.default.s2};
|
14
|
+
overflow-y: auto;
|
14
15
|
`;
|
15
16
|
ModalBody.displayName = 'ModalBody';
|
16
17
|
/* @component */
|
@@ -55,6 +55,8 @@ const Background = _styledComponents.default.div`
|
|
55
55
|
align-items: center;
|
56
56
|
`;
|
57
57
|
const ModalContainer = _styledComponents.default.div`
|
58
|
+
display: flex;
|
59
|
+
flex-direction: column;
|
58
60
|
background: white;
|
59
61
|
position: relative;
|
60
62
|
width: ${props => props.width};
|
@@ -64,7 +66,6 @@ const ModalContainer = _styledComponents.default.div`
|
|
64
66
|
border-radius: ${_vars.default.borderRadius};
|
65
67
|
max-height: 90%;
|
66
68
|
overflow-x: hidden;
|
67
|
-
overflow-y: auto;
|
68
69
|
${props => props.version === '1' && '-webkit-overflow-scrolling: touch'};
|
69
70
|
|
70
71
|
${props => props.allowOverflow && (0, _styledComponents.css)`
|
@@ -133,6 +133,7 @@ const TimePicker = _ref => {
|
|
133
133
|
const valueAsString = (0, _durationToTimeString.default)(value);
|
134
134
|
return _react.default.createElement(_react.default.Fragment, null, _react.default.createElement(MobileTimePicker, {
|
135
135
|
type: "time",
|
136
|
+
"data-testid": "mobileTimePicker",
|
136
137
|
onChange: e => {
|
137
138
|
const timeString = e.target.value;
|
138
139
|
|
package/dist/setupTests.js
CHANGED
@@ -2,6 +2,8 @@
|
|
2
2
|
|
3
3
|
var _enzyme = require("enzyme");
|
4
4
|
|
5
|
+
var _react = require("@testing-library/react");
|
6
|
+
|
5
7
|
var _enzymeAdapterReact = _interopRequireDefault(require("enzyme-adapter-react-16"));
|
6
8
|
|
7
9
|
var _reactGa = _interopRequireDefault(require("react-ga"));
|
@@ -53,4 +55,7 @@ afterEach(() => {
|
|
53
55
|
});
|
54
56
|
(0, _enzyme.configure)({
|
55
57
|
adapter: new _enzymeAdapterReact.default()
|
58
|
+
});
|
59
|
+
(0, _react.configure)({
|
60
|
+
defaultHidden: true
|
56
61
|
});
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "bright-components",
|
3
|
-
"version": "10.1
|
3
|
+
"version": "10.2.1",
|
4
4
|
"private": false,
|
5
5
|
"main": "./dist",
|
6
6
|
"repository": {
|
@@ -73,10 +73,11 @@
|
|
73
73
|
"@babel/preset-env": "^7.16.5",
|
74
74
|
"@babel/preset-react": "^7.7.4",
|
75
75
|
"@svgr/webpack": "4.3.2",
|
76
|
+
"@testing-library/dom": "^8.11.2",
|
76
77
|
"@testing-library/jest-dom": "^4.1.0",
|
77
78
|
"@testing-library/react": "^9.1.4",
|
78
79
|
"@testing-library/react-hooks": "^2.0.1",
|
79
|
-
"@testing-library/user-event": "^
|
80
|
+
"@testing-library/user-event": "^12.8.3",
|
80
81
|
"babel-eslint": "10.0.2",
|
81
82
|
"babel-jest": "^24.9.0",
|
82
83
|
"babel-loader": "8.0.6",
|
@@ -27,8 +27,8 @@ Box.displayName = 'Box';
|
|
27
27
|
|
28
28
|
const Checkmark = styled.span`
|
29
29
|
position: relative;
|
30
|
-
top: ${({ outline }) => (outline ? '-4px' : '-2px')};
|
31
|
-
left: ${({ outline }) => (outline ? '-2px' : '0')};
|
30
|
+
top: ${({ outline, disabled }) => (outline && !disabled ? '-4px' : '-2px')};
|
31
|
+
left: ${({ outline, disabled }) => (outline && !disabled ? '-2px' : '0')};
|
32
32
|
display: block;
|
33
33
|
width: 16px;
|
34
34
|
height: 16px;
|
@@ -0,0 +1,208 @@
|
|
1
|
+
import React, { useState } from 'react';
|
2
|
+
import { format, isValid, parse, getYear } from 'date-fns';
|
3
|
+
import styled from 'styled-components';
|
4
|
+
import Input from 'components/Input';
|
5
|
+
import ErrorMessage from 'components/ErrorMessage';
|
6
|
+
import { string, func, bool, shape, instanceOf, number } from 'prop-types';
|
7
|
+
import colors from 'constants/colors';
|
8
|
+
import spacing from 'constants/spacing';
|
9
|
+
import CalendarIcon from 'components/Icons/Calendar/';
|
10
|
+
import { event } from 'react-ga';
|
11
|
+
|
12
|
+
const HiddenBox = styled(Input.withComponent('div'))`
|
13
|
+
display: flex;
|
14
|
+
align-items: center;
|
15
|
+
${props =>
|
16
|
+
props.error &&
|
17
|
+
`
|
18
|
+
margin-bottom: 0px !important;
|
19
|
+
border-bottom-left-radius: 0px;
|
20
|
+
border-bottom-right-radius: 0px;
|
21
|
+
border-color: ${colors.borderError} !important;
|
22
|
+
`};
|
23
|
+
input {
|
24
|
+
height: 2.5rem !important;
|
25
|
+
min-height: 2.5rem !important;
|
26
|
+
border: 0 !important;
|
27
|
+
margin: 0 !important;
|
28
|
+
padding: 0 !important;
|
29
|
+
box-shadow: none !important;
|
30
|
+
}
|
31
|
+
`;
|
32
|
+
HiddenBox.displayName = 'HiddenBox';
|
33
|
+
|
34
|
+
const OpenCalendarIcon = styled(CalendarIcon)`
|
35
|
+
cursor: ${props => (props.disabled ? 'not-allowed' : 'pointer')};
|
36
|
+
margin-left: ${spacing.s1};
|
37
|
+
color: ${colors.primary};
|
38
|
+
`;
|
39
|
+
OpenCalendarIcon.displayName = 'OpenCalendarIcon';
|
40
|
+
|
41
|
+
const formats = {
|
42
|
+
CA: { placeholderDate: 'YY/MM/DD', dateFormat: 'yy/MM/dd' },
|
43
|
+
default: { placeholderDate: 'DD/MM/YY', dateFormat: 'dd/MM/yy' }
|
44
|
+
};
|
45
|
+
|
46
|
+
const makeInnerDate = (date, dateFormat) => {
|
47
|
+
if (date.from) {
|
48
|
+
return format(date.from, dateFormat);
|
49
|
+
}
|
50
|
+
return '';
|
51
|
+
};
|
52
|
+
|
53
|
+
const NewDisplay = ({
|
54
|
+
placeholder,
|
55
|
+
datesToDisplay,
|
56
|
+
range,
|
57
|
+
allowClear,
|
58
|
+
yearRange,
|
59
|
+
onSelectedDate,
|
60
|
+
locale,
|
61
|
+
clearValue,
|
62
|
+
disabled,
|
63
|
+
error,
|
64
|
+
toggleDayPicker,
|
65
|
+
GA: { category, actionId },
|
66
|
+
recordValue,
|
67
|
+
dayPickerOpen
|
68
|
+
}) => {
|
69
|
+
const { placeholderDate, dateFormat } = formats[locale] || formats.default;
|
70
|
+
|
71
|
+
const [hasFocus, setHasFocus] = useState(false);
|
72
|
+
const [hasError, setHasError] = useState(false);
|
73
|
+
const [innerDate, setInnerDate] = useState(
|
74
|
+
makeInnerDate(range, dateFormat)
|
75
|
+
);
|
76
|
+
|
77
|
+
return (
|
78
|
+
<>
|
79
|
+
<HiddenBox error={error} data-testid="input-selector">
|
80
|
+
<Input
|
81
|
+
data-testid="new input"
|
82
|
+
placeholder={hasFocus ? placeholderDate : placeholder}
|
83
|
+
value={hasFocus ? innerDate : datesToDisplay}
|
84
|
+
fullWidth
|
85
|
+
disabled={disabled}
|
86
|
+
onFocus={() => {
|
87
|
+
setInnerDate(makeInnerDate(range, dateFormat));
|
88
|
+
setHasFocus(true);
|
89
|
+
setHasError(false);
|
90
|
+
}}
|
91
|
+
onBlur={({ target: { value } }) => {
|
92
|
+
setHasFocus(false);
|
93
|
+
if (dayPickerOpen) toggleDayPicker();
|
94
|
+
if (!value && (allowClear || !range.from)) {
|
95
|
+
return range.from ? clearValue() : null;
|
96
|
+
}
|
97
|
+
|
98
|
+
const newDate = {
|
99
|
+
from: parse(value, dateFormat, new Date()),
|
100
|
+
to: parse(value, dateFormat, new Date())
|
101
|
+
};
|
102
|
+
|
103
|
+
const fromYear = getYear(newDate.from);
|
104
|
+
const toYear = getYear(newDate.to);
|
105
|
+
|
106
|
+
if (
|
107
|
+
!isValid(newDate.from) ||
|
108
|
+
!isValid(newDate.to) ||
|
109
|
+
fromYear < yearRange.min ||
|
110
|
+
toYear > yearRange.max
|
111
|
+
) {
|
112
|
+
setHasError(
|
113
|
+
!(isValid(newDate.from) && isValid(newDate.to))
|
114
|
+
? 'invalid'
|
115
|
+
: 'range'
|
116
|
+
);
|
117
|
+
|
118
|
+
return range.from
|
119
|
+
? onSelectedDate(allowClear ? '' : range)
|
120
|
+
: null;
|
121
|
+
}
|
122
|
+
|
123
|
+
if (category) {
|
124
|
+
const label = `${format(
|
125
|
+
newDate.from,
|
126
|
+
'EEE dd MMM'
|
127
|
+
)} ${format(newDate.from, 'yyyy')}`;
|
128
|
+
|
129
|
+
event({
|
130
|
+
category,
|
131
|
+
action: `${actionId} - Set via Typing`,
|
132
|
+
...(recordValue ? { label } : {})
|
133
|
+
});
|
134
|
+
}
|
135
|
+
|
136
|
+
return onSelectedDate(newDate);
|
137
|
+
}}
|
138
|
+
onChange={({ target: { value } }) => {
|
139
|
+
setInnerDate(
|
140
|
+
value
|
141
|
+
.replace(/.*\/$/g, text =>
|
142
|
+
value.length < innerDate.length
|
143
|
+
? value.slice(0, -1)
|
144
|
+
: text
|
145
|
+
)
|
146
|
+
.replace(/(\d\d)(\d)/g, '$1/$2')
|
147
|
+
.replace(/^(\d\/)$/g, '0$1')
|
148
|
+
.replace(/\d\d$/g, text =>
|
149
|
+
value.length > innerDate.length &&
|
150
|
+
value.length < 7
|
151
|
+
? `${text}/`
|
152
|
+
: text
|
153
|
+
)
|
154
|
+
.replace(/^(\d\d\/)(\d\/)$/g, '$10$2')
|
155
|
+
.replace(/[^\d/]/g, '')
|
156
|
+
.replace(/^(.{0,8})(.*)$/g, '$1')
|
157
|
+
.replace(/\/\/$/g, '/')
|
158
|
+
);
|
159
|
+
}}
|
160
|
+
/>
|
161
|
+
<OpenCalendarIcon
|
162
|
+
data-testid="calendarIcon"
|
163
|
+
size={22}
|
164
|
+
disabled={disabled}
|
165
|
+
onClick={() => {
|
166
|
+
setHasError(false);
|
167
|
+
toggleDayPicker();
|
168
|
+
}}
|
169
|
+
/>
|
170
|
+
</HiddenBox>
|
171
|
+
{hasError && (
|
172
|
+
<ErrorMessage showIcon={false}>
|
173
|
+
{hasError === 'invalid'
|
174
|
+
? 'Date is invalid'
|
175
|
+
: `Year is outside of range. Must be between ${yearRange.min} - ${yearRange.max}`}
|
176
|
+
</ErrorMessage>
|
177
|
+
)}
|
178
|
+
</>
|
179
|
+
);
|
180
|
+
};
|
181
|
+
|
182
|
+
NewDisplay.propTypes = {
|
183
|
+
placeholder: string.isRequired,
|
184
|
+
datesToDisplay: string.isRequired,
|
185
|
+
range: shape({
|
186
|
+
from: instanceOf(Date),
|
187
|
+
to: instanceOf(Date)
|
188
|
+
}).isRequired,
|
189
|
+
allowClear: bool.isRequired,
|
190
|
+
yearRange: shape({
|
191
|
+
min: number,
|
192
|
+
max: number
|
193
|
+
}).isRequired,
|
194
|
+
onSelectedDate: func.isRequired,
|
195
|
+
locale: string.isRequired,
|
196
|
+
clearValue: func.isRequired,
|
197
|
+
disabled: bool.isRequired,
|
198
|
+
error: bool.isRequired,
|
199
|
+
toggleDayPicker: func.isRequired,
|
200
|
+
GA: shape({
|
201
|
+
category: string,
|
202
|
+
actionId: string
|
203
|
+
}).isRequired,
|
204
|
+
recordValue: bool.isRequired,
|
205
|
+
dayPickerOpen: bool.isRequired
|
206
|
+
};
|
207
|
+
|
208
|
+
export default NewDisplay;
|
@@ -231,3 +231,20 @@ initialState={dates: {from: new Date(2018, 3, 1), to: undefined}};
|
|
231
231
|
isDateSelect={true}
|
232
232
|
/>
|
233
233
|
```
|
234
|
+
Day Picker - typeable
|
235
|
+
```js
|
236
|
+
initialState={dates: {from: new Date(2018, 3, 1), to: undefined}};
|
237
|
+
<DayPicker
|
238
|
+
range={state.dates}
|
239
|
+
yearRange={{ min: 2000, max: 2030}}
|
240
|
+
style={{
|
241
|
+
width: '70%'
|
242
|
+
}}
|
243
|
+
GA={{
|
244
|
+
category: 'Test',
|
245
|
+
actionId: 'Test'
|
246
|
+
}}
|
247
|
+
onSelectedDate={dates=>setState({dates})}
|
248
|
+
typeable
|
249
|
+
/>
|
250
|
+
```
|