@ionic/core 7.5.3-nightly.20231031 → 7.5.3

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.
@@ -94,6 +94,13 @@ export class Datetime {
94
94
  this.workingParts = Object.assign({}, parts);
95
95
  };
96
96
  this.setActiveParts = (parts, removeDate = false) => {
97
+ /** if the datetime component is in readonly mode,
98
+ * allow browsing of the calendar without changing
99
+ * the set value
100
+ */
101
+ if (this.readonly) {
102
+ return;
103
+ }
97
104
  const { multiple, minParts, maxParts, activeParts } = this;
98
105
  /**
99
106
  * When setting the active parts, it is possible
@@ -914,7 +921,13 @@ export class Datetime {
914
921
  * are rendered independently of presentation.
915
922
  */
916
923
  renderFooter() {
917
- const { showDefaultButtons, showClearButton } = this;
924
+ const { disabled, readonly, showDefaultButtons, showClearButton } = this;
925
+ /**
926
+ * The cancel, clear, and confirm buttons
927
+ * should not be interactive if the datetime
928
+ * is disabled or readonly.
929
+ */
930
+ const isButtonDisabled = disabled || readonly;
918
931
  const hasSlottedButtons = this.el.querySelector('[slot="buttons"]') !== null;
919
932
  if (!hasSlottedButtons && !showDefaultButtons && !showClearButton) {
920
933
  return;
@@ -933,7 +946,7 @@ export class Datetime {
933
946
  return (h("div", { class: "datetime-footer" }, h("div", { class: "datetime-buttons" }, h("div", { class: {
934
947
  ['datetime-action-buttons']: true,
935
948
  ['has-clear-button']: this.showClearButton,
936
- } }, h("slot", { name: "buttons" }, h("ion-buttons", null, showDefaultButtons && (h("ion-button", { id: "cancel-button", color: this.color, onClick: () => this.cancel(true) }, this.cancelText)), h("div", { class: "datetime-action-buttons-container" }, showClearButton && (h("ion-button", { id: "clear-button", color: this.color, onClick: () => clearButtonClick() }, this.clearText)), showDefaultButtons && (h("ion-button", { id: "confirm-button", color: this.color, onClick: () => this.confirm(true) }, this.doneText)))))))));
949
+ } }, h("slot", { name: "buttons" }, h("ion-buttons", null, showDefaultButtons && (h("ion-button", { id: "cancel-button", color: this.color, onClick: () => this.cancel(true), disabled: isButtonDisabled }, this.cancelText)), h("div", { class: "datetime-action-buttons-container" }, showClearButton && (h("ion-button", { id: "clear-button", color: this.color, onClick: () => clearButtonClick(), disabled: isButtonDisabled }, this.clearText)), showDefaultButtons && (h("ion-button", { id: "confirm-button", color: this.color, onClick: () => this.confirm(true), disabled: isButtonDisabled }, this.doneText)))))))));
937
950
  }
938
951
  /**
939
952
  * Wheel picker render methods
@@ -1224,13 +1237,14 @@ export class Datetime {
1224
1237
  * Grid Render Methods
1225
1238
  */
