@primer/components 0.0.0-202192231947 → 0.0.0-202192543046

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.
Files changed (177) hide show
  1. package/CHANGELOG.md +23 -1
  2. package/codemods/deprecateUtilityComponents.js +1 -1
  3. package/dist/browser.esm.js +880 -770
  4. package/dist/browser.esm.js.map +1 -1
  5. package/dist/browser.umd.js +883 -773
  6. package/dist/browser.umd.js.map +1 -1
  7. package/lib/ActionList/Item.js +4 -4
  8. package/lib/ActionList/List.d.ts +2 -1
  9. package/lib/AnchoredOverlay/AnchoredOverlay.d.ts +6 -3
  10. package/lib/AnchoredOverlay/AnchoredOverlay.js +11 -3
  11. package/lib/Autocomplete/Autocomplete.d.ts +306 -0
  12. package/lib/Autocomplete/Autocomplete.js +145 -0
  13. package/lib/Autocomplete/AutocompleteContext.d.ts +17 -0
  14. package/lib/Autocomplete/AutocompleteContext.js +11 -0
  15. package/lib/Autocomplete/AutocompleteInput.d.ts +294 -0
  16. package/lib/Autocomplete/AutocompleteInput.js +157 -0
  17. package/lib/Autocomplete/AutocompleteMenu.d.ts +72 -0
  18. package/lib/Autocomplete/AutocompleteMenu.js +224 -0
  19. package/lib/Autocomplete/AutocompleteOverlay.d.ts +20 -0
  20. package/lib/Autocomplete/AutocompleteOverlay.js +80 -0
  21. package/lib/Autocomplete/index.d.ts +2 -0
  22. package/lib/Autocomplete/index.js +15 -0
  23. package/lib/BaseStyles.js +1 -1
  24. package/lib/BorderBox.js +1 -1
  25. package/lib/Button/Button.js +1 -1
  26. package/lib/Button/ButtonInvisible.js +1 -1
  27. package/lib/Button/ButtonTableList.js +1 -1
  28. package/lib/Caret.js +2 -2
  29. package/lib/DatePicker/DatePicker.js +14 -8
  30. package/lib/DatePicker/DatePickerAnchor.js +7 -2
  31. package/lib/DatePicker/DatePickerOverlay.d.ts +3 -0
  32. package/lib/DatePicker/DatePickerOverlay.js +39 -0
  33. package/lib/DatePicker/DatePickerPanel.js +92 -9
  34. package/lib/DatePicker/Day.js +2 -1
  35. package/lib/DatePicker/Month.js +16 -6
  36. package/lib/DatePicker/useDatePicker.d.ts +18 -2
  37. package/lib/DatePicker/useDatePicker.js +155 -51
  38. package/lib/Dialog.js +1 -1
  39. package/lib/FilteredActionList/FilteredActionList.js +5 -31
  40. package/lib/Flash.js +16 -16
  41. package/lib/Label.js +1 -1
  42. package/lib/Overlay.d.ts +1 -0
  43. package/lib/Overlay.js +3 -1
  44. package/lib/Pagination/Pagination.js +1 -1
  45. package/lib/ProgressBar.js +1 -1
  46. package/lib/SelectMenu/SelectMenu.d.ts +12 -10
  47. package/lib/StateLabel.js +13 -19
  48. package/lib/TextInput.d.ts +5 -13
  49. package/lib/TextInput.js +4 -46
  50. package/lib/TextInputWithTokens.d.ts +325 -0
  51. package/lib/TextInputWithTokens.js +245 -0
  52. package/lib/Token/AvatarToken.d.ts +7 -0
  53. package/lib/Token/AvatarToken.js +64 -0
  54. package/lib/Token/IssueLabelToken.d.ts +14 -0
  55. package/lib/Token/IssueLabelToken.js +144 -0
  56. package/lib/Token/Token.d.ts +15 -0
  57. package/lib/Token/Token.js +94 -0
  58. package/lib/Token/TokenBase.d.ts +31 -0
  59. package/lib/Token/TokenBase.js +108 -0
  60. package/lib/Token/_RemoveTokenButton.d.ts +12 -0
  61. package/lib/Token/_RemoveTokenButton.js +77 -0
  62. package/lib/Token/_TokenTextContainer.d.ts +3 -0
  63. package/lib/Token/_TokenTextContainer.js +17 -0
  64. package/lib/Token/index.d.ts +3 -0
  65. package/lib/Token/index.js +31 -0
  66. package/lib/_TextInputWrapper.d.ts +10 -0
  67. package/lib/_TextInputWrapper.js +51 -0
  68. package/lib/_UnstyledTextInput.d.ts +2 -0
  69. package/lib/_UnstyledTextInput.js +20 -0
  70. package/lib/behaviors/scrollIntoViewingArea.d.ts +1 -0
  71. package/lib/behaviors/scrollIntoViewingArea.js +39 -0
  72. package/lib/hooks/useOpenAndCloseFocus.d.ts +2 -1
  73. package/lib/hooks/useOpenAndCloseFocus.js +7 -2
  74. package/lib/hooks/useOverlay.d.ts +2 -1
  75. package/lib/hooks/useOverlay.js +4 -2
  76. package/lib/index.d.ts +5 -0
  77. package/lib/index.js +36 -0
  78. package/lib/theme-preval.js +372 -3102
  79. package/lib/utils/testing.d.ts +51 -494
  80. package/lib/utils/{types.d.ts → types/AriaRole.d.ts} +0 -13
  81. package/lib/utils/{types.js → types/AriaRole.js} +0 -0
  82. package/lib/utils/types/ComponentProps.d.ts +9 -0
  83. package/lib/utils/types/ComponentProps.js +1 -0
  84. package/lib/utils/types/Flatten.d.ts +4 -0
  85. package/lib/utils/types/Flatten.js +1 -0
  86. package/lib/utils/types/MandateProps.d.ts +3 -0
  87. package/lib/utils/types/MandateProps.js +1 -0
  88. package/lib/utils/types/Merge.d.ts +19 -0
  89. package/lib/utils/types/Merge.js +1 -0
  90. package/lib/utils/types/index.d.ts +5 -0
  91. package/lib/utils/types/index.js +70 -0
  92. package/lib-esm/ActionList/Item.js +4 -4
  93. package/lib-esm/ActionList/List.d.ts +2 -1
  94. package/lib-esm/AnchoredOverlay/AnchoredOverlay.d.ts +6 -3
  95. package/lib-esm/AnchoredOverlay/AnchoredOverlay.js +11 -3
  96. package/lib-esm/Autocomplete/Autocomplete.d.ts +306 -0
  97. package/lib-esm/Autocomplete/Autocomplete.js +123 -0
  98. package/lib-esm/Autocomplete/AutocompleteContext.d.ts +17 -0
  99. package/lib-esm/Autocomplete/AutocompleteContext.js +2 -0
  100. package/lib-esm/Autocomplete/AutocompleteInput.d.ts +294 -0
  101. package/lib-esm/Autocomplete/AutocompleteInput.js +138 -0
  102. package/lib-esm/Autocomplete/AutocompleteMenu.d.ts +72 -0
  103. package/lib-esm/Autocomplete/AutocompleteMenu.js +205 -0
  104. package/lib-esm/Autocomplete/AutocompleteOverlay.d.ts +20 -0
  105. package/lib-esm/Autocomplete/AutocompleteOverlay.js +62 -0
  106. package/lib-esm/Autocomplete/index.d.ts +2 -0
  107. package/lib-esm/Autocomplete/index.js +1 -0
  108. package/lib-esm/BaseStyles.js +1 -1
  109. package/lib-esm/BorderBox.js +1 -1
  110. package/lib-esm/Button/Button.js +1 -1
  111. package/lib-esm/Button/ButtonInvisible.js +1 -1
  112. package/lib-esm/Button/ButtonTableList.js +1 -1
  113. package/lib-esm/Caret.js +2 -2
  114. package/lib-esm/DatePicker/DatePicker.js +13 -6
  115. package/lib-esm/DatePicker/DatePickerAnchor.js +7 -2
  116. package/lib-esm/DatePicker/DatePickerOverlay.d.ts +3 -0
  117. package/lib-esm/DatePicker/DatePickerOverlay.js +24 -0
  118. package/lib-esm/DatePicker/DatePickerPanel.js +86 -10
  119. package/lib-esm/DatePicker/Day.js +2 -1
  120. package/lib-esm/DatePicker/Month.js +15 -6
  121. package/lib-esm/DatePicker/useDatePicker.d.ts +18 -2
  122. package/lib-esm/DatePicker/useDatePicker.js +156 -52
  123. package/lib-esm/Dialog.js +1 -1
  124. package/lib-esm/FilteredActionList/FilteredActionList.js +3 -31
  125. package/lib-esm/Flash.js +16 -16
  126. package/lib-esm/Label.js +1 -1
  127. package/lib-esm/Overlay.d.ts +1 -0
  128. package/lib-esm/Overlay.js +3 -1
  129. package/lib-esm/Pagination/Pagination.js +1 -1
  130. package/lib-esm/ProgressBar.js +1 -1
  131. package/lib-esm/SelectMenu/SelectMenu.d.ts +12 -10
  132. package/lib-esm/StateLabel.js +13 -19
  133. package/lib-esm/TextInput.d.ts +5 -13
  134. package/lib-esm/TextInput.js +4 -37
  135. package/lib-esm/TextInputWithTokens.d.ts +325 -0
  136. package/lib-esm/TextInputWithTokens.js +220 -0
  137. package/lib-esm/Token/AvatarToken.d.ts +7 -0
  138. package/lib-esm/Token/AvatarToken.js +43 -0
  139. package/lib-esm/Token/IssueLabelToken.d.ts +14 -0
  140. package/lib-esm/Token/IssueLabelToken.js +124 -0
  141. package/lib-esm/Token/Token.d.ts +15 -0
  142. package/lib-esm/Token/Token.js +73 -0
  143. package/lib-esm/Token/TokenBase.d.ts +31 -0
  144. package/lib-esm/Token/TokenBase.js +87 -0
  145. package/lib-esm/Token/_RemoveTokenButton.d.ts +12 -0
  146. package/lib-esm/Token/_RemoveTokenButton.js +60 -0
  147. package/lib-esm/Token/_TokenTextContainer.d.ts +3 -0
  148. package/lib-esm/Token/_TokenTextContainer.js +6 -0
  149. package/lib-esm/Token/index.d.ts +3 -0
  150. package/lib-esm/Token/index.js +3 -0
  151. package/lib-esm/_TextInputWrapper.d.ts +10 -0
  152. package/lib-esm/_TextInputWrapper.js +31 -0
  153. package/lib-esm/_UnstyledTextInput.d.ts +2 -0
  154. package/lib-esm/_UnstyledTextInput.js +7 -0
  155. package/lib-esm/behaviors/scrollIntoViewingArea.d.ts +1 -0
  156. package/lib-esm/behaviors/scrollIntoViewingArea.js +30 -0
  157. package/lib-esm/hooks/useOpenAndCloseFocus.d.ts +2 -1
  158. package/lib-esm/hooks/useOpenAndCloseFocus.js +7 -2
  159. package/lib-esm/hooks/useOverlay.d.ts +2 -1
  160. package/lib-esm/hooks/useOverlay.js +4 -2
  161. package/lib-esm/index.d.ts +5 -0
  162. package/lib-esm/index.js +3 -0
  163. package/lib-esm/theme-preval.js +372 -3102
  164. package/lib-esm/utils/testing.d.ts +51 -494
  165. package/lib-esm/utils/{types.d.ts → types/AriaRole.d.ts} +0 -13
  166. package/lib-esm/utils/{types.js → types/AriaRole.js} +0 -0
  167. package/lib-esm/utils/types/ComponentProps.d.ts +9 -0
  168. package/lib-esm/utils/types/ComponentProps.js +1 -0
  169. package/lib-esm/utils/types/Flatten.d.ts +4 -0
  170. package/lib-esm/utils/types/Flatten.js +1 -0
  171. package/lib-esm/utils/types/MandateProps.d.ts +3 -0
  172. package/lib-esm/utils/types/MandateProps.js +1 -0
  173. package/lib-esm/utils/types/Merge.d.ts +19 -0
  174. package/lib-esm/utils/types/Merge.js +1 -0
  175. package/lib-esm/utils/types/index.d.ts +5 -0
  176. package/lib-esm/utils/types/index.js +5 -0
  177. package/package.json +10 -9
