baseui 10.12.1 → 11.0.2

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 (307) hide show
  1. package/README.md +3 -3
  2. package/accordion/accordion.js +60 -13
  3. package/accordion/accordion.js.flow +49 -12
  4. package/accordion/index.d.ts +0 -3
  5. package/accordion/panel.js +7 -6
  6. package/accordion/panel.js.flow +20 -20
  7. package/accordion/stateless-accordion.js +2 -4
  8. package/accordion/stateless-accordion.js.flow +0 -2
  9. package/accordion/types.js.flow +0 -5
  10. package/button/constants.js +1 -2
  11. package/button/constants.js.flow +0 -1
  12. package/button/index.d.ts +0 -1
  13. package/button/styled-components.js +2 -29
  14. package/button/styled-components.js.flow +2 -30
  15. package/checkbox/checkbox.js +6 -30
  16. package/checkbox/checkbox.js.flow +7 -38
  17. package/checkbox/constants.js +2 -1
  18. package/checkbox/constants.js.flow +2 -1
  19. package/checkbox/index.d.ts +4 -6
  20. package/checkbox/index.js +0 -6
  21. package/checkbox/index.js.flow +0 -1
  22. package/checkbox/styled-components.js +52 -149
  23. package/checkbox/styled-components.js.flow +59 -165
  24. package/checkbox/types.js.flow +0 -5
  25. package/data-table/column-categorical.js +1 -1
  26. package/data-table/column-categorical.js.flow +1 -1
  27. package/data-table/column-datetime.js +1 -1
  28. package/data-table/column-datetime.js.flow +3 -1
  29. package/data-table/column.js +6 -2
  30. package/data-table/column.js.flow +9 -7
  31. package/data-table/data-table.js +10 -2
  32. package/data-table/data-table.js.flow +4 -1
  33. package/data-table/header-cell.js +3 -0
  34. package/data-table/header-cell.js.flow +1 -1
  35. package/data-table/index.d.ts +7 -8
  36. package/data-table/stateful-data-table.js +2 -1
  37. package/data-table/stateful-data-table.js.flow +1 -0
  38. package/data-table/types.js.flow +8 -0
  39. package/datepicker/calendar.js +28 -15
  40. package/datepicker/calendar.js.flow +31 -14
  41. package/datepicker/constants.js +12 -2
  42. package/datepicker/constants.js.flow +10 -0
  43. package/datepicker/datepicker.js +117 -86
  44. package/datepicker/datepicker.js.flow +123 -66
  45. package/datepicker/day.js +85 -34
  46. package/datepicker/day.js.flow +118 -54
  47. package/datepicker/locale.js.flow +0 -1
  48. package/datepicker/month.js +3 -1
  49. package/datepicker/month.js.flow +2 -0
  50. package/datepicker/stateful-calendar.js +6 -1
  51. package/datepicker/stateful-calendar.js.flow +8 -1
  52. package/datepicker/stateful-container.js +23 -2
  53. package/datepicker/stateful-container.js.flow +17 -3
  54. package/datepicker/stateful-datepicker.js +6 -1
  55. package/datepicker/stateful-datepicker.js.flow +7 -1
  56. package/datepicker/styled-components.js +23 -1
  57. package/datepicker/styled-components.js.flow +12 -2
  58. package/datepicker/types.js.flow +46 -43
  59. package/datepicker/utils/date-helpers.js +30 -0
  60. package/datepicker/utils/date-helpers.js.flow +12 -0
  61. package/datepicker/week.js +3 -1
  62. package/datepicker/week.js.flow +2 -0
  63. package/es/accordion/accordion.js +52 -12
  64. package/es/accordion/panel.js +7 -5
  65. package/es/accordion/stateless-accordion.js +2 -4
  66. package/es/button/constants.js +1 -2
  67. package/es/button/styled-components.js +2 -29
  68. package/es/checkbox/checkbox.js +7 -32
  69. package/es/checkbox/constants.js +2 -1
  70. package/es/checkbox/index.js +1 -1
  71. package/es/checkbox/styled-components.js +51 -146
  72. package/es/data-table/column-categorical.js +1 -1
  73. package/es/data-table/column-datetime.js +1 -1
  74. package/es/data-table/column.js +6 -2
  75. package/es/data-table/data-table.js +6 -2
  76. package/es/data-table/header-cell.js +3 -0
  77. package/es/data-table/stateful-data-table.js +2 -1
  78. package/es/datepicker/calendar.js +28 -15
  79. package/es/datepicker/constants.js +8 -0
  80. package/es/datepicker/datepicker.js +106 -79
  81. package/es/datepicker/day.js +77 -34
  82. package/es/datepicker/month.js +3 -1
  83. package/es/datepicker/stateful-calendar.js +6 -1
  84. package/es/datepicker/stateful-container.js +22 -2
  85. package/es/datepicker/stateful-datepicker.js +6 -1
  86. package/es/datepicker/styled-components.js +8 -2
  87. package/es/datepicker/types.js +1 -1
  88. package/es/datepicker/utils/date-helpers.js +16 -0
  89. package/es/datepicker/week.js +3 -1
  90. package/es/file-uploader/file-uploader.js +4 -4
  91. package/es/form-control/styled-components.js +0 -1
  92. package/es/header-navigation/styled-components.js +3 -3
  93. package/es/helpers/overrides.js +1 -2
  94. package/es/input/styled-components.js +4 -4
  95. package/es/layer/layer.js +4 -4
  96. package/es/list/list-item.js +5 -1
  97. package/es/list/menu-adapter.js +4 -0
  98. package/es/locale/index.js +0 -7
  99. package/es/menu/stateful-container.js +0 -1
  100. package/es/menu/styled-components.js +1 -1
  101. package/es/modal/index.js +1 -1
  102. package/es/modal/modal.js +19 -65
  103. package/es/modal/styled-components.js +12 -48
  104. package/es/phone-input/default-props.js +1 -1
  105. package/es/phone-input/index.js +0 -4
  106. package/es/phone-input/phone-input-lite.js +55 -31
  107. package/es/radio/radio.js +1 -7
  108. package/es/radio/radiogroup.js +3 -28
  109. package/es/radio/styled-components.js +4 -5
  110. package/es/rating/styled-components.js +3 -3
  111. package/es/select/index.js +1 -2
  112. package/es/select/select-component.js +20 -20
  113. package/es/select/styled-components.js +21 -17
  114. package/es/snackbar/snackbar-context.js +1 -1
  115. package/es/snackbar/styled-components.js +2 -2
  116. package/es/spinner/index.js +3 -9
  117. package/es/spinner/styled-components.js +2 -32
  118. package/es/table/filter.js +3 -3
  119. package/es/tag/styled-components.js +1 -1
  120. package/es/themes/dark-theme/color-component-tokens.js +0 -38
  121. package/es/themes/dark-theme/color-tokens.js +0 -2
  122. package/es/themes/dark-theme/create-dark-theme.js +0 -2
  123. package/es/themes/dark-theme/dark-theme.js +0 -2
  124. package/es/themes/light-theme/color-component-tokens.js +0 -38
  125. package/es/themes/light-theme/color-tokens.js +0 -2
  126. package/es/themes/light-theme/create-light-theme.js +0 -2
  127. package/es/themes/light-theme/light-theme.js +0 -2
  128. package/es/timepicker/timepicker.js +1 -8
  129. package/es/typography/index.js +1 -31
  130. package/esm/accordion/accordion.js +60 -13
  131. package/esm/accordion/panel.js +7 -6
  132. package/esm/accordion/stateless-accordion.js +2 -4
  133. package/esm/button/constants.js +1 -2
  134. package/esm/button/styled-components.js +2 -29
  135. package/esm/checkbox/checkbox.js +7 -30
  136. package/esm/checkbox/constants.js +2 -1
  137. package/esm/checkbox/index.js +1 -1
  138. package/esm/checkbox/styled-components.js +52 -147
  139. package/esm/data-table/column-categorical.js +1 -1
  140. package/esm/data-table/column-datetime.js +1 -1
  141. package/esm/data-table/column.js +6 -2
  142. package/esm/data-table/data-table.js +10 -2
  143. package/esm/data-table/header-cell.js +3 -0
  144. package/esm/data-table/stateful-data-table.js +2 -1
  145. package/esm/datepicker/calendar.js +28 -15
  146. package/esm/datepicker/constants.js +8 -0
  147. package/esm/datepicker/datepicker.js +116 -86
  148. package/esm/datepicker/day.js +84 -34
  149. package/esm/datepicker/month.js +3 -1
  150. package/esm/datepicker/stateful-calendar.js +6 -1
  151. package/esm/datepicker/stateful-container.js +23 -2
  152. package/esm/datepicker/stateful-datepicker.js +6 -1
  153. package/esm/datepicker/styled-components.js +24 -2
  154. package/esm/datepicker/types.js +1 -1
  155. package/esm/datepicker/utils/date-helpers.js +30 -0
  156. package/esm/datepicker/week.js +3 -1
  157. package/esm/file-uploader/file-uploader.js +4 -4
  158. package/esm/form-control/styled-components.js +0 -1
  159. package/esm/header-navigation/styled-components.js +3 -3
  160. package/esm/helpers/overrides.js +1 -2
  161. package/esm/input/styled-components.js +4 -4
  162. package/esm/layer/layer.js +4 -4
  163. package/esm/list/list-item.js +5 -1
  164. package/esm/list/menu-adapter.js +4 -0
  165. package/esm/locale/index.js +0 -7
  166. package/esm/menu/stateful-container.js +0 -1
  167. package/esm/menu/styled-components.js +1 -1
  168. package/esm/modal/index.js +1 -1
  169. package/esm/modal/modal.js +28 -71
  170. package/esm/modal/styled-components.js +6 -38
  171. package/esm/phone-input/default-props.js +1 -1
  172. package/esm/phone-input/index.js +0 -4
  173. package/esm/phone-input/phone-input-lite.js +60 -37
  174. package/esm/radio/radio.js +1 -7
  175. package/esm/radio/radiogroup.js +3 -28
  176. package/esm/radio/styled-components.js +4 -5
  177. package/esm/rating/styled-components.js +3 -3
  178. package/esm/select/index.js +1 -2
  179. package/esm/select/select-component.js +20 -20
  180. package/esm/select/styled-components.js +21 -14
  181. package/esm/snackbar/snackbar-context.js +1 -1
  182. package/esm/snackbar/styled-components.js +2 -2
  183. package/esm/spinner/index.js +3 -9
  184. package/esm/spinner/styled-components.js +2 -40
  185. package/esm/table/filter.js +3 -3
  186. package/esm/tag/styled-components.js +1 -1
  187. package/esm/themes/dark-theme/color-component-tokens.js +0 -38
  188. package/esm/themes/dark-theme/color-tokens.js +0 -2
  189. package/esm/themes/dark-theme/create-dark-theme.js +1 -2
  190. package/esm/themes/dark-theme/dark-theme.js +1 -2
  191. package/esm/themes/light-theme/color-component-tokens.js +0 -38
  192. package/esm/themes/light-theme/color-tokens.js +0 -2
  193. package/esm/themes/light-theme/create-light-theme.js +1 -2
  194. package/esm/themes/light-theme/light-theme.js +1 -2
  195. package/esm/timepicker/timepicker.js +1 -8
  196. package/esm/typography/index.js +1 -35
  197. package/file-uploader/file-uploader.js +3 -3
  198. package/file-uploader/file-uploader.js.flow +4 -4
  199. package/form-control/index.d.ts +9 -0
  200. package/form-control/styled-components.js +0 -1
  201. package/form-control/styled-components.js.flow +0 -1
  202. package/header-navigation/styled-components.js +3 -3
  203. package/header-navigation/styled-components.js.flow +3 -3
  204. package/helpers/overrides.js +1 -2
  205. package/helpers/overrides.js.flow +1 -1
  206. package/input/index.d.ts +5 -9
  207. package/input/styled-components.js +4 -4
  208. package/input/styled-components.js.flow +4 -4
  209. package/layer/layer.js +4 -4
  210. package/layer/layer.js.flow +4 -3
  211. package/list/list-item.js +5 -1
  212. package/list/list-item.js.flow +4 -0
  213. package/list/menu-adapter.js +4 -0
  214. package/list/menu-adapter.js.flow +4 -0
  215. package/list/types.js.flow +4 -0
  216. package/locale/index.js +0 -7
  217. package/locale/index.js.flow +0 -7
  218. package/locale.ts +0 -1
  219. package/menu/index.d.ts +1 -3
  220. package/menu/stateful-container.js +0 -1
  221. package/menu/stateful-container.js.flow +0 -1
  222. package/menu/styled-components.js +1 -1
  223. package/menu/styled-components.js.flow +1 -1
  224. package/modal/index.d.ts +4 -6
  225. package/modal/index.js +0 -6
  226. package/modal/index.js.flow +0 -1
  227. package/modal/modal.js +27 -70
  228. package/modal/modal.js.flow +17 -83
  229. package/modal/styled-components.js +7 -40
  230. package/modal/styled-components.js.flow +12 -44
  231. package/modal/types.js.flow +1 -10
  232. package/package.json +3 -2
  233. package/phone-input/default-props.js +1 -1
  234. package/phone-input/default-props.js.flow +1 -1
  235. package/phone-input/index.d.ts +0 -1
  236. package/phone-input/index.js +0 -36
  237. package/phone-input/index.js.flow +0 -4
  238. package/phone-input/phone-input-lite.js +63 -38
  239. package/phone-input/phone-input-lite.js.flow +66 -44
  240. package/radio/index.d.ts +4 -9
  241. package/radio/radio.js +1 -7
  242. package/radio/radio.js.flow +1 -8
  243. package/radio/radiogroup.js +3 -28
  244. package/radio/radiogroup.js.flow +2 -26
  245. package/radio/styled-components.js +4 -5
  246. package/radio/styled-components.js.flow +3 -4
  247. package/radio/types.js.flow +4 -15
  248. package/rating/styled-components.js +3 -3
  249. package/rating/styled-components.js.flow +3 -3
  250. package/select/index.d.ts +0 -2
  251. package/select/index.js +0 -6
  252. package/select/index.js.flow +0 -2
  253. package/select/select-component.js +23 -24
  254. package/select/select-component.js.flow +25 -14
  255. package/select/styled-components.js +23 -17
  256. package/select/styled-components.js.flow +17 -12
  257. package/snackbar/snackbar-context.js +1 -1
  258. package/snackbar/snackbar-context.js.flow +1 -1
  259. package/snackbar/styled-components.js +1 -1
  260. package/snackbar/styled-components.js.flow +11 -11
  261. package/spinner/index.d.ts +5 -18
  262. package/spinner/index.js +2 -68
  263. package/spinner/index.js.flow +2 -27
  264. package/spinner/styled-components.js +9 -45
  265. package/spinner/styled-components.js.flow +2 -34
  266. package/spinner/types.js.flow +1 -19
  267. package/styles/types.js.flow +0 -2
  268. package/table/filter.js +3 -3
  269. package/table/filter.js.flow +3 -3
  270. package/tag/styled-components.js +1 -1
  271. package/tag/styled-components.js.flow +1 -1
  272. package/tag/types.js.flow +1 -1
  273. package/theme.ts +0 -81
  274. package/themes/dark-theme/color-component-tokens.js +0 -38
  275. package/themes/dark-theme/color-component-tokens.js.flow +0 -42
  276. package/themes/dark-theme/color-tokens.js +0 -2
  277. package/themes/dark-theme/color-tokens.js.flow +0 -2
  278. package/themes/dark-theme/create-dark-theme.js +1 -3
  279. package/themes/dark-theme/create-dark-theme.js.flow +0 -2
  280. package/themes/dark-theme/dark-theme.js +1 -3
  281. package/themes/dark-theme/dark-theme.js.flow +0 -2
  282. package/themes/light-theme/color-component-tokens.js +0 -38
  283. package/themes/light-theme/color-component-tokens.js.flow +0 -43
  284. package/themes/light-theme/color-tokens.js +0 -2
  285. package/themes/light-theme/color-tokens.js.flow +0 -2
  286. package/themes/light-theme/create-light-theme.js +1 -3
  287. package/themes/light-theme/create-light-theme.js.flow +0 -2
  288. package/themes/light-theme/light-theme.js +1 -3
  289. package/themes/light-theme/light-theme.js.flow +0 -2
  290. package/themes/types.js.flow +0 -68
  291. package/timepicker/timepicker.js +1 -8
  292. package/timepicker/timepicker.js.flow +4 -10
  293. package/typography/index.d.ts +0 -23
  294. package/typography/index.js +2 -57
  295. package/typography/index.js.flow +0 -31
  296. package/es/spinner/spinner.js +0 -68
  297. package/es/themes/dark-theme/color-deprecated-semantic-tokens.js +0 -35
  298. package/es/themes/light-theme/color-deprecated-semantic-tokens.js +0 -35
  299. package/esm/spinner/spinner.js +0 -125
  300. package/esm/themes/dark-theme/color-deprecated-semantic-tokens.js +0 -38
  301. package/esm/themes/light-theme/color-deprecated-semantic-tokens.js +0 -38
  302. package/spinner/spinner.js +0 -136
  303. package/spinner/spinner.js.flow +0 -75
  304. package/themes/dark-theme/color-deprecated-semantic-tokens.js +0 -50
  305. package/themes/dark-theme/color-deprecated-semantic-tokens.js.flow +0 -42
  306. package/themes/light-theme/color-deprecated-semantic-tokens.js +0 -50
  307. package/themes/light-theme/color-deprecated-semantic-tokens.js.flow +0 -42
