@dhis2-ui/calendar 9.11.3 → 9.12.0-alpha.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,81 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.CalendarContainer = void 0;
7
+ var _style = _interopRequireDefault(require("styled-jsx/style"));
8
+ var _uiConstants = require("@dhis2/ui-constants");
9
+ var _propTypes = _interopRequireDefault(require("prop-types"));
10
+ var _react = _interopRequireWildcard(require("react"));
11
+ var _calendarTable = require("./calendar-table.js");
12
+ var _navigationContainer = require("./navigation-container.js");
13
+ function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); }
14
+ function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
15
+ function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
16
+ function _extends() { return _extends = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends.apply(null, arguments); }
17
+ const wrapperBorderColor = _uiConstants.colors.grey300;
18
+ const backgroundColor = 'none';
19
+ const CalendarContainer = exports.CalendarContainer = /*#__PURE__*/_react.default.memo(function CalendarContainer(_ref) {
20
+ let {
21
+ date,
22
+ width,
23
+ cellSize,
24
+ calendarWeekDays,
25
+ weekDayLabels,
26
+ currMonth,
27
+ currYear,
28
+ nextMonth,
29
+ nextYear,
30
+ prevMonth,
31
+ prevYear,
32
+ languageDirection,
33
+ excludedRef,
34
+ unfocusable
35
+ } = _ref;
36
+ const navigationProps = (0, _react.useMemo)(() => {
37
+ return {
38
+ currMonth,
39
+ currYear,
40
+ nextMonth,
41
+ nextYear,
42
+ prevMonth,
43
+ prevYear,
44
+ languageDirection
45
+ };
46
+ }, [currMonth, currYear, languageDirection, nextMonth, nextYear, prevMonth, prevYear]);
47
+ return /*#__PURE__*/_react.default.createElement("div", {
48
+ className: _style.default.dynamic([["2823859047", [backgroundColor, wrapperBorderColor, width]]])
49
+ }, /*#__PURE__*/_react.default.createElement("div", {
50
+ dir: languageDirection,
51
+ "data-test": "calendar",
52
+ className: _style.default.dynamic([["2823859047", [backgroundColor, wrapperBorderColor, width]]]) + " " + "calendar-wrapper"
53
+ }, /*#__PURE__*/_react.default.createElement("div", {
54
+ ref: excludedRef,
55
+ className: _style.default.dynamic([["2823859047", [backgroundColor, wrapperBorderColor, width]]])
56
+ }, /*#__PURE__*/_react.default.createElement(_navigationContainer.NavigationContainer, _extends({}, navigationProps, {
57
+ unfocusable: unfocusable
58
+ })), /*#__PURE__*/_react.default.createElement(_calendarTable.CalendarTable, {
59
+ selectedDate: date,
60
+ calendarWeekDays: calendarWeekDays,
61
+ weekDayLabels: weekDayLabels,
62
+ cellSize: cellSize,
63
+ width: width,
64
+ unfocusable: unfocusable
65
+ }))), /*#__PURE__*/_react.default.createElement(_style.default, {
66
+ id: "2823859047",
67
+ dynamic: [backgroundColor, wrapperBorderColor, width]
68
+ }, [`.calendar-wrapper.__jsx-style-dynamic-selector{font-family:Roboto,sans-serif;font-weight:400;font-size:14px;background-color:${backgroundColor};display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;border:1px solid ${wrapperBorderColor};border-radius:3px;min-width:${width};width:-webkit-max-content;width:-moz-max-content;width:max-content;box-shadow:0px 4px 6px -2px #2129340d;box-shadow:0px 10px 15px -3px #2129341a;}`]));
69
+ });
70
+ CalendarContainer.defaultProps = {
71
+ cellSize: '32px',
72
+ width: '240px',
73
+ unfocusable: false
74
+ };
75
+ CalendarContainer.propTypes = {
76
+ /** the currently selected date using an iso-like format YYYY-MM-DD, in the calendar system provided (not iso8601) */
77
+ date: _propTypes.default.string,
78
+ unfocusable: _propTypes.default.bool,
79
+ ..._calendarTable.CalendarTableProps,
80
+ ..._navigationContainer.NavigationContainerProps
81
+ };
@@ -14,7 +14,8 @@ const CalendarTableCell = _ref => {
14
14
  let {
15
15
  day,
16
16
  cellSize,
17
- selectedDate
17
+ selectedDate,
18
+ unfocusable
18
19
  } = _ref;
19
20
  const dayHoverBackgroundColor = _uiConstants.colors.grey200;
20
21
  const selectedDayBackgroundColor = _uiConstants.colors.teal700;
@@ -24,6 +25,7 @@ const CalendarTableCell = _ref => {
24
25
  className: _style.default.dynamic([["2052411850", [cellSize, cellSize, cellSize, cellSize, _uiConstants.colors.grey900, dayHoverBackgroundColor, _uiConstants.colors.grey300, selectedDayBackgroundColor, _uiConstants.colors.teal600, _uiConstants.colors.teal200, _uiConstants.colors.grey600]]])
25
26
  }, /*#__PURE__*/_react.default.createElement("button", {
26
27
  name: "day",
28
+ tabIndex: unfocusable ? -1 : 0,
27
29
  className: _style.default.dynamic([["2052411850", [cellSize, cellSize, cellSize, cellSize, _uiConstants.colors.grey900, dayHoverBackgroundColor, _uiConstants.colors.grey300, selectedDayBackgroundColor, _uiConstants.colors.teal600, _uiConstants.colors.teal200, _uiConstants.colors.grey600]]]) + " " + ((0, _classnames.default)('day', {
28
30
  isSelected: selectedDate === (day === null || day === void 0 ? void 0 : day.calendarDate),
29
31
  isToday: day.isToday,
@@ -45,5 +47,6 @@ CalendarTableCell.propTypes = {
45
47
  label: _propTypes.default.oneOfType([_propTypes.default.string, _propTypes.default.number]),
46
48
  onClick: _propTypes.default.func
47
49
  }),
48
- selectedDate: _propTypes.default.string
50
+ selectedDate: _propTypes.default.string,
51
+ unfocusable: _propTypes.default.bool
49
52
  };
@@ -3,7 +3,7 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
- exports.CalendarTable = void 0;
6
+ exports.CalendarTableProps = exports.CalendarTable = void 0;
7
7
  var _style = _interopRequireDefault(require("styled-jsx/style"));
8
8
  var _uiConstants = require("@dhis2/ui-constants");
9
9
  var _propTypes = _interopRequireDefault(require("prop-types"));
@@ -17,7 +17,8 @@ const CalendarTable = _ref => {
17
17
  calendarWeekDays,
18
18
  width,
19
19
  cellSize,
20
- selectedDate
20
+ selectedDate,
21
+ unfocusable
21
22
  } = _ref;
22
23
  return /*#__PURE__*/_react.default.createElement("div", {
23
24
  className: _style.default.dynamic([["452536960", [_uiConstants.spacers.dp4, _uiConstants.spacers.dp4]]]) + " " + "calendar-table-wrapper"
@@ -35,14 +36,15 @@ const CalendarTable = _ref => {
35
36
  day: day,
36
37
  key: day === null || day === void 0 ? void 0 : day.calendarDate,
37
38
  cellSize: cellSize,
38
- width: width
39
+ width: width,
40
+ unfocusable: unfocusable
39
41
  })))))), /*#__PURE__*/_react.default.createElement(_style.default, {
40
42
  id: "452536960",
41
43
  dynamic: [_uiConstants.spacers.dp4, _uiConstants.spacers.dp4]
42
44
  }, [`.calendar-table.__jsx-style-dynamic-selector{border:none;border-collapse:collapse;width:100%;margin-block:${_uiConstants.spacers.dp4};}`, ".calendar-table.__jsx-style-dynamic-selector tr.__jsx-style-dynamic-selector,.calendar-table.__jsx-style-dynamic-selector td.__jsx-style-dynamic-selector{border:none;}", `.calendar-table-wrapper.__jsx-style-dynamic-selector{padding-inline:${_uiConstants.spacers.dp4};}`]));