1226
1239
  renderCalendarHeader(mode) {
1240
+ const { disabled } = this;
1227
1241
  const expandedIcon = mode === 'ios' ? chevronDown : caretUpSharp;
1228
1242
  const collapsedIcon = mode === 'ios' ? chevronForward : caretDownSharp;
1229
- const prevMonthDisabled = isPrevMonthDisabled(this.workingParts, this.minParts, this.maxParts);
1230
- const nextMonthDisabled = isNextMonthDisabled(this.workingParts, this.maxParts);
1243
+ const prevMonthDisabled = disabled || isPrevMonthDisabled(this.workingParts, this.minParts, this.maxParts);
1244
+ const nextMonthDisabled = disabled || isNextMonthDisabled(this.workingParts, this.maxParts);
1231
1245
  // don't use the inheritAttributes util because it removes dir from the host, and we still need that
1232
1246
  const hostDir = this.el.getAttribute('dir') || undefined;
1233
- return (h("div", { class: "calendar-header" }, h("div", { class: "calendar-action-buttons" }, h("div", { class: "calendar-month-year" }, h("ion-item", { part: "month-year-button", ref: (el) => (this.monthYearToggleItemRef = el), button: true, "aria-label": "Show year picker", detail: false, lines: "none", onClick: () => {
1247
+ return (h("div", { class: "calendar-header" }, h("div", { class: "calendar-action-buttons" }, h("div", { class: "calendar-month-year" }, h("ion-item", { part: "month-year-button", ref: (el) => (this.monthYearToggleItemRef = el), button: true, "aria-label": "Show year picker", detail: false, lines: "none", disabled: disabled, onClick: () => {
1234
1248
  var _a;
1235
1249
  this.toggleMonthAndYearView();
1236
1250
  /**
@@ -1254,20 +1268,23 @@ export class Datetime {
1254
1268
  }))));
1255
1269
  }
1256
1270
  renderMonth(month, year) {
1271
+ const { disabled, readonly } = this;
1257
1272
  const yearAllowed = this.parsedYearValues === undefined || this.parsedYearValues.includes(year);
1258
1273
  const monthAllowed = this.parsedMonthValues === undefined || this.parsedMonthValues.includes(month);
1259
1274
  const isCalMonthDisabled = !yearAllowed || !monthAllowed;
1260
- const swipeDisabled = isMonthDisabled({
1261
- month,
1262
- year,
1263
- day: null,
1264
- }, {
1265
- // The day is not used when checking if a month is disabled.
1266
- // Users should be able to access the min or max month, even if the
1267
- // min/max date is out of bounds (e.g. min is set to Feb 15, Feb should not be disabled).
1268
- minParts: Object.assign(Object.assign({}, this.minParts), { day: null }),
1269
- maxParts: Object.assign(Object.assign({}, this.maxParts), { day: null }),
1270
- });
1275
+ const isDatetimeDisabled = disabled || readonly;
1276
+ const swipeDisabled = disabled ||
1277
+ isMonthDisabled({
1278
+ month,
1279
+ year,
1280
+ day: null,
1281
+ }, {
1282
+ // The day is not used when checking if a month is disabled.
1283
+ // Users should be able to access the min or max month, even if the
1284
+ // min/max date is out of bounds (e.g. min is set to Feb 15, Feb should not be disabled).
1285
+ minParts: Object.assign(Object.assign({}, this.minParts), { day: null }),
1286
+ maxParts: Object.assign(Object.assign({}, this.maxParts), { day: null }),
1287
+ });
1271
1288
  // The working month should never have swipe disabled.
1272
1289
  // Otherwise the CSS scroll snap will not work and the user
1273
1290
  // can free-scroll the calendar.
@@ -1282,9 +1299,9 @@ export class Datetime {
1282
1299
  const { el, highlightedDates, isDateEnabled, multiple } = this;
1283
1300
  const referenceParts = { month, day, year };
1284
1301
  const isCalendarPadding = day === null;
1285
- const { isActive, isToday, ariaLabel, ariaSelected, disabled, text } = getCalendarDayState(this.locale, referenceParts, this.activeParts, this.todayParts, this.minParts, this.maxParts, this.parsedDayValues);
1302
+ const { isActive, isToday, ariaLabel, ariaSelected, disabled: isDayDisabled, text, } = getCalendarDayState(this.locale, referenceParts, this.activeParts, this.todayParts, this.minParts, this.maxParts, this.parsedDayValues);
1286
1303
  const dateIsoString = convertDataToISO(referenceParts);
1287
- let isCalDayDisabled = isCalMonthDisabled || disabled;
1304
+ let isCalDayDisabled = isCalMonthDisabled || isDayDisabled;
1288
1305
  if (!isCalDayDisabled && isDateEnabled !== undefined) {
1289
1306
  try {
1290
1307
  /**
@@ -1298,6 +1315,13 @@ export class Datetime {
1298
1315
  printIonError('Exception thrown from provided `isDateEnabled` function. Please check your function and try again.', el, e);
1299
1316
  }
1300
1317
  }
1318
+ /**
1319
+ * Some days are constrained through max & min or allowed dates
1320
+ * and also disabled because the component is readonly or disabled.
1321
+ * These need to be displayed differently.
1322
+ */
1323
+ const isCalDayConstrained = isCalDayDisabled && isDatetimeDisabled;
1324
+ const isButtonDisabled = isCalDayDisabled || isDatetimeDisabled;
1301
1325
  let dateStyle = undefined;
1302
1326
  /**
1303
1327
  * Custom highlight styles should not override the style for selected dates,
@@ -1324,10 +1348,11 @@ export class Datetime {
1324
1348
  el.style.setProperty('color', `${dateStyle ? dateStyle.textColor : ''}`, 'important');
1325
1349
  el.style.setProperty('background-color', `${dateStyle ? dateStyle.backgroundColor : ''}`, 'important');
1326
1350
  }
1327
- }, tabindex: "-1", "data-day": day, "data-month": month, "data-year": year, "data-index": index, "data-day-of-week": dayOfWeek, disabled: isCalDayDisabled, class: {
1351
+ }, tabindex: "-1", "data-day": day, "data-month": month, "data-year": year, "data-index": index, "data-day-of-week": dayOfWeek, disabled: isButtonDisabled, class: {
1328
1352
  'calendar-day-padding': isCalendarPadding,
1329
1353
  'calendar-day': true,
1330
1354
  'calendar-day-active': isActive,
1355
+ 'calendar-day-constrained': isCalDayConstrained,
1331
1356
  'calendar-day-today': isToday,
1332
1357
  }, part: dateParts, "aria-hidden": isCalendarPadding ? 'true' : null, "aria-selected": ariaSelected, "aria-label": ariaLabel, onClick: () => {
1333
1358
  if (isCalendarPadding) {
@@ -1369,7 +1394,7 @@ export class Datetime {
1369
1394
  return h("slot", { name: "time-label" }, "Time");
1370
1395
  }
1371
1396
  renderTimeOverlay() {
1372
- const { hourCycle, isTimePopoverOpen, locale } = this;
1397
+ const { disabled, hourCycle, isTimePopoverOpen, locale } = this;
1373
1398
  const computedHourCycle = getHourCycle(locale, hourCycle);
1374
1399
  const activePart = this.getActivePartsWithFallback();
1375
1400
  return [
@@ -1377,7 +1402,7 @@ export class Datetime {
1377
1402
  h("button", { class: {
1378
1403
  'time-body': true,
1379
1404
  'time-body-active': isTimePopoverOpen,
1380
- }, part: `time-button${isTimePopoverOpen ? ' active' : ''}`, "aria-expanded": "false", "aria-haspopup": "true", onClick: async (ev) => {
1405
+ }, part: `time-button${isTimePopoverOpen ? ' active' : ''}`, "aria-expanded": "false", "aria-haspopup": "true", disabled: disabled, onClick: async (ev) => {
1381
1406
  const { popoverRef } = this;
1382
1407
  if (popoverRef) {
1383
1408
  this.isTimePopoverOpen = true;
@@ -1617,7 +1642,7 @@ export class Datetime {
1617
1642
  "optional": false,
1618
1643
  "docs": {
1619
1644
  "tags": [],
1620
- "text": "If `true`, the datetime appears normal but is not interactive."
1645
+ "text": "If `true`, the datetime appears normal but the selected date cannot be changed."
1621
1646
  },
1622
1647
  "attribute": "readonly",
1623
1648
  "reflect": false,
@@ -224,15 +224,35 @@ ion-picker-column-internal {
224
224
  display: none;
225
225
  }
226
226
 
227
- :host(.datetime-readonly),
228
227
  :host(.datetime-disabled) {
229
228
  pointer-events: none;
230
229
  }
231
-
232
- :host(.datetime-disabled) {
230
+ :host(.datetime-disabled) .calendar-days-of-week,
231
+ :host(.datetime-disabled) .datetime-time {
233
232
  opacity: 0.4;
234
233
  }
235
234
 
235
+ :host(.datetime-readonly) {
236
+ pointer-events: none;
237
+ /**
238
+ * Allow user to navigate months
239
+ * while in readonly mode
240
+ */
241
+ /**
242
+ * Disabled buttons should have full opacity
243
+ * in readonly mode
244
+ */
245
+ }
246
+ :host(.datetime-readonly) .calendar-action-buttons,
247
+ :host(.datetime-readonly) .calendar-body,
248
+ :host(.datetime-readonly) .datetime-year {
249
+ pointer-events: initial;
250
+ }
251
+ :host(.datetime-readonly) .calendar-day[disabled]:not(.calendar-day-constrained),
252
+ :host(.datetime-readonly) .datetime-action-buttons ion-button[disabled] {
253
+ opacity: 1;
254
+ }
255
+
236
256
  /**
237
257
  * Title should not wrap
238
258
  * to the next line and should
@@ -26,3 +26,69 @@ configs({ directions: ['ltr'] }).forEach(({ title, screenshot, config }) => {
26
26
  });
27
27
  });
28
28
  });
29
+ /**
30
+ * This behavior does not differ across
31
+ * modes/directions.
32
+ */
33
+ configs({ modes: ['ios'], directions: ['ltr'] }).forEach(({ title, config }) => {
34
+ test.describe(title('datetime: a11y'), () => {
35
+ test('datetime should be keyboard navigable', async ({ page, browserName }) => {
36
+ await page.setContent(`
37
+ <ion-datetime value="2022-02-22T16:30:00"></ion-datetime>
38
+ `, config);
39
+ const tabKey = browserName === 'webkit' ? 'Alt+Tab' : 'Tab';
40
+ const datetime = page.locator('ion-datetime');
41
+ const monthYearButton = page.locator('.calendar-month-year ion-item');
42
+ const prevButton = page.locator('.calendar-next-prev ion-button:nth-child(1)');
43
+ const nextButton = page.locator('.calendar-next-prev ion-button:nth-child(2)');
44
+ await page.keyboard.press(tabKey);
45
+ await expect(monthYearButton).toBeFocused();
46
+ await page.keyboard.press(tabKey);
47
+ await expect(prevButton).toBeFocused();
48
+ await page.keyboard.press(tabKey);
49
+ await expect(nextButton).toBeFocused();
50
+ // check value before & after selecting via keyboard
51
+ const initialValue = await datetime.evaluate((el) => el.value);
52
+ expect(initialValue).toBe('2022-02-22T16:30:00');
53
+ await page.keyboard.press(tabKey);
54
+ await page.waitForChanges();
55
+ await page.keyboard.press('ArrowLeft');
56
+ await page.waitForChanges();
57
+ await page.keyboard.press('Enter');
58
+ await page.waitForChanges();
59
+ const newValue = await datetime.evaluate((el) => el.value);
60
+ expect(newValue).not.toBe('2022-02-22T16:30:00');
61
+ });
62
+ test('buttons should be keyboard navigable', async ({ page }) => {
63
+ await page.setContent(`
64
+
65
+ <ion-datetime value="2022-02-22T16:30:00" show-default-buttons="true" show-clear-button="true"></ion-datetime>
66
+ `, config);
67
+ await page.waitForSelector('.datetime-ready');
68
+ const clearButton = page.locator('#clear-button button');
69
+ const selectedDay = page.locator('.calendar-day-active');
70
+ await expect(selectedDay).toHaveText('22');
71
+ await clearButton.focus();
72
+ await page.waitForChanges();
73
+ await expect(clearButton).toBeFocused();
74
+ await page.keyboard.press('Enter');
75
+ await page.waitForChanges();
76
+ await expect(selectedDay).toHaveCount(0);
77
+ });
78
+ test('should navigate through months via right arrow key', async ({ page }) => {
79
+ await page.setContent(`
80
+
81
+ <ion-datetime value="2022-02-28"></ion-datetime>
82
+ `, config);
83
+ await page.waitForSelector('.datetime-ready');
84
+ const calendarMonthYear = page.locator('ion-datetime .calendar-month-year');
85
+ const calendarBody = page.locator('.calendar-body');
86
+ await expect(calendarMonthYear).toHaveText('February 2022');
87
+ await calendarBody.focus();
88
+ await page.waitForChanges();
89
+ await page.keyboard.press('ArrowRight');
90
+ await page.waitForChanges();
91
+ await expect(calendarMonthYear).toHaveText('March 2022');
92
+ });
93
+ });
94
+ });
@@ -0,0 +1,68 @@
1
+ /*!
2
+ * (C) Ionic http://ionicframework.com - MIT License
3
+ */
4
+ import { expect } from "@playwright/test";
5
+ import { configs, test } from "../../../../utils/test/playwright/index";
6
+ /**
7
+ * This behavior does not differ across
8
+ * modes/directions.
9
+ */
10
+ configs({ modes: ['ios'], directions: ['ltr'] }).forEach(({ title, config, screenshot }) => {
11
+ test.describe(title('datetime: disabled'), () => {
12
+ test('should not have visual regressions', async ({ page }) => {
13
+ await page.setContent(`
14
+ <ion-datetime value="2022-02-05T00:00:00" min="2022-01-01T00:00:00" max="2022-02-20T23:59:59" day-values="5,6,10,11,15,16,20" show-default-buttons disabled></ion-datetime>
15
+ `, config);
16
+ const datetime = page.locator('ion-datetime');
17
+ await expect(datetime).toHaveScreenshot(screenshot(`datetime-disabled`));
18
+ });
19
+ test('date should be disabled', async ({ page }) => {
20
+ await page.setContent(`
21
+ <ion-datetime value="2022-02-28" disabled></ion-datetime>
22
+ `, config);
23
+ await page.waitForSelector('.datetime-ready');
24
+ const febFirstButton = page.locator(`.calendar-day[data-day='1'][data-month='2']`);
25
+ await expect(febFirstButton).toBeDisabled();
26
+ });
27
+ test('month-year button should be disabled', async ({ page }) => {
28
+ await page.setContent(`
29
+ <ion-datetime value="2022-02-28" disabled></ion-datetime>
30
+ `, config);
31
+ await page.waitForSelector('.datetime-ready');
32
+ const calendarMonthYear = page.locator('ion-datetime .calendar-month-year');
33
+ await expect(calendarMonthYear.locator('button')).toBeDisabled();
34
+ });
35
+ test('next and prev buttons should be disabled', async ({ page }) => {
36
+ await page.setContent(`
37
+ <ion-datetime value="2022-02-28" disabled></ion-datetime>
38
+ `, config);
39
+ const prevMonthButton = page.locator('ion-datetime .calendar-next-prev ion-button:first-of-type button');
40
+ const nextMonthButton = page.locator('ion-datetime .calendar-next-prev ion-button:last-of-type button');
41
+ await expect(prevMonthButton).toBeDisabled();
42
+ await expect(nextMonthButton).toBeDisabled();
43
+ });
44
+ test('clear button should be disabled', async ({ page }) => {
45
+ await page.setContent(`
46
+
47
+ <ion-datetime value="2022-02-22T16:30:00" show-default-buttons="true" show-clear-button="true" disabled></ion-datetime>
48
+ `, config);
49
+ await page.waitForSelector('.datetime-ready');
50
+ const clearButton = page.locator('#clear-button button');
51
+ await expect(clearButton).toBeDisabled();
52
+ });
53
+ test('should not navigate through months via right arrow key', async ({ page }) => {
54
+ await page.setContent(`
55
+ <ion-datetime value="2022-02-28" disabled></ion-datetime>
56
+ `, config);
57
+ await page.waitForSelector('.datetime-ready');
58
+ const calendarMonthYear = page.locator('ion-datetime .calendar-month-year');
59
+ const calendarBody = page.locator('.calendar-body');
60
+ await expect(calendarMonthYear).toHaveText('February 2022');
61
+ await calendarBody.focus();
62
+ await page.waitForChanges();
63
+ await page.keyboard.press('ArrowRight');
64
+ await page.waitForChanges();
65
+ await expect(calendarMonthYear).toHaveText('February 2022');
66
+ });
67
+ });
68
+ });
@@ -0,0 +1,113 @@
1
+ /*!
2
+ * (C) Ionic http://ionicframework.com - MIT License
3
+ */
4
+ import { expect } from "@playwright/test";
5
+ import { configs, test } from "../../../../utils/test/playwright/index";
6
+ /**
7
+ * This behavior does not differ across
8
+ * modes/directions.
9
+ */
10
+ configs({ modes: ['ios'], directions: ['ltr'] }).forEach(({ title, config, screenshot }) => {
11
+ test.describe(title('datetime: readonly'), () => {
12
+ test('should not have visual regressions', async ({ page }) => {
13
+ await page.setContent(`
14
+ <ion-datetime value="2022-02-05T00:00:00" min="2022-01-01T00:00:00" max="2022-02-20T23:59:59" day-values="5,6,10,11,15,16,20" show-default-buttons readonly></ion-datetime>
15
+ `, config);
16
+ const datetime = page.locator('ion-datetime');
17
+ await expect(datetime).toHaveScreenshot(screenshot(`datetime-readonly`));
18
+ });
19
+ test('date should be disabled', async ({ page }) => {
20
+ await page.setContent(`
21
+ <ion-datetime value="2022-02-28" readonly></ion-datetime>
22
+ `, config);
23
+ await page.waitForSelector('.datetime-ready');
24
+ const febFirstButton = page.locator(`.calendar-day[data-day='1'][data-month='2']`);
25
+ await expect(febFirstButton).toBeDisabled();
26
+ });
27
+ test('should navigate months via month-year button', async ({ page }) => {
28
+ await page.setContent(`
29
+ <ion-datetime value="2022-02-22T16:30:00" readonly></ion-datetime>
30
+ `, config);
31
+ const ionChange = await page.spyOnEvent('ionChange');
32
+ await page.waitForSelector('.datetime-ready');
33
+ const calendarMonthYear = page.locator('ion-datetime .calendar-month-year');
34
+ await expect(calendarMonthYear).toHaveText('February 2022');
35
+ await calendarMonthYear.click();
36
+ await page.waitForChanges();
37
+ await page.locator('.month-column .picker-item[data-value="3"]').click();
38
+ await page.waitForChanges();
39
+ await expect(calendarMonthYear).toHaveText('March 2022');
40
+ await expect(ionChange).not.toHaveReceivedEvent();
41
+ });
42
+ test('should open picker using keyboard navigation', async ({ page, browserName }) => {
43
+ await page.setContent(`
44
+ <ion-datetime value="2022-02-22T16:30:00" readonly></ion-datetime>
45
+ `, config);
46
+ const tabKey = browserName === 'webkit' ? 'Alt+Tab' : 'Tab';
47
+ await page.waitForSelector('.datetime-ready');
48
+ const calendarMonthYear = page.locator('ion-datetime .calendar-month-year');
49
+ const monthYearButton = page.locator('.calendar-month-year ion-item');
50
+ await expect(calendarMonthYear).toHaveText('February 2022');
51
+ await page.keyboard.press(tabKey);
52
+ await expect(monthYearButton).toBeFocused();
53
+ await page.waitForChanges();
54
+ await page.keyboard.press('Enter');
55
+ await page.waitForChanges();
56
+ const marchPickerItem = page.locator('.month-column .picker-item[data-value="3"]');
57
+ await expect(marchPickerItem).toBeVisible();
58
+ });
59
+ test('should view next month via next button', async ({ page }) => {
60
+ await page.setContent(`
61
+ <ion-datetime value="2022-02-22T16:30:00" readonly></ion-datetime>
62
+ `, config);
63
+ const ionChange = await page.spyOnEvent('ionChange');
64
+ const calendarMonthYear = page.locator('ion-datetime .calendar-month-year');
65
+ await expect(calendarMonthYear).toHaveText('February 2022');
66
+ const nextMonthButton = page.locator('ion-datetime .calendar-next-prev ion-button + ion-button');
67
+ await nextMonthButton.click();
68
+ await page.waitForChanges();
69
+ await expect(calendarMonthYear).toHaveText('March 2022');
70
+ await expect(ionChange).not.toHaveReceivedEvent();
71
+ });
72
+ test('should not change value when the month is changed via keyboard navigation', async ({ page, browserName }) => {
73
+ await page.setContent(`
74
+ <ion-datetime value="2022-02-22T16:30:00" readonly></ion-datetime>
75
+ `, config);
76
+ const tabKey = browserName === 'webkit' ? 'Alt+Tab' : 'Tab';
77
+ const datetime = page.locator('ion-datetime');
78
+ const monthYearButton = page.locator('.calendar-month-year ion-item');
79
+ const prevButton = page.locator('.calendar-next-prev ion-button:nth-child(1)');
80
+ const nextButton = page.locator('.calendar-next-prev ion-button:nth-child(2)');
81
+ const calendarMonthYear = page.locator('ion-datetime .calendar-month-year');
82
+ await page.keyboard.press(tabKey);
83
+ await expect(monthYearButton).toBeFocused();
84
+ await page.keyboard.press(tabKey);
85
+ await expect(prevButton).toBeFocused();
86
+ await page.keyboard.press(tabKey);
87
+ await expect(nextButton).toBeFocused();
88
+ // check value before & after selecting via keyboard
89
+ const initialValue = await datetime.evaluate((el) => el.value);
90
+ expect(initialValue).toBe('2022-02-22T16:30:00');
91
+ await expect(calendarMonthYear).toHaveText('February 2022');
92
+ await page.keyboard.press(tabKey);
93
+ await page.waitForChanges();
94
+ await page.keyboard.press('ArrowLeft');
95
+ await page.waitForChanges();
96
+ await expect(calendarMonthYear).toHaveText('January 2022');
97
+ await page.keyboard.press('Enter');
98
+ await page.waitForChanges();
99
+ const newValue = await datetime.evaluate((el) => el.value);
100
+ // should not have changed
101
+ expect(newValue).toBe('2022-02-22T16:30:00');
102
+ });
103
+ test('clear button should be disabled', async ({ page }) => {
104
+ await page.setContent(`
105
+
106
+ <ion-datetime value="2022-02-22T16:30:00" show-default-buttons="true" show-clear-button="true" readonly></ion-datetime>
107
+ `, config);
108
+ await page.waitForSelector('.datetime-ready');
109
+ const clearButton = page.locator('#clear-button button');
110
+ await expect(clearButton).toBeDisabled();
111
+ });
112
+ });
113
+ });
package/dist/docs.json CHANGED
@@ -1,5 +1,5 @@
1
1
  {
2
- "timestamp": "2023-10-31T06:03:42",
2
+ "timestamp": "2023-11-01T13:35:52",
3
3
  "compiler": {
4
4
  "name": "@stencil/core",
5
5
  "version": "4.6.0",
@@ -7477,7 +7477,7 @@
7477
7477
  "mutable": false,
7478
7478
  "attr": "readonly",
7479
7479
  "reflectToAttr": false,
7480
- "docs": "If `true`, the datetime appears normal but is not interactive.",
7480
+ "docs": "If `true`, the datetime appears normal but the selected date cannot be changed.",
7481
7481
  "docsTags": [],
7482
7482
  "default": "false",
7483
7483
  "values": [