@@ -7,7 +7,7 @@ exports.DatePickerPanel = void 0;
7
7
 
8
8
  var _dateFns = require("date-fns");
9
9
 
10
- var _react = _interopRequireDefault(require("react"));
10
+ var _react = _interopRequireWildcard(require("react"));
11
11
 
12
12
  var _Box = _interopRequireDefault(require("../Box"));
13
13
 
@@ -19,24 +19,107 @@ var _constants = require("../constants");
19
19
 
20
20
  var _useDatePicker = _interopRequireDefault(require("./useDatePicker"));
21
21
 
22
+ var _octiconsReact = require("@primer/octicons-react");
23
+
24
+ var _StyledOcticon = _interopRequireDefault(require("../StyledOcticon"));
25
+
26
+ var _Button = _interopRequireWildcard(require("../Button"));
27
+
22
28
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
23
29
 
30
+ function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
31
+
32
+ function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
33
+
24
34
  const DatePickerPanelContainer = (0, _styledComponents.default)(_Box.default).withConfig({
25
35
  displayName: "DatePickerPanel__DatePickerPanelContainer",
26
36
  componentId: "sc-19upxpo-0"
27
- })(["align-items:flex-start;display:flex;flex-direction:row;gap:", ";padding:", ";"], (0, _constants.get)('space.6'), (0, _constants.get)('space.3'));
37
+ })(["align-items:stretch;display:flex;flex-direction:column;"]);
38
+ const DatePickerPanelMonths = (0, _styledComponents.default)(_Box.default).withConfig({
39
+ displayName: "DatePickerPanel__DatePickerPanelMonths",
40
+ componentId: "sc-19upxpo-1"
41
+ })(["align-items:flex-start;display:flex;flex-direction:row;gap:", ";padding:", ";position:relative;"], (0, _constants.get)('space.6'), (0, _constants.get)('space.3'));
42
+ const DatePickerPanelFooter = (0, _styledComponents.default)(_Box.default).withConfig({
43
+ displayName: "DatePickerPanel__DatePickerPanelFooter",
44
+ componentId: "sc-19upxpo-2"
45
+ })(["align-items:flex-start;border-top:1px solid;border-top-color:", ";display:flex;gap:", ";padding-top:12px;padding-bottom:12px;padding-left:", ";padding-right:", ";flex-direction:row;justify-content:space-between;position:relative;"], (0, _constants.get)('colors.border.default'), (0, _constants.get)('space.6'), (0, _constants.get)('space.3'), (0, _constants.get)('space.3'));
46
+ const ArrowButton = (0, _styledComponents.default)(_Button.default).withConfig({
47
+ displayName: "DatePickerPanel__ArrowButton",
48
+ componentId: "sc-19upxpo-3"
49
+ })(["position:absolute;width:40px;height:28px;top:12px;", ";"], props => `${props.side}: ${(0, _constants.get)('space.3')(props)}`);
28
50
 
