@instructure/ui-date-input 10.2.3-snapshot-9 → 10.2.3-snapshot-11
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 +172 -73
- package/es/DateInput2/props.js +3 -5
- package/lib/DateInput2/index.js +172 -73
- package/lib/DateInput2/props.js +3 -5
- package/package.json +20 -20
- package/src/DateInput/README.md +1 -1
- package/src/DateInput2/README.md +195 -53
- package/src/DateInput2/index.tsx +184 -95
- package/src/DateInput2/props.ts +49 -37
- package/tsconfig.build.tsbuildinfo +1 -1
- package/types/DateInput2/index.d.ts +36 -2
- package/types/DateInput2/index.d.ts.map +1 -1
- package/types/DateInput2/props.d.ts +20 -28
- package/types/DateInput2/props.d.ts.map +1 -1
package/src/DateInput2/index.tsx
CHANGED
@@ -25,7 +25,6 @@
|
|
25
25
|
/** @jsx jsx */
|
26
26
|
import { useState, useEffect, useContext } from 'react'
|
27
27
|
import type { SyntheticEvent } from 'react'
|
28
|
-
import moment from 'moment-timezone'
|
29
28
|
import { Calendar } from '@instructure/ui-calendar'
|
30
29
|
import { IconButton } from '@instructure/ui-buttons'
|
31
30
|
import {
|
@@ -43,38 +42,103 @@ import { jsx } from '@instructure/emotion'
|
|
43
42
|
import { propTypes } from './props'
|
44
43
|
import type { DateInput2Props } from './props'
|
45
44
|
import type { FormMessage } from '@instructure/ui-form-field'
|
45
|
+
import type { Moment } from '@instructure/ui-i18n'
|
46
46
|
|
47
|
-
function
|
48
|
-
|
49
|
-
}
|
50
|
-
|
51
|
-
function isValidMomentDate(
|
52
|
-
dateString: string,
|
47
|
+
function parseLocaleDate(
|
48
|
+
dateString: string = '',
|
53
49
|
locale: string,
|
54
|
-
|
55
|
-
):
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
50
|
+
timeZone: string
|
51
|
+
): Date | null {
|
52
|
+
// This function may seem complicated but it basically does one thing:
|
53
|
+
// Given a dateString, a locale and a timeZone. The dateString is assumed to be formatted according
|
54
|
+
// to the locale. So if the locale is `en-us` the dateString is expected to be in the format of M/D/YYYY.
|
55
|
+
// The dateString is also assumed to be in the given timeZone, so "1/1/2020" in "America/Los_Angeles" timezone is
|
56
|
+
// expected to be "2020-01-01T08:00:00.000Z" in UTC time.
|
57
|
+
// This function tries to parse the dateString taking these variables into account and return a javascript Date object
|
58
|
+
// that is adjusted to be in UTC.
|
59
|
+
|
60
|
+
// Split string on '.', whitespace, '/', ',' or '-' using regex: /[.\s/.-]+/.
|
61
|
+
// The '+' allows splitting on consecutive delimiters.
|
62
|
+
// `.filter(Boolean)` is needed because some locales have a delimeter at the end (e.g.: hungarian dates are formatted as `2024. 09. 19.`)
|
63
|
+
const splitDate = dateString.split(/[,.\s/.-]+/).filter(Boolean)
|
64
|
+
|
65
|
+
// create a locale formatted new date to later extract the order and delimeter information
|
66
|
+
const localeDate = new Intl.DateTimeFormat(locale).formatToParts(new Date())
|
67
|
+
|
68
|
+
let index = 0
|
69
|
+
let day: number | undefined,
|
70
|
+
month: number | undefined,
|
71
|
+
year: number | undefined
|
72
|
+
localeDate.forEach((part) => {
|
73
|
+
if (part.type === 'month') {
|
74
|
+
month = parseInt(splitDate[index], 10)
|
75
|
+
index++
|
76
|
+
} else if (part.type === 'day') {
|
77
|
+
day = parseInt(splitDate[index], 10)
|
78
|
+
index++
|
79
|
+
} else if (part.type === 'year') {
|
80
|
+
year = parseInt(splitDate[index], 10)
|
81
|
+
index++
|
82
|
+
}
|
83
|
+
})
|
84
|
+
|
85
|
+
// sensible limitations
|
86
|
+
if (!year || !month || !day || year < 1000 || year > 9999) return null
|
87
|
+
|
88
|
+
// create utc date from year, month (zero indexed) and day
|
89
|
+
const date = new Date(Date.UTC(year, month - 1, day))
|
90
|
+
|
91
|
+
if (date.getMonth() !== month - 1 || date.getDate() !== day) {
|
92
|
+
// Check if the Date object adjusts the values. If it does, the input is invalid.
|
93
|
+
return null
|
94
|
+
}
|
95
|
+
|
96
|
+
// Format date string in the provided timezone. The locale here is irrelevant, we only care about how to time is adjusted for the timezone.
|
97
|
+
const parts = new Intl.DateTimeFormat('en-US', {
|
98
|
+
timeZone,
|
99
|
+
year: 'numeric',
|
100
|
+
month: '2-digit',
|
101
|
+
day: '2-digit',
|
102
|
+
hour: '2-digit',
|
103
|
+
minute: '2-digit',
|
104
|
+
second: '2-digit',
|
105
|
+
hour12: false
|
106
|
+
}).formatToParts(date)
|
107
|
+
|
108
|
+
// Extract the date and time parts from the formatted string
|
109
|
+
const dateStringInTimezone: {
|
110
|
+
[key: string]: number
|
111
|
+
} = parts.reduce((acc, part) => {
|
112
|
+
return part.type === 'literal'
|
113
|
+
? acc
|
114
|
+
: {
|
115
|
+
...acc,
|
116
|
+
[part.type]: part.value
|
117
|
+
}
|
118
|
+
}, {})
|
119
|
+
|
120
|
+
// Create a date string in the format 'YYYY-MM-DDTHH:mm:ss'
|
121
|
+
const dateInTimezone = `${dateStringInTimezone.year}-${dateStringInTimezone.month}-${dateStringInTimezone.day}T${dateStringInTimezone.hour}:${dateStringInTimezone.minute}:${dateStringInTimezone.second}`
|
122
|
+
|
123
|
+
// Calculate time difference for timezone offset
|
124
|
+
const timeDiff = new Date(dateInTimezone + 'Z').getTime() - date.getTime()
|
125
|
+
const utcTime = new Date(date.getTime() - timeDiff)
|
126
|
+
// Return the UTC Date corresponding to the time in the specified timezone
|
127
|
+
return utcTime
|
65
128
|
}
|
66
129
|
|
67
130
|
/**
|
68
131
|
---
|
69
132
|
category: components
|
70
133
|
---
|
134
|
+
|
135
|
+
@module experimental
|
71
136
|
**/
|
72
137
|
const DateInput2 = ({
|
73
138
|
renderLabel,
|
74
139
|
screenReaderLabels,
|
75
140
|
isRequired = false,
|
76
141
|
interaction = 'enabled',
|
77
|
-
size = 'medium',
|
78
142
|
isInline = false,
|
79
143
|
value,
|
80
144
|
messages,
|
@@ -82,80 +146,24 @@ const DateInput2 = ({
|
|
82
146
|
onChange,
|
83
147
|
onBlur,
|
84
148
|
withYearPicker,
|
85
|
-
onRequestValidateDate,
|
86
149
|
invalidDateErrorMessage,
|
87
150
|
locale,
|
88
151
|
timezone,
|
89
152
|
placeholder,
|
153
|
+
dateFormat,
|
154
|
+
onRequestValidateDate,
|
155
|
+
// margin, TODO enable this prop
|
90
156
|
...rest
|
91
157
|
}: DateInput2Props) => {
|
92
|
-
const [selectedDate, setSelectedDate] = useState<string>('')
|
93
|
-
const [inputMessages, setInputMessages] = useState<FormMessage[]>(
|
94
|
-
messages || []
|
95
|
-
)
|
96
|
-
const [showPopover, setShowPopover] = useState<boolean>(false)
|
97
158
|
const localeContext = useContext(ApplyLocaleContext)
|
98
159
|
|
99
|
-
useEffect(() => {
|
100
|
-
validateInput(true)
|
101
|
-
}, [value])
|
102
|
-
|
103
|
-
useEffect(() => {
|
104
|
-
setInputMessages(messages || [])
|
105
|
-
}, [messages])
|
106
|
-
|
107
|
-
const handleInputChange = (e: SyntheticEvent, value: string) => {
|
108
|
-
onChange?.(e, value)
|
109
|
-
}
|
110
|
-
|
111
|
-
const handleDateSelected = (
|
112
|
-
dateString: string,
|
113
|
-
_momentDate: any, // real type is Moment but used `any` to avoid importing the moment lib
|
114
|
-
e: SyntheticEvent
|
115
|
-
) => {
|
116
|
-
const formattedDate = new Date(dateString).toLocaleDateString(getLocale(), {
|
117
|
-
month: 'long',
|
118
|
-
year: 'numeric',
|
119
|
-
day: 'numeric',
|
120
|
-
timeZone: getTimezone()
|
121
|
-
})
|
122
|
-
handleInputChange(e, formattedDate)
|
123
|
-
setShowPopover(false)
|
124
|
-
onRequestValidateDate?.(formattedDate, true)
|
125
|
-
}
|
126
|
-
|
127
|
-
const validateInput = (onlyRemoveError = false): boolean => {
|
128
|
-
// TODO `isValidDate` and `isValidMomentDate` basically have the same functionality but the latter is a bit more strict (e.g.: `33` is only valid in `isValidMomentDate`)
|
129
|
-
// in the future we should get rid of moment but currently Calendar is using it for validation too so we can only remove it simultaneously
|
130
|
-
// otherwise DateInput could pass invalid dates to Calendar and break it
|
131
|
-
if (
|
132
|
-
(isValidDate(value || '') &&
|
133
|
-
isValidMomentDate(value || '', getLocale(), getTimezone())) ||
|
134
|
-
value === ''
|
135
|
-
) {
|
136
|
-
setSelectedDate(value || '')
|
137
|
-
setInputMessages(messages || [])
|
138
|
-
return true
|
139
|
-
}
|
140
|
-
if (!onlyRemoveError && typeof invalidDateErrorMessage === 'string') {
|
141
|
-
setInputMessages((messages) => [
|
142
|
-
{
|
143
|
-
type: 'error',
|
144
|
-
text: invalidDateErrorMessage
|
145
|
-
},
|
146
|
-
...messages
|
147
|
-
])
|
148
|
-
}
|
149
|
-
|
150
|
-
return false
|
151
|
-
}
|
152
|
-
|
153
160
|
const getLocale = () => {
|
154
161
|
if (locale) {
|
155
162
|
return locale
|
156
163
|
} else if (localeContext.locale) {
|
157
164
|
return localeContext.locale
|
158
165
|
}
|
166
|
+
// default to the system's locale
|
159
167
|
return Locale.browserLocale()
|
160
168
|
}
|
161
169
|
|
@@ -169,32 +177,114 @@ const DateInput2 = ({
|
|
169
177
|
return Intl.DateTimeFormat().resolvedOptions().timeZone
|
170
178
|
}
|
171
179
|
|
180
|
+
const [inputMessages, setInputMessages] = useState<FormMessage[]>(
|
181
|
+
messages || []
|
182
|
+
)
|
183
|
+
const [showPopover, setShowPopover] = useState<boolean>(false)
|
184
|
+
|
185
|
+
useEffect(() => {
|
186
|
+
// don't set input messages if there is an error set already
|
187
|
+
if (!inputMessages) {
|
188
|
+
setInputMessages(messages || [])
|
189
|
+
}
|
190
|
+
}, [messages])
|
191
|
+
|
192
|
+
useEffect(() => {
|
193
|
+
const [, utcIsoDate] = parseDate(value)
|
194
|
+
// clear error messages if date becomes valid
|
195
|
+
if (utcIsoDate || !value) {
|
196
|
+
setInputMessages(messages || [])
|
197
|
+
}
|
198
|
+
}, [value])
|
199
|
+
|
200
|
+
const parseDate = (dateString: string = ''): [string, string] => {
|
201
|
+
let date: Date | null = null
|
202
|
+
if (dateFormat) {
|
203
|
+
if (typeof dateFormat === 'string') {
|
204
|
+
// use dateFormat instead of the user locale
|
205
|
+
date = parseLocaleDate(dateString, dateFormat, getTimezone())
|
206
|
+
} else if (dateFormat.parser) {
|
207
|
+
date = dateFormat.parser(dateString)
|
208
|
+
}
|
209
|
+
} else {
|
210
|
+
// no dateFormat prop passed, use locale for formatting
|
211
|
+
date = parseLocaleDate(dateString, getLocale(), getTimezone())
|
212
|
+
}
|
213
|
+
return date ? [formatDate(date), date.toISOString()] : ['', '']
|
214
|
+
}
|
215
|
+
|
216
|
+
const formatDate = (date: Date): string => {
|
217
|
+
// use formatter function if provided
|
218
|
+
if (typeof dateFormat !== 'string' && dateFormat?.formatter) {
|
219
|
+
return dateFormat.formatter(date)
|
220
|
+
}
|
221
|
+
// if dateFormat set to a locale, use that, otherwise default to the user's locale
|
222
|
+
return date.toLocaleDateString(
|
223
|
+
typeof dateFormat === 'string' ? dateFormat : getLocale(),
|
224
|
+
{ timeZone: getTimezone(), calendar: 'gregory', numberingSystem: 'latn' }
|
225
|
+
)
|
226
|
+
}
|
227
|
+
|
228
|
+
const getDateFromatHint = () => {
|
229
|
+
const exampleDate = new Date('2024-09-01')
|
230
|
+
const formattedDate = formatDate(exampleDate)
|
231
|
+
|
232
|
+
// Create a regular expression to find the exact match of the number
|
233
|
+
const regex = (n: string) => {
|
234
|
+
return new RegExp(`(?<!\\d)0*${n}(?!\\d)`, 'g')
|
235
|
+
}
|
236
|
+
|
237
|
+
// Replace the matched number with the same number of dashes
|
238
|
+
const year = `${exampleDate.getFullYear()}`
|
239
|
+
const month = `${exampleDate.getMonth() + 1}`
|
240
|
+
const day = `${exampleDate.getDate()}`
|
241
|
+
return formattedDate
|
242
|
+
.replace(regex(year), (match) => 'Y'.repeat(match.length))
|
243
|
+
.replace(regex(month), (match) => 'M'.repeat(match.length))
|
244
|
+
.replace(regex(day), (match) => 'D'.repeat(match.length))
|
245
|
+
}
|
246
|
+
|
247
|
+
const handleInputChange = (e: SyntheticEvent, newValue: string) => {
|
248
|
+
const [, utcIsoDate] = parseDate(newValue)
|
249
|
+
onChange?.(e, newValue, utcIsoDate)
|
250
|
+
}
|
251
|
+
|
252
|
+
const handleDateSelected = (
|
253
|
+
dateString: string,
|
254
|
+
_momentDate: Moment,
|
255
|
+
e: SyntheticEvent
|
256
|
+
) => {
|
257
|
+
setShowPopover(false)
|
258
|
+
const newValue = formatDate(new Date(dateString))
|
259
|
+
onChange?.(e, newValue, dateString)
|
260
|
+
onRequestValidateDate?.(e, newValue, dateString)
|
261
|
+
}
|
262
|
+
|
172
263
|
const handleBlur = (e: SyntheticEvent) => {
|
173
|
-
const
|
174
|
-
if (
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
})
|
181
|
-
handleInputChange(e, formattedDate)
|
264
|
+
const [localeDate, utcIsoDate] = parseDate(value)
|
265
|
+
if (localeDate) {
|
266
|
+
if (localeDate !== value) {
|
267
|
+
onChange?.(e, localeDate, utcIsoDate)
|
268
|
+
}
|
269
|
+
} else if (value && invalidDateErrorMessage) {
|
270
|
+
setInputMessages([{ type: 'error', text: invalidDateErrorMessage }])
|
182
271
|
}
|
183
|
-
onRequestValidateDate?.(value,
|
184
|
-
onBlur?.(e)
|
272
|
+
onRequestValidateDate?.(e, value || '', utcIsoDate)
|
273
|
+
onBlur?.(e, value || '', utcIsoDate)
|
185
274
|
}
|
186
275
|
|
276
|
+
const selectedDate = parseDate(value)[1]
|
187
277
|
return (
|
188
278
|
<TextInput
|
189
279
|
{...passthroughProps(rest)}
|
280
|
+
// margin={'large'} TODO add this prop to TextInput
|
190
281
|
renderLabel={renderLabel}
|
191
282
|
onChange={handleInputChange}
|
192
283
|
onBlur={handleBlur}
|
193
284
|
isRequired={isRequired}
|
194
285
|
value={value}
|
195
|
-
placeholder={placeholder}
|
286
|
+
placeholder={placeholder ?? getDateFromatHint()}
|
196
287
|
width={width}
|
197
|
-
size={size}
|
198
288
|
display={isInline ? 'inline-block' : 'block'}
|
199
289
|
messages={inputMessages}
|
200
290
|
interaction={interaction}
|
@@ -206,7 +296,6 @@ const DateInput2 = ({
|
|
206
296
|
withBorder={false}
|
207
297
|
screenReaderLabel={screenReaderLabels.calendarIcon}
|
208
298
|
shape="circle"
|
209
|
-
size={size}
|
210
299
|
interaction={interaction}
|
211
300
|
>
|
212
301
|
<IconCalendarMonthLine />
|
@@ -225,8 +314,8 @@ const DateInput2 = ({
|
|
225
314
|
onDateSelected={handleDateSelected}
|
226
315
|
selectedDate={selectedDate}
|
227
316
|
visibleMonth={selectedDate}
|
228
|
-
locale={
|
229
|
-
timezone={
|
317
|
+
locale={getLocale()}
|
318
|
+
timezone={getTimezone()}
|
230
319
|
role="listbox"
|
231
320
|
renderNextMonthButton={
|
232
321
|
<IconButton
|
package/src/DateInput2/props.ts
CHANGED
@@ -23,14 +23,18 @@
|
|
23
23
|
*/
|
24
24
|
|
25
25
|
import PropTypes from 'prop-types'
|
26
|
-
import type { SyntheticEvent } from 'react'
|
26
|
+
import type { SyntheticEvent, InputHTMLAttributes } from 'react'
|
27
27
|
|
28
28
|
import { controllable } from '@instructure/ui-prop-types'
|
29
29
|
import { FormPropTypes } from '@instructure/ui-form-field'
|
30
30
|
import type { FormMessage } from '@instructure/ui-form-field'
|
31
|
-
import type {
|
31
|
+
import type {
|
32
|
+
OtherHTMLAttributes,
|
33
|
+
Renderable,
|
34
|
+
PropValidators
|
35
|
+
} from '@instructure/shared-types'
|
32
36
|
|
33
|
-
type
|
37
|
+
type DateInput2OwnProps = {
|
34
38
|
/**
|
35
39
|
* Specifies the input label.
|
36
40
|
*/
|
@@ -43,24 +47,27 @@ type DateInput2Props = {
|
|
43
47
|
/**
|
44
48
|
* Specifies the input value.
|
45
49
|
*/
|
46
|
-
value?: string
|
50
|
+
value?: string
|
47
51
|
/**
|
48
|
-
*
|
49
|
-
*/
|
50
|
-
size?: 'small' | 'medium' | 'large'
|
51
|
-
/**
|
52
|
-
* Html placeholder text to display when the input has no value. This should
|
53
|
-
* be hint text, not a label replacement.
|
52
|
+
* Placeholder text for the input field. If it's left undefined it will display a hint for the date format (like `DD/MM/YYYY`).
|
54
53
|
*/
|
55
54
|
placeholder?: string
|
56
55
|
/**
|
57
56
|
* Callback fired when the input changes.
|
58
57
|
*/
|
59
|
-
onChange?: (
|
58
|
+
onChange?: (
|
59
|
+
event: React.SyntheticEvent,
|
60
|
+
inputValue: string,
|
61
|
+
utcDateString: string
|
62
|
+
) => void
|
60
63
|
/**
|
61
64
|
* Callback executed when the input fires a blur event.
|
62
65
|
*/
|
63
|
-
onBlur?: (
|
66
|
+
onBlur?: (
|
67
|
+
event: React.SyntheticEvent,
|
68
|
+
value: string,
|
69
|
+
utcDateString: string
|
70
|
+
) => void
|
64
71
|
/**
|
65
72
|
* Specifies if interaction with the input is enabled, disabled, or readonly.
|
66
73
|
* When "disabled", the input changes visibly to indicate that it cannot
|
@@ -90,24 +97,6 @@ type DateInput2Props = {
|
|
90
97
|
* }`
|
91
98
|
*/
|
92
99
|
messages?: FormMessage[]
|
93
|
-
/**
|
94
|
-
* Callback fired requesting the calendar be shown.
|
95
|
-
*/
|
96
|
-
onRequestShowCalendar?: (event: SyntheticEvent) => void
|
97
|
-
/**
|
98
|
-
* Callback fired requesting the calendar be hidden.
|
99
|
-
*/
|
100
|
-
onRequestHideCalendar?: (event: SyntheticEvent) => void
|
101
|
-
/**
|
102
|
-
* Callback fired when the input is blurred. Feedback should be provided
|
103
|
-
* to the user when this function is called if the selected date or input
|
104
|
-
* value is invalid. The component has an internal check whether the date can
|
105
|
-
* be parsed to a valid date.
|
106
|
-
*/
|
107
|
-
onRequestValidateDate?: (
|
108
|
-
value?: string,
|
109
|
-
internalValidationPassed?: boolean
|
110
|
-
) => void | FormMessage[]
|
111
100
|
/**
|
112
101
|
* The message shown to the user when the date is invalid. If this prop is not set, validation is bypassed.
|
113
102
|
* If it's set to an empty string, validation happens and the input border changes to red if validation hasn't passed.
|
@@ -135,7 +124,7 @@ type DateInput2Props = {
|
|
135
124
|
* This property can also be set via a context property and if both are set
|
136
125
|
* then the component property takes precedence over the context property.
|
137
126
|
*
|
138
|
-
* The
|
127
|
+
* The system timezone will be used if no value is set via a component
|
139
128
|
* property or a context property.
|
140
129
|
**/
|
141
130
|
timezone?: string
|
@@ -157,15 +146,39 @@ type DateInput2Props = {
|
|
157
146
|
startYear: number
|
158
147
|
endYear: number
|
159
148
|
}
|
149
|
+
/**
|
150
|
+
* By default the date format is determined by the locale but can be changed via this prop to an alternate locale (passing it in as a string) or a custom parser and formatter (both as functions)
|
151
|
+
*/
|
152
|
+
dateFormat?:
|
153
|
+
| {
|
154
|
+
parser: (input: string) => Date | null
|
155
|
+
formatter: (date: Date) => string
|
156
|
+
}
|
157
|
+
| string
|
158
|
+
|
159
|
+
/**
|
160
|
+
* Callback executed when the input fires a blur event or a date is selected from the picker.
|
161
|
+
*/
|
162
|
+
onRequestValidateDate?: (
|
163
|
+
event: React.SyntheticEvent,
|
164
|
+
value: string,
|
165
|
+
utcDateString: string
|
166
|
+
) => void
|
167
|
+
// margin?: Spacing // TODO enable this prop
|
160
168
|
}
|
161
169
|
|
162
|
-
type PropKeys = keyof
|
170
|
+
type PropKeys = keyof DateInput2OwnProps
|
171
|
+
|
172
|
+
type DateInput2Props = DateInput2OwnProps &
|
173
|
+
OtherHTMLAttributes<
|
174
|
+
DateInput2OwnProps,
|
175
|
+
InputHTMLAttributes<DateInput2OwnProps & Element>
|
176
|
+
>
|
163
177
|
|
164
178
|
const propTypes: PropValidators<PropKeys> = {
|
165
179
|
renderLabel: PropTypes.oneOfType([PropTypes.node, PropTypes.func]).isRequired,
|
166
180
|
screenReaderLabels: PropTypes.object.isRequired,
|
167
181
|
value: controllable(PropTypes.string),
|
168
|
-
size: PropTypes.oneOf(['small', 'medium', 'large']),
|
169
182
|
placeholder: PropTypes.string,
|
170
183
|
onChange: PropTypes.func,
|
171
184
|
onBlur: PropTypes.func,
|
@@ -174,16 +187,15 @@ const propTypes: PropValidators<PropKeys> = {
|
|
174
187
|
isInline: PropTypes.bool,
|
175
188
|
width: PropTypes.string,
|
176
189
|
messages: PropTypes.arrayOf(FormPropTypes.message),
|
177
|
-
onRequestShowCalendar: PropTypes.func,
|
178
|
-
onRequestHideCalendar: PropTypes.func,
|
179
|
-
onRequestValidateDate: PropTypes.func,
|
180
190
|
invalidDateErrorMessage: PropTypes.oneOfType([
|
181
191
|
PropTypes.func,
|
182
192
|
PropTypes.string
|
183
193
|
]),
|
184
194
|
locale: PropTypes.string,
|
185
195
|
timezone: PropTypes.string,
|
186
|
-
withYearPicker: PropTypes.object
|
196
|
+
withYearPicker: PropTypes.object,
|
197
|
+
dateFormat: PropTypes.oneOfType([PropTypes.string, PropTypes.object]),
|
198
|
+
onRequestValidateDate: PropTypes.func
|
187
199
|
}
|
188
200
|
|
189
201
|
export type { DateInput2Props }
|