@contentful/field-editor-date 1.3.5 → 1.5.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/dist/cjs/DateEditor.js +186 -0
  2. package/dist/cjs/DatepickerInput.js +92 -0
  3. package/dist/cjs/DatepickerInput.spec.js +110 -0
  4. package/dist/cjs/TimepickerInput.js +132 -0
  5. package/dist/cjs/TimezonePickerInput.js +32 -0
  6. package/dist/cjs/index.js +20 -0
  7. package/dist/cjs/types.js +4 -0
  8. package/dist/cjs/utils/data.spec.js +56 -0
  9. package/dist/cjs/utils/date.js +116 -0
  10. package/dist/cjs/utils/zoneOffsets.js +61 -0
  11. package/dist/esm/DateEditor.js +132 -0
  12. package/dist/esm/DatepickerInput.js +38 -0
  13. package/dist/esm/DatepickerInput.spec.js +62 -0
  14. package/dist/esm/TimepickerInput.js +78 -0
  15. package/dist/esm/TimezonePickerInput.js +17 -0
  16. package/dist/esm/index.js +2 -0
  17. package/dist/esm/types.js +1 -0
  18. package/dist/esm/utils/data.spec.js +47 -0
  19. package/dist/esm/utils/date.js +87 -0
  20. package/dist/esm/utils/zoneOffsets.js +43 -0
  21. package/dist/{DateEditor.d.ts → types/DateEditor.d.ts} +29 -29
  22. package/dist/{DatepickerInput.d.ts → types/DatepickerInput.d.ts} +8 -8
  23. package/dist/types/DatepickerInput.spec.d.ts +1 -0
  24. package/dist/{TimepickerInput.d.ts → types/TimepickerInput.d.ts} +12 -12
  25. package/dist/{TimezonePickerInput.d.ts → types/TimezonePickerInput.d.ts} +7 -7
  26. package/dist/{index.d.ts → types/index.d.ts} +2 -2
  27. package/dist/types/types.d.ts +9 -0
  28. package/dist/types/utils/data.spec.d.ts +1 -0
  29. package/dist/{utils → types/utils}/date.d.ts +27 -27
  30. package/dist/{utils → types/utils}/zoneOffsets.d.ts +2 -2
  31. package/package.json +28 -14
  32. package/CHANGELOG.md +0 -288
  33. package/dist/field-editor-date.cjs.development.js +0 -463
  34. package/dist/field-editor-date.cjs.development.js.map +0 -1
  35. package/dist/field-editor-date.cjs.production.min.js +0 -2
  36. package/dist/field-editor-date.cjs.production.min.js.map +0 -1
  37. package/dist/field-editor-date.esm.js +0 -455
  38. package/dist/field-editor-date.esm.js.map +0 -1
  39. package/dist/index.js +0 -8
  40. package/dist/types.d.ts +0 -9