29
51
  const DatePickerPanel = () => {
30
52
  const {
31
- configuration
53
+ configuration,
54
+ saveValue,
55
+ revertValue,
56
+ currentViewingDate,
57
+ goToMonth,
58
+ nextMonth,
59
+ previousMonth
32
60
  } = (0, _useDatePicker.default)();
33
- return /*#__PURE__*/_react.default.createElement(DatePickerPanelContainer, null, /*#__PURE__*/_react.default.createElement(_Month.Month, {
34
- month: new Date().getMonth(),
35
- year: new Date().getFullYear()
61
+ const previousDisabled = (0, _react.useMemo)(() => {
62
+ const {
63
+ minDate
64
+ } = configuration;
65
+ if (!minDate) return false;
66
+ const previous = (0, _dateFns.subMonths)(currentViewingDate, 1);
67
+
68
+ if (minDate.getFullYear() >= previous.getFullYear() && minDate.getMonth() > previous.getMonth()) {
69
+ return true;
70
+ }
71
+
72
+ return false;
73
+ }, [configuration, currentViewingDate]);
74
+ const nextDisabled = (0, _react.useMemo)(() => {
75
+ const {
76
+ maxDate,
77
+ view
78
+ } = configuration;
79
+ if (!maxDate) return false;
80
+ const next = (0, _dateFns.addMonths)(currentViewingDate, view === '2-month' ? 2 : 1);
81
+
82
+ if (maxDate.getFullYear() <= next.getFullYear() && maxDate.getMonth() < next.getMonth()) {
83
+ return true;
84
+ }
85
+
86
+ return false;
87
+ }, [configuration, currentViewingDate]);
88
+ return /*#__PURE__*/_react.default.createElement(DatePickerPanelContainer, null, /*#__PURE__*/_react.default.createElement(DatePickerPanelMonths, null, /*#__PURE__*/_react.default.createElement(ArrowButton, {
89
+ variant: "small",
90
+ side: "left",
91
+ onClick: previousMonth,
92
+ disabled: previousDisabled
93
+ }, /*#__PURE__*/_react.default.createElement(_StyledOcticon.default, {
94
+ icon: _octiconsReact.ChevronLeftIcon,
95
+ color: "fg.muted"
96
+ })), /*#__PURE__*/_react.default.createElement(_Month.Month, {
97
+ month: currentViewingDate.getMonth(),
98
+ year: currentViewingDate.getFullYear()
36
99
  }), configuration.view === '2-month' && /*#__PURE__*/_react.default.createElement(_Month.Month, {
37
- month: (0, _dateFns.addMonths)(new Date(), 1).getMonth(),
38
- year: (0, _dateFns.addMonths)(new Date(), 1).getFullYear()
39
- }));
100
+ month: (0, _dateFns.addMonths)(currentViewingDate, 1).getMonth(),
101
+ year: (0, _dateFns.addMonths)(currentViewingDate, 1).getFullYear()
102
+ }), /*#__PURE__*/_react.default.createElement(ArrowButton, {
103
+ variant: "small",
104
+ side: "right",
105
+ onClick: nextMonth,
106
+ disabled: nextDisabled
107
+ }, /*#__PURE__*/_react.default.createElement(_StyledOcticon.default, {
108
+ icon: _octiconsReact.ChevronRightIcon,
109
+ color: "fg.muted"
110
+ }))), /*#__PURE__*/_react.default.createElement(DatePickerPanelFooter, null, /*#__PURE__*/_react.default.createElement(_Box.default, null, /*#__PURE__*/_react.default.createElement(_Button.default, {
111
+ variant: "small",
112
+ sx: {
113
+ mr: 1
114
+ },
115
+ onClick: () => revertValue()
116
+ }, "Reset"), /*#__PURE__*/_react.default.createElement(_Button.default, {
117
+ variant: "small",
118
+ onClick: () => goToMonth(new Date())
119
+ }, "Today")), configuration.confirmation && /*#__PURE__*/_react.default.createElement(_Button.ButtonPrimary, {
120
+ variant: "small",
121
+ onClick: () => saveValue()
122
+ }, "Apply")));
40
123
  };
