Skip to content

Commit 6dfdc2c

Browse files
authored
merge feature-7.8 (#29152)
2 parents 636531f + 01ae835 commit 6dfdc2c

File tree

16 files changed

+605
-75
lines changed

16 files changed

+605
-75
lines changed

core/api.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -394,6 +394,7 @@ ion-datetime,prop,dayValues,number | number[] | string | undefined,undefined,fal
394394
ion-datetime,prop,disabled,boolean,false,false,false
395395
ion-datetime,prop,doneText,string,'Done',false,false
396396
ion-datetime,prop,firstDayOfWeek,number,0,false,false
397+
ion-datetime,prop,formatOptions,undefined | { date: DateTimeFormatOptions; time?: DateTimeFormatOptions | undefined; } | { date?: DateTimeFormatOptions | undefined; time: DateTimeFormatOptions; },undefined,false,false
397398
ion-datetime,prop,highlightedDates,((dateIsoString: string) => DatetimeHighlightStyle | undefined) | DatetimeHighlight[] | undefined,undefined,false,false
398399
ion-datetime,prop,hourCycle,"h11" | "h12" | "h23" | "h24" | undefined,undefined,false,false
399400
ion-datetime,prop,hourValues,number | number[] | string | undefined,undefined,false,false
@@ -1157,6 +1158,7 @@ ion-row,shadow
11571158

11581159
ion-searchbar,scoped
11591160
ion-searchbar,prop,animated,boolean,false,false,false
1161+
ion-searchbar,prop,autocapitalize,string,undefined,true,false
11601162
ion-searchbar,prop,autocomplete,"name" | "email" | "tel" | "url" | "on" | "off" | "honorific-prefix" | "given-name" | "additional-name" | "family-name" | "honorific-suffix" | "nickname" | "username" | "new-password" | "current-password" | "one-time-code" | "organization-title" | "organization" | "street-address" | "address-line1" | "address-line2" | "address-line3" | "address-level4" | "address-level3" | "address-level2" | "address-level1" | "country" | "country-name" | "postal-code" | "cc-name" | "cc-given-name" | "cc-additional-name" | "cc-family-name" | "cc-number" | "cc-exp" | "cc-exp-month" | "cc-exp-year" | "cc-csc" | "cc-type" | "transaction-currency" | "transaction-amount" | "language" | "bday" | "bday-day" | "bday-month" | "bday-year" | "sex" | "tel-country-code" | "tel-national" | "tel-area-code" | "tel-local" | "tel-extension" | "impp" | "photo",'off',false,false
11611163
ion-searchbar,prop,autocorrect,"off" | "on",'off',false,false
11621164
ion-searchbar,prop,cancelButtonIcon,string,config.get('backButtonIcon', arrowBackSharp) as string,false,false
@@ -1167,6 +1169,8 @@ ion-searchbar,prop,debounce,number | undefined,undefined,false,false
11671169
ion-searchbar,prop,disabled,boolean,false,false,false
11681170
ion-searchbar,prop,enterkeyhint,"done" | "enter" | "go" | "next" | "previous" | "search" | "send" | undefined,undefined,false,false
11691171
ion-searchbar,prop,inputmode,"decimal" | "email" | "none" | "numeric" | "search" | "tel" | "text" | "url" | undefined,undefined,false,false
1172+
ion-searchbar,prop,maxlength,number | undefined,undefined,false,false
1173+
ion-searchbar,prop,minlength,number | undefined,undefined,false,false
11701174
ion-searchbar,prop,mode,"ios" | "md",undefined,false,false
11711175
ion-searchbar,prop,name,string,this.inputId,false,false
11721176
ion-searchbar,prop,placeholder,string,'Search',false,false

core/src/components.d.ts

Lines changed: 34 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ import { RouteID, RouterDirection, RouterEventDetail, RouteWrite } from "./compo
1515
import { BreadcrumbCollapsedClickEventDetail } from "./components/breadcrumb/breadcrumb-interface";
1616
import { CheckboxChangeEventDetail } from "./components/checkbox/checkbox-interface";
1717
import { ScrollBaseDetail, ScrollDetail } from "./components/content/content-interface";
18-
import { DatetimeChangeEventDetail, DatetimeHighlight, DatetimeHighlightCallback, DatetimeHourCycle, DatetimePresentation, TitleSelectedDatesFormatter } from "./components/datetime/datetime-interface";
18+
import { DatetimeChangeEventDetail, DatetimeHighlight, DatetimeHighlightCallback, DatetimeHourCycle, DatetimePresentation, FormatOptions, TitleSelectedDatesFormatter } from "./components/datetime/datetime-interface";
1919
import { SpinnerTypes } from "./components/spinner/spinner-configs";
2020
import { InputChangeEventDetail, InputInputEventDetail } from "./components/input/input-interface";
2121
import { CounterFormatter } from "./components/item/item-interface";
@@ -51,7 +51,7 @@ export { RouteID, RouterDirection, RouterEventDetail, RouteWrite } from "./compo
5151
export { BreadcrumbCollapsedClickEventDetail } from "./components/breadcrumb/breadcrumb-interface";
5252
export { CheckboxChangeEventDetail } from "./components/checkbox/checkbox-interface";
5353
export { ScrollBaseDetail, ScrollDetail } from "./components/content/content-interface";
54-
export { DatetimeChangeEventDetail, DatetimeHighlight, DatetimeHighlightCallback, DatetimeHourCycle, DatetimePresentation, TitleSelectedDatesFormatter } from "./components/datetime/datetime-interface";
54+
export { DatetimeChangeEventDetail, DatetimeHighlight, DatetimeHighlightCallback, DatetimeHourCycle, DatetimePresentation, FormatOptions, TitleSelectedDatesFormatter } from "./components/datetime/datetime-interface";
5555
export { SpinnerTypes } from "./components/spinner/spinner-configs";
5656
export { InputChangeEventDetail, InputInputEventDetail } from "./components/input/input-interface";
5757
export { CounterFormatter } from "./components/item/item-interface";
@@ -858,6 +858,10 @@ export namespace Components {
858858
* The first day of the week to use for `ion-datetime`. The default value is `0` and represents Sunday.
859859
*/
860860
"firstDayOfWeek": number;
861+
/**
862+
* Formatting options for dates and times. Should include a 'date' and/or 'time' object, each of which is of type [Intl.DateTimeFormatOptions](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/DateTimeFormat/DateTimeFormat#options).
863+
*/
864+
"formatOptions"?: FormatOptions;
861865
/**
862866
* Used to apply custom text and background colors to specific dates. Can be either an array of objects containing ISO strings and colors, or a callback that receives an ISO string and returns the colors. Only applies to the `date`, `date-time`, and `time-date` presentations, with `preferWheel="false"`.
863867
*/
@@ -2548,6 +2552,10 @@ export namespace Components {
25482552
* If `true`, enable searchbar animation.
25492553
*/
25502554
"animated": boolean;
2555+
/**
2556+
* Indicates whether and how the text value should be automatically capitalized as it is entered/edited by the user. Available options: `"off"`, `"none"`, `"on"`, `"sentences"`, `"words"`, `"characters"`.
2557+
*/
2558+
"autocapitalize": string;
25512559
/**
25522560
* Set the input's autocomplete property.
25532561
*/
@@ -2592,6 +2600,14 @@ export namespace Components {
25922600
* A hint to the browser for which keyboard to display. Possible values: `"none"`, `"text"`, `"tel"`, `"url"`, `"email"`, `"numeric"`, `"decimal"`, and `"search"`.
25932601
*/
25942602
"inputmode"?: 'none' | 'text' | 'tel' | 'url' | 'email' | 'numeric' | 'decimal' | 'search';
2603+
/**
2604+
* This attribute specifies the maximum number of characters that the user can enter.
2605+
*/
2606+
"maxlength"?: number;
2607+
/**
2608+
* This attribute specifies the minimum number of characters that the user can enter.
2609+
*/
2610+
"minlength"?: number;
25952611
/**
25962612
* The mode determines which platform styles to use.
25972613
*/
@@ -5541,6 +5557,10 @@ declare namespace LocalJSX {
55415557
* The first day of the week to use for `ion-datetime`. The default value is `0` and represents Sunday.
55425558
*/
55435559
"firstDayOfWeek"?: number;
5560+
/**
5561+
* Formatting options for dates and times. Should include a 'date' and/or 'time' object, each of which is of type [Intl.DateTimeFormatOptions](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/DateTimeFormat/DateTimeFormat#options).
5562+
*/
5563+
"formatOptions"?: FormatOptions;
55445564
/**
55455565
* Used to apply custom text and background colors to specific dates. Can be either an array of objects containing ISO strings and colors, or a callback that receives an ISO string and returns the colors. Only applies to the `date`, `date-time`, and `time-date` presentations, with `preferWheel="false"`.
55465566
*/
@@ -7272,6 +7292,10 @@ declare namespace LocalJSX {
72727292
* If `true`, enable searchbar animation.
72737293
*/
72747294
"animated"?: boolean;
7295+
/**
7296+
* Indicates whether and how the text value should be automatically capitalized as it is entered/edited by the user. Available options: `"off"`, `"none"`, `"on"`, `"sentences"`, `"words"`, `"characters"`.
7297+
*/
7298+
"autocapitalize": string;
72757299
/**
72767300
* Set the input's autocomplete property.
72777301
*/
@@ -7312,6 +7336,14 @@ declare namespace LocalJSX {
73127336
* A hint to the browser for which keyboard to display. Possible values: `"none"`, `"text"`, `"tel"`, `"url"`, `"email"`, `"numeric"`, `"decimal"`, and `"search"`.
73137337
*/
73147338
"inputmode"?: 'none' | 'text' | 'tel' | 'url' | 'email' | 'numeric' | 'decimal' | 'search';
7339+
/**
7340+
* This attribute specifies the maximum number of characters that the user can enter.
7341+
*/
7342+
"maxlength"?: number;
7343+
/**
7344+
* This attribute specifies the minimum number of characters that the user can enter.
7345+
*/
7346+
"minlength"?: number;
73157347
/**
73167348
* The mode determines which platform styles to use.
73177349
*/

core/src/components/datetime-button/datetime-button.tsx

Lines changed: 21 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import { getIonMode } from '../../global/ionic-global';
88
import type { Color } from '../../interface';
99
import type { DatetimePresentation } from '../datetime/datetime-interface';
1010
import { getToday } from '../datetime/utils/data';
11-
import { getMonthAndYear, getMonthDayAndYear, getLocalizedDateTime, getLocalizedTime } from '../datetime/utils/format';
11+
import { getLocalizedDateTime, getLocalizedTime } from '../datetime/utils/format';
1212
import { getHourCycle } from '../datetime/utils/helpers';
1313
import { parseDate } from '../datetime/utils/parse';
1414
/**
@@ -196,7 +196,7 @@ export class DatetimeButton implements ComponentInterface {
196196
return;
197197
}
198198

199-
const { value, locale, hourCycle, preferWheel, multiple, titleSelectedDatesFormatter } = datetimeEl;
199+
const { value, locale, formatOptions, hourCycle, preferWheel, multiple, titleSelectedDatesFormatter } = datetimeEl;
200200

201201
const parsedValues = this.getParsedDateValues(value);
202202

@@ -225,8 +225,12 @@ export class DatetimeButton implements ComponentInterface {
225225
switch (datetimePresentation) {
226226
case 'date-time':
227227
case 'time-date':
228-
const dateText = getMonthDayAndYear(locale, firstParsedDatetime);
229-
const timeText = getLocalizedTime(locale, firstParsedDatetime, computedHourCycle);
228+
const dateText = getLocalizedDateTime(
229+
locale,
230+
firstParsedDatetime,
231+
formatOptions?.date ?? { month: 'short', day: 'numeric', year: 'numeric' }
232+
);
233+
const timeText = getLocalizedTime(locale, firstParsedDatetime, computedHourCycle, formatOptions?.time);
230234
if (preferWheel) {
231235
this.dateText = `${dateText} ${timeText}`;
232236
} else {
@@ -246,20 +250,28 @@ export class DatetimeButton implements ComponentInterface {
246250
}
247251
this.dateText = headerText;
248252
} else {
249-
this.dateText = getMonthDayAndYear(locale, firstParsedDatetime);
253+
this.dateText = getLocalizedDateTime(
254+
locale,
255+
firstParsedDatetime,
256+
formatOptions?.date ?? { month: 'short', day: 'numeric', year: 'numeric' }
257+
);
250258
}
251259
break;
252260
case 'time':
253-
this.timeText = getLocalizedTime(locale, firstParsedDatetime, computedHourCycle);
261+
this.timeText = getLocalizedTime(locale, firstParsedDatetime, computedHourCycle, formatOptions?.time);
254262
break;
255263
case 'month-year':
256-
this.dateText = getMonthAndYear(locale, firstParsedDatetime);
264+
this.dateText = getLocalizedDateTime(
265+
locale,
266+
firstParsedDatetime,
267+
formatOptions?.date ?? { month: 'long', year: 'numeric' }
268+
);
257269
break;
258270
case 'month':
259-
this.dateText = getLocalizedDateTime(locale, firstParsedDatetime, { month: 'long' });
271+
this.dateText = getLocalizedDateTime(locale, firstParsedDatetime, formatOptions?.time ?? { month: 'long' });
260272
break;
261273
case 'year':
262-
this.dateText = getLocalizedDateTime(locale, firstParsedDatetime, { year: 'numeric' });
274+
this.dateText = getLocalizedDateTime(locale, firstParsedDatetime, formatOptions?.time ?? { year: 'numeric' });
263275
break;
264276
}
265277
};

core/src/components/datetime-button/test/basic/datetime-button.e2e.ts

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -244,4 +244,87 @@ configs({ modes: ['md'], directions: ['ltr'] }).forEach(({ title, config }) => {
244244
await expect(page.locator('#time-button')).not.toBeVisible();
245245
});
246246
});
247+
248+
test.describe(title('datetime-button: formatOptions'), () => {
249+
test('should include date and time for presentation date-time', async ({ page }) => {
250+
await page.setContent(
251+
`
252+
<ion-datetime-button datetime="datetime"></ion-datetime-button>
253+
<ion-datetime id="datetime" presentation="date-time" value="2023-11-02T01:22:00" locale="en-US"></ion-datetime>
254+
<script>
255+
const datetime = document.querySelector('ion-datetime');
256+
datetime.formatOptions = {
257+
date: {
258+
weekday: "short",
259+
month: "long",
260+
day: "2-digit"
261+
},
262+
time: {
263+
hour: "2-digit",
264+
minute: "2-digit"
265+
}
266+
}
267+
</script>
268+
`,
269+
config
270+
);
271+
272+
await page.locator('.datetime-ready').waitFor();
273+
274+
await expect(page.locator('#date-button')).toContainText('Thu, November 02');
275+
await expect(page.locator('#time-button')).toContainText('01:22 AM');
276+
});
277+
278+
test('should include date for presentation date', async ({ page }) => {
279+
await page.setContent(
280+
`
281+
<ion-datetime-button datetime="datetime"></ion-datetime-button>
282+
<ion-datetime id="datetime" presentation="date" value="2023-11-02" locale="en-US"></ion-datetime>
283+
<script>
284+
const datetime = document.querySelector('ion-datetime');
285+
datetime.formatOptions = {
286+
date: {
287+
weekday: "short",
288+
month: "long",
289+
day: "2-digit"
290+
}
291+
}
292+
</script>
293+
`,
294+
config
295+
);
296+
297+
await page.locator('.datetime-ready').waitFor();
298+
299+
await expect(page.locator('#date-button')).toContainText('Thu, November 02');
300+
});
301+
302+
test('should include date and time in same button for preferWheel', async ({ page }) => {
303+
await page.setContent(
304+
`
305+
<ion-datetime-button datetime="datetime"></ion-datetime-button>
306+
<ion-datetime id="datetime" presentation="date-time" value="2023-11-02T01:22:00" locale="en-US" prefer-wheel="true"></ion-datetime>
307+
<script>
308+
const datetime = document.querySelector('ion-datetime');
309+
datetime.formatOptions = {
310+
date: {
311+
weekday: "short",
312+
month: "long",
313+
day: "2-digit"
314+
},
315+
time: {
316+
hour: "2-digit",
317+
minute: "2-digit"
318+
}
319+
}
320+
</script>
321+
`,
322+
config
323+
);
324+
325+
await page.locator('.datetime-ready').waitFor();
326+
327+
await expect(page.locator('ion-datetime-button')).toContainText('Thu, November 02 01:22 AM');
328+
});
329+
});
247330
});

core/src/components/datetime-button/test/basic/index.html

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -215,8 +215,41 @@ <h2>preferWheel / date-time</h2>
215215
></ion-datetime>
216216
</ion-popover>
217217
</div>
218+
219+
<div class="grid-item">
220+
<h2>formatOptions</h2>
221+
222+
<ion-item>
223+
<ion-label>Start Date</ion-label>
224+
<ion-datetime-button datetime="format-options" slot="end"></ion-datetime-button>
225+
</ion-item>
226+
227+
<ion-popover arrow="false">
228+
<ion-datetime
229+
id="format-options"
230+
presentation="date-time"
231+
value="2023-11-02T01:22:00"
232+
locale="en-US"
233+
></ion-datetime>
234+
</ion-popover>
235+
</div>
218236
</div>
219237
</ion-content>
220238
</ion-app>
221239
</body>
240+
241+
<script>
242+
const formatOptionsDatetime = document.querySelector('#format-options');
243+
formatOptionsDatetime.formatOptions = {
244+
date: {
245+
weekday: 'short',
246+
month: 'long',
247+
day: '2-digit',
248+
},
249+
time: {
250+
hour: '2-digit',
251+
minute: '2-digit',
252+
},
253+
};
254+
</script>
222255
</html>

core/src/components/datetime/datetime-interface.ts

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,3 +36,16 @@ export type DatetimeHighlight = { date: string } & DatetimeHighlightStyle;
3636
export type DatetimeHighlightCallback = (dateIsoString: string) => DatetimeHighlightStyle | undefined;
3737

3838
export type DatetimeHourCycle = 'h11' | 'h12' | 'h23' | 'h24';
39+
40+
/**
41+
* FormatOptions must include date and/or time; it cannot be an empty object
42+
*/
43+
export type FormatOptions =
44+
| {
45+
date: Intl.DateTimeFormatOptions;
46+
time?: Intl.DateTimeFormatOptions;
47+
}
48+
| {
49+
date?: Intl.DateTimeFormatOptions;
50+
time: Intl.DateTimeFormatOptions;
51+
};

0 commit comments

Comments
 (0)