@@ -1,463 +0,0 @@
1
- 'use strict';
2
-
3
- Object.defineProperty(exports, '__esModule', { value: true });
4
-
5
- function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; }
6
-
7
- var React = require('react');
8
- var React__default = _interopDefault(React);
9
- var f36Components = require('@contentful/f36-components');
10
- var tokens = _interopDefault(require('@contentful/f36-tokens'));
11
- var fieldEditorShared = require('@contentful/field-editor-shared');
12
- var emotion = require('emotion');
13
- var moment = _interopDefault(require('moment'));
14
-
15
- function _extends() {
16
- _extends = Object.assign || function (target) {
17
- for (var i = 1; i < arguments.length; i++) {
18
- var source = arguments[i];
19
-
20
- for (var key in source) {
21
- if (Object.prototype.hasOwnProperty.call(source, key)) {
22
- target[key] = source[key];
23
- }
24
- }
25
- }
26
-
27
- return target;
28
- };
29
-
30
- return _extends.apply(this, arguments);
31
- }
32
-
33
- var YEAR_RANGE = 100;
34
- var styles = {
35
- root: /*#__PURE__*/emotion.css({
36
- maxWidth: '270px'
37
- })
38
- };
39
- var DatepickerInput = function DatepickerInput(props) {
40
- var _props$value;
41
-
42
- var _useMemo = React.useMemo(function () {
43
- var fromDate = new Date();
44
- fromDate.setFullYear(fromDate.getFullYear() - YEAR_RANGE);
45
- var toDate = new Date();
46
- toDate.setFullYear(toDate.getFullYear() + YEAR_RANGE);
47
- return [fromDate, toDate];
48
- }, []),
49
- fromDate = _useMemo[0],
50
- toDate = _useMemo[1]; // The DatepickerInput should be time and timezone agnostic,
51
- // thats why we don't use moment().toDate() to get Date object.
52
- // moment().toDate() takes into account time and timezone and converts it
53
- // based on your system timezone which can result in the date change.
54
- // e.g. if user has a timezone +02:00, moment('2022-09-16T00:00+04:00').toDate()
55
- // will return September 15 instead of September 16
56
-
57
-
58
- var dateObj = (_props$value = props.value) == null ? void 0 : _props$value.toObject();
59
- var selectedDate = dateObj ? new Date(dateObj.years, dateObj.months, dateObj.date) : undefined;
60
- return React__default.createElement(f36Components.Datepicker, {
61
- className: styles.root,
62
- selected: selectedDate,
63
- onSelect: function onSelect(day) {
64
- var momentDay = day ? moment(day) : undefined;
65
- props.onChange(momentDay);
66
- },
67
- inputProps: {
68
- isDisabled: props.disabled,
69
- placeholder: ''
70
- },
71
- fromDate: fromDate,
72
- toDate: toDate
73
- });
74
- };
75
-
76
- var validInputFormats = ['hh:mm a', 'hh:mm A', 'h:mm a', 'h:mm A', 'hh:mm', 'k:mm', 'kk:mm', 'h a', 'h A', 'h', 'hh', 'HH'];
77
-
78
- function parseRawInput(raw) {
79
- var time = null; // eslint-disable-next-line -- TODO: refactor to use for of loop
80
-
81
- for (var i = 0; i < validInputFormats.length; i++) {
82
- var date = moment(raw, validInputFormats[i]);
83
-
84
- if (date.isValid()) {
85
- time = date;
86
- break;
87
- }
88
- }
89
-
90
- return time;
91
- }
92
-
93
- var getDefaultTime = function getDefaultTime() {
94
- return moment("12:00 AM", 'hh:mm A');
95
- };
96
-
97
- var formatToString = function formatToString(uses12hClock, value) {
98
- return uses12hClock ? value.format('hh:mm A') : value.format('HH:mm');
99
- };
100
-
101
- var TimepickerInput = function TimepickerInput(_ref) {
102
- var disabled = _ref.disabled,
103
- uses12hClock = _ref.uses12hClock,
104
- _ref$time = _ref.time,
105
- time = _ref$time === void 0 ? '12:00' : _ref$time,
106
- _ref$ampm = _ref.ampm,
107
- ampm = _ref$ampm === void 0 ? 'AM' : _ref$ampm,
108
- onChange = _ref.onChange;
109
-
110
- var _useState = React.useState(function () {
111
- return formatToString(uses12hClock, getDefaultTime());
112
- }),
113
- selectedTime = _useState[0],
114
- setSelectedTime = _useState[1];
115
-
116
- React.useEffect(function () {
117
- setSelectedTime(formatToString(uses12hClock, moment(time + " " + ampm, 'hh:mm A')));
118
- }, [time, ampm, uses12hClock]);
119
- var handleChange = React.useCallback(function (e) {
120
- setSelectedTime(e.currentTarget.value);
121
- }, []);
122
- var handleFocus = React.useCallback(function (e) {
123
- e.preventDefault();
124
- e.target.select();
125
- }, []);
126
-
127
- var handleBlur = function handleBlur() {
128
- var parsedTime = parseRawInput(selectedTime);
129
- var value = parsedTime != null ? parsedTime : getDefaultTime();
130
- setSelectedTime(formatToString(uses12hClock, value));
131
- onChange({
132
- time: value.format('hh:mm'),
133
- ampm: value.format('A')
134
- });
135
- };
136
-
137
- return React__default.createElement(f36Components.Flex, {
138
- className: emotion.css({
139
- width: '145px'
140
- })
141
- }, React__default.createElement(f36Components.TextInput, {
142
- "aria-label": "Select time",
143
- placeholder: uses12hClock ? '12:00 AM' : '00:00',
144
- "date-time-type": uses12hClock ? '12' : '24',
145
- testId: "time-input",
146
- value: selectedTime,
147
- isDisabled: disabled,
148
- onFocus: handleFocus,
149
- onBlur: handleBlur,
150
- onChange: handleChange
151
- }));
152
- };
153
-
154
- var defaultZoneOffset = '+00:00';
155
- var zoneOffsets = ['-12:00', '-11:00', '-10:00', '-09:30', '-09:00', '-08:00', '-07:00', '-06:00', '-05:00', '-04:30', '-04:00', '-03:30', '-03:00', '-02:00', '-01:00', '+00:00', '+01:00', '+02:00', '+03:00', '+03:30', '+04:00', '+04:30', '+05:00', '+05:30', '+05:45', '+06:00', '+06:30', '+07:00', '+08:00', '+08:45', '+09:00', '+09:30', '+10:00', '+10:30', '+11:00', '+11:30', '+12:00', '+12:45', '+13:00', '+14:00'];
156
-
157
- var TimezonepickerInput = function TimezonepickerInput(_ref) {
158
- var disabled = _ref.disabled,
159
- _onChange = _ref.onChange,
160
- _ref$value = _ref.value,
161
- value = _ref$value === void 0 ? defaultZoneOffset : _ref$value;
162
- return React__default.createElement(f36Components.Select, {
163
- "aria-label": "Select timezone",
164
- testId: "timezone-input",
165
- value: value,
166
- isDisabled: disabled,
167
- onChange: function onChange(e) {
168
- _onChange(e.currentTarget.value);
169
- }
170
- }, zoneOffsets.map(function (offset) {
171
- return React__default.createElement(f36Components.Select.Option, {
172
- key: offset,
173
- value: offset
174
- }, "UTC", offset);
175
- }));
176
- };
177
-
178
- // eslint-disable-next-line -- TODO: move to date-fns
179
- var ZONE_RX = /(Z|[+-]\d{2}[:+]?\d{2})$/;
180
-
181
- function startOfToday(format) {
182
- return moment().set({
183
- hours: 0,
184
- minutes: 0
185
- }).format(format);
186
- }
187
-
188
- function fieldValueToMoment(datetimeString) {
189
- if (!datetimeString) {
190
- return null;
191
- }
192
-
193
- var datetime = moment(datetimeString);
194
-
195
- if (ZONE_RX.test(datetimeString)) {
196
- datetime.utcOffset(datetimeString);
197
- }
198
-
199
- return datetime;
200
- }
201
-
202
- function timeFromUserInput(input) {
203
- var timeInput = input.time || '00:00';
204
- return moment.utc(timeInput + '!' + input.ampm, 'HH:mm!A');
205
- }
206
- /**
207
- * Convert the user input object into either a 'moment' value or an
208
- * invalid symbol.
209
- *
210
- * Success is indicated by returning '{valid: value}' and failure is
211
- * indicated by returning '{invalid: true}'. If 'input.date' is
212
- * 'null' we return '{valid: null}'
213
- */
214
-
215
-
216
- function datetimeFromUserInput(input) {
217
- if (!input.date) {
218
- return {
219
- valid: null
220
- };
221
- }
222
-
223
- var time = timeFromUserInput(input);
224
- var date = moment.parseZone(input.utcOffset, 'Z').set(input.date.toObject()).set({
225
- hours: time.hours(),
226
- minutes: time.minutes()
227
- });
228
-
229
- if (date.isValid()) {
230
- return {
231
- valid: date
232
- };
233
- } else {
234
- return {
235
- invalid: true,
236
- valid: null
237
- };
238
- }
239
- }
240
- /**
241
- * Parse user input into a string that is stored in the API.
242
- *
243
- * Returns a sum type with either the string as the `valid` property
244
- * or the `invalid` property set to `false`.
245
- */
246
-
247
-
248
- function buildFieldValue(_ref) {
249
- var data = _ref.data,
250
- usesTime = _ref.usesTime,
251
- usesTimezone = _ref.usesTimezone;
252
- var date = datetimeFromUserInput(data);
253
-
254
- if (date.invalid) {
255
- return {
256
- invalid: true
257
- };
258
- }
259
-
260
- var format;
261
-
262
- if (usesTimezone) {
263
- format = 'YYYY-MM-DDTHH:mmZ';
264
- } else if (usesTime) {
265
- format = 'YYYY-MM-DDTHH:mm';
266
- } else {
267
- format = 'YYYY-MM-DD';
268
- }
269
-
270
- return {
271
- valid: date != null && date.valid ? date.valid.format(format) : null,
272
- invalid: false
273
- };
274
- }
275
- function getDefaultAMPM() {
276
- return 'AM';
277
- }
278
- function getDefaultUtcOffset() {
279
- return startOfToday('Z');
280
- }
281
- /**
282
- * Create the user input object from the field value.
283
- */
284
-
285
- function userInputFromDatetime(_ref2) {
286
- var value = _ref2.value,
287
- uses12hClock = _ref2.uses12hClock;
288
- var datetime = fieldValueToMoment(value);
289
-
290
- if (datetime) {
291
- var timeFormat = uses12hClock ? 'hh:mm' : 'HH:mm';
292
- return {
293
- date: datetime,
294
- time: datetime.format(timeFormat),
295
- ampm: datetime.format('A'),
296
- utcOffset: datetime.format('Z')
297
- };
298
- } else {
299
- return {
300
- ampm: getDefaultAMPM(),
301
- utcOffset: getDefaultUtcOffset()
302
- };
303
- }
304
- }
305
-
306
- var styles$1 = {
307
- root: /*#__PURE__*/emotion.css({
308
- display: 'flex',
309
- alignItems: 'center'
310
- }),
311
- separator: /*#__PURE__*/emotion.css({
312
- marginLeft: tokens.spacingM
313
- })
314
- };
315
-
316
- function useEffectWithoutFirstRender(callback, deps) {
317
- var isFirstRun = React.useRef(true);
318
- React.useEffect(function () {
319
- if (isFirstRun.current) {
320
- isFirstRun.current = false;
321
- return;
322
- }
323
-
324
- callback(); // eslint-disable-next-line react-hooks/exhaustive-deps -- TODO: Evaluate the dependencies
325
- }, deps);
326
- }
327
-
328
- function DateEditorContainer(_ref) {
329
- var initialValue = _ref.initialValue,
330
- usesTime = _ref.usesTime,
331
- usesTimezone = _ref.usesTimezone,
332
- uses12hClock = _ref.uses12hClock,
333
- disabled = _ref.disabled,
334
- hasClear = _ref.hasClear,
335
- onChange = _ref.onChange;
336
-
337
- var _React$useState = React.useState(function () {
338
- return initialValue;
339
- }),
340
- value = _React$useState[0],
341
- setValue = _React$useState[1];
342
-
343
- useEffectWithoutFirstRender(function () {
344
- onChange(value);
345
- }, [value]);
346
- return React.createElement("div", {
347
- "data-test-id": "date-editor",
348
- className: styles$1.root
349
- }, React.createElement(DatepickerInput, {
350
- disabled: disabled,
351
- value: value.date,
352
- onChange: function onChange(date) {
353
- setValue(function (value) {
354
- return _extends({}, value, {
355
- date: date
356
- });
357
- });
358
- }
359
- }), usesTime && React.createElement(React.Fragment, null, React.createElement("div", {
360
- className: styles$1.separator
361
- }), React.createElement(TimepickerInput, {
362
- disabled: disabled,
363
- time: value.time,
364
- ampm: value.ampm,
365
- onChange: function onChange(_ref2) {
366
- var time = _ref2.time,
367
- ampm = _ref2.ampm;
368
- setValue(function (value) {
369
- return _extends({}, value, {
370
- time: time,
371
- ampm: ampm
372
- });
373
- });
374
- },
375
- uses12hClock: uses12hClock
376
- })), usesTimezone && React.createElement(React.Fragment, null, React.createElement("div", {
377
- className: styles$1.separator
378
- }), React.createElement(TimezonepickerInput, {
379
- disabled: disabled,
380
- value: value.utcOffset,
381
- onChange: function onChange(utcOffset) {
382
- setValue(function (value) {
383
- return _extends({}, value, {
384
- utcOffset: utcOffset
385
- });
386
- });
387
- }
388
- })), hasClear && React.createElement(React.Fragment, null, React.createElement("div", {
389
- className: styles$1.separator
390
- }), React.createElement(f36Components.TextLink, {
391
- as: "button",
392
- isDisabled: disabled,
393
- testId: "date-clear",
394
- onClick: function onClick() {
395
- setValue({
396
- date: undefined,
397
- time: undefined,
398
- ampm: getDefaultAMPM(),
399
- utcOffset: getDefaultUtcOffset()
400
- });
401
- }
402
- }, "Clear")));
403
- }
404
-
405
- function DateEditor(props) {
406
- var _parameters$instance$, _parameters$instance, _parameters$instance$2, _parameters$instance2;
407
-
408
- var field = props.field,
409
- parameters = props.parameters;
410
- var formatParam = (_parameters$instance$ = parameters == null ? void 0 : (_parameters$instance = parameters.instance) == null ? void 0 : _parameters$instance.format) != null ? _parameters$instance$ : 'timeZ';
411
- var ampmParam = (_parameters$instance$2 = parameters == null ? void 0 : (_parameters$instance2 = parameters.instance) == null ? void 0 : _parameters$instance2.ampm) != null ? _parameters$instance$2 : '24';
412
- var usesTime = formatParam !== 'dateonly';
413
- var usesTimezone = formatParam === 'timeZ';
414
- var uses12hClock = ampmParam === '12';
415
- return React.createElement(fieldEditorShared.FieldConnector, {
416
- field: field,
417
- isInitiallyDisabled: props.isInitiallyDisabled,
418
- isDisabled: props.isDisabled,
419
- throttle: 0
420
- }, function (_ref3) {
421
- var value = _ref3.value,
422
- disabled = _ref3.disabled,
423
- setValue = _ref3.setValue,
424
- externalReset = _ref3.externalReset;
425
- var datetimeValue = userInputFromDatetime({
426
- value: value,
427
- uses12hClock: uses12hClock
428
- });
429
- return React.createElement(DateEditorContainer, {
430
- initialValue: datetimeValue,
431
- uses12hClock: uses12hClock,
432
- usesTimezone: usesTimezone,
433
- usesTime: usesTime,
434
- disabled: disabled,
435
- hasClear: Boolean(value),
436
- onChange: function onChange(data) {
437
- var fieldValue = buildFieldValue({
438
- data: data,
439
- usesTime: usesTime,
440
- usesTimezone: usesTimezone
441
- });
442
-
443
- if (fieldValue.invalid) {
444
- return;
445
- } // if value is present - then override it with a new one
446
- // if value is not present - then set a new one if it's not nullable only
447
-
448
-
449
- if (Boolean(value) || !value && Boolean(fieldValue.valid)) {
450
- setValue(fieldValue.valid);
451
- }
452
- },
453
- key: "date-container-" + externalReset
454
- });
455
- });
456
- }
457
- DateEditor.defaultProps = {
458
- isInitiallyDisabled: true
459
- };
460
-
461
- exports.DateEditor = DateEditor;
462
- exports.zoneOffsets = zoneOffsets;
463
- //# sourceMappingURL=field-editor-date.cjs.development.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"field-editor-date.cjs.development.js","sources":["../src/DatepickerInput.tsx","../src/TimepickerInput.tsx","../src/utils/zoneOffsets.ts","../src/TimezonePickerInput.tsx","../src/utils/date.ts","../src/DateEditor.tsx"],"sourcesContent":["import React, { useMemo } from 'react';\n\nimport { Datepicker } from '@contentful/f36-components';\nimport { css } from 'emotion';\n// eslint-disable-next-line -- TODO: move to date-fns\nimport moment from 'moment';\n\nconst YEAR_RANGE = 100;\n\nconst styles = {\n root: css({\n maxWidth: '270px',\n }),\n};\n\nexport type DatePickerProps = {\n value?: moment.Moment;\n onChange: (val: moment.Moment | undefined) => void;\n disabled?: boolean;\n};\n\nexport const DatepickerInput = (props: DatePickerProps) => {\n const [fromDate, toDate] = useMemo(() => {\n const fromDate = new Date();\n fromDate.setFullYear(fromDate.getFullYear() - YEAR_RANGE);\n const toDate = new Date();\n toDate.setFullYear(toDate.getFullYear() + YEAR_RANGE);\n\n return [fromDate, toDate];\n }, []);\n\n // The DatepickerInput should be time and timezone agnostic,\n // thats why we don't use moment().toDate() to get Date object.\n // moment().toDate() takes into account time and timezone and converts it\n // based on your system timezone which can result in the date change.\n // e.g. if user has a timezone +02:00, moment('2022-09-16T00:00+04:00').toDate()\n // will return September 15 instead of September 16\n const dateObj = props.value?.toObject();\n const selectedDate = dateObj ? new Date(dateObj.years, dateObj.months, dateObj.date) : undefined;\n\n return (\n <Datepicker\n className={styles.root}\n selected={selectedDate}\n onSelect={(day) => {\n const momentDay = day ? moment(day) : undefined;\n props.onChange(momentDay);\n }}\n inputProps={{ isDisabled: props.disabled, placeholder: '' }}\n fromDate={fromDate}\n toDate={toDate}\n />\n );\n};\n","import React, { useState, useCallback, useEffect } from 'react';\n// eslint-disable-next-line -- TODO: move to date-fns\nimport moment from 'moment';\nimport { css } from 'emotion';\n\nimport { TextInput, Flex } from '@contentful/f36-components';\n\nexport type TimepickerProps = {\n disabled: boolean;\n uses12hClock: boolean;\n onChange: (value: { time: string; ampm: string }) => void;\n time?: string;\n ampm?: string;\n};\n\nconst validInputFormats = [\n 'hh:mm a',\n 'hh:mm A',\n 'h:mm a',\n 'h:mm A',\n 'hh:mm',\n 'k:mm',\n 'kk:mm',\n 'h a',\n 'h A',\n 'h',\n 'hh',\n 'HH',\n];\n\nfunction parseRawInput(raw: string): moment.Moment | null {\n let time: moment.Moment | null = null;\n\n // eslint-disable-next-line -- TODO: refactor to use for of loop\n for (let i = 0; i < validInputFormats.length; i++) {\n const date = moment(raw, validInputFormats[i]);\n if (date.isValid()) {\n time = date;\n break;\n }\n }\n\n return time;\n}\n\nconst getDefaultTime = () => {\n return moment(`12:00 AM`, 'hh:mm A');\n};\n\nconst formatToString = (uses12hClock: boolean, value: moment.Moment): string => {\n return uses12hClock ? value.format('hh:mm A') : value.format('HH:mm');\n};\n\nexport const TimepickerInput = ({\n disabled,\n uses12hClock,\n time = '12:00',\n ampm = 'AM',\n onChange,\n}: TimepickerProps) => {\n const [selectedTime, setSelectedTime] = useState<string>(() => {\n return formatToString(uses12hClock, getDefaultTime());\n });\n\n useEffect(() => {\n setSelectedTime(formatToString(uses12hClock, moment(`${time} ${ampm}`, 'hh:mm A')));\n }, [time, ampm, uses12hClock]);\n\n const handleChange = useCallback((e: React.ChangeEvent<HTMLInputElement>) => {\n setSelectedTime(e.currentTarget.value);\n }, []);\n\n const handleFocus = useCallback((e) => {\n e.preventDefault();\n e.target.select();\n }, []);\n\n const handleBlur = () => {\n const parsedTime = parseRawInput(selectedTime);\n const value = parsedTime ?? getDefaultTime();\n setSelectedTime(formatToString(uses12hClock, value));\n onChange({ time: value.format('hh:mm'), ampm: value.format('A') });\n };\n\n return (\n <Flex className={css({ width: '145px' })}>\n <TextInput\n aria-label=\"Select time\"\n placeholder={uses12hClock ? '12:00 AM' : '00:00'}\n date-time-type={uses12hClock ? '12' : '24'}\n testId=\"time-input\"\n value={selectedTime}\n isDisabled={disabled}\n onFocus={handleFocus}\n onBlur={handleBlur}\n onChange={handleChange}\n />\n </Flex>\n );\n};\n","export const defaultZoneOffset = '+00:00';\n\nexport const zoneOffsets = [\n '-12:00',\n '-11:00',\n '-10:00',\n '-09:30',\n '-09:00',\n '-08:00',\n '-07:00',\n '-06:00',\n '-05:00',\n '-04:30',\n '-04:00',\n '-03:30',\n '-03:00',\n '-02:00',\n '-01:00',\n '+00:00',\n '+01:00',\n '+02:00',\n '+03:00',\n '+03:30',\n '+04:00',\n '+04:30',\n '+05:00',\n '+05:30',\n '+05:45',\n '+06:00',\n '+06:30',\n '+07:00',\n '+08:00',\n '+08:45',\n '+09:00',\n '+09:30',\n '+10:00',\n '+10:30',\n '+11:00',\n '+11:30',\n '+12:00',\n '+12:45',\n '+13:00',\n '+14:00',\n];\n","import React, { ChangeEvent } from 'react';\nimport { zoneOffsets, defaultZoneOffset } from './utils/zoneOffsets';\n\nimport { Select } from '@contentful/f36-components';\n\nexport type TimezonepickerProps = {\n disabled: boolean;\n onChange: (value: string) => void;\n value?: string;\n};\nexport const TimezonepickerInput = ({\n disabled,\n onChange,\n value = defaultZoneOffset,\n}: TimezonepickerProps) => {\n return (\n <Select\n aria-label=\"Select timezone\"\n testId=\"timezone-input\"\n value={value}\n isDisabled={disabled}\n onChange={(e: ChangeEvent<HTMLSelectElement>) => {\n onChange(e.currentTarget.value);\n }}>\n {zoneOffsets.map((offset) => (\n <Select.Option key={offset} value={offset}>\n UTC{offset}\n </Select.Option>\n ))}\n </Select>\n );\n};\n","// eslint-disable-next-line -- TODO: move to date-fns\nimport moment from 'moment';\nimport { TimeResult } from '../types';\n\nconst ZONE_RX = /(Z|[+-]\\d{2}[:+]?\\d{2})$/;\n\nfunction startOfToday(format: string) {\n return moment().set({ hours: 0, minutes: 0 }).format(format);\n}\n\nfunction fieldValueToMoment(datetimeString: string | null | undefined): moment.Moment | null {\n if (!datetimeString) {\n return null;\n }\n\n const datetime = moment(datetimeString);\n if (ZONE_RX.test(datetimeString)) {\n datetime.utcOffset(datetimeString);\n }\n return datetime;\n}\n\nfunction timeFromUserInput(input: TimeResult) {\n const timeInput = input.time || '00:00';\n return moment.utc(timeInput + '!' + input.ampm, 'HH:mm!A');\n}\n\n/**\n * Convert the user input object into either a 'moment' value or an\n * invalid symbol.\n *\n * Success is indicated by returning '{valid: value}' and failure is\n * indicated by returning '{invalid: true}'. If 'input.date' is\n * 'null' we return '{valid: null}'\n */\nfunction datetimeFromUserInput(input: TimeResult): {\n invalid?: boolean;\n valid: moment.Moment | null;\n} {\n if (!input.date) {\n return { valid: null };\n }\n\n const time = timeFromUserInput(input);\n\n const date = moment\n .parseZone(input.utcOffset, 'Z')\n .set(input.date.toObject())\n .set({ hours: time.hours(), minutes: time.minutes() });\n\n if (date.isValid()) {\n return { valid: date };\n } else {\n return { invalid: true, valid: null };\n }\n}\n\n/**\n * Parse user input into a string that is stored in the API.\n *\n * Returns a sum type with either the string as the `valid` property\n * or the `invalid` property set to `false`.\n */\nexport function buildFieldValue({\n data,\n usesTime,\n usesTimezone,\n}: {\n data: TimeResult;\n usesTime: boolean;\n usesTimezone: boolean;\n}) {\n const date = datetimeFromUserInput(data);\n if (date.invalid) {\n return {\n invalid: true,\n };\n }\n\n let format;\n if (usesTimezone) {\n format = 'YYYY-MM-DDTHH:mmZ';\n } else if (usesTime) {\n format = 'YYYY-MM-DDTHH:mm';\n } else {\n format = 'YYYY-MM-DD';\n }\n return { valid: date?.valid ? date.valid.format(format) : null, invalid: false };\n}\n\nexport function getDefaultAMPM() {\n return 'AM';\n}\n\nexport function getDefaultUtcOffset() {\n return startOfToday('Z');\n}\n\n/**\n * Create the user input object from the field value.\n */\nexport function userInputFromDatetime({\n value,\n uses12hClock,\n}: {\n value: string | undefined | null;\n uses12hClock: boolean;\n}): TimeResult {\n const datetime = fieldValueToMoment(value);\n\n if (datetime) {\n const timeFormat = uses12hClock ? 'hh:mm' : 'HH:mm';\n return {\n date: datetime,\n time: datetime.format(timeFormat),\n ampm: datetime.format('A'),\n utcOffset: datetime.format('Z'),\n };\n } else {\n return {\n ampm: getDefaultAMPM(),\n utcOffset: getDefaultUtcOffset(),\n };\n }\n}\n","import * as React from 'react';\n\nimport { TextLink } from '@contentful/f36-components';\nimport tokens from '@contentful/f36-tokens';\nimport { FieldAPI, FieldConnector, ParametersAPI } from '@contentful/field-editor-shared';\nimport { css } from 'emotion';\n\nimport { DatepickerInput } from './DatepickerInput';\nimport { TimepickerInput } from './TimepickerInput';\nimport { TimezonepickerInput } from './TimezonePickerInput';\nimport { TimeFormat, DateTimeFormat, TimeResult } from './types';\nimport {\n userInputFromDatetime,\n buildFieldValue,\n getDefaultAMPM,\n getDefaultUtcOffset,\n} from './utils/date';\n\nexport interface DateEditorProps {\n /**\n * is the field disabled initially\n */\n isInitiallyDisabled: boolean;\n\n /*\n * is the field manually disabled\n */\n isDisabled?: boolean;\n\n /**\n * sdk.field\n */\n field: FieldAPI;\n\n /**\n * sdk.parameters\n */\n parameters?: ParametersAPI & {\n instance?: {\n format?: DateTimeFormat;\n ampm?: TimeFormat;\n };\n };\n}\n\nconst styles = {\n root: css({\n display: 'flex',\n alignItems: 'center',\n }),\n separator: css({\n marginLeft: tokens.spacingM,\n }),\n};\n\nfunction useEffectWithoutFirstRender(callback: Function, deps: Array<any>) {\n const isFirstRun = React.useRef(true);\n React.useEffect(() => {\n if (isFirstRun.current) {\n isFirstRun.current = false;\n return;\n }\n callback();\n // eslint-disable-next-line react-hooks/exhaustive-deps -- TODO: Evaluate the dependencies\n }, deps);\n}\n\nfunction DateEditorContainer({\n initialValue,\n usesTime,\n usesTimezone,\n uses12hClock,\n disabled,\n hasClear,\n onChange,\n}: {\n initialValue: TimeResult;\n usesTime: boolean;\n usesTimezone: boolean;\n uses12hClock: boolean;\n disabled: boolean;\n hasClear: boolean;\n onChange: (value: TimeResult) => void;\n}) {\n const [value, setValue] = React.useState<TimeResult>(() => initialValue);\n\n useEffectWithoutFirstRender(() => {\n onChange(value);\n }, [value]);\n\n return (\n <div data-test-id=\"date-editor\" className={styles.root}>\n <DatepickerInput\n disabled={disabled}\n value={value.date}\n onChange={(date) => {\n setValue((value) => ({\n ...value,\n date,\n }));\n }}\n />\n {usesTime && (\n <>\n <div className={styles.separator} />\n <TimepickerInput\n disabled={disabled}\n time={value.time}\n ampm={value.ampm}\n onChange={({ time, ampm }) => {\n setValue((value) => ({\n ...value,\n time,\n ampm,\n }));\n }}\n uses12hClock={uses12hClock}\n />\n </>\n )}\n {usesTimezone && (\n <>\n <div className={styles.separator} />\n <TimezonepickerInput\n disabled={disabled}\n value={value.utcOffset}\n onChange={(utcOffset) => {\n setValue((value) => ({\n ...value,\n utcOffset,\n }));\n }}\n />\n </>\n )}\n {hasClear && (\n <>\n <div className={styles.separator} />\n <TextLink\n as=\"button\"\n isDisabled={disabled}\n testId=\"date-clear\"\n onClick={() => {\n setValue({\n date: undefined,\n time: undefined,\n ampm: getDefaultAMPM(),\n utcOffset: getDefaultUtcOffset(),\n });\n }}>\n Clear\n </TextLink>\n </>\n )}\n </div>\n );\n}\n\nexport function DateEditor(props: DateEditorProps) {\n const { field, parameters } = props;\n\n const formatParam = parameters?.instance?.format ?? 'timeZ';\n const ampmParam = parameters?.instance?.ampm ?? '24';\n\n const usesTime = formatParam !== 'dateonly';\n const usesTimezone = formatParam === 'timeZ';\n const uses12hClock = ampmParam === '12';\n\n return (\n <FieldConnector<string>\n field={field}\n isInitiallyDisabled={props.isInitiallyDisabled}\n isDisabled={props.isDisabled}\n throttle={0}>\n {({ value, disabled, setValue, externalReset }) => {\n const datetimeValue = userInputFromDatetime({\n value,\n uses12hClock,\n });\n return (\n <DateEditorContainer\n initialValue={datetimeValue}\n uses12hClock={uses12hClock}\n usesTimezone={usesTimezone}\n usesTime={usesTime}\n disabled={disabled}\n hasClear={Boolean(value)}\n onChange={(data) => {\n const fieldValue = buildFieldValue({ data, usesTime, usesTimezone });\n if (fieldValue.invalid) {\n return;\n }\n // if value is present - then override it with a new one\n // if value is not present - then set a new one if it's not nullable only\n if (Boolean(value) || (!value && Boolean(fieldValue.valid))) {\n setValue(fieldValue.valid);\n }\n }}\n key={`date-container-${externalReset}`}\n />\n );\n }}\n </FieldConnector>\n );\n}\n\nDateEditor.defaultProps = {\n isInitiallyDisabled: true,\n};\n"],"names":["YEAR_RANGE","styles","root","css","maxWidth","DatepickerInput","props","useMemo","fromDate","Date","setFullYear","getFullYear","toDate","dateObj","value","toObject","selectedDate","years","months","date","undefined","React","Datepicker","className","selected","onSelect","day","momentDay","moment","onChange","inputProps","isDisabled","disabled","placeholder","validInputFormats","parseRawInput","raw","time","i","length","isValid","getDefaultTime","formatToString","uses12hClock","format","TimepickerInput","ampm","useState","selectedTime","setSelectedTime","useEffect","handleChange","useCallback","e","currentTarget","handleFocus","preventDefault","target","select","handleBlur","parsedTime","Flex","width","TextInput","testId","onFocus","onBlur","defaultZoneOffset","zoneOffsets","TimezonepickerInput","Select","map","offset","Option","key","ZONE_RX","startOfToday","set","hours","minutes","fieldValueToMoment","datetimeString","datetime","test","utcOffset","timeFromUserInput","input","timeInput","utc","datetimeFromUserInput","valid","parseZone","invalid","buildFieldValue","data","usesTime","usesTimezone","getDefaultAMPM","getDefaultUtcOffset","userInputFromDatetime","timeFormat","display","alignItems","separator","marginLeft","tokens","spacingM","useEffectWithoutFirstRender","callback","deps","isFirstRun","current","DateEditorContainer","initialValue","hasClear","setValue","TextLink","as","onClick","DateEditor","field","parameters","formatParam","instance","ampmParam","FieldConnector","isInitiallyDisabled","throttle","externalReset","datetimeValue","Boolean","fieldValue","defaultProps"],"mappings":"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"}
@@ -1,2 +0,0 @@
1
- "use strict";function e(e){return e&&"object"==typeof e&&"default"in e?e.default:e}Object.defineProperty(exports,"__esModule",{value:!0});var t=require("react"),n=e(t),a=require("@contentful/f36-components"),r=e(require("@contentful/f36-tokens")),i=require("@contentful/field-editor-shared"),l=require("emotion"),u=e(require("moment"));function o(){return(o=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var a in n)Object.prototype.hasOwnProperty.call(n,a)&&(e[a]=n[a])}return e}).apply(this,arguments)}var s={root:l.css({maxWidth:"270px"})},m=function(e){var r,i=t.useMemo((function(){var e=new Date;e.setFullYear(e.getFullYear()-100);var t=new Date;return t.setFullYear(t.getFullYear()+100),[e,t]}),[]),l=i[0],o=i[1],m=null==(r=e.value)?void 0:r.toObject(),c=m?new Date(m.years,m.months,m.date):void 0;return n.createElement(a.Datepicker,{className:s.root,selected:c,onSelect:function(t){var n=t?u(t):void 0;e.onChange(n)},inputProps:{isDisabled:e.disabled,placeholder:""},fromDate:l,toDate:o})},c=["hh:mm a","hh:mm A","h:mm a","h:mm A","hh:mm","k:mm","kk:mm","h a","h A","h","hh","HH"],d=function(){return u("12:00 AM","hh:mm A")},f=function(e,t){return t.format(e?"hh:mm A":"HH:mm")},v=function(e){var r=e.disabled,i=e.uses12hClock,o=e.time,s=void 0===o?"12:00":o,m=e.ampm,v=void 0===m?"AM":m,h=e.onChange,p=t.useState((function(){return f(i,d())})),b=p[0],g=p[1];t.useEffect((function(){g(f(i,u(s+" "+v,"hh:mm A")))}),[s,v,i]);var C=t.useCallback((function(e){g(e.currentTarget.value)}),[]),D=t.useCallback((function(e){e.preventDefault(),e.target.select()}),[]);return n.createElement(a.Flex,{className:l.css({width:"145px"})},n.createElement(a.TextInput,{"aria-label":"Select time",placeholder:i?"12:00 AM":"00:00","date-time-type":i?"12":"24",testId:"time-input",value:b,isDisabled:r,onFocus:D,onBlur:function(){var e=function(e){for(var t=null,n=0;n<c.length;n++){var a=u(e,c[n]);if(a.isValid()){t=a;break}}return t}(b),t=null!=e?e:d();g(f(i,t)),h({time:t.format("hh:mm"),ampm:t.format("A")})},onChange:C}))},h=["-12:00","-11:00","-10:00","-09:30","-09:00","-08:00","-07:00","-06:00","-05:00","-04:30","-04:00","-03:30","-03:00","-02:00","-01:00","+00:00","+01:00","+02:00","+03:00","+03:30","+04:00","+04:30","+05:00","+05:30","+05:45","+06:00","+06:30","+07:00","+08:00","+08:45","+09:00","+09:30","+10:00","+10:30","+11:00","+11:30","+12:00","+12:45","+13:00","+14:00"],p=function(e){var t=e.onChange,r=e.value;return n.createElement(a.Select,{"aria-label":"Select timezone",testId:"timezone-input",value:void 0===r?"+00:00":r,isDisabled:e.disabled,onChange:function(e){t(e.currentTarget.value)}},h.map((function(e){return n.createElement(a.Select.Option,{key:e,value:e},"UTC",e)})))},b=/(Z|[+-]\d{2}[:+]?\d{2})$/;function g(){return u().set({hours:0,minutes:0}).format("Z")}var C={root:l.css({display:"flex",alignItems:"center"}),separator:l.css({marginLeft:r.spacingM})};function D(e){var n,r,i,l=e.initialValue,u=e.usesTime,s=e.usesTimezone,c=e.uses12hClock,d=e.disabled,f=e.hasClear,h=e.onChange,b=t.useState((function(){return l})),D=b[0],E=b[1];return n=function(){h(D)},r=[D],i=t.useRef(!0),t.useEffect((function(){i.current?i.current=!1:n()}),r),t.createElement("div",{"data-test-id":"date-editor",className:C.root},t.createElement(m,{disabled:d,value:D.date,onChange:function(e){E((function(t){return o({},t,{date:e})}))}}),u&&t.createElement(t.Fragment,null,t.createElement("div",{className:C.separator}),t.createElement(v,{disabled:d,time:D.time,ampm:D.ampm,onChange:function(e){var t=e.time,n=e.ampm;E((function(e){return o({},e,{time:t,ampm:n})}))},uses12hClock:c})),s&&t.createElement(t.Fragment,null,t.createElement("div",{className:C.separator}),t.createElement(p,{disabled:d,value:D.utcOffset,onChange:function(e){E((function(t){return o({},t,{utcOffset:e})}))}})),f&&t.createElement(t.Fragment,null,t.createElement("div",{className:C.separator}),t.createElement(a.TextLink,{as:"button",isDisabled:d,testId:"date-clear",onClick:function(){E({date:void 0,time:void 0,ampm:"AM",utcOffset:g()})}},"Clear")))}function E(e){var n,a,r,l,o=e.parameters,s=null!=(n=null==o||null==(a=o.instance)?void 0:a.format)?n:"timeZ",m=null!=(r=null==o||null==(l=o.instance)?void 0:l.ampm)?r:"24",c="dateonly"!==s,d="timeZ"===s,f="12"===m;return t.createElement(i.FieldConnector,{field:e.field,isInitiallyDisabled:e.isInitiallyDisabled,isDisabled:e.isDisabled,throttle:0},(function(e){var n=e.value,a=e.disabled,r=e.setValue,i=e.externalReset,l=function(e){var t=e.uses12hClock,n=function(e){if(!e)return null;var t=u(e);return b.test(e)&&t.utcOffset(e),t}(e.value);return n?{date:n,time:n.format(t?"hh:mm":"HH:mm"),ampm:n.format("A"),utcOffset:n.format("Z")}:{ampm:"AM",utcOffset:g()}}({value:n,uses12hClock:f});return t.createElement(D,{initialValue:l,uses12hClock:f,usesTimezone:d,usesTime:c,disabled:a,hasClear:Boolean(n),onChange:function(e){var t=function(e){var t=e.usesTime,n=e.usesTimezone,a=function(e){if(!e.date)return{valid:null};var t=function(e){return u.utc((e.time||"00:00")+"!"+e.ampm,"HH:mm!A")}(e),n=u.parseZone(e.utcOffset,"Z").set(e.date.toObject()).set({hours:t.hours(),minutes:t.minutes()});return n.isValid()?{valid:n}:{invalid:!0,valid:null}}(e.data);return a.invalid?{invalid:!0}:{valid:null!=a&&a.valid?a.valid.format(n?"YYYY-MM-DDTHH:mmZ":t?"YYYY-MM-DDTHH:mm":"YYYY-MM-DD"):null,invalid:!1}}({data:e,usesTime:c,usesTimezone:d});t.invalid||(Boolean(n)||!n&&Boolean(t.valid))&&r(t.valid)},key:"date-container-"+i})}))}E.defaultProps={isInitiallyDisabled:!0},exports.DateEditor=E,exports.zoneOffsets=h;
2
- //# sourceMappingURL=field-editor-date.cjs.production.min.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"field-editor-date.cjs.production.min.js","sources":["../src/DatepickerInput.tsx","../src/TimepickerInput.tsx","../src/utils/zoneOffsets.ts","../src/TimezonePickerInput.tsx","../src/utils/date.ts","../src/DateEditor.tsx"],"sourcesContent":["import React, { useMemo } from 'react';\n\nimport { Datepicker } from '@contentful/f36-components';\nimport { css } from 'emotion';\n// eslint-disable-next-line -- TODO: move to date-fns\nimport moment from 'moment';\n\nconst YEAR_RANGE = 100;\n\nconst styles = {\n root: css({\n maxWidth: '270px',\n }),\n};\n\nexport type DatePickerProps = {\n value?: moment.Moment;\n onChange: (val: moment.Moment | undefined) => void;\n disabled?: boolean;\n};\n\nexport const DatepickerInput = (props: DatePickerProps) => {\n const [fromDate, toDate] = useMemo(() => {\n const fromDate = new Date();\n fromDate.setFullYear(fromDate.getFullYear() - YEAR_RANGE);\n const toDate = new Date();\n toDate.setFullYear(toDate.getFullYear() + YEAR_RANGE);\n\n return [fromDate, toDate];\n }, []);\n\n // The DatepickerInput should be time and timezone agnostic,\n // thats why we don't use moment().toDate() to get Date object.\n // moment().toDate() takes into account time and timezone and converts it\n // based on your system timezone which can result in the date change.\n // e.g. if user has a timezone +02:00, moment('2022-09-16T00:00+04:00').toDate()\n // will return September 15 instead of September 16\n const dateObj = props.value?.toObject();\n const selectedDate = dateObj ? new Date(dateObj.years, dateObj.months, dateObj.date) : undefined;\n\n return (\n <Datepicker\n className={styles.root}\n selected={selectedDate}\n onSelect={(day) => {\n const momentDay = day ? moment(day) : undefined;\n props.onChange(momentDay);\n }}\n inputProps={{ isDisabled: props.disabled, placeholder: '' }}\n fromDate={fromDate}\n toDate={toDate}\n />\n );\n};\n","import React, { useState, useCallback, useEffect } from 'react';\n// eslint-disable-next-line -- TODO: move to date-fns\nimport moment from 'moment';\nimport { css } from 'emotion';\n\nimport { TextInput, Flex } from '@contentful/f36-components';\n\nexport type TimepickerProps = {\n disabled: boolean;\n uses12hClock: boolean;\n onChange: (value: { time: string; ampm: string }) => void;\n time?: string;\n ampm?: string;\n};\n\nconst validInputFormats = [\n 'hh:mm a',\n 'hh:mm A',\n 'h:mm a',\n 'h:mm A',\n 'hh:mm',\n 'k:mm',\n 'kk:mm',\n 'h a',\n 'h A',\n 'h',\n 'hh',\n 'HH',\n];\n\nfunction parseRawInput(raw: string): moment.Moment | null {\n let time: moment.Moment | null = null;\n\n // eslint-disable-next-line -- TODO: refactor to use for of loop\n for (let i = 0; i < validInputFormats.length; i++) {\n const date = moment(raw, validInputFormats[i]);\n if (date.isValid()) {\n time = date;\n break;\n }\n }\n\n return time;\n}\n\nconst getDefaultTime = () => {\n return moment(`12:00 AM`, 'hh:mm A');\n};\n\nconst formatToString = (uses12hClock: boolean, value: moment.Moment): string => {\n return uses12hClock ? value.format('hh:mm A') : value.format('HH:mm');\n};\n\nexport const TimepickerInput = ({\n disabled,\n uses12hClock,\n time = '12:00',\n ampm = 'AM',\n onChange,\n}: TimepickerProps) => {\n const [selectedTime, setSelectedTime] = useState<string>(() => {\n return formatToString(uses12hClock, getDefaultTime());\n });\n\n useEffect(() => {\n setSelectedTime(formatToString(uses12hClock, moment(`${time} ${ampm}`, 'hh:mm A')));\n }, [time, ampm, uses12hClock]);\n\n const handleChange = useCallback((e: React.ChangeEvent<HTMLInputElement>) => {\n setSelectedTime(e.currentTarget.value);\n }, []);\n\n const handleFocus = useCallback((e) => {\n e.preventDefault();\n e.target.select();\n }, []);\n\n const handleBlur = () => {\n const parsedTime = parseRawInput(selectedTime);\n const value = parsedTime ?? getDefaultTime();\n setSelectedTime(formatToString(uses12hClock, value));\n onChange({ time: value.format('hh:mm'), ampm: value.format('A') });\n };\n\n return (\n <Flex className={css({ width: '145px' })}>\n <TextInput\n aria-label=\"Select time\"\n placeholder={uses12hClock ? '12:00 AM' : '00:00'}\n date-time-type={uses12hClock ? '12' : '24'}\n testId=\"time-input\"\n value={selectedTime}\n isDisabled={disabled}\n onFocus={handleFocus}\n onBlur={handleBlur}\n onChange={handleChange}\n />\n </Flex>\n );\n};\n","export const defaultZoneOffset = '+00:00';\n\nexport const zoneOffsets = [\n '-12:00',\n '-11:00',\n '-10:00',\n '-09:30',\n '-09:00',\n '-08:00',\n '-07:00',\n '-06:00',\n '-05:00',\n '-04:30',\n '-04:00',\n '-03:30',\n '-03:00',\n '-02:00',\n '-01:00',\n '+00:00',\n '+01:00',\n '+02:00',\n '+03:00',\n '+03:30',\n '+04:00',\n '+04:30',\n '+05:00',\n '+05:30',\n '+05:45',\n '+06:00',\n '+06:30',\n '+07:00',\n '+08:00',\n '+08:45',\n '+09:00',\n '+09:30',\n '+10:00',\n '+10:30',\n '+11:00',\n '+11:30',\n '+12:00',\n '+12:45',\n '+13:00',\n '+14:00',\n];\n","import React, { ChangeEvent } from 'react';\nimport { zoneOffsets, defaultZoneOffset } from './utils/zoneOffsets';\n\nimport { Select } from '@contentful/f36-components';\n\nexport type TimezonepickerProps = {\n disabled: boolean;\n onChange: (value: string) => void;\n value?: string;\n};\nexport const TimezonepickerInput = ({\n disabled,\n onChange,\n value = defaultZoneOffset,\n}: TimezonepickerProps) => {\n return (\n <Select\n aria-label=\"Select timezone\"\n testId=\"timezone-input\"\n value={value}\n isDisabled={disabled}\n onChange={(e: ChangeEvent<HTMLSelectElement>) => {\n onChange(e.currentTarget.value);\n }}>\n {zoneOffsets.map((offset) => (\n <Select.Option key={offset} value={offset}>\n UTC{offset}\n </Select.Option>\n ))}\n </Select>\n );\n};\n","// eslint-disable-next-line -- TODO: move to date-fns\nimport moment from 'moment';\nimport { TimeResult } from '../types';\n\nconst ZONE_RX = /(Z|[+-]\\d{2}[:+]?\\d{2})$/;\n\nfunction startOfToday(format: string) {\n return moment().set({ hours: 0, minutes: 0 }).format(format);\n}\n\nfunction fieldValueToMoment(datetimeString: string | null | undefined): moment.Moment | null {\n if (!datetimeString) {\n return null;\n }\n\n const datetime = moment(datetimeString);\n if (ZONE_RX.test(datetimeString)) {\n datetime.utcOffset(datetimeString);\n }\n return datetime;\n}\n\nfunction timeFromUserInput(input: TimeResult) {\n const timeInput = input.time || '00:00';\n return moment.utc(timeInput + '!' + input.ampm, 'HH:mm!A');\n}\n\n/**\n * Convert the user input object into either a 'moment' value or an\n * invalid symbol.\n *\n * Success is indicated by returning '{valid: value}' and failure is\n * indicated by returning '{invalid: true}'. If 'input.date' is\n * 'null' we return '{valid: null}'\n */\nfunction datetimeFromUserInput(input: TimeResult): {\n invalid?: boolean;\n valid: moment.Moment | null;\n} {\n if (!input.date) {\n return { valid: null };\n }\n\n const time = timeFromUserInput(input);\n\n const date = moment\n .parseZone(input.utcOffset, 'Z')\n .set(input.date.toObject())\n .set({ hours: time.hours(), minutes: time.minutes() });\n\n if (date.isValid()) {\n return { valid: date };\n } else {\n return { invalid: true, valid: null };\n }\n}\n\n/**\n * Parse user input into a string that is stored in the API.\n *\n * Returns a sum type with either the string as the `valid` property\n * or the `invalid` property set to `false`.\n */\nexport function buildFieldValue({\n data,\n usesTime,\n usesTimezone,\n}: {\n data: TimeResult;\n usesTime: boolean;\n usesTimezone: boolean;\n}) {\n const date = datetimeFromUserInput(data);\n if (date.invalid) {\n return {\n invalid: true,\n };\n }\n\n let format;\n if (usesTimezone) {\n format = 'YYYY-MM-DDTHH:mmZ';\n } else if (usesTime) {\n format = 'YYYY-MM-DDTHH:mm';\n } else {\n format = 'YYYY-MM-DD';\n }\n return { valid: date?.valid ? date.valid.format(format) : null, invalid: false };\n}\n\nexport function getDefaultAMPM() {\n return 'AM';\n}\n\nexport function getDefaultUtcOffset() {\n return startOfToday('Z');\n}\n\n/**\n * Create the user input object from the field value.\n */\nexport function userInputFromDatetime({\n value,\n uses12hClock,\n}: {\n value: string | undefined | null;\n uses12hClock: boolean;\n}): TimeResult {\n const datetime = fieldValueToMoment(value);\n\n if (datetime) {\n const timeFormat = uses12hClock ? 'hh:mm' : 'HH:mm';\n return {\n date: datetime,\n time: datetime.format(timeFormat),\n ampm: datetime.format('A'),\n utcOffset: datetime.format('Z'),\n };\n } else {\n return {\n ampm: getDefaultAMPM(),\n utcOffset: getDefaultUtcOffset(),\n };\n }\n}\n","import * as React from 'react';\n\nimport { TextLink } from '@contentful/f36-components';\nimport tokens from '@contentful/f36-tokens';\nimport { FieldAPI, FieldConnector, ParametersAPI } from '@contentful/field-editor-shared';\nimport { css } from 'emotion';\n\nimport { DatepickerInput } from './DatepickerInput';\nimport { TimepickerInput } from './TimepickerInput';\nimport { TimezonepickerInput } from './TimezonePickerInput';\nimport { TimeFormat, DateTimeFormat, TimeResult } from './types';\nimport {\n userInputFromDatetime,\n buildFieldValue,\n getDefaultAMPM,\n getDefaultUtcOffset,\n} from './utils/date';\n\nexport interface DateEditorProps {\n /**\n * is the field disabled initially\n */\n isInitiallyDisabled: boolean;\n\n /*\n * is the field manually disabled\n */\n isDisabled?: boolean;\n\n /**\n * sdk.field\n */\n field: FieldAPI;\n\n /**\n * sdk.parameters\n */\n parameters?: ParametersAPI & {\n instance?: {\n format?: DateTimeFormat;\n ampm?: TimeFormat;\n };\n };\n}\n\nconst styles = {\n root: css({\n display: 'flex',\n alignItems: 'center',\n }),\n separator: css({\n marginLeft: tokens.spacingM,\n }),\n};\n\nfunction useEffectWithoutFirstRender(callback: Function, deps: Array<any>) {\n const isFirstRun = React.useRef(true);\n React.useEffect(() => {\n if (isFirstRun.current) {\n isFirstRun.current = false;\n return;\n }\n callback();\n // eslint-disable-next-line react-hooks/exhaustive-deps -- TODO: Evaluate the dependencies\n }, deps);\n}\n\nfunction DateEditorContainer({\n initialValue,\n usesTime,\n usesTimezone,\n uses12hClock,\n disabled,\n hasClear,\n onChange,\n}: {\n initialValue: TimeResult;\n usesTime: boolean;\n usesTimezone: boolean;\n uses12hClock: boolean;\n disabled: boolean;\n hasClear: boolean;\n onChange: (value: TimeResult) => void;\n}) {\n const [value, setValue] = React.useState<TimeResult>(() => initialValue);\n\n useEffectWithoutFirstRender(() => {\n onChange(value);\n }, [value]);\n\n return (\n <div data-test-id=\"date-editor\" className={styles.root}>\n <DatepickerInput\n disabled={disabled}\n value={value.date}\n onChange={(date) => {\n setValue((value) => ({\n ...value,\n date,\n }));\n }}\n />\n {usesTime && (\n <>\n <div className={styles.separator} />\n <TimepickerInput\n disabled={disabled}\n time={value.time}\n ampm={value.ampm}\n onChange={({ time, ampm }) => {\n setValue((value) => ({\n ...value,\n time,\n ampm,\n }));\n }}\n uses12hClock={uses12hClock}\n />\n </>\n )}\n {usesTimezone && (\n <>\n <div className={styles.separator} />\n <TimezonepickerInput\n disabled={disabled}\n value={value.utcOffset}\n onChange={(utcOffset) => {\n setValue((value) => ({\n ...value,\n utcOffset,\n }));\n }}\n />\n </>\n )}\n {hasClear && (\n <>\n <div className={styles.separator} />\n <TextLink\n as=\"button\"\n isDisabled={disabled}\n testId=\"date-clear\"\n onClick={() => {\n setValue({\n date: undefined,\n time: undefined,\n ampm: getDefaultAMPM(),\n utcOffset: getDefaultUtcOffset(),\n });\n }}>\n Clear\n </TextLink>\n </>\n )}\n </div>\n );\n}\n\nexport function DateEditor(props: DateEditorProps) {\n const { field, parameters } = props;\n\n const formatParam = parameters?.instance?.format ?? 'timeZ';\n const ampmParam = parameters?.instance?.ampm ?? '24';\n\n const usesTime = formatParam !== 'dateonly';\n const usesTimezone = formatParam === 'timeZ';\n const uses12hClock = ampmParam === '12';\n\n return (\n <FieldConnector<string>\n field={field}\n isInitiallyDisabled={props.isInitiallyDisabled}\n isDisabled={props.isDisabled}\n throttle={0}>\n {({ value, disabled, setValue, externalReset }) => {\n const datetimeValue = userInputFromDatetime({\n value,\n uses12hClock,\n });\n return (\n <DateEditorContainer\n initialValue={datetimeValue}\n uses12hClock={uses12hClock}\n usesTimezone={usesTimezone}\n usesTime={usesTime}\n disabled={disabled}\n hasClear={Boolean(value)}\n onChange={(data) => {\n const fieldValue = buildFieldValue({ data, usesTime, usesTimezone });\n if (fieldValue.invalid) {\n return;\n }\n // if value is present - then override it with a new one\n // if value is not present - then set a new one if it's not nullable only\n if (Boolean(value) || (!value && Boolean(fieldValue.valid))) {\n setValue(fieldValue.valid);\n }\n }}\n key={`date-container-${externalReset}`}\n />\n );\n }}\n </FieldConnector>\n );\n}\n\nDateEditor.defaultProps = {\n isInitiallyDisabled: true,\n};\n"],"names":["styles","root","css","maxWidth","DatepickerInput","props","useMemo","fromDate","Date","setFullYear","getFullYear","toDate","dateObj","value","_props$value","toObject","selectedDate","years","months","date","undefined","React","Datepicker","className","selected","onSelect","day","momentDay","moment","onChange","inputProps","isDisabled","disabled","placeholder","validInputFormats","getDefaultTime","formatToString","uses12hClock","format","TimepickerInput","time","ampm","useState","selectedTime","setSelectedTime","useEffect","handleChange","useCallback","e","currentTarget","handleFocus","preventDefault","target","select","Flex","width","TextInput","testId","onFocus","onBlur","parsedTime","raw","i","length","isValid","parseRawInput","zoneOffsets","TimezonepickerInput","Select","map","offset","Option","key","ZONE_RX","getDefaultUtcOffset","set","hours","minutes","display","alignItems","separator","marginLeft","tokens","spacingM","DateEditorContainer","callback","deps","isFirstRun","initialValue","usesTime","usesTimezone","hasClear","setValue","current","utcOffset","TextLink","as","onClick","DateEditor","parameters","formatParam","instance","_parameters$instance","ampmParam","_parameters$instance2","FieldConnector","field","isInitiallyDisabled","throttle","externalReset","datetimeValue","datetime","datetimeString","test","fieldValueToMoment","userInputFromDatetime","Boolean","data","fieldValue","input","valid","utc","timeFromUserInput","parseZone","invalid","datetimeFromUserInput","buildFieldValue","defaultProps"],"mappings":"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"}