41
124
 
42
125
  exports.DatePickerPanel = DatePickerPanel;
@@ -120,7 +120,7 @@ const DayComponent = (0, _styledComponents.default)(DayBaseComponent).attrs(prop
120
120
  })).withConfig({
121
121
  displayName: "Day__DayComponent",
122
122
  componentId: "sc-1japneh-1"
123
- })(["background-color:", ";border-radius:", ";transition:0.2s background-color ease;& ", "{align-self:center;color:", ";display:flex;font-family:", ";font-size:", ";justify-self:center;user-select:none;transition:0.2s color ease;}&:hover{background-color:", ";cursor:pointer;transition:0.05s background-color ease;& ", "{color:", ";transition:0.1s color ease;}}&:active{background-color:", ";box-shadow:inset ", ";transition:0.1s background-color ease,0.1s box-shadow ease,0.1s color ease;& ", "{color:", ";transition:0.1s color ease;}}"], props => props.background, props => props.borderRadius, _Text.default, props => props.textColor, (0, _constants.get)('fonts.mono'), (0, _constants.get)('fontSizes.0'), props => props.backgroundHover, _Text.default, props => props.textColorHover, props => props.backgroundPressed, (0, _constants.get)('shadows.shadow.medium'), _Text.default, props => props.textColorPressed);
123
+ })(["background-color:", ";border-radius:", ";transition:0.1s background-color ease;& ", "{align-self:center;color:", ";display:flex;font-family:", ";font-size:", ";justify-self:center;user-select:none;transition:0.1s color ease;}&:hover{background-color:", ";cursor:pointer;transition:0.05s background-color ease;& ", "{color:", ";transition:0.1s color ease;}}&:active{background-color:", ";box-shadow:inset ", ";transition:0.1s background-color ease,0.1s box-shadow ease,0.1s color ease;& ", "{color:", ";transition:0.1s color ease;}}"], props => props.background, props => props.borderRadius, _Text.default, props => props.textColor, (0, _constants.get)('fonts.mono'), (0, _constants.get)('fontSizes.0'), props => props.backgroundHover, _Text.default, props => props.textColorHover, props => props.backgroundPressed, (0, _constants.get)('shadows.shadow.medium'), _Text.default, props => props.textColorPressed);
124
124
 
