@ionic/core 7.7.5 → 7.8.1-nightly.20240314
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/components/data.js +23 -38
- package/components/ion-datetime-button.js +11 -10
- package/components/ion-datetime.js +69 -7
- package/components/ion-searchbar.js +34 -5
- package/components/picker-column-internal.js +8 -4
- package/dist/cjs/{data-a5109f09.js → data-4487a815.js} +22 -39
- package/dist/cjs/ion-datetime-button.cjs.entry.js +11 -10
- package/dist/cjs/ion-datetime_3.cjs.entry.js +66 -7
- package/dist/cjs/ion-picker-column-internal.cjs.entry.js +8 -4
- package/dist/cjs/ion-searchbar.cjs.entry.js +28 -4
- package/dist/cjs/ionic.cjs.js +1 -1
- package/dist/cjs/loader.cjs.js +1 -1
- package/dist/collection/components/alert/test/a11y/alert.e2e.js +4 -0
- package/dist/collection/components/datetime/datetime.js +50 -7
- package/dist/collection/components/datetime/test/basic/datetime.e2e.js +77 -0
- package/dist/collection/components/datetime/test/format.spec.js +65 -15
- package/dist/collection/components/datetime/utils/format.js +24 -37
- package/dist/collection/components/datetime/utils/validate.js +45 -0
- package/dist/collection/components/datetime-button/datetime-button.js +11 -10
- package/dist/collection/components/datetime-button/test/basic/datetime-button.e2e.js +65 -0
- package/dist/collection/components/picker-column-internal/picker-column-internal.js +8 -4
- package/dist/collection/components/searchbar/searchbar.js +84 -5
- package/dist/collection/components/searchbar/test/searchbar.spec.js +20 -2
- package/dist/collection/components/toggle/toggle.js +1 -1
- package/dist/docs.json +114 -2
- package/dist/esm/{data-0f3ab200.js → data-bb424ba8.js} +23 -38
- package/dist/esm/ion-datetime-button.entry.js +11 -10
- package/dist/esm/ion-datetime_3.entry.js +66 -7
- package/dist/esm/ion-picker-column-internal.entry.js +8 -4
- package/dist/esm/ion-searchbar.entry.js +29 -5
- package/dist/esm/ionic.js +1 -1
- package/dist/esm/loader.js +1 -1
- package/dist/esm-es5/data-bb424ba8.js +4 -0
- package/dist/esm-es5/ion-datetime-button.entry.js +1 -1
- package/dist/esm-es5/ion-datetime_3.entry.js +1 -1
- package/dist/esm-es5/ion-picker-column-internal.entry.js +1 -1
- package/dist/esm-es5/ion-searchbar.entry.js +1 -1
- package/dist/esm-es5/ionic.js +1 -1
- package/dist/esm-es5/loader.js +1 -1
- package/dist/html.html-data.json +13 -1
- package/dist/ionic/ionic.esm.js +1 -1
- package/dist/ionic/p-2b77099e.system.entry.js +4 -0
- package/dist/ionic/p-3789920e.js +4 -0
- package/dist/ionic/p-4abb3f9e.entry.js +4 -0
- package/dist/ionic/p-60c9fd9e.system.js +1 -1
- package/dist/ionic/p-8a1b0abb.system.js +4 -0
- package/dist/ionic/p-8a5c2121.entry.js +4 -0
- package/dist/ionic/p-a722d78f.system.entry.js +4 -0
- package/dist/ionic/p-bc56a728.entry.js +4 -0
- package/dist/ionic/{p-0e7c8334.system.entry.js → p-c2a9829c.system.entry.js} +1 -1
- package/dist/ionic/p-cfd31f45.system.entry.js +4 -0
- package/dist/ionic/p-e02681a6.entry.js +4 -0
- package/dist/types/components/datetime/datetime-interface.d.ts +10 -0
- package/dist/types/components/datetime/datetime.d.ts +9 -1
- package/dist/types/components/datetime/utils/format.d.ts +7 -13
- package/dist/types/components/datetime/utils/validate.d.ts +8 -0
- package/dist/types/components/searchbar/searchbar.d.ts +38 -0
- package/dist/types/components/toggle/toggle.d.ts +1 -1
- package/dist/types/components.d.ts +36 -4
- package/hydrate/index.js +135 -60
- package/package.json +1 -1
- package/dist/esm-es5/data-0f3ab200.js +0 -4
- package/dist/ionic/p-6f5b32c7.system.entry.js +0 -4
- package/dist/ionic/p-7330c044.system.js +0 -4
- package/dist/ionic/p-76afa95f.entry.js +0 -4
- package/dist/ionic/p-81f18ed1.system.entry.js +0 -4
- package/dist/ionic/p-c05202a7.entry.js +0 -4
- package/dist/ionic/p-c67c9644.entry.js +0 -4
- package/dist/ionic/p-e447e552.entry.js +0 -4
- package/dist/ionic/p-ef269a56.system.entry.js +0 -4
- package/dist/ionic/p-f7dce541.js +0 -4
|
@@ -404,3 +404,80 @@ configs({ directions: ['ltr'] }).forEach(({ title, screenshot, config }) => {
|
|
|
404
404
|
});
|
|
405
405
|
});
|
|
406
406
|
});
|
|
407
|
+
/**
|
|
408
|
+
* This behavior does not differ across
|
|
409
|
+
* directions.
|
|
410
|
+
*/
|
|
411
|
+
configs({ directions: ['ltr'] }).forEach(({ title, config }) => {
|
|
412
|
+
test.describe(title('datetime: formatOptions'), () => {
|
|
413
|
+
test('should format header and time button', async ({ page }) => {
|
|
414
|
+
await page.setContent(`
|
|
415
|
+
<ion-datetime value="2022-02-01T16:30:00">
|
|
416
|
+
<span slot="title">Select Date</span>
|
|
417
|
+
</ion-datetime>
|
|
418
|
+
<script>
|
|
419
|
+
const datetime = document.querySelector('ion-datetime');
|
|
420
|
+
datetime.formatOptions = {
|
|
421
|
+
time: { hour: '2-digit', minute: '2-digit' },
|
|
422
|
+
date: { day: '2-digit', month: 'long', era: 'short' },
|
|
423
|
+
}
|
|
424
|
+
</script>
|
|
425
|
+
`, config);
|
|
426
|
+
await page.locator('.datetime-ready').waitFor();
|
|
427
|
+
const headerDate = page.locator('ion-datetime .datetime-selected-date');
|
|
428
|
+
await expect(headerDate).toHaveText('February 01 AD');
|
|
429
|
+
const timeBody = page.locator('ion-datetime .time-body');
|
|
430
|
+
await expect(timeBody).toHaveText('04:30 PM');
|
|
431
|
+
});
|
|
432
|
+
});
|
|
433
|
+
});
|
|
434
|
+
/**
|
|
435
|
+
* This behavior does not differ across
|
|
436
|
+
* modes/directions.
|
|
437
|
+
*/
|
|
438
|
+
configs({ modes: ['md'], directions: ['ltr'] }).forEach(({ title, config }) => {
|
|
439
|
+
test.describe(title('datetime: formatOptions misconfiguration errors'), () => {
|
|
440
|
+
test('should log a warning if time zone is provided', async ({ page }) => {
|
|
441
|
+
const logs = [];
|
|
442
|
+
page.on('console', (msg) => {
|
|
443
|
+
if (msg.type() === 'warning') {
|
|
444
|
+
logs.push(msg.text());
|
|
445
|
+
}
|
|
446
|
+
});
|
|
447
|
+
await page.setContent(`
|
|
448
|
+
<ion-datetime value="2022-02-01T16:30:00" presentation="date">
|
|
449
|
+
<span slot="title">Select Date</span>
|
|
450
|
+
</ion-datetime>
|
|
451
|
+
<script>
|
|
452
|
+
const datetime = document.querySelector('ion-datetime');
|
|
453
|
+
datetime.formatOptions = {
|
|
454
|
+
date: { timeZone: 'UTC' },
|
|
455
|
+
}
|
|
456
|
+
</script>
|
|
457
|
+
`, config);
|
|
458
|
+
await page.locator('.datetime-ready').waitFor();
|
|
459
|
+
expect(logs.length).toBe(1);
|
|
460
|
+
expect(logs[0]).toContain('[Ionic Warning]: Datetime: "timeZone" and "timeZoneName" are not supported in "formatOptions".');
|
|
461
|
+
});
|
|
462
|
+
test('should log a warning if the required formatOptions are not provided for a presentation', async ({ page }) => {
|
|
463
|
+
const logs = [];
|
|
464
|
+
page.on('console', (msg) => {
|
|
465
|
+
if (msg.type() === 'warning') {
|
|
466
|
+
logs.push(msg.text());
|
|
467
|
+
}
|
|
468
|
+
});
|
|
469
|
+
await page.setContent(`
|
|
470
|
+
<ion-datetime value="2022-02-01T16:30:00">
|
|
471
|
+
<span slot="title">Select Date</span>
|
|
472
|
+
</ion-datetime>
|
|
473
|
+
<script>
|
|
474
|
+
const datetime = document.querySelector('ion-datetime');
|
|
475
|
+
datetime.formatOptions = {}
|
|
476
|
+
</script>
|
|
477
|
+
`, config);
|
|
478
|
+
await page.locator('.datetime-ready').waitFor();
|
|
479
|
+
expect(logs.length).toBe(1);
|
|
480
|
+
expect(logs[0]).toContain("[Ionic Warning]: Datetime: The 'date-time' presentation requires either a date or time object (or both) in formatOptions.");
|
|
481
|
+
});
|
|
482
|
+
});
|
|
483
|
+
});
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/*!
|
|
2
2
|
* (C) Ionic http://ionicframework.com - MIT License
|
|
3
3
|
*/
|
|
4
|
-
import { generateDayAriaLabel,
|
|
4
|
+
import { generateDayAriaLabel, getFormattedHour, addTimePadding, getMonthAndYear, getLocalizedDayPeriod, getLocalizedTime, stripTimeZone, } from "../utils/format";
|
|
5
5
|
describe('generateDayAriaLabel()', () => {
|
|
6
6
|
it('should return Wednesday, May 12', () => {
|
|
7
7
|
const reference = { month: 5, day: 12, year: 2021 };
|
|
@@ -24,20 +24,6 @@ describe('generateDayAriaLabel()', () => {
|
|
|
24
24
|
expect(generateDayAriaLabel('en-US', false, reference)).toEqual('Saturday, April 1');
|
|
25
25
|
});
|
|
26
26
|
});
|
|
27
|
-
describe('getMonthAndDay()', () => {
|
|
28
|
-
it('should return Tue, May 11', () => {
|
|
29
|
-
expect(getMonthAndDay('en-US', { month: 5, day: 11, year: 2021 })).toEqual('Tue, May 11');
|
|
30
|
-
});
|
|
31
|
-
it('should return mar, 11 may', () => {
|
|
32
|
-
expect(getMonthAndDay('es-ES', { month: 5, day: 11, year: 2021 })).toEqual('mar, 11 may');
|
|
33
|
-
});
|
|
34
|
-
it('should return Sat, Apr 1', () => {
|
|
35
|
-
expect(getMonthAndDay('en-US', { month: 4, day: 1, year: 2006 })).toEqual('Sat, Apr 1');
|
|
36
|
-
});
|
|
37
|
-
it('should return sáb, 1 abr', () => {
|
|
38
|
-
expect(getMonthAndDay('es-ES', { month: 4, day: 1, year: 2006 })).toEqual('sáb, 1 abr');
|
|
39
|
-
});
|
|
40
|
-
});
|
|
41
27
|
describe('getFormattedHour()', () => {
|
|
42
28
|
it('should only add padding if using 24 hour time', () => {
|
|
43
29
|
expect(getFormattedHour(1, 'h11')).toEqual('1');
|
|
@@ -121,4 +107,68 @@ describe('getLocalizedTime', () => {
|
|
|
121
107
|
expect(getLocalizedTime('en-US', datetimeParts, 'h12')).toEqual('10:40 PM');
|
|
122
108
|
expect(getLocalizedTime('en-US', datetimeParts, 'h23')).toEqual('22:40');
|
|
123
109
|
});
|
|
110
|
+
it('should use formatOptions', () => {
|
|
111
|
+
const datetimeParts = {
|
|
112
|
+
day: 1,
|
|
113
|
+
month: 1,
|
|
114
|
+
year: 2022,
|
|
115
|
+
hour: 9,
|
|
116
|
+
minute: 40,
|
|
117
|
+
};
|
|
118
|
+
const formatOptions = {
|
|
119
|
+
hour: '2-digit',
|
|
120
|
+
minute: '2-digit',
|
|
121
|
+
dayPeriod: 'short',
|
|
122
|
+
day: '2-digit',
|
|
123
|
+
};
|
|
124
|
+
// Even though this method is intended to be used for time, the date may be displayed as well when passing formatOptions
|
|
125
|
+
expect(getLocalizedTime('en-US', datetimeParts, 'h12', formatOptions)).toEqual('01, 09:40 in the morning');
|
|
126
|
+
});
|
|
127
|
+
it('should override provided time zone with UTC', () => {
|
|
128
|
+
const datetimeParts = {
|
|
129
|
+
day: 1,
|
|
130
|
+
month: 1,
|
|
131
|
+
year: 2022,
|
|
132
|
+
hour: 9,
|
|
133
|
+
minute: 40,
|
|
134
|
+
};
|
|
135
|
+
const formatOptions = {
|
|
136
|
+
timeZone: 'Australia/Sydney',
|
|
137
|
+
timeZoneName: 'long',
|
|
138
|
+
hour: 'numeric',
|
|
139
|
+
minute: 'numeric',
|
|
140
|
+
};
|
|
141
|
+
expect(getLocalizedTime('en-US', datetimeParts, 'h12', formatOptions)).toEqual('9:40 AM');
|
|
142
|
+
});
|
|
143
|
+
it('should not include time zone name', () => {
|
|
144
|
+
const datetimeParts = {
|
|
145
|
+
day: 1,
|
|
146
|
+
month: 1,
|
|
147
|
+
year: 2022,
|
|
148
|
+
hour: 9,
|
|
149
|
+
minute: 40,
|
|
150
|
+
};
|
|
151
|
+
const formatOptions = {
|
|
152
|
+
timeZone: 'America/Los_Angeles',
|
|
153
|
+
timeZoneName: 'long',
|
|
154
|
+
hour: 'numeric',
|
|
155
|
+
minute: 'numeric',
|
|
156
|
+
};
|
|
157
|
+
expect(getLocalizedTime('en-US', datetimeParts, 'h12', formatOptions)).toEqual('9:40 AM');
|
|
158
|
+
});
|
|
159
|
+
});
|
|
160
|
+
describe('stripTimeZone', () => {
|
|
161
|
+
it('should remove the time zone name from the options and set the time zone to UTC', () => {
|
|
162
|
+
const formatOptions = {
|
|
163
|
+
timeZone: 'America/Los_Angeles',
|
|
164
|
+
timeZoneName: 'long',
|
|
165
|
+
hour: 'numeric',
|
|
166
|
+
minute: 'numeric',
|
|
167
|
+
};
|
|
168
|
+
expect(stripTimeZone(formatOptions)).toEqual({
|
|
169
|
+
timeZone: 'UTC',
|
|
170
|
+
hour: 'numeric',
|
|
171
|
+
minute: 'numeric',
|
|
172
|
+
});
|
|
173
|
+
});
|
|
124
174
|
});
|
|
@@ -9,7 +9,26 @@ const getFormattedDayPeriod = (dayPeriod) => {
|
|
|
9
9
|
}
|
|
10
10
|
return dayPeriod.toUpperCase();
|
|
11
11
|
};
|
|
12
|
-
|
|
12
|
+
/**
|
|
13
|
+
* Including time zone options may lead to the rendered text showing a
|
|
14
|
+
* different time from what was selected in the Datetime, which could cause
|
|
15
|
+
* confusion.
|
|
16
|
+
*/
|
|
17
|
+
export const stripTimeZone = (formatOptions) => {
|
|
18
|
+
return Object.assign(Object.assign({}, formatOptions), {
|
|
19
|
+
/**
|
|
20
|
+
* Setting the time zone to UTC ensures that the value shown is always the
|
|
21
|
+
* same as what was selected and safeguards against older Safari bugs with
|
|
22
|
+
* Intl.DateTimeFormat.
|
|
23
|
+
*/
|
|
24
|
+
timeZone: 'UTC',
|
|
25
|
+
/**
|
|
26
|
+
* We do not want to display the time zone name
|
|
27
|
+
*/
|
|
28
|
+
timeZoneName: undefined
|
|
29
|
+
});
|
|
30
|
+
};
|
|
31
|
+
export const getLocalizedTime = (locale, refParts, hourCycle, formatOptions = { hour: 'numeric', minute: 'numeric' }) => {
|
|
13
32
|
const timeParts = {
|
|
14
33
|
hour: refParts.hour,
|
|
15
34
|
minute: refParts.minute,
|
|
@@ -17,28 +36,13 @@ export const getLocalizedTime = (locale, refParts, hourCycle) => {
|
|
|
17
36
|
if (timeParts.hour === undefined || timeParts.minute === undefined) {
|
|
18
37
|
return 'Invalid Time';
|
|
19
38
|
}
|
|
20
|
-
return new Intl.DateTimeFormat(locale, {
|
|
21
|
-
hour: 'numeric',
|
|
22
|
-
minute: 'numeric',
|
|
23
|
-
/**
|
|
24
|
-
* Setting the timeZone to UTC prevents
|
|
25
|
-
* new Intl.DatetimeFormat from subtracting
|
|
26
|
-
* the user's current timezone offset
|
|
27
|
-
* when formatting the time.
|
|
28
|
-
*/
|
|
29
|
-
timeZone: 'UTC',
|
|
39
|
+
return new Intl.DateTimeFormat(locale, Object.assign(Object.assign({}, stripTimeZone(formatOptions)), {
|
|
30
40
|
/**
|
|
31
41
|
* We use hourCycle here instead of hour12 due to:
|
|
32
42
|
* https://bugs.chromium.org/p/chromium/issues/detail?id=1347316&q=hour12&can=2
|
|
33
43
|
*/
|
|
34
|
-
hourCycle
|
|
35
|
-
|
|
36
|
-
* Setting Z at the end indicates that this
|
|
37
|
-
* date string is in the UTC time zone. This
|
|
38
|
-
* prevents new Date from adding the time zone
|
|
39
|
-
* offset when getting the ISO string.
|
|
40
|
-
*/
|
|
41
|
-
}).format(new Date(convertDataToISO(Object.assign({
|
|
44
|
+
hourCycle
|
|
45
|
+
})).format(new Date(convertDataToISO(Object.assign({
|
|
42
46
|
/**
|
|
43
47
|
* JS uses a simplified ISO 8601 format which allows for
|
|
44
48
|
* date-only formats and date-time formats, but not
|
|
@@ -125,14 +129,6 @@ export const generateDayAriaLabel = (locale, today, refParts) => {
|
|
|
125
129
|
*/
|
|
126
130
|
return today ? `Today, ${labelString}` : labelString;
|
|
127
131
|
};
|
|
128
|
-
/**
|
|
129
|
-
* Gets the day of the week, month, and day
|
|
130
|
-
* Used for the header in MD mode.
|
|
131
|
-
*/
|
|
132
|
-
export const getMonthAndDay = (locale, refParts) => {
|
|
133
|
-
const date = getNormalizedDate(refParts);
|
|
134
|
-
return new Intl.DateTimeFormat(locale, { weekday: 'short', month: 'short', day: 'numeric', timeZone: 'UTC' }).format(date);
|
|
135
|
-
};
|
|
136
132
|
/**
|
|
137
133
|
* Given a locale and a date object,
|
|
138
134
|
* return a formatted string that includes
|
|
@@ -143,15 +139,6 @@ export const getMonthAndYear = (locale, refParts) => {
|
|
|
143
139
|
const date = getNormalizedDate(refParts);
|
|
144
140
|
return new Intl.DateTimeFormat(locale, { month: 'long', year: 'numeric', timeZone: 'UTC' }).format(date);
|
|
145
141
|
};
|
|
146
|
-
/**
|
|
147
|
-
* Given a locale and a date object,
|
|
148
|
-
* return a formatted string that includes
|
|
149
|
-
* the short month, numeric day, and full year.
|
|
150
|
-
* Example: Apr 22, 2021
|
|
151
|
-
*/
|
|
152
|
-
export const getMonthDayAndYear = (locale, refParts) => {
|
|
153
|
-
return getLocalizedDateTime(locale, refParts, { month: 'short', day: 'numeric', year: 'numeric' });
|
|
154
|
-
};
|
|
155
142
|
/**
|
|
156
143
|
* Given a locale and a date object,
|
|
157
144
|
* return a formatted string that includes
|
|
@@ -201,7 +188,7 @@ export const getNormalizedDate = (refParts) => {
|
|
|
201
188
|
*/
|
|
202
189
|
export const getLocalizedDateTime = (locale, refParts, options) => {
|
|
203
190
|
const date = getNormalizedDate(refParts);
|
|
204
|
-
return getDateTimeFormat(locale, options).format(date);
|
|
191
|
+
return getDateTimeFormat(locale, stripTimeZone(options)).format(date);
|
|
205
192
|
};
|
|
206
193
|
/**
|
|
207
194
|
* Given a locale, DatetimeParts, and options
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/*!
|
|
2
|
+
* (C) Ionic http://ionicframework.com - MIT License
|
|
3
|
+
*/
|
|
4
|
+
import { printIonWarning } from "../../../utils/logging/index";
|
|
5
|
+
/**
|
|
6
|
+
* If a time zone is provided in the format options, the rendered text could
|
|
7
|
+
* differ from what was selected in the Datetime, which could cause
|
|
8
|
+
* confusion.
|
|
9
|
+
*/
|
|
10
|
+
export const warnIfTimeZoneProvided = (el, formatOptions) => {
|
|
11
|
+
var _a, _b, _c, _d;
|
|
12
|
+
if (((_a = formatOptions === null || formatOptions === void 0 ? void 0 : formatOptions.date) === null || _a === void 0 ? void 0 : _a.timeZone) ||
|
|
13
|
+
((_b = formatOptions === null || formatOptions === void 0 ? void 0 : formatOptions.date) === null || _b === void 0 ? void 0 : _b.timeZoneName) ||
|
|
14
|
+
((_c = formatOptions === null || formatOptions === void 0 ? void 0 : formatOptions.time) === null || _c === void 0 ? void 0 : _c.timeZone) ||
|
|
15
|
+
((_d = formatOptions === null || formatOptions === void 0 ? void 0 : formatOptions.time) === null || _d === void 0 ? void 0 : _d.timeZoneName)) {
|
|
16
|
+
printIonWarning('Datetime: "timeZone" and "timeZoneName" are not supported in "formatOptions".', el);
|
|
17
|
+
}
|
|
18
|
+
};
|
|
19
|
+
export const checkForPresentationFormatMismatch = (el, presentation, formatOptions) => {
|
|
20
|
+
// formatOptions is not required
|
|
21
|
+
if (!formatOptions)
|
|
22
|
+
return;
|
|
23
|
+
// If formatOptions is provided, the date and/or time objects are required, depending on the presentation
|
|
24
|
+
switch (presentation) {
|
|
25
|
+
case 'date':
|
|
26
|
+
case 'month-year':
|
|
27
|
+
case 'month':
|
|
28
|
+
case 'year':
|
|
29
|
+
if (formatOptions.date === undefined) {
|
|
30
|
+
printIonWarning(`Datetime: The '${presentation}' presentation requires a date object in formatOptions.`, el);
|
|
31
|
+
}
|
|
32
|
+
break;
|
|
33
|
+
case 'time':
|
|
34
|
+
if (formatOptions.time === undefined) {
|
|
35
|
+
printIonWarning(`Datetime: The 'time' presentation requires a time object in formatOptions.`, el);
|
|
36
|
+
}
|
|
37
|
+
break;
|
|
38
|
+
case 'date-time':
|
|
39
|
+
case 'time-date':
|
|
40
|
+
if (formatOptions.date === undefined && formatOptions.time === undefined) {
|
|
41
|
+
printIonWarning(`Datetime: The '${presentation}' presentation requires either a date or time object (or both) in formatOptions.`, el);
|
|
42
|
+
}
|
|
43
|
+
break;
|
|
44
|
+
}
|
|
45
|
+
};
|
|
@@ -7,7 +7,7 @@ import { printIonError } from "../../utils/logging/index";
|
|
|
7
7
|
import { createColorClasses } from "../../utils/theme";
|
|
8
8
|
import { getIonMode } from "../../global/ionic-global";
|
|
9
9
|
import { getToday } from "../datetime/utils/data";
|
|
10
|
-
import {
|
|
10
|
+
import { getLocalizedDateTime, getLocalizedTime } from "../datetime/utils/format";
|
|
11
11
|
import { getHourCycle } from "../datetime/utils/helpers";
|
|
12
12
|
import { parseDate } from "../datetime/utils/parse";
|
|
13
13
|
/**
|
|
@@ -43,11 +43,12 @@ export class DatetimeButton {
|
|
|
43
43
|
* to the locale specified on ion-datetime.
|
|
44
44
|
*/
|
|
45
45
|
this.setDateTimeText = () => {
|
|
46
|
+
var _a, _b, _c, _d, _e;
|
|
46
47
|
const { datetimeEl, datetimePresentation } = this;
|
|
47
48
|
if (!datetimeEl) {
|
|
48
49
|
return;
|
|
49
50
|
}
|
|
50
|
-
const { value, locale, hourCycle, preferWheel, multiple, titleSelectedDatesFormatter } = datetimeEl;
|
|
51
|
+
const { value, locale, formatOptions, hourCycle, preferWheel, multiple, titleSelectedDatesFormatter } = datetimeEl;
|
|
51
52
|
const parsedValues = this.getParsedDateValues(value);
|
|
52
53
|
/**
|
|
53
54
|
* Both ion-datetime and ion-datetime-button default
|
|
@@ -70,8 +71,8 @@ export class DatetimeButton {
|
|
|
70
71
|
switch (datetimePresentation) {
|
|
71
72
|
case 'date-time':
|
|
72
73
|
case 'time-date':
|
|
73
|
-
const dateText =
|
|
74
|
-
const timeText = getLocalizedTime(locale, firstParsedDatetime, computedHourCycle);
|
|
74
|
+
const dateText = getLocalizedDateTime(locale, firstParsedDatetime, (_a = formatOptions === null || formatOptions === void 0 ? void 0 : formatOptions.date) !== null && _a !== void 0 ? _a : { month: 'short', day: 'numeric', year: 'numeric' });
|
|
75
|
+
const timeText = getLocalizedTime(locale, firstParsedDatetime, computedHourCycle, formatOptions === null || formatOptions === void 0 ? void 0 : formatOptions.time);
|
|
75
76
|
if (preferWheel) {
|
|
76
77
|
this.dateText = `${dateText} ${timeText}`;
|
|
77
78
|
}
|
|
@@ -94,20 +95,20 @@ export class DatetimeButton {
|
|
|
94
95
|
this.dateText = headerText;
|
|
95
96
|
}
|
|
96
97
|
else {
|
|
97
|
-
this.dateText =
|
|
98
|
+
this.dateText = getLocalizedDateTime(locale, firstParsedDatetime, (_b = formatOptions === null || formatOptions === void 0 ? void 0 : formatOptions.date) !== null && _b !== void 0 ? _b : { month: 'short', day: 'numeric', year: 'numeric' });
|
|
98
99
|
}
|
|
99
100
|
break;
|
|
100
101
|
case 'time':
|
|
101
|
-
this.timeText = getLocalizedTime(locale, firstParsedDatetime, computedHourCycle);
|
|
102
|
+
this.timeText = getLocalizedTime(locale, firstParsedDatetime, computedHourCycle, formatOptions === null || formatOptions === void 0 ? void 0 : formatOptions.time);
|
|
102
103
|
break;
|
|
103
104
|
case 'month-year':
|
|
104
|
-
this.dateText =
|
|
105
|
+
this.dateText = getLocalizedDateTime(locale, firstParsedDatetime, (_c = formatOptions === null || formatOptions === void 0 ? void 0 : formatOptions.date) !== null && _c !== void 0 ? _c : { month: 'long', year: 'numeric' });
|
|
105
106
|
break;
|
|
106
107
|
case 'month':
|
|
107
|
-
this.dateText = getLocalizedDateTime(locale, firstParsedDatetime, { month: 'long' });
|
|
108
|
+
this.dateText = getLocalizedDateTime(locale, firstParsedDatetime, (_d = formatOptions === null || formatOptions === void 0 ? void 0 : formatOptions.time) !== null && _d !== void 0 ? _d : { month: 'long' });
|
|
108
109
|
break;
|
|
109
110
|
case 'year':
|
|
110
|
-
this.dateText = getLocalizedDateTime(locale, firstParsedDatetime, { year: 'numeric' });
|
|
111
|
+
this.dateText = getLocalizedDateTime(locale, firstParsedDatetime, (_e = formatOptions === null || formatOptions === void 0 ? void 0 : formatOptions.time) !== null && _e !== void 0 ? _e : { year: 'numeric' });
|
|
111
112
|
break;
|
|
112
113
|
}
|
|
113
114
|
};
|
|
@@ -336,7 +337,7 @@ export class DatetimeButton {
|
|
|
336
337
|
render() {
|
|
337
338
|
const { color, dateText, timeText, selectedButton, datetimeActive, disabled } = this;
|
|
338
339
|
const mode = getIonMode(this);
|
|
339
|
-
return (h(Host, { key: '
|
|
340
|
+
return (h(Host, { key: '861a08f4a239de771875aee9b505e06ac7064b32', class: createColorClasses(color, {
|
|
340
341
|
[mode]: true,
|
|
341
342
|
[`${selectedButton}-active`]: datetimeActive,
|
|
342
343
|
['datetime-button-disabled']: disabled,
|
|
@@ -174,4 +174,69 @@ configs({ modes: ['md'], directions: ['ltr'] }).forEach(({ title, config }) => {
|
|
|
174
174
|
await expect(page.locator('#time-button')).not.toBeVisible();
|
|
175
175
|
});
|
|
176
176
|
});
|
|
177
|
+
test.describe(title('datetime-button: formatOptions'), () => {
|
|
178
|
+
test('should include date and time for presentation date-time', async ({ page }) => {
|
|
179
|
+
await page.setContent(`
|
|
180
|
+
<ion-datetime-button datetime="datetime"></ion-datetime-button>
|
|
181
|
+
<ion-datetime id="datetime" presentation="date-time" value="2023-11-02T01:22:00" locale="en-US"></ion-datetime>
|
|
182
|
+
<script>
|
|
183
|
+
const datetime = document.querySelector('ion-datetime');
|
|
184
|
+
datetime.formatOptions = {
|
|
185
|
+
date: {
|
|
186
|
+
weekday: "short",
|
|
187
|
+
month: "long",
|
|
188
|
+
day: "2-digit"
|
|
189
|
+
},
|
|
190
|
+
time: {
|
|
191
|
+
hour: "2-digit",
|
|
192
|
+
minute: "2-digit"
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
</script>
|
|
196
|
+
`, config);
|
|
197
|
+
await page.locator('.datetime-ready').waitFor();
|
|
198
|
+
await expect(page.locator('#date-button')).toContainText('Thu, November 02');
|
|
199
|
+
await expect(page.locator('#time-button')).toContainText('01:22 AM');
|
|
200
|
+
});
|
|
201
|
+
test('should include date for presentation date', async ({ page }) => {
|
|
202
|
+
await page.setContent(`
|
|
203
|
+
<ion-datetime-button datetime="datetime"></ion-datetime-button>
|
|
204
|
+
<ion-datetime id="datetime" presentation="date" value="2023-11-02" locale="en-US"></ion-datetime>
|
|
205
|
+
<script>
|
|
206
|
+
const datetime = document.querySelector('ion-datetime');
|
|
207
|
+
datetime.formatOptions = {
|
|
208
|
+
date: {
|
|
209
|
+
weekday: "short",
|
|
210
|
+
month: "long",
|
|
211
|
+
day: "2-digit"
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
</script>
|
|
215
|
+
`, config);
|
|
216
|
+
await page.locator('.datetime-ready').waitFor();
|
|
217
|
+
await expect(page.locator('#date-button')).toContainText('Thu, November 02');
|
|
218
|
+
});
|
|
219
|
+
test('should include date and time in same button for preferWheel', async ({ page }) => {
|
|
220
|
+
await page.setContent(`
|
|
221
|
+
<ion-datetime-button datetime="datetime"></ion-datetime-button>
|
|
222
|
+
<ion-datetime id="datetime" presentation="date-time" value="2023-11-02T01:22:00" locale="en-US" prefer-wheel="true"></ion-datetime>
|
|
223
|
+
<script>
|
|
224
|
+
const datetime = document.querySelector('ion-datetime');
|
|
225
|
+
datetime.formatOptions = {
|
|
226
|
+
date: {
|
|
227
|
+
weekday: "short",
|
|
228
|
+
month: "long",
|
|
229
|
+
day: "2-digit"
|
|
230
|
+
},
|
|
231
|
+
time: {
|
|
232
|
+
hour: "2-digit",
|
|
233
|
+
minute: "2-digit"
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
</script>
|
|
237
|
+
`, config);
|
|
238
|
+
await page.locator('.datetime-ready').waitFor();
|
|
239
|
+
await expect(page.locator('ion-datetime-button')).toContainText('Thu, November 02 01:22 AM');
|
|
240
|
+
});
|
|
241
|
+
});
|
|
177
242
|
});
|
|
@@ -244,7 +244,11 @@ export class PickerColumnInternal {
|
|
|
244
244
|
*/
|
|
245
245
|
componentWillLoad() {
|
|
246
246
|
const visibleCallback = (entries) => {
|
|
247
|
-
|
|
247
|
+
/**
|
|
248
|
+
* Browsers will sometimes group multiple IO events into a single callback.
|
|
249
|
+
* As a result, we want to grab the last/most recent event in case there are multiple events.
|
|
250
|
+
*/
|
|
251
|
+
const ev = entries[entries.length - 1];
|
|
248
252
|
if (ev.isIntersecting) {
|
|
249
253
|
const { activeItem, el } = this;
|
|
250
254
|
this.isColumnVisible = true;
|
|
@@ -333,11 +337,11 @@ export class PickerColumnInternal {
|
|
|
333
337
|
* the attribute can be moved to datetime.tsx and set on every
|
|
334
338
|
* instance of ion-picker-column-internal there instead.
|
|
335
339
|
*/
|
|
336
|
-
return (h(Host, { key: '
|
|
340
|
+
return (h(Host, { key: '2cf182b9d88219e7ab1feb66c90992c4b9bc6b8e', exportparts: `${PICKER_ITEM_PART}, ${PICKER_ITEM_ACTIVE_PART}`, disabled: pickerDisabled, tabindex: pickerDisabled ? null : 0, class: createColorClasses(color, {
|
|
337
341
|
[mode]: true,
|
|
338
342
|
['picker-column-active']: isActive,
|
|
339
343
|
['picker-column-numeric-input']: numericInput,
|
|
340
|
-
}) }, h("div", { key: '
|
|
344
|
+
}) }, h("div", { key: '86fa9a1464c03dd25fbe4880b91a597228e0b9c6', class: "picker-item picker-item-empty", "aria-hidden": "true" }, "\u00A0"), h("div", { key: '3bcc466879ea06355c4132d1b7dd469f5aeb193b', class: "picker-item picker-item-empty", "aria-hidden": "true" }, "\u00A0"), h("div", { key: '3aa4e3a12f2fa7d05692c1758648817b19fa6e12', class: "picker-item picker-item-empty", "aria-hidden": "true" }, "\u00A0"), items.map((item, index) => {
|
|
341
345
|
const isItemDisabled = pickerDisabled || item.disabled || false;
|
|
342
346
|
{
|
|
343
347
|
/*
|
|
@@ -354,7 +358,7 @@ export class PickerColumnInternal {
|
|
|
354
358
|
}, "data-value": item.value, "data-index": index, onClick: (ev) => {
|
|
355
359
|
this.centerPickerItemInView(ev.target, true);
|
|
356
360
|
}, disabled: isItemDisabled, part: PICKER_ITEM_PART }, item.text));
|
|
357
|
-
}), h("div", { key: '
|
|
361
|
+
}), h("div", { key: '0400a6791070b947db3ca692cf780190f7798d88', class: "picker-item picker-item-empty", "aria-hidden": "true" }, "\u00A0"), h("div", { key: '48c4c5e7d2534fd394a3cf6f608eb9998e795bcc', class: "picker-item picker-item-empty", "aria-hidden": "true" }, "\u00A0"), h("div", { key: '2881a12b028923f6e6f140ed963de8646cadf0aa', class: "picker-item picker-item-empty", "aria-hidden": "true" }, "\u00A0")));
|
|
358
362
|
}
|
|
359
363
|
static get is() { return "ion-picker-column-internal"; }
|
|
360
364
|
static get encapsulation() { return "shadow"; }
|