@instructure/ui-date-input 10.18.2-snapshot-3 → 10.18.2-snapshot-5
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 +5 -2
- package/es/DateInput2/index.js +13 -34
- package/lib/DateInput2/index.js +13 -34
- package/package.json +20 -20
- package/src/DateInput2/index.tsx +12 -38
- package/tsconfig.build.tsbuildinfo +1 -1
- package/types/DateInput2/index.d.ts.map +1 -1
package/CHANGELOG.md
CHANGED
@@ -3,9 +3,12 @@
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
4
4
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
5
5
|
|
6
|
-
## [10.18.2-snapshot-
|
6
|
+
## [10.18.2-snapshot-5](https://github.com/instructure/instructure-ui/compare/v10.18.1...v10.18.2-snapshot-5) (2025-06-03)
|
7
7
|
|
8
|
-
|
8
|
+
|
9
|
+
### Bug Fixes
|
10
|
+
|
11
|
+
* **ui-date-input:** make DateInput2 date parsing work in every locale and timezone ([7d2ed73](https://github.com/instructure/instructure-ui/commit/7d2ed732a4b8608b6fc29996e416b51ac25faf0c))
|
9
12
|
|
10
13
|
|
11
14
|
|
package/es/DateInput2/index.js
CHANGED
@@ -24,14 +24,14 @@ var _IconCalendarMonthLin, _IconArrowOpenEndSoli, _IconArrowOpenStartSo;
|
|
24
24
|
* SOFTWARE.
|
25
25
|
*/
|
26
26
|
|
27
|
-
import { useState, useEffect,
|
27
|
+
import { useState, useEffect, forwardRef } from 'react';
|
28
28
|
import { Calendar } from '@instructure/ui-calendar';
|
29
29
|
import { IconButton } from '@instructure/ui-buttons';
|
30
30
|
import { IconCalendarMonthLine, IconArrowOpenEndSolid, IconArrowOpenStartSolid } from '@instructure/ui-icons';
|
31
31
|
import { Popover } from '@instructure/ui-popover';
|
32
32
|
import { TextInput } from '@instructure/ui-text-input';
|
33
33
|
import { callRenderProp, passthroughProps } from '@instructure/ui-react-utils';
|
34
|
-
import {
|
34
|
+
import { getLocale, getTimezone } from '@instructure/ui-i18n';
|
35
35
|
import { propTypes } from './props';
|
36
36
|
import { jsx as _jsx } from "@emotion/react/jsx-runtime";
|
37
37
|
function parseLocaleDate(dateString = '', locale, timeZone) {
|
@@ -70,10 +70,6 @@ function parseLocaleDate(dateString = '', locale, timeZone) {
|
|
70
70
|
|
71
71
|
// create utc date from year, month (zero indexed) and day
|
72
72
|
const date = new Date(Date.UTC(year, month - 1, day));
|
73
|
-
if (date.getMonth() !== month - 1 || date.getDate() !== day) {
|
74
|
-
// Check if the Date object adjusts the values. If it does, the input is invalid.
|
75
|
-
return null;
|
76
|
-
}
|
77
73
|
|
78
74
|
// Format date string in the provided timezone. The locale here is irrelevant, we only care about how to time is adjusted for the timezone.
|
79
75
|
const parts = new Intl.DateTimeFormat('en-US', {
|
@@ -135,25 +131,8 @@ const DateInput2 = /*#__PURE__*/forwardRef(({
|
|
135
131
|
inputRef,
|
136
132
|
...rest
|
137
133
|
}, ref) => {
|
138
|
-
const
|
139
|
-
const
|
140
|
-
if (locale) {
|
141
|
-
return locale;
|
142
|
-
} else if (localeContext.locale) {
|
143
|
-
return localeContext.locale;
|
144
|
-
}
|
145
|
-
// default to the system's locale
|
146
|
-
return Locale.browserLocale();
|
147
|
-
};
|
148
|
-
const getTimezone = () => {
|
149
|
-
if (timezone) {
|
150
|
-
return timezone;
|
151
|
-
} else if (localeContext.timezone) {
|
152
|
-
return localeContext.timezone;
|
153
|
-
}
|
154
|
-
// default to the system's timezone
|
155
|
-
return Intl.DateTimeFormat().resolvedOptions().timeZone;
|
156
|
-
};
|
134
|
+
const userLocale = locale || getLocale();
|
135
|
+
const userTimezone = timezone || getTimezone();
|
157
136
|
const _useState = useState(messages || []),
|
158
137
|
_useState2 = _slicedToArray(_useState, 2),
|
159
138
|
inputMessages = _useState2[0],
|
@@ -181,23 +160,23 @@ const DateInput2 = /*#__PURE__*/forwardRef(({
|
|
181
160
|
if (dateFormat) {
|
182
161
|
if (typeof dateFormat === 'string') {
|
183
162
|
// use dateFormat instead of the user locale
|
184
|
-
date = parseLocaleDate(dateString, dateFormat,
|
163
|
+
date = parseLocaleDate(dateString, dateFormat, userTimezone);
|
185
164
|
} else if (dateFormat.parser) {
|
186
165
|
date = dateFormat.parser(dateString);
|
187
166
|
}
|
188
167
|
} else {
|
189
168
|
// no dateFormat prop passed, use locale for formatting
|
190
|
-
date = parseLocaleDate(dateString,
|
169
|
+
date = parseLocaleDate(dateString, userLocale, userTimezone);
|
191
170
|
}
|
192
171
|
return date ? [formatDate(date), date.toISOString()] : ['', ''];
|
193
172
|
};
|
194
|
-
const formatDate = (date, timeZone =
|
173
|
+
const formatDate = (date, timeZone = userTimezone) => {
|
195
174
|
// use formatter function if provided
|
196
175
|
if (typeof dateFormat !== 'string' && dateFormat !== null && dateFormat !== void 0 && dateFormat.formatter) {
|
197
176
|
return dateFormat.formatter(date);
|
198
177
|
}
|
199
178
|
// if dateFormat set to a locale, use that, otherwise default to the user's locale
|
200
|
-
return date.toLocaleDateString(typeof dateFormat === 'string' ? dateFormat :
|
179
|
+
return date.toLocaleDateString(typeof dateFormat === 'string' ? dateFormat : userLocale, {
|
201
180
|
timeZone,
|
202
181
|
calendar: 'gregory',
|
203
182
|
numberingSystem: 'latn'
|
@@ -213,9 +192,9 @@ const DateInput2 = /*#__PURE__*/forwardRef(({
|
|
213
192
|
};
|
214
193
|
|
215
194
|
// Replace the matched number with the same number of dashes
|
216
|
-
const year =
|
217
|
-
const month =
|
218
|
-
const day =
|
195
|
+
const year = '2024';
|
196
|
+
const month = '9';
|
197
|
+
const day = '1';
|
219
198
|
return formattedDate.replace(regex(year), match => 'Y'.repeat(match.length)).replace(regex(month), match => 'M'.repeat(match.length)).replace(regex(day), match => 'D'.repeat(match.length));
|
220
199
|
};
|
221
200
|
const handleInputChange = (e, newValue) => {
|
@@ -286,8 +265,8 @@ const DateInput2 = /*#__PURE__*/forwardRef(({
|
|
286
265
|
selectedDate: selectedDate,
|
287
266
|
disabledDates: disabledDates,
|
288
267
|
visibleMonth: selectedDate,
|
289
|
-
locale:
|
290
|
-
timezone:
|
268
|
+
locale: userLocale,
|
269
|
+
timezone: userTimezone,
|
291
270
|
renderNextMonthButton: _jsx(IconButton, {
|
292
271
|
size: "small",
|
293
272
|
withBackground: false,
|
package/lib/DateInput2/index.js
CHANGED
@@ -16,8 +16,8 @@ var _Popover = require("@instructure/ui-popover/lib/Popover");
|
|
16
16
|
var _TextInput = require("@instructure/ui-text-input/lib/TextInput");
|
17
17
|
var _callRenderProp = require("@instructure/ui-react-utils/lib/callRenderProp.js");
|
18
18
|
var _passthroughProps = require("@instructure/ui-react-utils/lib/passthroughProps.js");
|
19
|
-
var
|
20
|
-
var
|
19
|
+
var _getLocale = require("@instructure/ui-i18n/lib/getLocale.js");
|
20
|
+
var _getTimezone = require("@instructure/ui-i18n/lib/getTimezone.js");
|
21
21
|
var _props = require("./props");
|
22
22
|
var _jsxRuntime = require("@emotion/react/jsx-runtime");
|
23
23
|
var _IconCalendarMonthLin, _IconArrowOpenEndSoli, _IconArrowOpenStartSo;
|
@@ -80,10 +80,6 @@ function parseLocaleDate(dateString = '', locale, timeZone) {
|
|
80
80
|
|
81
81
|
// create utc date from year, month (zero indexed) and day
|
82
82
|
const date = new Date(Date.UTC(year, month - 1, day));
|
83
|
-
if (date.getMonth() !== month - 1 || date.getDate() !== day) {
|
84
|
-
// Check if the Date object adjusts the values. If it does, the input is invalid.
|
85
|
-
return null;
|
86
|
-
}
|
87
83
|
|
88
84
|
// Format date string in the provided timezone. The locale here is irrelevant, we only care about how to time is adjusted for the timezone.
|
89
85
|
const parts = new Intl.DateTimeFormat('en-US', {
|
@@ -145,25 +141,8 @@ const DateInput2 = exports.DateInput2 = /*#__PURE__*/(0, _react.forwardRef)(({
|
|
145
141
|
inputRef,
|
146
142
|
...rest
|
147
143
|
}, ref) => {
|
148
|
-
const
|
149
|
-
const
|
150
|
-
if (locale) {
|
151
|
-
return locale;
|
152
|
-
} else if (localeContext.locale) {
|
153
|
-
return localeContext.locale;
|
154
|
-
}
|
155
|
-
// default to the system's locale
|
156
|
-
return _Locale.Locale.browserLocale();
|
157
|
-
};
|
158
|
-
const getTimezone = () => {
|
159
|
-
if (timezone) {
|
160
|
-
return timezone;
|
161
|
-
} else if (localeContext.timezone) {
|
162
|
-
return localeContext.timezone;
|
163
|
-
}
|
164
|
-
// default to the system's timezone
|
165
|
-
return Intl.DateTimeFormat().resolvedOptions().timeZone;
|
166
|
-
};
|
144
|
+
const userLocale = locale || (0, _getLocale.getLocale)();
|
145
|
+
const userTimezone = timezone || (0, _getTimezone.getTimezone)();
|
167
146
|
const _useState = (0, _react.useState)(messages || []),
|
168
147
|
_useState2 = (0, _slicedToArray2.default)(_useState, 2),
|
169
148
|
inputMessages = _useState2[0],
|
@@ -191,23 +170,23 @@ const DateInput2 = exports.DateInput2 = /*#__PURE__*/(0, _react.forwardRef)(({
|
|
191
170
|
if (dateFormat) {
|
192
171
|
if (typeof dateFormat === 'string') {
|
193
172
|
// use dateFormat instead of the user locale
|
194
|
-
date = parseLocaleDate(dateString, dateFormat,
|
173
|
+
date = parseLocaleDate(dateString, dateFormat, userTimezone);
|
195
174
|
} else if (dateFormat.parser) {
|
196
175
|
date = dateFormat.parser(dateString);
|
197
176
|
}
|
198
177
|
} else {
|
199
178
|
// no dateFormat prop passed, use locale for formatting
|
200
|
-
date = parseLocaleDate(dateString,
|
179
|
+
date = parseLocaleDate(dateString, userLocale, userTimezone);
|
201
180
|
}
|
202
181
|
return date ? [formatDate(date), date.toISOString()] : ['', ''];
|
203
182
|
};
|
204
|
-
const formatDate = (date, timeZone =
|
183
|
+
const formatDate = (date, timeZone = userTimezone) => {
|
205
184
|
// use formatter function if provided
|
206
185
|
if (typeof dateFormat !== 'string' && dateFormat !== null && dateFormat !== void 0 && dateFormat.formatter) {
|
207
186
|
return dateFormat.formatter(date);
|
208
187
|
}
|
209
188
|
// if dateFormat set to a locale, use that, otherwise default to the user's locale
|
210
|
-
return date.toLocaleDateString(typeof dateFormat === 'string' ? dateFormat :
|
189
|
+
return date.toLocaleDateString(typeof dateFormat === 'string' ? dateFormat : userLocale, {
|
211
190
|
timeZone,
|
212
191
|
calendar: 'gregory',
|
213
192
|
numberingSystem: 'latn'
|
@@ -223,9 +202,9 @@ const DateInput2 = exports.DateInput2 = /*#__PURE__*/(0, _react.forwardRef)(({
|
|
223
202
|
};
|
224
203
|
|
225
204
|
// Replace the matched number with the same number of dashes
|
226
|
-
const year =
|
227
|
-
const month =
|
228
|
-
const day =
|
205
|
+
const year = '2024';
|
206
|
+
const month = '9';
|
207
|
+
const day = '1';
|
229
208
|
return formattedDate.replace(regex(year), match => 'Y'.repeat(match.length)).replace(regex(month), match => 'M'.repeat(match.length)).replace(regex(day), match => 'D'.repeat(match.length));
|
230
209
|
};
|
231
210
|
const handleInputChange = (e, newValue) => {
|
@@ -296,8 +275,8 @@ const DateInput2 = exports.DateInput2 = /*#__PURE__*/(0, _react.forwardRef)(({
|
|
296
275
|
selectedDate: selectedDate,
|
297
276
|
disabledDates: disabledDates,
|
298
277
|
visibleMonth: selectedDate,
|
299
|
-
locale:
|
300
|
-
timezone:
|
278
|
+
locale: userLocale,
|
279
|
+
timezone: userTimezone,
|
301
280
|
renderNextMonthButton: (0, _jsxRuntime.jsx)(_IconButton.IconButton, {
|
302
281
|
size: "small",
|
303
282
|
withBackground: false,
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "@instructure/ui-date-input",
|
3
|
-
"version": "10.18.2-snapshot-
|
3
|
+
"version": "10.18.2-snapshot-5",
|
4
4
|
"description": "A UI component library made by Instructure Inc.",
|
5
5
|
"author": "Instructure, Inc. Engineering and Product Design",
|
6
6
|
"module": "./es/index.js",
|
@@ -23,11 +23,11 @@
|
|
23
23
|
},
|
24
24
|
"license": "MIT",
|
25
25
|
"devDependencies": {
|
26
|
-
"@instructure/ui-axe-check": "10.18.2-snapshot-
|
27
|
-
"@instructure/ui-babel-preset": "10.18.2-snapshot-
|
28
|
-
"@instructure/ui-buttons": "10.18.2-snapshot-
|
29
|
-
"@instructure/ui-scripts": "10.18.2-snapshot-
|
30
|
-
"@instructure/ui-test-utils": "10.18.2-snapshot-
|
26
|
+
"@instructure/ui-axe-check": "10.18.2-snapshot-5",
|
27
|
+
"@instructure/ui-babel-preset": "10.18.2-snapshot-5",
|
28
|
+
"@instructure/ui-buttons": "10.18.2-snapshot-5",
|
29
|
+
"@instructure/ui-scripts": "10.18.2-snapshot-5",
|
30
|
+
"@instructure/ui-test-utils": "10.18.2-snapshot-5",
|
31
31
|
"@testing-library/jest-dom": "^6.6.3",
|
32
32
|
"@testing-library/react": "^16.0.1",
|
33
33
|
"@testing-library/user-event": "^14.5.2",
|
@@ -35,20 +35,20 @@
|
|
35
35
|
},
|
36
36
|
"dependencies": {
|
37
37
|
"@babel/runtime": "^7.26.0",
|
38
|
-
"@instructure/emotion": "10.18.2-snapshot-
|
39
|
-
"@instructure/shared-types": "10.18.2-snapshot-
|
40
|
-
"@instructure/ui-calendar": "10.18.2-snapshot-
|
41
|
-
"@instructure/ui-form-field": "10.18.2-snapshot-
|
42
|
-
"@instructure/ui-i18n": "10.18.2-snapshot-
|
43
|
-
"@instructure/ui-icons": "10.18.2-snapshot-
|
44
|
-
"@instructure/ui-popover": "10.18.2-snapshot-
|
45
|
-
"@instructure/ui-position": "10.18.2-snapshot-
|
46
|
-
"@instructure/ui-prop-types": "10.18.2-snapshot-
|
47
|
-
"@instructure/ui-react-utils": "10.18.2-snapshot-
|
48
|
-
"@instructure/ui-selectable": "10.18.2-snapshot-
|
49
|
-
"@instructure/ui-testable": "10.18.2-snapshot-
|
50
|
-
"@instructure/ui-text-input": "10.18.2-snapshot-
|
51
|
-
"@instructure/ui-utils": "10.18.2-snapshot-
|
38
|
+
"@instructure/emotion": "10.18.2-snapshot-5",
|
39
|
+
"@instructure/shared-types": "10.18.2-snapshot-5",
|
40
|
+
"@instructure/ui-calendar": "10.18.2-snapshot-5",
|
41
|
+
"@instructure/ui-form-field": "10.18.2-snapshot-5",
|
42
|
+
"@instructure/ui-i18n": "10.18.2-snapshot-5",
|
43
|
+
"@instructure/ui-icons": "10.18.2-snapshot-5",
|
44
|
+
"@instructure/ui-popover": "10.18.2-snapshot-5",
|
45
|
+
"@instructure/ui-position": "10.18.2-snapshot-5",
|
46
|
+
"@instructure/ui-prop-types": "10.18.2-snapshot-5",
|
47
|
+
"@instructure/ui-react-utils": "10.18.2-snapshot-5",
|
48
|
+
"@instructure/ui-selectable": "10.18.2-snapshot-5",
|
49
|
+
"@instructure/ui-testable": "10.18.2-snapshot-5",
|
50
|
+
"@instructure/ui-text-input": "10.18.2-snapshot-5",
|
51
|
+
"@instructure/ui-utils": "10.18.2-snapshot-5",
|
52
52
|
"moment-timezone": "^0.5.45",
|
53
53
|
"prop-types": "^15.8.1"
|
54
54
|
},
|
package/src/DateInput2/index.tsx
CHANGED
@@ -25,7 +25,6 @@
|
|
25
25
|
import {
|
26
26
|
useState,
|
27
27
|
useEffect,
|
28
|
-
useContext,
|
29
28
|
forwardRef,
|
30
29
|
ForwardedRef,
|
31
30
|
ValidationMap
|
@@ -41,8 +40,7 @@ import {
|
|
41
40
|
import { Popover } from '@instructure/ui-popover'
|
42
41
|
import { TextInput } from '@instructure/ui-text-input'
|
43
42
|
import { callRenderProp, passthroughProps } from '@instructure/ui-react-utils'
|
44
|
-
|
45
|
-
import { ApplyLocaleContext, Locale } from '@instructure/ui-i18n'
|
43
|
+
import { getLocale, getTimezone } from '@instructure/ui-i18n'
|
46
44
|
|
47
45
|
import { propTypes } from './props'
|
48
46
|
import type { DateInput2Props } from './props'
|
@@ -93,11 +91,6 @@ function parseLocaleDate(
|
|
93
91
|
// create utc date from year, month (zero indexed) and day
|
94
92
|
const date = new Date(Date.UTC(year, month - 1, day))
|
95
93
|
|
96
|
-
if (date.getMonth() !== month - 1 || date.getDate() !== day) {
|
97
|
-
// Check if the Date object adjusts the values. If it does, the input is invalid.
|
98
|
-
return null
|
99
|
-
}
|
100
|
-
|
101
94
|
// Format date string in the provided timezone. The locale here is irrelevant, we only care about how to time is adjusted for the timezone.
|
102
95
|
const parts = new Intl.DateTimeFormat('en-US', {
|
103
96
|
timeZone,
|
@@ -166,27 +159,8 @@ const DateInput2 = forwardRef(
|
|
166
159
|
}: DateInput2Props,
|
167
160
|
ref: ForwardedRef<TextInput>
|
168
161
|
) => {
|
169
|
-
const
|
170
|
-
|
171
|
-
const getLocale = () => {
|
172
|
-
if (locale) {
|
173
|
-
return locale
|
174
|
-
} else if (localeContext.locale) {
|
175
|
-
return localeContext.locale
|
176
|
-
}
|
177
|
-
// default to the system's locale
|
178
|
-
return Locale.browserLocale()
|
179
|
-
}
|
180
|
-
|
181
|
-
const getTimezone = () => {
|
182
|
-
if (timezone) {
|
183
|
-
return timezone
|
184
|
-
} else if (localeContext.timezone) {
|
185
|
-
return localeContext.timezone
|
186
|
-
}
|
187
|
-
// default to the system's timezone
|
188
|
-
return Intl.DateTimeFormat().resolvedOptions().timeZone
|
189
|
-
}
|
162
|
+
const userLocale = locale || getLocale()
|
163
|
+
const userTimezone = timezone || getTimezone()
|
190
164
|
|
191
165
|
const [inputMessages, setInputMessages] = useState<FormMessage[]>(
|
192
166
|
messages || []
|
@@ -213,20 +187,20 @@ const DateInput2 = forwardRef(
|
|
213
187
|
if (dateFormat) {
|
214
188
|
if (typeof dateFormat === 'string') {
|
215
189
|
// use dateFormat instead of the user locale
|
216
|
-
date = parseLocaleDate(dateString, dateFormat,
|
190
|
+
date = parseLocaleDate(dateString, dateFormat, userTimezone)
|
217
191
|
} else if (dateFormat.parser) {
|
218
192
|
date = dateFormat.parser(dateString)
|
219
193
|
}
|
220
194
|
} else {
|
221
195
|
// no dateFormat prop passed, use locale for formatting
|
222
|
-
date = parseLocaleDate(dateString,
|
196
|
+
date = parseLocaleDate(dateString, userLocale, userTimezone)
|
223
197
|
}
|
224
198
|
return date ? [formatDate(date), date.toISOString()] : ['', '']
|
225
199
|
}
|
226
200
|
|
227
201
|
const formatDate = (
|
228
202
|
date: Date,
|
229
|
-
timeZone: string =
|
203
|
+
timeZone: string = userTimezone
|
230
204
|
): string => {
|
231
205
|
// use formatter function if provided
|
232
206
|
if (typeof dateFormat !== 'string' && dateFormat?.formatter) {
|
@@ -234,7 +208,7 @@ const DateInput2 = forwardRef(
|
|
234
208
|
}
|
235
209
|
// if dateFormat set to a locale, use that, otherwise default to the user's locale
|
236
210
|
return date.toLocaleDateString(
|
237
|
-
typeof dateFormat === 'string' ? dateFormat :
|
211
|
+
typeof dateFormat === 'string' ? dateFormat : userLocale,
|
238
212
|
{
|
239
213
|
timeZone,
|
240
214
|
calendar: 'gregory',
|
@@ -253,9 +227,9 @@ const DateInput2 = forwardRef(
|
|
253
227
|
}
|
254
228
|
|
255
229
|
// Replace the matched number with the same number of dashes
|
256
|
-
const year =
|
257
|
-
const month =
|
258
|
-
const day =
|
230
|
+
const year = '2024'
|
231
|
+
const month = '9'
|
232
|
+
const day = '1'
|
259
233
|
return formattedDate
|
260
234
|
.replace(regex(year), (match) => 'Y'.repeat(match.length))
|
261
235
|
.replace(regex(month), (match) => 'M'.repeat(match.length))
|
@@ -340,8 +314,8 @@ const DateInput2 = forwardRef(
|
|
340
314
|
selectedDate={selectedDate}
|
341
315
|
disabledDates={disabledDates}
|
342
316
|
visibleMonth={selectedDate}
|
343
|
-
locale={
|
344
|
-
timezone={
|
317
|
+
locale={userLocale}
|
318
|
+
timezone={userTimezone}
|
345
319
|
renderNextMonthButton={
|
346
320
|
<IconButton
|
347
321
|
size="small"
|