@atlaskit/datetime-picker 14.0.1 → 14.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +17 -0
- package/dist/cjs/components/date-picker.js +1 -7
- package/dist/cjs/components/date-time-picker.js +1 -1
- package/dist/cjs/components/time-picker.js +284 -312
- package/dist/cjs/internal/menu.js +0 -1
- package/dist/es2019/components/date-picker.js +1 -7
- package/dist/es2019/components/date-time-picker.js +1 -1
- package/dist/es2019/components/time-picker.js +246 -297
- package/dist/es2019/internal/menu.js +0 -1
- package/dist/esm/components/date-picker.js +1 -7
- package/dist/esm/components/date-time-picker.js +1 -1
- package/dist/esm/components/time-picker.js +283 -313
- package/dist/esm/internal/menu.js +0 -1
- package/dist/types/components/date-picker.d.ts +0 -3
- package/dist/types/components/time-picker.d.ts +2 -104
- package/dist/types/types.d.ts +4 -0
- package/dist/types-ts4.5/components/date-picker.d.ts +0 -3
- package/dist/types-ts4.5/components/time-picker.d.ts +2 -104
- package/dist/types-ts4.5/types.d.ts +4 -0
- package/package.json +3 -8
|
@@ -18,7 +18,7 @@ import { convertTokens } from '../internal/parse-tokens';
|
|
|
18
18
|
import DatePicker from './date-picker';
|
|
19
19
|
import TimePicker from './time-picker';
|
|
20
20
|
const packageName = "@atlaskit/datetime-picker";
|
|
21
|
-
const packageVersion = "14.0.
|
|
21
|
+
const packageVersion = "14.0.3";
|
|
22
22
|
// Make DatePicker 50% the width of DateTimePicker
|
|
23
23
|
// If rendering an icon container, shrink the TimePicker
|
|
24
24
|
const datePickerContainerStyles = css({
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import _extends from "@babel/runtime/helpers/extends";
|
|
2
|
-
import
|
|
3
|
-
import React from 'react';
|
|
2
|
+
import React, { forwardRef, useReducer, useState } from 'react';
|
|
4
3
|
|
|
5
4
|
// eslint-disable-next-line no-restricted-imports
|
|
6
5
|
import { format, isValid } from 'date-fns';
|
|
7
|
-
import {
|
|
6
|
+
import { usePlatformLeafEventHandler } from '@atlaskit/analytics-next';
|
|
7
|
+
import __noop from '@atlaskit/ds-lib/noop';
|
|
8
8
|
import { createLocalizationProvider } from '@atlaskit/locale';
|
|
9
9
|
import Select, { CreatableSelect, mergeStyles } from '@atlaskit/select';
|
|
10
10
|
// eslint-disable-next-line @atlaskit/design-system/no-deprecated-imports
|
|
@@ -15,7 +15,7 @@ import parseTime from '../internal/parse-time';
|
|
|
15
15
|
import { convertTokens } from '../internal/parse-tokens';
|
|
16
16
|
import { makeSingleValue } from '../internal/single-value';
|
|
17
17
|
const packageName = "@atlaskit/datetime-picker";
|
|
18
|
-
const packageVersion = "14.0.
|
|
18
|
+
const packageVersion = "14.0.3";
|
|
19
19
|
const menuStyles = {
|
|
20
20
|
/* Need to remove default absolute positioning as that causes issues with position fixed */
|
|
21
21
|
position: 'static',
|
|
@@ -24,287 +24,11 @@ const menuStyles = {
|
|
|
24
24
|
/* React-Popper has already offset the menu so we need to reset the margin, otherwise the offset value is doubled */
|
|
25
25
|
margin: 0
|
|
26
26
|
};
|
|
27
|
-
const
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
defaultValue: '',
|
|
32
|
-
hideIcon: false,
|
|
33
|
-
id: '',
|
|
34
|
-
innerProps: {},
|
|
35
|
-
isDisabled: false,
|
|
36
|
-
isInvalid: false,
|
|
37
|
-
label: '',
|
|
38
|
-
name: '',
|
|
39
|
-
// These disables are here for proper typing when used as defaults. They
|
|
40
|
-
// should *not* use the `noop` function.
|
|
41
|
-
/* eslint-disable @repo/internal/react/use-noop */
|
|
42
|
-
onBlur: _event => {},
|
|
43
|
-
onChange: _value => {},
|
|
44
|
-
onFocus: _event => {},
|
|
45
|
-
/* eslint-enable @repo/internal/react/use-noop */
|
|
46
|
-
parseInputValue: (time, _timeFormat) => parseTime(time),
|
|
47
|
-
selectProps: {},
|
|
48
|
-
spacing: 'default',
|
|
49
|
-
times: defaultTimes,
|
|
50
|
-
timeIsEditable: false,
|
|
51
|
-
locale: 'en-US'
|
|
52
|
-
// Not including a default prop for value as it will
|
|
53
|
-
// Make the component a controlled component
|
|
27
|
+
const analyticsAttributes = {
|
|
28
|
+
componentName: 'timePicker',
|
|
29
|
+
packageName,
|
|
30
|
+
packageVersion
|
|
54
31
|
};
|
|
55
|
-
class TimePickerComponent extends React.Component {
|
|
56
|
-
constructor(...args) {
|
|
57
|
-
super(...args);
|
|
58
|
-
_defineProperty(this, "containerRef", null);
|
|
59
|
-
_defineProperty(this, "state", {
|
|
60
|
-
isOpen: this.props.defaultIsOpen,
|
|
61
|
-
clearingFromIcon: false,
|
|
62
|
-
value: this.props.defaultValue,
|
|
63
|
-
isFocused: false
|
|
64
|
-
});
|
|
65
|
-
// All state needs to be accessed via this function so that the state is mapped from props
|
|
66
|
-
// correctly to allow controlled/uncontrolled usage.
|
|
67
|
-
_defineProperty(this, "getValue", () => {
|
|
68
|
-
var _this$props$value;
|
|
69
|
-
return (_this$props$value = this.props.value) !== null && _this$props$value !== void 0 ? _this$props$value : this.state.value;
|
|
70
|
-
});
|
|
71
|
-
_defineProperty(this, "getIsOpen", () => {
|
|
72
|
-
var _this$props$isOpen;
|
|
73
|
-
return (_this$props$isOpen = this.props.isOpen) !== null && _this$props$isOpen !== void 0 ? _this$props$isOpen : this.state.isOpen;
|
|
74
|
-
});
|
|
75
|
-
_defineProperty(this, "onChange", (newValue, action) => {
|
|
76
|
-
const rawValue = newValue ? newValue.value || newValue : '';
|
|
77
|
-
const value = rawValue.toString();
|
|
78
|
-
let changedState = {
|
|
79
|
-
value
|
|
80
|
-
};
|
|
81
|
-
if (action && action.action === 'clear') {
|
|
82
|
-
changedState = {
|
|
83
|
-
...changedState,
|
|
84
|
-
clearingFromIcon: true
|
|
85
|
-
};
|
|
86
|
-
}
|
|
87
|
-
this.setState(changedState);
|
|
88
|
-
this.props.onChange(value);
|
|
89
|
-
});
|
|
90
|
-
/**
|
|
91
|
-
* Only allow custom times if timeIsEditable prop is true
|
|
92
|
-
*/
|
|
93
|
-
_defineProperty(this, "onCreateOption", inputValue => {
|
|
94
|
-
if (this.props.timeIsEditable) {
|
|
95
|
-
const {
|
|
96
|
-
parseInputValue,
|
|
97
|
-
timeFormat
|
|
98
|
-
} = this.props;
|
|
99
|
-
let sanitizedInput;
|
|
100
|
-
try {
|
|
101
|
-
sanitizedInput = parseInputValue(inputValue, timeFormat || defaultTimeFormat);
|
|
102
|
-
} catch (e) {
|
|
103
|
-
return; // do nothing, the main validation should happen in the form
|
|
104
|
-
}
|
|
105
|
-
const includesSeconds = !!(timeFormat && /[:.]?(s|ss)/.test(timeFormat));
|
|
106
|
-
const formatFormat = includesSeconds ? 'HH:mm:ss' : 'HH:mm';
|
|
107
|
-
const formattedValue = format(sanitizedInput, formatFormat) || '';
|
|
108
|
-
this.setState({
|
|
109
|
-
value: formattedValue
|
|
110
|
-
});
|
|
111
|
-
this.props.onChange(formattedValue);
|
|
112
|
-
} else {
|
|
113
|
-
this.onChange(inputValue);
|
|
114
|
-
}
|
|
115
|
-
});
|
|
116
|
-
_defineProperty(this, "onMenuOpen", () => {
|
|
117
|
-
// Don't open menu after the user has clicked clear
|
|
118
|
-
if (this.state.clearingFromIcon) {
|
|
119
|
-
this.setState({
|
|
120
|
-
clearingFromIcon: false
|
|
121
|
-
});
|
|
122
|
-
} else {
|
|
123
|
-
this.setState({
|
|
124
|
-
isOpen: true
|
|
125
|
-
});
|
|
126
|
-
}
|
|
127
|
-
});
|
|
128
|
-
_defineProperty(this, "onMenuClose", () => {
|
|
129
|
-
// Don't close menu after the user has clicked clear
|
|
130
|
-
if (this.state.clearingFromIcon) {
|
|
131
|
-
this.setState({
|
|
132
|
-
clearingFromIcon: false
|
|
133
|
-
});
|
|
134
|
-
} else {
|
|
135
|
-
this.setState({
|
|
136
|
-
isOpen: false
|
|
137
|
-
});
|
|
138
|
-
}
|
|
139
|
-
});
|
|
140
|
-
_defineProperty(this, "setContainerRef", ref => {
|
|
141
|
-
const oldRef = this.containerRef;
|
|
142
|
-
this.containerRef = ref;
|
|
143
|
-
// Cause a re-render if we're getting the container ref for the first time
|
|
144
|
-
// as the layered menu requires it for dimension calculation
|
|
145
|
-
if (oldRef == null && ref != null) {
|
|
146
|
-
this.forceUpdate();
|
|
147
|
-
}
|
|
148
|
-
});
|
|
149
|
-
_defineProperty(this, "onBlur", event => {
|
|
150
|
-
this.setState({
|
|
151
|
-
isFocused: false
|
|
152
|
-
});
|
|
153
|
-
this.props.onBlur(event);
|
|
154
|
-
});
|
|
155
|
-
_defineProperty(this, "onFocus", event => {
|
|
156
|
-
this.setState({
|
|
157
|
-
isFocused: true
|
|
158
|
-
});
|
|
159
|
-
this.props.onFocus(event);
|
|
160
|
-
});
|
|
161
|
-
_defineProperty(this, "onSelectKeyDown", event => {
|
|
162
|
-
const {
|
|
163
|
-
key
|
|
164
|
-
} = event;
|
|
165
|
-
const keyPressed = key.toLowerCase();
|
|
166
|
-
if (this.state.clearingFromIcon && (keyPressed === 'backspace' || keyPressed === 'delete')) {
|
|
167
|
-
// If being cleared from keyboard, don't change behaviour
|
|
168
|
-
this.setState({
|
|
169
|
-
clearingFromIcon: false
|
|
170
|
-
});
|
|
171
|
-
}
|
|
172
|
-
});
|
|
173
|
-
}
|
|
174
|
-
render() {
|
|
175
|
-
const {
|
|
176
|
-
appearance,
|
|
177
|
-
'aria-describedby': ariaDescribedBy,
|
|
178
|
-
autoFocus,
|
|
179
|
-
formatDisplayLabel,
|
|
180
|
-
hideIcon,
|
|
181
|
-
id,
|
|
182
|
-
innerProps,
|
|
183
|
-
isDisabled,
|
|
184
|
-
label,
|
|
185
|
-
locale,
|
|
186
|
-
name,
|
|
187
|
-
placeholder,
|
|
188
|
-
selectProps,
|
|
189
|
-
spacing,
|
|
190
|
-
testId,
|
|
191
|
-
isInvalid,
|
|
192
|
-
timeIsEditable,
|
|
193
|
-
timeFormat,
|
|
194
|
-
times
|
|
195
|
-
} = this.props;
|
|
196
|
-
const ICON_PADDING = 2;
|
|
197
|
-
const l10n = createLocalizationProvider(locale);
|
|
198
|
-
const value = this.getValue() || '';
|
|
199
|
-
const isOpen = this.getIsOpen();
|
|
200
|
-
const {
|
|
201
|
-
styles: selectStyles = {},
|
|
202
|
-
...otherSelectProps
|
|
203
|
-
} = selectProps;
|
|
204
|
-
const SelectComponent = timeIsEditable ? CreatableSelect : Select;
|
|
205
|
-
|
|
206
|
-
/**
|
|
207
|
-
* There are multiple props that can change how the time is formatted.
|
|
208
|
-
* The priority of props used is:
|
|
209
|
-
* 1. formatDisplayLabel
|
|
210
|
-
* 2. timeFormat
|
|
211
|
-
* 3. locale
|
|
212
|
-
*/
|
|
213
|
-
const formatTime = time => {
|
|
214
|
-
if (formatDisplayLabel) {
|
|
215
|
-
return formatDisplayLabel(time, timeFormat || defaultTimeFormat);
|
|
216
|
-
}
|
|
217
|
-
const date = parseTime(time);
|
|
218
|
-
if (!(date instanceof Date)) {
|
|
219
|
-
return '';
|
|
220
|
-
}
|
|
221
|
-
if (!isValid(date)) {
|
|
222
|
-
return time;
|
|
223
|
-
}
|
|
224
|
-
if (timeFormat) {
|
|
225
|
-
return format(date, convertTokens(timeFormat));
|
|
226
|
-
}
|
|
227
|
-
return l10n.formatTime(date);
|
|
228
|
-
};
|
|
229
|
-
const options = times.map(time => {
|
|
230
|
-
return {
|
|
231
|
-
label: formatTime(time),
|
|
232
|
-
value: time
|
|
233
|
-
};
|
|
234
|
-
});
|
|
235
|
-
const initialValue = value ? {
|
|
236
|
-
label: formatTime(value),
|
|
237
|
-
value
|
|
238
|
-
} : null;
|
|
239
|
-
const SingleValue = makeSingleValue({
|
|
240
|
-
lang: this.props.locale
|
|
241
|
-
});
|
|
242
|
-
const selectComponents = {
|
|
243
|
-
DropdownIndicator: EmptyComponent,
|
|
244
|
-
Menu: FixedLayerMenu,
|
|
245
|
-
SingleValue,
|
|
246
|
-
...(hideIcon && {
|
|
247
|
-
ClearIndicator: EmptyComponent
|
|
248
|
-
})
|
|
249
|
-
};
|
|
250
|
-
const renderIconContainer = Boolean(!hideIcon && value);
|
|
251
|
-
const mergedStyles = mergeStyles(selectStyles, {
|
|
252
|
-
control: base => ({
|
|
253
|
-
...base
|
|
254
|
-
}),
|
|
255
|
-
menu: base => ({
|
|
256
|
-
...base,
|
|
257
|
-
...menuStyles,
|
|
258
|
-
// Fixed positioned elements no longer inherit width from their parent, so we must explicitly set the
|
|
259
|
-
// menu width to the width of our container
|
|
260
|
-
width: this.containerRef ? this.containerRef.getBoundingClientRect().width : 'auto'
|
|
261
|
-
}),
|
|
262
|
-
indicatorsContainer: base => ({
|
|
263
|
-
...base,
|
|
264
|
-
paddingLeft: renderIconContainer ? ICON_PADDING : 0,
|
|
265
|
-
paddingRight: renderIconContainer ? gridSize() - ICON_PADDING : 0
|
|
266
|
-
})
|
|
267
|
-
});
|
|
268
|
-
return /*#__PURE__*/React.createElement("div", _extends({}, innerProps, {
|
|
269
|
-
ref: this.setContainerRef,
|
|
270
|
-
"data-testid": testId && `${testId}--container`
|
|
271
|
-
}), /*#__PURE__*/React.createElement("input", {
|
|
272
|
-
name: name,
|
|
273
|
-
type: "hidden",
|
|
274
|
-
value: value,
|
|
275
|
-
"data-testid": testId && `${testId}--input`,
|
|
276
|
-
onKeyDown: this.onSelectKeyDown
|
|
277
|
-
}), /*#__PURE__*/React.createElement(SelectComponent, _extends({
|
|
278
|
-
"aria-describedby": ariaDescribedBy,
|
|
279
|
-
"aria-label": label || undefined,
|
|
280
|
-
appearance: appearance,
|
|
281
|
-
autoFocus: autoFocus,
|
|
282
|
-
components: selectComponents,
|
|
283
|
-
inputId: id,
|
|
284
|
-
isClearable: true,
|
|
285
|
-
isDisabled: isDisabled,
|
|
286
|
-
menuIsOpen: isOpen && !isDisabled,
|
|
287
|
-
menuPlacement: "auto",
|
|
288
|
-
openMenuOnFocus: true,
|
|
289
|
-
onBlur: this.onBlur,
|
|
290
|
-
onCreateOption: this.onCreateOption,
|
|
291
|
-
onChange: this.onChange,
|
|
292
|
-
options: options,
|
|
293
|
-
onFocus: this.onFocus,
|
|
294
|
-
onMenuOpen: this.onMenuOpen,
|
|
295
|
-
onMenuClose: this.onMenuClose,
|
|
296
|
-
placeholder: placeholder || l10n.formatTime(placeholderDatetime),
|
|
297
|
-
styles: mergedStyles,
|
|
298
|
-
value: initialValue,
|
|
299
|
-
spacing: spacing,
|
|
300
|
-
fixedLayerRef: this.containerRef,
|
|
301
|
-
isInvalid: isInvalid,
|
|
302
|
-
testId: testId
|
|
303
|
-
}, otherSelectProps)));
|
|
304
|
-
}
|
|
305
|
-
}
|
|
306
|
-
_defineProperty(TimePickerComponent, "defaultProps", timePickerDefaultProps);
|
|
307
|
-
export { TimePickerComponent as TimePickerWithoutAnalytics };
|
|
308
32
|
|
|
309
33
|
/**
|
|
310
34
|
* __Time picker__
|
|
@@ -315,19 +39,244 @@ export { TimePickerComponent as TimePickerWithoutAnalytics };
|
|
|
315
39
|
* - [Code](https://atlassian.design/components/datetime-picker/time-picker/code)
|
|
316
40
|
* - [Usage](https://atlassian.design/components/datetime-picker/time-picker/usage)
|
|
317
41
|
*/
|
|
318
|
-
const TimePicker =
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
42
|
+
const TimePicker = /*#__PURE__*/forwardRef(({
|
|
43
|
+
'aria-describedby': ariaDescribedBy,
|
|
44
|
+
analyticsContext,
|
|
45
|
+
appearance = 'default',
|
|
46
|
+
autoFocus = false,
|
|
47
|
+
defaultIsOpen = false,
|
|
48
|
+
defaultValue = '',
|
|
49
|
+
formatDisplayLabel,
|
|
50
|
+
hideIcon = false,
|
|
51
|
+
id = '',
|
|
52
|
+
innerProps = {},
|
|
53
|
+
isDisabled = false,
|
|
54
|
+
isInvalid = false,
|
|
55
|
+
isOpen: providedIsOpen,
|
|
56
|
+
label = '',
|
|
57
|
+
locale = 'en-US',
|
|
58
|
+
name = '',
|
|
59
|
+
onBlur: providedOnBlur = __noop,
|
|
60
|
+
onChange: providedOnChange = __noop,
|
|
61
|
+
onFocus: providedOnFocus = __noop,
|
|
62
|
+
parseInputValue = (time, _timeFormat) => parseTime(time),
|
|
63
|
+
placeholder,
|
|
64
|
+
selectProps = {},
|
|
65
|
+
spacing = 'default',
|
|
66
|
+
testId,
|
|
67
|
+
timeFormat,
|
|
68
|
+
timeIsEditable = false,
|
|
69
|
+
times = defaultTimes,
|
|
70
|
+
value: providedValue
|
|
71
|
+
}, ref) => {
|
|
72
|
+
const [containerRef, setContainerRef] = useState(null);
|
|
73
|
+
/**
|
|
74
|
+
* When being cleared from the icon the TimePicker is blurred.
|
|
75
|
+
* This variable defines whether the default onMenuOpen or onMenuClose
|
|
76
|
+
* events should behave as normal
|
|
77
|
+
*/
|
|
78
|
+
const [clearingFromIcon, setClearingFromIcon] = useState(false);
|
|
79
|
+
// TODO: Remove isFocused? Does it do anything?
|
|
80
|
+
const [_, setIsFocused] = useState(false);
|
|
81
|
+
const [isOpen, setIsOpen] = useState(providedIsOpen || defaultIsOpen);
|
|
82
|
+
const [value, setValue] = useState(providedValue || defaultValue);
|
|
83
|
+
|
|
84
|
+
// Hack to force update: https://legacy.reactjs.org/docs/hooks-faq.html#is-there-something-like-forceupdate
|
|
85
|
+
const [, forceUpdate] = useReducer(x => x + 1, 0);
|
|
86
|
+
const providedOnChangeWithAnalytics = usePlatformLeafEventHandler({
|
|
87
|
+
fn: providedOnChange,
|
|
324
88
|
action: 'selectedTime',
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
89
|
+
analyticsData: analyticsContext,
|
|
90
|
+
...analyticsAttributes
|
|
91
|
+
});
|
|
92
|
+
const onChange = (newValue, action) => {
|
|
93
|
+
const rawValue = newValue ? newValue.value || newValue : '';
|
|
94
|
+
const finalValue = rawValue.toString();
|
|
95
|
+
setValue(finalValue);
|
|
96
|
+
if (action && action.action === 'clear') {
|
|
97
|
+
setClearingFromIcon(true);
|
|
98
|
+
}
|
|
99
|
+
providedOnChangeWithAnalytics(finalValue);
|
|
100
|
+
};
|
|
101
|
+
|
|
102
|
+
/**
|
|
103
|
+
* Only allow custom times if timeIsEditable prop is true
|
|
104
|
+
*/
|
|
105
|
+
const onCreateOption = inputValue => {
|
|
106
|
+
if (timeIsEditable) {
|
|
107
|
+
let sanitizedInput;
|
|
108
|
+
try {
|
|
109
|
+
sanitizedInput = parseInputValue(inputValue, timeFormat || defaultTimeFormat);
|
|
110
|
+
} catch (e) {
|
|
111
|
+
return; // do nothing, the main validation should happen in the form
|
|
112
|
+
}
|
|
113
|
+
const includesSeconds = !!(timeFormat && /[:.]?(s|ss)/.test(timeFormat));
|
|
114
|
+
const formatFormat = includesSeconds ? 'HH:mm:ss' : 'HH:mm';
|
|
115
|
+
const formattedValue = format(sanitizedInput, formatFormat) || '';
|
|
116
|
+
setValue(formattedValue);
|
|
117
|
+
providedOnChange(formattedValue);
|
|
118
|
+
} else {
|
|
119
|
+
providedOnChange(inputValue);
|
|
120
|
+
}
|
|
121
|
+
};
|
|
122
|
+
const onMenuOpen = () => {
|
|
123
|
+
// Don't open menu after the user has clicked clear
|
|
124
|
+
if (clearingFromIcon) {
|
|
125
|
+
setClearingFromIcon(false);
|
|
126
|
+
} else {
|
|
127
|
+
setIsOpen(true);
|
|
128
|
+
}
|
|
129
|
+
};
|
|
130
|
+
const onMenuClose = () => {
|
|
131
|
+
// Don't close menu after the user has clicked clear
|
|
132
|
+
if (clearingFromIcon) {
|
|
133
|
+
setClearingFromIcon(false);
|
|
134
|
+
} else {
|
|
135
|
+
setIsOpen(false);
|
|
136
|
+
}
|
|
137
|
+
};
|
|
138
|
+
const setInternalContainerRef = ref => {
|
|
139
|
+
const oldRef = containerRef;
|
|
140
|
+
setContainerRef(ref);
|
|
141
|
+
// Cause a re-render if we're getting the container ref for the first time
|
|
142
|
+
// as the layered menu requires it for dimension calculation
|
|
143
|
+
if (oldRef === null && ref !== null) {
|
|
144
|
+
forceUpdate();
|
|
145
|
+
}
|
|
146
|
+
};
|
|
147
|
+
const onBlur = event => {
|
|
148
|
+
setIsFocused(false);
|
|
149
|
+
providedOnBlur(event);
|
|
150
|
+
};
|
|
151
|
+
const onFocus = event => {
|
|
152
|
+
setIsFocused(true);
|
|
153
|
+
providedOnFocus(event);
|
|
154
|
+
};
|
|
155
|
+
const onSelectKeyDown = event => {
|
|
156
|
+
const {
|
|
157
|
+
key
|
|
158
|
+
} = event;
|
|
159
|
+
const keyPressed = key.toLowerCase();
|
|
160
|
+
if (clearingFromIcon && (keyPressed === 'backspace' || keyPressed === 'delete')) {
|
|
161
|
+
// If being cleared from keyboard, don't change behaviour
|
|
162
|
+
setClearingFromIcon(false);
|
|
330
163
|
}
|
|
331
|
-
}
|
|
332
|
-
|
|
164
|
+
};
|
|
165
|
+
const ICON_PADDING = 2;
|
|
166
|
+
const l10n = createLocalizationProvider(locale);
|
|
167
|
+
const {
|
|
168
|
+
styles: selectStyles = {},
|
|
169
|
+
...otherSelectProps
|
|
170
|
+
} = selectProps;
|
|
171
|
+
const SelectComponent = timeIsEditable ? CreatableSelect : Select;
|
|
172
|
+
|
|
173
|
+
/**
|
|
174
|
+
* There are multiple props that can change how the time is formatted.
|
|
175
|
+
* The priority of props used is:
|
|
176
|
+
* 1. formatDisplayLabel
|
|
177
|
+
* 2. timeFormat
|
|
178
|
+
* 3. locale
|
|
179
|
+
*/
|
|
180
|
+
const formatTime = time => {
|
|
181
|
+
if (formatDisplayLabel) {
|
|
182
|
+
return formatDisplayLabel(time, timeFormat || defaultTimeFormat);
|
|
183
|
+
}
|
|
184
|
+
const date = parseTime(time);
|
|
185
|
+
if (!(date instanceof Date)) {
|
|
186
|
+
return '';
|
|
187
|
+
}
|
|
188
|
+
if (!isValid(date)) {
|
|
189
|
+
return time;
|
|
190
|
+
}
|
|
191
|
+
if (timeFormat) {
|
|
192
|
+
return format(date, convertTokens(timeFormat));
|
|
193
|
+
}
|
|
194
|
+
return l10n.formatTime(date);
|
|
195
|
+
};
|
|
196
|
+
const options = times.map(time => {
|
|
197
|
+
return {
|
|
198
|
+
label: formatTime(time),
|
|
199
|
+
value: time
|
|
200
|
+
};
|
|
201
|
+
});
|
|
202
|
+
let initialValue;
|
|
203
|
+
if (providedValue !== null && providedValue !== undefined && providedValue !== '') {
|
|
204
|
+
initialValue = {
|
|
205
|
+
label: formatTime(providedValue),
|
|
206
|
+
value: providedValue
|
|
207
|
+
};
|
|
208
|
+
} else if (providedValue !== '' && value) {
|
|
209
|
+
initialValue = {
|
|
210
|
+
label: formatTime(value),
|
|
211
|
+
value: value
|
|
212
|
+
};
|
|
213
|
+
} else {
|
|
214
|
+
initialValue = null;
|
|
215
|
+
}
|
|
216
|
+
const SingleValue = makeSingleValue({
|
|
217
|
+
lang: locale
|
|
218
|
+
});
|
|
219
|
+
const selectComponents = {
|
|
220
|
+
DropdownIndicator: EmptyComponent,
|
|
221
|
+
Menu: FixedLayerMenu,
|
|
222
|
+
SingleValue,
|
|
223
|
+
...(hideIcon && {
|
|
224
|
+
ClearIndicator: EmptyComponent
|
|
225
|
+
})
|
|
226
|
+
};
|
|
227
|
+
const renderIconContainer = Boolean(!hideIcon && value);
|
|
228
|
+
const mergedStyles = mergeStyles(selectStyles, {
|
|
229
|
+
control: base => ({
|
|
230
|
+
...base
|
|
231
|
+
}),
|
|
232
|
+
menu: base => ({
|
|
233
|
+
...base,
|
|
234
|
+
...menuStyles,
|
|
235
|
+
// Fixed positioned elements no longer inherit width from their parent, so we must explicitly set the
|
|
236
|
+
// menu width to the width of our container
|
|
237
|
+
width: containerRef ? containerRef.getBoundingClientRect().width : 'auto'
|
|
238
|
+
}),
|
|
239
|
+
indicatorsContainer: base => ({
|
|
240
|
+
...base,
|
|
241
|
+
paddingLeft: renderIconContainer ? ICON_PADDING : 0,
|
|
242
|
+
paddingRight: renderIconContainer ? gridSize() - ICON_PADDING : 0
|
|
243
|
+
})
|
|
244
|
+
});
|
|
245
|
+
return /*#__PURE__*/React.createElement("div", _extends({}, innerProps, {
|
|
246
|
+
ref: setInternalContainerRef,
|
|
247
|
+
"data-testid": testId && `${testId}--container`
|
|
248
|
+
}), /*#__PURE__*/React.createElement("input", {
|
|
249
|
+
name: name,
|
|
250
|
+
type: "hidden",
|
|
251
|
+
value: value,
|
|
252
|
+
"data-testid": testId && `${testId}--input`,
|
|
253
|
+
onKeyDown: onSelectKeyDown
|
|
254
|
+
}), /*#__PURE__*/React.createElement(SelectComponent, _extends({
|
|
255
|
+
"aria-describedby": ariaDescribedBy,
|
|
256
|
+
"aria-label": label || undefined,
|
|
257
|
+
appearance: appearance,
|
|
258
|
+
autoFocus: autoFocus,
|
|
259
|
+
components: selectComponents,
|
|
260
|
+
inputId: id,
|
|
261
|
+
isClearable: true,
|
|
262
|
+
isDisabled: isDisabled,
|
|
263
|
+
menuIsOpen: isOpen && !isDisabled,
|
|
264
|
+
menuPlacement: "auto",
|
|
265
|
+
openMenuOnFocus: true,
|
|
266
|
+
onBlur: onBlur,
|
|
267
|
+
onCreateOption: onCreateOption,
|
|
268
|
+
onChange: onChange,
|
|
269
|
+
options: options,
|
|
270
|
+
onFocus: onFocus,
|
|
271
|
+
onMenuOpen: onMenuOpen,
|
|
272
|
+
onMenuClose: onMenuClose,
|
|
273
|
+
placeholder: placeholder || l10n.formatTime(placeholderDatetime),
|
|
274
|
+
styles: mergedStyles,
|
|
275
|
+
value: initialValue,
|
|
276
|
+
spacing: spacing,
|
|
277
|
+
fixedLayerRef: containerRef,
|
|
278
|
+
isInvalid: isInvalid,
|
|
279
|
+
testId: testId
|
|
280
|
+
}, otherSelectProps)));
|
|
281
|
+
});
|
|
333
282
|
export default TimePicker;
|
|
@@ -69,7 +69,6 @@ export const Menu = ({
|
|
|
69
69
|
onChange: selectProps.onCalendarChange,
|
|
70
70
|
onSelect: selectProps.onCalendarSelect,
|
|
71
71
|
previousMonthLabel: selectProps.previousMonthLabel,
|
|
72
|
-
calendarRef: selectProps.calendarRef,
|
|
73
72
|
selected: [selectProps.calendarValue],
|
|
74
73
|
shouldSetFocusOnCurrentDay: selectProps.shouldSetFocusOnCurrentDay,
|
|
75
74
|
locale: selectProps.calendarLocale,
|
|
@@ -30,7 +30,7 @@ import { getSafeCalendarValue, getShortISOString } from '../internal/parse-date'
|
|
|
30
30
|
import { convertTokens } from '../internal/parse-tokens';
|
|
31
31
|
import { makeSingleValue } from '../internal/single-value';
|
|
32
32
|
var packageName = "@atlaskit/datetime-picker";
|
|
33
|
-
var packageVersion = "14.0.
|
|
33
|
+
var packageVersion = "14.0.3";
|
|
34
34
|
var datePickerDefaultProps = {
|
|
35
35
|
appearance: 'default',
|
|
36
36
|
autoFocus: false,
|
|
@@ -68,7 +68,6 @@ var DatePickerComponent = /*#__PURE__*/function (_Component) {
|
|
|
68
68
|
var _this;
|
|
69
69
|
_classCallCheck(this, DatePickerComponent);
|
|
70
70
|
_this = _super.call(this, props);
|
|
71
|
-
_defineProperty(_assertThisInitialized(_this), "calendarRef", null);
|
|
72
71
|
_defineProperty(_assertThisInitialized(_this), "containerRef", null);
|
|
73
72
|
// All state needs to be accessed via this function so that the state is mapped from props
|
|
74
73
|
// correctly to allow controlled/uncontrolled usage.
|
|
@@ -298,9 +297,6 @@ var DatePickerComponent = /*#__PURE__*/function (_Component) {
|
|
|
298
297
|
_this.onClear();
|
|
299
298
|
}
|
|
300
299
|
});
|
|
301
|
-
_defineProperty(_assertThisInitialized(_this), "refCalendar", function (ref) {
|
|
302
|
-
_this.calendarRef = ref;
|
|
303
|
-
});
|
|
304
300
|
_defineProperty(_assertThisInitialized(_this), "handleSelectInputChange", function (selectInputValue, actionMeta) {
|
|
305
301
|
var onInputChange = _this.props.selectProps.onInputChange;
|
|
306
302
|
if (onInputChange) {
|
|
@@ -427,7 +423,6 @@ var DatePickerComponent = /*#__PURE__*/function (_Component) {
|
|
|
427
423
|
} : {};
|
|
428
424
|
var calendarProps = {
|
|
429
425
|
calendarContainerRef: this.containerRef,
|
|
430
|
-
calendarRef: this.refCalendar,
|
|
431
426
|
calendarDisabled: disabled,
|
|
432
427
|
calendarDisabledDateFilter: disabledDateFilter,
|
|
433
428
|
calendarMaxDate: maxDate,
|
|
@@ -507,7 +502,6 @@ var DatePickerComponent = /*#__PURE__*/function (_Component) {
|
|
|
507
502
|
calendarLocale: calendarProps.calendarLocale,
|
|
508
503
|
calendarMaxDate: calendarProps.calendarMaxDate,
|
|
509
504
|
calendarMinDate: calendarProps.calendarMinDate,
|
|
510
|
-
calendarRef: calendarProps.calendarRef,
|
|
511
505
|
calendarValue: calendarProps.calendarValue,
|
|
512
506
|
calendarView: calendarProps.calendarView,
|
|
513
507
|
calendarWeekStartDay: calendarProps.calendarWeekStartDay,
|
|
@@ -31,7 +31,7 @@ import { convertTokens } from '../internal/parse-tokens';
|
|
|
31
31
|
import DatePicker from './date-picker';
|
|
32
32
|
import TimePicker from './time-picker';
|
|
33
33
|
var packageName = "@atlaskit/datetime-picker";
|
|
34
|
-
var packageVersion = "14.0.
|
|
34
|
+
var packageVersion = "14.0.3";
|
|
35
35
|
// Make DatePicker 50% the width of DateTimePicker
|
|
36
36
|
// If rendering an icon container, shrink the TimePicker
|
|
37
37
|
var datePickerContainerStyles = css({
|