@instructure/ui-date-time-input 8.23.1-snapshot.9 → 8.24.1-snapshot.17

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/CHANGELOG.md CHANGED
@@ -3,6 +3,17 @@
3
3
  All notable changes to this project will be documented in this file.
4
4
  See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
5
5
 
6
+ # [8.24.0](https://github.com/instructure/instructure-ui/compare/v8.23.0...v8.24.0) (2022-04-26)
7
+
8
+ ### Bug Fixes
9
+
10
+ - **ui-date-time-input:** fix Date input to fill container in `DateTimeInput` ([4069706](https://github.com/instructure/instructure-ui/commit/40697060749bb4770120e822ef2b2466279b1497))
11
+
12
+ ### Features
13
+
14
+ - **ui-date-time-input:** allow to disable dates in the calendar.
15
+ - **ui-date-time-input:** add `rowSpacing` and `colSpacing` props to DateTimeInput ([5e829fa](https://github.com/instructure/instructure-ui/commit/5e829fae6b005f080497818df8b3fff19365aab3))
16
+
6
17
  # [8.23.0](https://github.com/instructure/instructure-ui/compare/v8.22.0...v8.23.0) (2022-04-07)
7
18
 
8
19
  **Note:** Version bump only for package @instructure/ui-date-time-input
@@ -50,7 +50,6 @@ let DateTimeInput = (_dec = testable(), _dec(_class = (_class2 = class DateTimeI
50
50
  // componentDidMount()
51
51
 
52
52
  this.context = void 0;
53
- this._timeInput = void 0;
54
53
  this.ref = null;
55
54
 
56
55
  this.handleRef = el => {
@@ -142,10 +141,6 @@ let DateTimeInput = (_dec = testable(), _dec(_class = (_class2 = class DateTimeI
142
141
  }
143
142
  };
144
143
 
145
- this.timeInputComponentRef = node => {
146
- this._timeInput = node;
147
- };
148
-
149
144
  this.handleShowCalendar = _event => {
150
145
  this.setState({
151
146
  isShowingCalendar: true
@@ -241,8 +236,6 @@ let DateTimeInput = (_dec = testable(), _dec(_class = (_class2 = class DateTimeI
241
236
  const parsed = DateTime.parse(dateStr, this.locale(), this.timezone());
242
237
 
243
238
  if (parsed.isValid()) {
244
- var _this$state, _this$_timeInput;
245
-
246
239
  if (doNotChangeTime && this.state.timeSelectValue) {
247
240
  // There is a selected time, adjust the parsed date to its value
248
241
  const timeParsed = DateTime.parse(this.state.timeSelectValue, this.locale(), this.timezone());
@@ -253,7 +246,30 @@ let DateTimeInput = (_dec = testable(), _dec(_class = (_class2 = class DateTimeI
253
246
  parsed.date(this.state.iso.date()).month(this.state.iso.month()).year(this.state.iso.year());
254
247
  }
255
248
 
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();
249
+ const newTimeSelectValue = parsed.toISOString();
250
+
251
+ if (this.isDisabledDate(parsed)) {
252
+ let text = typeof this.props.disabledDateTimeMessage === 'function' ? this.props.disabledDateTimeMessage(parsed.toISOString(true)) : this.props.disabledDateTimeMessage;
253
+
254
+ if (!text) {
255
+ text = typeof this.props.invalidDateTimeMessage === 'function' ? this.props.invalidDateTimeMessage(parsed.toISOString(true)) : this.props.invalidDateTimeMessage;
256
+ }
257
+
258
+ errorMsg = text ? {
259
+ text,
260
+ type: 'error'
261
+ } : void 0;
262
+ return {
263
+ iso: parsed.clone(),
264
+ calendarSelectedDate: parsed.clone(),
265
+ dateInputTextChanged: false,
266
+ dateInputText: parsed.format(this.dateFormat),
267
+ message: errorMsg,
268
+ timeSelectValue: newTimeSelectValue,
269
+ renderedDate: parsed.clone()
270
+ };
271
+ }
272
+
257
273
  return {
258
274
  iso: parsed.clone(),
259
275
  calendarSelectedDate: parsed.clone(),
@@ -309,6 +325,26 @@ let DateTimeInput = (_dec = testable(), _dec(_class = (_class2 = class DateTimeI
309
325
 
310
326
  get dateFormat() {
311
327
  return this.props.dateFormat;
328
+ }
329
+
330
+ isDisabledDate(date) {
331
+ const disabledDates = this.props.disabledDates;
332
+
333
+ if (!disabledDates) {
334
+ return false;
335
+ }
336
+
337
+ if (Array.isArray(disabledDates)) {
338
+ for (const aDisabledDate of disabledDates) {
339
+ if (date.isSame(aDisabledDate, 'day')) {
340
+ return true;
341
+ }
342
+ }
343
+
344
+ return false;
345
+ }
346
+
347
+ return disabledDates(date.toISOString());
312
348
  } // Called when the user enters text into dateInput
313
349
 
314
350
 
@@ -369,7 +405,8 @@ let DateTimeInput = (_dec = testable(), _dec(_class = (_class2 = class DateTimeI
369
405
  isOutsideMonth: !date.isSame(renderedDate, 'month'),
370
406
  label: date.format('D MMMM YYYY') // used by screen readers
371
407
  ,
372
- onClick: this.handleDayClick
408
+ onClick: this.handleDayClick,
409
+ interaction: this.isDisabledDate(date) ? 'disabled' : 'enabled'
373
410
  }, date.format('DD'));
374
411
  });
375
412
  } // The default weekdays rendered in the calendar
@@ -439,18 +476,21 @@ let DateTimeInput = (_dec = testable(), _dec(_class = (_class2 = class DateTimeI
439
476
  timezone = _this$props2.timezone,
440
477
  messages = _this$props2.messages,
441
478
  layout = _this$props2.layout,
479
+ rowSpacing = _this$props2.rowSpacing,
480
+ colSpacing = _this$props2.colSpacing,
442
481
  isRequired = _this$props2.isRequired,
443
482
  interaction = _this$props2.interaction,
444
483
  renderWeekdayLabels = _this$props2.renderWeekdayLabels;
445
484
  return /*#__PURE__*/React.createElement(FormFieldGroup, {
446
485
  description: description,
447
- colSpacing: "medium",
448
- rowSpacing: "small",
449
486
  layout: layout,
487
+ rowSpacing: rowSpacing,
488
+ colSpacing: colSpacing,
450
489
  vAlign: "top",
451
490
  elementRef: this.handleRef,
452
491
  messages: [...(this.state.message ? [this.state.message] : []), ...(messages || [])]
453
492
  }, /*#__PURE__*/React.createElement(DateInput, {
493
+ display: "block",
454
494
  value: this.state.dateInputText,
455
495
  onChange: this.handleDateTextChange,
456
496
  onBlur: this.handleBlur,
@@ -476,7 +516,6 @@ let DateTimeInput = (_dec = testable(), _dec(_class = (_class2 = class DateTimeI
476
516
  value: this.state.timeSelectValue,
477
517
  onChange: this.handleTimeChange,
478
518
  onBlur: this.handleBlur,
479
- ref: this.timeInputComponentRef,
480
519
  renderLabel: timeRenderLabel,
481
520
  locale: locale,
482
521
  format: timeFormat,
@@ -489,6 +528,8 @@ let DateTimeInput = (_dec = testable(), _dec(_class = (_class2 = class DateTimeI
489
528
 
490
529
  }, _class2.displayName = "DateTimeInput", _class2.DEFAULT_MESSAGE_FORMAT = 'LLLL', _class2.propTypes = propTypes, _class2.allowedProps = allowedProps, _class2.defaultProps = {
491
530
  layout: 'inline',
531
+ colSpacing: 'medium',
532
+ rowSpacing: 'small',
492
533
  timeStep: 30,
493
534
  messageFormat: _class2.DEFAULT_MESSAGE_FORMAT,
494
535
  isRequired: false,
@@ -42,6 +42,8 @@ const propTypes = {
42
42
  messages: PropTypes.arrayOf(FormPropTypes.message),
43
43
  messageFormat: PropTypes.string,
44
44
  layout: PropTypes.oneOf(['stacked', 'columns', 'inline']),
45
+ rowSpacing: PropTypes.oneOf(['none', 'small', 'medium', 'large']),
46
+ colSpacing: PropTypes.oneOf(['none', 'small', 'medium', 'large']),
45
47
  value: controllable(I18nPropTypes.iso8601, 'onChange'),
46
48
  defaultValue: I18nPropTypes.iso8601,
47
49
  renderWeekdayLabels: PropTypes.arrayOf(PropTypes.oneOfType([PropTypes.func, PropTypes.node])),
@@ -49,7 +51,9 @@ const propTypes = {
49
51
  onChange: PropTypes.func,
50
52
  dateInputRef: PropTypes.func,
51
53
  timeInputRef: PropTypes.func,
52
- 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])
53
57
  };
54
- const allowedProps = ['description', 'dateRenderLabel', 'prevMonthLabel', 'nextMonthLabel', 'datePlaceholder', 'dateFormat', 'interaction', 'timeRenderLabel', 'timeStep', 'timeFormat', 'locale', 'timezone', 'invalidDateTimeMessage', 'messages', 'messageFormat', 'layout', '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'];
55
59
  export { propTypes, allowedProps };
@@ -53,7 +53,6 @@ let DateTimeInput = (_dec = (0, _testable.testable)(), _dec(_class = (_class2 =
53
53
  // componentDidMount()
54
54
 
55
55
  this.context = void 0;
56
- this._timeInput = void 0;
57
56
  this.ref = null;
58
57
 
59
58
  this.handleRef = el => {
@@ -147,10 +146,6 @@ let DateTimeInput = (_dec = (0, _testable.testable)(), _dec(_class = (_class2 =
147
146
  }
148
147
  };
149
148
 
150
- this.timeInputComponentRef = node => {
151
- this._timeInput = node;
152
- };
153
-
154
149
  this.handleShowCalendar = _event => {
155
150
  this.setState({
156
151
  isShowingCalendar: true
@@ -246,8 +241,6 @@ let DateTimeInput = (_dec = (0, _testable.testable)(), _dec(_class = (_class2 =
246
241
  const parsed = _DateTime.DateTime.parse(dateStr, this.locale(), this.timezone());
247
242
 
248
243
  if (parsed.isValid()) {
249
- var _this$state, _this$_timeInput;
250
-
251
244
  if (doNotChangeTime && this.state.timeSelectValue) {
252
245
  // There is a selected time, adjust the parsed date to its value
253
246
  const timeParsed = _DateTime.DateTime.parse(this.state.timeSelectValue, this.locale(), this.timezone());
@@ -259,7 +252,30 @@ let DateTimeInput = (_dec = (0, _testable.testable)(), _dec(_class = (_class2 =
259
252
  parsed.date(this.state.iso.date()).month(this.state.iso.month()).year(this.state.iso.year());
260
253
  }
261
254
 
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();
255
+ const newTimeSelectValue = parsed.toISOString();
256
+
257
+ if (this.isDisabledDate(parsed)) {
258
+ let text = typeof this.props.disabledDateTimeMessage === 'function' ? this.props.disabledDateTimeMessage(parsed.toISOString(true)) : this.props.disabledDateTimeMessage;
259
+
260
+ if (!text) {
261
+ text = typeof this.props.invalidDateTimeMessage === 'function' ? this.props.invalidDateTimeMessage(parsed.toISOString(true)) : this.props.invalidDateTimeMessage;
262
+ }
263
+
264
+ errorMsg = text ? {
265
+ text,
266
+ type: 'error'
267
+ } : void 0;
268
+ return {
269
+ iso: parsed.clone(),
270
+ calendarSelectedDate: parsed.clone(),
271
+ dateInputTextChanged: false,
272
+ dateInputText: parsed.format(this.dateFormat),
273
+ message: errorMsg,
274
+ timeSelectValue: newTimeSelectValue,
275
+ renderedDate: parsed.clone()
276
+ };
277
+ }
278
+
263
279
  return {
264
280
  iso: parsed.clone(),
265
281
  calendarSelectedDate: parsed.clone(),
@@ -315,6 +331,26 @@ let DateTimeInput = (_dec = (0, _testable.testable)(), _dec(_class = (_class2 =
315
331
 
316
332
  get dateFormat() {
317
333
  return this.props.dateFormat;
334
+ }
335
+
336
+ isDisabledDate(date) {
337
+ const disabledDates = this.props.disabledDates;
338
+
339
+ if (!disabledDates) {
340
+ return false;
341
+ }
342
+
343
+ if (Array.isArray(disabledDates)) {
344
+ for (const aDisabledDate of disabledDates) {
345
+ if (date.isSame(aDisabledDate, 'day')) {
346
+ return true;
347
+ }
348
+ }
349
+
350
+ return false;
351
+ }
352
+
353
+ return disabledDates(date.toISOString());
318
354
  } // Called when the user enters text into dateInput
319
355
 
320
356
 
@@ -378,7 +414,8 @@ let DateTimeInput = (_dec = (0, _testable.testable)(), _dec(_class = (_class2 =
378
414
  isOutsideMonth: !date.isSame(renderedDate, 'month'),
379
415
  label: date.format('D MMMM YYYY') // used by screen readers
380
416
  ,
381
- onClick: this.handleDayClick
417
+ onClick: this.handleDayClick,
418
+ interaction: this.isDisabledDate(date) ? 'disabled' : 'enabled'
382
419
  }, date.format('DD'));
383
420
  });
384
421
  } // The default weekdays rendered in the calendar
@@ -450,18 +487,21 @@ let DateTimeInput = (_dec = (0, _testable.testable)(), _dec(_class = (_class2 =
450
487
  timezone = _this$props2.timezone,
451
488
  messages = _this$props2.messages,
452
489
  layout = _this$props2.layout,
490
+ rowSpacing = _this$props2.rowSpacing,
491
+ colSpacing = _this$props2.colSpacing,
453
492
  isRequired = _this$props2.isRequired,
454
493
  interaction = _this$props2.interaction,
455
494
  renderWeekdayLabels = _this$props2.renderWeekdayLabels;
456
495
  return /*#__PURE__*/_react.default.createElement(_FormFieldGroup.FormFieldGroup, {
457
496
  description: description,
458
- colSpacing: "medium",
459
- rowSpacing: "small",
460
497
  layout: layout,
498
+ rowSpacing: rowSpacing,
499
+ colSpacing: colSpacing,
461
500
  vAlign: "top",
462
501
  elementRef: this.handleRef,
463
502
  messages: [...(this.state.message ? [this.state.message] : []), ...(messages || [])]
464
503
  }, /*#__PURE__*/_react.default.createElement(_DateInput.DateInput, {
504
+ display: "block",
465
505
  value: this.state.dateInputText,
466
506
  onChange: this.handleDateTextChange,
467
507
  onBlur: this.handleBlur,
@@ -487,7 +527,6 @@ let DateTimeInput = (_dec = (0, _testable.testable)(), _dec(_class = (_class2 =
487
527
  value: this.state.timeSelectValue,
488
528
  onChange: this.handleTimeChange,
489
529
  onBlur: this.handleBlur,
490
- ref: this.timeInputComponentRef,
491
530
  renderLabel: timeRenderLabel,
492
531
  locale: locale,
493
532
  format: timeFormat,
@@ -500,6 +539,8 @@ let DateTimeInput = (_dec = (0, _testable.testable)(), _dec(_class = (_class2 =
500
539
 
501
540
  }, _class2.displayName = "DateTimeInput", _class2.DEFAULT_MESSAGE_FORMAT = 'LLLL', _class2.propTypes = _props.propTypes, _class2.allowedProps = _props.allowedProps, _class2.defaultProps = {
502
541
  layout: 'inline',
542
+ colSpacing: 'medium',
543
+ rowSpacing: 'small',
503
544
  timeStep: 30,
504
545
  messageFormat: _class2.DEFAULT_MESSAGE_FORMAT,
505
546
  isRequired: false,
@@ -55,6 +55,8 @@ const propTypes = {
55
55
  messages: _propTypes.default.arrayOf(_FormPropTypes.FormPropTypes.message),
56
56
  messageFormat: _propTypes.default.string,
57
57
  layout: _propTypes.default.oneOf(['stacked', 'columns', 'inline']),
58
+ rowSpacing: _propTypes.default.oneOf(['none', 'small', 'medium', 'large']),
59
+ colSpacing: _propTypes.default.oneOf(['none', 'small', 'medium', 'large']),
58
60
  value: (0, _controllable.controllable)(_I18nPropTypes.I18nPropTypes.iso8601, 'onChange'),
59
61
  defaultValue: _I18nPropTypes.I18nPropTypes.iso8601,
60
62
  renderWeekdayLabels: _propTypes.default.arrayOf(_propTypes.default.oneOfType([_propTypes.default.func, _propTypes.default.node])),
@@ -62,8 +64,10 @@ const propTypes = {
62
64
  onChange: _propTypes.default.func,
63
65
  dateInputRef: _propTypes.default.func,
64
66
  timeInputRef: _propTypes.default.func,
65
- 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])
66
70
  };
67
71
  exports.propTypes = propTypes;
68
- const allowedProps = ['description', 'dateRenderLabel', 'prevMonthLabel', 'nextMonthLabel', 'datePlaceholder', 'dateFormat', 'interaction', 'timeRenderLabel', 'timeStep', 'timeFormat', 'locale', 'timezone', 'invalidDateTimeMessage', 'messages', 'messageFormat', 'layout', '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'];
69
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.9+11828d0b3",
3
+ "version": "8.24.1-snapshot.17+0604ec59c",
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.9+11828d0b3",
27
- "@instructure/ui-test-locator": "8.23.1-snapshot.9+11828d0b3",
28
- "@instructure/ui-test-utils": "8.23.1-snapshot.9+11828d0b3"
26
+ "@instructure/ui-babel-preset": "8.24.1-snapshot.17+0604ec59c",
27
+ "@instructure/ui-test-locator": "8.24.1-snapshot.17+0604ec59c",
28
+ "@instructure/ui-test-utils": "8.24.1-snapshot.17+0604ec59c"
29
29
  },
30
30
  "dependencies": {
31
31
  "@babel/runtime": "^7.13.10",
32
- "@instructure/debounce": "8.23.1-snapshot.9+11828d0b3",
33
- "@instructure/emotion": "8.23.1-snapshot.9+11828d0b3",
34
- "@instructure/ui-a11y-content": "8.23.1-snapshot.9+11828d0b3",
35
- "@instructure/ui-buttons": "8.23.1-snapshot.9+11828d0b3",
36
- "@instructure/ui-calendar": "8.23.1-snapshot.9+11828d0b3",
37
- "@instructure/ui-date-input": "8.23.1-snapshot.9+11828d0b3",
38
- "@instructure/ui-form-field": "8.23.1-snapshot.9+11828d0b3",
39
- "@instructure/ui-i18n": "8.23.1-snapshot.9+11828d0b3",
40
- "@instructure/ui-icons": "8.23.1-snapshot.9+11828d0b3",
41
- "@instructure/ui-prop-types": "8.23.1-snapshot.9+11828d0b3",
42
- "@instructure/ui-react-utils": "8.23.1-snapshot.9+11828d0b3",
43
- "@instructure/ui-testable": "8.23.1-snapshot.9+11828d0b3",
44
- "@instructure/ui-time-select": "8.23.1-snapshot.9+11828d0b3",
45
- "@instructure/ui-utils": "8.23.1-snapshot.9+11828d0b3",
32
+ "@instructure/debounce": "8.24.1-snapshot.17+0604ec59c",
33
+ "@instructure/emotion": "8.24.1-snapshot.17+0604ec59c",
34
+ "@instructure/ui-a11y-content": "8.24.1-snapshot.17+0604ec59c",
35
+ "@instructure/ui-buttons": "8.24.1-snapshot.17+0604ec59c",
36
+ "@instructure/ui-calendar": "8.24.1-snapshot.17+0604ec59c",
37
+ "@instructure/ui-date-input": "8.24.1-snapshot.17+0604ec59c",
38
+ "@instructure/ui-form-field": "8.24.1-snapshot.17+0604ec59c",
39
+ "@instructure/ui-i18n": "8.24.1-snapshot.17+0604ec59c",
40
+ "@instructure/ui-icons": "8.24.1-snapshot.17+0604ec59c",
41
+ "@instructure/ui-prop-types": "8.24.1-snapshot.17+0604ec59c",
42
+ "@instructure/ui-react-utils": "8.24.1-snapshot.17+0604ec59c",
43
+ "@instructure/ui-testable": "8.24.1-snapshot.17+0604ec59c",
44
+ "@instructure/ui-time-select": "8.24.1-snapshot.17+0604ec59c",
45
+ "@instructure/ui-utils": "8.24.1-snapshot.17+0604ec59c",
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": "11828d0b32844a522d267e189c8bc52aa928843a"
55
+ "gitHead": "0604ec59c560ca2868fdac84d6f4948f92d38d5b"
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
- #### Localization
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
- #### Examples
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: 350,width: '40em'}}>
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: '20em'}}>
78
+ <div style={{width: '25em'}}>
73
79
  <div style={{marginBottom: '1em', fontStyle: 'italic'}}>You entered:<br/>{text}</div>
74
- <div style={{height: 350}}>
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: 350, width: '40em' }}>
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
- The properties of DateTimeInput prefaced with _date_ are passed to the underlying [DateInput](#DateInput)
151
- (e.g. _dateLabel_ is DateInput's _label_), while the properties prefaced
152
- with _time_ are forwarded to the underlying
153
- [TimeSelect](#TimeSelect). Others are either shared by both sub-components (e.g. locale), or
154
- are unique to DateTimeInput (e.g. description).
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
+ ```