@atlaskit/datetime-picker 15.12.2 → 15.13.0

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 (40) hide show
  1. package/CHANGELOG.md +9 -0
  2. package/dist/cjs/components/date-picker.js +639 -7
  3. package/dist/cjs/components/date-time-picker.js +379 -9
  4. package/dist/cjs/components/time-picker.js +2 -2
  5. package/dist/es2019/components/date-picker.js +570 -5
  6. package/dist/es2019/components/date-time-picker.js +347 -6
  7. package/dist/es2019/components/time-picker.js +2 -2
  8. package/dist/esm/components/date-picker.js +637 -7
  9. package/dist/esm/components/date-time-picker.js +375 -8
  10. package/dist/esm/components/time-picker.js +2 -2
  11. package/dist/types/components/date-picker.d.ts +18 -19
  12. package/dist/types/components/date-time-picker.d.ts +14 -31
  13. package/dist/types-ts4.5/components/date-picker.d.ts +18 -19
  14. package/dist/types-ts4.5/components/date-time-picker.d.ts +14 -31
  15. package/package.json +5 -8
  16. package/dist/cjs/components/date-picker-class.js +0 -685
  17. package/dist/cjs/components/date-picker-fc.js +0 -639
  18. package/dist/cjs/components/date-time-picker-class.js +0 -436
  19. package/dist/cjs/components/date-time-picker-fc.js +0 -394
  20. package/dist/cjs/internal/ff-component.js +0 -58
  21. package/dist/es2019/components/date-picker-class.js +0 -649
  22. package/dist/es2019/components/date-picker-fc.js +0 -563
  23. package/dist/es2019/components/date-time-picker-class.js +0 -400
  24. package/dist/es2019/components/date-time-picker-fc.js +0 -354
  25. package/dist/es2019/internal/ff-component.js +0 -47
  26. package/dist/esm/components/date-picker-class.js +0 -680
  27. package/dist/esm/components/date-picker-fc.js +0 -630
  28. package/dist/esm/components/date-time-picker-class.js +0 -434
  29. package/dist/esm/components/date-time-picker-fc.js +0 -384
  30. package/dist/esm/internal/ff-component.js +0 -49
  31. package/dist/types/components/date-picker-class.d.ts +0 -110
  32. package/dist/types/components/date-picker-fc.d.ts +0 -20
  33. package/dist/types/components/date-time-picker-class.d.ts +0 -85
  34. package/dist/types/components/date-time-picker-fc.d.ts +0 -15
  35. package/dist/types/internal/ff-component.d.ts +0 -34
  36. package/dist/types-ts4.5/components/date-picker-class.d.ts +0 -110
  37. package/dist/types-ts4.5/components/date-picker-fc.d.ts +0 -20
  38. package/dist/types-ts4.5/components/date-time-picker-class.d.ts +0 -85
  39. package/dist/types-ts4.5/components/date-time-picker-fc.d.ts +0 -15
  40. package/dist/types-ts4.5/internal/ff-component.d.ts +0 -34
