@patternfly/react-core 4.276.6 → 4.276.8

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@patternfly/react-core",
3
- "version": "4.276.6",
3
+ "version": "4.276.8",
4
4
  "description": "This library provides a set of common React components for use with the PatternFly reference implementation.",
5
5
  "main": "dist/js/index.js",
6
6
  "module": "dist/esm/index.js",
@@ -71,5 +71,5 @@
71
71
  "react": "^16.8 || ^17 || ^18",
72
72
  "react-dom": "^16.8 || ^17 || ^18"
73
73
  },
74
- "gitHead": "e2d787cd453afc07405d7f5f10eb6b64a215b064"
74
+ "gitHead": "8e892ec941ec177d7424f5c6a74694b3c7e53941"
75
75
  }
@@ -376,9 +376,22 @@ export class TimePicker extends React.Component<TimePickerProps, TimePickerState
376
376
  onToggle = (isOpen: boolean) => {
377
377
  // on close, parse and validate input
378
378
  this.setState(prevState => {
379
- const { timeRegex, isInvalid } = prevState;
380
- const { delimiter, is24Hour, includeSeconds } = this.props;
381
- const time = parseTime(prevState.timeState, timeRegex, delimiter, !is24Hour, includeSeconds);
379
+ const { timeRegex, isInvalid, timeState } = prevState;
380
+ const { delimiter, is24Hour, includeSeconds, onChange } = this.props;
381
+ const time = parseTime(timeState, timeRegex, delimiter, !is24Hour, includeSeconds);
382
+
383
+ // Call onChange when Enter is pressed in input and timeoption does not exist in menu
384
+ if (onChange && !isOpen && time !== timeState) {
385
+ onChange(
386
+ null,
387
+ time,
388
+ getHours(time, timeRegex),
389
+ getMinutes(time, timeRegex),
390
+ getSeconds(time, timeRegex),
391
+ this.isValid(time)
392
+ );
393
+ }
394
+
382
395
  return {
383
396
  isTimeOptionsOpen: isOpen,
384
397
  timeState: time,
@@ -417,7 +430,6 @@ export class TimePicker extends React.Component<TimePickerProps, TimePickerState
417
430
  onInputChange = (newTime: string, event: React.FormEvent<HTMLInputElement>) => {
418
431
  const { onChange } = this.props;
419
432
  const { timeRegex } = this.state;
420
-
421
433
  if (onChange) {
422
434
  onChange(
423
435
  event,
@@ -86,6 +86,27 @@ describe('TimePicker', () => {
86
86
  expects: { hour: 23, minutes: 59, seconds: null }
87
87
  });
88
88
  });
89
+
90
+ test('should call onChange when pressing Enter', async () => {
91
+ const onChange = jest.fn();
92
+ const user = userEvent.setup();
93
+
94
+ render(<TimePicker onChange={onChange} aria-label="time picker" />);
95
+
96
+ // Take into account timezones when tests are ran
97
+ const isPM = new Date().getHours() > 12;
98
+
99
+ await user.type(screen.getByLabelText('time picker'), `11:11`);
100
+ await user.keyboard('[Enter]');
101
+ expect(onChange).toHaveBeenLastCalledWith(
102
+ expect.any(Object),
103
+ `11:11 ${isPM ? 'PM' : 'AM'}`,
104
+ isPM ? 23 : 11,
105
+ 11,
106
+ null,
107
+ true
108
+ );
109
+ });
89
110
  });
90
111
 
91
112
  describe('test isInvalid', () => {
@@ -17,34 +17,35 @@ DateRangePicker = () => {
17
17
  const [from, setFrom] = React.useState();
18
18
  const [to, setTo] = React.useState();
19
19
 
20
- const toValidator = date => isValidDate(from) && date >= from ? '' : 'To date must be less than from date';
21
- const onFromChange = (_str, date) => {
20
+ const toValidator = (date) =>
21
+ isValidDate(from) && date >= from ? '' : 'The "to" date must be after the "from" date';
22
+
23
+ const onFromChange = (_event, _value, date) => {
22
24
  setFrom(new Date(date));
23
25
  if (isValidDate(date)) {
24
26
  date.setDate(date.getDate() + 1);
25
27
  setTo(yyyyMMddFormat(date));
26
- }
27
- else {
28
+ } else {
28
29
  setTo('');
29
30
  }
30
31
  };
31
32
 
33
+ const onToChange = (_event, _value, date) => {
34
+ if (isValidDate(date)) {
35
+ setTo(yyyyMMddFormat(date));
36
+ }
37
+ };
38
+
32
39
  return (
33
40
  <Split>
34
41
  <SplitItem>
35
- <DatePicker
36
- onChange={onFromChange}
37
- aria-label="Start date"
38
- placeholder="YYYY-MM-DD"
39
- />
40
- </SplitItem>
41
- <SplitItem style={{ padding: '6px 12px 0 12px' }}>
42
- to
42
+ <DatePicker onChange={onFromChange} aria-label="Start date" placeholder="YYYY-MM-DD" />
43
43
  </SplitItem>
44
+ <SplitItem style={{ padding: '6px 12px 0 12px' }}>to</SplitItem>
44
45
  <SplitItem>
45
46
  <DatePicker
46
47
  value={to}
47
- onChange={date => setTo(date)}
48
+ onChange={onToChange}
48
49
  isDisabled={!isValidDate(from)}
49
50
  rangeStart={from}
50
51
  validators={[toValidator]}
@@ -54,23 +55,34 @@ DateRangePicker = () => {
54
55
  </SplitItem>
55
56
  </Split>
56
57
  );
57
- }
58
+ };
58
59
  ```
59
60
 
60
61
  ### Date and time range picker
61
62
 
62
63
  ```js
63
- import { Flex, FlexItem, InputGroup, DatePicker, isValidDate, TimePicker, yyyyMMddFormat, updateDateTime } from '@patternfly/react-core';
64
+ import {
65
+ Flex,
66
+ FlexItem,
67
+ InputGroup,
68
+ DatePicker,
69
+ isValidDate,
70
+ TimePicker,
71
+ yyyyMMddFormat,
72
+ updateDateTime
73
+ } from '@patternfly/react-core';
64
74
 
65
75
  DateTimeRangePicker = () => {
66
76
  const [from, setFrom] = React.useState();
67
77
  const [to, setTo] = React.useState();
68
78
 
69
- const toValidator = date => {
70
- return isValidDate(from) && yyyyMMddFormat(date) >= yyyyMMddFormat(from) ? '' : 'To date must after from date';
79
+ const toValidator = (date) => {
80
+ return isValidDate(from) && yyyyMMddFormat(date) >= yyyyMMddFormat(from)
81
+ ? ''
82
+ : 'The "to" date must be after the "from" date';
71
83
  };
72
-
73
- const onFromDateChange = (inputDate, newFromDate) => {
84
+
85
+ const onFromDateChange = (_event, inputDate, newFromDate) => {
74
86
  if (isValidDate(from) && isValidDate(newFromDate) && inputDate === yyyyMMddFormat(newFromDate)) {
75
87
  newFromDate.setHours(from.getHours());
76
88
  newFromDate.setMinutes(from.getMinutes());
@@ -79,7 +91,7 @@ DateTimeRangePicker = () => {
79
91
  setFrom(new Date(newFromDate));
80
92
  }
81
93
  };
82
-
94
+
83
95
  const onFromTimeChange = (_event, time, hour, minute) => {
84
96
  if (isValidDate(from)) {
85
97
  const updatedFromDate = new Date(from);
@@ -89,16 +101,16 @@ DateTimeRangePicker = () => {
89
101
  }
90
102
  };
91
103
 
92
- const onToDateChange = (inputDate, newToDate) => {
104
+ const onToDateChange = (_event, inputDate, newToDate) => {
93
105
  if (isValidDate(to) && isValidDate(newToDate) && inputDate === yyyyMMddFormat(newToDate)) {
94
106
  newToDate.setHours(to.getHours());
95
107
  newToDate.setMinutes(to.getMinutes());
96
108
  }
97
- if (isValidDate(newToDate) && inputDate === yyyyMMddFormat(newToDate)){
109
+ if (isValidDate(newToDate) && inputDate === yyyyMMddFormat(newToDate)) {
98
110
  setTo(newToDate);
99
111
  }
100
112
  };
101
-
113
+
102
114
  const onToTimeChange = (_event, time, hour, minute) => {
103
115
  if (isValidDate(to)) {
104
116
  const updatedToDate = new Date(to);
@@ -109,24 +121,14 @@ DateTimeRangePicker = () => {
109
121
  };
110
122
 
111
123
  return (
112
- <Flex direction={{default: 'column', lg: 'row'}}>
124
+ <Flex direction={{ default: 'column', lg: 'row' }}>
113
125
  <FlexItem>
114
126
  <InputGroup>
115
- <DatePicker
116
- onChange={onFromDateChange}
117
- aria-label="Start date"
118
- placeholder="YYYY-MM-DD"
119
- />
120
- <TimePicker
121
- aria-label="Start time"
122
- style={{width: '150px'}}
123
- onChange={onFromTimeChange}
124
- />
127
+ <DatePicker onChange={onFromDateChange} aria-label="Start date" placeholder="YYYY-MM-DD" />
128
+ <TimePicker aria-label="Start time" style={{ width: '150px' }} onChange={onFromTimeChange} />
125
129
  </InputGroup>
126
130
  </FlexItem>
127
- <FlexItem>
128
- to
129
- </FlexItem>
131
+ <FlexItem>to</FlexItem>
130
132
  <FlexItem>
131
133
  <InputGroup>
132
134
  <DatePicker
@@ -138,19 +140,22 @@ DateTimeRangePicker = () => {
138
140
  aria-label="End date"
139
141
  placeholder="YYYY-MM-DD"
140
142
  />
141
- <TimePicker style={{width: '150px'}} onChange={onToTimeChange} isDisabled={!isValidDate(from)}/>
143
+ <TimePicker style={{ width: '150px' }} onChange={onToTimeChange} isDisabled={!isValidDate(from)} />
142
144
  </InputGroup>
143
145
  </FlexItem>
144
146
  </Flex>
145
147
  );
146
- }
148
+ };
147
149
  ```
148
150
 
149
-
150
151
  ### Date and time pickers in modal
152
+
151
153
  Modals trap focus and watch a few document level events. In order to place a date picker in a modal:
154
+
152
155
  - To avoid the modal's escape press event handler from overruling the date picker's escape press handlers, use the `DatePickerRef` to close the calendar when it is open and the escape key is pressed.
153
156
  - Append the calendar to the modal to keep it as close to the date picker in the DOM while maintaining correct layouts visually
154
157
  In order to place a time picker in the modal, its menu must be appended to the time picker's parent.
158
+
155
159
  ```ts file="./examples/DateTimePickerInModal.tsx"
160
+
156
161
  ```