@instructure/ui-date-time-input 8.23.1-snapshot.26 → 8.23.1-snapshot.31
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/es/DateTimeInput/index.js +45 -1
- package/es/DateTimeInput/props.js +4 -2
- package/lib/DateTimeInput/index.js +45 -1
- package/lib/DateTimeInput/props.js +4 -2
- package/package.json +19 -19
- package/src/DateTimeInput/README.md +80 -15
- package/src/DateTimeInput/index.tsx +39 -0
- package/src/DateTimeInput/props.ts +24 -3
- package/tsconfig.build.tsbuildinfo +1 -1
- package/types/DateTimeInput/index.d.ts +1 -0
- package/types/DateTimeInput/index.d.ts.map +1 -1
- package/types/DateTimeInput/props.d.ts +7 -1
- package/types/DateTimeInput/props.d.ts.map +1 -1
|
@@ -254,6 +254,29 @@ let DateTimeInput = (_dec = testable(), _dec(_class = (_class2 = class DateTimeI
|
|
|
254
254
|
}
|
|
255
255
|
|
|
256
256
|
const newTimeSelectValue = (_this$state = this.state) !== null && _this$state !== void 0 && _this$state.timeSelectValue ? this.state.timeSelectValue : (_this$_timeInput = this._timeInput) === null || _this$_timeInput === void 0 ? void 0 : _this$_timeInput.getBaseDate().minute(parsed.minute()).hour(parsed.hour()).toISOString();
|
|
257
|
+
|
|
258
|
+
if (this.isDisabledDate(parsed)) {
|
|
259
|
+
let text = typeof this.props.disabledDateTimeMessage === 'function' ? this.props.disabledDateTimeMessage(parsed.toISOString(true)) : this.props.disabledDateTimeMessage;
|
|
260
|
+
|
|
261
|
+
if (!text) {
|
|
262
|
+
text = typeof this.props.invalidDateTimeMessage === 'function' ? this.props.invalidDateTimeMessage(parsed.toISOString(true)) : this.props.invalidDateTimeMessage;
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
errorMsg = text ? {
|
|
266
|
+
text,
|
|
267
|
+
type: 'error'
|
|
268
|
+
} : void 0;
|
|
269
|
+
return {
|
|
270
|
+
iso: parsed.clone(),
|
|
271
|
+
calendarSelectedDate: parsed.clone(),
|
|
272
|
+
dateInputTextChanged: false,
|
|
273
|
+
dateInputText: parsed.format(this.dateFormat),
|
|
274
|
+
message: errorMsg,
|
|
275
|
+
timeSelectValue: newTimeSelectValue,
|
|
276
|
+
renderedDate: parsed.clone()
|
|
277
|
+
};
|
|
278
|
+
}
|
|
279
|
+
|
|
257
280
|
return {
|
|
258
281
|
iso: parsed.clone(),
|
|
259
282
|
calendarSelectedDate: parsed.clone(),
|
|
@@ -309,6 +332,26 @@ let DateTimeInput = (_dec = testable(), _dec(_class = (_class2 = class DateTimeI
|
|
|
309
332
|
|
|
310
333
|
get dateFormat() {
|
|
311
334
|
return this.props.dateFormat;
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
isDisabledDate(date) {
|
|
338
|
+
const disabledDates = this.props.disabledDates;
|
|
339
|
+
|
|
340
|
+
if (!disabledDates) {
|
|
341
|
+
return false;
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
if (Array.isArray(disabledDates)) {
|
|
345
|
+
for (const aDisabledDate of disabledDates) {
|
|
346
|
+
if (date.isSame(aDisabledDate, 'day')) {
|
|
347
|
+
return true;
|
|
348
|
+
}
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
return false;
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
return disabledDates(date.toISOString());
|
|
312
355
|
} // Called when the user enters text into dateInput
|
|
313
356
|
|
|
314
357
|
|
|
@@ -369,7 +412,8 @@ let DateTimeInput = (_dec = testable(), _dec(_class = (_class2 = class DateTimeI
|
|
|
369
412
|
isOutsideMonth: !date.isSame(renderedDate, 'month'),
|
|
370
413
|
label: date.format('D MMMM YYYY') // used by screen readers
|
|
371
414
|
,
|
|
372
|
-
onClick: this.handleDayClick
|
|
415
|
+
onClick: this.handleDayClick,
|
|
416
|
+
interaction: this.isDisabledDate(date) ? 'disabled' : 'enabled'
|
|
373
417
|
}, date.format('DD'));
|
|
374
418
|
});
|
|
375
419
|
} // The default weekdays rendered in the calendar
|
|
@@ -51,7 +51,9 @@ const propTypes = {
|
|
|
51
51
|
onChange: PropTypes.func,
|
|
52
52
|
dateInputRef: PropTypes.func,
|
|
53
53
|
timeInputRef: PropTypes.func,
|
|
54
|
-
onBlur: PropTypes.func
|
|
54
|
+
onBlur: PropTypes.func,
|
|
55
|
+
disabledDates: PropTypes.oneOfType([PropTypes.func, PropTypes.arrayOf(PropTypes.string)]),
|
|
56
|
+
disabledDateTimeMessage: PropTypes.oneOfType([PropTypes.string, PropTypes.func])
|
|
55
57
|
};
|
|
56
|
-
const allowedProps = ['description', 'dateRenderLabel', 'prevMonthLabel', 'nextMonthLabel', 'datePlaceholder', 'dateFormat', 'interaction', 'timeRenderLabel', 'timeStep', 'timeFormat', 'locale', 'timezone', 'invalidDateTimeMessage', 'messages', 'messageFormat', 'layout', 'rowSpacing', 'colSpacing', 'value', 'defaultValue', 'renderWeekdayLabels', 'isRequired', 'onChange', 'dateInputRef', 'timeInputRef', 'onBlur'];
|
|
58
|
+
const allowedProps = ['description', 'dateRenderLabel', 'prevMonthLabel', 'nextMonthLabel', 'datePlaceholder', 'dateFormat', 'interaction', 'timeRenderLabel', 'timeStep', 'timeFormat', 'locale', 'timezone', 'invalidDateTimeMessage', 'messages', 'messageFormat', 'layout', 'rowSpacing', 'colSpacing', 'value', 'defaultValue', 'renderWeekdayLabels', 'isRequired', 'onChange', 'dateInputRef', 'timeInputRef', 'onBlur', 'disabledDates', 'disabledDateTimeMessage'];
|
|
57
59
|
export { propTypes, allowedProps };
|
|
@@ -260,6 +260,29 @@ let DateTimeInput = (_dec = (0, _testable.testable)(), _dec(_class = (_class2 =
|
|
|
260
260
|
}
|
|
261
261
|
|
|
262
262
|
const newTimeSelectValue = (_this$state = this.state) !== null && _this$state !== void 0 && _this$state.timeSelectValue ? this.state.timeSelectValue : (_this$_timeInput = this._timeInput) === null || _this$_timeInput === void 0 ? void 0 : _this$_timeInput.getBaseDate().minute(parsed.minute()).hour(parsed.hour()).toISOString();
|
|
263
|
+
|
|
264
|
+
if (this.isDisabledDate(parsed)) {
|
|
265
|
+
let text = typeof this.props.disabledDateTimeMessage === 'function' ? this.props.disabledDateTimeMessage(parsed.toISOString(true)) : this.props.disabledDateTimeMessage;
|
|
266
|
+
|
|
267
|
+
if (!text) {
|
|
268
|
+
text = typeof this.props.invalidDateTimeMessage === 'function' ? this.props.invalidDateTimeMessage(parsed.toISOString(true)) : this.props.invalidDateTimeMessage;
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
errorMsg = text ? {
|
|
272
|
+
text,
|
|
273
|
+
type: 'error'
|
|
274
|
+
} : void 0;
|
|
275
|
+
return {
|
|
276
|
+
iso: parsed.clone(),
|
|
277
|
+
calendarSelectedDate: parsed.clone(),
|
|
278
|
+
dateInputTextChanged: false,
|
|
279
|
+
dateInputText: parsed.format(this.dateFormat),
|
|
280
|
+
message: errorMsg,
|
|
281
|
+
timeSelectValue: newTimeSelectValue,
|
|
282
|
+
renderedDate: parsed.clone()
|
|
283
|
+
};
|
|
284
|
+
}
|
|
285
|
+
|
|
263
286
|
return {
|
|
264
287
|
iso: parsed.clone(),
|
|
265
288
|
calendarSelectedDate: parsed.clone(),
|
|
@@ -315,6 +338,26 @@ let DateTimeInput = (_dec = (0, _testable.testable)(), _dec(_class = (_class2 =
|
|
|
315
338
|
|
|
316
339
|
get dateFormat() {
|
|
317
340
|
return this.props.dateFormat;
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
isDisabledDate(date) {
|
|
344
|
+
const disabledDates = this.props.disabledDates;
|
|
345
|
+
|
|
346
|
+
if (!disabledDates) {
|
|
347
|
+
return false;
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
if (Array.isArray(disabledDates)) {
|
|
351
|
+
for (const aDisabledDate of disabledDates) {
|
|
352
|
+
if (date.isSame(aDisabledDate, 'day')) {
|
|
353
|
+
return true;
|
|
354
|
+
}
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
return false;
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
return disabledDates(date.toISOString());
|
|
318
361
|
} // Called when the user enters text into dateInput
|
|
319
362
|
|
|
320
363
|
|
|
@@ -378,7 +421,8 @@ let DateTimeInput = (_dec = (0, _testable.testable)(), _dec(_class = (_class2 =
|
|
|
378
421
|
isOutsideMonth: !date.isSame(renderedDate, 'month'),
|
|
379
422
|
label: date.format('D MMMM YYYY') // used by screen readers
|
|
380
423
|
,
|
|
381
|
-
onClick: this.handleDayClick
|
|
424
|
+
onClick: this.handleDayClick,
|
|
425
|
+
interaction: this.isDisabledDate(date) ? 'disabled' : 'enabled'
|
|
382
426
|
}, date.format('DD'));
|
|
383
427
|
});
|
|
384
428
|
} // The default weekdays rendered in the calendar
|
|
@@ -64,8 +64,10 @@ const propTypes = {
|
|
|
64
64
|
onChange: _propTypes.default.func,
|
|
65
65
|
dateInputRef: _propTypes.default.func,
|
|
66
66
|
timeInputRef: _propTypes.default.func,
|
|
67
|
-
onBlur: _propTypes.default.func
|
|
67
|
+
onBlur: _propTypes.default.func,
|
|
68
|
+
disabledDates: _propTypes.default.oneOfType([_propTypes.default.func, _propTypes.default.arrayOf(_propTypes.default.string)]),
|
|
69
|
+
disabledDateTimeMessage: _propTypes.default.oneOfType([_propTypes.default.string, _propTypes.default.func])
|
|
68
70
|
};
|
|
69
71
|
exports.propTypes = propTypes;
|
|
70
|
-
const allowedProps = ['description', 'dateRenderLabel', 'prevMonthLabel', 'nextMonthLabel', 'datePlaceholder', 'dateFormat', 'interaction', 'timeRenderLabel', 'timeStep', 'timeFormat', 'locale', 'timezone', 'invalidDateTimeMessage', 'messages', 'messageFormat', 'layout', 'rowSpacing', 'colSpacing', 'value', 'defaultValue', 'renderWeekdayLabels', 'isRequired', 'onChange', 'dateInputRef', 'timeInputRef', 'onBlur'];
|
|
72
|
+
const allowedProps = ['description', 'dateRenderLabel', 'prevMonthLabel', 'nextMonthLabel', 'datePlaceholder', 'dateFormat', 'interaction', 'timeRenderLabel', 'timeStep', 'timeFormat', 'locale', 'timezone', 'invalidDateTimeMessage', 'messages', 'messageFormat', 'layout', 'rowSpacing', 'colSpacing', 'value', 'defaultValue', 'renderWeekdayLabels', 'isRequired', 'onChange', 'dateInputRef', 'timeInputRef', 'onBlur', 'disabledDates', 'disabledDateTimeMessage'];
|
|
71
73
|
exports.allowedProps = allowedProps;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@instructure/ui-date-time-input",
|
|
3
|
-
"version": "8.23.1-snapshot.
|
|
3
|
+
"version": "8.23.1-snapshot.31+6580c14f5",
|
|
4
4
|
"description": "A UI component that allows to select date and time.",
|
|
5
5
|
"author": "Instructure, Inc. Engineering and Product Design",
|
|
6
6
|
"module": "./es/index.js",
|
|
@@ -23,26 +23,26 @@
|
|
|
23
23
|
},
|
|
24
24
|
"license": "MIT",
|
|
25
25
|
"devDependencies": {
|
|
26
|
-
"@instructure/ui-babel-preset": "8.23.1-snapshot.
|
|
27
|
-
"@instructure/ui-test-locator": "8.23.1-snapshot.
|
|
28
|
-
"@instructure/ui-test-utils": "8.23.1-snapshot.
|
|
26
|
+
"@instructure/ui-babel-preset": "8.23.1-snapshot.31+6580c14f5",
|
|
27
|
+
"@instructure/ui-test-locator": "8.23.1-snapshot.31+6580c14f5",
|
|
28
|
+
"@instructure/ui-test-utils": "8.23.1-snapshot.31+6580c14f5"
|
|
29
29
|
},
|
|
30
30
|
"dependencies": {
|
|
31
31
|
"@babel/runtime": "^7.13.10",
|
|
32
|
-
"@instructure/debounce": "8.23.1-snapshot.
|
|
33
|
-
"@instructure/emotion": "8.23.1-snapshot.
|
|
34
|
-
"@instructure/ui-a11y-content": "8.23.1-snapshot.
|
|
35
|
-
"@instructure/ui-buttons": "8.23.1-snapshot.
|
|
36
|
-
"@instructure/ui-calendar": "8.23.1-snapshot.
|
|
37
|
-
"@instructure/ui-date-input": "8.23.1-snapshot.
|
|
38
|
-
"@instructure/ui-form-field": "8.23.1-snapshot.
|
|
39
|
-
"@instructure/ui-i18n": "8.23.1-snapshot.
|
|
40
|
-
"@instructure/ui-icons": "8.23.1-snapshot.
|
|
41
|
-
"@instructure/ui-prop-types": "8.23.1-snapshot.
|
|
42
|
-
"@instructure/ui-react-utils": "8.23.1-snapshot.
|
|
43
|
-
"@instructure/ui-testable": "8.23.1-snapshot.
|
|
44
|
-
"@instructure/ui-time-select": "8.23.1-snapshot.
|
|
45
|
-
"@instructure/ui-utils": "8.23.1-snapshot.
|
|
32
|
+
"@instructure/debounce": "8.23.1-snapshot.31+6580c14f5",
|
|
33
|
+
"@instructure/emotion": "8.23.1-snapshot.31+6580c14f5",
|
|
34
|
+
"@instructure/ui-a11y-content": "8.23.1-snapshot.31+6580c14f5",
|
|
35
|
+
"@instructure/ui-buttons": "8.23.1-snapshot.31+6580c14f5",
|
|
36
|
+
"@instructure/ui-calendar": "8.23.1-snapshot.31+6580c14f5",
|
|
37
|
+
"@instructure/ui-date-input": "8.23.1-snapshot.31+6580c14f5",
|
|
38
|
+
"@instructure/ui-form-field": "8.23.1-snapshot.31+6580c14f5",
|
|
39
|
+
"@instructure/ui-i18n": "8.23.1-snapshot.31+6580c14f5",
|
|
40
|
+
"@instructure/ui-icons": "8.23.1-snapshot.31+6580c14f5",
|
|
41
|
+
"@instructure/ui-prop-types": "8.23.1-snapshot.31+6580c14f5",
|
|
42
|
+
"@instructure/ui-react-utils": "8.23.1-snapshot.31+6580c14f5",
|
|
43
|
+
"@instructure/ui-testable": "8.23.1-snapshot.31+6580c14f5",
|
|
44
|
+
"@instructure/ui-time-select": "8.23.1-snapshot.31+6580c14f5",
|
|
45
|
+
"@instructure/ui-utils": "8.23.1-snapshot.31+6580c14f5",
|
|
46
46
|
"prop-types": "^15"
|
|
47
47
|
},
|
|
48
48
|
"peerDependencies": {
|
|
@@ -52,5 +52,5 @@
|
|
|
52
52
|
"access": "public"
|
|
53
53
|
},
|
|
54
54
|
"sideEffects": false,
|
|
55
|
-
"gitHead": "
|
|
55
|
+
"gitHead": "6580c14f523ae758258b43f961f558773f7eddfa"
|
|
56
56
|
}
|
|
@@ -5,13 +5,19 @@ describes: DateTimeInput
|
|
|
5
5
|
A DateTimeInput component is used to enter a date-time value. It is built as a composition
|
|
6
6
|
of the [DateInput](#DateInput) and [TimeSelect](#TimeSelect) components.
|
|
7
7
|
|
|
8
|
-
|
|
8
|
+
The properties of DateTimeInput prefaced with _date_ are passed to the underlying [DateInput](#DateInput)
|
|
9
|
+
(e.g. _dateLabel_ is DateInput's _label_), while the properties prefaced
|
|
10
|
+
with _time_ are forwarded to the underlying
|
|
11
|
+
[TimeSelect](#TimeSelect). Others are either shared by both sub-components (e.g. locale), or
|
|
12
|
+
are unique to DateTimeInput (e.g. description).
|
|
13
|
+
|
|
14
|
+
### Localization
|
|
9
15
|
|
|
10
16
|
The component is localized via its `locale` and `timezone` parameters. Both are read from `props`, `context` and from the browser's locale in this priority order. `locale` determines the language and format dates and time are displayed in (e.g. month names, AM/PM or 24-hour format) and the beginning of the week (e.g. Monday in Germany, Sunday in the U.S.) in the dropdown calendar.
|
|
11
17
|
|
|
12
|
-
|
|
18
|
+
### Examples
|
|
13
19
|
|
|
14
|
-
A DateTimeInput with `columns` layout and a default value:
|
|
20
|
+
#### A DateTimeInput with `columns` layout and a default value:
|
|
15
21
|
|
|
16
22
|
```js
|
|
17
23
|
---
|
|
@@ -21,7 +27,7 @@ render: false
|
|
|
21
27
|
class Example extends React.Component {
|
|
22
28
|
render () {
|
|
23
29
|
return (
|
|
24
|
-
<div style= { {height:
|
|
30
|
+
<div style= { {height: '10rem',width: '40em'}}>
|
|
25
31
|
<DateTimeInput
|
|
26
32
|
description="Pick a date and time"
|
|
27
33
|
datePlaceholder="Choose a date"
|
|
@@ -39,7 +45,7 @@ class Example extends React.Component {
|
|
|
39
45
|
render(<Example />)
|
|
40
46
|
```
|
|
41
47
|
|
|
42
|
-
A required DateInput with `stacked` layout that warns if the value in the past:
|
|
48
|
+
#### A required DateInput with `stacked` layout that warns if the value in the past:
|
|
43
49
|
|
|
44
50
|
```js
|
|
45
51
|
---
|
|
@@ -69,9 +75,9 @@ class Example extends React.Component {
|
|
|
69
75
|
render () {
|
|
70
76
|
const text = this.state.value ? new Date(this.state.value).toString() : 'N/A'
|
|
71
77
|
return (
|
|
72
|
-
<div style={{width: '
|
|
78
|
+
<div style={{width: '25em'}}>
|
|
73
79
|
<div style={{marginBottom: '1em', fontStyle: 'italic'}}>You entered:<br/>{text}</div>
|
|
74
|
-
<div style={{height:
|
|
80
|
+
<div style={{height: '14rem'}}>
|
|
75
81
|
<DateTimeInput
|
|
76
82
|
description={<ScreenReaderContent>Pick a date and time</ScreenReaderContent>}
|
|
77
83
|
datePlaceholder="Choose"
|
|
@@ -94,7 +100,7 @@ class Example extends React.Component {
|
|
|
94
100
|
render(<Example />)
|
|
95
101
|
```
|
|
96
102
|
|
|
97
|
-
A disabled DateTimeInput:
|
|
103
|
+
#### A disabled DateTimeInput:
|
|
98
104
|
|
|
99
105
|
```js
|
|
100
106
|
---
|
|
@@ -115,7 +121,7 @@ render: true
|
|
|
115
121
|
/>
|
|
116
122
|
```
|
|
117
123
|
|
|
118
|
-
A DateTimeInput in a different locale and timezone where these are set from the React `context`:
|
|
124
|
+
#### A DateTimeInput in a different locale and timezone where these are set from the React `context`:
|
|
119
125
|
|
|
120
126
|
```js
|
|
121
127
|
---
|
|
@@ -126,7 +132,7 @@ class Example extends React.Component {
|
|
|
126
132
|
render() {
|
|
127
133
|
return (
|
|
128
134
|
<ApplyLocale locale="fr" timezone="Africa/Nairobi">
|
|
129
|
-
<div style={{ height:
|
|
135
|
+
<div style={{ height: '12rem', width: '40em' }}>
|
|
130
136
|
<DateTimeInput
|
|
131
137
|
description="Pick a date and time"
|
|
132
138
|
datePlaceholder="Choose a date"
|
|
@@ -147,8 +153,67 @@ class Example extends React.Component {
|
|
|
147
153
|
render(<Example />)
|
|
148
154
|
```
|
|
149
155
|
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
156
|
+
#### A `DateTimeInput` with some disabled dates that are supplied via a `string` array:
|
|
157
|
+
|
|
158
|
+
```js
|
|
159
|
+
---
|
|
160
|
+
example: true
|
|
161
|
+
render: true
|
|
162
|
+
---
|
|
163
|
+
<DateTimeInput
|
|
164
|
+
description="Pick a date and time"
|
|
165
|
+
datePlaceholder="Choose a date"
|
|
166
|
+
dateRenderLabel="Date"
|
|
167
|
+
timeRenderLabel="Time"
|
|
168
|
+
invalidDateTimeMessage="Invalid date"
|
|
169
|
+
disabledDateTimeMessage="Disabled date"
|
|
170
|
+
prevMonthLabel="Previous month"
|
|
171
|
+
nextMonthLabel="Next month"
|
|
172
|
+
defaultValue="2022-04-08T13:30"
|
|
173
|
+
layout="columns"
|
|
174
|
+
disabledDates={['2022-04-01T13:30', '2022-04-03T13:30', '2022-04-04T13:30']}
|
|
175
|
+
locale="en-us"
|
|
176
|
+
timezone="America/Denver"
|
|
177
|
+
/>
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
#### A `DateTimeInput` with some disabled dates that are supplied via a `function`:
|
|
181
|
+
|
|
182
|
+
```js
|
|
183
|
+
---
|
|
184
|
+
example: true
|
|
185
|
+
render: false
|
|
186
|
+
---
|
|
187
|
+
const locale = 'en-us'
|
|
188
|
+
const timezone = 'America/Denver'
|
|
189
|
+
|
|
190
|
+
class Example extends React.Component {
|
|
191
|
+
getDisabledDates(isoDateToCheck) {
|
|
192
|
+
const parsed = moment.tz(isoDateToCheck, [moment.ISO_8601], locale, timezone)
|
|
193
|
+
const now = moment().locale(locale).tz(timezone)
|
|
194
|
+
return parsed.isBefore(now)
|
|
195
|
+
}
|
|
196
|
+
render() {
|
|
197
|
+
return (
|
|
198
|
+
<div style= { {height: '12rem', width: '40em'}}>
|
|
199
|
+
<DateTimeInput
|
|
200
|
+
description="Pick a date and time"
|
|
201
|
+
datePlaceholder="Choose a date"
|
|
202
|
+
dateRenderLabel="Date"
|
|
203
|
+
timeRenderLabel="Time"
|
|
204
|
+
invalidDateTimeMessage={(rawDateValue) => 'Invalid date: ' + rawDateValue}
|
|
205
|
+
disabledDateTimeMessage={(rawDateValue) => 'Disabled date: ' + rawDateValue}
|
|
206
|
+
prevMonthLabel="Previous month"
|
|
207
|
+
nextMonthLabel="Next month"
|
|
208
|
+
defaultValue="2022-04-08T13:30"
|
|
209
|
+
layout="columns"
|
|
210
|
+
disabledDates={this.getDisabledDates}
|
|
211
|
+
locale={locale}
|
|
212
|
+
timezone={timezone}
|
|
213
|
+
/>
|
|
214
|
+
</div>)
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
render(<Example />)
|
|
219
|
+
```
|
|
@@ -143,6 +143,28 @@ class DateTimeInput extends Component<DateTimeInputProps, DateTimeInputState> {
|
|
|
143
143
|
.minute(parsed.minute())
|
|
144
144
|
.hour(parsed.hour())
|
|
145
145
|
.toISOString()
|
|
146
|
+
if (this.isDisabledDate(parsed)) {
|
|
147
|
+
let text =
|
|
148
|
+
typeof this.props.disabledDateTimeMessage === 'function'
|
|
149
|
+
? this.props.disabledDateTimeMessage(parsed.toISOString(true))
|
|
150
|
+
: this.props.disabledDateTimeMessage
|
|
151
|
+
if (!text) {
|
|
152
|
+
text =
|
|
153
|
+
typeof this.props.invalidDateTimeMessage === 'function'
|
|
154
|
+
? this.props.invalidDateTimeMessage(parsed.toISOString(true))
|
|
155
|
+
: this.props.invalidDateTimeMessage
|
|
156
|
+
}
|
|
157
|
+
errorMsg = text ? { text, type: 'error' } : undefined
|
|
158
|
+
return {
|
|
159
|
+
iso: parsed.clone(),
|
|
160
|
+
calendarSelectedDate: parsed.clone(),
|
|
161
|
+
dateInputTextChanged: false,
|
|
162
|
+
dateInputText: parsed.format(this.dateFormat),
|
|
163
|
+
message: errorMsg,
|
|
164
|
+
timeSelectValue: newTimeSelectValue,
|
|
165
|
+
renderedDate: parsed.clone()
|
|
166
|
+
}
|
|
167
|
+
}
|
|
146
168
|
return {
|
|
147
169
|
iso: parsed.clone(),
|
|
148
170
|
calendarSelectedDate: parsed.clone(),
|
|
@@ -196,6 +218,22 @@ class DateTimeInput extends Component<DateTimeInputProps, DateTimeInputState> {
|
|
|
196
218
|
return this.props.dateFormat
|
|
197
219
|
}
|
|
198
220
|
|
|
221
|
+
isDisabledDate(date: Moment) {
|
|
222
|
+
const disabledDates = this.props.disabledDates
|
|
223
|
+
if (!disabledDates) {
|
|
224
|
+
return false
|
|
225
|
+
}
|
|
226
|
+
if (Array.isArray(disabledDates)) {
|
|
227
|
+
for (const aDisabledDate of disabledDates) {
|
|
228
|
+
if (date.isSame(aDisabledDate, 'day')) {
|
|
229
|
+
return true
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
return false
|
|
233
|
+
}
|
|
234
|
+
return disabledDates(date.toISOString())
|
|
235
|
+
}
|
|
236
|
+
|
|
199
237
|
// Called when the user enters text into dateInput
|
|
200
238
|
handleDateTextChange = (_event: SyntheticEvent, date: { value: string }) => {
|
|
201
239
|
const dateParsed = this.tryParseDate(date.value)
|
|
@@ -408,6 +446,7 @@ class DateTimeInput extends Component<DateTimeInputProps, DateTimeInputState> {
|
|
|
408
446
|
isOutsideMonth={!date.isSame(renderedDate, 'month')}
|
|
409
447
|
label={date.format('D MMMM YYYY')} // used by screen readers
|
|
410
448
|
onClick={this.handleDayClick}
|
|
449
|
+
interaction={this.isDisabledDate(date) ? 'disabled' : 'enabled'}
|
|
411
450
|
>
|
|
412
451
|
{date.format('DD')}
|
|
413
452
|
</DateInput.Day>
|
|
@@ -205,7 +205,7 @@ type DateTimeInputProps = {
|
|
|
205
205
|
* Called when the date-time value has changed.
|
|
206
206
|
* The passed in parameters are:
|
|
207
207
|
* - *event*: The triggering event (which may be from the underlying
|
|
208
|
-
*
|
|
208
|
+
* `DateInput` or `TimeSelect`)
|
|
209
209
|
* - *isoValue*: The new date value in ISO8601 format, undefined if its invalid
|
|
210
210
|
**/
|
|
211
211
|
onChange?: (event: SyntheticEvent, isoValue?: string) => void
|
|
@@ -223,6 +223,17 @@ type DateTimeInputProps = {
|
|
|
223
223
|
* component
|
|
224
224
|
*/
|
|
225
225
|
onBlur?: (e: SyntheticEvent) => void
|
|
226
|
+
/*
|
|
227
|
+
* Specify which date(s) will be shown as disabled in the calendar.
|
|
228
|
+
* You can either supply an array of ISO8601 timeDate strings or
|
|
229
|
+
* a function that will be called for each date shown in the calendar.
|
|
230
|
+
*/
|
|
231
|
+
disabledDates?: string[] | ((isoDateToCheck: string) => boolean)
|
|
232
|
+
/**
|
|
233
|
+
* Error message shown to the user if they enter a date that is disabled.
|
|
234
|
+
* If not specified the component will show the `invalidDateTimeMessage`.
|
|
235
|
+
*/
|
|
236
|
+
disabledDateTimeMessage?: string | ((rawDateValue: string) => string)
|
|
226
237
|
}
|
|
227
238
|
|
|
228
239
|
type DateTimeInputState = {
|
|
@@ -283,7 +294,15 @@ const propTypes: PropValidators<PropKeys> = {
|
|
|
283
294
|
onChange: PropTypes.func,
|
|
284
295
|
dateInputRef: PropTypes.func,
|
|
285
296
|
timeInputRef: PropTypes.func,
|
|
286
|
-
onBlur: PropTypes.func
|
|
297
|
+
onBlur: PropTypes.func,
|
|
298
|
+
disabledDates: PropTypes.oneOfType([
|
|
299
|
+
PropTypes.func,
|
|
300
|
+
PropTypes.arrayOf(PropTypes.string)
|
|
301
|
+
]),
|
|
302
|
+
disabledDateTimeMessage: PropTypes.oneOfType([
|
|
303
|
+
PropTypes.string,
|
|
304
|
+
PropTypes.func
|
|
305
|
+
])
|
|
287
306
|
}
|
|
288
307
|
|
|
289
308
|
const allowedProps: AllowedPropKeys = [
|
|
@@ -312,7 +331,9 @@ const allowedProps: AllowedPropKeys = [
|
|
|
312
331
|
'onChange',
|
|
313
332
|
'dateInputRef',
|
|
314
333
|
'timeInputRef',
|
|
315
|
-
'onBlur'
|
|
334
|
+
'onBlur',
|
|
335
|
+
'disabledDates',
|
|
336
|
+
'disabledDateTimeMessage'
|
|
316
337
|
]
|
|
317
338
|
|
|
318
339
|
export type { DateTimeInputProps, DateTimeInputState }
|