@@ -1,7 +1,348 @@
1
- import { fg } from '@atlaskit/platform-feature-flags';
2
- import { componentWithCondition } from '../internal/ff-component';
3
- import DateTimePickerOld from './date-time-picker-class';
4
- import DateTimePickerNew from './date-time-picker-fc';
5
- const DateTimePicker = componentWithCondition(() => fg('dst-date-time-picker-use-functional-component'), DateTimePickerNew, DateTimePickerOld);
6
- // eslint-disable-next-line @repo/internal/react/require-jsdoc
1
+ import _extends from "@babel/runtime/helpers/extends";
2
+ import React, { forwardRef, useCallback, useEffect, useState } from 'react';
3
+ import { format, isValid, parseISO } from 'date-fns';
4
+ import { usePlatformLeafEventHandler } from '@atlaskit/analytics-next';
5
+ import { IconButton } from '@atlaskit/button/new';
6
+ import SelectClearIcon from '@atlaskit/icon/utility/migration/cross-circle--select-clear';
7
+ import { Box, Inline, xcss } from '@atlaskit/primitives';
8
+ import { mergeStyles } from '@atlaskit/select';
9
+ import { formatDateTimeZoneIntoIso } from '../internal';
10
+ import { DateTimePickerContainer } from '../internal/date-time-picker-container';
11
+ import { convertTokens } from '../internal/parse-tokens';
12
+ import DatePicker from './date-picker';
13
+ import TimePicker from './time-picker';
14
+ const packageName = "@atlaskit/datetime-picker";
15
+ const packageVersion = "15.13.0";
16
+ const analyticsAttributes = {
17
+ componentName: 'dateTimePicker',
18
+ packageName,
19
+ packageVersion
20
+ };
21
+
22
+ // Make DatePicker 50% the width of DateTimePicker
23
+ // If rendering an icon container, shrink the TimePicker
24
+ const datePickerContainerStyles = xcss({
25
+ flexBasis: '50%',
26
+ flexGrow: 1,
27
+ flexShrink: 0
28
+ });
29
+ const timePickerContainerStyles = xcss({
30
+ flexBasis: '50%',
31
+ flexGrow: 1
32
+ });
33
+ const iconContainerStyles = xcss({
34
+ display: 'flex',
35
+ alignItems: 'center',
36
+ flexBasis: 'inherit'
37
+ });
38
+
39
+ // react-select overrides (via @atlaskit/select).
40
+ const styles = {
41
+ control: style => ({
42
+ ...style,
43
+ backgroundColor: 'transparent',
44
+ border: 2,
45
+ borderRadius: 0,
46
+ paddingLeft: 0,
47
+ ':hover': {
48
+ backgroundColor: 'transparent',
49
+ cursor: 'inherit'
50
+ }
51
+ })
52
+ };
53
+ export const datePickerDefaultAriaLabel = 'Date';
54
+ export const timePickerDefaultAriaLabel = 'Time';
55
+
56
+ /**
57
+ * __Date time picker__
58
+ *
59
+ * A date time picker allows the user to select an associated date and time.
60
+ *
61
+ * - [Examples](https://atlassian.design/components/datetime-picker/examples)
62
+ * - [Code](https://atlassian.design/components/datetime-picker/code)
63
+ * - [Usage](https://atlassian.design/components/datetime-picker/usage)
64
+ */
65
+ const DateTimePicker = /*#__PURE__*/forwardRef(({
66
+ 'aria-describedby': ariaDescribedBy,
67
+ appearance = 'default',
68
+ autoFocus = false,
69
+ clearControlLabel = 'clear',
70
+ datePickerProps: datePickerPropsWithSelectProps = {},
71
+ defaultValue = '',
72
+ id = '',
73
+ innerProps = {},
74
+ isDisabled = false,
75
+ isInvalid = false,
76
+ isRequired = false,
77
+ name = '',
78
+ // These disables are here for proper typing when used as defaults. They
79
+ // should *not* use the `noop` function.
80
+ /* eslint-disable @repo/internal/react/use-noop */
81
+ onBlur = _event => {},
82
+ onChange: onChangeProp = _value => {},
83
+ onFocus = _event => {},
84
+ /* eslint-enable @repo/internal/react/use-noop */
85
+ parseValue: providedParseValue,
86
+ spacing = 'default',
87
+ locale = 'en-US',
88
+ testId,
89
+ timePickerProps: timePickerPropsWithSelectProps = {},
90
+ value: providedValue
91
+ }, ref) => {
92
+ const [dateValue, setDateValue] = useState((datePickerPropsWithSelectProps === null || datePickerPropsWithSelectProps === void 0 ? void 0 : datePickerPropsWithSelectProps.defaultValue) || '');
93
+ const [isFocused, setIsFocused] = useState(false);
94
+ const [timeValue, setTimeValue] = useState((timePickerPropsWithSelectProps === null || timePickerPropsWithSelectProps === void 0 ? void 0 : timePickerPropsWithSelectProps.defaultValue) || '');
95
+ const [value, setValue] = useState(defaultValue || '');
96
+ const [zoneValue, setZoneValue] = useState('');
97
+ useEffect(() => {
98
+ if (providedValue) {
99
+ setValue(providedValue);
100
+ }
101
+ }, [providedValue]);
102
+ const parseValue = useCallback((value, providedDateValue, providedTimeValue, providedZoneValue) => {
103
+ if (providedParseValue) {
104
+ const parsedFromFn = providedParseValue(value, providedDateValue, providedTimeValue, providedZoneValue);
105
+ // This handles cases found in Jira where the parse function actually does
106
+ // nothing and returns undefined. The previous `getSafeState` function
107
+ // just spread the values over the state, but if it returned `undefined`,
108
+ // it would just rely on the previous state values. Considering this is
109
+ // what is input to this function anyway, this is a safe way to handle
110
+ // this, colocate the behavior, and not rely on `getSafeState`.
111
+ return parsedFromFn || {
112
+ dateValue: providedDateValue,
113
+ timeValue: providedTimeValue,
114
+ zoneValue: providedZoneValue
115
+ };
116
+ }
117
+ const parsed = parseISO(value);
118
+ return isValid(parsed) ? {
119
+ dateValue: format(parsed, convertTokens('YYYY-MM-DD')),
120
+ timeValue: format(parsed, convertTokens('HH:mm')),
121
+ zoneValue: format(parsed, convertTokens('ZZ'))
122
+ } : {
123
+ dateValue,
124
+ timeValue,
125
+ zoneValue
126
+ };
127
+ }, [providedParseValue, dateValue, timeValue, zoneValue]);
128
+ useEffect(() => {
129
+ const parsedValues = parseValue(value, dateValue, timeValue, zoneValue);
130
+ setDateValue(parsedValues.dateValue);
131
+ setTimeValue(parsedValues.timeValue);
132
+ setZoneValue(parsedValues.zoneValue);
133
+ }, [value, dateValue, timeValue, zoneValue, parseValue]);
134
+ const onDateBlur = event => {
135
+ setIsFocused(false);
136
+ onBlur(event);
137
+ if (datePickerPropsWithSelectProps !== null && datePickerPropsWithSelectProps !== void 0 && datePickerPropsWithSelectProps.onBlur) {
138
+ datePickerPropsWithSelectProps.onBlur(event);
139
+ }
140
+ };
141
+ const onTimeBlur = event => {
142
+ setIsFocused(false);
143
+ onBlur(event);
144
+ if (timePickerPropsWithSelectProps !== null && timePickerPropsWithSelectProps !== void 0 && timePickerPropsWithSelectProps.onBlur) {
145
+ timePickerPropsWithSelectProps.onBlur(event);
146
+ }
147
+ };
148
+ const onDateFocus = event => {
149
+ setIsFocused(false);
150
+ onFocus(event);
151
+ if (datePickerPropsWithSelectProps !== null && datePickerPropsWithSelectProps !== void 0 && datePickerPropsWithSelectProps.onFocus) {
152
+ datePickerPropsWithSelectProps.onFocus(event);
153
+ }
154
+ };
155
+ const onTimeFocus = event => {
156
+ setIsFocused(false);
157
+ onFocus(event);
158
+ if (timePickerPropsWithSelectProps !== null && timePickerPropsWithSelectProps !== void 0 && timePickerPropsWithSelectProps.onFocus) {
159
+ timePickerPropsWithSelectProps.onFocus(event);
160
+ }
161
+ };
162
+ const onDateChange = dateValue => {
163
+ const parsedValues = parseValue(value, dateValue, timeValue, zoneValue);
164
+ onValueChange({
165
+ providedDateValue: dateValue,
166
+ providedTimeValue: parsedValues.timeValue,
167
+ providedZoneValue: parsedValues.zoneValue
168
+ });
169
+ if (datePickerPropsWithSelectProps !== null && datePickerPropsWithSelectProps !== void 0 && datePickerPropsWithSelectProps.onChange) {
170
+ datePickerPropsWithSelectProps.onChange(dateValue);
171
+ }
172
+ };
173
+ const onTimeChange = timeValue => {
174
+ const parsedValues = parseValue(value, dateValue, timeValue, zoneValue);
175
+ onValueChange({
176
+ providedDateValue: parsedValues.dateValue,
177
+ providedTimeValue: timeValue,
178
+ providedZoneValue: parsedValues.zoneValue
179
+ });
180
+ if (timePickerPropsWithSelectProps !== null && timePickerPropsWithSelectProps !== void 0 && timePickerPropsWithSelectProps.onChange) {
181
+ timePickerPropsWithSelectProps.onChange(timeValue);
182
+ }
183
+ };
184
+ const onClear = () => {
185
+ const parsedValues = parseValue(value, dateValue, timeValue, zoneValue);
186
+ onValueChange({
187
+ providedDateValue: '',
188
+ providedTimeValue: '',
189
+ providedZoneValue: parsedValues.zoneValue
190
+ });
191
+ if (datePickerPropsWithSelectProps !== null && datePickerPropsWithSelectProps !== void 0 && datePickerPropsWithSelectProps.onChange) {
192
+ datePickerPropsWithSelectProps.onChange('');
193
+ }
194
+ if (timePickerPropsWithSelectProps !== null && timePickerPropsWithSelectProps !== void 0 && timePickerPropsWithSelectProps.onChange) {
195
+ timePickerPropsWithSelectProps.onChange('');
196
+ }
197
+ };
198
+ const onChangePropWithAnalytics = usePlatformLeafEventHandler({
199
+ fn: onChangeProp,
200
+ action: 'selectedDate',
201
+ actionSubject: 'datePicker',
202
+ ...analyticsAttributes
203
+ });
204
+ const onValueChange = ({
205
+ providedDateValue,
206
+ providedTimeValue,
207
+ providedZoneValue
208
+ }) => {
209
+ setDateValue(providedDateValue);
210
+ setTimeValue(providedTimeValue);
211
+ setZoneValue(providedZoneValue);
212
+ if (providedDateValue && providedTimeValue) {
213
+ const value = formatDateTimeZoneIntoIso(providedDateValue, providedTimeValue, providedZoneValue);
214
+ const {
215
+ zoneValue: parsedZone
216
+ } = parseValue(value, providedDateValue, providedTimeValue, providedZoneValue);
217
+ const valueWithValidZone = formatDateTimeZoneIntoIso(providedDateValue, providedTimeValue, parsedZone);
218
+ setValue(valueWithValidZone);
219
+ onChangePropWithAnalytics(valueWithValidZone);
220
+ // If the date or time value was cleared when there is an existing datetime value, then clear the value.
221
+ } else if (value) {
222
+ setValue('');
223
+ onChangePropWithAnalytics('');
224
+ }
225
+ };
226
+ const {
227
+ selectProps: datePickerSelectProps,
228
+ ...datePickerProps
229
+ } = datePickerPropsWithSelectProps;
230
+ const datePickerAriaDescribedBy = datePickerProps['aria-describedby'] || ariaDescribedBy;
231
+ const datePickerLabel = datePickerProps.label || datePickerDefaultAriaLabel;
232
+ const mergedDatePickerSelectProps = {
233
+ ...datePickerSelectProps,
234
+ styles: mergeStyles(styles, datePickerSelectProps === null || datePickerSelectProps === void 0 ? void 0 : datePickerSelectProps.styles)
235
+ };
236
+ const {
237
+ selectProps: timePickerSelectProps,
238
+ ...timePickerProps
239
+ } = timePickerPropsWithSelectProps;
240
+ const timePickerAriaDescribedBy = timePickerProps['aria-describedby'] || ariaDescribedBy;
241
+ const timePickerLabel = timePickerProps.label || timePickerDefaultAriaLabel;
242
+ const mergedTimePickerSelectProps = {
243
+ ...timePickerSelectProps,
244
+ styles: mergeStyles(styles, timePickerSelectProps === null || timePickerSelectProps === void 0 ? void 0 : timePickerSelectProps.styles)
245
+ };
246
+
247
+ // Render DateTimePicker's IconContainer when a value has been filled
248
+ // Don't use Date or TimePicker's because they can't be customised
249
+ const isClearable = Boolean(dateValue || timeValue);
250
+ return /*#__PURE__*/React.createElement(DateTimePickerContainer, {
251
+ appearance: appearance,
252
+ isDisabled: isDisabled,
253
+ isFocused: isFocused,
254
+ isInvalid: isInvalid,
255
+ testId: testId,
256
+ innerProps: innerProps
257
+ }, /*#__PURE__*/React.createElement("input", {
258
+ name: name,
259
+ type: "hidden",
260
+ value: value,
261
+ "data-testid": testId && `${testId}--input`
262
+ }), /*#__PURE__*/React.createElement(Box, {
263
+ xcss: datePickerContainerStyles
264
+ }, /*#__PURE__*/React.createElement(DatePicker, {
265
+ appearance: appearance,
266
+ "aria-describedby": datePickerAriaDescribedBy,
267
+ autoFocus: datePickerProps.autoFocus || autoFocus,
268
+ dateFormat: datePickerProps.dateFormat,
269
+ defaultIsOpen: datePickerProps.defaultIsOpen,
270
+ defaultValue: datePickerProps.defaultValue,
271
+ disabled: datePickerProps.disabled,
272
+ disabledDateFilter: datePickerProps.disabledDateFilter,
273
+ formatDisplayLabel: datePickerProps.formatDisplayLabel,
274
+ hideIcon: datePickerProps.hideIcon || true,
275
+ icon: datePickerProps.icon,
276
+ id: datePickerProps.id || id,
277
+ innerProps: datePickerProps.innerProps,
278
+ inputLabel: datePickerProps.inputLabel,
279
+ inputLabelId: datePickerProps.inputLabelId,
280
+ isDisabled: datePickerProps.isDisabled || isDisabled,
281
+ isInvalid: datePickerProps.isInvalid || isInvalid,
282
+ isOpen: datePickerProps.isOpen,
283
+ isRequired: datePickerProps.isRequired || isRequired,
284
+ label: datePickerLabel,
285
+ locale: datePickerProps.locale || locale,
286
+ maxDate: datePickerProps.maxDate,
287
+ minDate: datePickerProps.minDate,
288
+ name: datePickerProps.name,
289
+ nextMonthLabel: datePickerProps.nextMonthLabel,
290
+ onBlur: onDateBlur,
291
+ onChange: onDateChange,
292
+ onFocus: onDateFocus,
293
+ openCalendarLabel: datePickerProps.openCalendarLabel,
294
+ parseInputValue: datePickerProps.parseInputValue,
295
+ placeholder: datePickerProps.placeholder,
296
+ previousMonthLabel: datePickerProps.previousMonthLabel,
297
+ selectProps: mergedDatePickerSelectProps,
298
+ shouldShowCalendarButton: datePickerProps.shouldShowCalendarButton,
299
+ spacing: datePickerProps.spacing || spacing,
300
+ testId: testId && `${testId}--datepicker` || datePickerProps.testId,
301
+ value: dateValue,
302
+ weekStartDay: datePickerProps.weekStartDay
303
+ })), /*#__PURE__*/React.createElement(Box, {
304
+ xcss: timePickerContainerStyles
305
+ }, /*#__PURE__*/React.createElement(TimePicker, {
306
+ appearance: timePickerProps.appearance || appearance,
307
+ "aria-describedby": timePickerAriaDescribedBy,
308
+ autoFocus: timePickerProps.autoFocus,
309
+ defaultIsOpen: timePickerProps.defaultIsOpen,
310
+ defaultValue: timePickerProps.defaultValue,
311
+ formatDisplayLabel: timePickerProps.formatDisplayLabel,
312
+ hideIcon: timePickerProps.hideIcon || true,
313
+ id: timePickerProps.id,
314
+ innerProps: timePickerProps.innerProps,
315
+ isDisabled: timePickerProps.isDisabled || isDisabled,
316
+ isInvalid: timePickerProps.isInvalid || isInvalid,
317
+ isOpen: timePickerProps.isOpen,
318
+ isRequired: timePickerProps.isRequired || isRequired,
319
+ label: timePickerLabel,
320
+ locale: timePickerProps.locale || locale,
321
+ name: timePickerProps.name,
322
+ onBlur: onTimeBlur,
323
+ onChange: onTimeChange,
324
+ onFocus: onTimeFocus,
325
+ parseInputValue: timePickerProps.parseInputValue,
326
+ placeholder: timePickerProps.placeholder,
327
+ selectProps: mergedTimePickerSelectProps,
328
+ spacing: timePickerProps.spacing || spacing,
329
+ testId: timePickerProps.testId || testId && `${testId}--timepicker`,
330
+ timeFormat: timePickerProps.timeFormat,
331
+ timeIsEditable: timePickerProps.timeIsEditable,
332
+ times: timePickerProps.times,
333
+ value: timeValue
334
+ })), isClearable && !isDisabled ? /*#__PURE__*/React.createElement(Inline, {
335
+ xcss: iconContainerStyles
336
+ }, /*#__PURE__*/React.createElement(IconButton, {
337
+ appearance: "subtle",
338
+ label: clearControlLabel,
339
+ icon: iconProps => /*#__PURE__*/React.createElement(SelectClearIcon, _extends({}, iconProps, {
340
+ color: "var(--ds-text-subtlest, #626F86)",
341
+ LEGACY_size: "small"
342
+ })),
343
+ onClick: onClear,
344
+ testId: testId && `${testId}--icon--container`,
345
+ tabIndex: -1
346
+ })) : null);
347
+ });
7
348
  export default DateTimePicker;
@@ -11,7 +11,7 @@ import parseTime from '../internal/parse-time';
11
11
  import { convertTokens } from '../internal/parse-tokens';
12
12
  import { makeSingleValue } from '../internal/single-value';
13
13
  const packageName = "@atlaskit/datetime-picker";
14
- const packageVersion = "15.12.2";
14
+ const packageVersion = "15.13.0";
15
15
  const menuStyles = {
16
16
  /* Need to remove default absolute positioning as that causes issues with position fixed */
17
17
  position: 'static',
@@ -262,7 +262,7 @@ const TimePicker = /*#__PURE__*/forwardRef(({
262
262
  onKeyDown: onSelectKeyDown
263
263
  }), /*#__PURE__*/React.createElement(SelectComponent, _extends({
264
264
  "aria-describedby": ariaDescribedBy,
265
- "aria-label": label || undefined,
265
+ label: label || undefined,
266
266
  appearance: appearance,
267
267
  autoFocus: autoFocus,
268
268
  clearControlLabel: clearControlLabel,