@@ -19,23 +19,26 @@ import {
19
19
  StyledStartDate,
20
20
  StyledEndDate,
21
21
  } from './styled-components.js';
22
- import type { DatepickerPropsT } from './types.js';
22
+ import type { DatepickerPropsT, InputRoleT } from './types.js';
23
23
  import DateHelpers from './utils/date-helpers.js';
24
24
  import dateFnsAdapter from './utils/date-fns-adapter.js';
25
25
  import type { LocaleT } from '../locale/types.js';
26
+ import { INPUT_ROLE, RANGED_CALENDAR_BEHAVIOR } from './constants.js';
26
27
 
27
28
  export const DEFAULT_DATE_FORMAT = 'yyyy/MM/dd';
28
29
 
29
- const INPUT_DELIMITER = ' ';
30
+ const INPUT_DELIMITER = '–';
30
31
 
31
- const combineSeparatedInputs = (newInputValue, prevCombinedInputValue = '', separatedInput) => {
32
+ const combineSeparatedInputs = (newInputValue, prevCombinedInputValue = '', inputRole) => {
32
33
  let inputValue = newInputValue;
33
- const [prevStartDate = '', prevEndDate = ''] = prevCombinedInputValue.split(INPUT_DELIMITER);
34
- if (separatedInput === 'startDate' && prevEndDate) {
35
- inputValue = `${inputValue} – ${prevEndDate}`;
34
+ const [prevStartDate = '', prevEndDate = ''] = prevCombinedInputValue.split(
35
+ ` ${INPUT_DELIMITER} `
36
+ );
37
+ if (inputRole === INPUT_ROLE.startDate && prevEndDate) {
38
+ inputValue = `${inputValue} ${INPUT_DELIMITER} ${prevEndDate}`;
36
39
  }
37
- if (separatedInput === 'endDate') {
38
- inputValue = `${prevStartDate} ${inputValue}`;
40
+ if (inputRole === INPUT_ROLE.endDate) {
41
+ inputValue = `${prevStartDate} ${INPUT_DELIMITER} ${inputValue}`;
39
42
  }
40
43
  return inputValue;
41
44
  };
@@ -43,6 +46,7 @@ const combineSeparatedInputs = (newInputValue, prevCombinedInputValue = '', sepa
43
46
  type StateT = {|
44
47
  calendarFocused: boolean,
45
48
  isOpen: boolean,
49
+ selectedInput: ?InputRoleT,
46
50
  isPseudoFocused: boolean,
47
51
  lastActiveElm: ?HTMLElement,
48
52
  inputValue?: string,
@@ -62,32 +66,71 @@ export default class Datepicker<T = Date> extends React.Component<DatepickerProp
62
66
 
63
67
  constructor(props: DatepickerPropsT<T>) {
64
68
  super(props);
65
- //$FlowFixMe
69
+ //$FlowFixMe[incompatible-call]
66
70
  this.dateHelpers = new DateHelpers(props.adapter);
67
71
  this.state = {
68
72
  calendarFocused: false,
69
73
  isOpen: false,
74
+ selectedInput: null,
70
75
  isPseudoFocused: false,
71
76
  lastActiveElm: null,
72
77
  inputValue: this.formatDisplayValue(props.value) || '',
73
78
  };
74
79
  }
75
80
 
76
- onChange: ({ date: ?T | Array<T> }) => void = (data) => {
81
+ handleChange: (?T | $ReadOnlyArray<?T>) => void = (date) => {
82
+ const onChange = this.props.onChange;
83
+ const onRangeChange = this.props.onRangeChange;
84
+
85
+ if (Array.isArray(date)) {
86
+ if (onChange && date.every(Boolean)) {
87
+ // flowlint-next-line unclear-type:off
88
+ onChange({ date: ((date: any): Array<T>) });
89
+ }
90
+
91
+ if (onRangeChange) {
92
+ onRangeChange({ date: [...date] });
93
+ }
94
+ } else {
95
+ if (onChange) {
96
+ onChange({ date });
97
+ }
98
+
99
+ if (onRangeChange) {
100
+ onRangeChange({ date });
101
+ }
102
+ }
103
+ };
104
+
105
+ onCalendarSelect: ({ +date: ?T | Array<?T> }) => void = (data) => {
77
106
  let isOpen = false;
78
107
  let isPseudoFocused = false;
79
108
  let calendarFocused = false;
80
109
  let nextDate = data.date;
81
110
 
82
111
  if (Array.isArray(nextDate) && this.props.range) {
83
- if (nextDate.length < 2) {
112
+ if (!nextDate[0] || !nextDate[1]) {
84
113
  isOpen = true;
85
114
  isPseudoFocused = true;
86
115
  calendarFocused = null;
87
- } else if (nextDate.length === 2) {
116
+ } else if (nextDate[0] && nextDate[1]) {
88
117
  const [start, end] = nextDate;
89
118
  if (this.dateHelpers.isAfter(start, end)) {
90
- nextDate = [start, start];
119
+ if (this.hasLockedBehavior()) {
120
+ nextDate = this.props.value;
121
+ isOpen = true;
122
+ } else {
123
+ nextDate = [start, start];
124
+ }
125
+ } else if (
126
+ this.dateHelpers.dateRangeIncludesDates(
127
+ // $FlowFixMe Cannot call `this.dateHelpers.dateRangeIncludesDates` with `nextDate` bound to the first parameter because read-only array type [1] is incompatible with array type [2]
128
+ nextDate,
129
+ this.props.excludeDates
130
+ )
131
+ ) {
132
+ nextDate = this.props.value;
133
+ isOpen = true;
91
134
  }
92
135
 
93
136
  if (this.state.lastActiveElm) {
@@ -131,28 +174,37 @@ export default class Datepicker<T = Date> extends React.Component<DatepickerProp
131
174
  inputValue: this.formatDisplayValue(nextDate),
132
175
  });
133
176
 
134
- this.props.onChange && this.props.onChange({ date: nextDate });
177
+ this.handleChange(nextDate);
135
178
  };
136
179
 
137
- formatDate(date: ?T | Array<T>, formatString: string) {
138
- const format = (date) => {
180
+ getNullDatePlaceholder(formatString: string) {
181
+ return (this.getMask() || formatString).split(INPUT_DELIMITER)[0].replace(/[0-9]|[a-z]/g, ' ');
182
+ }
183
+
184
+ formatDate(date: ?T | $ReadOnlyArray<?T>, formatString: string) {
185
+ const format = (date: T) => {
139
186
  if (formatString === DEFAULT_DATE_FORMAT) {
140
187
  return this.dateHelpers.format(date, 'slashDate', this.props.locale);
141
188
  }
142
189
  return this.dateHelpers.formatDate(date, formatString, this.props.locale);
143
190
  };
191
+
144
192
  if (!date) {
145
193
  return '';
146
194
  } else if (Array.isArray(date) && !date[0] && !date[1]) {
147
195
  return '';
196
+ } else if (Array.isArray(date) && !date[0] && date[1]) {
197
+ const endDate = format(date[1]);
198
+ const startDate = this.getNullDatePlaceholder(formatString);
199
+ return [startDate, endDate].join(` ${INPUT_DELIMITER} `);
148
200
  } else if (Array.isArray(date)) {
149
- return date.map((day) => format(day)).join(INPUT_DELIMITER);
201
+ return date.map((day) => (day ? format(day) : '')).join(` ${INPUT_DELIMITER} `);
150
202
  } else {
151
203
  return format(date);
152
204
  }
153
205
  }
154
206
 
155
- formatDisplayValue: (?T | Array<T>) => string = (date: ?T | Array<T>) => {
207
+ formatDisplayValue: (?T | $ReadOnlyArray<?T>) => string = (date) => {
156
208
  const { displayValueAtRangeIndex, formatDisplayValue, range } = this.props;
157
209
  const formatString = this.normalizeDashes(this.props.formatString);
158
210
 
@@ -181,12 +233,13 @@ export default class Datepicker<T = Date> extends React.Component<DatepickerProp
181
233
  return this.formatDate(date, formatString);
182
234
  };
183
235
 
184
- open = () => {
236
+ open = (inputRole?: InputRoleT) => {
185
237
  this.setState(
186
238
  {
187
239
  isOpen: true,
188
240
  isPseudoFocused: true,
189
241
  calendarFocused: false,
242
+ selectedInput: inputRole,
190
243
  },
191
244
  this.props.onOpen
192
245
  );
@@ -197,6 +250,7 @@ export default class Datepicker<T = Date> extends React.Component<DatepickerProp
197
250
  this.setState(
198
251
  {
199
252
  isOpen: false,
253
+ selectedInput: null,
200
254
  isPseudoFocused,
201
255
  calendarFocused: false,
202
256
  },
@@ -229,19 +283,16 @@ export default class Datepicker<T = Date> extends React.Component<DatepickerProp
229
283
  }
230
284
 
231
285
  if (range && !separateRangeInputs) {
232
- return '9999/99/99 9999/99/99';
286
+ return `9999/99/99 ${INPUT_DELIMITER} 9999/99/99`;
233
287
  }
234
288
 
235
289
  return '9999/99/99';
236
290
  };
237
291
 
238
- handleInputChange = (
239
- event: SyntheticInputEvent<HTMLInputElement>,
240
- separatedInput?: 'startDate' | 'endDate'
241
- ) => {
292
+ handleInputChange = (event: SyntheticInputEvent<HTMLInputElement>, inputRole?: InputRoleT) => {
242
293
  const inputValue =
243
294
  this.props.range && this.props.separateRangeInputs
244
- ? combineSeparatedInputs(event.currentTarget.value, this.state.inputValue, separatedInput)
295
+ ? combineSeparatedInputs(event.currentTarget.value, this.state.inputValue, inputRole)
245
296
  : event.currentTarget.value;
246
297
 
247
298
  const mask = this.getMask();
@@ -251,12 +302,10 @@ export default class Datepicker<T = Date> extends React.Component<DatepickerProp
251
302
  (typeof mask === 'string' && inputValue === mask.replace(/9/g, ' ')) ||
252
303
  inputValue.length === 0
253
304
  ) {
254
- if (this.props.onChange) {
255
- if (this.props.range) {
256
- this.props.onChange({ date: [] });
257
- } else {
258
- this.props.onChange({ date: null });
259
- }
305
+ if (this.props.range) {
306
+ this.handleChange([]);
307
+ } else {
308
+ this.handleChange(null);
260
309
  }
261
310
  }
262
311
 
@@ -270,7 +319,7 @@ export default class Datepicker<T = Date> extends React.Component<DatepickerProp
270
319
  };
271
320
 
272
321
  if (this.props.range && typeof this.props.displayValueAtRangeIndex !== 'number') {
273
- const [left, right] = this.normalizeDashes(inputValue).split(INPUT_DELIMITER);
322
+ const [left, right] = this.normalizeDashes(inputValue).split(` ${INPUT_DELIMITER} `);
274
323
 
275
324
  let startDate = this.dateHelpers.date(left);
276
325
  let endDate = this.dateHelpers.date(right);
@@ -280,18 +329,15 @@ export default class Datepicker<T = Date> extends React.Component<DatepickerProp
280
329
  endDate = parseDateString(right);
281
330
  }
282
331
 
283
- const onChange = this.props.onChange;
284
- if (onChange) {
285
- const datesValid = this.dateHelpers.isValid(startDate) && this.dateHelpers.isValid(endDate);
332
+ const datesValid = this.dateHelpers.isValid(startDate) && this.dateHelpers.isValid(endDate);
286
333
 
287
- // added equal case so that times within the same day can be expressed
288
- const rangeValid =
289
- this.dateHelpers.isAfter(endDate, startDate) ||
290
- this.dateHelpers.isEqual(startDate, endDate);
334
+ // added equal case so that times within the same day can be expressed
335
+ const rangeValid =
336
+ this.dateHelpers.isAfter(endDate, startDate) ||
337
+ this.dateHelpers.isEqual(startDate, endDate);
291
338
 
292
- if (datesValid && rangeValid) {
293
- onChange({ date: [startDate, endDate] });
294
- }
339
+ if (datesValid && rangeValid) {
340
+ this.handleChange([startDate, endDate]);
295
341
  }
296
342
  } else {
297
343
  const dateString = this.normalizeDashes(inputValue);
@@ -306,41 +352,41 @@ export default class Datepicker<T = Date> extends React.Component<DatepickerProp
306
352
  date = parseDateString(dateString);
307
353
  }
308
354
 
309
- const { displayValueAtRangeIndex, onChange, range, value } = this.props;
310
- if (date && this.dateHelpers.isValid(date) && onChange) {
355
+ const { displayValueAtRangeIndex, range, value } = this.props;
356
+ if (date && this.dateHelpers.isValid(date)) {
311
357
  if (range && Array.isArray(value) && typeof displayValueAtRangeIndex === 'number') {
312
358
  let [left, right] = value;
313
359
  if (displayValueAtRangeIndex === 0) {
314
360
  left = date;
315
361
  if (!right) {
316
- onChange({ date: [left] });
362
+ this.handleChange([left]);
317
363
  } else {
318
364
  if (this.dateHelpers.isAfter(right, left) || this.dateHelpers.isEqual(left, right)) {
319
- onChange({ date: [left, right] });
365
+ this.handleChange([left, right]);
320
366
  } else {
321
367
  // Is resetting back to previous value appropriate? Invalid range is not
322
368
  // communicated to the user, but if it was not reset the text value would
323
369
  // show one value and date value another. This seems a bit better but clearly
324
370
  // has a downside.
325
- onChange({ date: [...value] });
371
+ this.handleChange([...value]);
326
372
  }
327
373
  }
328
374
  } else if (displayValueAtRangeIndex === 1) {
329
375
  right = date;
330
376
  if (!left) {
331
377
  // If start value is not defined, set start/end to the same day.
332
- onChange({ date: [right, right] });
378
+ this.handleChange([right, right]);
333
379
  } else {
334
380
  if (this.dateHelpers.isAfter(right, left) || this.dateHelpers.isEqual(left, right)) {
335
- onChange({ date: [left, right] });
381
+ this.handleChange([left, right]);
336
382
  } else {
337
383
  // See comment above about resetting dates on invalid range
338
- onChange({ date: [...value] });
384
+ this.handleChange([...value]);
339
385
  }
340
386
  }
341
387
  }
342
388
  } else {
343
- onChange({ date });
389
+ this.handleChange(date);
344
390
  }
345
391
  }
346
392
  }
@@ -370,7 +416,15 @@ export default class Datepicker<T = Date> extends React.Component<DatepickerProp
370
416
 
371
417
  normalizeDashes = (inputValue: string) => {
372
418
  // replacing both hyphens and em-dashes with en-dashes
373
- return inputValue.replace(/-/g, '–').replace(/—/g, '–');
419
+ return inputValue.replace(/-/g, INPUT_DELIMITER).replace(/—/g, INPUT_DELIMITER);
420
+ };
421
+
422
+ hasLockedBehavior = () => {
423
+ return (
424
+ this.props.rangedCalendarBehavior === RANGED_CALENDAR_BEHAVIOR.locked &&
425
+ this.props.range &&
426
+ this.props.separateRangeInputs
427
+ );
374
428
  };
375
429
 
376
430
  componentDidUpdate(prevProps: DatepickerPropsT<T>) {
@@ -381,7 +435,7 @@ export default class Datepicker<T = Date> extends React.Component<DatepickerProp
381
435
  }
382
436
  }
383
437
 
384
- renderInputComponent(locale: LocaleT, separatedInput?: 'startDate' | 'endDate') {
438
+ renderInputComponent(locale: LocaleT, inputRole?: InputRoleT) {
385
439
  const { overrides = {} } = this.props;
386
440
 
387
441
  const [InputComponent, inputProps] = getOverrides(overrides.Input, MaskedInput);
@@ -390,20 +444,20 @@ export default class Datepicker<T = Date> extends React.Component<DatepickerProp
390
444
  this.props.placeholder || this.props.placeholder === ''
391
445
  ? this.props.placeholder
392
446
  : this.props.range && !this.props.separateRangeInputs
393
- ? 'YYYY/MM/DD YYYY/MM/DD'
447
+ ? `YYYY/MM/DD ${INPUT_DELIMITER} YYYY/MM/DD`
394
448
  : 'YYYY/MM/DD';
395
449
 
396
- const [startDate = '', endDate = ''] = (this.state.inputValue || '').split(INPUT_DELIMITER);
450
+ const [startDate = '', endDate = ''] = (this.state.inputValue || '').split(
451
+ ` ${INPUT_DELIMITER} `
452
+ );
397
453
 
398
454
  const value =
399
- separatedInput === 'startDate'
455
+ inputRole === INPUT_ROLE.startDate
400
456
  ? startDate
401
- : separatedInput === 'endDate'
457
+ : inputRole === INPUT_ROLE.endDate
402
458
  ? endDate
403
459
  : this.state.inputValue;
404
460
 
405
- const onChange = (event) => this.handleInputChange(event, separatedInput);
406
-
407
461
  return (
408
462
  <InputComponent
409
463
  aria-disabled={this.props.disabled}
@@ -419,10 +473,10 @@ export default class Datepicker<T = Date> extends React.Component<DatepickerProp
419
473
  disabled={this.props.disabled}
420
474
  size={this.props.size}
421
475
  value={value}
422
- onFocus={this.open}
476
+ onFocus={() => this.open(inputRole)}
423
477
  onBlur={this.handleInputBlur}
424
478
  onKeyDown={this.handleKeyDown}
425
- onChange={onChange}
479
+ onChange={(event) => this.handleInputChange(event, inputRole)}
426
480
  placeholder={placeholder}
427
481
  mask={this.getMask()}
428
482
  required={this.props.required}
@@ -462,7 +516,9 @@ export default class Datepicker<T = Date> extends React.Component<DatepickerProp
462
516
  trapTabbing={true}
463
517
  value={this.props.value}
464
518
  {...this.props}
465
- onChange={this.onChange}
519
+ onChange={this.onCalendarSelect}
520
+ selectedInput={this.state.selectedInput}
521
+ hasLockedBehavior={this.hasLockedBehavior()}
466
522
  />
467
523
  }
468
524
  {...popoverProps}
@@ -476,11 +532,11 @@ export default class Datepicker<T = Date> extends React.Component<DatepickerProp
476
532
  <>
477
533
  <StartDate {...startDateProps}>
478
534
  <InputLabel {...inputLabelProps}>{startDateLabel}</InputLabel>
479
- {this.renderInputComponent(locale, 'startDate')}
535
+ {this.renderInputComponent(locale, INPUT_ROLE.startDate)}
480
536
  </StartDate>
481
537
  <EndDate {...endDateProps}>
482
538
  <InputLabel {...inputLabelProps}>{endDateLabel}</InputLabel>
483
- {this.renderInputComponent(locale, 'endDate')}
539
+ {this.renderInputComponent(locale, INPUT_ROLE.endDate)}
484
540
  </EndDate>
485
541
  </>
486
542
  ) : (
@@ -524,7 +580,8 @@ export default class Datepicker<T = Date> extends React.Component<DatepickerProp
524
580
  >
525
581
  {
526
582
  // No date selected
527
- !this.props.value || (Array.isArray(this.props.value) && !this.props.value.length)
583
+ !this.props.value ||
584
+ (Array.isArray(this.props.value) && !this.props.value[0] && !this.props.value[1])
528
585
  ? ''
529
586
  : // Date selected in a non-range picker
530
587
  !Array.isArray(this.props.value)
@@ -532,7 +589,7 @@ export default class Datepicker<T = Date> extends React.Component<DatepickerProp
532
589
  date: this.state.inputValue || '',
533
590
  })
534
591
  : // Start and end dates are selected in a range picker
535
- this.props.value.length > 1
592
+ this.props.value[0] && this.props.value[1]
536
593
  ? getInterpolatedString(locale.datepicker.selectedDateRange, {
537
594
  startDate: this.formatDisplayValue(this.props.value[0]),
538
595
  endDate: this.formatDisplayValue(
package/datepicker/day.js CHANGED
@@ -21,6 +21,8 @@ var _index = require("../locale/index.js");
21
21
 
22
22
  var _focusVisible = require("../utils/focusVisible.js");
23
23
 
24
+ var _constants = require("./constants.js");
25
+
24
26
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
25
27
 
26
28
  function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function _getRequireWildcardCache() { return cache; }; return cache; }
@@ -96,22 +98,49 @@ var Day = /*#__PURE__*/function (_React$Component) {
96
98
  var _this$props = _this.props,
97
99
  range = _this$props.range,
98
100
  value = _this$props.value;
99
- var date;
101
+ var nextDate;
102
+
103
+ if (Array.isArray(value) && range && _this.props.hasLockedBehavior) {
104
+ var currentDate = _this.props.value;
105
+ var nextStartDate = null;
106
+ var nextEndDate = null;
107
+
108
+ if (_this.props.selectedInput === _constants.INPUT_ROLE.startDate) {
109
+ nextStartDate = selectedDate;
110
+ nextEndDate = Array.isArray(currentDate) && currentDate[1] ? currentDate[1] : null;
111
+ } else if (_this.props.selectedInput === _constants.INPUT_ROLE.endDate) {
112
+ nextStartDate = Array.isArray(currentDate) && currentDate[0] ? currentDate[0] : null;
113
+ nextEndDate = selectedDate;
114
+ }
100
115
 
101
- if (Array.isArray(value) && range) {
102
- if (!value.length || value.length > 1) {
103
- date = [selectedDate];
104
- } else if (_this.dateHelpers.isAfter(selectedDate, value[0])) {
105
- date = [value[0], selectedDate];
116
+ nextDate = [nextStartDate];
117
+
118
+ if (nextEndDate) {
119
+ nextDate.push(nextEndDate);
120
+ }
121
+ } else if (Array.isArray(value) && range && !_this.props.hasLockedBehavior) {
122
+ var _value = _slicedToArray(value, 2),
123
+ start = _value[0],
124
+ end = _value[1]; // Starting a new range
125
+
126
+
127
+ if (!start && !end || start && end) {
128
+ nextDate = [selectedDate, null]; // EndDate needs a StartDate, SelectedDate comes before EndDate
129
+ } else if (!start && end && _this.dateHelpers.isAfter(end, selectedDate)) {
130
+ nextDate = [selectedDate, end]; // EndDate needs a StartDate, but SelectedDate comes after EndDate
131
+ } else if (!start && end && _this.dateHelpers.isAfter(selectedDate, end)) {
132
+ nextDate = [end, selectedDate]; // StartDate needs an EndDate, SelectedDate comes after StartDate
133
+ } else if (start && !end && _this.dateHelpers.isAfter(selectedDate, start)) {
134
+ nextDate = [start, selectedDate];
106
135
  } else {
107
- date = [selectedDate, value[0]];
136
+ nextDate = [selectedDate, start];
108
137
  }
109
138
  } else {
110
- date = selectedDate;
139
+ nextDate = selectedDate;
111
140
  }
112
141
 
113
142
  _this.props.onSelect({
114
- date: date
143
+ date: nextDate
115
144
  });
116
145
  });
117
146
 
@@ -298,13 +327,18 @@ var Day = /*#__PURE__*/function (_React$Component) {
298
327
  var date = this.getDateProp();
299
328
  var value = this.props.value;
300
329
 
301
- if (Array.isArray(value) && !value[0] && !value[1]) {
302
- return false;
303
- } // fix flow by passing a specific arg type and remove 'Array.isArray(value)'
330
+ if (Array.isArray(value)) {
331
+ var _value2 = _slicedToArray(value, 2),
332
+ start = _value2[0],
333
+ end = _value2[1];
304
334
 
335
+ if (!start && !end) {
336
+ return false;
337
+ }
305
338
 
306
- if (Array.isArray(value) && value.length > 1) {
307
- return this.dateHelpers.isDayInRange(this.clampToDayStart(date), this.clampToDayStart(value[0]), this.clampToDayStart(value[1]));
339
+ if (start && end) {
340
+ return this.dateHelpers.isDayInRange(this.clampToDayStart(date), this.clampToDayStart(start), this.clampToDayStart(end));
341
+ }
308
342
  }
309
343
  } // calculated for range case only
310
344
 
@@ -316,16 +350,29 @@ var Day = /*#__PURE__*/function (_React$Component) {
316
350
  value = _this$props4.value,
317
351
  highlightedDate = _this$props4.highlightedDate;
318
352
 
319
- if (Array.isArray(value) && !value[0] && !value[1]) {
320
- return false;
321
- } // fix flow by passing a specific arg type and remove 'Array.isArray(value)'
353
+ if (Array.isArray(value)) {
354
+ var _value3 = _slicedToArray(value, 2),
355
+ start = _value3[0],
356
+ end = _value3[1];
322
357
 
358
+ if (!start && !end) {
359
+ return false;
360
+ }
323
361
 
324
- if (Array.isArray(value) && highlightedDate && value[0] && !value[1]) {
325
- if (this.dateHelpers.isAfter(highlightedDate, value[0])) {
326
- return this.dateHelpers.isDayInRange(this.clampToDayStart(date), this.clampToDayStart(value[0]), this.clampToDayStart(highlightedDate));
327
- } else {
328
- return this.dateHelpers.isDayInRange(this.clampToDayStart(date), this.clampToDayStart(highlightedDate), this.clampToDayStart(value[0]));
362
+ if (highlightedDate && start && !end) {
363
+ if (this.dateHelpers.isAfter(highlightedDate, start)) {
364
+ return this.dateHelpers.isDayInRange(this.clampToDayStart(date), this.clampToDayStart(start), this.clampToDayStart(highlightedDate));
365
+ } else {
366
+ return this.dateHelpers.isDayInRange(this.clampToDayStart(date), this.clampToDayStart(highlightedDate), this.clampToDayStart(start));
367
+ }
368
+ }
369
+
370
+ if (highlightedDate && !start && end) {
371
+ if (this.dateHelpers.isAfter(highlightedDate, end)) {
372
+ return this.dateHelpers.isDayInRange(this.clampToDayStart(date), this.clampToDayStart(end), this.clampToDayStart(highlightedDate));
373
+ } else {
374
+ return this.dateHelpers.isDayInRange(this.clampToDayStart(date), this.clampToDayStart(highlightedDate), this.clampToDayStart(end));
375
+ }
329
376
  }
330
377
  }
331
378
  }
@@ -337,21 +384,22 @@ var Day = /*#__PURE__*/function (_React$Component) {
337
384
  value = _this$props5.value,
338
385
  highlightedDate = _this$props5.highlightedDate,
339
386
  range = _this$props5.range,
340
- highlighted = _this$props5.highlighted;
387
+ highlighted = _this$props5.highlighted,
388
+ peekNextMonth = _this$props5.peekNextMonth;
341
389
  var $isHighlighted = highlighted;
342
390
  var $selected = this.isSelected();
343
- var $hasRangeHighlighted = !!(Array.isArray(value) && range && value.length === 1 && highlightedDate && !this.dateHelpers.isSameDay(value[0], highlightedDate));
344
- var $outsideMonth = !this.props.peekNextMonth && this.isOutsideMonth();
345
- var $outsideMonthWithinRange = !!(Array.isArray(value) && range && $outsideMonth && !this.props.peekNextMonth && this.isOutsideOfMonthButWithinRange());
391
+ var $hasRangeHighlighted = !!(Array.isArray(value) && range && highlightedDate && (value[0] && !value[1] && !this.dateHelpers.isSameDay(value[0], highlightedDate) || !value[0] && value[1] && !this.dateHelpers.isSameDay(value[1], highlightedDate)));
392
+ var $outsideMonth = !peekNextMonth && this.isOutsideMonth();
393
+ var $outsideMonthWithinRange = !!(Array.isArray(value) && range && $outsideMonth && !peekNextMonth && this.isOutsideOfMonthButWithinRange());
346
394
  return {
347
395
  $date: date,
348
396
  $density: this.props.density,
349
397
  $disabled: this.props.disabled,
350
- $endDate: Array.isArray(value) && this.props.range && $selected && this.dateHelpers.isSameDay(date, value[1]) || false,
398
+ $endDate: Array.isArray(value) && !!(value[0] && value[1]) && range && $selected && this.dateHelpers.isSameDay(date, value[1]) || false,
351
399
  $hasDateLabel: !!this.props.dateLabel,
352
400
  $hasRangeHighlighted: $hasRangeHighlighted,
353
- $hasRangeOnRight: Array.isArray(value) && $hasRangeHighlighted && highlightedDate && value[0] && this.dateHelpers.isAfter(highlightedDate, value[0]),
354
- $hasRangeSelected: Array.isArray(value) ? value.length === 2 : false,
401
+ $hasRangeOnRight: Array.isArray(value) && $hasRangeHighlighted && highlightedDate && (value[0] && this.dateHelpers.isAfter(highlightedDate, value[0]) || value[1] && this.dateHelpers.isAfter(highlightedDate, value[1])),
402
+ $hasRangeSelected: Array.isArray(value) ? !!(value[0] && value[1]) : false,
355
403
  $highlightedDate: highlightedDate,
356
404
  $isHighlighted: $isHighlighted,
357
405
  $isHovered: this.state.isHovered,
@@ -361,12 +409,15 @@ var Day = /*#__PURE__*/function (_React$Component) {
361
409
  $month: this.getMonthProp(),
362
410
  $outsideMonth: $outsideMonth,
363
411
  $outsideMonthWithinRange: $outsideMonthWithinRange,
364
- $peekNextMonth: this.props.peekNextMonth,
365
- $pseudoHighlighted: this.props.range && !$isHighlighted && !$selected ? this.isPseudoHighlighted() : false,
366
- $pseudoSelected: this.props.range && !$selected ? this.isPseudoSelected() : false,
367
- $range: this.props.range,
412
+ $peekNextMonth: peekNextMonth,
413
+ $pseudoHighlighted: range && !$isHighlighted && !$selected ? this.isPseudoHighlighted() : false,
414
+ $pseudoSelected: range && !$selected ? this.isPseudoSelected() : false,
415
+ $range: range,
368
416
  $selected: $selected,
369
- $startDate: Array.isArray(this.props.value) && this.props.value.length > 1 && this.props.range && $selected ? this.dateHelpers.isSameDay(date, this.props.value[0]) : false
417
+ $startDate: Array.isArray(value) && value[0] && value[1] && range && $selected ? this.dateHelpers.isSameDay(date, value[0]) : false,
418
+ $hasLockedBehavior: this.props.hasLockedBehavior,
419
+ $selectedInput: this.props.selectedInput,
420
+ $value: this.props.value
370
421
  };
371
422
  }
372
423
  }, {