43
45
  };
44
46
  exports.CalendarTable = CalendarTable;
45
- CalendarTable.propTypes = {
47
+ const CalendarTableProps = exports.CalendarTableProps = {
46
48
  calendarWeekDays: _propTypes.default.arrayOf(_propTypes.default.arrayOf(_propTypes.default.shape({
47
49
  calendarDate: _propTypes.default.string,
48
50
  isInCurrentMonth: _propTypes.default.bool,
@@ -54,6 +56,8 @@ CalendarTable.propTypes = {
54
56
  }).isRequired).isRequired).isRequired,
55
57
  cellSize: _propTypes.default.string,
56
58
  selectedDate: _propTypes.default.string,
59
+ unfocusable: _propTypes.default.bool,
57
60
  weekDayLabels: _propTypes.default.arrayOf(_propTypes.default.string),
58
61
  width: _propTypes.default.string
59
- };
62
+ };
63
+ CalendarTable.propTypes = CalendarTableProps;
@@ -4,13 +4,10 @@ Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
6
  exports.CalendarProps = exports.Calendar = void 0;
7
- var _style = _interopRequireDefault(require("styled-jsx/style"));
8
7
  var _multiCalendarDates = require("@dhis2/multi-calendar-dates");
9
- var _uiConstants = require("@dhis2/ui-constants");
10
8
  var _propTypes = _interopRequireDefault(require("prop-types"));
11
9
  var _react = _interopRequireWildcard(require("react"));
12
- var _calendarTable = require("./calendar-table.js");
13
- var _navigationContainer = require("./navigation-container.js");
10
+ var _calendarContainer = require("./calendar-container.js");
14
11
  function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); }
15
12
  function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
16
13
  function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
