@instructure/ui-date-input 9.3.1-snapshot-4 → 9.3.1-snapshot-6
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 +8 -5
- package/es/DateInput2/props.js +1 -0
- package/lib/DateInput2/index.js +8 -5
- package/lib/DateInput2/props.js +1 -0
- package/package.json +20 -20
- package/src/DateInput2/README.md +54 -3
- package/src/DateInput2/index.tsx +18 -23
- package/src/DateInput2/props.ts +13 -1
- package/tsconfig.build.tsbuildinfo +1 -1
- package/types/DateInput2/index.d.ts +1 -1
- package/types/DateInput2/index.d.ts.map +1 -1
- package/types/DateInput2/props.d.ts +9 -1
- package/types/DateInput2/props.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
|
-
## [9.3.1-snapshot-
|
6
|
+
## [9.3.1-snapshot-6](https://github.com/instructure/instructure-ui/compare/v9.3.0...v9.3.1-snapshot-6) (2024-07-25)
|
7
7
|
|
8
|
-
|
8
|
+
|
9
|
+
### Features
|
10
|
+
|
11
|
+
* **ui-date-input,ui-text-input:** add custom validation function and fix small layout issue ([77218be](https://github.com/instructure/instructure-ui/commit/77218be635611c1c674cc6c85d4dceaa76509117))
|
9
12
|
|
10
13
|
|
11
14
|
|
package/es/DateInput2/index.js
CHANGED
@@ -61,6 +61,7 @@ const DateInput2 = ({
|
|
61
61
|
onChange,
|
62
62
|
onBlur,
|
63
63
|
withYearPicker,
|
64
|
+
onRequestValidateDate,
|
64
65
|
invalidDateErrorMessage,
|
65
66
|
locale,
|
66
67
|
timezone,
|
@@ -98,6 +99,7 @@ const DateInput2 = ({
|
|
98
99
|
});
|
99
100
|
handleInputChange(e, formattedDate);
|
100
101
|
setShowPopover(false);
|
102
|
+
onRequestValidateDate === null || onRequestValidateDate === void 0 ? void 0 : onRequestValidateDate(formattedDate, true);
|
101
103
|
};
|
102
104
|
const validateInput = (onlyRemoveError = false) => {
|
103
105
|
// 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`)
|
@@ -108,11 +110,11 @@ const DateInput2 = ({
|
|
108
110
|
setInputMessages(messages || []);
|
109
111
|
return true;
|
110
112
|
}
|
111
|
-
if (!onlyRemoveError) {
|
112
|
-
setInputMessages([{
|
113
|
+
if (!onlyRemoveError && typeof invalidDateErrorMessage === 'string') {
|
114
|
+
setInputMessages(messages => [{
|
113
115
|
type: 'error',
|
114
|
-
text: invalidDateErrorMessage
|
115
|
-
}]);
|
116
|
+
text: invalidDateErrorMessage
|
117
|
+
}, ...messages]);
|
116
118
|
}
|
117
119
|
return false;
|
118
120
|
};
|
@@ -134,7 +136,6 @@ const DateInput2 = ({
|
|
134
136
|
return Intl.DateTimeFormat().resolvedOptions().timeZone;
|
135
137
|
};
|
136
138
|
const handleBlur = e => {
|
137
|
-
onBlur === null || onBlur === void 0 ? void 0 : onBlur(e);
|
138
139
|
const isInputValid = validateInput(false);
|
139
140
|
if (isInputValid && value) {
|
140
141
|
const formattedDate = new Date(value).toLocaleDateString(getLocale(), {
|
@@ -145,6 +146,8 @@ const DateInput2 = ({
|
|
145
146
|
});
|
146
147
|
handleInputChange(e, formattedDate);
|
147
148
|
}
|
149
|
+
onRequestValidateDate === null || onRequestValidateDate === void 0 ? void 0 : onRequestValidateDate(value, isInputValid);
|
150
|
+
onBlur === null || onBlur === void 0 ? void 0 : onBlur(e);
|
148
151
|
};
|
149
152
|
return jsx(TextInput, Object.assign({}, passthroughProps(rest), {
|
150
153
|
renderLabel: renderLabel,
|
package/es/DateInput2/props.js
CHANGED
@@ -40,6 +40,7 @@ const propTypes = {
|
|
40
40
|
messages: PropTypes.arrayOf(FormPropTypes.message),
|
41
41
|
onRequestShowCalendar: PropTypes.func,
|
42
42
|
onRequestHideCalendar: PropTypes.func,
|
43
|
+
onRequestValidateDate: PropTypes.func,
|
43
44
|
invalidDateErrorMessage: PropTypes.oneOfType([PropTypes.func, PropTypes.string]),
|
44
45
|
locale: PropTypes.string,
|
45
46
|
timezone: PropTypes.string,
|
package/lib/DateInput2/index.js
CHANGED
@@ -70,6 +70,7 @@ const DateInput2 = ({
|
|
70
70
|
onChange,
|
71
71
|
onBlur,
|
72
72
|
withYearPicker,
|
73
|
+
onRequestValidateDate,
|
73
74
|
invalidDateErrorMessage,
|
74
75
|
locale,
|
75
76
|
timezone,
|
@@ -107,6 +108,7 @@ const DateInput2 = ({
|
|
107
108
|
});
|
108
109
|
handleInputChange(e, formattedDate);
|
109
110
|
setShowPopover(false);
|
111
|
+
onRequestValidateDate === null || onRequestValidateDate === void 0 ? void 0 : onRequestValidateDate(formattedDate, true);
|
110
112
|
};
|
111
113
|
const validateInput = (onlyRemoveError = false) => {
|
112
114
|
// 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`)
|
@@ -117,11 +119,11 @@ const DateInput2 = ({
|
|
117
119
|
setInputMessages(messages || []);
|
118
120
|
return true;
|
119
121
|
}
|
120
|
-
if (!onlyRemoveError) {
|
121
|
-
setInputMessages([{
|
122
|
+
if (!onlyRemoveError && typeof invalidDateErrorMessage === 'string') {
|
123
|
+
setInputMessages(messages => [{
|
122
124
|
type: 'error',
|
123
|
-
text: invalidDateErrorMessage
|
124
|
-
}]);
|
125
|
+
text: invalidDateErrorMessage
|
126
|
+
}, ...messages]);
|
125
127
|
}
|
126
128
|
return false;
|
127
129
|
};
|
@@ -143,7 +145,6 @@ const DateInput2 = ({
|
|
143
145
|
return Intl.DateTimeFormat().resolvedOptions().timeZone;
|
144
146
|
};
|
145
147
|
const handleBlur = e => {
|
146
|
-
onBlur === null || onBlur === void 0 ? void 0 : onBlur(e);
|
147
148
|
const isInputValid = validateInput(false);
|
148
149
|
if (isInputValid && value) {
|
149
150
|
const formattedDate = new Date(value).toLocaleDateString(getLocale(), {
|
@@ -154,6 +155,8 @@ const DateInput2 = ({
|
|
154
155
|
});
|
155
156
|
handleInputChange(e, formattedDate);
|
156
157
|
}
|
158
|
+
onRequestValidateDate === null || onRequestValidateDate === void 0 ? void 0 : onRequestValidateDate(value, isInputValid);
|
159
|
+
onBlur === null || onBlur === void 0 ? void 0 : onBlur(e);
|
157
160
|
};
|
158
161
|
return (0, _emotion.jsx)(_TextInput.TextInput, Object.assign({}, (0, _passthroughProps.passthroughProps)(rest), {
|
159
162
|
renderLabel: renderLabel,
|
package/lib/DateInput2/props.js
CHANGED
@@ -47,6 +47,7 @@ const propTypes = exports.propTypes = {
|
|
47
47
|
messages: _propTypes.default.arrayOf(_FormPropTypes.FormPropTypes.message),
|
48
48
|
onRequestShowCalendar: _propTypes.default.func,
|
49
49
|
onRequestHideCalendar: _propTypes.default.func,
|
50
|
+
onRequestValidateDate: _propTypes.default.func,
|
50
51
|
invalidDateErrorMessage: _propTypes.default.oneOfType([_propTypes.default.func, _propTypes.default.string]),
|
51
52
|
locale: _propTypes.default.string,
|
52
53
|
timezone: _propTypes.default.string,
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "@instructure/ui-date-input",
|
3
|
-
"version": "9.3.1-snapshot-
|
3
|
+
"version": "9.3.1-snapshot-6",
|
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": "9.3.1-snapshot-
|
27
|
-
"@instructure/ui-babel-preset": "9.3.1-snapshot-
|
28
|
-
"@instructure/ui-buttons": "9.3.1-snapshot-
|
29
|
-
"@instructure/ui-scripts": "9.3.1-snapshot-
|
30
|
-
"@instructure/ui-test-utils": "9.3.1-snapshot-
|
26
|
+
"@instructure/ui-axe-check": "9.3.1-snapshot-6",
|
27
|
+
"@instructure/ui-babel-preset": "9.3.1-snapshot-6",
|
28
|
+
"@instructure/ui-buttons": "9.3.1-snapshot-6",
|
29
|
+
"@instructure/ui-scripts": "9.3.1-snapshot-6",
|
30
|
+
"@instructure/ui-test-utils": "9.3.1-snapshot-6",
|
31
31
|
"@testing-library/jest-dom": "^6.4.6",
|
32
32
|
"@testing-library/react": "^15.0.7",
|
33
33
|
"@testing-library/user-event": "^14.5.2",
|
@@ -35,20 +35,20 @@
|
|
35
35
|
},
|
36
36
|
"dependencies": {
|
37
37
|
"@babel/runtime": "^7.24.5",
|
38
|
-
"@instructure/emotion": "9.3.1-snapshot-
|
39
|
-
"@instructure/shared-types": "9.3.1-snapshot-
|
40
|
-
"@instructure/ui-calendar": "9.3.1-snapshot-
|
41
|
-
"@instructure/ui-form-field": "9.3.1-snapshot-
|
42
|
-
"@instructure/ui-i18n": "9.3.1-snapshot-
|
43
|
-
"@instructure/ui-icons": "9.3.1-snapshot-
|
44
|
-
"@instructure/ui-popover": "9.3.1-snapshot-
|
45
|
-
"@instructure/ui-position": "9.3.1-snapshot-
|
46
|
-
"@instructure/ui-prop-types": "9.3.1-snapshot-
|
47
|
-
"@instructure/ui-react-utils": "9.3.1-snapshot-
|
48
|
-
"@instructure/ui-selectable": "9.3.1-snapshot-
|
49
|
-
"@instructure/ui-testable": "9.3.1-snapshot-
|
50
|
-
"@instructure/ui-text-input": "9.3.1-snapshot-
|
51
|
-
"@instructure/ui-utils": "9.3.1-snapshot-
|
38
|
+
"@instructure/emotion": "9.3.1-snapshot-6",
|
39
|
+
"@instructure/shared-types": "9.3.1-snapshot-6",
|
40
|
+
"@instructure/ui-calendar": "9.3.1-snapshot-6",
|
41
|
+
"@instructure/ui-form-field": "9.3.1-snapshot-6",
|
42
|
+
"@instructure/ui-i18n": "9.3.1-snapshot-6",
|
43
|
+
"@instructure/ui-icons": "9.3.1-snapshot-6",
|
44
|
+
"@instructure/ui-popover": "9.3.1-snapshot-6",
|
45
|
+
"@instructure/ui-position": "9.3.1-snapshot-6",
|
46
|
+
"@instructure/ui-prop-types": "9.3.1-snapshot-6",
|
47
|
+
"@instructure/ui-react-utils": "9.3.1-snapshot-6",
|
48
|
+
"@instructure/ui-selectable": "9.3.1-snapshot-6",
|
49
|
+
"@instructure/ui-testable": "9.3.1-snapshot-6",
|
50
|
+
"@instructure/ui-text-input": "9.3.1-snapshot-6",
|
51
|
+
"@instructure/ui-utils": "9.3.1-snapshot-6",
|
52
52
|
"moment-timezone": "^0.5.45",
|
53
53
|
"prop-types": "^15.8.1"
|
54
54
|
},
|
package/src/DateInput2/README.md
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
---
|
2
|
-
describes:
|
2
|
+
describes: DateInput2
|
3
3
|
---
|
4
4
|
|
5
5
|
This component is an updated version of [`DateInput`](/#DateInput) that's easier to configure for developers, has a better UX, better accessibility features and a year picker. We recommend using this instead of `DateInput` which will be deprecated in the future.
|
@@ -74,7 +74,7 @@ This component is an updated version of [`DateInput`](/#DateInput) that's easier
|
|
74
74
|
invalidDateErrorMessage="Invalid date"
|
75
75
|
withYearPicker={{
|
76
76
|
screenReaderLabel: 'Year picker',
|
77
|
-
startYear:
|
77
|
+
startYear: 1900,
|
78
78
|
endYear: 2024
|
79
79
|
}}
|
80
80
|
/>
|
@@ -103,7 +103,7 @@ This component is an updated version of [`DateInput`](/#DateInput) that's easier
|
|
103
103
|
invalidDateErrorMessage="Invalid date"
|
104
104
|
withYearPicker={{
|
105
105
|
screenReaderLabel: 'Year picker',
|
106
|
-
startYear:
|
106
|
+
startYear: 1900,
|
107
107
|
endYear: 2024
|
108
108
|
}}
|
109
109
|
/>
|
@@ -112,3 +112,54 @@ This component is an updated version of [`DateInput`](/#DateInput) that's easier
|
|
112
112
|
|
113
113
|
render(<Example />)
|
114
114
|
```
|
115
|
+
|
116
|
+
### With custom validation
|
117
|
+
|
118
|
+
```js
|
119
|
+
---
|
120
|
+
type: example
|
121
|
+
---
|
122
|
+
const Example = () => {
|
123
|
+
const [value, setValue] = useState('')
|
124
|
+
const [messages, setMessages] = useState([])
|
125
|
+
|
126
|
+
const handleDateValidation = (dateString, isValidDate) => {
|
127
|
+
if (!isValidDate) {
|
128
|
+
setMessages([{
|
129
|
+
type: 'error',
|
130
|
+
text: 'This is not a valid date'
|
131
|
+
}])
|
132
|
+
} else if (new Date(dateString) < new Date('January 1, 1900')) {
|
133
|
+
setMessages([{
|
134
|
+
type: 'error',
|
135
|
+
text: 'Use date after January 1, 1900'
|
136
|
+
}])
|
137
|
+
} else {
|
138
|
+
setMessages([])
|
139
|
+
}
|
140
|
+
}
|
141
|
+
|
142
|
+
return (
|
143
|
+
<DateInput2
|
144
|
+
renderLabel="Choose a date after January 1, 1900"
|
145
|
+
screenReaderLabels={{
|
146
|
+
calendarIcon: 'Calendar',
|
147
|
+
nextMonthButton: 'Next month',
|
148
|
+
prevMonthButton: 'Previous month'
|
149
|
+
}}
|
150
|
+
width="20rem"
|
151
|
+
value={value}
|
152
|
+
messages={messages}
|
153
|
+
onRequestValidateDate={handleDateValidation}
|
154
|
+
onChange={(e, value) => setValue(value)}
|
155
|
+
withYearPicker={{
|
156
|
+
screenReaderLabel: 'Year picker',
|
157
|
+
startYear: 1900,
|
158
|
+
endYear: 2024
|
159
|
+
}}
|
160
|
+
/>
|
161
|
+
)
|
162
|
+
}
|
163
|
+
|
164
|
+
render(<Example />)
|
165
|
+
```
|
package/src/DateInput2/index.tsx
CHANGED
@@ -56,17 +56,7 @@ function isValidMomentDate(
|
|
56
56
|
return moment
|
57
57
|
.tz(
|
58
58
|
dateString,
|
59
|
-
[
|
60
|
-
moment.ISO_8601,
|
61
|
-
'llll',
|
62
|
-
'LLLL',
|
63
|
-
'lll',
|
64
|
-
'LLL',
|
65
|
-
'll',
|
66
|
-
'LL',
|
67
|
-
'l',
|
68
|
-
'L'
|
69
|
-
],
|
59
|
+
[moment.ISO_8601, 'llll', 'LLLL', 'lll', 'LLL', 'll', 'LL', 'l', 'L'],
|
70
60
|
locale,
|
71
61
|
true,
|
72
62
|
timezone
|
@@ -92,6 +82,7 @@ const DateInput2 = ({
|
|
92
82
|
onChange,
|
93
83
|
onBlur,
|
94
84
|
withYearPicker,
|
85
|
+
onRequestValidateDate,
|
95
86
|
invalidDateErrorMessage,
|
96
87
|
locale,
|
97
88
|
timezone,
|
@@ -130,6 +121,7 @@ const DateInput2 = ({
|
|
130
121
|
})
|
131
122
|
handleInputChange(e, formattedDate)
|
132
123
|
setShowPopover(false)
|
124
|
+
onRequestValidateDate?.(formattedDate, true)
|
133
125
|
}
|
134
126
|
|
135
127
|
const validateInput = (onlyRemoveError = false): boolean => {
|
@@ -145,14 +137,16 @@ const DateInput2 = ({
|
|
145
137
|
setInputMessages(messages || [])
|
146
138
|
return true
|
147
139
|
}
|
148
|
-
if (!onlyRemoveError) {
|
149
|
-
setInputMessages([
|
140
|
+
if (!onlyRemoveError && typeof invalidDateErrorMessage === 'string') {
|
141
|
+
setInputMessages((messages) => [
|
150
142
|
{
|
151
143
|
type: 'error',
|
152
|
-
text: invalidDateErrorMessage
|
153
|
-
}
|
144
|
+
text: invalidDateErrorMessage
|
145
|
+
},
|
146
|
+
...messages
|
154
147
|
])
|
155
148
|
}
|
149
|
+
|
156
150
|
return false
|
157
151
|
}
|
158
152
|
|
@@ -176,17 +170,18 @@ const DateInput2 = ({
|
|
176
170
|
}
|
177
171
|
|
178
172
|
const handleBlur = (e: SyntheticEvent) => {
|
179
|
-
onBlur?.(e)
|
180
173
|
const isInputValid = validateInput(false)
|
181
174
|
if (isInputValid && value) {
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
175
|
+
const formattedDate = new Date(value).toLocaleDateString(getLocale(), {
|
176
|
+
month: 'long',
|
177
|
+
year: 'numeric',
|
178
|
+
day: 'numeric',
|
179
|
+
timeZone: getTimezone()
|
180
|
+
})
|
181
|
+
handleInputChange(e, formattedDate)
|
189
182
|
}
|
183
|
+
onRequestValidateDate?.(value, isInputValid)
|
184
|
+
onBlur?.(e)
|
190
185
|
}
|
191
186
|
|
192
187
|
return (
|
package/src/DateInput2/props.ts
CHANGED
@@ -99,7 +99,18 @@ type DateInput2Props = {
|
|
99
99
|
*/
|
100
100
|
onRequestHideCalendar?: (event: SyntheticEvent) => void
|
101
101
|
/**
|
102
|
-
*
|
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
|
+
/**
|
112
|
+
* The message shown to the user when the date is invalid. If this prop is not set, validation is bypassed.
|
113
|
+
* If it's set to an empty string, validation happens and the input border changes to red if validation hasn't passed.
|
103
114
|
**/
|
104
115
|
invalidDateErrorMessage?: string
|
105
116
|
/**
|
@@ -165,6 +176,7 @@ const propTypes: PropValidators<PropKeys> = {
|
|
165
176
|
messages: PropTypes.arrayOf(FormPropTypes.message),
|
166
177
|
onRequestShowCalendar: PropTypes.func,
|
167
178
|
onRequestHideCalendar: PropTypes.func,
|
179
|
+
onRequestValidateDate: PropTypes.func,
|
168
180
|
invalidDateErrorMessage: PropTypes.oneOfType([
|
169
181
|
PropTypes.func,
|
170
182
|
PropTypes.string
|