@instructure/ui-date-input 10.11.1-snapshot-18 → 10.12.1-pr-snapshot-1741273500459

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 CHANGED
@@ -3,9 +3,28 @@
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.11.1-snapshot-18](https://github.com/instructure/instructure-ui/compare/v10.11.0...v10.11.1-snapshot-18) (2025-02-21)
6
+ ## [10.12.1-pr-snapshot-1741273500459](https://github.com/instructure/instructure-ui/compare/v10.12.0...v10.12.1-pr-snapshot-1741273500459) (2025-03-06)
7
7
 
8
- **Note:** Version bump only for package @instructure/ui-date-input
8
+
9
+ ### Bug Fixes
10
+
11
+ * **many:** fix form label not read by NVDA in hover mode and other layout issues ([ef77281](https://github.com/instructure/instructure-ui/commit/ef77281890511e8eea794196445d3ef2454537ba))
12
+
13
+
14
+ ### Features
15
+
16
+ * **ui-date-input:** add feature to disable dates and access the input's ref ([411219e](https://github.com/instructure/instructure-ui/commit/411219e4347c75ed2ffeda320b33c591ffc05329))
17
+
18
+
19
+
20
+
21
+
22
+ # [10.12.0](https://github.com/instructure/instructure-ui/compare/v10.11.0...v10.12.0) (2025-02-24)
23
+
24
+
25
+ ### Features
26
+
27
+ * **many:** introduce new spacing tokens; add margin prop for more components ([048c902](https://github.com/instructure/instructure-ui/commit/048c902406c00611cd117fb2fb8164a6eba62fb8))
9
28
 
10
29
 
11
30
 
@@ -263,7 +263,7 @@ describe('<DateInput />', () => {
263
263
  onRequestShowCalendar: onRequestShowCalendar
264
264
  }, generateDays())),
265
265
  container = _render5.container;
266
- const dateInput = container.querySelector("[class$='-formFieldLabel']");
266
+ const dateInput = container.querySelector('span[class$="-formFieldLayout__label"]');
267
267
  expect(dateInput).toHaveTextContent('Choose date');
268
268
  await userEvent.click(dateInput);
269
269
  await waitFor(() => {
@@ -71,11 +71,9 @@ describe('<DateInput2 />', () => {
71
71
  it('should render an input label', async () => {
72
72
  const _render2 = render(_DateInputExample2 || (_DateInputExample2 = /*#__PURE__*/React.createElement(DateInputExample, null))),
73
73
  container = _render2.container;
74
- const dateInput = container.querySelector('input');
75
74
  const label = container.querySelector('label');
76
75
  expect(label).toBeInTheDocument();
77
76
  expect(label).toHaveTextContent(LABEL_TEXT);
78
- expect(dateInput === null || dateInput === void 0 ? void 0 : dateInput.id).toBe(label === null || label === void 0 ? void 0 : label.htmlFor);
79
77
  });
80
78
  it('should render an input placeholder', async () => {
81
79
  const placeholder = 'Placeholder';
@@ -110,8 +110,6 @@ function parseLocaleDate(dateString = '', locale, timeZone) {
110
110
  ---
111
111
  category: components
112
112
  ---
113
-
114
- @module experimental
115
113
  **/
116
114
  const DateInput2 = ({
117
115
  renderLabel,
@@ -131,8 +129,10 @@ const DateInput2 = ({
131
129
  placeholder,
132
130
  dateFormat,
133
131
  onRequestValidateDate,
132
+ disabledDates,
134
133
  renderCalendarIcon,
135
- // margin, TODO enable this prop
134
+ margin,
135
+ inputRef,
136
136
  ...rest
137
137
  }) => {
138
138
  const localeContext = useContext(ApplyLocaleContext);
@@ -250,7 +250,7 @@ const DateInput2 = ({
250
250
  };
251
251
  const selectedDate = parseDate(value)[1];
252
252
  return jsx(TextInput, Object.assign({}, passthroughProps(rest), {
253
- // margin={'large'} TODO add this prop to TextInput
253
+ inputRef: inputRef,
254
254
  renderLabel: renderLabel,
255
255
  onChange: handleInputChange,
256
256
  onBlur: handleBlur,
@@ -261,6 +261,7 @@ const DateInput2 = ({
261
261
  display: isInline ? 'inline-block' : 'block',
262
262
  messages: inputMessages,
263
263
  interaction: interaction,
264
+ margin: margin,
264
265
  renderAfterInput: jsx(Popover, {
265
266
  renderTrigger: jsx(IconButton, {
266
267
  withBackground: false,
@@ -280,6 +281,7 @@ const DateInput2 = ({
280
281
  withYearPicker: withYearPicker,
281
282
  onDateSelected: handleDateSelected,
282
283
  selectedDate: selectedDate,
284
+ disabledDates: disabledDates,
283
285
  visibleMonth: selectedDate,
284
286
  locale: getLocale(),
285
287
  timezone: getTimezone(),
@@ -43,6 +43,9 @@ const propTypes = {
43
43
  withYearPicker: PropTypes.object,
44
44
  dateFormat: PropTypes.oneOfType([PropTypes.string, PropTypes.object]),
45
45
  onRequestValidateDate: PropTypes.func,
46
- renderCalendarIcon: PropTypes.oneOfType([PropTypes.node, PropTypes.func])
46
+ renderCalendarIcon: PropTypes.oneOfType([PropTypes.node, PropTypes.func]),
47
+ margin: PropTypes.string,
48
+ disabledDates: PropTypes.oneOfType([PropTypes.array, PropTypes.func]),
49
+ inputRef: PropTypes.func
47
50
  };
48
51
  export { propTypes };
@@ -265,7 +265,7 @@ describe('<DateInput />', () => {
265
265
  onRequestShowCalendar: onRequestShowCalendar
266
266
  }, generateDays())),
267
267
  container = _render5.container;
268
- const dateInput = container.querySelector("[class$='-formFieldLabel']");
268
+ const dateInput = container.querySelector('span[class$="-formFieldLayout__label"]');
269
269
  expect(dateInput).toHaveTextContent('Choose date');
270
270
  await _userEvent.default.click(dateInput);
271
271
  await (0, _react2.waitFor)(() => {
@@ -75,11 +75,9 @@ describe('<DateInput2 />', () => {
75
75
  it('should render an input label', async () => {
76
76
  const _render2 = (0, _react2.render)(_DateInputExample2 || (_DateInputExample2 = /*#__PURE__*/_react.default.createElement(DateInputExample, null))),
77
77
  container = _render2.container;
78
- const dateInput = container.querySelector('input');
79
78
  const label = container.querySelector('label');
80
79
  expect(label).toBeInTheDocument();
81
80
  expect(label).toHaveTextContent(LABEL_TEXT);
82
- expect(dateInput === null || dateInput === void 0 ? void 0 : dateInput.id).toBe(label === null || label === void 0 ? void 0 : label.htmlFor);
83
81
  });
84
82
  it('should render an input placeholder', async () => {
85
83
  const placeholder = 'Placeholder';
@@ -120,8 +120,6 @@ function parseLocaleDate(dateString = '', locale, timeZone) {
120
120
  ---
121
121
  category: components
122
122
  ---
123
-
124
- @module experimental
125
123
  **/
126
124
  const DateInput2 = ({
127
125
  renderLabel,
@@ -141,8 +139,10 @@ const DateInput2 = ({
141
139
  placeholder,
142
140
  dateFormat,
143
141
  onRequestValidateDate,
142
+ disabledDates,
144
143
  renderCalendarIcon,
145
- // margin, TODO enable this prop
144
+ margin,
145
+ inputRef,
146
146
  ...rest
147
147
  }) => {
148
148
  const localeContext = (0, _react.useContext)(_ApplyLocaleContext.ApplyLocaleContext);
@@ -260,7 +260,7 @@ const DateInput2 = ({
260
260
  };
261
261
  const selectedDate = parseDate(value)[1];
262
262
  return (0, _emotion.jsx)(_TextInput.TextInput, Object.assign({}, (0, _passthroughProps.passthroughProps)(rest), {
263
- // margin={'large'} TODO add this prop to TextInput
263
+ inputRef: inputRef,
264
264
  renderLabel: renderLabel,
265
265
  onChange: handleInputChange,
266
266
  onBlur: handleBlur,
@@ -271,6 +271,7 @@ const DateInput2 = ({
271
271
  display: isInline ? 'inline-block' : 'block',
272
272
  messages: inputMessages,
273
273
  interaction: interaction,
274
+ margin: margin,
274
275
  renderAfterInput: (0, _emotion.jsx)(_Popover.Popover, {
275
276
  renderTrigger: (0, _emotion.jsx)(_IconButton.IconButton, {
276
277
  withBackground: false,
@@ -290,6 +291,7 @@ const DateInput2 = ({
290
291
  withYearPicker: withYearPicker,
291
292
  onDateSelected: handleDateSelected,
292
293
  selectedDate: selectedDate,
294
+ disabledDates: disabledDates,
293
295
  visibleMonth: selectedDate,
294
296
  locale: getLocale(),
295
297
  timezone: getTimezone(),
@@ -50,5 +50,8 @@ const propTypes = exports.propTypes = {
50
50
  withYearPicker: _propTypes.default.object,
51
51
  dateFormat: _propTypes.default.oneOfType([_propTypes.default.string, _propTypes.default.object]),
52
52
  onRequestValidateDate: _propTypes.default.func,
53
- renderCalendarIcon: _propTypes.default.oneOfType([_propTypes.default.node, _propTypes.default.func])
53
+ renderCalendarIcon: _propTypes.default.oneOfType([_propTypes.default.node, _propTypes.default.func]),
54
+ margin: _propTypes.default.string,
55
+ disabledDates: _propTypes.default.oneOfType([_propTypes.default.array, _propTypes.default.func]),
56
+ inputRef: _propTypes.default.func
54
57
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@instructure/ui-date-input",
3
- "version": "10.11.1-snapshot-18",
3
+ "version": "10.12.1-pr-snapshot-1741273500459",
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.11.1-snapshot-18",
27
- "@instructure/ui-babel-preset": "10.11.1-snapshot-18",
28
- "@instructure/ui-buttons": "10.11.1-snapshot-18",
29
- "@instructure/ui-scripts": "10.11.1-snapshot-18",
30
- "@instructure/ui-test-utils": "10.11.1-snapshot-18",
26
+ "@instructure/ui-axe-check": "10.12.1-pr-snapshot-1741273500459",
27
+ "@instructure/ui-babel-preset": "10.12.1-pr-snapshot-1741273500459",
28
+ "@instructure/ui-buttons": "10.12.1-pr-snapshot-1741273500459",
29
+ "@instructure/ui-scripts": "10.12.1-pr-snapshot-1741273500459",
30
+ "@instructure/ui-test-utils": "10.12.1-pr-snapshot-1741273500459",
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.11.1-snapshot-18",
39
- "@instructure/shared-types": "10.11.1-snapshot-18",
40
- "@instructure/ui-calendar": "10.11.1-snapshot-18",
41
- "@instructure/ui-form-field": "10.11.1-snapshot-18",
42
- "@instructure/ui-i18n": "10.11.1-snapshot-18",
43
- "@instructure/ui-icons": "10.11.1-snapshot-18",
44
- "@instructure/ui-popover": "10.11.1-snapshot-18",
45
- "@instructure/ui-position": "10.11.1-snapshot-18",
46
- "@instructure/ui-prop-types": "10.11.1-snapshot-18",
47
- "@instructure/ui-react-utils": "10.11.1-snapshot-18",
48
- "@instructure/ui-selectable": "10.11.1-snapshot-18",
49
- "@instructure/ui-testable": "10.11.1-snapshot-18",
50
- "@instructure/ui-text-input": "10.11.1-snapshot-18",
51
- "@instructure/ui-utils": "10.11.1-snapshot-18",
38
+ "@instructure/emotion": "10.12.1-pr-snapshot-1741273500459",
39
+ "@instructure/shared-types": "10.12.1-pr-snapshot-1741273500459",
40
+ "@instructure/ui-calendar": "10.12.1-pr-snapshot-1741273500459",
41
+ "@instructure/ui-form-field": "10.12.1-pr-snapshot-1741273500459",
42
+ "@instructure/ui-i18n": "10.12.1-pr-snapshot-1741273500459",
43
+ "@instructure/ui-icons": "10.12.1-pr-snapshot-1741273500459",
44
+ "@instructure/ui-popover": "10.12.1-pr-snapshot-1741273500459",
45
+ "@instructure/ui-position": "10.12.1-pr-snapshot-1741273500459",
46
+ "@instructure/ui-prop-types": "10.12.1-pr-snapshot-1741273500459",
47
+ "@instructure/ui-react-utils": "10.12.1-pr-snapshot-1741273500459",
48
+ "@instructure/ui-selectable": "10.12.1-pr-snapshot-1741273500459",
49
+ "@instructure/ui-testable": "10.12.1-pr-snapshot-1741273500459",
50
+ "@instructure/ui-text-input": "10.12.1-pr-snapshot-1741273500459",
51
+ "@instructure/ui-utils": "10.12.1-pr-snapshot-1741273500459",
52
52
  "moment-timezone": "^0.5.45",
53
53
  "prop-types": "^15.8.1"
54
54
  },
@@ -2,7 +2,7 @@
2
2
  describes: DateInput
3
3
  ---
4
4
 
5
- > _Note:_ you can now try the updated (but still experimental) [`DateInput2`](/#DateInput2) which is easier to configure for developers, has a better UX, better accessibility features and a year picker. We recommend using that instead of `DateInput` which will be deprecated in the future.
5
+ > _Note:_ we recommend to update to the new [`DateInput2`](/#DateInput2) which is easier to configure for developers, has a better UX, better accessibility features and a year picker. `DateInput` will be deprecated in the future.
6
6
 
7
7
  The `DateInput` component provides a visual interface for inputting date data.
8
8
 
@@ -381,7 +381,9 @@ describe('<DateInput />', () => {
381
381
  {generateDays()}
382
382
  </DateInput>
383
383
  )
384
- const dateInput = container.querySelector("[class$='-formFieldLabel']")
384
+ const dateInput = container.querySelector(
385
+ 'span[class$="-formFieldLayout__label"]'
386
+ )
385
387
 
386
388
  expect(dateInput).toHaveTextContent('Choose date')
387
389
 
@@ -305,3 +305,38 @@ render(<Example />)
305
305
  ### Date format hint
306
306
 
307
307
  If the `placeholder` property is undefined it will display a hint for the date format (like `DD/MM/YYYY`). Usually it is recommended to leave it as it is for a better user experience.
308
+
309
+ ### Disabling dates
310
+
311
+ You can use the `disabledDates` prop to disable specific dates. It accepts either an array of ISO8601 date strings or a function. Keep in mind that this will only disable the dates in the calendar and does not prevent the user the enter them into the input field. To validate those values please use the `onRequestValidateDate` prop.
312
+
313
+ ```js
314
+ ---
315
+ type: example
316
+ ---
317
+ const Example = () => {
318
+ const [inputValue, setInputValue] = useState('2/5/2025')
319
+ const [dateString, setDateString] = useState('')
320
+ return (
321
+ <DateInput2
322
+ renderLabel="Choose a date"
323
+ disabledDates={['2025-02-11', '2025-02-12', '2025-02-13']}
324
+ screenReaderLabels={{
325
+ calendarIcon: 'Calendar',
326
+ nextMonthButton: 'Next month',
327
+ prevMonthButton: 'Previous month'
328
+ }}
329
+ value={inputValue}
330
+ locale="en-us"
331
+ width="20rem"
332
+ onChange={(e, inputValue, dateString) => {
333
+ setInputValue(inputValue)
334
+ setDateString(dateString)
335
+ }}
336
+ invalidDateErrorMessage="Invalid date"
337
+ />
338
+ )
339
+ }
340
+
341
+ render(<Example />)
342
+ ```
@@ -77,12 +77,10 @@ describe('<DateInput2 />', () => {
77
77
  it('should render an input label', async () => {
78
78
  const { container } = render(<DateInputExample />)
79
79
 
80
- const dateInput = container.querySelector('input')
81
80
  const label = container.querySelector('label')
82
81
 
83
82
  expect(label).toBeInTheDocument()
84
83
  expect(label).toHaveTextContent(LABEL_TEXT)
85
- expect(dateInput?.id).toBe(label?.htmlFor)
86
84
  })
87
85
 
88
86
  it('should render an input placeholder', async () => {
@@ -131,8 +131,6 @@ function parseLocaleDate(
131
131
  ---
132
132
  category: components
133
133
  ---
134
-
135
- @module experimental
136
134
  **/
137
135
  const DateInput2 = ({
138
136
  renderLabel,
@@ -152,8 +150,10 @@ const DateInput2 = ({
152
150
  placeholder,
153
151
  dateFormat,
154
152
  onRequestValidateDate,
153
+ disabledDates,
155
154
  renderCalendarIcon,
156
- // margin, TODO enable this prop
155
+ margin,
156
+ inputRef,
157
157
  ...rest
158
158
  }: DateInput2Props) => {
159
159
  const localeContext = useContext(ApplyLocaleContext)
@@ -275,10 +275,11 @@ const DateInput2 = ({
275
275
  }
276
276
 
277
277
  const selectedDate = parseDate(value)[1]
278
+
278
279
  return (
279
280
  <TextInput
280
281
  {...passthroughProps(rest)}
281
- // margin={'large'} TODO add this prop to TextInput
282
+ inputRef={inputRef}
282
283
  renderLabel={renderLabel}
283
284
  onChange={handleInputChange}
284
285
  onBlur={handleBlur}
@@ -289,6 +290,7 @@ const DateInput2 = ({
289
290
  display={isInline ? 'inline-block' : 'block'}
290
291
  messages={inputMessages}
291
292
  interaction={interaction}
293
+ margin={margin}
292
294
  renderAfterInput={
293
295
  <Popover
294
296
  renderTrigger={
@@ -318,6 +320,7 @@ const DateInput2 = ({
318
320
  withYearPicker={withYearPicker}
319
321
  onDateSelected={handleDateSelected}
320
322
  selectedDate={selectedDate}
323
+ disabledDates={disabledDates}
321
324
  visibleMonth={selectedDate}
322
325
  locale={getLocale()}
323
326
  timezone={getTimezone()}
@@ -33,6 +33,7 @@ import type {
33
33
  Renderable,
34
34
  PropValidators
35
35
  } from '@instructure/shared-types'
36
+ import type { Spacing } from '@instructure/emotion'
36
37
 
37
38
  type DateInput2OwnProps = {
38
39
  /**
@@ -164,12 +165,27 @@ type DateInput2OwnProps = {
164
165
  value: string,
165
166
  utcDateString: string
166
167
  ) => void
167
- // margin?: Spacing // TODO enable this prop
168
168
 
169
169
  /**
170
170
  * Custom icon for the icon button opening the picker.
171
171
  */
172
172
  renderCalendarIcon?: Renderable
173
+
174
+ /**
175
+ * Margin around the component. Accepts a `Spacing` token. See token values and example usage in [this guide](https://instructure.design/#layout-spacing).
176
+ */
177
+ margin?: Spacing
178
+ /*
179
+ * Specify which date(s) will be shown as disabled in the calendar.
180
+ * You can either supply an array of ISO8601 timeDate strings or
181
+ * a function that will be called for each date shown in the calendar.
182
+ */
183
+ disabledDates?: string[] | ((isoDateToCheck: string) => boolean)
184
+
185
+ /**
186
+ * A function that provides a reference to the inner input element
187
+ */
188
+ inputRef?: (inputElement: HTMLInputElement | null) => void
173
189
  }
174
190
 
175
191
  type PropKeys = keyof DateInput2OwnProps
@@ -201,7 +217,10 @@ const propTypes: PropValidators<PropKeys> = {
201
217
  withYearPicker: PropTypes.object,
202
218
  dateFormat: PropTypes.oneOfType([PropTypes.string, PropTypes.object]),
203
219
  onRequestValidateDate: PropTypes.func,
204
- renderCalendarIcon: PropTypes.oneOfType([PropTypes.node, PropTypes.func])
220
+ renderCalendarIcon: PropTypes.oneOfType([PropTypes.node, PropTypes.func]),
221
+ margin: PropTypes.string,
222
+ disabledDates: PropTypes.oneOfType([PropTypes.array, PropTypes.func]),
223
+ inputRef: PropTypes.func
205
224
  }
206
225
 
207
226
  export type { DateInput2Props }