@@ -27,8 +24,6 @@ const Calendar = _ref => {
27
24
  width,
28
25
  cellSize
29
26
  } = _ref;
30
- const wrapperBorderColor = _uiConstants.colors.grey300;
31
- const backgroundColor = 'none';
32
27
  const [selectedDateString, setSelectedDateString] = (0, _react.useState)(date);
33
28
  const languageDirection = (0, _multiCalendarDates.useResolvedDirection)(dir, locale);
34
29
  const options = {
@@ -38,7 +33,7 @@ const Calendar = _ref => {
38
33
  numberingSystem,
39
34
  weekDayFormat
40
35
  };
41
- const pickerOptions = (0, _multiCalendarDates.useDatePicker)({
36
+ const pickerResults = (0, _multiCalendarDates.useDatePicker)({
42
37
  onDateSelect: result => {
43
38
  const {
44
39
  calendarDateString
@@ -49,29 +44,30 @@ const Calendar = _ref => {
49
44
  date: selectedDateString,
50
45
  options
51
46
  });
52
- const {
53
- calendarWeekDays,
54
- weekDayLabels
55
- } = pickerOptions;
56
- return /*#__PURE__*/_react.default.createElement("div", {
57
- className: _style.default.dynamic([["2823859047", [backgroundColor, wrapperBorderColor, width]]])
58
- }, /*#__PURE__*/_react.default.createElement("div", {
59
- dir: languageDirection,
60
- "data-test": "calendar",
61
- className: _style.default.dynamic([["2823859047", [backgroundColor, wrapperBorderColor, width]]]) + " " + "calendar-wrapper"
62
- }, /*#__PURE__*/_react.default.createElement(_navigationContainer.NavigationContainer, {
63
- pickerOptions: pickerOptions,
64
- languageDirection: languageDirection
65
- }), /*#__PURE__*/_react.default.createElement(_calendarTable.CalendarTable, {
66
- selectedDate: selectedDateString,
67
- calendarWeekDays: calendarWeekDays,
68
- weekDayLabels: weekDayLabels,
69
- cellSize: cellSize,
70
- width: width
71
- })), /*#__PURE__*/_react.default.createElement(_style.default, {
72
- id: "2823859047",
73
- dynamic: [backgroundColor, wrapperBorderColor, width]
74
- }, [`.calendar-wrapper.__jsx-style-dynamic-selector{font-family:Roboto,sans-serif;font-weight:400;font-size:14px;background-color:${backgroundColor};display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;border:1px solid ${wrapperBorderColor};border-radius:3px;min-width:${width};width:-webkit-max-content;width:-moz-max-content;width:max-content;box-shadow:0px 4px 6px -2px #2129340d;box-shadow:0px 10px 15px -3px #2129341a;}`]));
47
+ const calendarProps = (0, _react.useMemo)(() => {
48
+ return {
49
+ date,
50
+ dir,
51
+ locale,
52
+ width,
53
+ cellSize,
54
+ // minDate,
55
+ // maxDate,
56
+ // validation, // todo: clarify how we use validation props (and format) in Calendar (not CalendarInput)
57
+ // format,
58
+ isValid: pickerResults.isValid,
59
+ calendarWeekDays: pickerResults.calendarWeekDays,
60
+ weekDayLabels: pickerResults.weekDayLabels,
61
+ currMonth: pickerResults.currMonth,
62
+ currYear: pickerResults.currYear,
63
+ nextMonth: pickerResults.nextMonth,
64
+ nextYear: pickerResults.nextYear,
65
+ prevMonth: pickerResults.prevMonth,
66
+ prevYear: pickerResults.prevYear,
67
+ languageDirection
68
+ };
69
+ }, [cellSize, date, dir, locale, pickerResults, width, languageDirection]);
70
+ return /*#__PURE__*/_react.default.createElement("div", null, /*#__PURE__*/_react.default.createElement(_calendarContainer.CalendarContainer, calendarProps));
75
71
  };
76
72
  exports.Calendar = Calendar;
77
73
  Calendar.defaultProps = {
@@ -3,7 +3,7 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
- exports.NavigationContainer = void 0;
6
+ exports.NavigationContainerProps = exports.NavigationContainer = void 0;
7
7
  var _style = _interopRequireDefault(require("styled-jsx/style"));
8
8
  var _uiConstants = require("@dhis2/ui-constants");
9
9
  var _uiIcons = require("@dhis2/ui-icons");
@@ -17,18 +17,16 @@ const NavigationContainer = _ref => {
17
17
  var _currYear$label;
18
18
  let {
19
19
  languageDirection,
20
- pickerOptions
21
- } = _ref;
22
- const PreviousIcon = languageDirection === 'ltr' ? _uiIcons.IconChevronLeft16 : _uiIcons.IconChevronRight16;
23
- const NextIcon = languageDirection === 'ltr' ? _uiIcons.IconChevronRight16 : _uiIcons.IconChevronLeft16;
24
- const {
25
20
  currMonth,
26
21
  currYear,
27
22
  nextMonth,
28
23
  nextYear,
29
24
  prevMonth,
30
- prevYear
31
- } = pickerOptions;
25
+ prevYear,
26
+ unfocusable
27
+ } = _ref;
28
+ const PreviousIcon = languageDirection === 'ltr' ? _uiIcons.IconChevronLeft16 : _uiIcons.IconChevronRight16;
29
+ const NextIcon = languageDirection === 'ltr' ? _uiIcons.IconChevronRight16 : _uiIcons.IconChevronLeft16;
32
30
 
33
31
  // Ethiopic years - when localised to English - add the era (i.e. 2015 ERA1), which is redundant in practice (like writing AD for gregorian years)
34
32
  // there is an ongoing discussion in JS-Temporal polyfill whether the era should be included or not, but for our case, it's safer to remove it
@@ -45,6 +43,7 @@ const NavigationContainer = _ref => {
45
43
  "data-test": "calendar-previous-month",
46
44
  "aria-label": `${_index.default.t(`Go to ${prevMonth.label}`)}`,
47
45
  type: "button",
46
+ tabIndex: unfocusable ? -1 : 0,
48
47
  className: _style.default.dynamic([["3883083596", [_uiConstants.spacers.dp4, _uiConstants.colors.grey600, _uiConstants.colors.grey200, _uiConstants.colors.grey900, _uiConstants.colors.grey300, _uiConstants.spacers.dp8, _uiConstants.spacers.dp4, wrapperBorderColor, headerBackground]]])
49
48
  }, /*#__PURE__*/_react.default.createElement(PreviousIcon, {
50
49
  className: _style.default.dynamic([["3883083596", [_uiConstants.spacers.dp4, _uiConstants.colors.grey600, _uiConstants.colors.grey200, _uiConstants.colors.grey900, _uiConstants.colors.grey300, _uiConstants.spacers.dp8, _uiConstants.spacers.dp4, wrapperBorderColor, headerBackground]]])
@@ -60,6 +59,7 @@ const NavigationContainer = _ref => {
60
59
  name: "next-month",
61
60
  "aria-label": `${_index.default.t(`Go to ${nextMonth.label}`)}`,
62
61
  type: "button",
62
+ tabIndex: unfocusable ? -1 : 0,
63
63
  className: _style.default.dynamic([["3883083596", [_uiConstants.spacers.dp4, _uiConstants.colors.grey600, _uiConstants.colors.grey200, _uiConstants.colors.grey900, _uiConstants.colors.grey300, _uiConstants.spacers.dp8, _uiConstants.spacers.dp4, wrapperBorderColor, headerBackground]]])
64
64
  }, /*#__PURE__*/_react.default.createElement(NextIcon, {
65
65
  className: _style.default.dynamic([["3883083596", [_uiConstants.spacers.dp4, _uiConstants.colors.grey600, _uiConstants.colors.grey200, _uiConstants.colors.grey900, _uiConstants.colors.grey300, _uiConstants.spacers.dp8, _uiConstants.spacers.dp4, wrapperBorderColor, headerBackground]]])
@@ -72,6 +72,7 @@ const NavigationContainer = _ref => {
72
72
  name: "previous-year",
73
73
  "aria-label": `${_index.default.t('Go to previous year')}`,
74
74
  type: "button",
75
+ tabIndex: unfocusable ? -1 : 0,
75
76
  className: _style.default.dynamic([["3883083596", [_uiConstants.spacers.dp4, _uiConstants.colors.grey600, _uiConstants.colors.grey200, _uiConstants.colors.grey900, _uiConstants.colors.grey300, _uiConstants.spacers.dp8, _uiConstants.spacers.dp4, wrapperBorderColor, headerBackground]]])
76
77
  }, /*#__PURE__*/_react.default.createElement(PreviousIcon, {
77
78
  className: _style.default.dynamic([["3883083596", [_uiConstants.spacers.dp4, _uiConstants.colors.grey600, _uiConstants.colors.grey200, _uiConstants.colors.grey900, _uiConstants.colors.grey300, _uiConstants.spacers.dp8, _uiConstants.spacers.dp4, wrapperBorderColor, headerBackground]]])
@@ -87,6 +88,7 @@ const NavigationContainer = _ref => {
87
88
  name: "next-year",
88
89
  "aria-label": `${_index.default.t('Go to next year')}`,
89
90
  type: "button",
91
+ tabIndex: unfocusable ? -1 : 0,
90
92
  className: _style.default.dynamic([["3883083596", [_uiConstants.spacers.dp4, _uiConstants.colors.grey600, _uiConstants.colors.grey200, _uiConstants.colors.grey900, _uiConstants.colors.grey300, _uiConstants.spacers.dp8, _uiConstants.spacers.dp4, wrapperBorderColor, headerBackground]]])
91
93
  }, /*#__PURE__*/_react.default.createElement(NextIcon, {
92
94
  className: _style.default.dynamic([["3883083596", [_uiConstants.spacers.dp4, _uiConstants.colors.grey600, _uiConstants.colors.grey200, _uiConstants.colors.grey900, _uiConstants.colors.grey300, _uiConstants.spacers.dp8, _uiConstants.spacers.dp4, wrapperBorderColor, headerBackground]]])
@@ -96,30 +98,30 @@ const NavigationContainer = _ref => {
96
98
  }, ["button.__jsx-style-dynamic-selector{background:none;border:0;}", ".month.__jsx-style-dynamic-selector,.year.__jsx-style-dynamic-selector{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;width:100%;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:center;-webkit-justify-content:center;-ms-flex-pack:center;justify-content:center;cursor:default;}", ".month.__jsx-style-dynamic-selector .curr.__jsx-style-dynamic-selector,.year.__jsx-style-dynamic-selector .curr.__jsx-style-dynamic-selector{-webkit-flex:2;-ms-flex:2;flex:2;white-space:nowrap;}", ".prev.__jsx-style-dynamic-selector,.next.__jsx-style-dynamic-selector{-webkit-flex:1;-ms-flex:1;flex:1;text-align:center;}", `.prev.__jsx-style-dynamic-selector button.__jsx-style-dynamic-selector,.next.__jsx-style-dynamic-selector button.__jsx-style-dynamic-selector{padding:${_uiConstants.spacers.dp4};height:24px;width:24px;color:${_uiConstants.colors.grey600};border-radius:3px;}`, ".prev.__jsx-style-dynamic-selector button.__jsx-style-dynamic-selector svg.__jsx-style-dynamic-selector,.next.__jsx-style-dynamic-selector button.__jsx-style-dynamic-selector svg.__jsx-style-dynamic-selector{width:16px;height:16px;}", `.prev.__jsx-style-dynamic-selector:hover button.__jsx-style-dynamic-selector,.next.__jsx-style-dynamic-selector:hover button.__jsx-style-dynamic-selector{background-color:${_uiConstants.colors.grey200};color:${_uiConstants.colors.grey900};cursor:pointer;}`, `.prev.__jsx-style-dynamic-selector button.__jsx-style-dynamic-selector:active,.next.__jsx-style-dynamic-selector button.__jsx-style-dynamic-selector:active{background-color:${_uiConstants.colors.grey300};}`, ".label.__jsx-style-dynamic-selector{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;padding:4px 8px;-webkit-box-pack:center;-webkit-justify-content:center;-ms-flex-pack:center;justify-content:center;min-height:16px;}", `.navigation-container.__jsx-style-dynamic-selector{gap:${_uiConstants.spacers.dp8};padding:${_uiConstants.spacers.dp4};display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row;border-bottom:1px solid ${wrapperBorderColor};background-color:${headerBackground};font-size:1.08em;}`]));
97
99
  };
98
100
  exports.NavigationContainer = NavigationContainer;
99
- NavigationContainer.propTypes = {
101
+ const NavigationContainerProps = exports.NavigationContainerProps = {
102
+ currMonth: _propTypes.default.shape({
103
+ label: _propTypes.default.oneOfType([_propTypes.default.string, _propTypes.default.number])
104
+ }),
105
+ currYear: _propTypes.default.shape({
106
+ label: _propTypes.default.oneOfType([_propTypes.default.string, _propTypes.default.number])
107
+ }),
100
108
  languageDirection: _propTypes.default.oneOf(['ltr', 'rtl']),
101
- pickerOptions: _propTypes.default.shape({
102
- currMonth: _propTypes.default.shape({
103
- label: _propTypes.default.oneOfType([_propTypes.default.string, _propTypes.default.number])
104
- }),
105
- currYear: _propTypes.default.shape({
106
- label: _propTypes.default.oneOfType([_propTypes.default.string, _propTypes.default.number])
107
- }),
108
- nextMonth: _propTypes.default.shape({
109
- label: _propTypes.default.oneOfType([_propTypes.default.string, _propTypes.default.number]),
110
- navigateTo: _propTypes.default.func
111
- }),
112
- nextYear: _propTypes.default.shape({
113
- label: _propTypes.default.oneOfType([_propTypes.default.string, _propTypes.default.number]),
114
- navigateTo: _propTypes.default.func
115
- }),
116
- prevMonth: _propTypes.default.shape({
117
- label: _propTypes.default.oneOfType([_propTypes.default.string, _propTypes.default.number]),
118
- navigateTo: _propTypes.default.func
119
- }),
120
- prevYear: _propTypes.default.shape({
121
- label: _propTypes.default.oneOfType([_propTypes.default.string, _propTypes.default.number]),
122
- navigateTo: _propTypes.default.func
123
- })
124
- })
125
- };
109
+ nextMonth: _propTypes.default.shape({
110
+ label: _propTypes.default.oneOfType([_propTypes.default.string, _propTypes.default.number]),
111
+ navigateTo: _propTypes.default.func
112
+ }),
113
+ nextYear: _propTypes.default.shape({
114
+ label: _propTypes.default.oneOfType([_propTypes.default.string, _propTypes.default.number]),
115
+ navigateTo: _propTypes.default.func
116
+ }),
117
+ prevMonth: _propTypes.default.shape({
118
+ label: _propTypes.default.oneOfType([_propTypes.default.string, _propTypes.default.number]),
119
+ navigateTo: _propTypes.default.func
120
+ }),
121
+ prevYear: _propTypes.default.shape({
122
+ label: _propTypes.default.oneOfType([_propTypes.default.string, _propTypes.default.number]),
123
+ navigateTo: _propTypes.default.func
124
+ }),
125
+ unfocusable: _propTypes.default.bool
126
+ };
127
+ NavigationContainer.propTypes = NavigationContainerProps;
@@ -0,0 +1,46 @@
1
+ "use strict";
2
+
3
+ var _react = require("@testing-library/react");
4
+ var _react2 = _interopRequireDefault(require("react"));
5
+ var _calendarInput = require("../calendar-input.js");
6
+ function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
7
+ describe('Calendar Input', () => {
8
+ it('allow selection of a date through the calendar widget', async () => {
9
+ const onDateSelectMock = jest.fn();
10
+ const screen = (0, _react.render)( /*#__PURE__*/_react2.default.createElement(_calendarInput.CalendarInput, {
11
+ calendar: "gregory",
12
+ onDateSelect: onDateSelectMock
13
+ }));
14
+ const dateInput = (0, _react.within)(screen.getByTestId('dhis2-uicore-input')).getByRole('textbox');
15
+ _react.fireEvent.focus(dateInput);
16
+ const calendar = await screen.findByTestId('calendar');
17
+ expect(calendar).toBeInTheDocument();
18
+ const todayString = new Date().toISOString().slice(0, -14);
19
+ const today = (0, _react.within)(calendar).getByTestId(todayString);
20
+ _react.fireEvent.click(today);
21
+ await (0, _react.waitFor)(() => {
22
+ expect(calendar).not.toBeInTheDocument();
23
+ });
24
+ expect(onDateSelectMock).toHaveBeenCalledWith(expect.objectContaining({
25
+ calendarDateString: todayString
26
+ }));
27
+ });
28
+ it('allow selection of a date through the input', async () => {
29
+ const onDateSelectMock = jest.fn();
30
+ const screen = (0, _react.render)( /*#__PURE__*/_react2.default.createElement(_calendarInput.CalendarInput, {
31
+ calendar: "gregory",
32
+ onDateSelect: onDateSelectMock
33
+ }));
34
+ const dateInputString = '2024/10/12';
35
+ const dateInput = (0, _react.within)(screen.getByTestId('dhis2-uicore-input')).getByRole('textbox');
36
+ _react.fireEvent.change(dateInput, {
37
+ target: {
38
+ value: dateInputString
39
+ }
40
+ });
41
+ _react.fireEvent.blur(dateInput);
42
+ expect(onDateSelectMock).toHaveBeenCalledWith(expect.objectContaining({
43
+ calendarDateString: dateInputString
44
+ }));
45
+ });
46
+ });
@@ -5,6 +5,7 @@ Object.defineProperty(exports, "__esModule", {
5
5
  });
6
6
  exports.CalendarInput = void 0;
7
7
  var _style = _interopRequireDefault(require("styled-jsx/style"));
8
+ var _multiCalendarDates = require("@dhis2/multi-calendar-dates");
8
9
  var _button = require("@dhis2-ui/button");
9
10
  var _card = require("@dhis2-ui/card");
10
11
  var _input = require("@dhis2-ui/input");
@@ -12,6 +13,7 @@ var _layer = require("@dhis2-ui/layer");
12
13
  var _popper = require("@dhis2-ui/popper");
13
14
  var _classnames = _interopRequireDefault(require("classnames"));
14
15
  var _react = _interopRequireWildcard(require("react"));
16
+ var _calendarContainer = require("../calendar/calendar-container.js");
15
17
  var _calendar = require("../calendar/calendar.js");
16
18
  var _index = _interopRequireDefault(require("../locales/index.js"));
17
19
  function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); }
@@ -26,7 +28,7 @@ const offsetModifier = {
26
28
  };
27
29
  const CalendarInput = function () {
28
30
  let {
29
- onDateSelect,
31
+ onDateSelect: parentOnDateSelect,
30
32
  calendar,
31
33
  date,
32
34
  dir,
@@ -37,45 +39,86 @@ const CalendarInput = function () {
37
39
  width,
38
40
  cellSize,
39
41
  clearable,
42
+ minDate,
43
+ maxDate,
44
+ format,
45
+ // todo: props and types for format and validation
46
+ strictValidation,
40
47
  ...rest
41
48
  } = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
42
49
  const ref = (0, _react.useRef)();
43
50
  const [open, setOpen] = (0, _react.useState)(false);
44
- const calendarProps = _react.default.useMemo(() => {
45
- const onDateSelectWrapper = selectedDate => {
51
+ const [partialDate, setPartialDate] = (0, _react.useState)(date);
52
+ const excludeRef = (0, _react.useRef)(null);
53
+ (0, _react.useEffect)(() => setPartialDate(date), [date]);
54
+ const useDatePickerOptions = (0, _react.useMemo)(() => ({
55
+ calendar,
56
+ locale,
57
+ timeZone,
58
+ // todo: we probably shouldn't have had timezone here in the first place
59
+ numberingSystem,
60
+ weekDayFormat
61
+ }), [calendar, locale, numberingSystem, timeZone, weekDayFormat]);
62
+ const pickerResults = (0, _multiCalendarDates.useDatePicker)({
63
+ onDateSelect: result => {
46
64
  setOpen(false);
47
- onDateSelect === null || onDateSelect === void 0 ? void 0 : onDateSelect(selectedDate);
48
- };
65
+ parentOnDateSelect === null || parentOnDateSelect === void 0 ? void 0 : parentOnDateSelect(result);
66
+ },
67
+ date,
68
+ minDate: minDate,
69
+ maxDate: maxDate,
70
+ strictValidation: strictValidation,
71
+ format: format,
72
+ options: useDatePickerOptions
73
+ });
74
+ const handleChange = e => {
75
+ setPartialDate(e.value);
76
+ };
77
+ const handleBlur = (_, e) => {
78
+ parentOnDateSelect === null || parentOnDateSelect === void 0 ? void 0 : parentOnDateSelect({
79
+ calendarDateString: partialDate
80
+ });
81
+ if (excludeRef.current && !excludeRef.current.contains(e.relatedTarget)) {
82
+ setOpen(false);
83
+ }
84
+ };
85
+ const onFocus = () => {
86
+ setOpen(true);
87
+ };
88
+ const languageDirection = (0, _multiCalendarDates.useResolvedDirection)(dir, locale);
89
+ const calendarProps = (0, _react.useMemo)(() => {
49
90
  return {
50
- onDateSelect: onDateSelectWrapper,
51
- calendar,
52
91
  date,
53
- dir,
54
- locale,
55
- numberingSystem,
56
- weekDayFormat,
57
- timeZone,
58
92
  width,
59
- cellSize
93
+ cellSize,
94
+ isValid: pickerResults.isValid,
95
+ calendarWeekDays: pickerResults.calendarWeekDays,
96
+ weekDayLabels: pickerResults.weekDayLabels,
97
+ currMonth: pickerResults.currMonth,
98
+ currYear: pickerResults.currYear,
99
+ nextMonth: pickerResults.nextMonth,
100
+ nextYear: pickerResults.nextYear,
101
+ prevMonth: pickerResults.prevMonth,
102
+ prevYear: pickerResults.prevYear,
103
+ languageDirection
60
104
  };
61
- }, [calendar, cellSize, date, dir, locale, numberingSystem, onDateSelect, timeZone, weekDayFormat, width]);
62
- const onFocus = () => {
63
- setOpen(true);
64
- };
105
+ }, [cellSize, date, pickerResults, width, languageDirection]);
65
106
  return /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, /*#__PURE__*/_react.default.createElement("div", {
66
107
  ref: ref,
67
- className: "jsx-862452676" + " " + "calendar-input-wrapper"
108
+ className: "jsx-633677374" + " " + "calendar-input-wrapper"
68
109
  }, /*#__PURE__*/_react.default.createElement(_input.InputField, _extends({
69
110
  label: _index.default.t('Pick a date')
70
111
  }, rest, {
71
112
  type: "text",
72
113
  onFocus: onFocus,
73
- value: date
114
+ value: partialDate,
115
+ onChange: handleChange,
116
+ onBlur: handleBlur,
117
+ validationText: pickerResults.errorMessage || pickerResults.warningMessage,
118
+ error: !!pickerResults.errorMessage,
119
+ warning: !!pickerResults.warningMessage
74
120
  })), clearable && /*#__PURE__*/_react.default.createElement("div", {
75
- className: "jsx-862452676" + " " + ((0, _classnames.default)('calendar-clear-button', {
76
- // ToDo: this is a workaround to show the clear button in the correct place when an icon is shown.
77
- // Long-term, we should abstract and share the logic multi-select uses for the input-wrapper
78
- // https://dhis2.atlassian.net/browse/DHIS2-14848
121
+ className: "jsx-633677374" + " " + ((0, _classnames.default)('calendar-clear-button', {
79
122
  'with-icon': rest.valid || rest.error || rest.warning || rest.loading,
80
123
  'with-dense-wrapper': rest.dense
81
124
  }) || "")
@@ -83,7 +126,9 @@ const CalendarInput = function () {
83
126
  dataTest: "calendar-clear-button",
84
127
  secondary: true,
85
128
  small: true,
86
- onClick: () => calendarProps.onDateSelect(null),
129
+ onClick: () => {
130
+ parentOnDateSelect === null || parentOnDateSelect === void 0 ? void 0 : parentOnDateSelect(null);
131
+ },
87
132
  type: "button"
88
133
  }, _index.default.t('Clear')))), open && /*#__PURE__*/_react.default.createElement(_layer.Layer, {
89
134
  onBackdropClick: () => {
@@ -93,17 +138,17 @@ const CalendarInput = function () {
93
138
  reference: ref,
94
139
  placement: "bottom-start",
95
140
  modifiers: [offsetModifier]
96
- }, /*#__PURE__*/_react.default.createElement(_card.Card, null, /*#__PURE__*/_react.default.createElement(_calendar.Calendar, _extends({}, calendarProps, {
97
- date: date
141
+ }, /*#__PURE__*/_react.default.createElement(_card.Card, null, /*#__PURE__*/_react.default.createElement(_calendarContainer.CalendarContainer, _extends({}, calendarProps, {
142
+ excludedRef: excludeRef,
143
+ unfocusable: true
98
144
  }))))), /*#__PURE__*/_react.default.createElement(_style.default, {
99
- id: "862452676"
100
- }, [".calendar-input-wrapper.jsx-862452676{position:relative;}", ".calendar-clear-button.jsx-862452676{position:absolute;inset-inline-end:6px;-webkit-inset-block-start:27px;-ms-intb-rlock-start:27px;inset-block-start:27px;}", ".calendar-clear-button.with-icon.jsx-862452676{inset-inline-end:36px;}", ".calendar-clear-button.with-dense-wrapper.jsx-862452676{-webkit-inset-block-start:23px;-ms-intb-rlock-start:23px;inset-block-start:23px;}"]));
145
+ id: "633677374"
146
+ }, [".calendar-input-wrapper.jsx-633677374{position:relative;}", ".calendar-clear-button.jsx-633677374{position:absolute;inset-inline-end:6px;-webkit-inset-block-start:27px;-ms-intb-rlock-start:27px;inset-block-start:27px;}", ".calendar-clear-button.with-icon.jsx-633677374{inset-inline-end:36px;}", ".calendar-clear-button.with-dense-wrapper.jsx-633677374{-webkit-inset-block-start:23px;-ms-intb-rlock-start:23px;inset-block-start:23px;}"]));
101
147
  };
102
148
  exports.CalendarInput = CalendarInput;
103
149
  CalendarInput.defaultProps = {
104
150
  dataTest: 'dhis2-uiwidgets-calendar-inputfield'
105
151
  };
106
152
  CalendarInput.propTypes = {
107
- ..._calendar.CalendarProps,
108
- ..._input.InputFieldProps
153
+ ..._calendar.CalendarProps
109
154
  };
@@ -3,7 +3,9 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
- exports.default = exports.NepaliWithNepali = exports.NepaliWithEnglish = exports.IslamicWithArabic = exports.GregorianWithEnglish = exports.GregorianWithArabic = exports.EthiopicWithEnglish = exports.EthiopicWithAmharic = exports.CalendarWithClearButton = void 0;
6
+ exports.CalendarWithClearButton = void 0;
7
+ exports.CalendarWithEditiableInput = CalendarWithEditiableInput;
8
+ exports.default = exports.NepaliWithNepali = exports.NepaliWithEnglish = exports.IslamicWithArabic = exports.GregorianWithEnglish = exports.GregorianWithArabic = exports.EthiopicWithEnglish = exports.EthiopicWithAmharic = void 0;
7
9
  var _react = _interopRequireWildcard(require("react"));
8
10
  var _calendarInput = require("../calendar-input/calendar-input.js");
9
11
  var _calendarStoryWrapper = require("./calendar-story-wrapper.js");
@@ -114,4 +116,21 @@ const CalendarWithClearButton = _ref2 => {
114
116
  "data-test": "storybook-calendar-date-value"
115
117
  }, date !== null && date !== void 0 ? date : 'undefined')));
116
118
  };
117
- exports.CalendarWithClearButton = CalendarWithClearButton;
119
+ exports.CalendarWithClearButton = CalendarWithClearButton;
120
+ function CalendarWithEditiableInput() {
121
+ const [date, setDate] = (0, _react.useState)('2020-07-03');
122
+ return /*#__PURE__*/_react.default.createElement("div", null, /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, /*#__PURE__*/_react.default.createElement(_calendarInput.CalendarInput, {
123
+ editable: true,
124
+ date: date,
125
+ calendar: "gregory",
126
+ onDateSelect: selectedDate => {
127
+ const date = selectedDate === null || selectedDate === void 0 ? void 0 : selectedDate.calendarDateString;
128
+ setDate(date);
129
+ },
130
+ width: '700px',
131
+ inputWidth: "900px",
132
+ timeZone: 'UTC',
133
+ minDate: '2020-07-01',
134
+ maxDate: '2020-07-09'
135
+ })));
136
+ }