125
125
  const Day = ({
126
126
  date,
@@ -158,6 +158,7 @@ const Day = ({
158
158
  disabled: disabled,
159
159
  selected: selected,
160
160
  onClick: clickHandler,
161
+ onMouseEnter: () => onDayFocus(date),
161
162
  onFocus: () => onDayFocus(date),
162
163
  onBlur: () => onDayBlur(date),
163
164
  onKeyPress: keyPressHandler
@@ -19,6 +19,8 @@ var _constants = require("../constants");
19
19
 
20
20
  var _Day = require("./Day");
21
21
 
22
+ var _useDatePicker = _interopRequireDefault(require("./useDatePicker"));
23
+
22
24
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
23
25
 
24
26
  function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
@@ -42,17 +44,23 @@ const Month = ({
42
44
  month,
43
45
  year
44
46
  }) => {
47
+ const {
48
+ configuration
49
+ } = (0, _useDatePicker.default)();
45
50
  const [selectedDay, setSelectedDay] = (0, _react.useState)(null);
46
51
  const getTitle = (0, _react.useMemo)(() => `${(0, _dateFns.format)(new Date(year, month), 'MMMM yyyy')}`, [month, year]);
47
52
  const weekdayHeaders = (0, _react.useMemo)(() => {
48
53
  const now = new Date(year, month);
54
+ const weekOptions = {
55
+ weekStartsOn: configuration.weekStartsOn === 'Sunday' ? 0 : 1
56
+ };
49
57
  return (0, _dateFns.eachDayOfInterval)({
50
- start: (0, _dateFns.startOfWeek)(now),
51
- end: (0, _dateFns.endOfWeek)(now)
58
+ start: (0, _dateFns.startOfWeek)(now, weekOptions),
59
+ end: (0, _dateFns.endOfWeek)(now, weekOptions)
52
60
  }).map(d => /*#__PURE__*/_react.default.createElement(WeekdayHeader, {
53
61
  key: `weekday-${d}-header`
54
62
  }, (0, _dateFns.format)(d, 'EEEEEE')));
55
- }, [month, year]);
63
+ }, [configuration.weekStartsOn, month, year]);
56
64
 
57
65
  const dayAction = date => {
58
66
  setSelectedDay(date);
@@ -61,8 +69,9 @@ const Month = ({
61
69
  const dayComponents = (0, _react.useMemo)(() => {
62
70
  const components = [];
63
71
  const firstDay = new Date(year, month, 1);
72
+ const preBlanks = configuration.weekStartsOn === 'Sunday' ? firstDay.getDay() : (firstDay.getDay() + 6) % 7;
64
73
 
65
- for (let i = 0; i < firstDay.getDay(); i++) {
74
+ for (let i = 0; i < preBlanks; i++) {
66
75
  components.push( /*#__PURE__*/_react.default.createElement(_Day.BlankDay, {
67
76
  key: `month-pre-blank-${i}`
68
77
  }));
@@ -79,15 +88,16 @@ const Month = ({
79
88
  }
80
89
 
81
90
  const lastDay = (0, _dateFns.lastDayOfMonth)(firstDay);
91
+ const postBlanks = configuration.weekStartsOn === 'Sunday' ? lastDay.getDay() : (lastDay.getDay() + 6) % 7;
82
92
 
83
- for (let i = 6; i > lastDay.getDay(); i--) {
93
+ for (let i = 6; i > postBlanks; i--) {
84
94
  components.push( /*#__PURE__*/_react.default.createElement(_Day.BlankDay, {
85
95
  key: `month-post-blank-${i}`
86
96
  }));
87
97
  }
88
98
 
89
99
  return components;
90
- }, [month, selectedDay, year]);
100
+ }, [configuration.weekStartsOn, month, selectedDay, year]);
91
101
  return /*#__PURE__*/_react.default.createElement(MonthComponent, {
92
102
  role: "grid"
93
103
  }, /*#__PURE__*/_react.default.createElement(MonthTitle, null, getTitle), weekdayHeaders, dayComponents);
@@ -1,6 +1,7 @@
1
1
  import React from 'react';
2
2
  export declare type AnchorVariant = 'input' | 'button' | 'icon-only';
3
3
  export declare type DateFormat = 'short' | 'long' | string;
4
+ export declare type SelectionVariant = 'single' | 'multi' | 'range';
4
5
  export interface DatePickerConfiguration {
5
6
  anchorVariant?: AnchorVariant;
6
7
  blockedDates?: Array<Date>;
@@ -12,8 +13,9 @@ export interface DatePickerConfiguration {
12
13
  maxDate?: Date;
13
14
  placeholder?: string;
14
15
  rangeIncrement?: number;
15
- selection?: 'single' | 'multi' | 'range';
16
+ selection?: SelectionVariant;
16
17
  view?: '1-month' | '2-month';
18
+ weekStartsOn?: 'Sunday' | 'Monday';
17
19
  }
18
20
  export declare type RangeSelection = {
19
21
  from: Date;
@@ -26,13 +28,20 @@ export declare type StringRangeSelection = {
26
28
  export interface DatePickerContext {
27
29
  disabled?: boolean;
28
30
  configuration: DatePickerConfiguration;
31
+ currentViewingDate: Date;
32
+ goToMonth: (date: Date) => void;
33
+ hoverRange?: RangeSelection | null;
29
34
  selection?: Selection;
30
35
  softSelection?: Partial<RangeSelection> | null;
31
36
  selectionActive?: boolean;
32
37
  formattedDate: string;
38
+ nextMonth: () => void;
33
39
  onSelection: (date: Date) => void;
34
40
  onDayFocus: (date: Date) => void;
35
41
  onDayBlur: (date: Date) => void;
42
+ previousMonth: () => void;
43
+ revertValue: () => void;
44
+ saveValue: (selection?: Selection) => void;
36
45
  }
37
46
  export declare type Selection = Date | Array<Date> | RangeSelection | null;
38
47
  export declare type StringSelection = string | Array<string> | {
@@ -45,13 +54,20 @@ declare const useDatePicker: (date?: Date | undefined) => {
45
54
  disabled: boolean;
46
55
  selected: DaySelection;
47
56
  configuration: DatePickerConfiguration;
57
+ currentViewingDate: Date;
58
+ goToMonth: (date: Date) => void;
59
+ hoverRange?: RangeSelection | null | undefined;
48
60
  selection?: Selection | undefined;
49
61
  softSelection?: Partial<RangeSelection> | null | undefined;
50
62
  selectionActive?: boolean | undefined;
51
63
  formattedDate: string;
64
+ nextMonth: () => void;
52
65
  onSelection: (date: Date) => void;
53
66
  onDayFocus: (date: Date) => void;
54
67
  onDayBlur: (date: Date) => void;
68
+ previousMonth: () => void;
69
+ revertValue: () => void;
70
+ saveValue: (selection?: Selection | undefined) => void;
55
71
  };
56
72
  export default useDatePicker;
57
73
  export interface DatePickerProviderProps {
@@ -60,7 +76,7 @@ export interface DatePickerProviderProps {
60
76
  value?: Selection | StringSelection;
61
77
  }
62
78
  export declare function isSingleSelection(selection: Selection): selection is Date;
63
- export declare function isMultiSelection(selection: Selection): selection is Array<Date>;
79
+ export declare function isMultiSelection(selection: Selection | StringSelection): selection is Array<Date> | Array<string>;
64
80
  export declare function isRangeSelection(selection: Selection | StringSelection): selection is RangeSelection | StringRangeSelection;
65
81
  export declare function isStringRangeSelection(selection: StringSelection): selection is StringRangeSelection;
66
82
  export declare const DatePickerProvider: React.FC<DatePickerProviderProps>;
@@ -25,35 +25,50 @@ const DatePickerContext = /*#__PURE__*/(0, _react.createContext)(null);
25
25
 
26
26
  const useDatePicker = date => {
27
27
  const value = (0, _react.useContext)(DatePickerContext);
28
+ const [selected, setSelected] = (0, _react.useState)(false);
28
29
 
29
30
  if (!value) {
30
31
  throw new Error('useDatePicker must be used inside a DatePickerProvider');
31
32
  }
32
33
 
33
- let selected = false;
34
- let blocked,
35
- disabled = false;
36
-
37
- if (date) {
38
- if (value.selection) {
39
- if (isMultiSelection(value.selection)) {
40
- selected = !!value.selection.find(d => (0, _dateFns.isEqual)(d, date));
41
- } else if (isRangeSelection(value.selection)) {
42
- if ((0, _dateFns.isEqual)(date, value.selection.from)) {
43
- selected = 'start';
44
- } else if (value.selection.to && (0, _dateFns.isEqual)(date, value.selection.to)) {
45
- selected = 'end';
46
- } else if ((0, _dateFns.isAfter)(date, value.selection.from) && value.selection.to && (0, _dateFns.isBefore)(date, value.selection.to)) {
47
- selected = 'middle';
34
+ (0, _react.useEffect)(() => {
35
+ if (date) {
36
+ if (value.hoverRange) {
37
+ if (isRangeSelection(value.hoverRange)) {
38
+ if ((0, _dateFns.isEqual)(date, value.hoverRange.from)) {
39
+ setSelected('start');
40
+ } else if (value.hoverRange.to && (0, _dateFns.isEqual)(date, value.hoverRange.to)) {
41
+ setSelected('end');
42
+ } else if ((0, _dateFns.isAfter)(date, value.hoverRange.from) && value.hoverRange.to && (0, _dateFns.isBefore)(date, value.hoverRange.to)) {
43
+ setSelected('middle');
44
+ } else {
45
+ setSelected(false);
46
+ }
47
+ }
48
+ } else if (value.selection) {
49
+ if (isMultiSelection(value.selection)) {
50
+ setSelected(!!value.selection.find(d => (0, _dateFns.isEqual)(d, date)));
51
+ } else if (isRangeSelection(value.selection)) {
52
+ if ((0, _dateFns.isEqual)(date, value.selection.from)) {
53
+ setSelected('start');
54
+ } else if (value.selection.to && (0, _dateFns.isEqual)(date, value.selection.to)) {
55
+ setSelected('end');
56
+ } else if ((0, _dateFns.isAfter)(date, value.selection.from) && value.selection.to && (0, _dateFns.isBefore)(date, value.selection.to)) {
57
+ setSelected('middle');
58
+ } else {
59
+ setSelected(false);
60
+ }
48
61
  } else {
49
- selected = false;
62
+ setSelected((0, _dateFns.isEqual)(date, value.selection));
50
63
  }
51
- } else {
52
- selected = (0, _dateFns.isEqual)(date, value.selection);
53
64
  }
54
- } // Determine if date is blocked out
55
-
65
+ }
66
+ }, [date, value.hoverRange, value.selection]);
67
+ let blocked,
68
+ disabled = false;
56
69
 
70
+ if (date) {
71
+ // Determine if date is blocked out
57
72
  if (value.configuration.blockedDates) {
58
73
  blocked = !!value.configuration.blockedDates.find(d => (0, _dateFns.isEqual)(d, date));
59
74
  } // Determine if date is disabled
@@ -79,7 +94,7 @@ function isSingleSelection(selection) {
79
94
  }
80
95
 
81
96
  function isMultiSelection(selection) {
82
- return Array.isArray(selection) && selection.every(d => d instanceof Date);
97
+ return Array.isArray(selection);
83
98
  }
84
99
 
85
100
  function isRangeSelection(selection) {
@@ -90,24 +105,57 @@ function isStringRangeSelection(selection) {
90
105
  return !!selection.from;
91
106
  }
92
107
 
93
- function parseSelection(selection) {
108
+ function parseSelection(selection, variant) {
94
109
  if (!selection) return;
95
110
 
96
- if (Array.isArray(selection)) {
97
- const parsedSelection = [];
111
+ if (variant === 'multi') {
112
+ if (isMultiSelection(selection)) {
113
+ const parsedSelection = [];
98
114
 
99
- for (const d of selection) {
100
- parsedSelection.push(new Date(new Date(d).toDateString()));
101
- }
115
+ for (const d of selection) {
116
+ parsedSelection.push(new Date(new Date(d).toDateString()));
117
+ }
102
118
 
103
- return parsedSelection.sort((a, b) => b.getMilliseconds() - a.getMilliseconds());
104
- } else if (isRangeSelection(selection)) {
105
- return {
106
- from: new Date(new Date(selection.from).toDateString()),
107
- to: selection.to ? new Date(new Date(selection.to).toDateString()) : null
108
- };
119
+ return parsedSelection.sort((a, b) => a.getTime() - b.getTime());
120
+ } else if (selection instanceof Date) {
121
+ return [new Date(new Date(selection).toDateString())];
122
+ } else if (isRangeSelection(selection)) {
123
+ const parsedSelection = [];
124
+ parsedSelection.push(new Date(new Date(selection.from).toDateString()));
125
+
126
+ if (selection.to) {
127
+ parsedSelection.push(new Date(new Date(selection.to).toDateString()));
128
+ }
129
+
130
+ return parsedSelection.sort((a, b) => a.getTime() - b.getTime());
131
+ }
132
+ } else if (variant === 'range') {
133
+ if (isRangeSelection(selection)) {
134
+ return {
135
+ from: new Date(new Date(selection.from).toDateString()),
136
+ to: selection.to ? new Date(new Date(selection.to).toDateString()) : null
137
+ };
138
+ } else if (isMultiSelection(selection)) {
139
+ return {
140
+ from: new Date(new Date(selection[0]).toDateString()),
141
+ to: selection[1] ? new Date(new Date(selection[1]).toDateString()) : null
142
+ };
143
+ } else if (selection instanceof Date) {
144
+ return {
145
+ from: new Date(new Date(selection).toDateString()),
146
+ to: null
147
+ };
148
+ }
109
149
  } else {
110
- return new Date(new Date(selection).toDateString());
150
+ if (selection instanceof Date) {
151
+ return new Date(new Date(selection).toDateString());
152
+ } else if (isMultiSelection(selection)) {
153
+ return new Date(new Date(selection[0]).toDateString());
154
+ } else if (isRangeSelection(selection)) {
155
+ return new Date(new Date(selection.from).toDateString());
156
+ } else {
157
+ return;
158
+ }
111
159
  }
112
160
  }
113
161
 
@@ -118,7 +166,8 @@ const defaultConfiguration = {
118
166
  dimWeekends: false,
119
167
  placeholder: 'Select a Date...',
120
168
  selection: 'single',
121
- view: '2-month'
169
+ view: '2-month',
170
+ weekStartsOn: 'Sunday'
122
171
  };
123
172
 
124
173
  const DatePickerProvider = ({
@@ -128,11 +177,24 @@ const DatePickerProvider = ({
128
177
  value
129
178
  }) => {
130
179
  const [configuration, setConfiguration] = (0, _react.useState)((0, _deepmerge.default)(defaultConfiguration, externalConfig));
131
- const [selection, setSelection] = (0, _react.useState)(parseSelection(value));
180
+ const [previousSelection, setPreviousSelection] = (0, _react.useState)(parseSelection(value, configuration.selection));
181
+ const [selection, setSelection] = (0, _react.useState)(parseSelection(value, configuration.selection));
132
182
  const [hoverRange, setHoverRange] = (0, _react.useState)(null);
183
+ const [currentViewingDate, setCurrentViewingDate] = (0, _react.useState)(new Date());
133
184
  (0, _react.useEffect)(() => {
134
185
  setConfiguration((0, _deepmerge.default)(defaultConfiguration, externalConfig));
135
- }, [externalConfig]);
186
+ setSelection(parseSelection(selection, configuration.selection)); // Don't want this to run every time selection gets updated
187
+ // eslint-disable-next-line react-hooks/exhaustive-deps
188
+ }, [configuration.selection, externalConfig]);
189
+ const goToMonth = (0, _react.useCallback)(date => {
190
+ setCurrentViewingDate(new Date(new Date(date).toDateString()));
191
+ }, []);
192
+ const nextMonth = (0, _react.useCallback)(() => {
193
+ setCurrentViewingDate((0, _dateFns.addMonths)(currentViewingDate, 1));
194
+ }, [currentViewingDate]);
195
+ const previousMonth = (0, _react.useCallback)(() => {
196
+ setCurrentViewingDate((0, _dateFns.subMonths)(currentViewingDate, 1));
197
+ }, [currentViewingDate]);
136
198
  const getFormattedDate = (0, _react.useMemo)(() => {
137
199
  if (!selection) {
138
200
  return configuration.placeholder;
@@ -161,6 +223,10 @@ const DatePickerProvider = ({
161
223
  {
162
224
  if (selection instanceof Date) {
163
225
  return (0, _dateFns.format)(selection, template);
226
+ } else if (Array.isArray(selection)) {
227
+ return (0, _dateFns.format)(selection[0], template);
228
+ } else if (isRangeSelection(selection)) {
229
+ return (0, _dateFns.format)(selection.from, template);
164
230
  } else {
165
231
  return 'Invalid Selection';
166
232
  }
@@ -169,7 +235,13 @@ const DatePickerProvider = ({
169
235
  case 'multi':
170
236
  {
171
237
  if (Array.isArray(selection)) {
172
- return selection.map(d => (0, _dateFns.format)(d, template)).join(', ');
238
+ if (selection.length > 3) return `${selection.length} Selected`;
239
+ const formatted = selection.map(d => (0, _dateFns.format)(d, template)).join(', ');
240
+ return formatted;
241
+ } else if (selection instanceof Date) {
242
+ return [selection].map(d => (0, _dateFns.format)(d, template)).join(', ');
243
+ } else if (isRangeSelection(selection)) {
244
+ return [selection.to, selection.from].map(d => d ? (0, _dateFns.format)(d, template) : '').join(', ');
173
245
  } else {
174
246
  return 'Invalid Selection';
175
247
  }
@@ -179,6 +251,18 @@ const DatePickerProvider = ({
179
251
  {
180
252
  if (isRangeSelection(selection)) {
181
253
  return Object.entries(selection).map(([_, date]) => date ? (0, _dateFns.format)(date, template) : '').join(' - ');
254
+ } else if (selection instanceof Date) {
255
+ return Object.entries({
256
+ from: selection,
257
+ to: null
258
+ }).map(([_, date]) => date ? (0, _dateFns.format)(date, template) : '').join(' - ');
259
+ } else if (Array.isArray(selection)) {
260
+ return Object.entries({
261
+ from: selection[0],
262
+ to: selection[1]
263
+ }) // to date can still be null
264
+ // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
265
+ .map(([_, date]) => date ? (0, _dateFns.format)(date, template) : '').join(' - ');
182
266
  } else {
183
267
  return 'Invalid Selection';
184
268
  }
@@ -190,30 +274,41 @@ const DatePickerProvider = ({
190
274
  }
191
275
  }
192
276
  }, [configuration.dateFormat, configuration.placeholder, configuration.selection, selection]);
277
+ const saveValue = (0, _react.useCallback)(updatedSelection => {
278
+ setPreviousSelection(updatedSelection !== null && updatedSelection !== void 0 ? updatedSelection : selection);
279
+ closePicker === null || closePicker === void 0 ? void 0 : closePicker();
280
+ }, [closePicker, selection]);
193
281
  const selectionHandler = (0, _react.useCallback)(date => {
194
282
  if (configuration.selection === 'multi') {
195
- const selections = selection;
283
+ const selections = [...selection];
196
284
  const existingIndex = selections.findIndex(s => (0, _dateFns.isEqual)(s, date));
197
285
 
198
286
  if (existingIndex > -1) {
199
- setSelection(selections.splice(existingIndex, 1));
287
+ selections.splice(existingIndex, 1);
288
+ setSelection(selections.sort((a, b) => a.getTime() - b.getTime()));
200
289
  } else {
201
- setSelection([...selections, date]);
290
+ setSelection([...selections, date].sort((a, b) => a.getTime() - b.getTime()));
202
291
  }
203
292
  } else if (configuration.selection === 'range') {
204
293
  if (selection && isRangeSelection(selection) && !selection.to) {
205
- setSelection((0, _dateFns.isBefore)(date, selection.from) ? {
294
+ const updatedSelection = (0, _dateFns.isBefore)(date, selection.from) ? {
206
295
  from: date,
207
296
  to: selection.from
208
297
  } : {
209
298
  from: selection.from,
210
299
  to: date
211
- });
300
+ };
301
+ setSelection(updatedSelection);
302
+ setHoverRange(null);
212
303
 
213
304
  if (!configuration.confirmation) {
214
- closePicker === null || closePicker === void 0 ? void 0 : closePicker();
305
+ saveValue(updatedSelection);
215
306
  }
216
307
  } else {
308
+ setHoverRange({
309
+ from: date,
310
+ to: date
311
+ });
217
312
  setSelection({
218
313
  from: date,
219
314
  to: null
@@ -223,14 +318,14 @@ const DatePickerProvider = ({
223
318
  setSelection(date);
224
319
 
225
320
  if (!configuration.confirmation) {
226
- closePicker === null || closePicker === void 0 ? void 0 : closePicker();
321
+ saveValue(date);
227
322
  }
228
323
  }
229
- }, [closePicker, configuration.confirmation, configuration.selection, selection]);
324
+ }, [configuration.confirmation, configuration.selection, saveValue, selection]);
230
325
  const focusHnadler = (0, _react.useCallback)(date => {
231
326
  if (!selection) return;
232
327
 
233
- if (configuration.selection === 'range' && isRangeSelection(selection)) {
328
+ if (configuration.selection === 'range' && isRangeSelection(selection) && hoverRange) {
234
329
  setHoverRange((0, _dateFns.isBefore)(date, selection.from) ? {
235
330
  from: date,
236
331
  to: selection.from
@@ -239,26 +334,35 @@ const DatePickerProvider = ({
239
334
  to: date
240
335
  });
241
336
  }
242
- }, [configuration.selection, selection]);
337
+ }, [configuration.selection, hoverRange, selection]);
243
338
  const blurHnadler = (0, _react.useCallback)(date => {
244
339
  if (!selection || !hoverRange) return;
245
340
 
246
- if (configuration.selection === 'range' && isRangeSelection(selection) && (hoverRange.from === date || hoverRange.to === date)) {
247
- setHoverRange(null);
341
+ if (configuration.selection === 'range' && isRangeSelection(selection) && (hoverRange.from === date || hoverRange.to === date)) {// setHoverRange({from: hoverRange.from, to: hoverRange.from})
248
342
  }
249
343
  }, [configuration.selection, hoverRange, selection]);
344
+ const revertValue = (0, _react.useCallback)(() => {
345
+ setSelection(previousSelection);
346
+ }, [previousSelection]);
250
347
  const datePickerCtx = (0, _react.useMemo)(() => {
251
348
  return {
252
349
  configuration,
350
+ currentViewingDate,
253
351
  disabled: false,
254
352
  formattedDate: getFormattedDate,
353
+ goToMonth,
354
+ hoverRange,
355
+ nextMonth,
255
356
  onDayBlur: blurHnadler,
256
357
  onDayFocus: focusHnadler,
257
358
  onSelection: selectionHandler,
359
+ previousMonth,
360
+ revertValue,
361
+ saveValue,
258
362
  selectionActive: false,
259
363
  selection
260
364
  };
261
- }, [blurHnadler, configuration, focusHnadler, getFormattedDate, selection, selectionHandler]);
365
+ }, [blurHnadler, configuration, currentViewingDate, focusHnadler, getFormattedDate, goToMonth, hoverRange, nextMonth, previousMonth, revertValue, saveValue, selection, selectionHandler]);
262
366
  return /*#__PURE__*/_react.default.createElement(DatePickerContext.Provider, {
263
367
  value: datePickerCtx
264
368
  }, children);
package/lib/Dialog.js CHANGED
@@ -122,7 +122,7 @@ const Dialog = /*#__PURE__*/(0, _react.forwardRef)(({
122
122
  }), children)) : null;
123
123
  });
124
124
  DialogHeader.defaultProps = {
125
- backgroundColor: 'bg.tertiary'
125
+ backgroundColor: 'canvas.subtle'
126
126
  };
127
127
  DialogHeader.propTypes = { ..._Box.default.propTypes
128
128
  };